441 lines
16 KiB
Text
441 lines
16 KiB
Text
// WorldThing* events (excluding damage)
|
|
|
|
extend Class SWWMHandler
|
|
{
|
|
// prevents revived monsters from spawning in more golden shells
|
|
Array<Actor> alreadygold;
|
|
|
|
// legendary monster markers (for the "has mutated" message)
|
|
Array<Inventory> legtrack;
|
|
|
|
override void WorldThingRevived( WorldEvent e )
|
|
{
|
|
if ( profiling ) ProfileTick();
|
|
// reattach headpats
|
|
if ( SWWMUtility.IdentifyingDog(e.Thing) || SWWMUtility.IdentifyingCaco(e.Thing)
|
|
|| SWWMUtility.IdentifyingDrug(e.Thing) || SWWMUtility.IdentifyingDoubleBoi(e.Thing) )
|
|
{
|
|
// you can pet the dog, and you can also pet the caco (and friends)
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
}
|
|
if ( !(e.Thing is 'PlayerPawn') )
|
|
{
|
|
if ( profiling ) ProfileTock(PT_WORLDTHINGREVIVED);
|
|
return;
|
|
}
|
|
// reset some vars
|
|
if ( e.Thing.playernumber() != -1 )
|
|
{
|
|
multilevel[e.Thing.playernumber()] = 0;
|
|
spreecount[e.Thing.playernumber()] = 0;
|
|
tookdamage[e.Thing.playernumber()] = false;
|
|
lastkill[e.Thing.playernumber()] = int.min;
|
|
}
|
|
// reset uptime since player had just died
|
|
SWWMStats s = SWWMStats.Find(e.Thing.player);
|
|
if ( s ) s.lastspawn = level.totaltime;
|
|
if ( profiling ) ProfileTock(PT_WORLDTHINGREVIVED);
|
|
}
|
|
|
|
private bool HexenMap40()
|
|
{
|
|
if ( level.GetChecksum() ~== "2A6C4235B942467D25FD50D5B313E67A" ) return true; // 1.1
|
|
if ( level.GetChecksum() ~== "1C5DE5A921DEE405E98E7E09D9829387" ) return true; // 1.0
|
|
if ( level.GetChecksum() ~== "EFAFE59092DE5E613562ACF52B86C37F" ) return true; // beta
|
|
return false;
|
|
}
|
|
|
|
static int ShouldSpawnGold()
|
|
{
|
|
int totalneeded = 0;
|
|
// check "free space" in player inventories
|
|
for ( int i=0; i<MAXPLAYERS; i++ )
|
|
{
|
|
if ( !playeringame[i] || !players[i].mo ) continue;
|
|
let cg = players[i].mo.FindInventory("GoldShell");
|
|
if ( cg ) totalneeded += cg.MaxAmount-cg.Amount;
|
|
else totalneeded = GetDefaultByType("GoldShell").MaxAmount;
|
|
}
|
|
// subtract any shells already in the world
|
|
let ti = ThinkerIterator.Create("GoldShell");
|
|
GoldShell g;
|
|
while ( g = GoldShell(ti.Next()) )
|
|
{
|
|
if ( g.Owner ) continue;
|
|
totalneeded -= g.Amount;
|
|
}
|
|
return max(0,totalneeded);
|
|
}
|
|
|
|
override void WorldThingDied( WorldEvent e )
|
|
{
|
|
if ( profiling ) ProfileTick();
|
|
if ( e.Thing.default.bISMONSTER && e.Thing.default.bCOUNTKILL && ((e.Thing.default.bBOSS) || (e.Thing.GetSpawnHealth() >= 1000) || e.Thing.FindInventory("BossMarker")) && (alreadygold.Find(e.Thing) == alreadygold.Size()) )
|
|
{
|
|
// make sure we can't farm drops from revivable enemies
|
|
// (or cause some things to spam-spawn gold shells)
|
|
// (*cough* Touhou Doom *cough*)
|
|
alreadygold.Push(e.Thing);
|
|
// weight drop chance based on total count of this monster type
|
|
// guarantees that maps that get a bit slaughtery won't become easy farms for drops
|
|
int dropweight = 0;
|
|
let ti = ThinkerIterator.Create(e.Thing.GetClass());
|
|
while ( ti.Next() ) dropweight++;
|
|
int minchance = max(1,6-(e.Thing.GetSpawnHealth()/1000));
|
|
dropweight = max(minchance,dropweight/2);
|
|
// make sure the gold shell is "worth spawning", too
|
|
// (also, chance should be reduced as you acquire more shells)
|
|
int gchance = int(ceil(ShouldSpawnGold()/2.));
|
|
if ( !Random[GoldDrop](0,dropweight) && Random[GoldDrop](0,gchance) )
|
|
{
|
|
let g = Actor.Spawn("GoldShell",e.Thing.Vec3Offset(0,0,e.Thing.Height/2.));
|
|
double ang = FRandom[SpareShells](0.,360.);
|
|
g.vel.xy = Actor.AngleToVector(ang,FRandom[SpareShells](.4,.8));
|
|
g.vel.z = FRandom[SpareShells](2.,4.);
|
|
}
|
|
}
|
|
// Korax instakill
|
|
if ( (e.Thing is 'Korax') && !e.Thing.special2 && HexenMap40() )
|
|
{
|
|
e.Thing.special2 = 1;
|
|
// terminate the monster closet scripts, open all the
|
|
// doors ourselves
|
|
level.ExecuteSpecial(ACS_Terminate,e.Thing,null,false,220);
|
|
level.ExecuteSpecial(ACS_Terminate,e.Thing,null,false,220);
|
|
level.ExecuteSpecial(ACS_Terminate,e.Thing,null,false,221);
|
|
level.ExecuteSpecial(ACS_Terminate,e.Thing,null,false,255);
|
|
level.ExecuteSpecial(Door_Open,e.Thing,null,false,10,16);
|
|
level.ExecuteSpecial(Door_Open,e.Thing,null,false,11,16);
|
|
level.ExecuteSpecial(Door_Open,e.Thing,null,false,12,16);
|
|
level.ExecuteSpecial(Door_Open,e.Thing,null,false,13,16);
|
|
level.ExecuteSpecial(Door_Open,e.Thing,null,false,14,16);
|
|
level.ExecuteSpecial(Door_Open,e.Thing,null,false,10,16);
|
|
// keep the portal closed, you can't leave unless you
|
|
// kill everyone else
|
|
let t = new("KoraxYeeted");
|
|
t.ChangeStatNum(Thinker.STAT_USER);
|
|
}
|
|
// Archangelus instakill
|
|
if ( (e.Thing.GetClassName() == "ArchangelusA") && (e.Thing.DamageType == 'Ynykron') )
|
|
{
|
|
// this will skip the second phase dialogue
|
|
// (note that you can only have an Ynykron in this fight by cheating, tho)
|
|
archangelus_zapped = true;
|
|
}
|
|
// Archangelus death
|
|
if ( e.Thing.GetClassName() == "ArchangelusB" )
|
|
{
|
|
// kill all other monsters
|
|
let ti = ThinkerIterator.Create("Actor");
|
|
Actor a;
|
|
while ( a = Actor(ti.Next()) )
|
|
{
|
|
if ( (a != e.Thing) && (a.Health > 0) && (a.bBossSpawned || a.bCOUNTKILL) )
|
|
a.DamageMobj(e.Thing,e.Thing,a.Health,'EndMii',DMG_FORCED|DMG_THRUSTLESS);
|
|
}
|
|
}
|
|
// Origin instakill
|
|
if ( ((e.Thing.GetClassName() == "The_Origin_Phase_1") || (e.Thing.GetClassName() == "The_Origin_Phase_2")
|
|
|| (e.Thing.GetClassName() == "The_Absolute_Origin_Phase_1") || (e.Thing.GetClassName() == "The_Absolute_Origin_Phase_2"))
|
|
&& (e.Thing.DamageType == 'Ynykron') )
|
|
{
|
|
// this will trigger special dialogue on the next phase
|
|
origin_zapped = true;
|
|
}
|
|
if ( swwm_partytime )
|
|
{
|
|
let pt = Actor.Spawn("PartyTime",e.Thing.pos);
|
|
pt.target = e.Thing;
|
|
}
|
|
if ( profiling ) ProfileTock(PT_WORLDTHINGDIED);
|
|
}
|
|
|
|
private void DoKeyTagFix( Actor a )
|
|
{
|
|
if ( a is 'SWWMKey' ) return; // mod's custom keys are fine
|
|
if ( a is 'RedCard' ) a.SetTag("$T_REDCARD");
|
|
else if ( a is 'BlueCard' ) a.SetTag("$T_BLUECARD");
|
|
else if ( a is 'YellowCard' ) a.SetTag("$T_YELLOWCARD");
|
|
else if ( a is 'RedSkull' ) a.SetTag("$T_REDSKULL");
|
|
else if ( a is 'BlueSkull' ) a.SetTag("$T_BLUESKULL");
|
|
else if ( a is 'YellowSkull' ) a.SetTag("$T_YELLOWSKULL");
|
|
else if ( a is 'KeyYellow' ) a.SetTag("$T_KEYYELLOW");
|
|
else if ( a is 'KeyGreen' ) a.SetTag("$T_KEYGREEN");
|
|
else if ( a is 'KeyBlue' ) a.SetTag("$T_KEYBLUE");
|
|
else if ( a.GetClassName() == 'KeyRed' ) a.SetTag("$T_KEYRED");
|
|
else if ( a is 'KeySteel' ) a.SetTag("$T_KEYSTEEL");
|
|
else if ( a is 'KeyCave' ) a.SetTag("$T_KEYCAVE");
|
|
else if ( a is 'KeyAxe' ) a.SetTag("$T_KEYAXE");
|
|
else if ( a is 'KeyFire' ) a.SetTag("$T_KEYFIRE");
|
|
else if ( a is 'KeyEmerald' ) a.SetTag("$T_KEYEMERALD");
|
|
else if ( a is 'KeyDungeon' ) a.SetTag("$T_KEYDUNGEON");
|
|
else if ( a is 'KeySilver' ) a.SetTag("$T_KEYSILVER");
|
|
else if ( a is 'KeyRusted' ) a.SetTag("$T_KEYRUSTED");
|
|
else if ( a is 'KeyHorn' ) a.SetTag("$T_KEYHORN");
|
|
else if ( a is 'KeySwamp' ) a.SetTag("$T_KEYSWAMP");
|
|
else if ( a is 'KeyCastle' ) a.SetTag("$T_KEYCASTLE");
|
|
}
|
|
|
|
// tempfix keys have no tags
|
|
static void KeyTagFix( Actor a )
|
|
{
|
|
let hnd = SWWMHandler(Find("SWWMHandler"));
|
|
if ( hnd ) hnd.DoKeyTagFix(a);
|
|
}
|
|
|
|
// copies the floatbob of overlapping identical items, so it doesn't look weird
|
|
private void CopyFloatBob( Actor a )
|
|
{
|
|
for ( Actor t=a.CurSector.thinglist; t; t=t.snext )
|
|
{
|
|
if ( (t == a) || !(t is 'Inventory') || !(t.spawnpoint ~== a.spawnpoint) ) continue;
|
|
a.floatbobphase = t.floatbobphase;
|
|
a.angle = t.angle; // also copy angle
|
|
break;
|
|
}
|
|
}
|
|
|
|
private bool SuppressMultiItem( WorldEvent e )
|
|
{
|
|
// quick checks
|
|
if ( !G_SkillPropertyInt(SKILLP_SpawnMulti) || multiplayer || sv_alwaysspawnmulti )
|
|
return false;
|
|
// is it coop inventory? suppress it
|
|
if ( (e.Thing.spawnflags&(MTF_COOPERATIVE|MTF_DEATHMATCH)) && !(e.Thing.spawnflags&MTF_SINGLE) && ((e.Thing is 'Inventory') || (e.Thing is 'MaceSpawner')) )
|
|
{
|
|
e.Thing.ClearCounters();
|
|
e.Thing.Destroy();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
override void WorldThingDestroyed( WorldEvent e )
|
|
{
|
|
if ( profiling ) ProfileTick();
|
|
// for gibber throttling
|
|
if ( e.Thing is 'mkBloodDrop' ) blods_realcnt--;
|
|
else if ( e.Thing is 'mkFlyingGib' ) meats_realcnt--;
|
|
if ( profiling ) ProfileTock(PT_WORLDTHINGDESTROYED);
|
|
}
|
|
|
|
override void WorldThingSpawned( WorldEvent e )
|
|
{
|
|
if ( profiling ) ProfileTick();
|
|
// for gibber throttling
|
|
if ( e.Thing is 'mkBloodDrop' ) blods_realcnt++;
|
|
else if ( e.Thing is 'mkFlyingGib' ) meats_realcnt++;
|
|
if ( !e.Thing || SuppressMultiItem(e) )
|
|
{
|
|
if ( profiling ) ProfileTock(PT_WORLDTHINGSPAWNED);
|
|
return;
|
|
}
|
|
IWantDieSpawn(e);
|
|
if ( (e.Thing is 'TeleportDest') || (e.Thing is 'BossTarget') )
|
|
{
|
|
let d = Actor.Spawn("SWWMTeleportDest",e.Thing.pos);
|
|
d.bNOGRAVITY = e.Thing.bNOGRAVITY;
|
|
}
|
|
if ( e.Thing is 'Inventory' )
|
|
{
|
|
CopyFloatBob(e.Thing);
|
|
if ( Inventory(e.Thing).PickupFlash is 'SWWMPickupFlash' )
|
|
{
|
|
let p = Actor.Spawn(Inventory(e.Thing).PickupFlash,e.Thing.pos);
|
|
p.target = e.Thing;
|
|
p.SetStateLabel("Pickup");
|
|
}
|
|
// for notification
|
|
if ( e.Thing.GetClassName() == "LDLegendaryMonsterTransformed" )
|
|
legtrack.Push(Inventory(e.Thing));
|
|
}
|
|
if ( swwm_doomfall && e.Thing.bISMONSTER && !e.Thing.bBOSS )
|
|
e.Thing.bFALLDAMAGE = true;
|
|
if ( e.Thing is 'Key' )
|
|
{
|
|
DoKeyTagFix(e.Thing);
|
|
SWWMInterest.Spawn(self,thekey:Key(e.Thing));
|
|
}
|
|
if ( indoomvacation == -1 ) indoomvacation = SWWMUtility.InDoomVacation();
|
|
if ( inultdoom2 == -1 ) inultdoom2 = SWWMUtility.IsUltDoom2();
|
|
if ( e.Thing.GetClass() == 'Pig' )
|
|
e.Thing.SetTag("$FN_PIG"); // missing in gzdoom
|
|
// nashgore compat
|
|
else if ( e.Thing.GetClassName() == "NashGoreFootprintLeft" )
|
|
e.Thing.A_ChangeModel("",0,"","",0,"models/nashgore/Footprint","DemoFootprintL.png");
|
|
else if ( e.Thing.GetClassName() == "NashGoreFootprintRight" )
|
|
e.Thing.A_ChangeModel("",0,"","",0,"models/nashgore/Footprint","DemoFootprintR.png");
|
|
// eviternity stuff
|
|
else if ( (e.Thing.GetClassName() == "Archangelus")
|
|
|| (e.Thing.GetClassName() == "ArchangelusA")
|
|
|| (e.Thing.GetClassName() == "ArchangelusB") )
|
|
e.Thing.SetTag("$FN_ANGEL");
|
|
else if ( e.Thing.GetClassName() == "AstralCaco" )
|
|
e.Thing.SetTag("$FN_ASTRAL");
|
|
else if ( e.Thing.GetClassName() == "Annihilator" )
|
|
e.Thing.SetTag("$FN_ANNIHIL");
|
|
else if ( e.Thing.GetClassName() == "FormerCaptain" )
|
|
e.Thing.SetTag("$FN_FCAPTAIN");
|
|
else if ( e.Thing.GetClassName() == "NightmareDemon" )
|
|
e.Thing.SetTag("$FN_NDEMON");
|
|
// eviternity 2 stuff
|
|
else if ( e.Thing.GetClassName() == "FormerCorporal" )
|
|
e.Thing.SetTag("$FN_FCORPORAL");
|
|
else if ( e.Thing.GetClassName() == "AstralArachnotron" )
|
|
e.Thing.SetTag("$FN_ASTRALARACH");
|
|
else if ( e.Thing.GetClassName() == "AstralCacodemon" )
|
|
e.Thing.SetTag("$FN_ASTRAL");
|
|
else if ( e.Thing.GetClassName() == "Veilimp" )
|
|
e.Thing.SetTag("$FN_VEILIMP");
|
|
else if ( (e.Thing.GetClassName() == "GoldenAstralCaco")
|
|
|| (e.Thing.GetClassName() == "GoldenAstralCacoBoss") )
|
|
e.Thing.SetTag("$FN_ASTRALGOLD");
|
|
else if ( e.Thing.GetClassName() == "DukeOfHell" )
|
|
e.Thing.SetTag("$FN_DUKE");
|
|
else if ( e.Thing.GetClassName() == "AstralBabycaco" )
|
|
e.Thing.SetTag("$FN_ASTRALBABY");
|
|
else if ( e.Thing.GetClassName() == "NightmareCacodemon" )
|
|
e.Thing.SetTag("$FN_NAC");
|
|
else if ( e.Thing.GetClassName() == "AstralMancubus" )
|
|
e.Thing.SetTag("$FN_ASTRALFATSO");
|
|
else if ( (e.Thing.GetClassName() == "NecromenaceA")
|
|
|| (e.Thing.GetClassName() == "NecromenaceB")
|
|
|| (e.Thing.GetClassName() == "NecromenaceC")
|
|
|| (e.Thing.GetClassName() == "NecromenaceD") )
|
|
e.Thing.SetTag("$FN_NECROMENACE");
|
|
else if ( (e.Thing.GetClassName() == "The_Origin_Phase_1")
|
|
|| (e.Thing.GetClassName() == "The_Origin_Phase_2")
|
|
|| (e.Thing.GetClassName() == "The_Origin_Phase_3")
|
|
|| (e.Thing.GetClassName() == "The_Absolute_Origin_Phase_1")
|
|
|| (e.Thing.GetClassName() == "The_Absolute_Origin_Phase_2")
|
|
|| (e.Thing.GetClassName() == "The_Absolute_Origin_Phase_3") )
|
|
e.Thing.SetTag("$FN_ORIGIN");
|
|
else if ( e.Thing.GetClassName() == "SpectralAstralCacodemon" )
|
|
e.Thing.SetTag("$FN_SAC");
|
|
else if ( e.Thing.GetClassName() == "GrandDukeofHell" )
|
|
e.Thing.SetTag("$FN_GDUKE");
|
|
// doom vacation stuff
|
|
else if ( indoomvacation )
|
|
{
|
|
if ( e.Thing.GetClassName() == "Babe" )
|
|
{
|
|
e.Thing.bSHOOTABLE = false; // no hurt
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
HeadpatTracker(hp).heightfix = .2;
|
|
}
|
|
else if ( e.Thing.GetClassName() == "CommanderKeen" )
|
|
{
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
HeadpatTracker(hp).heightfix = .4;
|
|
HeadpatTracker(hp).angfix = 5;
|
|
}
|
|
else if ( e.Thing.GetClassName() == "BBChair" )
|
|
{
|
|
e.Thing.bUSESPECIAL = false;
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
HeadpatTracker(hp).heightfix = .2;
|
|
HeadpatTracker(hp).angfix = 15;
|
|
HeadpatTracker(hp).patstate = e.Thing.MeleeState;
|
|
}
|
|
else if ( e.Thing.GetClassName() == "EvilEye" )
|
|
{
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
HeadpatTracker(hp).heightfix = .1;
|
|
}
|
|
else if ( e.Thing.GetClassName() == "HeadCandles" )
|
|
{
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
HeadpatTracker(hp).angfix = 20;
|
|
}
|
|
else if ( e.Thing.GetClassName() == "HeartColumn" )
|
|
{
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
HeadpatTracker(hp).heightfix = -.3;
|
|
}
|
|
else if ( e.Thing.GetClassName() == "Meat2" )
|
|
{
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
HeadpatTracker(hp).heightfix = .6;
|
|
HeadpatTracker(hp).angfix = -15;
|
|
HeadpatTracker(hp).dvacationarghack = true;
|
|
}
|
|
else if ( e.Thing.GetClassName() == "Meat3" )
|
|
{
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
HeadpatTracker(hp).heightfix = .6;
|
|
HeadpatTracker(hp).angfix = 20;
|
|
HeadpatTracker(hp).dvacationarghack = true;
|
|
}
|
|
else if ( e.Thing.GetClassName() == "LegsBabe" )
|
|
{
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
HeadpatTracker(hp).heightfix = -1.5;
|
|
HeadpatTracker(hp).angfix = 20;
|
|
HeadpatTracker(hp).dvacationarghack = true;
|
|
}
|
|
else if ( e.Thing.GetClassName() == "Meat4" )
|
|
{
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
HeadpatTracker(hp).heightfix = .6;
|
|
HeadpatTracker(hp).angfix = 15;
|
|
HeadpatTracker(hp).dvacationarghack = true;
|
|
}
|
|
}
|
|
else if ( inultdoom2 && (e.Thing.GetClassName() == "WolfensteinSS") )
|
|
{
|
|
e.Thing.SetTag("$FN_ELITEZOMBIE");
|
|
//e.Thing.Obituary = "$OB_ELITEZOMBIE";
|
|
e.Thing.SeeSound = "grunt/sight";
|
|
e.Thing.AttackSound = "grunt/attack";
|
|
e.Thing.PainSound = "grunt/pain";
|
|
e.Thing.DeathSound = "grunt/death";
|
|
e.Thing.ActiveSound = "grunt/active";
|
|
}
|
|
else if ( ccloaded && (e.Thing.GetClassName() == "CCards_Token_Glitched") )
|
|
{
|
|
if ( !gdat.cclilithonce ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue.LILITH");
|
|
gdat.cclilithonce = true;
|
|
}
|
|
if ( SWWMUtility.IdentifyingDog(e.Thing) || SWWMUtility.IdentifyingCaco(e.Thing)
|
|
|| SWWMUtility.IdentifyingDrug(e.Thing) || SWWMUtility.IdentifyingDoubleBoi(e.Thing) )
|
|
{
|
|
// you can pet the dog, and you can also pet the caco (and friends)
|
|
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
|
hp.target = e.Thing;
|
|
}
|
|
// vanilla blood color changes
|
|
if ( (e.Thing.GetClass() == "BaronOfHell") || (e.Thing.GetClass() == "HellKnight") || (e.Thing.GetClass() == "Bishop") || (e.Thing.GetClass() == "Korax") )
|
|
{
|
|
let gb = Actor.Spawn("GreenBloodReference");
|
|
e.Thing.CopyBloodColor(gb);
|
|
gb.Destroy();
|
|
}
|
|
else if ( e.Thing.GetClass() == "Cacodemon" )
|
|
{
|
|
let bb = Actor.Spawn("BlueBloodReference");
|
|
e.Thing.CopyBloodColor(bb);
|
|
bb.Destroy();
|
|
}
|
|
else if ( (e.Thing.GetClass() == "Wizard") || (e.Thing.GetClass() == "Heresiarch") || (e.Thing.GetClass() == "Sorcerer2") )
|
|
{
|
|
let pb = Actor.Spawn("PurpleBloodReference");
|
|
e.Thing.CopyBloodColor(pb);
|
|
pb.Destroy();
|
|
}
|
|
else if ( e.Thing.GetClass() == "LostSoul" )
|
|
e.Thing.bNOBLOOD = true;
|
|
VanillaBossSpawn(e);
|
|
if ( profiling ) ProfileTock(PT_WORLDTHINGSPAWNED);
|
|
}
|
|
}
|