Various changes (see full commit message):

- Adjusted timing of crackshot sub-grenades so they're more useful
 - Added "Humiliation" bonus for killing an enemy with the Deep Impact primary
 - Added per-ammo obituaries to Wallbuster
 - Adjusted Pusher behaviour so it stops gracefully at skies
 - More accurate tracking of "favourite weapon"
 - Changed Vanilla Boss Enhancer so it only works on vanilla maps
This commit is contained in:
Mari the Deer 2020-06-07 14:47:27 +02:00
commit 4d3d1bf84e
14 changed files with 293 additions and 118 deletions

View file

@ -12,7 +12,11 @@ after the first release.
- PROWEL & TADEL (Ultra Suite 2 & 3)
- Super Happy Fun Ball (SWWM Z)
* Additional Demolitionist Menu features
- Per-monster kill tracker in stats tab
- Stats tab subsections
- Monster kill tracker
- Item pickup tracker
- Level stats tracker
- Achevements tracker (see below)
- Radio (add-on)
- Pong minigame
- Selling items at the store
@ -45,7 +49,7 @@ after the first release.
* Fake livestream chat overlay, with dynamic reactions to all sorts of stuff
* Character and item images for the library
* Full Mashiro model for Lämp easter egg
* Summonable Ibuki companion (w/ optional "stream friendly" clothing)
* Ibuki companion add-on (w/ optional "stream friendly" clothing)
* Saya model, for scenes or something idk
* Japanese Localization???
* Japanese localization???
* Strife support, with rewritten dialogue

View file

@ -522,6 +522,7 @@ FN_KEEN = "Ruined by Bethesda";
// obituaries
O_PUSHER = "%k opened some air holes into %o.";
O_DEEPIMPACT = "%o was impacted deeply by %k.";
O_DEEPIMPACT_WEAK = "%k coughed in %o's general direction.";
O_EXPLODIUM = "%k inflicted severe knee explosions onto %o.";
O_SPREADGUN_RED = "%k gave %o a mouthful of shot.";
O_SPREADGUN_GREEN = "%o got slugged by %k.";
@ -530,7 +531,10 @@ O_SPREADGUN_BLUE = "%k made %o very salty.";
O_SPREADGUN_BLACK = "%k set %o on fire along with everything around %h.";
O_SPREADGUN_PURPLE = "%o was conked by %k's lead ball.";
O_SPREADGUN_GOLD = "%o ate up %k's golden blast.";
O_WALLBUSTER = "%k gave %o a mighty busting.";
O_WALLBUSTER_RED = "%k gave %o a mighty busting.";
O_WALLBUSTER_GREEN = "%k turned %o into a donut.";
O_WALLBUSTER_BLUE = "%k made %o REALLY salty.";
O_WALLBUSTER_PURPLE = "%k inflicted lead ball torture onto %o.";
O_EVISCERATOR = "%o was eviscerated by %k.";
O_HELLBLAZER = "%k blasted %o into burning bits.";
O_SPARKSTER = "%o got sparked hard by %k.";
@ -681,6 +685,7 @@ SWWM_NEXIT = "Exit";
SWWM_SEXIT = "Secret Exit";
SWWM_LEG = "Legendary ";
SWWM_LEGPREFIX = "L";
SWWM_SHAMEFUL = "Humiliation";
// score messages
SWWM_FINDSECRET = "\cf%s\cf found a secret. +%d\c-";
SWWM_FINDKEY = "\cf%s\cf got the %s\cf. +%d\c-";

View file

