Hellblazer fully implemented.

Rebalanced Candygun.
Added vanilla boss healthbars + vanilla boss boosting (both optional).
Adjustments so the E1M8 exit and similar work fine with this mod.
Various language changes (mostly vanilla monster tags).
Doubled damage of Pusher altfire, so it matches the projectile's.
Adjusted minimum fall speed for stomping.
Other small fixed and adjustments.
This commit is contained in:
Mari the Deer 2020-04-20 21:40:26 +02:00
commit faddb088c1
52 changed files with 1328 additions and 161 deletions

View file

@ -28,7 +28,7 @@ user bool swwm_targettags = false; // show enemy tags above healthbars
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_fly6dof = false; // 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
@ -38,3 +38,5 @@ user int swwm_intertype = 0; // 0 - standard bg
// 1 - fanart
// 2 - 4komas
server bool swwm_balluse = false; // lead ball can "press" switches remotely
user bool swwm_bosshealthbars = true; // display large healthbars for vanilla boss encounters
server bool swwm_upgradebosses = true; // vanilla bosses will be "upgraded" to be less insta-die prone

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

View file

@ -449,33 +449,33 @@ TXT_HEXEN_WIN3MSG =
"got a fine lady waiting for me back home.\"";
// Re-tagged monsters
FN_ZOMBIE = "Zomb";
FN_SHOTGUN = "Baldy";
FN_SHOTGUN = "Bald Zomb";
FN_HEAVY = "Annoyance";
FN_IMP = "Simp";
FN_DEMON = "Pinky";
FN_SPECTRE = "Fuzzy";
FN_LOST = "Skully";
FN_CACO = "Caco";
FN_HELL = "Brownie";
FN_IMP = "Spiky Boi";
FN_DEMON = "Pinky Boi";
FN_SPECTRE = "Fuzzy Boi";
FN_LOST = "Fire Skully";
FN_CACO = "Friend-Shaped Demon";
FN_HELL = "Discount Baron";
FN_BARON = "Mr. Gruh";
FN_ARACH = "Babby";
FN_ARACH = "Babby Spooder";
FN_PAIN = "Ass Pain";
FN_REVEN = "AAAAAAAAA";
FN_MANCU = "He Thicc";
FN_ARCH = "Pls No";
FN_ARCH = "1000 Points Off";
FN_SPIDER = "Mama Spooder";
FN_CYBER = "Dat Ass";
FN_WOLFSS = "Mein Lieben";
CC_ZOMBIE = "Zomb";
CC_SHOTGUN = "Baldy";
CC_SHOTGUN = "Bald Zomb";
CC_HEAVY = "Annoyance";
CC_IMP = "Simp";
CC_DEMON = "Pinky";
CC_LOST = "Skully";
CC_CACO = "Caco";
CC_HELL = "Brownie";
CC_IMP = "Spiky Boi";
CC_DEMON = "Pinky Boi";
CC_LOST = "Fire Skully";
CC_CACO = "Friend-Shaped Demon";
CC_HELL = "Discount Baron";
CC_BARON = "Mr. Gruh";
CC_ARACH = "Babby";
CC_ARACH = "Babby Spooder";
CC_PAIN = "Ass Pain";
CC_REVEN = "AAAAAAAAA";
CC_MANCU = "He Thicc";
@ -484,16 +484,16 @@ CC_SPIDER = "Mama Spooder";
CC_CYBER = "Dat Ass";
CC_HERO = "You!";
FN_DOG = "Goodest Boy";
FN_CHICKEN = "Clucker";
FN_CHICKEN = "PECK";
FN_BEAST = "Друг";
FN_CLINK = "Slashy";
FN_DSPARIL = "Oh He Mad";
FN_CLINK = "Slashy Boi";
FN_DSPARIL = "Little Red Riding Hood";
FN_HERETICIMP = "Flying Pest";
FN_IRONLICH = "Jolly Lad";
FN_BONEKNIGHT = "Rattle Me Bones";
FN_MINOTAUR = "Buff";
FN_MUMMY = "Mummy";
FN_MUMMYLEADER = "Big Mummy";
FN_MINOTAUR = "Buff Bull";
FN_MUMMY = "Toilet Paper";
FN_MUMMYLEADER = "Toilet Paper whomst Scream";
FN_SNAKE = "Snek";
FN_WIZARD = "Yer a Wizard, Harry";
FN_FIREDEMON = "Hot Stuff";
@ -501,16 +501,19 @@ FN_DEMON1 = "Big Lizard";
FN_ETTIN = "Double Boi";
FN_CENTAUR = "Shield Idiot";
FN_SLAUGHTAUR = "Shield Idioter";
FN_BISHOP = "Hoodie";
FN_ICEGUY = "Cool Stuff";
FN_BISHOP = "Hoodie Boi";
FN_ICEGUY = "Cool Story Bro";
FN_SERPENT = "Swamp Snek";
FN_WRAITH = "Ded";
FN_WRAITH = "Ded Boi";
FN_DRAGON = "Buy Skyrim";
FN_KORAX = "Ugly Stinky Boi";
FN_FBOSS = "Buff Boi";
FN_MBOSS = "Magic Boi";
FN_CBOSS = "Holy Boi";
FN_HERESIARCH = "Oh Lawd He Comin'";
// Additional tags
FN_BOSSBRAIN = "Daikatana";
FN_KEEN = "Ruined by Bethesda";
// obituaries
O_PUSHER = "%k opened some air holes into %o.";
O_DEEPIMPACT = "%o was impacted deeply by %k.";
@ -553,7 +556,7 @@ OB_SLIME = "%o got slimed.";
OB_LAVA = "%o overheated";
OB_BARREL = "%o got barreled.";
OB_SPLASH = "%o got a bit too close there.";
OB_R_SPLASH = "%o was rawket'd.";
OB_R_SPLASH = "%o did an Icarus.";
OB_ROCKET = "%o ate a rocket.";
OB_KILLEDSELF = "%o self-destructed.";
OB_VOODOO = "%o violated the laws of causality.";
@ -646,6 +649,21 @@ SWWM_LQUOTE = "\"";
SWWM_RQUOTE = "\"";
D_FROGGY1 = "\cjA small price to pay...\c-";
D_FROGGY2 = "\cj... for \cdFroggy Chair\cj.\c-";
// boss tags
BT_BRUISERS = "Super Bruiser Bros";
BT_CYBIE = "Shoot It Until It Dies";
BT_SPIDER = "Big Brains Idiot";
BT_IOS = "Goaty McGoatface";
BT_LICHES = "The Jolly Lad Squad";
BT_MINOTAUR = "AWAKEN MY MASTERS";
BT_DSPARIL = "Red Robed Wizard Dude and Lizard";
BT_DSPARIL2 = "Red Robed Wizard Dude";
BT_CLERIC = "Traductus the Holy Boi";
BT_FIGHTER = "Zedek the Buff Boi";
BT_MAGE = "Menelkir the Magic Boi";
BT_DRAGON = "A Motherfucking Dragon";
BT_HERESIARCH = "Very Pissed Off Red Dude";
BT_KORAX = "Korax the Big Stinky Ugly Bastard";
// targetter
SWWM_OVERKILL = "Overkill";
SWWM_MULTIKILL = "Multi Kill";

