diff --git a/cvarinfo.txt b/cvarinfo.txt index e26ae5433..000a1f122 100644 --- a/cvarinfo.txt +++ b/cvarinfo.txt @@ -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 \ No newline at end of file diff --git a/decaldef.txt b/decaldef.txt index 6e4989d37..ea59cd04b 100644 --- a/decaldef.txt +++ b/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 +} diff --git a/keyconf.txt b/keyconf.txt index 4a27dbcd8..f26c3cce2 100644 --- a/keyconf.txt +++ b/keyconf.txt @@ -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" diff --git a/language.txt b/language.txt index 3bc3b5631..3e35fb509 100644 --- a/language.txt +++ b/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-"; diff --git a/menudef.txt b/menudef.txt index 99676a8c9..cb153b62b 100644 --- a/menudef.txt +++ b/menudef.txt @@ -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" { diff --git a/modeldef.spreadgun b/modeldef.spreadgun index 99f8a5687..45ce5c6ef 100644 --- a/modeldef.spreadgun +++ b/modeldef.spreadgun @@ -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" diff --git a/sndinfo.txt b/sndinfo.txt index 80ad8c5be..e1726d71f 100644 --- a/sndinfo.txt +++ b/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 diff --git a/sounds/demolitionist/demokick1.ogg b/sounds/demolitionist/demokick1.ogg new file mode 100644 index 000000000..9d785b950 Binary files /dev/null and b/sounds/demolitionist/demokick1.ogg differ diff --git a/sounds/demolitionist/demokick2.ogg b/sounds/demolitionist/demokick2.ogg new file mode 100644 index 000000000..2b13bd779 Binary files /dev/null and b/sounds/demolitionist/demokick2.ogg differ diff --git a/sounds/demolitionist/demokick3.ogg b/sounds/demolitionist/demokick3.ogg new file mode 100644 index 000000000..92698da25 Binary files /dev/null and b/sounds/demolitionist/demokick3.ogg differ diff --git a/sounds/spreadgun/spread_ball1.ogg b/sounds/spreadgun/spread_ball1.ogg new file mode 100644 index 000000000..49ed92575 Binary files /dev/null and b/sounds/spreadgun/spread_ball1.ogg differ diff --git a/sounds/spreadgun/spread_ball2.ogg b/sounds/spreadgun/spread_ball2.ogg new file mode 100644 index 000000000..928d33160 Binary files /dev/null and b/sounds/spreadgun/spread_ball2.ogg differ diff --git a/sounds/spreadgun/spread_ball3.ogg b/sounds/spreadgun/spread_ball3.ogg new file mode 100644 index 000000000..e4085aab2 Binary files /dev/null and b/sounds/spreadgun/spread_ball3.ogg differ diff --git a/sounds/spreadgun/spread_ballf1.ogg b/sounds/spreadgun/spread_ballf1.ogg new file mode 100644 index 000000000..ae2c3f278 Binary files /dev/null and b/sounds/spreadgun/spread_ballf1.ogg differ diff --git a/sounds/spreadgun/spread_ballf2.ogg b/sounds/spreadgun/spread_ballf2.ogg new file mode 100644 index 000000000..2582af613 Binary files /dev/null and b/sounds/spreadgun/spread_ballf2.ogg differ diff --git a/sounds/spreadgun/spread_ballf3.ogg b/sounds/spreadgun/spread_ballf3.ogg new file mode 100644 index 000000000..a055fcee3 Binary files /dev/null and b/sounds/spreadgun/spread_ballf3.ogg differ diff --git a/sounds/spreadgun/spread_casing1.ogg b/sounds/spreadgun/spread_casing1.ogg new file mode 100644 index 000000000..b125c33cb Binary files /dev/null and b/sounds/spreadgun/spread_casing1.ogg differ diff --git a/sounds/spreadgun/spread_casing2.ogg b/sounds/spreadgun/spread_casing2.ogg new file mode 100644 index 000000000..c4ace4092 Binary files /dev/null and b/sounds/spreadgun/spread_casing2.ogg differ diff --git a/sounds/spreadgun/spread_casing3.ogg b/sounds/spreadgun/spread_casing3.ogg new file mode 100644 index 000000000..1716f1d77 Binary files /dev/null and b/sounds/spreadgun/spread_casing3.ogg differ diff --git a/sounds/spreadgun/spread_casing4.ogg b/sounds/spreadgun/spread_casing4.ogg new file mode 100644 index 000000000..40288e97d Binary files /dev/null and b/sounds/spreadgun/spread_casing4.ogg differ diff --git a/sounds/spreadgun/spread_casing5.ogg b/sounds/spreadgun/spread_casing5.ogg new file mode 100644 index 000000000..b7feccfb3 Binary files /dev/null and b/sounds/spreadgun/spread_casing5.ogg differ diff --git a/sounds/spreadgun/spread_casing6.ogg b/sounds/spreadgun/spread_casing6.ogg new file mode 100644 index 000000000..b87320afc Binary files /dev/null and b/sounds/spreadgun/spread_casing6.ogg differ diff --git a/sounds/spreadgun/spread_gcasing1.ogg b/sounds/spreadgun/spread_gcasing1.ogg new file mode 100644 index 000000000..d6e713230 Binary files /dev/null and b/sounds/spreadgun/spread_gcasing1.ogg differ diff --git a/sounds/spreadgun/spread_gcasing2.ogg b/sounds/spreadgun/spread_gcasing2.ogg new file mode 100644 index 000000000..058637ffd Binary files /dev/null and b/sounds/spreadgun/spread_gcasing2.ogg differ diff --git a/sounds/spreadgun/spread_gcasing3.ogg b/sounds/spreadgun/spread_gcasing3.ogg new file mode 100644 index 000000000..bed3c4491 Binary files /dev/null and b/sounds/spreadgun/spread_gcasing3.ogg differ diff --git a/sounds/spreadgun/spread_pellet1.ogg b/sounds/spreadgun/spread_pellet1.ogg new file mode 100644 index 000000000..a0b5ea3ca Binary files /dev/null and b/sounds/spreadgun/spread_pellet1.ogg differ diff --git a/sounds/spreadgun/spread_pellet2.ogg b/sounds/spreadgun/spread_pellet2.ogg new file mode 100644 index 000000000..cc9ec117f Binary files /dev/null and b/sounds/spreadgun/spread_pellet2.ogg differ diff --git a/sounds/spreadgun/spread_pellet3.ogg b/sounds/spreadgun/spread_pellet3.ogg new file mode 100644 index 000000000..5abe914b4 Binary files /dev/null and b/sounds/spreadgun/spread_pellet3.ogg differ diff --git a/sounds/spreadgun/spread_pellet4.ogg b/sounds/spreadgun/spread_pellet4.ogg new file mode 100644 index 000000000..2b9a02e3e Binary files /dev/null and b/sounds/spreadgun/spread_pellet4.ogg differ diff --git a/sounds/spreadgun/spread_pellet5.ogg b/sounds/spreadgun/spread_pellet5.ogg new file mode 100644 index 000000000..3c2990a0c Binary files /dev/null and b/sounds/spreadgun/spread_pellet5.ogg differ diff --git a/sounds/spreadgun/spread_pellet6.ogg b/sounds/spreadgun/spread_pellet6.ogg new file mode 100644 index 000000000..716de49eb Binary files /dev/null and b/sounds/spreadgun/spread_pellet6.ogg differ diff --git a/sounds/spreadgun/spread_pellet7.ogg b/sounds/spreadgun/spread_pellet7.ogg new file mode 100644 index 000000000..b983b7d6a Binary files /dev/null and b/sounds/spreadgun/spread_pellet7.ogg differ diff --git a/sounds/spreadgun/spread_pellet8.ogg b/sounds/spreadgun/spread_pellet8.ogg new file mode 100644 index 000000000..f9c44eb60 Binary files /dev/null and b/sounds/spreadgun/spread_pellet8.ogg differ diff --git a/sounds/spreadgun/spread_pelletf1.ogg b/sounds/spreadgun/spread_pelletf1.ogg new file mode 100644 index 000000000..e33e87f85 Binary files /dev/null and b/sounds/spreadgun/spread_pelletf1.ogg differ diff --git a/sounds/spreadgun/spread_pelletf2.ogg b/sounds/spreadgun/spread_pelletf2.ogg new file mode 100644 index 000000000..ae58f98b7 Binary files /dev/null and b/sounds/spreadgun/spread_pelletf2.ogg differ diff --git a/sounds/spreadgun/spread_pelletf3.ogg b/sounds/spreadgun/spread_pelletf3.ogg new file mode 100644 index 000000000..f1adc58af Binary files /dev/null and b/sounds/spreadgun/spread_pelletf3.ogg differ diff --git a/sounds/spreadgun/spread_pelletf4.ogg b/sounds/spreadgun/spread_pelletf4.ogg new file mode 100644 index 000000000..f688ec0d6 Binary files /dev/null and b/sounds/spreadgun/spread_pelletf4.ogg differ diff --git a/sounds/spreadgun/spread_pelletf5.ogg b/sounds/spreadgun/spread_pelletf5.ogg new file mode 100644 index 000000000..66eb94710 Binary files /dev/null and b/sounds/spreadgun/spread_pelletf5.ogg differ diff --git a/sounds/spreadgun/spread_pelletf6.ogg b/sounds/spreadgun/spread_pelletf6.ogg new file mode 100644 index 000000000..8c7e31743 Binary files /dev/null and b/sounds/spreadgun/spread_pelletf6.ogg differ diff --git a/sounds/spreadgun/spread_salt1.ogg b/sounds/spreadgun/spread_salt1.ogg new file mode 100644 index 000000000..1076df4fd Binary files /dev/null and b/sounds/spreadgun/spread_salt1.ogg differ diff --git a/sounds/spreadgun/spread_salt2.ogg b/sounds/spreadgun/spread_salt2.ogg new file mode 100644 index 000000000..2f8347ff6 Binary files /dev/null and b/sounds/spreadgun/spread_salt2.ogg differ diff --git a/sounds/spreadgun/spread_salt3.ogg b/sounds/spreadgun/spread_salt3.ogg new file mode 100644 index 000000000..8d63a9530 Binary files /dev/null and b/sounds/spreadgun/spread_salt3.ogg differ diff --git a/sounds/spreadgun/spread_salt4.ogg b/sounds/spreadgun/spread_salt4.ogg new file mode 100644 index 000000000..e867a1d18 Binary files /dev/null and b/sounds/spreadgun/spread_salt4.ogg differ diff --git a/sounds/spreadgun/spread_slug1.ogg b/sounds/spreadgun/spread_slug1.ogg new file mode 100644 index 000000000..c8bb7bb81 Binary files /dev/null and b/sounds/spreadgun/spread_slug1.ogg differ diff --git a/sounds/spreadgun/spread_slug2.ogg b/sounds/spreadgun/spread_slug2.ogg new file mode 100644 index 000000000..827af027f Binary files /dev/null and b/sounds/spreadgun/spread_slug2.ogg differ diff --git a/sounds/spreadgun/spread_slugf1.ogg b/sounds/spreadgun/spread_slugf1.ogg new file mode 100644 index 000000000..090a40904 Binary files /dev/null and b/sounds/spreadgun/spread_slugf1.ogg differ diff --git a/sounds/spreadgun/spread_slugf2.ogg b/sounds/spreadgun/spread_slugf2.ogg new file mode 100644 index 000000000..ea132af75 Binary files /dev/null and b/sounds/spreadgun/spread_slugf2.ogg differ diff --git a/zscript/swwm_ammo.zsc b/zscript/swwm_ammo.zsc index 7f1e48b78..43dcb9069 100644 --- a/zscript/swwm_ammo.zsc +++ b/zscript/swwm_ammo.zsc @@ -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; } } diff --git a/zscript/swwm_common.zsc b/zscript/swwm_common.zsc index bd93a1c2e..bcacb1b78 100644 --- a/zscript/swwm_common.zsc +++ b/zscript/swwm_common.zsc @@ -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 combatactors; transient Array 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 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 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 diff --git a/zscript/swwm_inventory.zsc b/zscript/swwm_inventory.zsc index e34c12e1a..d938faf4b 100644 --- a/zscript/swwm_inventory.zsc +++ b/zscript/swwm_inventory.zsc @@ -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"; diff --git a/zscript/swwm_jackhammer.zsc b/zscript/swwm_jackhammer.zsc index ec80788df..e2838979c 100644 --- a/zscript/swwm_jackhammer.zsc +++ b/zscript/swwm_jackhammer.zsc @@ -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); diff --git a/zscript/swwm_menu.zsc b/zscript/swwm_menu.zsc index 4c14d4777..3f2075436 100644 --- a/zscript/swwm_menu.zsc +++ b/zscript/swwm_menu.zsc @@ -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); diff --git a/zscript/swwm_player.zsc b/zscript/swwm_player.zsc index 5f8b8caaa..c555ecf24 100644 --- a/zscript/swwm_player.zsc +++ b/zscript/swwm_player.zsc @@ -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 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 diff --git a/zscript/swwm_powerup.zsc b/zscript/swwm_powerup.zsc index 43f4ee2ec..faa87b97f 100644 --- a/zscript/swwm_powerup.zsc +++ b/zscript/swwm_powerup.zsc @@ -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 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); diff --git a/zscript/swwm_shot.zsc b/zscript/swwm_shot.zsc index e6de4fe83..8a073fff2 100644 --- a/zscript/swwm_shot.zsc +++ b/zscript/swwm_shot.zsc @@ -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 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 hitlist; + Array shootthroughlist; + Array 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 types[] = {"RedShell","GreenShell","WhiteShell","BlueShell","BlackShell","PurpleShell","GoldShell"}; @@ -122,6 +431,7 @@ Class Spreadgun : SWWMWeapon action void A_DropShell() { static const Class types[] = {"RedShell","GreenShell","WhiteShell","BlueShell","BlackShell","PurpleShell","GoldShell"}; + static const Class 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 impact = "SpreadImpact", int bc = 1, bool large = false ) + { + for ( int i=0; i