Sheen HMG fully functional. May need touchups later.
|
|
@ -13,8 +13,8 @@ More weapons, because we need 'em. In addition, all the "easy to implement" mini
|
|||
- High Noon *(Land 6 killing shots in a single Puntzer Beta reload)*
|
||||
- [4] Puntzer Gamma *(Ultra Suite 2)*
|
||||
- You Gained Brouzouf *(Unload an entire mag in fuller auto with the Puntzer Gamma without missing a single shot)*
|
||||
- [5] Sheen HMG *(SWWM Platinum Ep2)*
|
||||
- Dakka *(Fire the Sheen HMG at 700 RPM for 30 seconds straight)*
|
||||
- ✓ [5] Sheen HMG *(SWWM Platinum Ep2)*
|
||||
- ✓ Dakka *(Fire the Sheen HMG at 700 RPM for 30 seconds straight)*
|
||||
- [6] Quadravol *(UnSX)*
|
||||
- Gravely Roast *(Perform 50 bayonet combos with the Quadravol)*
|
||||
- [7] Sparkster x3 *(UnSX 2)*
|
||||
|
|
|
|||
BIN
graphics/HUD/SheenBar.png
Normal file
|
After Width: | Height: | Size: 83 B |
|
Before Width: | Height: | Size: 97 B |
|
Before Width: | Height: | Size: 95 B |
|
Before Width: | Height: | Size: 95 B |
|
Before Width: | Height: | Size: 96 B |
|
|
@ -788,9 +788,9 @@ TT_PUNTZERGAMMA =
|
|||
"\cfAltfire:\c- Fuller-auto fire.\n"
|
||||
"\cfReload:\c- Reload weapon.";
|
||||
TT_SHEENHMG =
|
||||
"\cfFire:\c- Slow fire.\n"
|
||||
"\cfAltfire:\c- Moderate fire.\n"
|
||||
"\cfZoom:\c- Fast fire.";
|
||||
"\cfFire:\c- Shoot weapon.\n"
|
||||
"\cfAltfire:\c- Increase speed.\n"
|
||||
"\cfZoom:\c- Decrease speed.";
|
||||
TT_QUADRAVOL =
|
||||
"\cfFire:\c- Shoot weapon.\n"
|
||||
"\cfAltfire:\c- Pump weapon.\n"
|
||||
|
|
@ -810,7 +810,7 @@ TT_RAYKHOM =
|
|||
"\cfZoom:\c- Use scope.";
|
||||
TT_MORTALRIFLE =
|
||||
"\cfFire:\c- Shoot weapon.\n"
|
||||
"\cfAltfire:\c- Shoot grenade.\n"
|
||||
"\cfAltfire:\c- Shoot/reload grenade.\n"
|
||||
"\cfZoom:\c- Cycle fire modes.\n"
|
||||
"\cfReload:\c- Reload weapon.";
|
||||
TT_RAFANKOS =
|
||||
|
|
|
|||
|
|
@ -1459,7 +1459,7 @@ SWWM_LORETXT_HEAVYMAHSHEENGUN =
|
|||
"\n"
|
||||
"\cf300 RPM:\c- A slow spin. Sustained fire in this mode is theoretically endless, as the heat produced can be efficiently nullified by the internal cooling systems, it is therefore the recommended mode for most situations.\n"
|
||||
"\n"
|
||||
"\cf700 RPM:\c- Much faster spin, with moderate heat buildup. It's still possible to keep firing in this mode for about a minute or so from a cold start. If you need to deliver more pain and have the ammunition to spare, choose this.\n"
|
||||
"\cf700 RPM:\c- Much faster spin, with moderate heat buildup. It's still possible to keep firing within operational temperature for an extended period of time, albeit less accurately. If you need to deliver more pain and have the ammunition to spare, choose this.\n"
|
||||
"\n"
|
||||
"\cf2100 RPM:\c- Extremely fast, with the highest heat potential. Sustained fire in this mode may quickly trigger the weapon's safety lock should the rising heat get too close to non-operational temperature. If you want things dead fast and don't care about running out of ammo in a matter of seconds, do pick this.\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -494,6 +494,7 @@ SWWM_KBASETAB = "Library";
|
|||
SWWM_STORETAB = "Store";
|
||||
SWWM_STOREFULL = "You can't hold more of that.";
|
||||
SWWM_STOREMUNS = "You don't have enough money.";
|
||||
SWWM_STORESWAP = "You already own a weapon in the same slot: %s.";
|
||||
SWWM_NOSTORE = "(no items left to buy)";
|
||||
SWWM_NOSTORESELL = "(no items to be sold)";
|
||||
SWWM_CHATTAB = "Messages";
|
||||
|
|
|
|||
|
|
@ -667,7 +667,7 @@ TT_PLASMABLAST =
|
|||
TT_PLASMABLAST2 =
|
||||
"\cfPrimario:\c- Disparar arma derecha.\n"
|
||||
"\cfSecundario:\c- Disparar arma izquierda.\n"
|
||||
"\cfRecarga:\c- Recargar arna(s).";
|
||||
"\cfRecarga:\c- Recargar arma(s).";
|
||||
TT_PUNTZERBETA =
|
||||
"\cfPrimario:\c- Disparar arma.\n"
|
||||
"\cfSecundario:\c- Modo de disparo rápido.\n"
|
||||
|
|
@ -677,9 +677,9 @@ TT_PUNTZERGAMMA =
|
|||
"\cfSecundario:\c- Fuego super-automático.\n"
|
||||
"\cfRecarga:\c- Recargar arma.";
|
||||
TT_SHEENHMG =
|
||||
"\cfPrimario:\c- Fuego lento.\n"
|
||||
"\cfSecundario:\c- Fuego moderado.\n"
|
||||
"\cfZoom:\c- Fuego rápido.";
|
||||
"\cfPrimario:\c- Disparar arma.\n"
|
||||
"\cfSecundario:\c- Incrementar velocidad.\n"
|
||||
"\cfZoom:\c- Reducir velocidad.";
|
||||
TT_QUADRAVOL =
|
||||
"\cfPrimario:\c- Disparar arma.\n"
|
||||
"\cfSecundario:\c- Bombear arma.\n"
|
||||
|
|
@ -699,7 +699,7 @@ TT_RAYKHOM =
|
|||
"\cfZoom:\c- Usar mira.";
|
||||
TT_MORTALRIFLE =
|
||||
"\cfPrimario:\c- Disparar arma.\n"
|
||||
"\cfSecundario:\c- Disparar granada.\n"
|
||||
"\cfSecundario:\c- Disparar/recargar granada.\n"
|
||||
"\cfZoom:\c- Cambiar modo de disparo.\n"
|
||||
"\cfRecarga:\c- Recargar arma.";
|
||||
TT_RAFANKOS =
|
||||
|
|
|
|||
|
|
@ -1350,7 +1350,7 @@ SWWM_LORETXT_HEAVYMAHSHEENGUN =
|
|||
"\n"
|
||||
"\cf300 RPM:\c- Velocidad lenta. El fuego prolongado en este modo es en teoría infinito, ya que el calor producido puede ser anulado eficientemente por los sistemas de refrigeración internos, es entonces el modo recomendado para la mayoría de situaciones.\n"
|
||||
"\n"
|
||||
"\cf700 RPM:\c- Mayor velocidad, con calentamiento moderado. Aun es posible el fuego continuado en este modo, durante al menos un minuto aproximadamente desde un inicio en frío. Si necesitas repartir más dolor y tienes munición de sobra, usa esto.\n"
|
||||
"\cf700 RPM:\c- Mayor velocidad, con calentamiento moderado. El fuego prolongado sigue siendo posible dentro de la temperatura recomendada, aunque esto afectará a la puntería. Si necesitas repartir más dolor y tienes munición de sobra, usa esto.\n"
|
||||
"\n"
|
||||
"\cf2100 RPM:\c- Extremadamente rápido, con el mayor potencial de calor. El fuego prolongado en este modo puede activar rápidamente el bloqueo de seguridad del arma si el aumento de temperatura se acerca a niveles no operacionales. Si tienes prisa por matar y no te importa quedarte sin munición en pocos segundos, entonces elige esto.\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -459,6 +459,7 @@ SWWM_KBASETAB = "Biblioteca";
|
|||
SWWM_STORETAB = "Tienda";
|
||||
SWWM_STOREFULL = "No puedes llevar más de eso.";
|
||||
SWWM_STOREMUNS = "No tienes suficiente dinero.";
|
||||
SWWM_STORESWAP = "Ya posees un arma en la misma ranura: %s.";
|
||||
SWWM_NOSTORE = "(no queda nada que comprar)";
|
||||
SWWM_NOSTORESELL = "(no tienes ítems que vender)";
|
||||
SWWM_CHATTAB = "Mensajes";
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
[default]
|
||||
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r195 \cu(Fri 22 Jul 01:34:12 CEST 2022)\c-";
|
||||
SWWM_SHORTVER="\cw1.3pre r195 \cu(2022-07-22 01:34:12)\c-";
|
||||
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r197 \cu(Fri 22 Jul 20:20:58 CEST 2022)\c-";
|
||||
SWWM_SHORTVER="\cw1.3pre r197 \cu(2022-07-22 20:20:58)\c-";
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ The weapon is rated for three speeds:
|
|||
|
||||
\cf300 RPM:\c- A slow spin. Sustained fire in this mode is theoretically endless, as the heat produced can be efficiently nullified by the internal cooling systems, it is therefore the recommended mode for most situations.
|
||||
|
||||
\cf700 RPM:\c- Much faster spin, with moderate heat buildup. It's still possible to keep firing in this mode for about a minute or so from a cold start. If you need to deliver more pain and have the ammunition to spare, choose this.
|
||||
\cf700 RPM:\c- Much faster spin, with moderate heat buildup. It's still possible to keep firing within operational temperature for an extended period of time, albeit less accurately. If you need to deliver more pain and have the ammunition to spare, choose this.
|
||||
|
||||
\cf2100 RPM:\c- Extremely fast, with the highest heat potential. Sustained fire in this mode may quickly trigger the weapon's safety lock should the rising heat get too close to non-operational temperature. If you want things dead fast and don't care about running out of ammo in a matter of seconds, do pick this.
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ El arma está preparada para tres velocidades:
|
|||
|
||||
\cf300 RPM:\c- Velocidad lenta. El fuego prolongado en este modo es en teoría infinito, ya que el calor producido puede ser anulado eficientemente por los sistemas de refrigeración internos, es entonces el modo recomendado para la mayoría de situaciones.
|
||||
|
||||
\cf700 RPM:\c- Mayor velocidad, con calentamiento moderado. Aun es posible el fuego continuado en este modo, durante al menos un minuto aproximadamente desde un inicio en frío. Si necesitas repartir más dolor y tienes munición de sobra, usa esto.
|
||||
\cf700 RPM:\c- Mayor velocidad, con calentamiento moderado. El fuego prolongado sigue siendo posible dentro de la temperatura recomendada, aunque esto afectará a la puntería. Si necesitas repartir más dolor y tienes munición de sobra, usa esto.
|
||||
|
||||
\cf2100 RPM:\c- Extremadamente rápido, con el mayor potencial de calor. El fuego prolongado en este modo puede activar rápidamente el bloqueo de seguridad del arma si el aumento de temperatura se acerca a niveles no operacionales. Si tienes prisa por matar y no te importa quedarte sin munición en pocos segundos, entonces elige esto.
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ Model "SheenAmmo"
|
|||
|
||||
Model 0 "SheenBullet_d.3d"
|
||||
Skin 0 "SheenBullet.png"
|
||||
Scale 0.04 0.04 0.04
|
||||
Scale 0.025 0.025 0.025
|
||||
ZOffset 16
|
||||
PitchOffset 30
|
||||
ROTATING
|
||||
|
|
@ -83,7 +83,7 @@ Model "SheenAmmo2"
|
|||
|
||||
Model 0 "SheenBullet2_d.3d"
|
||||
Skin 0 "SheenBullet.png"
|
||||
Scale 0.04 0.04 0.04
|
||||
Scale 0.025 0.025 0.025
|
||||
ZOffset 16
|
||||
ROTATING
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ Model "SheenAmmo3"
|
|||
|
||||
Model 0 "SheenBullet3_d.3d"
|
||||
Skin 0 "SheenBullet.png"
|
||||
Scale 0.04 0.04 0.04
|
||||
Scale 0.025 0.025 0.025
|
||||
ZOffset 16
|
||||
ROTATING
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ Model "SheenSmallAmmo"
|
|||
Model 0 "SheenBullet10_d.3d"
|
||||
SurfaceSkin 0 0 "SheenBullet.png"
|
||||
SurfaceSkin 0 1 "SheenAmmoBand.png"
|
||||
Scale 0.04 0.04 0.04
|
||||
Scale 0.025 0.025 0.025
|
||||
ZOffset 16
|
||||
ROTATING
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ Model "SheenBigAmmo"
|
|||
|
||||
Model 0 "SheenBullet50_d.3d"
|
||||
Skin 0 "SheenAmmoBox.png"
|
||||
Scale 0.08 0.08 0.08
|
||||
Scale 0.05 0.05 0.05
|
||||
ZOffset 16
|
||||
ROTATING
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,86 @@
|
|||
Model "SheenTrail"
|
||||
{
|
||||
Path "models/extra"
|
||||
|
||||
Model 0 "BaseBeam_d.3d"
|
||||
Scale 1.5625 0.05 0.05
|
||||
Offset 200 0 0
|
||||
DONTCULLBACKFACES
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
|
||||
Skin 0 "dlc/SheenTracer.png"
|
||||
FrameIndex XZW1 A 0 0
|
||||
// recolors, whew
|
||||
Skin 0 "dlc/SheenTracer_White.png"
|
||||
FrameIndex XZW1 B 0 0
|
||||
Skin 0 "dlc/SheenTracer_Red.png"
|
||||
FrameIndex XZW1 C 0 0
|
||||
Skin 0 "dlc/SheenTracer_Yellow.png"
|
||||
FrameIndex XZW1 D 0 0
|
||||
Skin 0 "dlc/SheenTracer_Green.png"
|
||||
FrameIndex XZW1 E 0 0
|
||||
Skin 0 "dlc/SheenTracer_Cyan.png"
|
||||
FrameIndex XZW1 F 0 0
|
||||
Skin 0 "dlc/SheenTracer_Blue.png"
|
||||
FrameIndex XZW1 G 0 0
|
||||
Skin 0 "dlc/SheenTracer_Magenta.png"
|
||||
FrameIndex XZW1 H 0 0
|
||||
Skin 0 "dlc/SheenTracer_TransBlue.png"
|
||||
FrameIndex XZW1 I 0 0
|
||||
Skin 0 "dlc/SheenTracer_TransPink.png"
|
||||
FrameIndex XZW1 J 0 0
|
||||
}
|
||||
Model "SheenPhantom"
|
||||
{
|
||||
Path "models/extra"
|
||||
|
||||
Model 0 "BaseBeam_d.3d"
|
||||
Scale 0.1953125 0.02 0.02
|
||||
Offset 25 0 0
|
||||
DONTCULLBACKFACES
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
|
||||
Skin 0 "ChunkTrail.png"
|
||||
FrameIndex XZW1 A 0 0
|
||||
// recolors, whew
|
||||
Skin 0 "ChunkTrail_White.png"
|
||||
FrameIndex XZW1 B 0 0
|
||||
Skin 0 "ChunkTrail_Red.png"
|
||||
FrameIndex XZW1 C 0 0
|
||||
Skin 0 "ChunkTrail_Yellow.png"
|
||||
FrameIndex XZW1 D 0 0
|
||||
Skin 0 "ChunkTrail_Green.png"
|
||||
FrameIndex XZW1 E 0 0
|
||||
Skin 0 "ChunkTrail_Cyan.png"
|
||||
FrameIndex XZW1 F 0 0
|
||||
Skin 0 "ChunkTrail_Blue.png"
|
||||
FrameIndex XZW1 G 0 0
|
||||
Skin 0 "ChunkTrail_Magenta.png"
|
||||
FrameIndex XZW1 H 0 0
|
||||
Skin 0 "ChunkTrail_TransBlue.png"
|
||||
FrameIndex XZW1 I 0 0
|
||||
Skin 0 "ChunkTrail_TransPink.png"
|
||||
FrameIndex XZW1 J 0 0
|
||||
}
|
||||
|
||||
Model "SheenCasing"
|
||||
{
|
||||
Path "models"
|
||||
|
||||
Model 0 "SheenBulletCase_d.3d"
|
||||
Skin 0 "SheenBullet_Fired.png"
|
||||
Scale 0.025 0.025 0.025
|
||||
AngleOffset -90
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
ZOffset 0.5
|
||||
FrameIndex XZW1 B 0 0
|
||||
}
|
||||
|
||||
Model "HeavyMahSheenGun"
|
||||
{
|
||||
Path "models"
|
||||
|
|
@ -13,6 +96,41 @@ Model "HeavyMahSheenGun"
|
|||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
|
||||
Model "HeavyMahSheenGun"
|
||||
{
|
||||
Path "models/extra"
|
||||
|
||||
Model 2 "Flat_d.3d"
|
||||
Offset 0 -60 -15
|
||||
RollOffset 90
|
||||
AngleOffset 90
|
||||
|
||||
Scale 0.12 0.12 0.12
|
||||
Skin 2 "dlc/SheenMuz0.png"
|
||||
FrameIndex XZW0 A 2 0
|
||||
Scale 0.11 0.11 0.11
|
||||
Skin 2 "dlc/SheenMuz1.png"
|
||||
FrameIndex XZW0 B 2 0
|
||||
Scale 0.10 0.10 0.10
|
||||
Skin 2 "dlc/SheenMuz2.png"
|
||||
FrameIndex XZW0 C 2 0
|
||||
Scale 0.09 0.09 0.09
|
||||
Skin 2 "dlc/SheenMuz3.png"
|
||||
FrameIndex XZW0 D 2 0
|
||||
Scale 0.08 0.08 0.08
|
||||
Skin 2 "dlc/SheenMuz4.png"
|
||||
FrameIndex XZW0 E 2 0
|
||||
Scale 0.07 0.07 0.07
|
||||
Skin 2 "dlc/SheenMuz5.png"
|
||||
FrameIndex XZW0 F 2 0
|
||||
Scale 0.06 0.06 0.06
|
||||
Skin 2 "dlc/SheenMuz6.png"
|
||||
FrameIndex XZW0 G 2 0
|
||||
Scale 0.05 0.05 0.05
|
||||
Skin 2 "dlc/SheenMuz7.png"
|
||||
FrameIndex XZW0 H 2 0
|
||||
}
|
||||
|
||||
Model "HeavyMahSheenGun"
|
||||
{
|
||||
Path "models"
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.6 KiB |
35
shaders/glsl/SheenLED.fp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// this is a temporary gross hack
|
||||
|
||||
void SetupMaterial( inout Material mat )
|
||||
{
|
||||
mat.Base = getTexel(vTexCoord.st);
|
||||
// extract data from bytes of camtex
|
||||
vec4 ccol = texture(camtex,vec2(.5));
|
||||
int xy = int(ccol.r*255.); // low and mid digits (*F = HOT, F* = OK)
|
||||
int zw = int(ccol.g*255.); // high digit and speed (*F = blink)
|
||||
int u = int(ccol.b*255.); // width of heat bar
|
||||
int digit0 = zw&0x0F;
|
||||
int digit1 = (xy&0xF0)>>4;
|
||||
int digit2 = xy&0x0F;
|
||||
if ( digit0 != 0x0F )
|
||||
{
|
||||
vec2 tc;
|
||||
if ( digit1 == 0x0F )
|
||||
{
|
||||
// OK
|
||||
}
|
||||
else if ( digit2 == 0x0F )
|
||||
{
|
||||
// HOT
|
||||
}
|
||||
else
|
||||
{
|
||||
// digits
|
||||
tc = vec2(.125*(digit0%8),.5*(digit0/8));
|
||||
}
|
||||
}
|
||||
vec2 uv = vTexCoord.st*vec2(textureSize(tex,0));
|
||||
mat.Base *= 1.5*texture(pixtex,uv);
|
||||
mat.Normal = ApplyNormalMap(vTexCoord.st);
|
||||
mat.Bright = vec4(1.);
|
||||
}
|
||||
|
|
@ -62,7 +62,13 @@ sheen/700rpm sounds/dlc1/sheen/sheen_700rpm.ogg
|
|||
sheen/2100rpm sounds/dlc1/sheen/sheen_2100rpm.ogg
|
||||
sheen/crankin sounds/dlc1/sheen/sheen_crankin.ogg
|
||||
sheen/crankout sounds/dlc1/sheen/sheen_crankout.ogg
|
||||
// TODO overheat alarm
|
||||
sheen/overheat sounds/dlc1/sheen/sheen_overheat.ogg
|
||||
sheen/unlock sounds/dlc1/sheen/sheen_unlock.ogg
|
||||
sheen/casing1 sounds/dlc1/sheen/sheen_case1.ogg
|
||||
sheen/casing2 sounds/dlc1/sheen/sheen_case2.ogg
|
||||
sheen/casing3 sounds/dlc1/sheen/sheen_case3.ogg
|
||||
sheen/casing4 sounds/dlc1/sheen/sheen_case4.ogg
|
||||
$random sheen/casing { sheen/casing1 sheen/casing2 sheen/casing3 sheen/casing4 }
|
||||
|
||||
quadshot/select sounds/dlc1/quadshot/quad_select.ogg
|
||||
quadshot/deselect sounds/dlc1/quadshot/quad_deselect.ogg
|
||||
|
|
|
|||
BIN
sounds/dlc1/sheen/sheen_case1.ogg
Normal file
BIN
sounds/dlc1/sheen/sheen_case2.ogg
Normal file
BIN
sounds/dlc1/sheen/sheen_case3.ogg
Normal file
BIN
sounds/dlc1/sheen/sheen_case4.ogg
Normal file
BIN
sounds/dlc1/sheen/sheen_overheat.ogg
Normal file
BIN
sounds/dlc1/sheen/sheen_unlock.ogg
Normal file
|
|
@ -67,8 +67,8 @@ Class SheenAmmo : SWWMAmmo
|
|||
+FLOATBOB;
|
||||
FloatBobStrength 0.25;
|
||||
Accuracy 35;
|
||||
Radius 4;
|
||||
Height 24;
|
||||
Radius 2;
|
||||
Height 22;
|
||||
}
|
||||
States
|
||||
{
|
||||
|
|
@ -82,7 +82,7 @@ Class SheenAmmo2 : SheenAmmo
|
|||
Default
|
||||
{
|
||||
Inventory.Amount 2;
|
||||
Radius 6;
|
||||
Radius 4;
|
||||
}
|
||||
}
|
||||
Class SheenAmmo3 : SheenAmmo
|
||||
|
|
@ -90,7 +90,7 @@ Class SheenAmmo3 : SheenAmmo
|
|||
Default
|
||||
{
|
||||
Inventory.Amount 3;
|
||||
Radius 6;
|
||||
Radius 4;
|
||||
}
|
||||
}
|
||||
Class SheenSmallAmmo : SheenAmmo
|
||||
|
|
@ -98,7 +98,7 @@ Class SheenSmallAmmo : SheenAmmo
|
|||
Default
|
||||
{
|
||||
Inventory.Amount 10;
|
||||
Radius 6;
|
||||
Radius 4;
|
||||
}
|
||||
}
|
||||
Class SheenBigAmmo : SheenAmmo
|
||||
|
|
@ -106,7 +106,7 @@ Class SheenBigAmmo : SheenAmmo
|
|||
Default
|
||||
{
|
||||
Inventory.Amount 50;
|
||||
Radius 16;
|
||||
Radius 12;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
// Sheen HMG
|
||||
extend Class HeavyMahSheenGun
|
||||
{
|
||||
ui TextureID WeaponBox, BulletTex[2], SpeedTex, BarTex[4];
|
||||
ui TextureID WeaponBox, BulletTex[2], SpeedTex, BarTex;
|
||||
|
||||
override void DrawWeapon( double TicFrac, double bx, double by, double hs, Vector2 ss )
|
||||
{
|
||||
|
|
@ -11,16 +11,16 @@ extend Class HeavyMahSheenGun
|
|||
if ( !BulletTex[0] ) BulletTex[0] = TexMan.CheckForTexture("graphics/HUD/SheenRound.png",TexMan.Type_Any);
|
||||
if ( !BulletTex[1] ) BulletTex[1] = TexMan.CheckForTexture("graphics/HUD/SheenCasing.png",TexMan.Type_Any);
|
||||
if ( !SpeedTex ) SpeedTex = TexMan.CheckForTexture("graphics/HUD/SheenSpeed.png",TexMan.Type_Any);
|
||||
if ( !BarTex[0] ) BarTex[0] = TexMan.CheckForTexture("graphics/HUD/SheenBar0.png",TexMan.Type_Any);
|
||||
if ( !BarTex[1] ) BarTex[1] = TexMan.CheckForTexture("graphics/HUD/SheenBar1.png",TexMan.Type_Any);
|
||||
if ( !BarTex[2] ) BarTex[2] = TexMan.CheckForTexture("graphics/HUD/SheenBar2.png",TexMan.Type_Any);
|
||||
if ( !BarTex[3] ) BarTex[3] = TexMan.CheckForTexture("graphics/HUD/SheenBar3.png",TexMan.Type_Any);
|
||||
if ( !BarTex ) BarTex = TexMan.CheckForTexture("graphics/HUD/SheenBar.png",TexMan.Type_Any);
|
||||
Screen.DrawTexture(WeaponBox,false,bx-23,by-24,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
if ( firespeed == 0 ) for ( int i=0; i<2; i++ ) Screen.DrawTexture(SpeedTex,false,bx-21,(by-14)+i*8,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
else if ( firespeed == 1 ) for ( int i=0; i<3; i++ ) Screen.DrawTexture(SpeedTex,false,bx-21,(by-14)+i*4,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
else if ( firespeed == 2 ) for ( int i=0; i<5; i++ ) Screen.DrawTexture(SpeedTex,false,bx-21,(by-14)+i*2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
// TODO heat bar
|
||||
Screen.DrawText(NewConsoleFont,Font.CR_RED,64,64,String.Format("heat: %g\nshake: %g\nspread: %g\ntimer: %d",barrelheat,vibrate,aimerror,firetimer?((gametic-firetimer)/GameTicRate):0));
|
||||
double ht = clamp(HeatInter?HeatInter.GetValue(TicFrac):barrelheat,0.,100.);
|
||||
double hw = ht*.18;
|
||||
bool blinking = (incooldown)&&(gametic%8>=4);
|
||||
Screen.DrawTexture(BarTex,false,bx-20,by-21,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_SrcWidth,hw,DTA_DestWidthF,hw,DTA_ColorOverlay,Color(255,0,0,0));
|
||||
Screen.DrawTexture(BarTex,false,bx-21,by-22,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_SrcWidth,hw,DTA_DestWidthF,hw,DTA_ColorOverlay,blinking?Color(128,0,0,0):Color(0,0,0,0));
|
||||
bool isfired = !!fired;
|
||||
double firefact = 0.;
|
||||
if ( firespeed == 0 )
|
||||
|
|
|
|||
|
|
@ -7,37 +7,192 @@ Class HeavyMahSheenGun : SWWMWeapon
|
|||
int firespeed;
|
||||
double barrelheat, aimerror, vibrate;
|
||||
bool incooldown, stopfire, firstshot;
|
||||
int firetimer;
|
||||
int firetimer, shotcnt;
|
||||
|
||||
transient ui SmoothDynamicValueInterpolator HeatInter;
|
||||
transient SpreadSlugTracer st;
|
||||
|
||||
override void HudTick()
|
||||
{
|
||||
Super.HudTick();
|
||||
if ( !HeatInter ) HeatInter = SmoothDynamicValueInterpolator.Create(barrelheat,.5,1.,25.);
|
||||
HeatInter.Update(barrelheat);
|
||||
}
|
||||
|
||||
action void A_DropCasing()
|
||||
{
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),4*x+8*y-12*z);
|
||||
let c = Spawn("SheenCasing",origin);
|
||||
c.angle = angle;
|
||||
c.pitch = pitch;
|
||||
c.vel = x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](.5,2.)-(0,0,FRandom[Junk](2.,5.));
|
||||
c.vel += vel*.5;
|
||||
}
|
||||
|
||||
action void A_SheenFire()
|
||||
{
|
||||
double spreadfct = (1.+invoker.aimerror+(invoker.barrelheat/50.)+invoker.firespeed**2.);
|
||||
invoker.stopfire = ((invoker.Ammo1.Amount<=1)||!(player.cmd.buttons&BT_ATTACK)||(player.Health<=0));
|
||||
invoker.barrelheat = invoker.barrelheat*(1.025-invoker.firespeed*.008)+3.-(invoker.firespeed**.8)*1.35;
|
||||
invoker.aimerror = min(1.,invoker.aimerror*1.01+.01+invoker.firespeed*.01);
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x-4*z);
|
||||
SWWMHandler.DoFlash(self,Color(32,255,224,64),3);
|
||||
A_SWWMFlash();
|
||||
if ( invoker.firespeed == 1 )
|
||||
{
|
||||
A_AlertMonsters(swwm_uncapalert?0:3000);
|
||||
A_BumpFOV(.98);
|
||||
A_QuakeEx(2,2,2,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.2);
|
||||
A_StartSound("sheen/700rpm",CHAN_WEAPONEXTRA,CHANF_LOOPING,attenuation:.5);
|
||||
invoker.vibrate = .25;
|
||||
A_Overlay(-9999,"EjectRound3");
|
||||
SWWMUtility.DoKnockback(self,-x,9000.);
|
||||
SWWMUtility.AchievementProgress("dakka",(gametic-invoker.firetimer)/GameTicRate,player);
|
||||
}
|
||||
else if ( invoker.firespeed == 2 )
|
||||
{
|
||||
A_AlertMonsters(swwm_uncapalert?0:5000);
|
||||
A_BumpFOV(.99+FRandom[Sheen](-.005,.005));
|
||||
A_QuakeEx(2,2,2,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.15);
|
||||
A_StartSound("sheen/2100rpm",CHAN_WEAPONEXTRA,CHANF_LOOPING,attenuation:.4);
|
||||
invoker.vibrate = min(1.,invoker.vibrate*1.05+.05);
|
||||
SWWMUtility.DoKnockback(self,-x,15000.);
|
||||
A_Overlay(-9999,"EjectRound1");
|
||||
}
|
||||
else if ( invoker.firespeed == 0 )
|
||||
{
|
||||
A_AlertMonsters(swwm_uncapalert?0:2000);
|
||||
A_BumpFOV(.97);
|
||||
A_QuakeEx(2,2,2,8,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.25);
|
||||
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6);
|
||||
SWWMUtility.DoKnockback(self,-x,6000.);
|
||||
A_Overlay(-9999,"EjectRound7");
|
||||
}
|
||||
if ( invoker.barrelheat > 100. ) invoker.stopfire = invoker.incooldown = true;
|
||||
if ( invoker.barrelheat > 100. )
|
||||
{
|
||||
A_StartSound("sheen/overheat",CHAN_WEAPONEXTRA2,CHANF_LOOPING,attenuation:3.);
|
||||
invoker.stopfire = invoker.incooldown = true;
|
||||
}
|
||||
invoker.firstshot = true;
|
||||
if ( !sv_infiniteammo && !FindInventory('PowerInfiniteAmmo',true) )
|
||||
invoker.Ammo1.Amount--;
|
||||
invoker.fired = gametic;
|
||||
// TODO the actual firing itself
|
||||
// dakka dakka dakka
|
||||
Vector3 x2, y2, z2;
|
||||
[x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll);
|
||||
double a = FRandom[Sheen](0,360), s = FRandom[Sheen](.002,.02)*spreadfct;
|
||||
Vector3 dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
|
||||
if ( !invoker.st ) invoker.st = new("SpreadSlugTracer");
|
||||
let st = invoker.st; // thanks zscript
|
||||
st.ignoreme = self;
|
||||
st.penetration = 80.;
|
||||
st.hitlist.Clear();
|
||||
st.shootthroughlist.Clear();
|
||||
st.waterhitlist.Clear();
|
||||
st.Trace(origin,level.PointInSector(origin.xy),dir,8000.,TRACE_HitSky);
|
||||
if ( swwm_omnibust )
|
||||
{
|
||||
// Wall busting
|
||||
BusterWall.Bust(st.Results,int(st.penetration),self,st.Results.HitVector,st.Results.HitPos.z);
|
||||
}
|
||||
for ( int i=0; i<st.ShootThroughList.Size(); i++ )
|
||||
{
|
||||
st.ShootThroughList[i].Activate(self,0,SPAC_PCross);
|
||||
st.ShootThroughList[i].Activate(self,0,SPAC_Impact);
|
||||
}
|
||||
for ( int i=0; i<st.WaterHitList.Size(); i++ )
|
||||
{
|
||||
let b = Spawn("InvisibleSplasher",st.WaterHitList[i].hitpos);
|
||||
b.A_CheckTerrain();
|
||||
}
|
||||
for ( int i=5; i<st.Results.Distance; i+=10 )
|
||||
{
|
||||
if ( !Random[Boolet](0,2) ) continue;
|
||||
let b = Actor.Spawn("SWWMBubble",level.Vec3Offset(origin,dir*i));
|
||||
b.Scale *= FRandom[Boolet](.1,.3);
|
||||
}
|
||||
for ( int i=0; i<st.HitList.Size(); i++ )
|
||||
{
|
||||
int realdmg = st.HitList[i].HitDamage;
|
||||
let p = SWWMPuff.Setup(st.HitList[i].HitLocation,st.HitList[i].x,invoker,self,st.HitList[i].HitActor);
|
||||
SWWMDamageAccumulator.Accumulate(st.HitList[i].HitActor,realdmg,p,self,'shot',flags:DMG_INFLICTOR_IS_PUFF);
|
||||
SWWMUtility.DoKnockback(st.HitList[i].HitActor,st.HitList[i].x+(0,0,0.025),15000.*FRandom[Sheen](0.4,1.2));
|
||||
if ( st.HitList[i].HitActor.bNOBLOOD || st.HitList[i].HitActor.bDORMANT || st.HitList[i].HitActor.bINVULNERABLE )
|
||||
{
|
||||
let p = Spawn("SWWMBulletImpact",st.HitList[i].HitLocation);
|
||||
p.angle = atan2(st.HitList[i].x.y,st.HitList[i].x.x)+180;
|
||||
p.pitch = asin(st.HitList[i].x.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
st.HitList[i].HitActor.TraceBleed(realdmg,self);
|
||||
st.HitList[i].HitActor.SpawnBlood(st.HitList[i].HitLocation,atan2(st.HitList[i].x.y,st.HitList[i].x.x)+180,realdmg);
|
||||
st.HitList[i].HitActor.A_StartSound("spreadgun/slugf",CHAN_DAMAGE,CHANF_OVERLAP,1.,2.);
|
||||
}
|
||||
}
|
||||
if ( (st.Results.HitType != TRACE_HitNone) && (st.Results.HitType != TRACE_HasHitSky) && (st.Results.HitType != TRACE_HitActor) )
|
||||
{
|
||||
Vector3 hitnormal = -st.Results.HitVector;
|
||||
if ( st.Results.HitType == TRACE_HitFloor )
|
||||
{
|
||||
if ( st.Results.FFloor ) hitnormal = -st.Results.FFloor.top.Normal;
|
||||
else hitnormal = st.Results.HitSector.floorplane.Normal;
|
||||
}
|
||||
else if ( st.Results.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( st.Results.FFloor ) hitnormal = -st.Results.FFloor.bottom.Normal;
|
||||
else hitnormal = st.Results.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( st.Results.HitType == TRACE_HitWall )
|
||||
{
|
||||
hitnormal = (-st.Results.HitLine.delta.y,st.Results.HitLine.delta.x,0).unit();
|
||||
if ( !st.Results.Side ) hitnormal *= -1;
|
||||
}
|
||||
let p = Spawn("SWWMBulletImpact",st.Results.HitPos+hitnormal*4);
|
||||
p.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
p.pitch = asin(-hitnormal.z);
|
||||
if ( st.Results.HitType == TRACE_HitFloor ) p.CheckSplash(40);
|
||||
if ( st.Results.HitLine ) st.Results.HitLine.RemoteActivate(self,st.Results.Side,SPAC_Impact,st.Results.HitPos);
|
||||
}
|
||||
for ( int i=0; i<(5-invoker.firespeed); i++ )
|
||||
{
|
||||
let s = Spawn("SWWMSmoke",origin);
|
||||
s.scale *= .5;
|
||||
s.alpha *= .1;
|
||||
s.speed *= .7;
|
||||
s.vel += vel*.5+x*FRandom[Sheen](1.,3.);
|
||||
}
|
||||
if ( st.Results.Distance > 200. )
|
||||
{
|
||||
int trail = CVar.GetCVar('swwm_funtrails',player).GetInt();
|
||||
if ( trail == 8 ) trail = Random[Sheen](1,7);
|
||||
else if ( trail == 9 ) trail = 2+(invoker.shotcnt%6);
|
||||
else if ( trail == 10 ) switch ( invoker.shotcnt%5 )
|
||||
{
|
||||
case 0:
|
||||
case 3:
|
||||
trail = 8;
|
||||
break;
|
||||
case 1:
|
||||
case 4:
|
||||
trail = 9;
|
||||
break;
|
||||
case 2:
|
||||
trail = 1;
|
||||
break;
|
||||
}
|
||||
let t = Spawn("SheenTrail",origin);
|
||||
t.target = self;
|
||||
t.angle = atan2(dir.y,dir.x);
|
||||
t.pitch = asin(-dir.z);
|
||||
t.specialf1 = st.Results.Distance;
|
||||
t.frame = trail;
|
||||
}
|
||||
invoker.shotcnt++;
|
||||
}
|
||||
action void A_CheckContinueFire()
|
||||
{
|
||||
|
|
@ -46,11 +201,6 @@ Class HeavyMahSheenGun : SWWMWeapon
|
|||
}
|
||||
override void OwnerDied()
|
||||
{
|
||||
if ( Owner.IsActorPlayingSound(CHAN_WEAPONEXTRA) )
|
||||
{
|
||||
A_StopSound(CHAN_WEAPONEXTRA);
|
||||
A_StartSound("sheen/fire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.6,starttime:.2);
|
||||
}
|
||||
Super.OwnerDied();
|
||||
aimerror = 0.;
|
||||
vibrate = 0.;
|
||||
|
|
@ -64,21 +214,32 @@ Class HeavyMahSheenGun : SWWMWeapon
|
|||
override void DoEffect()
|
||||
{
|
||||
Super.DoEffect();
|
||||
barrelheat = max(0.,barrelheat*.99-.15);
|
||||
if ( barrelheat <= 0. ) incooldown = false;
|
||||
if ( incooldown ) barrelheat = max(0.,barrelheat*.995-.1);
|
||||
else barrelheat = max(0.,barrelheat*.99-.15);
|
||||
bool hascooled = false;
|
||||
if ( barrelheat <= 0. )
|
||||
{
|
||||
hascooled = incooldown;
|
||||
incooldown = false;
|
||||
}
|
||||
if ( !Owner || !Owner.player || (Owner.player.ReadyWeapon != self) )
|
||||
{
|
||||
aimerror = 0.;
|
||||
vibrate = 0.;
|
||||
return;
|
||||
}
|
||||
if ( hascooled )
|
||||
{
|
||||
Owner.A_StopSound(CHAN_WEAPONEXTRA2);
|
||||
Owner.A_StartSound("sheen/unlock",CHAN_WEAPONEXTRA2,CHANF_OVERLAP,attenuation:3.);
|
||||
}
|
||||
let pspm = Owner.player.FindPSprite(PSP_WEAPON);
|
||||
if ( pspm )
|
||||
{
|
||||
pspm.x = FRandom[Shivers](-1.,1.)*vibrate*4.;
|
||||
pspm.y = 32+FRandom[Shivers](-1.,1.)*vibrate*4.;
|
||||
}
|
||||
aimerror *= .95;
|
||||
aimerror *= .9;
|
||||
}
|
||||
override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount )
|
||||
{
|
||||
|
|
@ -128,7 +289,11 @@ Class HeavyMahSheenGun : SWWMWeapon
|
|||
XZW1 A -1;
|
||||
Stop;
|
||||
Select:
|
||||
XZW2 K 3 A_FullRaise();
|
||||
XZW2 K 3
|
||||
{
|
||||
A_FullRaise();
|
||||
if ( invoker.incooldown ) A_StartSound("sheen/overheat",CHAN_WEAPONEXTRA2,CHANF_LOOPING,attenuation:3.);
|
||||
}
|
||||
XZW2 LMNOP 3;
|
||||
XZW2 QRSTUV 2;
|
||||
XZW2 WX 3;
|
||||
|
|
@ -136,6 +301,7 @@ Class HeavyMahSheenGun : SWWMWeapon
|
|||
Ready:
|
||||
XZW2 A 1
|
||||
{
|
||||
invoker.shotcnt = 0;
|
||||
invoker.firetimer = gametic;
|
||||
invoker.aimerror = 0.;
|
||||
invoker.vibrate = 0.;
|
||||
|
|
@ -149,7 +315,7 @@ Class HeavyMahSheenGun : SWWMWeapon
|
|||
}
|
||||
Wait;
|
||||
Fire:
|
||||
XZW2 A 1;
|
||||
XZW2 A 2;
|
||||
XZW2 Z 1
|
||||
{
|
||||
invoker.firstshot = false;
|
||||
|
|
@ -320,29 +486,29 @@ Class HeavyMahSheenGun : SWWMWeapon
|
|||
XZW4 L 0;
|
||||
Goto VeryFastFireHold;
|
||||
EndFireFast7:
|
||||
XZW4 MNO 1 { invoker.vibrate *= .25; }
|
||||
XZW4 MNO 2 { invoker.vibrate *= .25; }
|
||||
Goto Ready;
|
||||
EndFireFast6:
|
||||
XZW4 PQR 1 { invoker.vibrate *= .25; }
|
||||
XZW4 PQR 2 { invoker.vibrate *= .25; }
|
||||
Goto Ready;
|
||||
EndFireFast5:
|
||||
XZW4 STU 1 { invoker.vibrate *= .25; }
|
||||
XZW4 STU 2 { invoker.vibrate *= .25; }
|
||||
Goto Ready;
|
||||
EndFireFast4:
|
||||
XZW4 VWX 1 { invoker.vibrate *= .25; }
|
||||
XZW4 VWX 2 { invoker.vibrate *= .25; }
|
||||
Goto Ready;
|
||||
EndFireFast3:
|
||||
XZW4 YZ 1 { invoker.vibrate *= .25; }
|
||||
XZW5 A 1 { invoker.vibrate *= .25; }
|
||||
XZW4 YZ 2 { invoker.vibrate *= .25; }
|
||||
XZW5 A 2 { invoker.vibrate *= .25; }
|
||||
Goto Ready;
|
||||
EndFireFast2:
|
||||
XZW5 BCD 1 { invoker.vibrate *= .25; }
|
||||
XZW5 BCD 2 { invoker.vibrate *= .25; }
|
||||
Goto Ready;
|
||||
EndFireFast1:
|
||||
XZW5 EFG 1 { invoker.vibrate *= .25; }
|
||||
XZW5 EFG 2 { invoker.vibrate *= .25; }
|
||||
Goto Ready;
|
||||
StopFire:
|
||||
XZW2 Z 1 A_StopSound(CHAN_WEAPONEXTRA); // just in case
|
||||
XZW2 Z 2 A_StopSound(CHAN_WEAPONEXTRA); // just in case
|
||||
Goto Ready;
|
||||
EjectRound7:
|
||||
TNT1 A 7;
|
||||
|
|
@ -351,10 +517,10 @@ Class HeavyMahSheenGun : SWWMWeapon
|
|||
TNT1 A 3;
|
||||
Goto EjectRound;
|
||||
EjectRound1:
|
||||
TNT1 A 7;
|
||||
TNT1 A 1;
|
||||
Goto EjectRound;
|
||||
EjectRound:
|
||||
TNT1 A 1; // TODO
|
||||
TNT1 A 1 A_DropCasing();
|
||||
Stop;
|
||||
AltFire:
|
||||
XZW2 A 3 A_StartSound("sheen/crankin",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
|
|
@ -403,7 +569,21 @@ Class HeavyMahSheenGun : SWWMWeapon
|
|||
Deselect:
|
||||
XZW2 A 2 A_StartSound("sheen/deselect",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW2 BCDEFGHIJK 2;
|
||||
XZW2 K -1 A_FullLower();
|
||||
XZW2 K -1
|
||||
{
|
||||
A_StopSound(CHAN_WEAPONEXTRA2);
|
||||
A_FullLower();
|
||||
}
|
||||
Stop;
|
||||
Flash:
|
||||
XZW0 A 2
|
||||
{
|
||||
let psp = player.GetPSprite(PSP_FLASH);
|
||||
psp.frame = Random[GunFlash](0,7);
|
||||
let l = Spawn("SWWMWeaponLight",pos);
|
||||
l.target = self;
|
||||
l.Args[3] -= psp.frame*5;
|
||||
}
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,108 @@
|
|||
// Sheen HMG projectiles and effects
|
||||
|
||||
Class SheenCasing : SWWMCasing
|
||||
{
|
||||
Default
|
||||
{
|
||||
BounceSound "sheen/casing";
|
||||
}
|
||||
}
|
||||
|
||||
Class SheenPhantom : Actor
|
||||
{
|
||||
Default
|
||||
{
|
||||
+NOBLOCKMAP;
|
||||
+NOGRAVITY;
|
||||
+DONTSPLASH;
|
||||
+NOTELEPORT;
|
||||
+NOINTERACTION;
|
||||
+INTERPOLATEANGLES;
|
||||
Radius .1;
|
||||
Height 0.;
|
||||
Alpha .5;
|
||||
RenderStyle "Add";
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
if ( isFrozen() ) return;
|
||||
A_FadeOut(frame?.02:.05);
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
XZW1 A -1 Bright;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class SheenTrail : Actor
|
||||
{
|
||||
Default
|
||||
{
|
||||
Obituary "$O_SHEENHMG";
|
||||
+NOBLOCKMAP;
|
||||
+NOGRAVITY;
|
||||
+DONTSPLASH;
|
||||
+NOTELEPORT;
|
||||
+NOINTERACTION;
|
||||
+INTERPOLATEANGLES;
|
||||
+FORCERADIUSDMG;
|
||||
+NODAMAGETHRUST;
|
||||
Speed 200;
|
||||
Radius .1;
|
||||
Height 0.;
|
||||
RenderStyle "Add";
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
Vector3 oldpos = pos;
|
||||
if ( isFrozen() ) return;
|
||||
if ( CurState == SpawnState )
|
||||
{
|
||||
Vector3 dir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
|
||||
Vector3 newpos = level.Vec3Offset(pos,dir*min(speed,specialf1));
|
||||
special1++;
|
||||
for ( int i=0; i<4; i++ )
|
||||
{
|
||||
let p = Spawn("SheenPhantom",level.Vec3Offset(pos,dir*(i+1)*50.));
|
||||
p.angle = angle;
|
||||
p.pitch = pitch;
|
||||
p.frame = frame;
|
||||
p.alpha *= clamp((special1+i*.25)/2.,.25,1.);
|
||||
}
|
||||
// burn the air throughout
|
||||
Vector3 tdir = level.Vec3Diff(pos,newpos);
|
||||
double dist = tdir.length();
|
||||
tdir /= dist;
|
||||
for ( int i=0; i<dist; i+=25 )
|
||||
{
|
||||
SetOrigin(level.Vec3Offset(pos,tdir*i),true);
|
||||
SWWMUtility.DoExplosion(self,min(5*special1,30),2000,50,damagetype:'Fire',ignoreme:target);
|
||||
}
|
||||
prev = oldpos; // interpolation
|
||||
SetOrigin(newpos,true);
|
||||
specialf1 -= speed;
|
||||
if ( specialf1 <= 0 ) SetStateLabel("Death");
|
||||
return;
|
||||
}
|
||||
if ( !CheckNoDelay() || (tics == -1) ) return;
|
||||
if ( tics > 0 ) tics--;
|
||||
while ( !tics )
|
||||
{
|
||||
if ( !SetState(CurState.NextState) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
XZW1 A -1 Bright;
|
||||
Stop;
|
||||
Death:
|
||||
TNT1 A 5;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -350,37 +350,6 @@ extend Class SWWMHandler
|
|||
if ( SWWMCredits.Take(players[e.Args[0]],e.Args[1]) )
|
||||
{
|
||||
let def = GetDefaultByType(item);
|
||||
SWWMWeapon sw;
|
||||
// drop the swapweapon if we own it first
|
||||
if ( swwm_swapweapons && (item is 'SWWMWeapon') && (sw = SWWMWeapon(def).HasSwapWeapon(players[e.Args[0]].mo)) )
|
||||
{
|
||||
// special case, otherwise candy gun won't drop itself
|
||||
if ( sw is 'CandyGun' ) CandyGun(sw).swapdrop = true;
|
||||
bool swapto = (sw == players[e.Args[0]].ReadyWeapon) || (sw.SisterWeapon && (sw.Sisterweapon == players[e.Args[0]].ReadyWeapon));
|
||||
int ngun = sw.Amount;
|
||||
if ( ngun == 2 )
|
||||
{
|
||||
// create a dual giver to drop
|
||||
let dg = SWWMDualWeaponGiver(Actor.Spawn("SWWMDualWeaponGiver",players[e.Args[0]].mo.pos+(0,0,10)));
|
||||
dg.angle = players[e.Args[0]].mo.angle;
|
||||
dg.VelFromAngle(5.);
|
||||
dg.vel.z += 1.;
|
||||
dg.vel += players[e.Args[0]].mo.vel;
|
||||
// transfer both guns
|
||||
dg.giveme[0] = SWWMWeapon(sw.CreateTossable(1));
|
||||
dg.giveme[0].AttachToOwner(dg);
|
||||
dg.giveme[1] = SWWMWeapon(sw.CreateTossable(1));
|
||||
dg.giveme[1].AttachToOwner(dg);
|
||||
dg.SetPickupState();
|
||||
}
|
||||
else players[e.Args[0]].mo.DropInventory(sw); // just drop it
|
||||
// don't autoswitch just yet (hacky)
|
||||
if ( swapto )
|
||||
{
|
||||
players[e.Args[0]].ReadyWeapon = null;
|
||||
players[e.Args[0]].PendingWeapon = WP_NOCHANGE;
|
||||
}
|
||||
}
|
||||
if ( (item is 'ArmorNuggetItem') || (item is 'HealthNuggetItem') )
|
||||
{
|
||||
// these have to be given in a loop because fun reasons
|
||||
|
|
|
|||
|
|
@ -598,6 +598,19 @@ Class DemolitionistMenuStoreItem : DemolitionistMenuListItem
|
|||
master.tmsgtic = Menu.MenuTime()+70;
|
||||
return;
|
||||
}
|
||||
if ( (inv is 'SWWMWeapon') && swwm_swapweapons )
|
||||
{
|
||||
// check swapweapon
|
||||
let wpn = GetDefaultByType((Class<SWWMWeapon>)(inv));
|
||||
let sw = wpn.HasSwapWeapon(players[consoleplayer].mo);
|
||||
if ( sw )
|
||||
{
|
||||
master.MenuSound("menu/noinvuse");
|
||||
master.tmsg = String.Format(StringTable.Localize("$SWWM_STORESWAP"),sw.GetTag());
|
||||
master.tmsgtic = Menu.MenuTime()+70;
|
||||
return;
|
||||
}
|
||||
}
|
||||
let cur = players[consoleplayer].mo.FindInventory(inv);
|
||||
int camt, max;
|
||||
if ( cur )
|
||||
|
|
|
|||
|
|
@ -2813,8 +2813,11 @@ Class Demolitionist : PlayerPawn
|
|||
// weapon get oneliner
|
||||
if ( (item is 'Weapon') && !(item is 'SWWMGesture') && !(item is 'SWWMItemGesture') && mystats && !mystats.GotWeapon(Weapon(item).GetClass()) && (player == players[consoleplayer]) && !ingivecheat )
|
||||
{
|
||||
if ( (item is 'HeavyMahSheenGun') && Random[DemoLines](0,2) && SWWMHandler.AddOneliner("sheenspecial",2,20) )
|
||||
if ( (item is 'HeavyMahSheenGun') && !Random[DemoLines](0,2) && SWWMHandler.AddOneliner("sheenspecial",2,20) )
|
||||
{
|
||||
A_StartSound("sheen/specialpick",CHAN_ITEM,CHANF_OVERLAP,1.,.5);
|
||||
A_StartSound("sheen/specialpick",CHAN_ITEM,CHANF_OVERLAP,1.,.5);
|
||||
}
|
||||
else if ( (item is 'SWWMWeapon') && (SWWMWeapon(item).GetLine != "") )
|
||||
{
|
||||
// fall back to generic weapon get if voicepack lacks weapon-specific lines
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ Class SWWMStats : SWWMStaticThinker
|
|||
else if ( ((inflictor is 'SaltImpact') && !inflictor.Args[0]) || ((inflictor is 'SaltBeam') && !inflictor.Args[1]) || (inflictor is 'CorrodeDebuff') || (inflictor is 'CorrosiveFlechette') || ((inflictor is 'TheBall') && !inflictor.special1) || (inflictor is 'GoldenImpact') || (inflictor is 'GoldenSubImpact') || (inflictor is 'GoldenSubSubImpact') ) which = 'Spreadgun';
|
||||
else if ( ((inflictor is 'SaltImpact') && inflictor.Args[0]) || ((inflictor is 'SaltBeam') && inflictor.Args[1]) || ((inflictor is 'TheBall') && inflictor.special1) ) which = 'Wallbuster';
|
||||
else if ( (inflictor is 'EvisceratorChunk') || (inflictor is 'EvisceratorProj') ) which = 'Eviscerator';
|
||||
else if ( inflictor is 'SheenTrail' ) which = 'HeavyMahSheenGun';
|
||||
else if ( (inflictor is 'HellblazerMissile') || (inflictor is 'HellblazerRavagerArm') || (inflictor is 'HellblazerWarheadArm') ) which = 'Hellblazer';
|
||||
else if ( (inflictor is 'BigBiospark') || (inflictor is 'BiosparkBall') || (inflictor is 'BiosparkBeamImpact') || (inflictor is 'BiosparkComboImpact') || (inflictor is 'BiosparkComboImpactSub') || (inflictor is 'BiosparkBeam') || (inflictor is 'BiosparkArc') || (inflictor is 'BiosparkCore') ) which = 'Sparkster';
|
||||
else if ( (inflictor is 'SilverAirRip') || (inflictor is 'SilverAirRip2') || (inflictor is 'SilverImpact') || (inflictor is 'FatChodeImpact') || (inflictor is 'FatChodeExplosionArm') ) which = 'SilverBullet';
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ Class SWWMWeapon : Weapon abstract
|
|||
// if the toucher owns our SwapWeapon, drop it before picking us up
|
||||
bool swapto = false;
|
||||
SWWMWeapon sw;
|
||||
if ( swwm_swapweapons && (sw = HasSwapWeapon(user)) )
|
||||
if ( swwm_swapweapons && (sw = HasSwapWeapon(user)) && (user.player.WeaponState&WF_WEAPONSWITCHOK) && !(user.player.WeaponState&WF_DISABLESWITCH) )
|
||||
{
|
||||
// special case, otherwise candy gun won't drop itself
|
||||
if ( sw is 'CandyGun' ) CandyGun(sw).swapdrop = true;
|
||||
|
|
|
|||