swwmgz_m/zscript/handler/swwm_handler_vanillaboss.zsc
Marisa the Magician 2aa0ea4680 More work towards Legacy of Rust support (with caveats).
As of this commit, do not consider the experience when playing that new
expansion to be complete. I've only partially written some of the mission texts
and rudimentarily enhanced some boss fights.

Currently there is one major limitation in that the intermission texts cannot
be replaced, as they're hardcoded inside the UMAPINFO. I don't know if I can
work around that.
2025-08-20 16:47:24 +02:00

759 lines
23 KiB
Text

// vanilla boss stuff
Class EndgameBossMarker : Inventory {}
Class BossMarker : Inventory {}
Class IconMessage : Inventory
{
override void DoEffect()
{
if ( Owner.InStateSequence(Owner.CurState,Owner.SeeState) )
{
Console.PrintfEx(PRINT_CHAT,StringTable.Localize("$BOSSLINE_IOS"));
DepleteOrDestroy();
return;
}
}
}
Class ArchangelusMessage : Inventory
{
override void DoEffect()
{
if ( Owner.InStateSequence(Owner.CurState,Owner.SeeState) )
{
Console.PrintfEx(PRINT_CHAT,StringTable.Localize("$BOSSLINE_ARCHANGELUS"));
DepleteOrDestroy();
return;
}
}
}
Class DSparilMessage : Inventory
{
override void DoEffect()
{
if ( Owner.InStateSequence(Owner.CurState,Owner.SeeState) )
{
Console.PrintfEx(PRINT_CHAT,StringTable.Localize("$BOSSLINE_DSPARIL"));
DepleteOrDestroy();
return;
}
}
}
Class ROM3R0Message : Inventory
{
override void DoEffect()
{
if ( Owner.InStateSequence(Owner.CurState,Owner.SeeState) )
{
Console.PrintfEx(PRINT_CHAT,StringTable.Localize("$BOSSLINE_ROM3R0"));
EventHandler.SendInterfaceEvent(consoleplayer,"swwmsetdialogue.ROMERO");
DepleteOrDestroy();
return;
}
}
}
Class ROM3R0Death : Inventory
{
override void OwnerDied()
{
// copied from boss brain
let ti = ThinkerIterator.Create('Actor');
Actor a;
while ( a = Actor(ti.Next()) )
{
if ( a is 'BossEye' ) a.SetStateLabel('Null');
else if ( a is 'SpawnShot' )
{
a.Spawn('SpawnFire',a.pos,ALLOW_REPLACE);
a.SetStateLabel('Null');
}
else if ( (a.Health > 0) && (a.bBossSpawned || a.bCOUNTKILL) )
a.DamageMobj(self,self,a.Health,'EndMii',DMG_FORCED|DMG_THRUSTLESS);
}
DepleteOrDestroy();
return;
}
}
Class TyrantWake : Inventory
{
override void DoEffect()
{
if ( Owner.InStateSequence(Owner.CurState,Owner.SeeState) )
{
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( hnd && (hnd.bosstag != "$BT_TYRANT2") )
{
hnd.bossactors.Clear();
hnd.initialized = false;
let ti = ThinkerIterator.Create('Deh_Actor_157');
Actor a;
while ( a = Actor(ti.Next()) )
hnd.bossactors.Push(a);
hnd.bosstag = "$BT_TYRANT2";
}
DepleteOrDestroy();
return;
}
}
}
extend Class SWWMHandler
{
String bosstag;
Array<Actor> bossactors;
Actor bossbrainactor;
Actor bossviewactor;
TextureID facetex[5];
bool initialized;
ui bool ui_initialized;
ui TextureID bbar_f[2], bbar_r[2], bbar_d[2];
ui double bossalpha;
ui SmoothLinearValueInterpolator ihealth;
ui SmoothDynamicValueInterpolator ihealthr;
ui int thealth, hmax;
ui int oldhealth[30];
ui int cummdamage, lastcummtic; // please do not misread
ui Font mSmallFont, mTinyFont;
bool archangelus_zapped; // skips second phase dialogue
bool origin_zapped; // bonus dlg for ynykron survival
bool origin_postzap; // so the bonus dlg doesn't play twice
enum EVanillaMap
{
MAP_NONE,
MAP_DE1M8,
MAP_DE2M8,
MAP_DE3M8,
MAP_DE4M8,
MAP_HE1M8_HE4M8,
MAP_HE2M8_HE5M8,
MAP_HE3M8,
MAP_DMAP07,
MAP_DMAP30,
MAP_DLVL08,
MAP_HMAP12,
MAP_HMAP23_HMAP27_HMAP48_HMAP55,
MAP_HMAP36,
MAP_HMAP37,
MAP_HMAP38,
MAP_HMAP40,
MAP_HMAP60,
MAP_EVMAP30, // eviternity
MAP_EVIIMAP30, // eviternity 2
MAP_DE1M8B, // "tech gone bad"
MAP_ID24MAP13, // TODO Soul Silo cybies
MAP_ID24MAP14 // TODO Brink tyrants
};
static play void AddBoss( int tid, String tag, bool endgame = false )
{
let hnd = SWWMHandler(EventHandler.Find('SWWMHandler'));
if ( !hnd ) return;
hnd.bossactors.Clear();
hnd.initialized = false;
let ai = level.CreateActorIterator(tid);
foreach ( a:ai )
{
hnd.bossactors.Push(a);
a.GiveInventory('BossMarker',1);
if ( endgame ) a.GiveInventory('EndgameBossMarker',1);
// boss brain type actors need to set an eye so we can detect when they "aggro"
if ( a is 'BossBrain' )
{
hnd.bossbrainactor = a;
// look for boss eyes
let eye = Actor(ThinkerIterator.Create('BossEye').Next());
hnd.bossviewactor = eye;
}
}
if ( hnd.bossactors.Size() == 0 ) return;
hnd.bosstag = (tag!="")?tag:hnd.bossactors[0].GetTag();
}
static play void AddBossActor( Actor a, String tag, bool endgame = false )
{
if ( !a ) return;
let hnd = SWWMHandler(EventHandler.Find('SWWMHandler'));
if ( !hnd ) return;
hnd.bossactors.Clear();
hnd.initialized = false;
hnd.bossactors.Push(a);
a.GiveInventory('BossMarker',1);
hnd.bosstag = (tag!="")?tag:a.GetTag();
// boss brain type actors need to set an eye so we can detect when they "aggro"
if ( a is 'BossBrain' )
{
hnd.bossbrainactor = a;
// look for boss eyes
let eye = Actor(ThinkerIterator.Create('BossEye').Next());
hnd.bossviewactor = eye;
}
}
private clearscope int WhichVanillaBossMap() const
{
String mapsum = level.GetChecksum();
if ( (mapsum ~== "94500F4B006B316FE03AC46865AEABF8")
|| (mapsum ~== "97079958C7E89C1908890730B8B9FEB7")
|| (mapsum ~== "058FB092EA1B70DA1E3CBF501C4A91A1") )
return MAP_DE1M8;
if ( mapsum ~== "A1F105211112747EE50BA520462A471E" )
return MAP_DE1M8B;
if ( mapsum ~== "EFFE91DF41AD41F6973C06F0AD67DDB9" )
return MAP_DE2M8;
if ( mapsum ~== "EF128313112110ED6C1549AF96AF26C9" )
return MAP_DE3M8;
if ( mapsum ~== "2DC939E508AB8EB68AF79D5B60568711" )
return MAP_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")
|| (mapsum ~== "FF8620A6B4EB60CCE737EBC1E6CC7A9F") ) // second sum is for Ultimate Doom 2
return MAP_DMAP07;
if ( mapsum ~== "5EECD88F4491F516D590CE4BBF45F532" )
return MAP_DMAP30;
if ( mapsum ~== "7EB864A03948C3F918F9223B2D1F8911" )
return MAP_DLVL08;
if ( (mapsum ~== "89C4CD26EF05E2577B10CAFE56226662")
|| (mapsum ~== "441BF111747671066A10A146C03EEFC4")
|| (mapsum ~== "55E321849F3699655D7E062C90682F63") )
return MAP_HMAP12;
if ( (mapsum ~== "E3B06F44DBF6F7E7754D7B1DAEF707E4")
|| (mapsum ~== "FC832437D7A2B7094A9B56C3909773D9")
|| (mapsum ~== "91AD797F95CC4C6D6AE33B21F664C60B")
|| (mapsum ~== "188B1B4244BD8DA501D8532696EC8654")
|| (mapsum ~== "5B29D0889DF09A8250D62FA09EB2B452")
|| (mapsum ~== "D3C5FA777BA52264546E6569F167AF0D")
|| (mapsum ~== "15FC0991D975325556EFF71F241A4458")
|| (mapsum ~== "2FAD54B58487884F06EAFA507B553921") )
return MAP_HMAP23_HMAP27_HMAP48_HMAP55;
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;
if ( mapsum ~== "B0ADDB295A3ACCE43978AAC91FB8C58A" )
return MAP_HMAP60;
if ( mapsum ~== "5C5E5C08AF3572F31CF27318679F2B4E" )
return MAP_EVMAP30;
if ( mapsum ~== "CF2B3E2589CA6FBB6EE3E3A09F19BA18" )
return MAP_EVIIMAP30;
if ( mapsum ~== "7CABD8B043B69996D9777F7070C8BCCE" )
return MAP_ID24MAP13;
if ( mapsum ~== "A3F7A58FC08C369F1360741A99F1497C" )
return MAP_ID24MAP14;
return MAP_NONE;
}
private void VanillaBossSpawn( WorldEvent e )
{
if ( bossmap == -1 ) bossmap = WhichVanillaBossMap();
if ( (bossmap == MAP_DE1M8) || (bossmap == MAP_DE1M8B) )
{
if ( e.Thing is 'BaronOfHell' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 3;
e.Thing.GiveInventory('BossMarker',1);
bosstag = "$BT_BRUISERS";
}
}
else if ( bossmap == MAP_DE2M8 )
{
if ( e.Thing is 'Cyberdemon' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 5;
e.Thing.GiveInventory('BossMarker',1);
bosstag = "$BT_CYBIE";
}
}
else if ( bossmap == MAP_DE3M8 )
{
if ( e.Thing is 'Spidermastermind' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 6;
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
bosstag = "$BT_SPIDER";
}
}
else if ( bossmap == MAP_DE4M8 )
{
if ( e.Thing is 'Spidermastermind' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 4;
e.Thing.GiveInventory('BossMarker',1);
bosstag = "$BT_SPIDER2";
}
}
else if ( bossmap == MAP_DMAP07 )
{
if ( (e.Thing is 'Fatso') || (e.Thing is 'Arachnotron') )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 2;
e.Thing.GiveInventory('BossMarker',1);
bosstag = "$BT_DIMPLE";
}
}
else if ( bossmap == MAP_DMAP30 )
{
if ( e.Thing is 'BossBrain' )
{
bossbrainactor = e.Thing;
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 40; // goodbye, instakills
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
bosstag = "$BT_IOS";
}
if ( e.Thing is 'BossEye' )
{
bossviewactor = e.Thing;
e.Thing.GiveInventory('IconMessage',1);
}
}
else if ( bossmap == MAP_DLVL08 )
{
if ( e.Thing is 'Cyberdemon' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 4;
e.Thing.GiveInventory('BossMarker',1);
bosstag = "$BT_CYBIE2";
}
}
else if ( bossmap == MAP_ID24MAP13 )
{
if ( e.Thing is 'Cyberdemon' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 4;
e.Thing.GiveInventory('BossMarker',1);
bosstag = "$BT_CYBIE3";
}
}
else if ( bossmap == MAP_ID24MAP14 )
{
if ( e.Thing is 'Deh_Actor_156' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 4;
e.Thing.GiveInventory('BossMarker',1);
bosstag = "$BT_TYRANT";
}
else if ( e.Thing is 'Deh_Actor_155' )
{
e.Thing.StartHealth = e.Thing.Health *= 4;
e.Thing.GiveInventory('BossMarker',1);
}
else if ( e.Thing is 'Deh_Actor_157' )
{
e.Thing.StartHealth = e.Thing.Health *= 4;
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('TyrantWake',1);
}
else if ( e.Thing is 'Cyberdemon' )
{
e.Thing.StartHealth = e.Thing.Health *= 4;
e.Thing.GiveInventory('BossMarker',1);
}
}
else if ( bossmap == MAP_HE1M8_HE4M8 )
{
if ( e.Thing is 'IronLich' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 4;
e.Thing.GiveInventory('BossMarker',1);
bosstag = "$BT_LICHES";
}
}
else if ( bossmap == MAP_HE2M8_HE5M8 )
{
if ( e.Thing is 'Minotaur' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 3;
e.Thing.GiveInventory('BossMarker',1);
bosstag = "$BT_MINOTAUR";
}
}
else if ( bossmap == MAP_HE3M8 )
{
if ( e.Thing is 'Sorcerer1' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 2;
bosstag = "$BT_DSPARIL";
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
}
else if ( e.Thing is 'Sorcerer2' )
{
// second phase
bossactors.Clear();
initialized = false;
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 8;
bosstag = "$BT_DSPARIL2";
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
e.Thing.GiveInventory('DSparilMessage',1);
}
}
else if ( bossmap == MAP_HMAP38 )
{
if ( e.Thing is 'ClericBoss' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 2;
bosstag = "$BT_CLERIC";
e.Thing.GiveInventory('BossMarker',1);
}
}
else if ( bossmap == MAP_HMAP36 )
{
if ( e.Thing is 'FighterBoss' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 2;
bosstag = "$BT_FIGHTER";
e.Thing.GiveInventory('BossMarker',1);
}
}
else if ( bossmap == MAP_HMAP37 )
{
if ( e.Thing is 'MageBoss' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 2;
bosstag = "$BT_MAGE";
e.Thing.GiveInventory('BossMarker',1);
}
}
else if ( bossmap == MAP_HMAP12 )
{
if ( e.Thing is 'Dragon' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 4;
bosstag = "$BT_DRAGON";
e.Thing.GiveInventory('BossMarker',1);
}
}
else if ( bossmap == MAP_HMAP23_HMAP27_HMAP48_HMAP55 )
{
if ( e.Thing is 'Heresiarch' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 8;
bosstag = "$BT_HERESIARCH";
e.Thing.GiveInventory('BossMarker',1);
}
}
else if ( bossmap == MAP_HMAP40 )
{
if ( e.Thing is 'Korax' )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 10;
bosstag = "$BT_KORAX";
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
}
}
else if ( bossmap == MAP_HMAP60 )
{
if ( (e.Thing is 'FighterBoss') || (e.Thing is 'ClericBoss') || (e.Thing is 'MageBoss') )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 4;
bosstag = "$BT_DEATHKINGS";
initialized = true; // healthbar shows from the start
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
}
}
else if ( bossmap == MAP_EVMAP30 )
{
if ( e.Thing.GetClassName() == 'Archangelus' )
{
bossactors.Push(e.Thing);
bossviewactor = e.Thing;
bosstag = "$BT_ARCHANGELUS";
e.Thing.GiveInventory('ArchangelusMessage',1);
}
else if ( e.Thing.GetClassName() == 'ArchangelusA' )
{
// first phase
bossactors.Clear();
bossviewactor = null;
initialized = false;
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 5;
bosstag = "$BT_ARCHANGELUS";
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
}
else if ( e.Thing.GetClassName() == 'ArchangelusB' )
{
// second phase
bossactors.Clear();
bossviewactor = null;
initialized = false;
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 5;
bosstag = "$BT_ARCHANGELUS";
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
if ( !archangelus_zapped )
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EVIB");
}
}
else if ( bossmap == MAP_EVIIMAP30 )
{
if ( (e.Thing.GetClassName() == 'The_Origin_Phase_1_Spawner') || (e.Thing.GetClassName() == 'The_Absolute_Origin_Phase_1_Spawner') )
{
bossactors.Push(e.Thing);
bossviewactor = e.Thing;
bosstag = "$BT_ORIGIN";
// hack to avoid "all clear" between phases
level.total_monsters += 3;
}
else if ( (e.Thing.GetClassName() == 'The_Origin_Phase_1') || (e.Thing.GetClassName() == 'The_Absolute_Origin_Phase_1') )
{
// first phase
bossactors.Clear();
bossviewactor = null;
initialized = false;
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 5;
bosstag = "$BT_ORIGIN";
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
// undo the hack (part 1)
level.total_monsters--;
}
else if ( (e.Thing.GetClassName() == 'The_Origin_Phase_2') || (e.Thing.GetClassName() == 'The_Absolute_Origin_Phase_2') )
{
// second phase
bossactors.Clear();
bossviewactor = null;
initialized = false;
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 5;
bosstag = "$BT_ORIGIN";
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
if ( origin_zapped )
{
origin_postzap = true;
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2N");
}
else SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2L");
// undo the hack (part 2)
level.total_monsters--;
}
else if ( (e.Thing.GetClassName() == 'The_Origin_Phase_3') || (e.Thing.GetClassName() == 'The_Absolute_Origin_Phase_3') )
{
// third phase
bossactors.Clear();
bossviewactor = null;
initialized = false;
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 5;
bosstag = "$BT_ORIGIN";
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
if ( origin_zapped )
{
if ( origin_postzap )
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2O");
else SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2N");
}
else SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2M");
// undo the hack (part 3)
level.total_monsters--;
}
}
if ( ccloaded && (e.Thing.GetClassName() == 'CCards_Boss_Romero') )
{
bossactors.Push(e.Thing);
e.Thing.StartHealth = e.Thing.Health *= 10;
bosstag = "ROM3R-0.666";
e.Thing.GiveInventory('BossMarker',1);
e.Thing.GiveInventory('EndgameBossMarker',1);
e.Thing.GiveInventory('ROM3R0Message',1);
e.Thing.GiveInventory('ROM3R0Death',1);
}
}
private void VanillaBossTick()
{
if ( initialized ) return;
// wait until bosses are active
foreach ( a:bossactors )
{
if ( !a ) continue;
if ( (!a.target || !a.CheckSight(a.target,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY))
&& (!bossviewactor || (bossviewactor && !bossviewactor.InStateSequence(bossviewactor.CurState,bossviewactor.SeeState))) ) continue;
initialized = true;
// oneliners
if ( bossmap == MAP_DMAP30 )
{
highesttic = gametic;
lastcombat = AddOneliner("romero",1,200);
}
else if ( bossmap == MAP_HE3M8 )
{
highesttic = gametic;
if ( bosstag == "$BT_DSPARIL2" ) lastcombat = AddOneliner("dsparilb",1,100);
else lastcombat = AddOneliner("dsparila",1,80);
}
else if ( bossmap == MAP_HMAP40 )
{
highesttic = gametic;
lastcombat = AddOneliner("korax",1,40);
}
else if ( (bossmap == MAP_EVMAP30) && bossviewactor )
{
highesttic = gametic;
lastcombat = AddOneliner("archangelus",1,300);
}
else if ( bossmap == MAP_EVIIMAP30 )
{
highesttic = gametic;
if ( (a.GetClassName() == 'The_Origin_Phase_1') || (a.GetClassName() == 'The_Absolute_Origin_Phase_1') )
lastcombat = AddOneliner("origin1",1,40);
else if ( (a.GetClassName() == 'The_Origin_Phase_2') || (a.GetClassName() == 'The_Absolute_Origin_Phase_2') )
lastcombat = AddOneliner("origin2",1,40);
else if ( (a.GetClassName() == 'The_Origin_Phase_3') || (a.GetClassName() == 'The_Absolute_Origin_Phase_3') )
lastcombat = AddOneliner("origin3",1,40);
}
break;
}
}
private ui void VanillaBossUiTick()
{
if ( (!ui_initialized && initialized) || (ui_initialized && !initialized) )
{
ui_initialized = true;
thealth = 0;
foreach ( a:bossactors )
{
if ( !a ) continue;
thealth += max(0,a.SpawnHealth());
}
hmax = thealth;
for ( int i=0; i<30; i++ ) oldhealth[i] = thealth;
cummdamage = 0;
if ( !ihealth ) ihealth = SmoothLinearValueInterpolator.Create(thealth,max(1,hmax/50));
else ihealth.Reset(thealth);
if ( !ihealthr ) ihealthr = SmoothDynamicValueInterpolator.Create(thealth,.5);
else ihealthr.Reset(thealth);
return;
}
if ( !ui_initialized ) return;
// update healthbar
int newhealth = 0;
foreach ( a:bossactors )
{
if ( !a ) continue;
newhealth += max(0,a.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 ) bossalpha = min(3.,bossalpha+1./30.);
else bossalpha = max(0,bossalpha-1./50.);
}
// called by HUD (done here for the sake of cleaner code)
ui void DrawBossBar( SWWMStatusBar bar )
{
if ( !ui_initialized || (bossalpha <= 0.) ) return;
if ( !mSmallFont ) mSmallFont = Font.GetFont('TewiFontOutline');
if ( !mTinyFont ) mTinyFont = Font.GetFont('MiniwiFontOutline');
if ( !bbar_f[0] ) bbar_f[0] = TexMan.CheckForTexture("graphics/HUD/BossHealthBarBox.png");
if ( !bbar_r[0] ) bbar_r[0] = TexMan.CheckForTexture("graphics/HUD/BossHealthBar.png");
if ( !bbar_d[0] ) bbar_d[0] = TexMan.CheckForTexture("graphics/HUD/BossHealthBarDecay.png");
if ( !bbar_f[1] ) bbar_f[1] = TexMan.CheckForTexture("graphics/HUD/BossHealthBarBoxSmol.png");
if ( !bbar_r[1] ) bbar_r[1] = TexMan.CheckForTexture("graphics/HUD/BossHealthBarSmol.png");
if ( !bbar_d[1] ) bbar_d[1] = TexMan.CheckForTexture("graphics/HUD/BossHealthBarDecaySmol.png");
bool bSmol = (bar.ss1.x<640.);
int intsz = bSmol?250:300;
double dblsz = bSmol?250.:300.;
Vector2 vpos = ((bar.ss1.x-intsz)/2.,bar.ss1.y*.75);
Screen.DrawTexture(bbar_f[bSmol],false,vpos.x-2,vpos.y-2,DTA_VirtualWidthF,bar.ss1.x,DTA_VirtualHeightF,bar.ss1.y,DTA_KeepRatio,true,DTA_Alpha,bossalpha);
if ( hmax )
{
double rw = clamp((ihealthr.GetValue(bar.FracTic)*dblsz)/hmax,0.,dblsz);
double dw = clamp((ihealth.GetValue(bar.FracTic)*dblsz)/hmax,0.,dblsz);
Screen.DrawTexture(bbar_d[bSmol],false,vpos.x,vpos.y,DTA_VirtualWidthF,bar.ss1.x,DTA_VirtualHeightF,bar.ss1.y,DTA_KeepRatio,true,DTA_Alpha,bossalpha,DTA_WindowRightF,dw);
Screen.DrawTexture(bbar_r[bSmol],false,vpos.x,vpos.y,DTA_VirtualWidthF,bar.ss1.x,DTA_VirtualHeightF,bar.ss1.y,DTA_KeepRatio,true,DTA_Alpha,bossalpha,DTA_WindowRightF,rw);
}
if ( (cummdamage > 0) && (gametic < lastcummtic+150) )
{
double calph = clamp(((lastcummtic+150)-gametic)/50.,0.,1.);
string dnum = String.Format("%d",cummdamage);
Screen.DrawText(mTinyFont,Font.CR_RED,(vpos.x+intsz)-(mTinyFont.StringWidth(dnum)+2),vpos.y-mTinyFont.GetHeight(),dnum,DTA_VirtualWidthF,bar.ss1.x,DTA_VirtualHeightF,bar.ss1.y,DTA_KeepRatio,true,DTA_Alpha,bossalpha*calph);
}
String bname = bosstag;
if ( (bname.Left(1) == "$") && swwm_funtags )
{
String fun = bname.."_FUN";
if ( !(StringTable.Localize(fun) ~== fun.Mid(1)) ) bname = fun;
}
Screen.DrawText(mSmallFont,Font.CR_WHITE,vpos.x+3,vpos.y-mSmallFont.GetHeight(),StringTable.Localize(bname),DTA_VirtualWidthF,bar.ss1.x,DTA_VirtualHeightF,bar.ss1.y,DTA_KeepRatio,true,DTA_Alpha,bossalpha);
}
// can't use this until I actually figure out how to make those walls damageable
/*override void WorldLineDamaged( WorldEvent e )
{
// allow boss brain to take (reduced) damage from the facewall being shot
if ( level.mapname ~== "MAP30" )
{
if ( !SWWMUtility.IsIOSWall(e.DamageLine) ) return;
if ( bossbrainactor )
bossbrainactor.DamageMobj(e.Inflictor,e.DamageSource,e.Damage/3,e.DamageType,e.DamageFlags,e.DamageAngle);
e.NewDamage = 0;
}
}*/
}