View file

@ -79,6 +79,9 @@ SWWM_INTERDEF = "N/A";
SWWM_INTERART = "Fanart";
SWWM_INTER4KOMA = "4Koma";
SWWM_BALLUSE = "Lead Balls can activate switches";
SWWM_BOSSBAR = "Show Boss Healthbars";
SWWM_BTITLE = "Balance Options";
SWWM_BOSSENHANCE = "Enhance Vanilla Bosses";
TOOLTIP_SWWM_VOICETYPE = "Sets the voice pack for the player.";
TOOLTIP_SWWM_MUTEVOICE = "Control what gets muted, if you'd rather have a more silent protagonist.";
TOOLTIP_SWWM_FLASHSTRENGTH = "Screen flashes usually happen when firing some weapons, you can lower this if these effects are harmful for you.";
@ -109,6 +112,8 @@ TOOLTIP_SWWM_REVIVE = "Allows the player to get back up after dying by pressing
TOOLTIP_SWWM_REVIVECOOLDOWN = "Time in seconds of downtime after using a reboot, where if you die again, you can't get back up. Set to 0 to allow unlimited reboots.";
TOOLTIP_SWWM_INTERTYPE = "Choose what to display in the background during intermissions.";
TOOLTIP_SWWM_BALLUSE = "Lead Ball projectiles can remotely activate use switches (excluding exits). Potentially OP.";
TOOLTIP_SWWM_BOSSHEALTHBARS = "Show a healthbar for vanilla boss encounters at the bottom of the screen. Just like Dark Souls™!";
TOOLTIP_SWWM_UPGRADEBOSSES = "Buffs the health of vanilla bosses in order to make the fights more \"fair\" with this mod, and less prone to instant wins.";
// knowledge base
SWWM_COMINGSOON = "(coming soon)";
SWWM_MISSTAB = "Mission";

View file

@ -448,42 +448,44 @@ TXT_HEXEN_WIN3MSG =
"una bella dama que me espera en casa.\"";
// Re-tagged monsters
FN_ZOMBIE = "Zombi";
FN_SHOTGUN = "Calvito";
FN_SHOTGUN = "Zombi Calvete";
FN_HEAVY = "Tocacojones";
FN_IMP = "Pinchitos";
FN_DEMON = "Rosita";
FN_SPECTRE = "Borroncito";
FN_LOST = "Calaverita";
FN_CACO = "Tomatín";
FN_HELL = "Marroncito";
FN_HELL = "Barón de Hacendado";
FN_BARON = "Señor Gruñón";
FN_ARACH = "Ñiño";
FN_ARACH = "Ñiño Araña";
FN_PAIN = "Dolor de Culo";
FN_SPIDER = "Mami Araña";
FN_CYBER = "Madre Mía Que Culazo";
FN_CYBER = "Culazo";
FN_WOLFSS = "Votante de VOX";
CC_ZOMBIE = "Zombi";
CC_SHOTGUN = "Calvito";
CC_SHOTGUN = "Zombi Calvete";
CC_HEAVY = "Tocacojones";
CC_IMP = "Pinchitos";
CC_DEMON = "Rosita";
CC_LOST = "Calaverita";
CC_CACO = "Tomatín";
CC_HELL = "Marroncito";
CC_HELL = "Barón de Hacendado";
CC_BARON = "Señor Gruñón";
CC_ARACH = "Ñiño";
CC_ARACH = "Ñiño Araña";
CC_PAIN = "Dolor de Culo";
CC_SPIDER = "Mami Araña";
CC_CYBER = "Madre Mía Que Culazo";
CC_CYBER = "Culazo";
CC_HERO = "¡Tú!";
FN_DOG = "Perrete";
FN_CHICKEN = "Gallina";
FN_CLINK = "Rasguñitos";
FN_DSPARIL = "El Brujo Ese";
FN_DSPARIL = "Caperucita Roja";
FN_HERETICIMP = "Bicho con Alas";
FN_IRONLICH = "Risitas";
FN_BONEKNIGHT = "Huesitos";
FN_MINOTAUR = "Tó Ciclao";
FN_MUMMY = "Momia";
FN_MUMMYLEADER = "Momia Grandota";
FN_MINOTAUR = "Toro Ciclao";
FN_MUMMY = "Papel de Culo";
FN_MUMMYLEADER = "Papel de Culo que Grita";
FN_SNAKE = "Culebrilla";
FN_WIZARD = "Eres Un Mago, Harry";
FN_FIREDEMON = "Bicho Ardiente";
@ -491,9 +493,9 @@ FN_DEMON1 = "Lagarto Grandote";
FN_ETTIN = "Perrito Doble";
FN_CENTAUR = "Idiota con Escudo";
FN_SLAUGHTAUR = "Superidiota con Escudo";
FN_BISHOP = "Encapuchao Volador";
FN_ICEGUY = "Bicho de Hielo";
FN_SERPENT = "Bicho del Pantano";
FN_BISHOP = "Encapuchao";
FN_ICEGUY = "Cosa Fría";
FN_SERPENT = "Bicho de Pantano";
FN_WRAITH = "Pariente de Fraga";
FN_DRAGON = "Compra Skyrim";
FN_KORAX = "El Tío Feo Ese";
@ -501,6 +503,8 @@ FN_FBOSS = "Tío Ciclao";
FN_MBOSS = "Tío Mágico";
FN_CBOSS = "Tío Santurrón";
FN_HERESIARCH = "Hostia Puta";
// Additional tags
FN_KEEN = "Arruinado por Bethesda";
// obituaries
O_PUSHER = "%k le abrió unos agujeros de ventilación a %o.";
O_DEEPIMPACT = "%o fue impactad@[ao_esp] profundamente por %k.";
@ -603,8 +607,8 @@ OB_DEMON1 = "%o se comió la bola de fuego de un lagarto grandote.";
OB_DEMON2 = "%o se comió los mocos de un lagarto grandote.";
OB_ETTIN = "%o se llevó un coscorrón del perrito doble.";
OB_CENTAUR = "%o fue acuchillad@[ao_esp] por un idiota con escudo.";
OB_SLAUGHTAURHIT = "%o fue acuchillad@[ao_esp] por un muy idiota con escudo.";
OB_SLAUGHTAUR = "%o se comió un disparo del muy idiota con escudo.";
OB_SLAUGHTAURHIT = "%o fue acuchillad@[ao_esp] por un superidiota con escudo.";
OB_SLAUGHTAUR = "%o se comió un disparo del superidiota con escudo.";
OB_BISHOP = "%o se comió toda la magia del encapuchao.";
OB_ICEGUY = "%o tiene frío.";
OB_SERPENTHIT = "%o encontró la cosa del pantano.";
@ -634,6 +638,19 @@ SWWM_REFAIL = "REINICIO DE EMERGENCIA FALLIDO - NO HAY SUFICIENTE POTENCIA AUXIL
D_REFAIL = "El Sistema de Reinicio de Emergencia se ha recargado completamente.";
D_FROGGY1 = "\cjUn pequeño precio a pagar...\c-";
D_FROGGY1 = "\cj... por una \cdSilla Rana\cj.\c-";
// boss tags
BT_CYBIE = "Dispara hasta que muera";
BT_SPIDER = "Cerebrito Idiota";
BT_IOS = "Cabra Emparedada";
BT_LICHES = "El Escuadrón Risitas";
BT_DSPARIL = "El Brujo Rojo Ese y Lagarto";
BT_DSPARIL2 = "El Brujo Rojo Ese";
BT_CLERIC = "Traductus el Santurrón";
BT_FIGHTER = "Zedek el Ciclao";
BT_MAGE = "Menelkir el Mágico";
BT_DRAGON = "Un Puñetero Dragón";
BT_HERESIARCH = "Tío Rojo Muy Cabreado";
BT_KORAX = "Korax el Bastardo Feo Asqueroso";
// targetter
SWWM_MULTIKILL = "Racha";
SWWM_SPREEKILL = "Intocable";