@ -513,6 +513,7 @@ 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.";
O_DEEPIMPACT_WEAK = "%k tosió en la dirección general de %o.";
O_EXPLODIUM = "%k inflingió explosiones de rodilla severas a %o.";
O_SPREADGUN_RED = "%k le dió a %o un bocado de perdigones.";
O_SPREADGUN_GREEN = "%o fue sluggead@[ao_esp] por %k.";
@ -521,7 +522,10 @@ O_SPREADGUN_BLUE = "%k puso a %o muy salad@[ao_esp].";
O_SPREADGUN_BLACK = "%k prendió fuego a %o y todo lo que había a su alrededor.";
O_SPREADGUN_PURPLE = "A %o le salió un chichón con la bola de plomo de %k.";
O_SPREADGUN_GOLD = "%o se tragó la explosión dorada de %k.";
O_WALLBUSTER = "%k ha destrozado a %o pero bien.";
O_WALLBUSTER_RED = "%k ha destrozado a %o pero bien.";
O_WALLBUSTER_GREEN = "%k convirtió a %o en rosquilla.";
O_WALLBUSTER_BLUE = "%k puso a %o muy MUY salad@[ao_esp].";
O_WALLBUSTER_PURPLE = "%k inflingió una tortura de bolas de plomo a %o.";
O_EVISCERATOR = "%o fue descuartizad@[ao_esp] por %k.";
O_HELLBLAZER = "%k reventó a %o en cachitos humeantes.";
O_SPARKSTER = "%o fue bien chispead@[ao_esp] por %k.";
@ -667,6 +671,7 @@ SWWM_NEXIT = "Salida";
SWWM_SEXIT = "Salida Secreta";
SWWM_LEG = " Legendario";
SWWM_LEGPREFIX = "R";
SWWM_SHAMEFUL = "Humillación";
// score messages
SWWM_FINDSECRET = "\cf%s\cf encontró un secreto. +%d\c-";
SWWM_FINDKEY = "\cf%s\cf obtuvo la %s\cf. +%d\c-";

View file

@ -1,2 +1,2 @@
[default]
SWWM_MODVER="\cxSWWM GZ\c- r319 (Sat 6 Jun 23:56:13 CEST 2020)";
SWWM_MODVER="\cxSWWM GZ\c- r320 (Sun 7 Jun 14:47:27 CEST 2020)";

View file

