// 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; } } extend Class SWWMHandler { String bosstag; Array 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 eviternatus_zapped; // bonus dlg for ynykron survival bool eviternatus_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 }; 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 ~== "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 ~== "966EF50BC1C9994F0F303CD1835014FF" ) // subject to change, not final return MAP_EVIIMAP30; return MAP_NONE; } private void VanillaBossSpawn( WorldEvent e ) { if ( bossmap == -1 ) bossmap = WhichVanillaBossMap(); if ( bossmap == MAP_DE1M8 ) { 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_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() == "EviternatusAntaSpawner" ) { bossactors.Push(e.Thing); bossviewactor = e.Thing; bosstag = "$BT_EVITERNATUS"; // hack to avoid "all clear" between phases level.total_monsters += 3; } else if ( e.Thing.GetClassName() == "EviternatusAnta" ) { // first phase bossactors.Clear(); bossviewactor = null; initialized = false; bossactors.Push(e.Thing); e.Thing.StartHealth = e.Thing.Health *= 5; bosstag = "$BT_EVITERNATUS"; e.Thing.GiveInventory('BossMarker',1); e.Thing.GiveInventory('EndgameBossMarker',1); // undo the hack (part 1) level.total_monsters--; } else if ( e.Thing.GetClassName() == "EviternatusBete" ) { // second phase bossactors.Clear(); bossviewactor = null; initialized = false; bossactors.Push(e.Thing); e.Thing.StartHealth = e.Thing.Health *= 5; bosstag = "$BT_EVITERNATUS"; e.Thing.GiveInventory('BossMarker',1); e.Thing.GiveInventory('EndgameBossMarker',1); if ( eviternatus_zapped ) { eviternatus_postzap = true; SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2N"); } else SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2L"); // undo the hack (part 2) level.total_monsters--; } else if ( e.Thing.GetClassName() == "EviternatusCeph" ) { // third phase bossactors.Clear(); bossviewactor = null; initialized = false; bossactors.Push(e.Thing); e.Thing.StartHealth = e.Thing.Health *= 5; bosstag = "$BT_EVITERNATUS"; e.Thing.GiveInventory('BossMarker',1); e.Thing.GiveInventory('EndgameBossMarker',1); if ( eviternatus_zapped ) { if ( eviternatus_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() == "EviternatusAnta" ) lastcombat = AddOneliner("eviternatus1",1,40); else if ( a.GetClassName() == "EviternatusBete" ) lastcombat = AddOneliner("eviternatus2",1,40); else if ( a.GetClassName() == "EviternatusCeph" ) lastcombat = AddOneliner("eviternatus3",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; } }*/ }