View file

@ -76,6 +76,9 @@ SWWM_REVIVECOOLDOWN = "Tiempo de recarga de Reinicio";
SWWM_UNLIMITED = "Ilimitado";
SWWM_INTERTYPE = "Arte de Intermisión";
SWWM_BALLUSE = "Las Bolas de Plomo activan botones";
SWWM_BOSSBAR = "Mostrar Barras de Salud de Bosses";
SWWM_BTITLE = "Opciones de Balance";
SWWM_BOSSENHANCE = "Mejorar Bosses Vanilla";
TOOLTIP_SWWM_VOICETYPE = "Selecciona el pack de voz para el jugador.";
TOOLTIP_SWWM_MUTEVOICE = "Controla lo que se mutea, si prefieres tener un protagonista más silencioso.";
TOOLTIP_SWWM_FLASHSTRENGTH = "Los destellos en pantalla suelen ocurrir al disparar algunas armas, puedes reducirlo si este tipo de effectos te causan malestar.";
@ -106,6 +109,8 @@ TOOLTIP_SWWM_REVIVE = "Permite al jugador volver a levantarse tras morir pulsand
TOOLTIP_SWWM_REVIVECOOLDOWN = "Tiempo en segundos tras reiniciar, durante el cual si mueres otra vez, no puedes volver a levantarte. Pon a 0 para permitir reinicios ilimitados.";
TOOLTIP_SWWM_INTERTYPE = "Elige qué mostrar de fondo durante intermisiones.";
TOOLTIP_SWWM_BALLUSE = "Los proyectiles de Bola de Plomo pueden activar botones usables remotamente (excluyendo salidas). Potencialmente roto.";
TOOLTIP_SWWM_BOSSHEALTHBARS = "Muestra una barra de vida para bosses vanilla en la parte inferior de la pantalla. ¡Es justo como Dark Souls™!";
TOOLTIP_SWWM_UPGRADEBOSSES = "Incrementa la salud de bosses vanilla para hacer que las peleas sean más \"justas\" con este mod, y no tan propensas a ganarse al instante.";
// knowledge base
SWWM_COMINGSOON = "(próximamente)";
SWWM_MISSTAB = "Misión";

View file

@ -41,12 +41,16 @@ OptionMenu "SWWMOptionMenu"
Slider "$SWWM_PICKLEN", "swwm_pickduration", 1, 30, 1, 0
Option "$SWWM_TARGET", "swwm_targeter", "YesNo"
Option "$SWWM_TARGETTAG", "swwm_targettags", "YesNo"
Option "$SWWM_BOSSBAR", "swwm_bosshealthbars", "YesNo"
Option "$SWWM_DAMNUMS", "swwm_healthnums", "YesNo"
Option "$SWWM_SCORENUMS", "swwm_scorenums", "YesNo"
Option "$SWWM_SCOREBONUS", "swwm_scorebonus", "YesNo"
Option "$SWWM_SHADERS", "swwm_shaders", "YesNo"
Option "$SWWM_INTERTYPE", "swwm_intertype", "SWWMInterType"
StaticText " "
StaticText "$SWWM_BTITLE", "Gold"
Option "$SWWM_BOSSENHANCE", "swwm_upgradebosses", "YesNo"
StaticText " "
StaticText "$SWWM_ITITLE", "Gold"
Option "$SWWM_ARMORUSE", "swwm_autousearmor", "YesNo"
Option "$SWWM_HEALTHUSE", "swwm_autousehealth", "YesNo"

View file

@ -44,6 +44,18 @@ Model "HellblazerCrackshot2"
FrameIndex XZW1 A 0 0
}
Model "HellblazerClusterMini"
{
Path "models"
Model 0 "HellblazerProj_d.3d"
Skin 0 "HellblazerMissile_Cluster.png"
Scale 0.02 0.02 0.02
USEACTORPITCH
USEACTORROLL
FrameIndex XZW1 A 0 0
}
Model "HellblazerRavager"
{
Path "models"
@ -466,13 +478,13 @@ Model "Hellblazer"
// CycleStart/End
FrameIndex XZW7 Z 1 33
// Cycle2
FrameIndex XZW8 A 0 41
FrameIndex XZW8 B 0 42
FrameIndex XZW8 C 0 43
FrameIndex XZW8 D 0 44
FrameIndex XZW8 E 0 45
FrameIndex XZW8 F 0 46
FrameIndex XZW8 G 0 47
FrameIndex XZW8 A 1 41
FrameIndex XZW8 B 1 42
FrameIndex XZW8 C 1 43
FrameIndex XZW8 D 1 44
FrameIndex XZW8 E 1 45
FrameIndex XZW8 F 1 46
FrameIndex XZW8 G 1 47
// Unload
FrameIndex XZW8 H 1 59
FrameIndex XZW8 I 1 60
@ -740,13 +752,13 @@ Model "Hellblazer"
FrameIndex XZWH M 1 22
FrameIndex XZWH N 1 23
// AltFire
FrameIndex XZWH O 0 25
FrameIndex XZWH P 0 26
FrameIndex XZWH Q 0 27
FrameIndex XZWH R 0 28
FrameIndex XZWH S 0 29
FrameIndex XZWH T 0 30
FrameIndex XZWH U 0 31
FrameIndex XZWH O 1 25
FrameIndex XZWH P 1 26
FrameIndex XZWH Q 1 27
FrameIndex XZWH R 1 28
FrameIndex XZWH S 1 29
FrameIndex XZWH T 1 30
FrameIndex XZWH U 1 31
// CycleStart/End
FrameIndex XZWH V 1 33
// Cycle3

BIN
palettes/DRed.pal Normal file

Binary file not shown.

View file

@ -590,6 +590,10 @@ hellblazer/hitcs1 sounds/hellblazer/blaze_hitcs1.ogg
hellblazer/hitcs2 sounds/hellblazer/blaze_hitcs2.ogg
hellblazer/hitcs3 sounds/hellblazer/blaze_hitcs3.ogg
$random hellblazer/hitcs { hellblazer/hitcs1 hellblazer/hitcs2 hellblazer/hitcs3 }
hellblazer/hitr1 sounds/hellblazer/blaze_hitr1.ogg
hellblazer/hitr2 sounds/hellblazer/blaze_hitr2.ogg
hellblazer/hitr3 sounds/hellblazer/blaze_hitr3.ogg
$random hellblazer/hitr { hellblazer/hitr1 hellblazer/hitr2 hellblazer/hitr3 }
hellblazer/hitw1 sounds/hellblazer/blaze_hitw1.ogg
hellblazer/hitw2 sounds/hellblazer/blaze_hitw2.ogg
$random hellblazer/hitw { hellblazer/hitw1 hellblazer/hitw2 }

BIN
sprites/RFLMA0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/RFLMB0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/RFLMC0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/RFLMD0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/RFLME0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/RFLMF0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/RFLMG0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/RFLMH0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/RFLMI0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/RFLMJ0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/RFLMK0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/RFLML0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/RFLMM0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/RFLMN0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/RFLMO0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/RFLMP0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/RFLMQ0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
sprites/RFLMR0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/RFLMS0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
sprites/RFLMT0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -1,17 +1,17 @@
GameInfo
{
AddEventHandlers = "SWWMCrashHandler", "SWWMBrutalHandler", "SWWMHandler"
AddEventHandlers = "SWWMCrashHandler", "SWWMBrutalHandler", "SWWMVanillaBossHandler", "SWWMHandler"
PlayerClasses = "Demolitionist"
StatusBarClass = "SWWMStatusBar"
BackpackType = "HammerspaceEmbiggener"
StatScreen_Single = "SWWMStatScreen_SP"
StatScreen_Coop = "SWWMStatScreen_Coop"
StatScreen_DM = "SWWMStatScreen_DM"
QuitSound = ""
QuitSound = "misc/teleport"
QuitMessages = "$QUITMSG", "$QUITMSG1", "$QUITMSG2", "$QUITMSG3",
"$QUITMSG4", "$QUITMSG5", "$QUITMSG6", "$QUITMSG7",
"$QUITMSG8", "$QUITMSG9", "$QUITMSG10", "$QUITMSG11",
"$QUITMSG12", "$QUITMSG13", "$QUITMSG14", "$QUITMSG15"
"$QUITMSG12", "$QUITMSG13", "$QUITMSG14"
ChatSound = "misc/chat"
IntermissionMusic = "music/DRAGONY.XM"
DefaultConversationMenuClass = "SWWMConversationMenu"

View file

@ -25,6 +25,7 @@ version "4.3"
#include "zscript/swwm_title.zsc"
#include "zscript/swwm_inter.zsc"
#include "zscript/swwm_strife.zsc"
#include "zscript/swwm_vanillaboss.zsc"
// items
#include "zscript/swwm_health.zsc"
#include "zscript/swwm_armor.zsc"

File diff suppressed because it is too large Load diff

View file

@ -2126,6 +2126,8 @@ Class SWWMHandler : EventHandler
DoKeyTagFix(e.Thing);
SWWMInterest.Spawn(thekey:Key(e.Thing));
}
else if ( e.Thing is 'BossBrain' ) e.Thing.SetTag("$FN_BOSSBRAIN");
else if ( e.Thing is 'CommanderKeen' ) e.Thing.SetTag("$FN_KEEN");
if ( (e.Thing.bSHOOTABLE || e.Thing.bISMONSTER) && !(e.Thing is 'LampMoth') && !(e.Thing is 'CompanionLamp') ) SWWMCombatTracker.Spawn(e.Thing);
}

View file

@ -23,6 +23,8 @@ Class SWWMStatusBar : BaseStatusBar
// the event handler, holding all sorts of stuff
SWWMHandler hnd;
// the boss stuff handler, for the boss healthbar
SWWMVanillaBossHandler bosshnd;
// client cvars
transient CVar safezone, maxchat[2], maxpick, chatduration, msgduration, pickduration, chatcol, teamcol, obitcol, critcol, pickcol, targetter, healthnums, scorenums, scorebonus, targettag, lang;
@ -765,80 +767,79 @@ Class SWWMStatusBar : BaseStatusBar
Screen.DrawText(mTewiFont.mFont,hcolor,margin+108,ss.y-(margin+16),String.Format("%3d",clamp(ht,0,999)),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
private void DrawPickups()
{
if ( !pickduration ) pickduration = CVar.GetCVar('swwm_pickduration',players[consoleplayer]);
if ( !pickcol ) pickcol = CVar.GetCVar('msg0color',players[consoleplayer]);
if ( PickupQueue.Size() <= 0 ) return;
// reverse order since they're drawn bottom to top
int mend = max(0,PickupQueue.Size()-(1+maxpick.GetInt()));
double yy = ss.y-(margin+50);
if ( bosshnd && (bosshnd.alpha > 0.) ) yy -= int(25*clamp(bosshnd.alpha*2.,0.,1.));
for ( int i=PickupQueue.Size()-1; i>=mend; i-- )
{
String cstr = PickupQueue[i].str;
if ( PickupQueue[i].rep > 1 ) cstr.AppendFormat(" (x%d)",PickupQueue[i].rep);
int curtime = (PickupQueue[i].tic+35*pickduration.GetInt())-level.totaltime;
double alph = clamp(curtime/20.,0.,1.);
Font fnt = LangFont(mTewiFont);
BrokenLines l = fnt.BreakLines(cstr,int(ss.x*.75));
int maxlen = 0;
for ( int j=0; j<l.Count(); j++ )
{
int len = fnt.StringWidth(l.StringAt(j));
if ( len > maxlen ) maxlen = len;
}
int h = fnt.GetHeight();
double xx = (ss.x-maxlen)/2.;
Screen.Dim("Black",.8*alph,int((xx-6)*hs.x),int((yy-h*(l.Count()-1))*hs.y),int((maxlen+12)*hs.x),int((h*l.Count()+4)*hs.y));
for ( int j=l.Count()-1; j>=0; j-- )
{
int len = fnt.StringWidth(l.StringAt(j));
xx = (ss.x-len)/2.;
Screen.DrawText(fnt,pickcol.GetInt(),xx,yy+2,l.StringAt(j),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
yy -= h;
}
yy -= 6;
}
}
private void DrawMessages()
{
if ( !chatduration ) chatduration = CVar.GetCVar('swwm_chatduration',players[consoleplayer]);
if ( !msgduration ) msgduration = CVar.GetCVar('swwm_msgduration',players[consoleplayer]);
if ( !pickduration ) pickduration = CVar.GetCVar('swwm_pickduration',players[consoleplayer]);
if ( !pickcol ) pickcol = CVar.GetCVar('msg0color',players[consoleplayer]);
if ( !obitcol ) obitcol = CVar.GetCVar('msg1color',players[consoleplayer]);
if ( !critcol ) critcol = CVar.GetCVar('msg2color',players[consoleplayer]);
if ( !chatcol ) chatcol = CVar.GetCVar('msg3color',players[consoleplayer]);
if ( !teamcol ) teamcol = CVar.GetCVar('msg4color',players[consoleplayer]);
// common message area
if ( MainQueue.Size() > 0 )
if ( MainQueue.Size() <= 0 ) return;
int mstart = max(0,MainQueue.Size()-(1+maxchat[chatopen>=gametic].GetInt()));
double xx = margin, yy = margin;
bool smol = (ss.x<640);
Screen.DrawTexture(ChatTex[smol?3:0],false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy++;
for ( int i=mstart; i<MainQueue.Size(); i++ )
{
int mstart = max(0,MainQueue.Size()-(1+maxchat[chatopen>=gametic].GetInt()));
double xx = margin, yy = margin;
bool smol = (ss.x<640);
Screen.DrawTexture(ChatTex[smol?3:0],false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy++;
for ( int i=mstart; i<MainQueue.Size(); i++ )
int col = critcol.GetInt();
if ( MainQueue[i].type == PRINT_MEDIUM ) col = obitcol.GetInt();
else if ( MainQueue[i].type == PRINT_CHAT ) col = chatcol.GetInt();
else if ( MainQueue[i].type == PRINT_TEAMCHAT ) col = teamcol.GetInt();
String cstr = MainQueue[i].str;
if ( MainQueue[i].rep > 1 ) cstr.AppendFormat(" (x%d)",MainQueue[i].rep);
int curtime = MainQueue[i].tic-level.totaltime;
if ( MainQueue[i].type < PRINT_CHAT ) curtime += 35*msgduration.GetInt();
else curtime += 35*chatduration.GetInt();
double alph = clamp(curtime/20.,0.,1.);
Font fnt = LangFont(mTewiFont);
BrokenLines l = fnt.BreakLines(cstr,smol?211:361);
for ( int j=0; j<l.Count(); j++ )
{
int col = critcol.GetInt();
if ( MainQueue[i].type == PRINT_MEDIUM ) col = obitcol.GetInt();
else if ( MainQueue[i].type == PRINT_CHAT ) col = chatcol.GetInt();
else if ( MainQueue[i].type == PRINT_TEAMCHAT ) col = teamcol.GetInt();
String cstr = MainQueue[i].str;
if ( MainQueue[i].rep > 1 ) cstr.AppendFormat(" (x%d)",MainQueue[i].rep);
int curtime = MainQueue[i].tic-level.totaltime;
if ( MainQueue[i].type < PRINT_CHAT ) curtime += 35*msgduration.GetInt();
else curtime += 35*chatduration.GetInt();
double alph = clamp(curtime/20.,0.,1.);
Font fnt = LangFont(mTewiFont);
BrokenLines l = fnt.BreakLines(cstr,smol?211:361);
for ( int j=0; j<l.Count(); j++ )
{
Screen.DrawTexture(ChatTex[smol?4:1],false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
Screen.DrawText(fnt,col,xx+4,yy,l.StringAt(j),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
yy += 13;
}
}
Screen.DrawTexture(ChatTex[smol?5:2],false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
// pickup messages
if ( PickupQueue.Size() > 0 )
{
// reverse order since they're drawn bottom to top
int mend = max(0,PickupQueue.Size()-(1+maxpick.GetInt()));
double yy = ss.y-(margin+50);
for ( int i=PickupQueue.Size()-1; i>=mend; i-- )
{
String cstr = PickupQueue[i].str;
if ( PickupQueue[i].rep > 1 ) cstr.AppendFormat(" (x%d)",PickupQueue[i].rep);
int curtime = (PickupQueue[i].tic+35*pickduration.GetInt())-level.totaltime;
double alph = clamp(curtime/20.,0.,1.);
Font fnt = LangFont(mTewiFont);
BrokenLines l = fnt.BreakLines(cstr,int(ss.x*.75));
int maxlen = 0;
for ( int j=0; j<l.Count(); j++ )
{
int len = fnt.StringWidth(l.StringAt(j));
if ( len > maxlen ) maxlen = len;
}
int h = fnt.GetHeight();
double xx = (ss.x-maxlen)/2.;
Screen.Dim("Black",.8*alph,int((xx-6)*hs.x),int((yy-h*(l.Count()-1))*hs.y),int((maxlen+12)*hs.x),int((h*l.Count()+4)*hs.y));
for ( int j=l.Count()-1; j>=0; j-- )
{
int len = fnt.StringWidth(l.StringAt(j));
xx = (ss.x-len)/2.;
Screen.DrawText(fnt,pickcol.GetInt(),xx,yy+2,l.StringAt(j),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
yy -= h;
}
yy -= 6;
Screen.DrawTexture(ChatTex[smol?4:1],false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
Screen.DrawText(fnt,col,xx+4,yy,l.StringAt(j),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph);
yy += 13;
}
}
Screen.DrawTexture(ChatTex[smol?5:2],false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
override bool DrawChat( String txt )
@ -953,6 +954,9 @@ Class SWWMStatusBar : BaseStatusBar
DrawInventory();
DrawStatus();
DrawWeapon();
if ( !bosshnd ) bosshnd = SWWMVanillaBossHandler(EventHandler.Find("SWWMVanillaBossHandler"));
else bosshnd.DrawBossBar(self);
DrawPickups();
DrawDeath();
DrawMessages();
}

View file

@ -182,6 +182,7 @@ Class SWWMHealth : Inventory abstract
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags )
{
if ( damageType == 'EndLevel' ) return;
bool shouldautouse = false;
if ( swwm_enforceautousehealth == 1 ) shouldautouse = true;
else if ( swwm_enforceautousehealth == -1 ) shouldautouse = false;

View file

@ -413,7 +413,7 @@ Class PusherWeapon : SWWMWeapon
{
A_QuakeEx(8,8,8,12,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.8);
A_AlertMonsters(1600);
int dmg = int(150*invoker.chargelevel);
int dmg = int(300*invoker.chargelevel);
if ( d.HitType == TRACE_HitActor )
{
double diff = deltaangle(self.angle,AngleTo(d.HitActor));

View file

@ -489,7 +489,7 @@ Class Demolitionist : PlayerPawn
// bump down weapon
bumpdown = true;
bumpvelz = -lastvelz;
if ( lastvelz < -30 )
if ( lastvelz < -25 )
{
let s = Spawn("DemolitionistShockwave",pos);
s.target = self;
@ -602,6 +602,13 @@ Class Demolitionist : PlayerPawn
// lucky collar
if ( Health < 25 ) damage /= 4;
if ( source == self ) damage /= 2;
if ( !inflictor && !source && (CurSector.flags&Sector.SECF_ENDLEVEL) )
{
// end level hax
damage = max(50,health-100);
flags |= DMG_FORCED|DMG_NO_ARMOR;
mod = 'EndLevel';
}
lastdamage = Super.DamageMobj(inflictor,source,damage,mod,flags,angle);
lastdamagetic = max(lastdamagetic,gametic+clamp(lastdamage/2,10,40));
if ( (lastdamage > 0) && (PainChance == 0) && (level.maptime>lastmpain) )

View file

@ -40,6 +40,7 @@ Class GrilledCheeseSandwich : Inventory
}
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags )
{
if ( damageType == 'EndLevel' ) return;
if ( passive && (Owner.Health-damage <= 0) && (Amount > 0) )
{
newdamage = 0;
@ -502,15 +503,13 @@ Class InvinciballPower : Powerup
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags )
{
if ( damageType == 'EndLevel' ) return;
if ( (damage > 0) && passive )
{
if ( (damagetype == 'Drowning') || (damagetype == 'Falling') || (damagetype == 'Poison') || (damagetype == 'PoisonCloud') )
return; // these go through armor and get ignored by the player
if ( damageType == 'Ynykron' )
{
newdamage = damage;
return;
}
return; // can't block this
newdamage = 0;
if ( level.maptime > lasteffect+5 )
{

View file

@ -172,7 +172,7 @@ Class CandyBeam : Actor
{
RenderStyle "Add";
Alpha 0.4;
DamageFunction 12;
DamageFunction 20;
ReactionTime 12;
Radius 0.1;
Height 0;
@ -232,7 +232,7 @@ Class CandyPop : Actor
{
A_AlertMonsters();
SWWMHandler.DoBlast(self,120,60000);
A_Explode(50,120);
A_Explode(100,120);
Scale *= FRandom[ExploS](0.6,1.8);
Scale.x *= RandomPick[ExploS](-1,1);
Scale.y *= RandomPick[ExploS](-1,1);
@ -273,7 +273,7 @@ Class TinyCandyBeam : CandyBeam
Default
{
ReactionTime 12;
DamageFunction 5;
DamageFunction 10;
}
States
{
@ -299,7 +299,7 @@ Class TinyCandyPop : CandyPop
{
A_AlertMonsters();
SWWMHandler.DoBlast(self,80,32000);
A_Explode(20,80);
A_Explode(40,80);
Scale *= FRandom[ExploS](0.6,1.8);
Scale.x *= RandomPick[ExploS](-1,1);
Scale.y *= RandomPick[ExploS](-1,1);
@ -359,7 +359,7 @@ Class CandyMagArm : Actor
SWWMHandler.DoBlast(self,50+6*reactiontime,3000+800*reactiontime);
double spd = vel.length();
vel = (vel*.1+(FRandom[ExploS](-.7,.7),FRandom[ExploS](-.7,.7),FRandom[ExploS](-.7,.7))).unit()*spd;
A_Explode(20+reactiontime*3,50+6*reactiontime);
A_Explode(40+reactiontime*5,50+6*reactiontime);
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,5);
let s = Spawn("SWWMSmoke",pos);
s.vel = pvel+vel*.2;
@ -435,7 +435,7 @@ Class CandyMagArmBig : CandyMagArm
SWWMHandler.DoBlast(self,100+8*reactiontime,3000+900*reactiontime);
double spd = vel.length();
vel = (vel*.1+(FRandom[ExploS](-.5,.5),FRandom[ExploS](-.5,.5),FRandom[ExploS](-.5,.5))).unit()*spd;
A_Explode(50+reactiontime*5,100+8*reactiontime);
A_Explode(80+reactiontime*8,100+8*reactiontime);
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,5);
let s = Spawn("SWWMSmoke",pos);
s.vel = pvel+vel*.2;
@ -512,7 +512,7 @@ Class CandyGunProj : Actor
Scale *= 6.+.2*special1;
A_AlertMonsters();
SWWMHandler.DoBlast(self,300+20*special1,80000+8000*special1);
A_Explode(1500+200*special1,300+20*special1);
A_Explode(3000+400*special1,300+20*special1);
A_QuakeEx(9,9,9,70,0,1500+100*special1,"",QF_RELATIVE|QF_SCALEDOWN,falloff:1200,rollintensity:2.);
A_StartSound("candygun/gunhit",CHAN_VOICE,attenuation:.24);
A_StartSound("candygun/gunhit",CHAN_WEAPON,attenuation:.12);
@ -621,7 +621,7 @@ Class CandyMagProj : Actor
Scale *= 3.+.2*special1;
A_AlertMonsters();
SWWMHandler.DoBlast(self,250+25*special1,80000+8000*special1);
A_Explode(300+200*special1,250+25*special1);
A_Explode(600+400*special1,250+25*special1);
A_QuakeEx(9,9,9,30,0,500+80*special1,"",QF_RELATIVE|QF_SCALEDOWN,falloff:500,rollintensity:2.);
A_StartSound("candygun/maghit",CHAN_VOICE,attenuation:.24);
A_StartSound("candygun/maghit",CHAN_WEAPON,attenuation:.12);
@ -713,7 +713,7 @@ Class CandyBulletImpact : Actor
Super.PostBeginPlay();
A_AlertMonsters();
SWWMHandler.DoBlast(self,200,48000);
A_Explode(300,200);
A_Explode(350,200);
A_QuakeEx(6,6,6,15,0,300,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200,rollintensity:0.2);
A_StartSound("candygun/hit",CHAN_VOICE,attenuation:.25);
A_StartSound("candygun/hit",CHAN_WEAPON,attenuation:.5);
@ -872,7 +872,7 @@ Class CandyGun : SWWMWeapon
SWWMBulletTrail.DoTrail(self,origin,dir,10000,2);
if ( d.HitType == TRACE_HitActor )
{
int dmg = 350;
int dmg = 500;
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 || d.HitActor.bINVULNERABLE )

View file

@ -0,0 +1,274 @@
// This is stuff for making vanilla doom/heretic/hexen boss encounters
// a bit more... "fair", so to speak
// Also adds cool Souls-style healthbars
Class SWWMVanillaBossHandler : EventHandler
{
String bosstag;
Array<Actor> bossactors;
Actor bossbrainactor;
Actor bossviewactor;
TextureID facetex[5];
bool initialized;
ui bool ui_initialized;
ui TextureID bbar_f, bbar_r, bbar_d;
ui double alpha;
ui DynamicValueInterpolator ihealth, ihealthr;
ui int thealth, hmax;
ui int oldhealth[30];
ui int cummdamage, lastcummtic; // please do not misread
transient ui CVar dodrawbossbar;
override void WorldThingSpawned( WorldEvent e )
{
bool upgrademe = swwm_upgradebosses;
if ( gameinfo.gametype&GAME_Doom )
{
if ( level.mapname ~== "E1M8" )
{
if ( e.Thing is 'BaronOfHell' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 3;
}
bosstag = "$BT_BRUISERS";
}
else if ( level.mapname ~== "E2M8" )
{
if ( e.Thing is 'Cyberdemon' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 4;
}
bosstag = "$BT_CYBIE";
}
else if ( (level.mapname ~== "E3M8") || (level.mapname ~== "E4M8") )
{
if ( e.Thing is 'Spidermastermind' )
{
bossactors.Push(e.Thing);
if ( upgrademe )
{
if ( level.mapname ~== "E3M8" ) e.Thing.Health *= 5;
else e.Thing.Health *= 3;
}
}
bosstag = "$BT_SPIDER";
}
else if ( level.mapname ~== "MAP30" )
{
if ( e.Thing is 'BossBrain' )
{
bossbrainactor = e.Thing;
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 16; // goodbye, instakills
}
if ( e.Thing is 'BossEye' )
bossviewactor = e.Thing;
bosstag = "$BT_IOS";
}
}
else if ( gameinfo.gametype&GAME_Heretic )
{
if ( (level.mapname ~== "E1M8") || (level.mapname ~== "E4M8") )
{
if ( e.Thing is 'IronLich' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 4;
}
bosstag = "$BT_LICHES";
}
else if ( (level.mapname ~== "E2M8") || (level.mapname ~== "E5M8") )
{
if ( e.Thing is 'Minotaur' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 2;
}
bosstag = "$BT_MINOTAUR";
}
else if ( level.mapname ~== "E3M8" )
{
if ( e.Thing is 'Sorcerer1' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 2;
bosstag = "$BT_DSPARIL";
}
else if ( e.Thing is 'Sorcerer2' )
{
// second phase
bossactors.Clear();
initialized = false;
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 3;
bosstag = "$BT_DSPARIL2";
}
}
}
else if ( gameinfo.gametype&GAME_Hexen )
{
if ( e.Thing is 'ClericBoss' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 3;
bosstag = "$BT_CLERIC";
}
else if ( e.Thing is 'FighterBoss' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 3;
bosstag = "$BT_FIGHTER";
}
else if ( e.Thing is 'MageBoss' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 3;
bosstag = "$BT_MAGE";
}
else if ( e.Thing is 'Dragon' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 4;
bosstag = "$BT_DRAGON";
}
else if ( e.Thing is 'Heresiarch' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 6;
bosstag = "$BT_HERESIARCH";
}
else if ( e.Thing is 'Korax' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 8;
bosstag = "$BT_KORAX";
}
}
}
override void WorldTick()
{
if ( initialized ) return;
// wait until bosses are active
for ( int i=0; i<bossactors.Size(); i++ )
{
if ( !bossactors[i] ) continue;
if ( (!bossactors[i].target || !bossactors[i].CheckSight(bossactors[i].target))
&& (!bossviewactor || (bossviewactor && !bossviewactor.target)) ) continue;
initialized = true;
break;
}
}
override void PostUITick()
{
if ( (!ui_initialized && initialized) || (ui_initialized && !initialized) )
{
ui_initialized = true;
thealth = 0;
for ( int i=0; i<bossactors.Size(); i++ )
{
if ( !bossactors[i] ) continue;
thealth += bossactors[i].Health;
}
hmax = thealth;
for ( int i=0; i<30; i++ ) oldhealth[i] = thealth;
cummdamage = 0;
if ( !ihealth ) ihealth = DynamicValueInterpolator.Create(thealth,.1,1,1000);
else ihealth.Reset(thealth);
if ( !ihealthr ) ihealthr = DynamicValueInterpolator.Create(thealth,.5,1,1000);
else ihealthr.Reset(thealth);
return;
}
if ( !ui_initialized ) return;
// update healthbar
int newhealth = 0;
for ( int i=0; i<bossactors.Size(); i++ )
{
if ( !bossactors[i] ) continue;
newhealth += bossactors[i].Health;
}
oldhealth[0] = newhealth;
int curcumm = max(0,thealth-newhealth);
if ( curcumm > 0 )
{
cummdamage += curcumm;
lastcummtic = gametic;
}
else if ( gametic > lastcummtic+150 ) cummdamage = 0;
thealth = newhealth;
ihealthr.Update(thealth);
if ( thealth > oldhealth[29] )
for ( int i=29; i>0; i-- )
oldhealth[i] = thealth;
ihealth.Update(oldhealth[29]);
for ( int i=29; i>0; i-- )
oldhealth[i] = oldhealth[i-1];
if ( thealth > 0 ) alpha = min(3.,alpha+1./30.);
else alpha = max(0,alpha-1./50.);
}
// called by HUD
ui void DrawBossBar( SWWMStatusBar bar )
{
if ( !ui_initialized || (alpha <= 0.) ) return;
if ( !dodrawbossbar ) dodrawbossbar = CVar.GetCVar('swwm_bosshealthbars',players[consoleplayer]);
if ( !dodrawbossbar.GetBool() ) return;
if ( !bbar_f ) bbar_f = TexMan.CheckForTexture("graphics/HUD/BossHealthBarBox.png",TexMan.Type_Any);
if ( !bbar_r ) bbar_r = TexMan.CheckForTexture("graphics/HUD/BossHealthBar.png",TexMan.Type_Any);
if ( !bbar_d ) bbar_d = TexMan.CheckForTexture("graphics/HUD/BossHealthBarDecay.png",TexMan.Type_Any);
Vector2 vpos = ((bar.ss.x-300)/2.,bar.ss.y-(bar.margin+35));
Screen.DrawTexture(bbar_f,false,vpos.x-2,vpos.y-2,DTA_VirtualWidthF,bar.ss.x,DTA_VirtualHeightF,bar.ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
int rw = int(clamp((ihealthr.GetValue()*300.)/hmax,0.,300.));
int dw = int(clamp((ihealth.GetValue()*300.)/hmax,0.,300.));
Screen.DrawTexture(bbar_d,false,vpos.x,vpos.y,DTA_VirtualWidthF,bar.ss.x,DTA_VirtualHeightF,bar.ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_WindowRight,dw);
Screen.DrawTexture(bbar_r,false,vpos.x,vpos.y,DTA_VirtualWidthF,bar.ss.x,DTA_VirtualHeightF,bar.ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_WindowRight,rw);
Font barfnt = bar.LangFont(bar.mTewiFont);
Font dmgfnt = bar.mTewiFont.mFont;
if ( (cummdamage > 0) && (gametic < lastcummtic+150) )
{
double calph = clamp(((lastcummtic+150)-gametic)/50.,0.,1.);
string dnum = String.Format("%d",cummdamage);
Screen.DrawText(dmgfnt,Font.CR_RED,vpos.x+300-dmgfnt.StringWidth(dnum),vpos.y-(dmgfnt.GetHeight()+2),dnum,DTA_VirtualWidthF,bar.ss.x,DTA_VirtualHeightF,bar.ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha*calph);
}
Screen.DrawText(barfnt,Font.CR_WHITE,vpos.x,vpos.y-(barfnt.GetHeight()+2),StringTable.Localize(bosstag),DTA_VirtualWidthF,bar.ss.x,DTA_VirtualHeightF,bar.ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
}
// can't use this until I actually figure out how to make those walls damageable
/*private bool IsIOSWall( Line l )
{
if ( !facetex[0] )
{
facetex[0] = TexMan.CheckForTexture("ZZZFACE1",TexMan.Type_Wall);
facetex[1] = TexMan.CheckForTexture("ZZZFACE2",TexMan.Type_Wall);
facetex[2] = TexMan.CheckForTexture("ZZZFACE3",TexMan.Type_Wall);
facetex[3] = TexMan.CheckForTexture("ZZZFACE4",TexMan.Type_Wall);
facetex[4] = TexMan.CheckForTexture("ZZZFACE5",TexMan.Type_Wall);
}
for ( int i=0; i<5; i++ )
{
for ( int j=0; j<3; j++ )
{
if ( l.sidedef[0].GetTexture(j) == facetex[i] ) return true;
if ( l.sidedef[1] && l.sidedef[1].GetTexture(j) == facetex[i] ) return true;
}
}
return false;
}
override void WorldLineDamaged( WorldEvent e )
{
// allow boss brain to take (reduced) damage from the facewall being shot
if ( level.mapname ~== "MAP30" )
{
if ( !IsIOSWall(e.DamageLine) ) return;
if ( bossbrainactor )
bossbrainactor.DamageMobj(e.Inflictor,e.DamageSource,e.Damage/3,e.DamageType,e.DamageFlags,e.DamageAngle);
e.NewDamage = 0;
}
}*/
}