@ -853,7 +853,7 @@ Class HellblazerClusterMini : HellblazerMissile
s.alpha *= .4;
s.vel = .3*vel + (traildir+(FRandom[Hellblazer](-.4,.4),FRandom[Hellblazer](-.4,.4),FRandom[Hellblazer](-.4,.4))).unit()*FRandom[Hellblazer](1.,2.);
}
if ( (deto > 2) && (GetAge() > 4) )
if ( (deto > 1) && (GetAge() > 2) )
{
ExplodeMissile();
return;

View file

@ -427,7 +427,16 @@ Class Wallbuster : SWWMWeapon
transient ui TextureID WeaponBox, AmmoIcon[4], LoadIcon[4], UsedIcon[4], EmptyIcon;
transient ui Font TewiFont;
Class<Ammo> curobt;
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
{
if ( curobt is 'RedShell' ) return StringTable.Localize("$O_WALLBUSTER_RED");
if ( curobt is 'GreenShell' ) return StringTable.Localize("$O_WALLBUSTER_GREEN");
if ( curobt is 'BlueShell' ) return StringTable.Localize("$O_WALLBUSTER_BLUE");
if ( curobt is 'PurpleShell' ) return StringTable.Localize("$O_WALLBUSTER_PURPLE");
return Super.GetObituary(victim,inflictor,mod,playerattack);
}
override void DrawWeapon( double TicFrac, double bx, double by, Vector2 hs, Vector2 ss )
{
static const Class<Ammo> types[] = {"RedShell","GreenShell","BlueShell","PurpleShell"};
@ -788,6 +797,7 @@ Class Wallbuster : SWWMWeapon
b.y += 8;
Vector2 n = (b.x*cos(t2)-b.y*sin(t2),b.x*sin(t2)+b.y*cos(t2));
origin = level.Vec3Offset(base,n.x*y+n.y*z);
invoker.curobt = types[which];
switch ( which )
{
case 1:
@ -840,6 +850,7 @@ Class Wallbuster : SWWMWeapon
b.pitch = asin(-x2.z);
b.Stamina += howmany*16;
b.Accuracy += 2+howmany/5;
b.Args[1] = 1; // came from wallbuster
}
for ( int i=0; i<(9-howmany/3); i++ )
{
@ -877,6 +888,7 @@ Class Wallbuster : SWWMWeapon
p.angle = atan2(dir.y,dir.x);
p.pitch = asin(-dir.z);
p.vel = dir*p.speed*1.25;
p.special1 = 1; // came from wallbuster
for ( int i=0; i<(4-howmany/8); i++ )
{
let s = Spawn("SWWMViewSmoke",origin);
@ -1102,7 +1114,7 @@ Class Wallbuster : SWWMWeapon
{
Tag "$T_WALLBUSTER";
Inventory.PickupMessage "$I_WALLBUSTER";
Obituary "$O_WALLBUSTER";
Obituary "$O_WALLBUSTER_RED";
Weapon.SlotNumber 4;
Weapon.SelectionOrder 2200;
Weapon.UpSound "wallbuster/select";

View file

@ -248,9 +248,17 @@ Class SWWMStats : Thinker
{
Class<Weapon> which = myplayer.ReadyWeapon?myplayer.ReadyWeapon.GetClass():null;
if ( inflictor is 'Weapon' ) which = Weapon(inflictor).GetClass();
// properly credit napalm damage to Spreadgun
if ( inflictor is 'OnFire' ) which = 'Spreadgun';
// TODO handle other projectiles
// properly credit some projectiles to their respective gun
if ( inflictor is 'AirBullet' ) which = 'DeepImpact';
else if ( inflictor is 'PusherProjectile' ) which = 'PusherWeapon';
else if ( (inflictor is 'ExplodiumMagArm') || (inflictor is 'ExplodiumMagProj') || (inflictor is 'ExplodiumBulletImpact') ) which = 'ExplodiumGun';
else if ( (inflictor is 'DragonBreathArm') || ((inflictor is 'SaltImpact') && !inflictor.Args[0]) || ((inflictor is 'SaltBeam') && !inflictor.Args[1]) || (inflictor is 'OnFire') || (inflictor is 'FlamingChunk') || ((inflictor is 'TheBall') && !inflictor.special1) || (inflictor is 'GoldenImpact') || (inflictor is 'GoldenSubImpact') || (inflictor is 'GoldenSubSubImpact') ) which = 'Spreadgun';
else if ( ((inflictor is 'SaltImpact') && inflictor.Args[0]) || ((inflictor is 'SaltBeam') && inflictor.Args[1]) || ((inflictor is 'TheBall') && inflictor.special1) ) which = 'Wallbuster';
else if ( (inflictor is 'EvisceratorChunk') || (inflictor is 'EvisceratorProj') ) which = 'Eviscerator';
else if ( (inflictor is 'HellblazerRavagerArm') || (inflictor is 'HellblazerWarheadArm') ) which = 'Hellblazer';
else if ( (inflictor is 'BigBiospark') || (inflictor is 'BiosparkBall') || (inflictor is 'BiosparkBeamImpact') || (inflictor is 'BiosparkComboImpact') || (inflictor is 'BiosparkBeam') || (inflictor is 'BiosparkArc') ) which = 'Sparkster';
else if ( (inflictor is 'CandyBeam') || (inflictor is 'CandyPop') || (inflictor is 'CandyMagArm') || (inflictor is 'CandyGunProj') || (inflictor is 'CandyMagProj') || (inflictor is 'CandyBulletImpact') ) which = 'CandyGun';
// TODO Silver Bullet / Ynykron projs when implemented
if ( !which ) return;
for ( int i=0; i<wstats.Size(); i++ )
{
@ -2423,6 +2431,17 @@ Class SWWMHandler : EventHandler
if ( e.DamageSource.player == players[consoleplayer] )
scr = SWWMScoreObj.Spawn(score,e.Thing.Vec3Offset(0,0,e.Thing.Height/2));
int ofs = 0;
if ( e.DamageType == 'Push' )
{
score += 1000;
if ( scr )
{
scr.xscore[ofs] = 0;
scr.xtcolor[ofs] = Font.CR_FIRE;
scr.xstr[ofs] = StringTable.Localize("$SWWM_SHAMEFUL");
scr.xcnt = ++ofs;
}
}
if ( ((e.Thing.Health <= e.Thing.GetGibHealth()) || (e.DamageSource.bEXTREMEDEATH) || (e.Inflictor && e.Inflictor.bEXTREMEDEATH) || (e.DamageType == 'Extreme')) && !e.DamageSource.bNOEXTREMEDEATH && (!e.Inflictor || !e.Inflictor.bNOEXTREMEDEATH) )
{
score = int(score*1.25);

View file

@ -8,9 +8,11 @@ Class AirBullet : FastProjectile
Default
{
Obituary "$O_DEEPIMPACT";
Radius 2;
Height 4;
DamageFunction 100;
DamageType 'AirRip';
Speed 400;
PROJECTILE;
+FORCERADIUSDMG;
@ -436,7 +438,7 @@ Class DeepImpact : SWWMWeapon
{
Tag "$T_DEEPIMPACT";
Inventory.PickupMessage "$I_DEEPIMPACT";
Obituary "$O_DEEPIMPACT";
Obituary "$O_DEEPIMPACT_WEAK";
Weapon.UpSound "deepimpact/select";
Weapon.SlotNumber 1;
Weapon.SelectionOrder 3000;

View file

@ -140,7 +140,7 @@ Class PusherProjectile : Actor
pitch += clamp(deltaangle(pitch,asin(-dir.z)),-2,2);
// cancel if we hit a wall dead-on
FLineTraceData d;
LineTrace(oldangle,30,oldpitch,TRF_THRUACTORS,5,data:d);
LineTrace(oldangle,30,oldpitch,TRF_THRUACTORS|TRF_NOSKY,5,data:d);
if ( d.HitType != TRACE_HitNone )
{
angle = oldangle;
@ -150,10 +150,31 @@ Class PusherProjectile : Actor
ExplodeMissile(BlockingLine,BlockingMobj);
}
}
private bool HitSkyLine( Line l, int hitside )
{
if ( !l ) return false;
// if it's onesided, check if it's a Line_Horizon
if ( !l.sidedef[1] ) return (l.special == Line_Horizon);
Sector outs, ins;
if ( hitside )
{
ins = l.backsector;
outs = l.frontsector;
}
else
{
ins = l.frontsector;
outs = l.backsector;
}
// return true if we're in a sector with sky and we hit the upper part of the line
if ( ins.GetTexture(1) != skyflatnum ) return false;
return (outs.ceilingplane.ZAtPoint(pos.xy) <= pos.z);
}
void A_HandleBounce()
{
Vector3 HitNormal = -vel.unit();
F3DFloor ff;
int lineside = 1;
if ( BlockingFloor )
{
// find closest 3d floor for its normal
@ -182,7 +203,10 @@ Class PusherProjectile : Actor
{
HitNormal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
if ( !SWWMUtility.PointOnLineSide(pos.xy,BlockingLine) )
{
lineside = 0;
HitNormal *= -1;
}
}
else if ( BlockingMobj )
{
@ -204,6 +228,13 @@ Class PusherProjectile : Actor
angle = oldangle;
pitch = oldpitch;
vel = oldvel;
// try to guess if we hit the sky
if ( HitSkyLine(BlockingLine,lineside) || (BlockingCeiling && (ceilingpic == skyflatnum)) || (BlockingFloor && (floorpic == skyflatnum)) )
{
special1 = 0;
ExplodeMissile();
return;
}
// re-do the bounce with our formula
vel = .8*((vel dot HitNormal)*HitNormal*(-1.8+FRandom[Pusher](.0,.8))+vel);
A_StartSound("pusher/bounce",volume:.3);
@ -243,6 +274,8 @@ Class PusherProjectile : Actor
bNOGRAVITY = true;
}
else pitch = 0;
gravity = 1.;
ClearBounce();
bSPECIAL = true;
A_SetSize(20,16);
A_ChangeLinkFlags(0);
@ -287,7 +320,10 @@ Class PusherProjectile : Actor
XZW1 A 0 A_HandleBounce();
Goto Spawn;
Death:
XZW1 A -1 A_BecomePickup();
XZW1 A 0 A_BecomePickup();
XZW1 A 1 A_JumpIf(pos.z<=floorz,1);
Wait;
XZW1 A -1 A_StartSound("pusher/bounce");
Stop;
}
}

View file

@ -561,6 +561,11 @@ Class SaltImpact : Actor
+NOTELEPORT;
+FOILINVUL;
}
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
{
if ( special1 == 1 ) return StringTable.Localize("$O_WALLBUSTER_BLUE");
return Super.GetObituary(victim,inflictor,mod,playerattack);
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
@ -636,6 +641,11 @@ Class SaltBeam : Actor
+FOILINVUL;
}
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
{
if ( special1 == 1 ) return StringTable.Localize("$O_WALLBUSTER_BLUE");
return Super.GetObituary(victim,inflictor,mod,playerattack);
}
void SpreadOut()
{
special1 = 1;
@ -697,6 +707,7 @@ Class SaltBeam : Actor
i.target = target;
i.special1 = (Stamina-9)/4;
i.special2 = Accuracy;
i.args[0] = args[1];
}
return;
}
@ -708,6 +719,7 @@ Class SaltBeam : Actor
i.target = target;
i.special1 = (Stamina-9)/4;
i.special2 = Accuracy;
i.args[0] = args[1];
return;
}
// next beam
@ -721,6 +733,7 @@ Class SaltBeam : Actor
next.target = target;
next.special2 = (special2+1)%10;
next.args[0] = args[0]+1;
next.args[1] = args[1];
next.SetStateLabel("TrailSpawn");
}
@ -1325,6 +1338,11 @@ Class TheBall : Actor
Radius 2;
Height 2;
}
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
{
if ( special1 == 1 ) return StringTable.Localize("$O_WALLBUSTER_PURPLE");
return Super.GetObituary(victim,inflictor,mod,playerattack);
}
override int SpecialMissileHit( Actor victim )
{
if ( (vel.length() <= 5) || ((victim == target) && !bHITOWNER) || (victim == lasthit) || (!victim.bSHOOTABLE && !victim.bSOLID) )

View file

@ -1208,6 +1208,7 @@ Class BiosparkBeam : Actor
Default
{
Obituary "$O_SPARKSTER";
RenderStyle "Add";
DamageFunction 30;
Speed 256;
@ -1485,6 +1486,7 @@ Class BiosparkArc : Actor
}
Default
{
Obituary "$O_SPARKSTER";
RenderStyle "Add";
DamageFunction 5;
ReactionTime 16;

View file

@ -36,6 +36,7 @@ Class ExplodiumMagArm : Actor
{
Default
{
Obituary "$O_EXPLODIUM";
PROJECTILE;
+THRUACTORS;
+BOUNCEONWALLS;
@ -105,6 +106,7 @@ Class ExplodiumMagProj : Actor
Default
{
Obituary "$O_EXPLODIUM";
DamageType "Explodium";
Radius 6;
Height 6;
@ -212,6 +214,7 @@ Class ExplodiumBulletImpact : Actor
{
Default
{
Obituary "$O_EXPLODIUM";
DamageType "Explodium";
RenderStyle "Add";
Scale 1.2;

View file

@ -174,6 +174,7 @@ Class CandyBeam : Actor
}
Default
{
Obituary "$O_CANDYGUN";
RenderStyle "Add";
Alpha 0.4;
DamageFunction 20;
@ -201,6 +202,7 @@ Class CandyPop : Actor
{
Default
{
Obituary "$O_CANDYGUN";
DamageType "Explodium";
RenderStyle "Add";
Scale 2.;
@ -329,6 +331,7 @@ Class CandyMagArm : Actor
{
Default
{
Obituary "$O_CANDYGUN";
PROJECTILE;
+THRUACTORS;
+BOUNCEONWALLS;
@ -485,6 +488,7 @@ Class CandyGunProj : Actor
Default
{
Obituary "$O_CANDYGUN";
DamageType "Explodium";
Radius 6;
Height 6;
@ -594,6 +598,7 @@ Class CandyMagProj : Actor
Default
{
Obituary "$O_CANDYGUN";
DamageType "Explodium";
Radius 6;
Height 6;
@ -700,6 +705,7 @@ Class CandyBulletImpact : Actor
{
Default
{
Obituary "$O_CANDYGUN";
DamageType "Explodium";
RenderStyle "Add";
Scale 2.;

View file

@ -21,144 +21,207 @@ Class SWWMVanillaBossHandler : EventHandler
ui int cummdamage, lastcummtic; // please do not misread
transient ui CVar dodrawbossbar;
enum EVanillaMap
{
MAP_NONE,
MAP_DE1M8,
MAP_DE2M8,
MAP_DE3M8_DE4M8,
MAP_HE1M8_HE4M8,
MAP_HE2M8_HE5M8,
MAP_HE3M8,
MAP_DMAP07,
MAP_DMAP30,
MAP_HMAP12,
MAP_HMAP23_HMAP27,
MAP_HMAP36,
MAP_HMAP37,
MAP_HMAP38,
MAP_HMAP40,
};
private int WhichVanillaBossMap()
{
String mapsum = level.GetChecksum();
if ( (mapsum ~== "94500F4B006B316FE03AC46865AEABF8")
|| (mapsum ~== "97079958C7E89C1908890730B8B9FEB7")
|| (mapsum ~== "058FB092EA1B70DA1E3CBF501C4A91A1") )
return MAP_DE1M8;
if ( mapsum ~== "EFFE91DF41AD41F6973C06F0AD67DDB9" )
return MAP_DE2M8;
if ( (mapsum ~== "EF128313112110ED6C1549AF96AF26C9")
|| (mapsum ~== "2DC939E508AB8EB68AF79D5B60568711") )
return MAP_DE3M8_DE4M8;
if ( (mapsum ~== "27639D04F8090D57A47D354992435893")
|| (mapsum ~== "30D1480A6D4F3A3153739D4CCF659C4E") )
return MAP_HE1M8_HE4M8;
if ( (mapsum ~== "5158C22A0F30CE5E558FD2A05D67685E")
|| (mapsum ~== "85AC7D20D18F9BC49B9696CC2E67F029") )
return MAP_HE2M8_HE5M8;
if ( mapsum ~== "4719C2C71EF28F52310B889DD5A9778B" )
return MAP_HE3M8;
if ( mapsum ~== "291F24417FB3DD411339AE82EF9B3597" )
return MAP_DMAP07;
if ( mapsum ~== "5EECD88F4491F516D590CE4BBF45F532" )
return MAP_DMAP30;
if ( (mapsum ~== "89C4CD26EF05E2577B10CAFE56226662")
|| (mapsum ~== "441BF111747671066A10A146C03EEFC4")
|| (mapsum ~== "55E321849F3699655D7E062C90682F63") )
return MAP_HMAP12;
if ( (mapsum ~== "E3B06F44DBF6F7E7754D7B1DAEF707E4")
|| (mapsum ~== "FC832437D7A2B7094A9B56C3909773D9")
|| (mapsum ~== "91AD797F95CC4C6D6AE33B21F664C60B")
|| (mapsum ~== "188B1B4244BD8DA501D8532696EC8654")
|| (mapsum ~== "5B29D0889DF09A8250D62FA09EB2B452")
|| (mapsum ~== "D3C5FA777BA52264546E6569F167AF0D") )
return MAP_HMAP23_HMAP27;
if ( (mapsum ~== "4444C95C2029DA6EECAC92DAA31CE665")
|| (mapsum ~== "33752742BCA8E539A6EE3E5D0FDA8744")
|| (mapsum ~== "3FFAF2F624C1B4BB6F581DCF7B99CBA7") )
return MAP_HMAP36;
if ( (mapsum ~== "78979A583B1E30D94C9DAE2BCFA9A18D")
|| (mapsum ~== "FDC90F44C65A71E0901C1B9FFFCF3D02")
|| (mapsum ~== "088ECE0E0F3E68448FA1D901001A0084") )
return MAP_HMAP37;
if ( (mapsum ~== "3BF62E4F9FB3CF9AF267421CE2D5F348")
|| (mapsum ~== "4799E1FDB5A3C0E3AD650B5AC215A737")
|| (mapsum ~== "5C63A02B0B04D9AE95CA51687DC3406F") )
return MAP_HMAP38;
if ( (mapsum ~== "EFAFE59092DE5E613562ACF52B86C37F")
|| (mapsum ~== "1C5DE5A921DEE405E98E7E09D9829387")
|| (mapsum ~== "2A6C4235B942467D25FD50D5B313E67A") )
return MAP_HMAP40;
return MAP_NONE;
}
override void WorldThingSpawned( WorldEvent e )
{
bool upgrademe = swwm_upgradebosses;
if ( gameinfo.gametype&GAME_Doom )
int bossmap = WhichVanillaBossMap();
if ( bossmap == MAP_DE1M8 )
{
if ( level.mapname ~== "E1M8" )
if ( e.Thing is 'BaronOfHell' )
{
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 ~== "MAP07" )
{
if ( (e.Thing is 'Fatso') || (e.Thing is 'Arachnotron') )
{
bossactors.Push(e.Thing);
if ( upgrademe )
e.Thing.Health *= 2;
}
bosstag = "$BT_DIMPLE";
}
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";
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 3;
}
bosstag = "$BT_BRUISERS";
}
else if ( gameinfo.gametype&GAME_Heretic )
else if ( bossmap == MAP_DE2M8 )
{
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 ( level.mapname ~== "TEST" ) // not in Kinsie's test map
return;
if ( e.Thing is 'ClericBoss' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 2;
bosstag = "$BT_CLERIC";
}
else if ( e.Thing is 'FighterBoss' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 2;
bosstag = "$BT_FIGHTER";
}
else if ( e.Thing is 'MageBoss' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 2;
bosstag = "$BT_MAGE";
}
else if ( e.Thing is 'Dragon' )
if ( e.Thing is 'Cyberdemon' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 4;
bosstag = "$BT_DRAGON";
}
else if ( e.Thing is 'Heresiarch' )
bosstag = "$BT_CYBIE";
}
else if ( bossmap == MAP_DE3M8_DE4M8 )
{
if ( e.Thing is 'Spidermastermind' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 6;
bosstag = "$BT_HERESIARCH";
if ( upgrademe )
{
if ( level.mapname ~== "E3M8" ) e.Thing.Health *= 5;
else e.Thing.Health *= 3;
}
}
else if ( e.Thing is 'Korax' )
bosstag = "$BT_SPIDER";
}
else if ( bossmap == MAP_DMAP07 )
{
if ( (e.Thing is 'Fatso') || (e.Thing is 'Arachnotron') )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 8;
bosstag = "$BT_KORAX";
if ( upgrademe )
e.Thing.Health *= 2;
}
bosstag = "$BT_DIMPLE";
}
else if ( bossmap == MAP_DMAP30 )
{
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 ( bossmap == MAP_HE1M8_HE4M8 )
{
if ( e.Thing is 'IronLich' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 4;
}
bosstag = "$BT_LICHES";
}
else if ( bossmap == MAP_HE2M8_HE5M8 )
{
if ( e.Thing is 'Minotaur' )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 2;
}
bosstag = "$BT_MINOTAUR";
}
else if ( bossmap == MAP_HE3M8 )
{
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 ( bossmap == MAP_HMAP38 )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 2;
bosstag = "$BT_CLERIC";
}
else if ( bossmap == MAP_HMAP36 )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 2;
bosstag = "$BT_FIGHTER";
}
else if ( bossmap == MAP_HMAP37 )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 2;
bosstag = "$BT_MAGE";
}
else if ( bossmap == MAP_HMAP12 )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 4;
bosstag = "$BT_DRAGON";
}
else if ( bossmap == MAP_HMAP23_HMAP27 )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 6;
bosstag = "$BT_HERESIARCH";
}
else if ( bossmap == MAP_HMAP40 )
{
bossactors.Push(e.Thing);
if ( upgrademe ) e.Thing.Health *= 8;
bosstag = "$BT_KORAX";
}
}