Spreadgun buckshot and slug implemented.
Tweaks here and there to other stuff. Refined wall jumping/climbing, also works on actors (including other players). Refined how boosting/dashing handles falling speeds. Added improved air control. It was very much needed. Added "kick" sounds to wall jumps. Add option to hear other player's voices in mp. Fix some broken localization. Fix invulnerable monsters bleeding from some attacks. Fix desync when jumping on top of another player with prediction enabled. Make moths immune to your damage, so you can stop accidentally killing them. Make normal ammo buyable in Hexen again.
This commit is contained in:
parent
66ca017300
commit
7a01fdc4e8
57 changed files with 979 additions and 115 deletions
|
|
@ -29,3 +29,6 @@ user bool swwm_healthnums = true; // show damage/healing numbers
|
|||
user bool swwm_scorenums = true; // show score numbers
|
||||
user bool swwm_scorebonus = true; // show score bonuses
|
||||
user bool swwm_fly6dof = true; // flying uses 6dof movement, toggleable for those who get motion sickness
|
||||
user bool swwm_othervoice = true; // can hear other player's voice lines in coop
|
||||
user bool swwm_shaders = true; // use pp shaders for some effects
|
||||
user bool swwm_earbuster = false; // limits loudness of wallbuster fire sounds
|
||||
64
decaldef.txt
64
decaldef.txt
|
|
@ -93,3 +93,67 @@ decal WumboScorch
|
|||
randomflipx
|
||||
randomflipy
|
||||
}
|
||||
|
||||
decal TinyBulletChip1
|
||||
{
|
||||
pic CHIP1
|
||||
translucent 0.85
|
||||
shade "00 00 00"
|
||||
x-scale 0.22
|
||||
y-scale 0.22
|
||||
randomflipx
|
||||
randomflipy
|
||||
}
|
||||
|
||||
decal TinyBulletChip2
|
||||
{
|
||||
pic CHIP2
|
||||
translucent 0.85
|
||||
shade "00 00 00"
|
||||
x-scale 0.22
|
||||
y-scale 0.22
|
||||
randomflipx
|
||||
randomflipy
|
||||
}
|
||||
|
||||
decal TinyBulletChip3
|
||||
{
|
||||
pic CHIP3
|
||||
translucent 0.85
|
||||
shade "00 00 00"
|
||||
x-scale 0.22
|
||||
y-scale 0.22
|
||||
randomflipx
|
||||
randomflipy
|
||||
}
|
||||
|
||||
decal TinyBulletChip4
|
||||
{
|
||||
pic CHIP4
|
||||
translucent 0.85
|
||||
shade "00 00 00"
|
||||
x-scale 0.22
|
||||
y-scale 0.22
|
||||
randomflipx
|
||||
randomflipy
|
||||
}
|
||||
|
||||
decal TinyBulletChip5
|
||||
{
|
||||
pic CHIP5
|
||||
translucent 0.85
|
||||
shade "00 00 00"
|
||||
x-scale 0.22
|
||||
y-scale 0.22
|
||||
randomflipx
|
||||
randomflipy
|
||||
}
|
||||
|
||||
decalgroup TinyBulletChip
|
||||
{
|
||||
TinyBulletChip1 1
|
||||
TinyBulletChip2 1
|
||||
TinyBulletChip3 1
|
||||
TinyBulletChip4 1
|
||||
TinyBulletChip5 1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
addkeysection "$SWWM_KEYS" "SWWM_GZ"
|
||||
addmenukey "$SWWM_PRIMARYFIRE" "+attack"
|
||||
addmenukey "$SWWM_SECONDARYFIRE" "+altattack"
|
||||
addmenukey "$SWWM_TERTIARYFIRE" "+reload"
|
||||
addmenukey "$SWWM_QUATERNARYFIRE" "+zoom"
|
||||
addmenukey "$SWWM_RELOADFIRE" "+reload"
|
||||
addmenukey "$SWWM_ZOOMFIREFIRE" "+zoom"
|
||||
addmenukey "$SWWM_MELEE" "+user1"
|
||||
addmenukey "$SWWM_DASH" "+user2"
|
||||
addmenukey "$SWWM_GESTURE1" "netevent swwmgesture 0"
|
||||
|
|
|
|||
32
language.txt
32
language.txt
|
|
@ -95,7 +95,7 @@ TOOLTIP_SWWM_SCORENUMS = "Show score kill numbers.";
|
|||
TOOLTIP_SWWM_SCOREBONUS = "Show additional bonus strings above score numbers (e.g.: multikill counters).";
|
||||
TOOLTIP_SWWM_EARBUSTER = "The Wallbuster's firing sounds may be painfully loud at times. This setting will limit the loudness to something more bearable.";
|
||||
TOOLTIP_SWWM_SHADERS = "Use postprocess shaders for things like powerups and the Silver Bullet scope. You can disable this if you'd prefer something lighter on the eyes.";
|
||||
TOOLTIP_SWWM_OTHERVOICE = "Allows you to hear other player's voice lines, provided you're close enough. If a player is using a voice pack you don't have, they will use the default voice.";
|
||||
TOOLTIP_SWWM_OTHERVOICE = "Allows you to hear other player's voice lines, provided you're close enough.";
|
||||
// knowledge base
|
||||
SWWM_COMINGSOON = "(coming soon)";
|
||||
SWWM_MISSTAB = "Mission";
|
||||
|
|
@ -275,7 +275,7 @@ SWWM_LORETAG_BIGSHOT = "Mr. BIG SHOT";
|
|||
SWWM_LORETAB_BIGSHOT = "People";
|
||||
SWWM_LOREREL_BIGSHOT = "Blackmann;Saya";
|
||||
SWWM_LORETXT_BIGSHOT =
|
||||
"Full Name: John \"Bigshot\" Gunns"
|
||||
"Full Name: John \"Bigshot\" Gunns\n"
|
||||
"Nationality: American\n"
|
||||
"Date Of Birth: 2110-11-12\n"
|
||||
"\n"
|
||||
|
|
@ -874,7 +874,7 @@ SWWM_LORETXT_MAIDBOT =
|
|||
"\n"
|
||||
"Summary: The first maidbot ever created by Saya, with all others being based on her. Although Maidbot works for the Miyamotos as a servant, she is also considered part of the family, and lives with them, even having her own bedroom. On the side, she's had a successful career as a J-Pop singer and idol, under the nickname of \"Meidobot\".\n"
|
||||
"\n"
|
||||
"Addendum: Maidbot was once fitted into an experimental \"combat body\" early on in order to assist the Red Oni in her mission on the US. She proved effective, but was not comfortable with the task and preferred to go back to being a normal girl afterwards.\n"
|
||||
"Addendum: Maidbot was once fitted into an experimental \"combat body\" in order to assist the Red Oni in her mission on the US. She proved effective, but was not comfortable with the task and preferred to go back to being a normal girl afterwards.\n"
|
||||
"\n"
|
||||
"Saya's Note: You know... all my maidbots, are fully equipped, hm? You know what I mean there... they're fully capable of \"loving\". Maidbot is no exception herself, and let me tell you... it feels like heaven to do things with her... ♥";
|
||||
SWWM_LORETAG_MIXOM = "Mixom";
|
||||
|
|
@ -1545,9 +1545,9 @@ T_KEYCASTLE = "\cxCastle Key\c-";
|
|||
GOTBLUECARD = "Blue Keycard";
|
||||
GOTYELWCARD = "Yellow Keycard";
|
||||
GOTREDCARD = "Red Keycard";
|
||||
GOTBLUESKULL = "Blue Skull Key";
|
||||
GOTYELWSKULL = "Yellow Skull Key";
|
||||
GOTREDSKULL = "Red Skull Key";
|
||||
GOTBLUESKUL = "Blue Skull Key";
|
||||
GOTYELWSKUL = "Yellow Skull Key";
|
||||
GOTREDSKUL = "Red Skull Key";
|
||||
// edited vanilla pickup messages
|
||||
TXT_DEFAULTPICKUPMSG = "Unidentified Item";
|
||||
// other edited messages
|
||||
|
|
@ -1648,6 +1648,7 @@ O_YNYKRON = "%o was instantly removed by %k.";
|
|||
O_YNYKRONALT = "%o was spaghettified by %k.";
|
||||
O_POUND = "%o was very impressed by %k's landing.";
|
||||
O_DASH = "%o was discombobulated by a very fast moving %k.";
|
||||
O_JUMP = "%o was stepped on %k.";
|
||||
O_MELEE = "%o was K.O.'d by %k.";
|
||||
O_MOTH = "%%o was assaulted by %s's moths.";
|
||||
O_MOTH2 = "%o was assaulted by moths.";
|
||||
|
|
@ -1700,7 +1701,7 @@ SWWM_NEXIT = "Exit";
|
|||
SWWM_SEXIT = "Secret Exit";
|
||||
// score messages
|
||||
SWWM_FINDSECRET = "\cf%s\cf found a secret. +%d\c-";
|
||||
SWWM_FINDKEY = "\cf%s\cf got the %s. +%d\c-";
|
||||
SWWM_FINDKEY = "\cf%s\cf got the %s\cf. +%d\c-";
|
||||
SWWM_LASTSECRET = "\cf%s\cf found the last secret. +%d\c-";
|
||||
SWWM_LASTITEM = "\cf%s\cf got the last item. +%d\c-";
|
||||
SWWM_LASTMONSTER = "\cf%s\cf killed the last monster. +%d\c-";
|
||||
|
|
@ -1727,7 +1728,7 @@ SWWM_INTERTIP18 = "All weapons have a quick melee attack available through a ded
|
|||
SWWM_INTERTIP19 = "With the right combination of dashing, boosting and wall jumping, it is perfectly possible to remain in the air for extended periods of time.";
|
||||
SWWM_INTERTIP20 = "In multiplayer, any keys you pick up will be immediately shared with other players.";
|
||||
SWWM_INTERTIP21 = "Aim for a high score! The more enemies you kill the better. Don't forget to put that cash to use at the in-game store when you can.";
|
||||
SWWM_INTERTIP22 = "Although chance boxes may sound like a terrible idea, there is a high chance to obtain very valuable items for a much lower cost.";
|
||||
SWWM_INTERTIP22 = "Although chance boxes may sound like a terrible idea, there is a high probability of obtaining very valuable items for a much lower cost.";
|
||||
|
||||
/* SUBTITLES */
|
||||
// voice name
|
||||
|
|
@ -2052,7 +2053,7 @@ TOOLTIP_SWWM_SCORENUMS = "Muestra números de puntuación con cada baja.";
|
|||
TOOLTIP_SWWM_SCOREBONUS = "Muestra textos de bonificación extra sobre los puntos (ej.: contadores de multikill).";
|
||||
TOOLTIP_SWWM_EARBUSTER = "Los sonidos de disparo del Wallbuster pueden a veces ser dolorosamente estridentes. Esta opción limitará la intensidad a un valor más soportable.";
|
||||
TOOLTIP_SWWM_SHADERS = "Usa shaders de postprocesado para cosas como powerups y la mira del Silver Bullet. Puedes desactivar esto si prefieres algo más ligero para la vista.";
|
||||
TOOLTIP_SWWM_OTHERVOICE = "Te permite oír los comentarios de voz de otros jugadores, si estás lo suficientemente cerca. Si un jugador está usando un pack de voz que no tienes, usarán la voz por defecto.";
|
||||
TOOLTIP_SWWM_OTHERVOICE = "Te permite oír los comentarios de voz de otros jugadores, si estás lo suficientemente cerca.";
|
||||
// knowledge base
|
||||
SWWM_COMINGSOON = "(próximamente)";
|
||||
SWWM_MISSTAB = "Misión";
|
||||
|
|
@ -2123,7 +2124,7 @@ SWWM_MISSION_DOOM =
|
|||
"\n"
|
||||
"No hemos podido proveerte de todo el equipamiento disponible, no hay tiempo. En vez de eso, vete fijando por si encuentras provisiones colocadas estratégicamente por el camino (si hay suerte los demonios no tocarán nada). Se que suena muy a videojuego, y si te oigo quejarte me puedes comer los calzones, la decisión no fue mía. Pues eso.\n"
|
||||
"\n"
|
||||
"Eres nuestra última esperanza, asi que lucha, Demo-chan, lucha por aquellos que quieres proteger, por todos nosotros... Haz que esos bastardos lo paguen.\n"
|
||||
"Eres nuestra última esperanza, así que lucha, Demo-chan, lucha por aquellos que quieres proteger, por todos nosotros... Haz que esos bastardos lo paguen.\n"
|
||||
"\n"
|
||||
" — Saya";
|
||||
SWWM_MISSION_HERETIC =
|
||||
|
|
@ -3262,9 +3263,9 @@ T_KEYCASTLE = "\cxLlave de Castillo\c-";
|
|||
GOTBLUECARD = "Tarjeta Llave Azul";
|
||||
GOTYELWCARD = "Tarjeta Llave Amarilla";
|
||||
GOTREDCARD = "Tarjeta Llave Roja";
|
||||
GOTBLUESKULL = "Calavera Llave Azul";
|
||||
GOTYELWSKULL = "Calavera Llave Amarilla";
|
||||
GOTREDSKULL = "Calavera Llave Roja";
|
||||
GOTBLUESKUL = "Calavera Llave Azul";
|
||||
GOTYELWSKUL = "Calavera Llave Amarilla";
|
||||
GOTREDSKUL = "Calavera Llave Roja";
|
||||
// edited vanilla pickup messages
|
||||
TXT_DEFAULTPICKUPMSG = "Item No Identificado";
|
||||
// other edited messages
|
||||
|
|
@ -3312,7 +3313,7 @@ FN_WOLFSS = "Votante de VOX";
|
|||
FN_DOG = "Perrete";
|
||||
FN_CHICKEN = "Gallina";
|
||||
FN_CLINK = "Rasguñitos";
|
||||
FN_DSPARIL = "Nosequé de Dos Perales";
|
||||
FN_DSPARIL = "El Brujo Ese";
|
||||
FN_HERETICIMP = "Bicho con Alas";
|
||||
FN_IRONLICH = "Risitas";
|
||||
FN_BONEKNIGHT = "Huesitos";
|
||||
|
|
@ -3357,6 +3358,7 @@ O_YNYKRON = "%o fue borrad@[ao_esp] instantáneamente por %k.";
|
|||
O_YNYKRONALT = "%o fue espaguetificad@[ao_esp] por %k.";
|
||||
O_POUND = "%o se llevó una gran impresión del aterrizaje de %k.";
|
||||
O_DASH = "%o fue descuajeringad@[ao_esp] a todo gas por %k.";
|
||||
O_JUMP = "%o fue pisotead@[ao_esp] por %k.";
|
||||
O_MELEE = "%o fue noquead@[ao_esp] por %k.";
|
||||
O_MOTH = "%%o fue asaltad@[ao_esp] por las polillas de %s.";
|
||||
O_MOTH2 = "%o fue asaltad@[ao_esp] por polillas.";
|
||||
|
|
@ -3407,7 +3409,7 @@ SWWM_NEXIT = "Salida";
|
|||
SWWM_SEXIT = "Salida Secreta";
|
||||
// score messages
|
||||
SWWM_FINDSECRET = "\cf%s\cf encontró un secreto. +%d\c-";
|
||||
SWWM_FINDKEY = "\cf%s\cf obtuvo la %s. +%d\c-";
|
||||
SWWM_FINDKEY = "\cf%s\cf obtuvo la %s\cf. +%d\c-";
|
||||
SWWM_LASTSECRET = "\cf%s\cf encontró el último secreto. +%d\c-";
|
||||
SWWM_LASTITEM = "\cf%s\cf obtuvo el último item. +%d\c-";
|
||||
SWWM_LASTMONSTER = "\cf%s\cf mató al último enemigo. +%d\c-";
|
||||
|
|
|
|||
|
|
@ -36,17 +36,20 @@ OptionMenu "SWWMOptionMenu"
|
|||
Option "$SWWM_DAMNUMS", "swwm_healthnums", "YesNo"
|
||||
Option "$SWWM_SCORENUMS", "swwm_scorenums", "YesNo"
|
||||
Option "$SWWM_SCOREBONUS", "swwm_scorebonus", "YesNo"
|
||||
Option "$SWWM_SHADERS", "swwm_shaders", "YesNo"
|
||||
StaticText " "
|
||||
StaticText "$SWWM_ITITLE", "Gold"
|
||||
Option "$SWWM_ARMORUSE", "swwm_autousearmor", "YesNo"
|
||||
Option "$SWWM_HEALTHUSE", "swwm_autousehealth", "YesNo"
|
||||
Option "$SWWM_AMMOUSE", "swwm_autouseammo", "YesNo"
|
||||
Option "$SWWM_EARBUSTER", "swwm_earbuster", "YesNo"
|
||||
StaticText " "
|
||||
StaticText "$SWWM_CTITLE", "Gold"
|
||||
Option "$SWWM_SKEYS", "swwm_sharekeys", "YesNo"
|
||||
Option "$SWWM_SVARMORUSE", "swwm_enforceautousearmor", "SWWMEnforce"
|
||||
Option "$SWWM_SVHEALTHUSE", "swwm_enforceautousehealth", "SWWMEnforce"
|
||||
Option "$SWWM_SVAMMOUSE", "swwm_enforceautouseammo", "SWWMEnforce"
|
||||
Option "$SWWM_OTHERVOICE", "swwm_othervoice", "YesNo"
|
||||
}
|
||||
OptionMenu "SWWMCreditsMenu"
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,95 @@
|
|||
Model "RedShellCasing"
|
||||
{
|
||||
Path "models"
|
||||
|
||||
Model 0 "ShotShell_d.3d"
|
||||
Skin 0 "Shell_Normal_Used.png"
|
||||
Scale 0.15 0.15 0.15
|
||||
ZOffset 1
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
Model "GreenShellCasing"
|
||||
{
|
||||
Path "models"
|
||||
|
||||
Model 0 "ShotShell_d.3d"
|
||||
Skin 0 "Shell_Slug_Used.png"
|
||||
Scale 0.15 0.15 0.15
|
||||
ZOffset 1
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
Model "WhiteShellCasing"
|
||||
{
|
||||
Path "models"
|
||||
|
||||
Model 0 "ShotShell_d.3d"
|
||||
Skin 0 "Shell_Dragon_Used.png"
|
||||
Scale 0.15 0.15 0.15
|
||||
ZOffset 1
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
Model "BlueShellCasing"
|
||||
{
|
||||
Path "models"
|
||||
|
||||
Model 0 "ShotShell_d.3d"
|
||||
Skin 0 "Shell_Kinylum_Used.png"
|
||||
Scale 0.15 0.15 0.15
|
||||
ZOffset 1
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
Model "BlackShellCasing"
|
||||
{
|
||||
Path "models"
|
||||
|
||||
Model 0 "ShotShell_d.3d"
|
||||
Skin 0 "Shell_Fuck_Used.png"
|
||||
Scale 0.15 0.15 0.15
|
||||
ZOffset 1
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
Model "PurpleShellCasing"
|
||||
{
|
||||
Path "models"
|
||||
|
||||
Model 0 "ShotShell_d.3d"
|
||||
Skin 0 "Shell_Ball_Used.png"
|
||||
Scale 0.15 0.15 0.15
|
||||
ZOffset 1
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
Model "GoldShellCasing"
|
||||
{
|
||||
Path "models"
|
||||
|
||||
Model 0 "ShotShell_d.3d"
|
||||
Skin 0 "Shell_Gold_Used.png"
|
||||
Scale 0.15 0.15 0.15
|
||||
ZOffset 1
|
||||
USEACTORPITCH
|
||||
USEACTORROLL
|
||||
|
||||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
|
||||
Model "Spreadgun"
|
||||
{
|
||||
Path "models"
|
||||
|
|
|
|||
50
sndinfo.txt
50
sndinfo.txt
|
|
@ -311,6 +311,10 @@ demolitionist/bump1 sounds/demolitionist/demobump1.ogg
|
|||
demolitionist/bump2 sounds/demolitionist/demobump2.ogg
|
||||
demolitionist/bump3 sounds/demolitionist/demobump3.ogg
|
||||
$random demolitionist/bump { demolitionist/bump1 demolitionist/bump2 demolitionist/bump3 }
|
||||
demolitionist/kick1 sounds/demolitionist/demokick1.ogg
|
||||
demolitionist/kick2 sounds/demolitionist/demokick2.ogg
|
||||
demolitionist/kick3 sounds/demolitionist/demokick3.ogg
|
||||
$random demolitionist/kick { demolitionist/kick1 demolitionist/kick2 demolitionist/kick3 }
|
||||
|
||||
$playersound demolitionist neutral *grunt DSEMPTY
|
||||
$playeralias demolitionist neutral *pain100 demolitionist/lopain
|
||||
|
|
@ -447,6 +451,52 @@ spreadgun/goldfire1 sounds/spreadgun/spread_goldfire1.ogg
|
|||
spreadgun/goldfire2 sounds/spreadgun/spread_goldfire2.ogg
|
||||
$random spreadgun/goldfire { spreadgun/goldfire1 spreadgun/goldfire2 }
|
||||
spreadgun/checkgun sounds/spreadgun/spread_idle.ogg
|
||||
spreadgun/casing1 sounds/spreadgun/spread_casing1.ogg
|
||||
spreadgun/casing2 sounds/spreadgun/spread_casing2.ogg
|
||||
spreadgun/casing3 sounds/spreadgun/spread_casing3.ogg
|
||||
spreadgun/casing4 sounds/spreadgun/spread_casing4.ogg
|
||||
spreadgun/casing5 sounds/spreadgun/spread_casing5.ogg
|
||||
spreadgun/casing6 sounds/spreadgun/spread_casing6.ogg
|
||||
$random spreadgun/casing { spreadgun/casing1 spreadgun/casing2 spreadgun/casing3 spreadgun/casing4 spreadgun/casing5 spreadgun/casing6 }
|
||||
spreadgun/gcasing1 sounds/spreadgun/spread_gcasing1.ogg
|
||||
spreadgun/gcasing2 sounds/spreadgun/spread_gcasing2.ogg
|
||||
spreadgun/gcasing3 sounds/spreadgun/spread_gcasing3.ogg
|
||||
$random spreadgun/gcasing { spreadgun/gcasing1 spreadgun/gcasing2 spreadgun/gcasing3 }
|
||||
spreadgun/pellet1 sounds/spreadgun/spread_pellet1.ogg
|
||||
spreadgun/pellet2 sounds/spreadgun/spread_pellet2.ogg
|
||||
spreadgun/pellet3 sounds/spreadgun/spread_pellet3.ogg
|
||||
spreadgun/pellet4 sounds/spreadgun/spread_pellet4.ogg
|
||||
spreadgun/pellet5 sounds/spreadgun/spread_pellet5.ogg
|
||||
spreadgun/pellet6 sounds/spreadgun/spread_pellet6.ogg
|
||||
spreadgun/pellet7 sounds/spreadgun/spread_pellet7.ogg
|
||||
spreadgun/pellet8 sounds/spreadgun/spread_pellet8.ogg
|
||||
$random spreadgun/pellet { spreadgun/pellet1 spreadgun/pellet2 spreadgun/pellet3 spreadgun/pellet4 spreadgun/pellet5 spreadgun/pellet6 spreadgun/pellet7 spreadgun/pellet8 }
|
||||
spreadgun/pelletf1 sounds/spreadgun/spread_pelletf1.ogg
|
||||
spreadgun/pelletf2 sounds/spreadgun/spread_pelletf2.ogg
|
||||
spreadgun/pelletf3 sounds/spreadgun/spread_pelletf3.ogg
|
||||
spreadgun/pelletf4 sounds/spreadgun/spread_pelletf4.ogg
|
||||
spreadgun/pelletf5 sounds/spreadgun/spread_pelletf5.ogg
|
||||
spreadgun/pelletf6 sounds/spreadgun/spread_pelletf6.ogg
|
||||
$random spreadgun/pelletf { spreadgun/pelletf1 spreadgun/pelletf2 spreadgun/pelletf3 spreadgun/pelletf4 spreadgun/pelletf5 spreadgun/pelletf6 }
|
||||
spreadgun/slug1 sounds/spreadgun/spread_slug1.ogg
|
||||
spreadgun/slug2 sounds/spreadgun/spread_slug2.ogg
|
||||
$random spreadgun/slug { spreadgun/slug1 spreadgun/slug2 }
|
||||
spreadgun/slugf1 sounds/spreadgun/spread_slugf1.ogg
|
||||
spreadgun/slugf2 sounds/spreadgun/spread_slugf2.ogg
|
||||
$random spreadgun/slugf { spreadgun/slugf1 spreadgun/slugf2 }
|
||||
spreadgun/ball1 sounds/spreadgun/spread_ball1.ogg
|
||||
spreadgun/ball2 sounds/spreadgun/spread_ball2.ogg
|
||||
spreadgun/ball3 sounds/spreadgun/spread_ball3.ogg
|
||||
$random spreadgun/ball { spreadgun/ball1 spreadgun/ball2 spreadgun/ball3 }
|
||||
spreadgun/ballf1 sounds/spreadgun/spread_ballf1.ogg
|
||||
spreadgun/ballf2 sounds/spreadgun/spread_ballf2.ogg
|
||||
spreadgun/ballf3 sounds/spreadgun/spread_ballf3.ogg
|
||||
$random spreadgun/ballf { spreadgun/ballf1 spreadgun/ballf2 spreadgun/ballf3 }
|
||||
spreadgun/salt1 sounds/spreadgun/spread_salt1.ogg
|
||||
spreadgun/salt2 sounds/spreadgun/spread_salt2.ogg
|
||||
spreadgun/salt3 sounds/spreadgun/spread_salt3.ogg
|
||||
spreadgun/salt4 sounds/spreadgun/spread_salt4.ogg
|
||||
$random spreadgun/salt { spreadgun/salt1 spreadgun/salt2 spreadgun/salt3 spreadgun/salt4 }
|
||||
|
||||
candygun/fire1 sounds/candygun/candy_fire1.ogg
|
||||
candygun/fire2 sounds/candygun/candy_fire2.ogg
|
||||
|
|
|
|||
BIN
sounds/demolitionist/demokick1.ogg
Normal file
BIN
sounds/demolitionist/demokick1.ogg
Normal file
Binary file not shown.
BIN
sounds/demolitionist/demokick2.ogg
Normal file
BIN
sounds/demolitionist/demokick2.ogg
Normal file
Binary file not shown.
BIN
sounds/demolitionist/demokick3.ogg
Normal file
BIN
sounds/demolitionist/demokick3.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_ball1.ogg
Normal file
BIN
sounds/spreadgun/spread_ball1.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_ball2.ogg
Normal file
BIN
sounds/spreadgun/spread_ball2.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_ball3.ogg
Normal file
BIN
sounds/spreadgun/spread_ball3.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_ballf1.ogg
Normal file
BIN
sounds/spreadgun/spread_ballf1.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_ballf2.ogg
Normal file
BIN
sounds/spreadgun/spread_ballf2.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_ballf3.ogg
Normal file
BIN
sounds/spreadgun/spread_ballf3.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_casing1.ogg
Normal file
BIN
sounds/spreadgun/spread_casing1.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_casing2.ogg
Normal file
BIN
sounds/spreadgun/spread_casing2.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_casing3.ogg
Normal file
BIN
sounds/spreadgun/spread_casing3.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_casing4.ogg
Normal file
BIN
sounds/spreadgun/spread_casing4.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_casing5.ogg
Normal file
BIN
sounds/spreadgun/spread_casing5.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_casing6.ogg
Normal file
BIN
sounds/spreadgun/spread_casing6.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_gcasing1.ogg
Normal file
BIN
sounds/spreadgun/spread_gcasing1.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_gcasing2.ogg
Normal file
BIN
sounds/spreadgun/spread_gcasing2.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_gcasing3.ogg
Normal file
BIN
sounds/spreadgun/spread_gcasing3.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pellet1.ogg
Normal file
BIN
sounds/spreadgun/spread_pellet1.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pellet2.ogg
Normal file
BIN
sounds/spreadgun/spread_pellet2.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pellet3.ogg
Normal file
BIN
sounds/spreadgun/spread_pellet3.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pellet4.ogg
Normal file
BIN
sounds/spreadgun/spread_pellet4.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pellet5.ogg
Normal file
BIN
sounds/spreadgun/spread_pellet5.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pellet6.ogg
Normal file
BIN
sounds/spreadgun/spread_pellet6.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pellet7.ogg
Normal file
BIN
sounds/spreadgun/spread_pellet7.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pellet8.ogg
Normal file
BIN
sounds/spreadgun/spread_pellet8.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pelletf1.ogg
Normal file
BIN
sounds/spreadgun/spread_pelletf1.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pelletf2.ogg
Normal file
BIN
sounds/spreadgun/spread_pelletf2.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pelletf3.ogg
Normal file
BIN
sounds/spreadgun/spread_pelletf3.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pelletf4.ogg
Normal file
BIN
sounds/spreadgun/spread_pelletf4.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pelletf5.ogg
Normal file
BIN
sounds/spreadgun/spread_pelletf5.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_pelletf6.ogg
Normal file
BIN
sounds/spreadgun/spread_pelletf6.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_salt1.ogg
Normal file
BIN
sounds/spreadgun/spread_salt1.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_salt2.ogg
Normal file
BIN
sounds/spreadgun/spread_salt2.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_salt3.ogg
Normal file
BIN
sounds/spreadgun/spread_salt3.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_salt4.ogg
Normal file
BIN
sounds/spreadgun/spread_salt4.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_slug1.ogg
Normal file
BIN
sounds/spreadgun/spread_slug1.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_slug2.ogg
Normal file
BIN
sounds/spreadgun/spread_slug2.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_slugf1.ogg
Normal file
BIN
sounds/spreadgun/spread_slugf1.ogg
Normal file
Binary file not shown.
BIN
sounds/spreadgun/spread_slugf2.ogg
Normal file
BIN
sounds/spreadgun/spread_slugf2.ogg
Normal file
Binary file not shown.
|
|
@ -874,7 +874,7 @@ Class FabricatorTier1 : AmmoFabricator
|
|||
Inventory.PickupMessage "$T_FABRICATOR1";
|
||||
Inventory.MaxAmount 30;
|
||||
AmmoFabricator.Budget 2000;
|
||||
AmmoFabricator.PerType 4;
|
||||
AmmoFabricator.PerType 2;
|
||||
Stamina 3000;
|
||||
}
|
||||
}
|
||||
|
|
@ -887,7 +887,7 @@ Class FabricatorTier2 : AmmoFabricator
|
|||
Inventory.PickupMessage "$T_FABRICATOR2";
|
||||
Inventory.MaxAmount 20;
|
||||
AmmoFabricator.Budget 15000;
|
||||
AmmoFabricator.PerType 8;
|
||||
AmmoFabricator.PerType 4;
|
||||
Stamina 12000;
|
||||
}
|
||||
}
|
||||
|
|
@ -900,7 +900,7 @@ Class FabricatorTier3 : AmmoFabricator
|
|||
Inventory.PickupMessage "$T_FABRICATOR3";
|
||||
Inventory.MaxAmount 10;
|
||||
AmmoFabricator.Budget 100000;
|
||||
AmmoFabricator.PerType 16;
|
||||
AmmoFabricator.PerType 8;
|
||||
Stamina 150000;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -515,6 +515,7 @@ Class SWWMOneLiner : HUDMessageBase
|
|||
|
||||
override bool Tick()
|
||||
{
|
||||
if ( players[consoleplayer].Health <= 0 ) curtime = int.min;
|
||||
curtime--;
|
||||
return (curtime<-20);
|
||||
}
|
||||
|
|
@ -818,6 +819,7 @@ Class SWWMChip : Actor
|
|||
+INTERPOLATEANGLES;
|
||||
+ROLLSPRITE;
|
||||
+ROLLCENTER;
|
||||
+FORCEXYBILLBOARD;
|
||||
BounceType "Doom";
|
||||
BounceFactor 0.3;
|
||||
Gravity 0.35;
|
||||
|
|
@ -1019,14 +1021,14 @@ Class SWWMBulletTrail : LineTracer
|
|||
t.ShootThroughList[i].Activate(target,0,SPAC_PCross);
|
||||
for ( int i=0; i<t.WaterHitList.Size(); i++ )
|
||||
{
|
||||
let b = Actor.Spawn("InvisibleSplasher",t.WaterHitList[0].hitpos);
|
||||
let b = Actor.Spawn("InvisibleSplasher",t.WaterHitList[i].hitpos);
|
||||
b.A_CheckTerrain();
|
||||
}
|
||||
for ( int i=5; i<t.Results.Distance; i+=10 )
|
||||
{
|
||||
if ( !Random[Boolet](0,bubblechance) ) continue;
|
||||
let b = Actor.Spawn(smoky?"SWWMSmallSmoke":"SWWMBubble",level.Vec3Offset(pos,dir*i));
|
||||
b.Scale *= FRandom[Boolet](0.4,0.6);
|
||||
b.Scale *= FRandom[Boolet](.4,.6);
|
||||
}
|
||||
t.Destroy();
|
||||
}
|
||||
|
|
@ -1177,7 +1179,7 @@ Class LastLine
|
|||
Class SWWMHandler : EventHandler
|
||||
{
|
||||
transient String oneliner, onelinersnd;
|
||||
transient int onelinertic, onelinerspan;
|
||||
transient int onelinertic, onelinerspan, onelinerlevel;
|
||||
transient int lastlock, lastcombat;
|
||||
transient Array<Actor> combatactors;
|
||||
transient Array<Int> combattics;
|
||||
|
|
@ -1192,25 +1194,40 @@ Class SWWMHandler : EventHandler
|
|||
|
||||
transient CVar mutevoice;
|
||||
|
||||
static int AddOneliner( String type, int delay = 5 )
|
||||
static int AddOneliner( String type, int level, int delay = 5 )
|
||||
{
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( !hnd ) return 0;
|
||||
CVar voicetype = CVar.GetCVar('swwm_voicetype',players[consoleplayer]);
|
||||
String voicetype = CVar.GetCVar('swwm_voicetype',players[consoleplayer]).GetString();
|
||||
// suppress non-rage comments when ragekit is active, only screaming allowed
|
||||
if ( players[consoleplayer].mo.FindInventory("RagekitPower") && (type != "ragekit") && (CVar.GetCVar('swwm_mutevoice',players[consoleplayer]).GetInt() < 2) ) return 0;
|
||||
if ( players[consoleplayer].mo.FindInventory("RagekitPower") && (type != "ragekit") ) return 0;
|
||||
int whichline;
|
||||
int countem = 0, i = 1;
|
||||
String testme, locme;
|
||||
do
|
||||
{
|
||||
testme = String.Format("SWWM_SUBS_%s_%s%d",voicetype.GetString().MakeUpper(),type.MakeUpper(),i);
|
||||
testme = String.Format("SWWM_SUBS_%s_%s%d",voicetype.MakeUpper(),type.MakeUpper(),i);
|
||||
locme = StringTable.Localize(testme,false);
|
||||
if ( testme != locme ) countem++;
|
||||
i++;
|
||||
}
|
||||
while ( (testme != locme) && (i < 100) ); // gotta prevent infinite loops
|
||||
if ( countem == 0 ) return 0;
|
||||
if ( countem == 0 )
|
||||
{
|
||||
if ( voicetype ~== "default" ) return 0;
|
||||
// retry with the default voicetype
|
||||
voicetype = "default";
|
||||
i = 1;
|
||||
do
|
||||
{
|
||||
testme = String.Format("SWWM_SUBS_DEFAULT_%s%d",type.MakeUpper(),i);
|
||||
locme = StringTable.Localize(testme,false);
|
||||
if ( testme != locme ) countem++;
|
||||
i++;
|
||||
}
|
||||
while ( (testme != locme) && (i < 100) ); // gotta prevent infinite loops
|
||||
if ( countem == 0 ) return 0;
|
||||
}
|
||||
// check last line so we don't repeat
|
||||
int last = 0, ent;
|
||||
for ( int i=0; i<hnd.lastlines.Size(); i++ )
|
||||
|
|
@ -1234,10 +1251,11 @@ Class SWWMHandler : EventHandler
|
|||
lst.lineno = whichline;
|
||||
hnd.lastlines.Push(lst);
|
||||
}
|
||||
hnd.oneliner = String.Format("$SWWM_SUBS_%s_%s%d",voicetype.GetString().MakeUpper(),type.MakeUpper(),whichline);
|
||||
hnd.onelinersnd = String.Format("voice/%s/%s%d",voicetype.GetString(),type,whichline);
|
||||
hnd.oneliner = String.Format("$SWWM_SUBS_%s_%s%d",voicetype.MakeUpper(),type.MakeUpper(),whichline);
|
||||
hnd.onelinersnd = String.Format("voice/%s/%s%d",voicetype,type,whichline);
|
||||
hnd.onelinertic = gametic+delay;
|
||||
hnd.onelinerspan = int(S_GetLength(hnd.onelinersnd)*Thinker.TICRATE);
|
||||
hnd.onelinerlevel = level;
|
||||
return hnd.onelinertic+hnd.onelinerspan;
|
||||
}
|
||||
|
||||
|
|
@ -1325,8 +1343,8 @@ Class SWWMHandler : EventHandler
|
|||
override void WorldLoaded( WorldEvent e )
|
||||
{
|
||||
if ( !mutevoice ) mutevoice = CVar.GetCVar('swwm_mutevoice',players[consoleplayer]);
|
||||
if ( !e.IsSaveGame && !e.IsReopen && (gamestate != GS_TITLELEVEL) && (mutevoice.GetInt() < 3) )
|
||||
AddOneliner("mapstart");
|
||||
if ( !e.IsSaveGame && !e.IsReopen && (gamestate != GS_TITLELEVEL) )
|
||||
AddOneliner("mapstart",3);
|
||||
if ( !e.IsSaveGame && !e.IsReopen )
|
||||
{
|
||||
// for skipping over merged exit lines (sharing vertices)
|
||||
|
|
@ -1467,7 +1485,11 @@ Class SWWMHandler : EventHandler
|
|||
if ( onelinertic && (onelinertic < gametic) )
|
||||
{
|
||||
if ( players[consoleplayer].health > 0 )
|
||||
players[consoleplayer].mo.A_StartSound(onelinersnd,CHAN_DEMOVOICE,CHANF_DEFAULT,1.,ATTN_NONE);
|
||||
{
|
||||
if ( onelinerlevel > mutevoice.GetInt() )
|
||||
players[consoleplayer].mo.A_StartSound(onelinersnd,CHAN_DEMOVOICE,CHANF_DEFAULT,1.,ATTN_NONE);
|
||||
SendNetworkEvent("swwmremoteliner."..onelinersnd,consoleplayer,onelinerlevel);
|
||||
}
|
||||
onelinertic = 0;
|
||||
onelinerspan = 0;
|
||||
}
|
||||
|
|
@ -1540,8 +1562,8 @@ Class SWWMHandler : EventHandler
|
|||
enteredcombat = true;
|
||||
}
|
||||
}
|
||||
if ( enteredcombat && (!highesttic || (gametic > highesttic+100)) && (mutevoice.GetInt() < 1) )
|
||||
lastcombat = AddOneliner("fightstart",10);
|
||||
if ( enteredcombat && (!highesttic || (gametic > highesttic+100)) )
|
||||
lastcombat = AddOneliner("fightstart",1,10);
|
||||
}
|
||||
|
||||
override void WorldThingDied( WorldEvent e )
|
||||
|
|
@ -1557,7 +1579,6 @@ Class SWWMHandler : EventHandler
|
|||
|
||||
override void WorldThingDamaged( WorldEvent e )
|
||||
{
|
||||
if ( !mutevoice ) mutevoice = CVar.GetCVar('swwm_mutevoice',players[consoleplayer]);
|
||||
if ( e.Damage > 0 )
|
||||
SWWMScoreObj.Spawn(-e.Damage,e.Thing.Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+e.Thing.Height/2),Font.CR_RED);
|
||||
if ( e.Thing.player )
|
||||
|
|
@ -1577,8 +1598,8 @@ Class SWWMHandler : EventHandler
|
|||
{
|
||||
if ( (e.DamageSource.bISMONSTER || e.DamageSource.player) && (e.Thing == players[consoleplayer].mo) && (e.Thing.Health > 0) )
|
||||
{
|
||||
if ( (!lastcombat || (gametic > lastcombat+20)) && (mutevoice.GetInt() < 1) )
|
||||
lastcombat = AddOneliner(e.Thing.IsFriend(e.DamageSource)?"friendhit":"gethit",15);
|
||||
if ( !lastcombat || (gametic > lastcombat+20) )
|
||||
lastcombat = AddOneliner(e.Thing.IsFriend(e.DamageSource)?"friendhit":"gethit",1,15);
|
||||
highesttic = gametic;
|
||||
}
|
||||
if ( (e.DamageSource == players[consoleplayer].mo) && (e.Thing.bISMONSTER || e.Thing.player) )
|
||||
|
|
@ -1586,8 +1607,8 @@ Class SWWMHandler : EventHandler
|
|||
// make sure it's not a moth, because otherwise they won't shut up about accidentally hurting them (it happens a lot)
|
||||
if ( e.Thing.IsFriend(e.DamageSource) && !(e.Thing is 'LampMoth') )
|
||||
{
|
||||
if ( (!lastcombat || (gametic > lastcombat+20)) && (mutevoice.GetInt() < 1) )
|
||||
lastcombat = AddOneliner("hitfriend",15);
|
||||
if ( !lastcombat || (gametic > lastcombat+20) )
|
||||
lastcombat = AddOneliner("hitfriend",1,15);
|
||||
highesttic = gametic;
|
||||
}
|
||||
}
|
||||
|
|
@ -1606,8 +1627,8 @@ Class SWWMHandler : EventHandler
|
|||
if ( e.DamageSource == players[consoleplayer].mo )
|
||||
{
|
||||
highesttic = gametic;
|
||||
if ( (!lastcombat || (gametic > lastcombat+20)) && (mutevoice.GetInt() < 1) )
|
||||
lastcombat = AddOneliner("scorekill",15);
|
||||
if ( !lastcombat || (gametic > lastcombat+20) )
|
||||
lastcombat = AddOneliner("scorekill",1,15);
|
||||
}
|
||||
if ( !e.Thing.default.bCountKill ) // no credits
|
||||
return;
|
||||
|
|
@ -1621,7 +1642,7 @@ Class SWWMHandler : EventHandler
|
|||
// scoring
|
||||
int score = min(2000,int(ceil(e.Thing.SpawnHealth()*.5)*10));
|
||||
int ofs = 0;
|
||||
if ( e.Thing.Health <= e.Thing.GetGibHealth() )
|
||||
if ( ((e.Thing.Health <= e.Thing.GetGibHealth()) || (e.DamageSource.bEXTREMEDEATH) || (e.Inflictor && e.Inflictor.bEXTREMEDEATH)) && !e.DamageSource.bNOEXTREMEDEATH && !(e.Inflictor && e.Inflictor.bNOEXTREMEDEATH) )
|
||||
{
|
||||
score = int(score*1.25);
|
||||
if ( e.DamageSource.player == players[consoleplayer] )
|
||||
|
|
@ -1640,7 +1661,7 @@ Class SWWMHandler : EventHandler
|
|||
{
|
||||
score += 10000;
|
||||
if ( e.DamageSource.player == players[consoleplayer] )
|
||||
SWWMScoreObj.Spawn(score,e.Thing.Vec3Offset(0,0,e.Thing.Height/2),Font.CR_FIRE,"$SWWM_BOSSKILL",++ofs);
|
||||
SWWMScoreObj.Spawn(0,e.Thing.Vec3Offset(0,0,e.Thing.Height/2),Font.CR_FIRE,"$SWWM_BOSSKILL",++ofs);
|
||||
}
|
||||
SWWMCredits.Give(e.DamageSource.player,score);
|
||||
if ( e.DamageSource.player == players[consoleplayer] )
|
||||
|
|
@ -1702,6 +1723,7 @@ Class SWWMHandler : EventHandler
|
|||
{
|
||||
let l = SWWMOneLiner.Make(oneliner,onelinerspan);
|
||||
StatusBar.AttachMessage(l,-3473);
|
||||
SendNetworkEvent("swwmremotelinertxt."..oneliner,consoleplayer,onelinerlevel);
|
||||
}
|
||||
for ( int i=0; i<flashes.size(); i++ )
|
||||
{
|
||||
|
|
@ -1738,8 +1760,8 @@ Class SWWMHandler : EventHandler
|
|||
if ( !locknum ) return;
|
||||
if ( e.Thing.CheckLocalView() && !e.Thing.CheckKeys(locknum,false,true) )
|
||||
{
|
||||
if ( (!lastlock || (gametic > lastlock+20)) && (mutevoice.GetInt() < 2) )
|
||||
lastlock = AddOneliner("locked");
|
||||
if ( !lastlock || (gametic > lastlock+20) )
|
||||
lastlock = AddOneliner("locked",2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2066,26 +2088,41 @@ Class SWWMHandler : EventHandler
|
|||
else if ( e.Name ~== "swwmkoraxline" )
|
||||
{
|
||||
if ( consoleplayer != e.Args[1] ) return;
|
||||
if ( CVar.GetCVar('swwm_mutevoice',players[consoleplayer]).GetInt() >= 3 ) return;
|
||||
switch ( e.Args[0] )
|
||||
{
|
||||
case 0:
|
||||
AddOneliner("koraxgreet",60);
|
||||
AddOneliner("koraxgreet",3,60);
|
||||
break;
|
||||
case 1:
|
||||
AddOneliner("koraxblood",150);
|
||||
AddOneliner("koraxblood",3,150);
|
||||
break;
|
||||
case 2:
|
||||
AddOneliner("koraxgame",120);
|
||||
AddOneliner("koraxgame",3,120);
|
||||
break;
|
||||
case 3:
|
||||
AddOneliner("koraxworship",80);
|
||||
AddOneliner("koraxworship",3,80);
|
||||
break;
|
||||
case 4:
|
||||
AddOneliner("koraxmasters",90);
|
||||
AddOneliner("koraxmasters",3,90);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( e.Name.Left(16) ~== "swwmremoteliner." )
|
||||
{
|
||||
if ( consoleplayer == e.Args[0] ) return;
|
||||
if ( !CVar.GetCVar('swwm_othervoice',players[consoleplayer]).GetBool() ) return;
|
||||
if ( CVar.GetCVar('swwm_mutevoice',players[consoleplayer]).GetInt() >= e.Args[1] ) return;
|
||||
players[e.Args[0]].mo.A_StartSound(e.Name.Mid(16),CHAN_DEMOVOICE,attenuation:.5);
|
||||
}
|
||||
else if ( e.Name.Left(19) ~== "swwmremotelinertxt." )
|
||||
{
|
||||
if ( consoleplayer == e.Args[0] ) return;
|
||||
if ( !CVar.GetCVar('swwm_othervoice',players[consoleplayer]).GetBool() ) return;
|
||||
if ( CVar.GetCVar('swwm_mutevoice',players[consoleplayer]).GetInt() >= e.Args[1] ) return;
|
||||
double dist = players[consoleplayer].Camera.Distance3D(players[e.Args[0]].mo);
|
||||
if ( dist < 2000 )
|
||||
Console.Printf("\cx%s\cx: %s\c-",players[e.Args[0]].GetUserName(),StringTable.Localize(e.Name.Mid(19)));
|
||||
}
|
||||
}
|
||||
|
||||
// stuff for hud
|
||||
|
|
|
|||
|
|
@ -269,9 +269,8 @@ Class SWWMCasing : Actor abstract
|
|||
Death:
|
||||
#### # -1
|
||||
{
|
||||
pitch = 0;
|
||||
pitch = roll = 0;
|
||||
angle = FRandom[Junk](0,360);
|
||||
roll = FRandom[Junk](0,360);
|
||||
}
|
||||
Stop;
|
||||
}
|
||||
|
|
@ -470,7 +469,7 @@ Class SWWMWeapon : Weapon abstract
|
|||
invoker.bEXTREMEDEATH = invoker.default.bEXTREMEDEATH;
|
||||
invoker.bNOEXTREMEDEATH = invoker.default.bEXTREMEDEATH;
|
||||
if ( d.HitActor.player ) d.HitActor.A_QuakeEx(2,2,2,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
|
||||
if ( !d.HitActor.bNOBLOOD )
|
||||
if ( !d.HitActor.bNOBLOOD && !d.HitActor.bINVULNERABLE )
|
||||
{
|
||||
d.HitActor.TraceBleed(dmg,invoker);
|
||||
d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg);
|
||||
|
|
@ -531,6 +530,14 @@ Class SWWMWeapon : Weapon abstract
|
|||
{
|
||||
return (AmmoType1&&(kind is AmmoType1))||(AmmoType2&&(kind is AmmoType2));
|
||||
}
|
||||
override void ModifyDropAmount( int dropamount )
|
||||
{
|
||||
Super.ModifyDropAmount(dropamount);
|
||||
if ( (AmmoGive1 <= 0) && (default.AmmoGive1 > 0) )
|
||||
AmmoGive1 = 1;
|
||||
if ( (AmmoGive2 <= 0) && (default.AmmoGive2 > 0) )
|
||||
AmmoGive2 = 1;
|
||||
}
|
||||
Default
|
||||
{
|
||||
Weapon.BobStyle "Alpha";
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ Class PusherProjectile : Actor
|
|||
{
|
||||
if ( target == lasthit ) return 0;
|
||||
lasthit = target;
|
||||
if ( target.bNOBLOOD ) A_StartSound("pusher/althit",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
if ( target.bNOBLOOD || target.bINVULNERABLE ) A_StartSound("pusher/althit",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
else A_StartSound("pusher/altmeat",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
target.A_QuakeEx(6,6,6,10,0,200,"",QF_RELATIVE|QF_SCALEDOWN,falloff:100,rollIntensity:.7);
|
||||
SWWMHandler.DoKnockback(target,vel.unit(),85000);
|
||||
|
|
@ -339,7 +339,7 @@ Class PusherWeapon : SWWMWeapon
|
|||
SWWMHandler.DoKnockback(d.HitActor,d.HitDir,8500);
|
||||
d.HitActor.A_QuakeEx(4,4,4,10,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.1);
|
||||
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'Tenderize',DMG_THRUSTLESS);
|
||||
if ( d.HitActor.bNOBLOOD )
|
||||
if ( d.HitActor.bNOBLOOD || d.HitActor.bINVULNERABLE )
|
||||
{
|
||||
let p = Spawn("PusherImpact",d.HitLocation-d.HitDir*4);
|
||||
p.angle = atan2(-d.HitDir.y,-d.HitDir.x);
|
||||
|
|
@ -421,7 +421,7 @@ Class PusherWeapon : SWWMWeapon
|
|||
SWWMHandler.DoKnockback(d.HitActor,d.HitDir,85000);
|
||||
d.HitActor.A_QuakeEx(9,9,9,15,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.1);
|
||||
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'Tenderize',DMG_THRUSTLESS);
|
||||
if ( d.HitActor.bNOBLOOD )
|
||||
if ( d.HitActor.bNOBLOOD || d.HitActor.bINVULNERABLE )
|
||||
{
|
||||
let p = Spawn("BigPusherImpact",d.HitLocation-d.HitDir*4);
|
||||
p.angle = atan2(-d.HitDir.y,-d.HitDir.x);
|
||||
|
|
|
|||
|
|
@ -504,8 +504,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
|
|||
if ( !type ) continue;
|
||||
// skip chanceboxes, since they're not yet implemented
|
||||
if ( type is 'Chancebox' ) continue;
|
||||
// no fabricators outside of hexen, otherwise no ammo
|
||||
if ( (gameinfo.gametype&GAME_Hexen) && (type is 'Ammo') ) continue;
|
||||
// no fabricators outside of hexen
|
||||
if ( !(gameinfo.gametype&GAME_Hexen) && (type is 'AmmoFabricator') ) continue;
|
||||
// skip maxed items
|
||||
let cur = players[consoleplayer].mo.FindInventory(type);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// The Demolitionist
|
||||
Class Demolitionist : PlayerPawn
|
||||
{
|
||||
int last_jump_held;
|
||||
int last_jump_held, last_boost;
|
||||
Vector3 dashdir;
|
||||
double dashfuel, dashboost;
|
||||
int dashcooldown, boostcooldown, fuelcooldown;
|
||||
|
|
@ -225,6 +225,7 @@ Class Demolitionist : PlayerPawn
|
|||
}
|
||||
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
|
||||
{
|
||||
if ( mod == 'Jump' ) return StringTable.Localize("$O_JUMP");
|
||||
if ( mod == 'Dash' ) return StringTable.Localize("$O_DASH");
|
||||
if ( mod == 'GroundPound' ) return StringTable.Localize("$O_POUND");
|
||||
return Super.GetObituary(victim,inflictor,mod,playerattack);
|
||||
|
|
@ -275,6 +276,7 @@ Class Demolitionist : PlayerPawn
|
|||
{
|
||||
A_AlertMonsters(800);
|
||||
dashboost *= (player.cmd.buttons&BT_JUMP)?.9:.4;
|
||||
last_boost = level.maptime+1;
|
||||
}
|
||||
mystats.fuelusage += dashfuel-max(0.,dashfuel-dashboost);
|
||||
dashfuel = max(0.,dashfuel-dashboost);
|
||||
|
|
@ -531,6 +533,19 @@ Class Demolitionist : PlayerPawn
|
|||
else
|
||||
{
|
||||
Super.MovePlayer();
|
||||
// override air control because we REALLY need the extra mobility
|
||||
if ( !player.onground && !bNOGRAVITY && (waterlevel < 2) )
|
||||
{
|
||||
double fs = TweakSpeeds(1.,0.);
|
||||
fs *= max(abs(player.cmd.forwardmove/12800.),abs(player.cmd.sidemove/10240.));
|
||||
if ( CanCrouch() && (player.crouchfactor != -1) ) fs *= player.crouchfactor;
|
||||
Vector3 accel = (RotateVector((player.cmd.forwardmove,-player.cmd.sidemove),angle),0);
|
||||
accel *= fs/960.;
|
||||
double spd = vel.length();
|
||||
if ( spd > 10. ) vel = (vel+accel/TICRATE).unit()*spd;
|
||||
else vel = vel+accel/TICRATE;
|
||||
player.jumptics = -2;
|
||||
}
|
||||
if ( abs(roll) > 0. ) roll += clamp(deltaangle(roll,0),-3.,3.);
|
||||
}
|
||||
guideangle *= .9;
|
||||
|
|
@ -568,7 +583,7 @@ Class Demolitionist : PlayerPawn
|
|||
player.cheats &= ~CF_REVERTPLEASE;
|
||||
player.camera = player.mo;
|
||||
}
|
||||
vel *= 0;
|
||||
vel.z += clamp(-vel.z*.4,0.,30.);
|
||||
player.jumptics = -1;
|
||||
SetStateLabel("Dash");
|
||||
A_StartSound("demolitionist/jet",CHAN_JETPACK,CHANF_LOOP);
|
||||
|
|
@ -578,8 +593,53 @@ Class Demolitionist : PlayerPawn
|
|||
override void CheckJump()
|
||||
{
|
||||
if ( InStateSequence(CurState,FindState("Dash")) ) return; // do not
|
||||
bool walljump = LineTrace(angle-180,Radius*2,0,TRF_NOSKY|TRF_THRUHITSCAN|TRF_BLOCKSELF|TRF_SOLIDACTORS,height*.2);
|
||||
bool wallclimb = LineTrace(angle,Radius*2,0,TRF_NOSKY|TRF_THRUHITSCAN|TRF_BLOCKSELF|TRF_SOLIDACTORS,height*.2);
|
||||
Vector2 walldir = (cos(angle),sin(angle));
|
||||
bool walljump = false, wallclimb = false;
|
||||
FLineTraceData d;
|
||||
Actor jumpactor = null;
|
||||
for ( int i=-4; i<int(height*.8); i++ )
|
||||
{
|
||||
if ( !wallclimb )
|
||||
{
|
||||
for ( int k=0; k<30; k+=10 )
|
||||
{
|
||||
for ( int j=-1; j<=1; j+=2 )
|
||||
{
|
||||
double ang = angle+k*j;
|
||||
wallclimb = LineTrace(ang,Radius+12,0,TRF_NOSKY|TRF_THRUHITSCAN|TRF_BLOCKSELF|TRF_SOLIDACTORS,i,data:d);
|
||||
if ( wallclimb )
|
||||
{
|
||||
jumpactor = d.HitActor;
|
||||
walldir = (walldir*.7+(cos(ang),sin(ang))*.3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( wallclimb ) break;
|
||||
}
|
||||
if ( wallclimb ) break;
|
||||
}
|
||||
if ( wallclimb ) break;
|
||||
if ( !walljump )
|
||||
{
|
||||
for ( int k=0; k<60; k+=10 )
|
||||
{
|
||||
for ( int j=-1; j<=1; j+=2 )
|
||||
{
|
||||
double ang = (angle-180)+k*j;
|
||||
walljump = LineTrace(ang,Radius+12,0,TRF_NOSKY|TRF_THRUHITSCAN|TRF_BLOCKSELF|TRF_SOLIDACTORS,i,data:d);
|
||||
if ( walljump )
|
||||
{
|
||||
jumpactor = d.HitActor;
|
||||
walldir = (walldir*.7+(cos(ang+180),sin(ang+180))*.3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( walljump ) break;
|
||||
}
|
||||
if ( walljump ) break;
|
||||
}
|
||||
if ( walljump ) break;
|
||||
}
|
||||
if ( player.cmd.buttons&BT_JUMP )
|
||||
{
|
||||
if ( player.crouchoffset ) player.crouching = 1;
|
||||
|
|
@ -590,6 +650,7 @@ Class Demolitionist : PlayerPawn
|
|||
&& ((player.onground && (player.jumptics == 0))
|
||||
|| (!player.onground && (level.maptime > last_jump_held) && (((dashfuel > 10.) && (boostcooldown <= 0)) || walljump || wallclimb))) )
|
||||
{
|
||||
if ( !player.onground && (level.maptime < last_boost+8) ) return;
|
||||
double jumpvelz = JumpZ*35./TICRATE;
|
||||
double jumpfac = 0;
|
||||
for ( let p=Inv; p; p=p.Inv )
|
||||
|
|
@ -603,21 +664,27 @@ Class Demolitionist : PlayerPawn
|
|||
}
|
||||
if ( jumpfac > 0 ) jumpvelz *= jumpfac;
|
||||
double pvelz = vel.z;
|
||||
if ( !player.onground )
|
||||
if ( !player.onground && !(player.cheats&CF_PREDICTING) )
|
||||
{
|
||||
// check for wall stuff
|
||||
if ( walljump )
|
||||
{
|
||||
vel.z = max(-abs(vel.z)*.1,vel.z);
|
||||
vel.z += jumpvelz;
|
||||
vel.xy = (cos(angle),sin(angle))*20*Speed;
|
||||
if ( vel.z < 10. )
|
||||
vel.z += jumpvelz+clamp(-pvelz*.6,0.,30.);
|
||||
vel.xy += walldir*20*Speed;
|
||||
}
|
||||
else if ( wallclimb )
|
||||
{
|
||||
vel.z = max(-abs(vel.z)*.1,vel.z);
|
||||
vel.z += jumpvelz;
|
||||
vel.xy = (cos(angle),sin(angle))*5*Speed;
|
||||
if ( vel.z < 10. )
|
||||
vel.z += jumpvelz+clamp(-pvelz*.8,0.,30.);
|
||||
vel.xy += walldir*5*Speed;
|
||||
}
|
||||
if ( jumpactor && jumpactor.bSHOOTABLE )
|
||||
{
|
||||
SWWMHandler.DoKnockback(jumpactor,(-walldir,0),12000);
|
||||
jumpactor.DamageMobj(self,self,10,'Jump');
|
||||
}
|
||||
if ( walljump || wallclimb ) A_StartSound("demolitionist/kick",CHAN_FOOTSTEP,CHANF_OVERLAP);
|
||||
}
|
||||
bOnMobj = false;
|
||||
player.jumpTics = -1;
|
||||
|
|
@ -627,16 +694,19 @@ Class Demolitionist : PlayerPawn
|
|||
{
|
||||
dashboost = 3.;
|
||||
boostcooldown = 20;
|
||||
vel.z += jumpvelz+clamp(-pvelz,0.,30.);
|
||||
if ( vel.z < 10. )
|
||||
vel.z += jumpvelz+clamp(-pvelz*.4,0.,30.);
|
||||
A_StartSound("demolitionist/jet",CHAN_JETPACK,CHANF_LOOP);
|
||||
mystats.boostcount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
dashboost = 0.;
|
||||
vel.z += jumpvelz*1.25;
|
||||
if ( vel.z < 10. )
|
||||
vel.z += jumpvelz*1.25;
|
||||
}
|
||||
SetStateLabel("Jump");
|
||||
if ( !player.onground ) last_boost = level.maptime+1;
|
||||
}
|
||||
last_jump_held = level.maptime+1;
|
||||
}
|
||||
|
|
@ -819,6 +889,7 @@ Class Demolitionist : PlayerPawn
|
|||
}
|
||||
void A_DemoScream()
|
||||
{
|
||||
A_StopSound(CHAN_DEMOVOICE);
|
||||
if ( !myvoice ) myvoice = CVar.GetCVar('swwm_voicetype',player);
|
||||
if ( !mute ) mute = CVar.GetCVar('swwm_mutevoice',player);
|
||||
A_PlayerScream();
|
||||
|
|
@ -828,7 +899,6 @@ Class Demolitionist : PlayerPawn
|
|||
override bool OnGiveSecret( bool printmsg, bool playsound )
|
||||
{
|
||||
if ( !player ) return false;
|
||||
if ( !mute ) mute = CVar.GetCVar('swwm_mutevoice',player);
|
||||
int score = 500;
|
||||
// last secret (this is called before counting it up, so have to subtract)
|
||||
if ( level.found_secrets == level.total_secrets-1 )
|
||||
|
|
@ -837,7 +907,7 @@ Class Demolitionist : PlayerPawn
|
|||
Console.Printf(StringTable.Localize("$SWWM_LASTSECRET"),player.GetUserName(),score);
|
||||
}
|
||||
else Console.Printf(StringTable.Localize("$SWWM_FINDSECRET"),player.GetUserName(),score);
|
||||
if ( CheckLocalView() && (mute.GetInt() < 2) ) SWWMHandler.AddOneliner("findsecret",40);
|
||||
if ( CheckLocalView() ) SWWMHandler.AddOneliner("findsecret",2,40);
|
||||
SWWMCredits.Give(player,score);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -847,9 +917,8 @@ Class Demolitionist : PlayerPawn
|
|||
if ( !player ) return;
|
||||
// add lore if any
|
||||
SWWMLoreLibrary.Add(player,item.GetClassName());
|
||||
if ( !mute ) mute = CVar.GetCVar('swwm_mutevoice',player);
|
||||
if ( (item is 'Weapon') && mystats && !mystats.GotWeapon(Weapon(item).GetClass()) && CheckLocalView() && (mute.GetInt() < 2) )
|
||||
SWWMHandler.AddOneliner("getweapon");
|
||||
if ( (item is 'Weapon') && mystats && !mystats.GotWeapon(Weapon(item).GetClass()) && CheckLocalView() )
|
||||
SWWMHandler.AddOneliner("getweapon",2);
|
||||
if ( (item is 'Key') && !key_reentrant )
|
||||
{
|
||||
// score
|
||||
|
|
@ -871,15 +940,14 @@ Class Demolitionist : PlayerPawn
|
|||
override bool UseInventory( Inventory item )
|
||||
{
|
||||
if ( !player ) return Super.UseInventory(item);
|
||||
if ( !mute ) mute = CVar.GetCVar('swwm_mutevoice',player);
|
||||
bool res = Super.UseInventory(item);
|
||||
if ( CheckLocalView() )
|
||||
{
|
||||
if ( !res && !(item is 'Weapon') ) A_StartSound("menu/noinvuse",CHAN_ITEM);
|
||||
if ( (item is 'PuzzleItem') && (mute.GetInt() < 2) )
|
||||
if ( item is 'PuzzleItem' )
|
||||
{
|
||||
if ( res ) SWWMHandler.AddOneliner("puzzsucc",10);
|
||||
else SWWMHandler.AddOneliner("puzzfail",20);
|
||||
if ( res ) SWWMHandler.AddOneliner("puzzsucc",2,10);
|
||||
else SWWMHandler.AddOneliner("puzzfail",2,20);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
|
@ -902,9 +970,11 @@ Class Demolitionist : PlayerPawn
|
|||
override bool Used( Actor user )
|
||||
{
|
||||
if ( !(user is 'Demolitionist') || !user.player ) return false;
|
||||
CVar othermute = CVar.GetCVar('swwm_mutevoice',user.player);
|
||||
if ( (user.player == players[consoleplayer]) && (othermute.GetInt() < 2) )
|
||||
SWWMHandler.AddOneliner("greet");
|
||||
if ( (user.player == players[consoleplayer]) && (health > 0) )
|
||||
{
|
||||
SWWMHandler.AddOneliner("greet",2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
States
|
||||
|
|
|
|||
|
|
@ -576,7 +576,7 @@ Class RagekitPower : Powerup
|
|||
Super.InitEffect();
|
||||
if ( !Owner ) return;
|
||||
if ( Owner.player == players[consoleplayer] )
|
||||
lastrage = SWWMHandler.AddOneliner("ragekit",20);
|
||||
lastrage = SWWMHandler.AddOneliner("ragekit",2,20);
|
||||
SWWMHandler.DoFlash(Owner,Color(64,255,0,0),30);
|
||||
Owner.A_QuakeEx(8,8,8,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.);
|
||||
lasteffect = int.min;
|
||||
|
|
@ -596,7 +596,7 @@ Class RagekitPower : Powerup
|
|||
{
|
||||
SWWMHandler.DoFlash(Owner,Color(16,255,0,0),5);
|
||||
if ( (Owner.player == players[consoleplayer]) && (gametic > lastrage) && (CVar.GetCVar('swwm_mutevoice',players[consoleplayer]).GetInt() < 2) )
|
||||
lastrage = SWWMHandler.AddOneliner("ragekit",5);
|
||||
lastrage = SWWMHandler.AddOneliner("ragekit",2,5);
|
||||
Owner.A_QuakeEx(2,2,2,Random[Rage](1,2),0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.5);
|
||||
}
|
||||
}
|
||||
|
|
@ -619,7 +619,7 @@ Class RagekitPower : Powerup
|
|||
SWWMHandler.DoFlash(Owner,Color(64,255,0,0),10);
|
||||
Owner.A_QuakeEx(8,8,8,Random[Rage](3,8),0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.);
|
||||
if ( (Owner.player == players[consoleplayer]) && (gametic > lastrage) )
|
||||
lastrage = SWWMHandler.AddOneliner("ragekit",5);
|
||||
lastrage = SWWMHandler.AddOneliner("ragekit",2,5);
|
||||
Owner.A_StartSound("powerup/ragekithit",CHAN_POWERUP);
|
||||
lasteffect = level.maptime;
|
||||
}
|
||||
|
|
@ -748,6 +748,12 @@ Class LampMoth : Actor
|
|||
if ( master && master.player ) SetFriendPlayer(master.player);
|
||||
else bFRIENDLY = false;
|
||||
}
|
||||
override int DamageMobj( Actor inflictor, Actor source, int damage, Name mod, int flags, double angle )
|
||||
{
|
||||
// no hurt moff
|
||||
if ( source && IsFriend(source) ) damage = 0;
|
||||
return Super.DamageMobj(inflictor,source,damage,mod,flags,angle);
|
||||
}
|
||||
bool isEntranced()
|
||||
{
|
||||
if ( !lamp )
|
||||
|
|
@ -880,7 +886,7 @@ Class LampMoth : Actor
|
|||
A_FaceTarget(0,0);
|
||||
lifespan -= 5;
|
||||
Vector3 awaydir = level.Vec3Diff(target.Vec3Offset(0,0,target.height),pos).unit();
|
||||
vel += awaydir*32.;
|
||||
vel += awaydir*8.;
|
||||
int dmg = target.DamageMobj(self,self,GetMissileDamage(0,0),'Melee',Random[Moth](0,8)?DMG_NO_PAIN:0);
|
||||
if ( !target.bNOBLOOD )
|
||||
{
|
||||
|
|
@ -1003,6 +1009,7 @@ Class CompanionLamp : Actor
|
|||
{
|
||||
Vector3 Trail;
|
||||
Array<LampMoth> moff;
|
||||
Actor parent;
|
||||
|
||||
Default
|
||||
{
|
||||
|
|
@ -1046,7 +1053,7 @@ Class CompanionLamp : Actor
|
|||
}
|
||||
let s = Spawn("SWWMSmallSmoke",m.pos);
|
||||
s.alpha *= .3;
|
||||
m.master = target;
|
||||
m.master = parent;
|
||||
m.lamp = self;
|
||||
m.trail = m.pos;
|
||||
moff.Push(m);
|
||||
|
|
@ -1054,7 +1061,7 @@ Class CompanionLamp : Actor
|
|||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
if ( !target || !SWWMLamp(master) )
|
||||
if ( !parent || !SWWMLamp(master) )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
|
|
@ -1080,7 +1087,7 @@ Class CompanionLamp : Actor
|
|||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
if ( !target || !SWWMLamp(master) )
|
||||
if ( !parent || !SWWMLamp(master) )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
|
|
@ -1092,8 +1099,8 @@ Class CompanionLamp : Actor
|
|||
{
|
||||
for ( int j=1; j>=-1; j-=2 )
|
||||
{
|
||||
double ang = (target.angle-180)+i*j;
|
||||
Vector3 testpos = level.Vec3Offset(target.pos,(cos(ang)*32,sin(ang)*32,target.height-8+1.5*sin(level.maptime*3.)));
|
||||
double ang = (parent.angle-180)+i*j;
|
||||
Vector3 testpos = level.Vec3Offset(parent.pos,(cos(ang)*32,sin(ang)*32,parent.height-8+1.5*sin(level.maptime*3.)));
|
||||
if ( !level.IsPointInLevel(testpos) ) continue;
|
||||
Vector3 oldpos = pos;
|
||||
Vector3 oldprev = prev;
|
||||
|
|
@ -1123,19 +1130,19 @@ Class CompanionLamp : Actor
|
|||
// check at most for a 45 degree offset
|
||||
if ( foundspot && (i > 45) ) break;
|
||||
}
|
||||
Vector3 diff = level.Vec3Diff(pos,target.pos);
|
||||
Vector3 diff = level.Vec3Diff(pos,parent.pos);
|
||||
if ( diff.length() > 400 )
|
||||
{
|
||||
Actor f = Spawn("SWWMItemFog",pos);
|
||||
f.A_StartSound("lamp/disappear",CHAN_VOICE);
|
||||
SetOrigin(trail,false);
|
||||
angle = AngleTo(target);
|
||||
angle = AngleTo(parent);
|
||||
vel *= 0.;
|
||||
f = Spawn("SWWMItemFog",pos);
|
||||
f.A_StartSound("lamp/appear",CHAN_VOICE);
|
||||
return;
|
||||
}
|
||||
angle += Clamp(deltaangle(angle,AngleTo(target)),-5.,5.);
|
||||
angle += Clamp(deltaangle(angle,AngleTo(parent)),-5.,5.);
|
||||
vel *= .8;
|
||||
bool blocked = false;
|
||||
if ( BlockingLine && BlockingLineIsBlocking() )
|
||||
|
|
@ -1174,7 +1181,7 @@ Class CompanionLamp : Actor
|
|||
vel += 4.*normal;
|
||||
blocked = true;
|
||||
}
|
||||
if ( (diff.x > -16) && (diff.x < 16) && (diff.y > -16) && (diff.y < 16) && (diff.z > -16) && (diff.z < target.height+8) )
|
||||
if ( (diff.x > -16) && (diff.x < 16) && (diff.y > -16) && (diff.y < 16) && (diff.z > -16) && (diff.z < parent.height+8) )
|
||||
{
|
||||
if ( diff.x < 0 ) vel.x -= .2;
|
||||
else vel.x += .2;
|
||||
|
|
@ -1277,7 +1284,7 @@ Class SWWMLamp : Inventory
|
|||
if ( !thelamp )
|
||||
{
|
||||
thelamp = Spawn("CompanionLamp",Owner.Vec3Offset(cos(Owner.angle)*20,sin(Owner.angle)*20,24));
|
||||
thelamp.target = Owner;
|
||||
CompanionLamp(thelamp).parent = Owner;
|
||||
thelamp.master = self;
|
||||
let f = Spawn("SWWMItemFog",thelamp.pos);
|
||||
f.A_StartSound("lamp/appear",CHAN_VOICE);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,303 @@
|
|||
// Blackmann "Rhino Stopper" Spreadgun (from Instant Action 3, also planned for Zanaveth Ultra Suite 2)
|
||||
// Slot 3, replaces Shotgun, Ethereal Crossbow, Serpent Staff
|
||||
|
||||
Class RedShellCasing : SWWMCasing
|
||||
{
|
||||
Default
|
||||
{
|
||||
BounceSound "spreadgun/casing";
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
heat = 0;
|
||||
}
|
||||
}
|
||||
Class GreenShellCasing : RedShellCasing {}
|
||||
Class WhiteShellCasing : RedShellCasing {}
|
||||
Class BlueShellCasing : RedShellCasing {}
|
||||
Class BlackShellCasing : RedShellCasing {}
|
||||
Class PurpleShellCasing : RedShellCasing {}
|
||||
Class GoldShellCasing : RedShellCasing
|
||||
{
|
||||
Default
|
||||
{
|
||||
BounceSound "spreadgun/gcasing";
|
||||
}
|
||||
}
|
||||
|
||||
Class SWWMDamageAccumulator : Thinker
|
||||
{
|
||||
Actor victim, inflictor, source;
|
||||
Array<Int> amounts;
|
||||
int total;
|
||||
Name type;
|
||||
bool dontgib;
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
// so many damn safeguards in this
|
||||
if ( !victim )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
int gibhealth = victim.GetGibHealth();
|
||||
// おまえはもう死んでいる
|
||||
if ( (victim.health-total <= gibhealth) && !dontgib )
|
||||
{
|
||||
// safeguard for inflictors that have somehow ceased to exist, which apparently STILL CAN HAPPEN
|
||||
if ( inflictor ) inflictor.bEXTREMEDEATH = true;
|
||||
else type = 'Extreme';
|
||||
}
|
||||
// make sure accumulation isn't reentrant
|
||||
// 何?
|
||||
for ( int i=0; i<amounts.Size(); i++ )
|
||||
{
|
||||
if ( !victim ) break;
|
||||
victim.DamageMobj(inflictor,source,amounts[i],type,DMG_THRUSTLESS);
|
||||
}
|
||||
// clean up
|
||||
if ( inflictor ) inflictor.bEXTREMEDEATH = false;
|
||||
Destroy();
|
||||
}
|
||||
|
||||
static void Accumulate( Actor victim, int amount, Actor inflictor, Actor source, Name type, bool dontgib = false )
|
||||
{
|
||||
if ( !victim ) return;
|
||||
let ti = ThinkerIterator.Create("SWWMDamageAccumulator",STAT_USER);
|
||||
SWWMDamageAccumulator a, match = null;
|
||||
while ( a = SWWMDamageAccumulator(ti.Next()) )
|
||||
{
|
||||
if ( a.victim != victim ) continue;
|
||||
match = a;
|
||||
break;
|
||||
}
|
||||
if ( !match )
|
||||
{
|
||||
match = new("SWWMDamageAccumulator");
|
||||
match.ChangeStatNum(STAT_USER);
|
||||
match.victim = victim;
|
||||
match.amounts.Clear();
|
||||
}
|
||||
match.amounts.Push(amount);
|
||||
match.total += amount;
|
||||
match.inflictor = inflictor;
|
||||
match.source = source;
|
||||
match.type = type;
|
||||
match.dontgib = dontgib;
|
||||
}
|
||||
|
||||
static clearscope int GetAmount( Actor victim )
|
||||
{
|
||||
let ti = ThinkerIterator.Create("SWWMDamageAccumulator",STAT_USER);
|
||||
SWWMDamageAccumulator a, match = null;
|
||||
while ( a = SWWMDamageAccumulator(ti.Next()) )
|
||||
{
|
||||
if ( a.victim != victim ) continue;
|
||||
return a.total;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Class SpreadgunTracer : LineTracer
|
||||
{
|
||||
Actor ignoreme;
|
||||
Array<HitListEntry> hitlist;
|
||||
Array<Line> shootthroughlist;
|
||||
Array<WaterHit> waterhitlist;
|
||||
|
||||
override ETraceStatus TraceCallback()
|
||||
{
|
||||
// liquid splashes
|
||||
if ( Results.CrossedWater )
|
||||
{
|
||||
let hl = new("WaterHit");
|
||||
hl.sect = Results.CrossedWater;
|
||||
hl.hitpos = Results.CrossedWaterPos;
|
||||
WaterHitList.Push(hl);
|
||||
}
|
||||
else if ( Results.Crossed3DWater )
|
||||
{
|
||||
let hl = new("WaterHit");
|
||||
hl.sect = Results.Crossed3DWater;
|
||||
hl.hitpos = Results.Crossed3DWaterPos;
|
||||
WaterHitList.Push(hl);
|
||||
}
|
||||
if ( Results.HitType == TRACE_HitActor )
|
||||
{
|
||||
if ( Results.HitActor == ignoreme ) return TRACE_Skip;
|
||||
if ( Results.HitActor.bSHOOTABLE )
|
||||
{
|
||||
int amt = SWWMDamageAccumulator.GetAmount(Results.HitActor);
|
||||
// getgibhealth isn't clearscope, fuck
|
||||
int gibhealth = -int(Results.HitActor.GetSpawnHealth()*gameinfo.gibfactor);
|
||||
if ( Results.HitActor.GibHealth != int.min ) gibhealth = -abs(Results.HitActor.GibHealth);
|
||||
// if gibbed, go through without dealing more damage
|
||||
if ( Results.HitActor.health-amt <= gibhealth ) return TRACE_Skip;
|
||||
let ent = new("HitListEntry");
|
||||
ent.hitactor = Results.HitActor;
|
||||
ent.hitlocation = Results.HitPos;
|
||||
ent.x = Results.HitVector;
|
||||
hitlist.Push(ent);
|
||||
// go right on through if dead
|
||||
if ( Results.HitActor.health-amt <= 0 ) return TRACE_Skip;
|
||||
// stap
|
||||
return TRACE_Abort;
|
||||
}
|
||||
return TRACE_Skip;
|
||||
}
|
||||
else if ( (Results.HitType == TRACE_HitWall) && (Results.Tier == TIER_Middle) )
|
||||
{
|
||||
if ( !Results.HitLine.sidedef[1] || (Results.HitLine.Flags&(Line.ML_BlockHitscan|Line.ML_BlockEverything)) )
|
||||
return TRACE_Stop;
|
||||
ShootThroughList.Push(Results.HitLine);
|
||||
return TRACE_Skip;
|
||||
}
|
||||
return TRACE_Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class SpreadSlugTracer : SpreadgunTracer
|
||||
{
|
||||
double penetration; // please don't laugh
|
||||
|
||||
override ETraceStatus TraceCallback()
|
||||
{
|
||||
// liquid splashes
|
||||
if ( Results.CrossedWater )
|
||||
{
|
||||
let hl = new("WaterHit");
|
||||
hl.sect = Results.CrossedWater;
|
||||
hl.hitpos = Results.CrossedWaterPos;
|
||||
WaterHitList.Push(hl);
|
||||
}
|
||||
else if ( Results.Crossed3DWater )
|
||||
{
|
||||
let hl = new("WaterHit");
|
||||
hl.sect = Results.Crossed3DWater;
|
||||
hl.hitpos = Results.Crossed3DWaterPos;
|
||||
WaterHitList.Push(hl);
|
||||
}
|
||||
if ( Results.HitType == TRACE_HitActor )
|
||||
{
|
||||
if ( Results.HitActor == ignoreme ) return TRACE_Skip;
|
||||
if ( Results.HitActor.bSHOOTABLE )
|
||||
{
|
||||
let ent = new("HitListEntry");
|
||||
ent.hitactor = Results.HitActor;
|
||||
ent.hitlocation = Results.HitPos;
|
||||
ent.x = Results.HitVector;
|
||||
ent.hitdamage = min(Results.HitActor.health+int(Results.HitActor.GetSpawnHealth()*gameinfo.gibfactor),int(penetration));
|
||||
hitlist.Push(ent);
|
||||
penetration = max(0,penetration-ent.hitdamage);
|
||||
if ( penetration <= 0 ) return TRACE_Abort;
|
||||
return TRACE_Skip;
|
||||
}
|
||||
return TRACE_Skip;
|
||||
}
|
||||
else if ( (Results.HitType == TRACE_HitWall) && (Results.Tier == TIER_Middle) )
|
||||
{
|
||||
if ( !Results.HitLine.sidedef[1] || (Results.HitLine.Flags&(Line.ML_BlockHitscan|Line.ML_BlockEverything)) )
|
||||
return TRACE_Stop;
|
||||
ShootThroughList.Push(Results.HitLine);
|
||||
return TRACE_Skip;
|
||||
}
|
||||
return TRACE_Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class SpreadImpact : Actor
|
||||
{
|
||||
Default
|
||||
{
|
||||
Radius 0.1;
|
||||
Height 0;
|
||||
+NOGRAVITY;
|
||||
+NOCLIP;
|
||||
+DONTSPLASH;
|
||||
+NOTELEPORT;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
A_StartSound("spreadgun/pellet",CHAN_VOICE,CHANF_DEFAULT,.4,4.);
|
||||
A_SprayDecal("TinyBulletChip",-20);
|
||||
int numpt = Random[Spreadgun](-2,2);
|
||||
Vector3 x = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (-x+(FRandom[Spreadgun](-.8,.8),FRandom[Spreadgun](-.8,.8),FRandom[Spreadgun](-.8,.8))).unit()*FRandom[Spreadgun](.1,1.2);
|
||||
let s = Spawn("SWWMSmoke",pos);
|
||||
s.vel = pvel;
|
||||
s.scale *= .6;
|
||||
s.special1 = Random[Spreadgun](0,1);
|
||||
s.SetShade(Color(1,1,1)*Random[Spreadgun](96,192));
|
||||
}
|
||||
numpt = Random[Spreadgun](-3,3);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[Spreadgun](-1,1),FRandom[Spreadgun](-1,1),FRandom[Spreadgun](-1,1)).unit()*FRandom[Spreadgun](2,8);
|
||||
let s = Spawn("SWWMSpark",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
numpt = Random[Spreadgun](-2,2);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[Spreadgun](-1,1),FRandom[Spreadgun](-1,1),FRandom[Spreadgun](-1,1)).unit()*FRandom[Spreadgun](2,8);
|
||||
let s = Spawn("SWWMChip",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
Class SlugImpact : Actor
|
||||
{
|
||||
Default
|
||||
{
|
||||
Radius 0.1;
|
||||
Height 0;
|
||||
+NOGRAVITY;
|
||||
+NOCLIP;
|
||||
+DONTSPLASH;
|
||||
+NOTELEPORT;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
A_StartSound("spreadgun/slug",CHAN_VOICE,CHANF_DEFAULT,1.,2.);
|
||||
A_SprayDecal("BulletChip",-20);
|
||||
int numpt = Random[Spreadgun](6,12);
|
||||
Vector3 x = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (-x+(FRandom[Spreadgun](-.8,.8),FRandom[Spreadgun](-.8,.8),FRandom[Spreadgun](-.8,.8))).unit()*FRandom[Spreadgun](.1,1.2);
|
||||
let s = Spawn("SWWMSmoke",pos);
|
||||
s.vel = pvel;
|
||||
s.special1 = Random[Spreadgun](0,2);
|
||||
s.SetShade(Color(1,1,1)*Random[Spreadgun](96,192));
|
||||
}
|
||||
numpt = Random[Spreadgun](4,8);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[Spreadgun](-1,1),FRandom[Spreadgun](-1,1),FRandom[Spreadgun](-1,1)).unit()*FRandom[Spreadgun](2,8);
|
||||
let s = Spawn("SWWMSpark",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
numpt = Random[Spreadgun](10,15);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[Spreadgun](-1,1),FRandom[Spreadgun](-1,1),FRandom[Spreadgun](-1,1)).unit()*FRandom[Spreadgun](2,8);
|
||||
let s = Spawn("SWWMChip",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
Class Spreadgun : SWWMWeapon
|
||||
{
|
||||
bool fired; // shell was used
|
||||
|
|
@ -9,6 +306,18 @@ Class Spreadgun : SWWMWeapon
|
|||
transient ui TextureID WeaponBox, AmmoIcon[7], LoadedIcon[7];
|
||||
transient ui Font TewiFont;
|
||||
|
||||
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
|
||||
{
|
||||
if ( loadammo is 'RedShell' ) return StringTable.Localize("$O_SPREADGUN_RED");
|
||||
if ( loadammo is 'GreenShell' ) return StringTable.Localize("$O_SPREADGUN_GREEN");
|
||||
if ( loadammo is 'WhiteShell' ) return StringTable.Localize("$O_SPREADGUN_WHITE");
|
||||
if ( loadammo is 'BlueShell' ) return StringTable.Localize("$O_SPREADGUN_BLUE");
|
||||
if ( loadammo is 'BlackShell' ) return StringTable.Localize("$O_SPREADGUN_BLACK");
|
||||
if ( loadammo is 'PurpleShell' ) return StringTable.Localize("$O_SPREADGUN_PURPLE");
|
||||
if ( loadammo is 'GoldShell' ) return StringTable.Localize("$O_SPREADGUN_GOLD");
|
||||
return Super.GetObituary(victim,inflictor,mod,playerattack);
|
||||
}
|
||||
|
||||
override void DrawWeapon( double TicFrac, double bx, double by, Vector2 hs, Vector2 ss )
|
||||
{
|
||||
static const Class<Ammo> types[] = {"RedShell","GreenShell","WhiteShell","BlueShell","BlackShell","PurpleShell","GoldShell"};
|
||||
|
|
@ -122,6 +431,7 @@ Class Spreadgun : SWWMWeapon
|
|||
action void A_DropShell()
|
||||
{
|
||||
static const Class<Ammo> types[] = {"RedShell","GreenShell","WhiteShell","BlueShell","BlackShell","PurpleShell","GoldShell"};
|
||||
static const Class<Actor> casetypes[] = {"RedShellCasing","GreenShellCasing","WhiteShellCasing","BlueShellCasing","BlackShellCasing","PurpleShellCasing","GoldShellCasing"};
|
||||
if ( !invoker.fired )
|
||||
{
|
||||
for ( int i=0; i<7; i++ )
|
||||
|
|
@ -131,7 +441,81 @@ Class Spreadgun : SWWMWeapon
|
|||
break;
|
||||
}
|
||||
}
|
||||
else Console.Printf("// TODO drop spent shell");
|
||||
else
|
||||
{
|
||||
for ( int i=0; i<7; i++ )
|
||||
{
|
||||
if ( invoker.loadammo != types[i] ) continue;
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x-10*z);
|
||||
let c = Spawn(casetypes[i],origin);
|
||||
c.angle = angle;
|
||||
c.pitch = pitch;
|
||||
c.vel = x*FRandom[Junk](-.2,.2)+y*FRandom[Junk](-.2,.2)-(0,0,FRandom[Junk](2,3));
|
||||
c.vel += vel*.5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
action void ProcessTraceHit( SpreadgunTracer t, Vector3 origin, Vector3 dir, int dmg, double mm, Class<Actor> impact = "SpreadImpact", int bc = 1, bool large = false )
|
||||
{
|
||||
for ( int i=0; i<t.ShootThroughList.Size(); i++ )
|
||||
t.ShootThroughList[i].Activate(self,0,SPAC_PCross);
|
||||
for ( int i=0; i<t.WaterHitList.Size(); i++ )
|
||||
{
|
||||
let b = Spawn(large?"InvisibleSplasher":"SmolInvisibleSplasher",t.WaterHitList[i].hitpos);
|
||||
b.A_CheckTerrain();
|
||||
}
|
||||
for ( int i=5; i<t.Results.Distance; i+=10 )
|
||||
{
|
||||
if ( !Random[Boolet](0,bc) ) continue;
|
||||
let b = Actor.Spawn("SWWMBubble",level.Vec3Offset(origin,dir*i));
|
||||
b.Scale *= FRandom[Boolet](.1,.3);
|
||||
}
|
||||
for ( int i=0; i<t.HitList.Size(); i++ )
|
||||
{
|
||||
int realdmg = dmg?dmg:t.HitList[i].HitDamage;
|
||||
SWWMDamageAccumulator.Accumulate(t.HitList[i].HitActor,realdmg,invoker,self,'shot',!large);
|
||||
SWWMHandler.DoKnockback(t.HitList[i].HitActor,t.HitList[i].x+(0,0,0.025),mm*FRandom[Spreadgun](0.4,1.2));
|
||||
if ( t.HitList[i].HitActor.bNOBLOOD || t.HitList[i].HitActor.bINVULNERABLE )
|
||||
{
|
||||
let p = Spawn(impact,t.HitList[i].HitLocation);
|
||||
p.angle = atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180;
|
||||
p.pitch = asin(t.HitList[i].x.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
t.HitList[i].HitActor.TraceBleed(realdmg,self);
|
||||
t.HitList[i].HitActor.SpawnBlood(t.HitList[i].HitLocation,atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180,realdmg);
|
||||
if ( large ) t.HitList[i].HitActor.A_StartSound("spreadgun/slugf",CHAN_BODY,CHANF_OVERLAP,1.,2.);
|
||||
else t.HitList[i].HitActor.A_StartSound("spreadgun/pelletf",CHAN_BODY,CHANF_OVERLAP,.4,4.);
|
||||
}
|
||||
}
|
||||
if ( t.Results.HitType != TRACE_HitNone )
|
||||
{
|
||||
Vector3 hitnormal = -t.Results.HitVector;
|
||||
if ( t.Results.HitType == TRACE_HitFloor )
|
||||
{
|
||||
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.top.Normal;
|
||||
else hitnormal = t.Results.HitSector.floorplane.Normal;
|
||||
}
|
||||
else if ( t.Results.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( t.Results.FFloor ) hitnormal = -t.Results.FFloor.bottom.Normal;
|
||||
else hitnormal = t.Results.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( t.Results.HitType == TRACE_HitWall )
|
||||
{
|
||||
hitnormal = (-t.Results.HitLine.delta.y,t.Results.HitLine.delta.x,0).unit();
|
||||
if ( !t.Results.Side ) hitnormal *= -1;
|
||||
}
|
||||
let p = Spawn(impact,t.Results.HitPos+hitnormal*4);
|
||||
p.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
p.pitch = asin(-hitnormal.z);
|
||||
if ( t.Results.HitLine ) t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos);
|
||||
}
|
||||
}
|
||||
|
||||
action void A_FireShell()
|
||||
|
|
@ -142,7 +526,6 @@ Class Spreadgun : SWWMWeapon
|
|||
static const int louds[] = {800,1000,1100,1200,1400,600,2500};
|
||||
static const int quakes[] = {3,4,2,4,3,1,6};
|
||||
static const Color cols[] = {Color(40,255,192,64),Color(36,255,192,80),Color(64,255,160,32),Color(48,32,176,255),Color(72,255,128,16),Color(24,255,224,96),Color(96,255,224,16)};
|
||||
Console.Printf("// TODO fire shell");
|
||||
for ( int i=0; i<7; i++ )
|
||||
{
|
||||
if ( invoker.loadammo != types[i] ) continue;
|
||||
|
|
@ -153,6 +536,108 @@ Class Spreadgun : SWWMWeapon
|
|||
A_ZoomFactor(1.+quakes[i]*.04,ZOOM_INSTANT);
|
||||
A_ZoomFactor(1.);
|
||||
SWWMHandler.DoFlash(self,cols[i],5);
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+2*y-2*z);
|
||||
Vector3 x2, y2, z2;
|
||||
[x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll);
|
||||
double a, s;
|
||||
Vector3 dir;
|
||||
SpreadgunTracer st;
|
||||
SpreadSlugTracer sst;
|
||||
switch ( i )
|
||||
{
|
||||
case 1:
|
||||
sst = new("SpreadSlugTracer");
|
||||
sst.ignoreme = self;
|
||||
sst.penetration = 250.;
|
||||
a = FRandom[Spreadgun](0,360);
|
||||
s = FRandom[Spreadgun](0,.01);
|
||||
dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
|
||||
sst.hitlist.Clear();
|
||||
sst.shootthroughlist.Clear();
|
||||
sst.waterhitlist.Clear();
|
||||
sst.Trace(origin,level.PointInSector(origin.xy),dir,8000.,0);
|
||||
ProcessTraceHit(sst,origin,dir,0,12000,"SlugImpact",1,true);
|
||||
for ( int i=0; i<3; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMViewSmoke",origin);
|
||||
SWWMViewSmoke(s).ofs = (15,3,-3);
|
||||
s.target = self;
|
||||
s.SetShade(Color(1,1,1)*Random[Spreadgun](96,192));
|
||||
s.alpha *= 0.5;
|
||||
}
|
||||
for ( int i=0; i<6; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMSmoke",origin);
|
||||
s.scale *= .8;
|
||||
s.alpha *= .3;
|
||||
s.SetShade(Color(1,1,1)*Random[Spreadgun](96,192));
|
||||
s.vel += vel*.5+x*FRandom[Spreadgun](3.,5.);
|
||||
}
|
||||
for ( int i=0; i<10; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMSpark",origin);
|
||||
s.scale *= .2;
|
||||
s.alpha *= .4;
|
||||
s.vel += vel*.5+x*FRandom[Spreadgun](4.,8.)+y*FRandom[Spreadgun](-1,1)+z*FRandom[Spreadgun](-1,1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
Console.Printf("\cg// TODO Dragon's Breath\c-");
|
||||
break;
|
||||
case 3:
|
||||
Console.Printf("\cg// TODO Kinylum Saltshot\c-");
|
||||
break;
|
||||
case 4:
|
||||
Console.Printf("\cg// TODO Napalm Rounds\c-");
|
||||
break;
|
||||
case 5:
|
||||
Console.Printf("\cg// TODO The Ball\c-");
|
||||
break;
|
||||
case 6:
|
||||
Console.Printf("\cg// TODO Golden Shell\c-");
|
||||
break;
|
||||
default:
|
||||
st = new("SpreadgunTracer");
|
||||
st.ignoreme = self;
|
||||
for ( int j=0; j<30; j++ )
|
||||
{
|
||||
a = FRandom[Spreadgun](0,360);
|
||||
s = FRandom[Spreadgun](0,.22);
|
||||
dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
|
||||
st.hitlist.Clear();
|
||||
st.shootthroughlist.Clear();
|
||||
st.waterhitlist.Clear();
|
||||
st.Trace(origin,level.PointInSector(origin.xy),dir,8000.,0);
|
||||
ProcessTraceHit(st,origin,dir,6,7000,bc:5);
|
||||
}
|
||||
for ( int i=0; i<9; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMViewSmoke",origin);
|
||||
SWWMViewSmoke(s).ofs = (15,3,-3);
|
||||
s.target = self;
|
||||
s.SetShade(Color(1,1,1)*Random[Spreadgun](96,192));
|
||||
s.alpha *= .2;
|
||||
}
|
||||
for ( int i=0; i<16; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMSmoke",origin);
|
||||
s.special1 = 1;
|
||||
s.scale *= .9;
|
||||
s.alpha *= .3;
|
||||
s.SetShade(Color(1,1,1)*Random[Spreadgun](96,192));
|
||||
s.vel += vel*.5+x*FRandom[Spreadgun](3.,5.)+y*FRandom[Spreadgun](-1,1)+z*FRandom[Spreadgun](-1,1);
|
||||
}
|
||||
for ( int i=0; i<20; i++ )
|
||||
{
|
||||
let s = Spawn("SWWMSpark",origin);
|
||||
s.scale *= .3;
|
||||
s.alpha *= .4;
|
||||
s.vel += vel*.5+x*FRandom[Spreadgun](4.,8.)+y*FRandom[Spreadgun](-2,2)+z*FRandom[Spreadgun](-2,2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
A_StartSound("spreadgun/hammer",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
|
|
@ -185,7 +670,6 @@ Class Spreadgun : SWWMWeapon
|
|||
Ammo a = Ammo(other.FindInventory(types[i]));
|
||||
if ( !a ) continue;
|
||||
nextammo = types[i];
|
||||
Ammo1 = a;
|
||||
return;
|
||||
}
|
||||
nextammo = AmmoType1;
|
||||
|
|
@ -206,17 +690,21 @@ Class Spreadgun : SWWMWeapon
|
|||
int ridx;
|
||||
if ( rev )
|
||||
{
|
||||
ridx = (cur-i)%7;
|
||||
if ( ridx < 0 ) ridx = 6;
|
||||
ridx = cur-i;
|
||||
if ( ridx < 0 ) break;
|
||||
}
|
||||
else ridx = (i+cur+1)%7;
|
||||
if ( CountInv(types[ridx]) <= 0 ) continue;
|
||||
next = ridx;
|
||||
break;
|
||||
}
|
||||
if ( rev && (invoker.nextammo == types[next]) )
|
||||
{
|
||||
A_SwitchAmmoType(false); // recheck forward
|
||||
return;
|
||||
}
|
||||
if ( invoker.nextammo != types[next] ) A_StartSound("misc/invchange",CHAN_WEAPONEXTRA,CHANF_UI|CHANF_LOCAL);
|
||||
invoker.nextammo = types[next];
|
||||
invoker.Ammo1 = Ammo(FindInventory(invoker.nextammo));
|
||||
A_WeaponReady(WRF_NOFIRE);
|
||||
}
|
||||
|
||||
|
|
@ -532,25 +1020,67 @@ Class Spreadgun : SWWMWeapon
|
|||
XZWK FGHI 2;
|
||||
Goto ReadyFired;
|
||||
FlashRed:
|
||||
XZWZ A 2 Bright;
|
||||
XZWZ A 2 Bright
|
||||
{
|
||||
let l = Spawn("SWWMWeaponLight",pos);
|
||||
l.args[3] = 120;
|
||||
l.target = self;
|
||||
}
|
||||
Stop;
|
||||
FlashGreen:
|
||||
XZWZ B 2 Bright;
|
||||
XZWZ B 2 Bright
|
||||
{
|
||||
let l = Spawn("SWWMWeaponLight",pos);
|
||||
l.args[3] = 90;
|
||||
l.target = self;
|
||||
}
|
||||
Stop;
|
||||
FlashWhite:
|
||||
XZWZ C 2 Bright;
|
||||
XZWZ C 2 Bright
|
||||
{
|
||||
let l = Spawn("SWWMWeaponLight",pos);
|
||||
l.args[1] = 176;
|
||||
l.args[2] = 32;
|
||||
l.args[3] = 160;
|
||||
l.target = self;
|
||||
}
|
||||
Stop;
|
||||
FlashBlue:
|
||||
XZWZ D 2 Bright;
|
||||
XZWZ D 2 Bright
|
||||
{
|
||||
let l = Spawn("SWWMWeaponLight",pos);
|
||||
l.args[0] = 96;
|
||||
l.args[1] = 224;
|
||||
l.args[2] = 255;
|
||||
l.args[3] = 160;
|
||||
l.target = self;
|
||||
}
|
||||
Stop;
|
||||
FlashBlack:
|
||||
XZWZ E 2 Bright;
|
||||
XZWZ E 2 Bright
|
||||
{
|
||||
let l = Spawn("SWWMWeaponLight",pos);
|
||||
l.args[1] = 144;
|
||||
l.args[2] = 16;
|
||||
l.args[3] = 280;
|
||||
l.target = self;
|
||||
}
|
||||
Stop;
|
||||
FlashPurple:
|
||||
XZWZ F 2 Bright;
|
||||
XZWZ F 2 Bright
|
||||
{
|
||||
let l = Spawn("SWWMWeaponLight",pos);
|
||||
l.args[3] = 60;
|
||||
l.target = self;
|
||||
}
|
||||
Stop;
|
||||
FlashGold:
|
||||
XZWZ G 2 Bright;
|
||||
XZWZ G 2 Bright
|
||||
{
|
||||
let l = Spawn("SWWMWeaponLight",pos);
|
||||
l.args[3] = 300;
|
||||
l.target = self;
|
||||
}
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ Class ExplodiumGun : SWWMWeapon
|
|||
int dmg = 40;
|
||||
SWWMHandler.DoKnockback(d.HitActor,d.HitDir,48000);
|
||||
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'Explodium',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
|
||||
if ( d.HitActor.bNOBLOOD )
|
||||
if ( d.HitActor.bNOBLOOD || d.HitActor.bINVULNERABLE )
|
||||
{
|
||||
let p = Spawn("SWWMBulletImpact",d.HitLocation);
|
||||
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
|
||||
|
|
|
|||
|
|
@ -825,7 +825,7 @@ Class CandyGun : SWWMWeapon
|
|||
int dmg = 350;
|
||||
SWWMHandler.DoKnockback(d.HitActor,d.HitDir,72000);
|
||||
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'Explodium',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
|
||||
if ( d.HitActor.bNOBLOOD )
|
||||
if ( d.HitActor.bNOBLOOD || d.HitActor.bINVULNERABLE )
|
||||
{
|
||||
let p = Spawn("SWWMBulletImpact",d.HitLocation);
|
||||
p.angle = atan2(d.HitDir.y,d.HitDir.x)+180;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue