A whole fat load of micro-optimizations.
Okuplok still lags like fuck, unfortunately.
This commit is contained in:
parent
825caeca29
commit
b6f631f6e9
15 changed files with 369 additions and 280 deletions
|
|
@ -30,7 +30,7 @@ extend Class SWWMHandler
|
|||
S_StartSound("misc/emone",CHAN_VOICE,CHANF_UI);
|
||||
}
|
||||
SWWMCredits.Give(players[e.Args[0]],999999999);
|
||||
SWWMScoreObj.Spawn(999999999,players[e.Args[0]].mo.Vec3Offset(0,0,players[e.Args[0]].mo.Height/2));
|
||||
SWWMScoreObj.SpawnFromHandler(self,999999999,players[e.Args[0]].mo.Vec3Offset(0,0,players[e.Args[0]].mo.Height/2));
|
||||
}
|
||||
else if ( e.Name ~== "swwmlorecheat" )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ extend Class SWWMHandler
|
|||
bool spawnme = true;
|
||||
if ( swwm_accdamage )
|
||||
{
|
||||
// find existing damage number
|
||||
// find existing damage number (slow)
|
||||
for ( SWWMScoreObj d=damnums; d; d=d.next )
|
||||
{
|
||||
if ( (d.starttic < level.maptime) || (d.acc != e.Thing) ) continue;
|
||||
|
|
@ -76,20 +76,7 @@ extend Class SWWMHandler
|
|||
break;
|
||||
}
|
||||
}
|
||||
if ( spawnme ) SWWMScoreObj.Spawn(-e.Damage,e.Thing.Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+e.Thing.Height/2),ST_Damage,e.Thing);
|
||||
// update combat tracker for it
|
||||
// note: don't update if it's a hostile player unless hurt by you or a friend
|
||||
if ( !(e.Thing is 'BossBrain') && (!e.Thing.player || (!e.Thing.IsFriend(players[consoleplayer].mo) && e.DamageSource && e.DamageSource.IsFriend(players[consoleplayer].mo))) )
|
||||
{
|
||||
for ( SWWMCombatTracker t=trackers; t; t=t.next )
|
||||
{
|
||||
if ( t.mytarget != e.Thing ) continue;
|
||||
t.updated = level.maptime+35;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fall dmg
|
||||
SWWMWhoPushedMe.SetInstigator(e.Thing,e.DamageSource);
|
||||
if ( spawnme ) SWWMScoreObj.SpawnFromHandler(self,-e.Damage,e.Thing.Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+e.Thing.Height/2),ST_Damage,e.Thing);
|
||||
// stats
|
||||
if ( e.Thing.player )
|
||||
{
|
||||
|
|
@ -102,34 +89,34 @@ extend Class SWWMHandler
|
|||
if ( e.Damage > s.toptaken ) s.toptaken = e.Damage;
|
||||
}
|
||||
}
|
||||
if ( e.DamageSource && e.DamageSource.player )
|
||||
if ( !e.DamageSource || !e.DamageSource.player ) return;
|
||||
// fall dmg
|
||||
SWWMWhoPushedMe.SetInstigator(e.Thing,e.DamageSource);
|
||||
dealtdamage[e.DamageSource.PlayerNumber()] = true;
|
||||
let s = SWWMStats.Find(e.DamageSource.player);
|
||||
if ( s ) // deathmatch telefrag-on-spawn may cause this to be null
|
||||
{
|
||||
dealtdamage[e.DamageSource.PlayerNumber()] = true;
|
||||
let s = SWWMStats.Find(e.DamageSource.player);
|
||||
if ( s ) // deathmatch telefrag-on-spawn may cause this to be null
|
||||
{
|
||||
s.AddDamageDealt(e.Damage);
|
||||
if ( e.Damage > s.topdealt ) s.topdealt = e.Damage;
|
||||
}
|
||||
SWWMFlyTracker.Track(e.Thing,e.DamageSource);
|
||||
if ( e.Thing.bBOSS || e.Thing.FindInventory("BossMarker") )
|
||||
{
|
||||
let tk = e.Thing.FindInventory("DeepImpactOnlyToken");
|
||||
if ( !tk )
|
||||
{
|
||||
tk = Inventory(Actor.Spawn("DeepImpactOnlyToken"));
|
||||
tk.AttachToOwner(e.Thing);
|
||||
tk.special1 = 0;
|
||||
}
|
||||
Inventory pb;
|
||||
if ( (tk.special1 != -1) && ((e.DamageType == 'Push') || (e.Inflictor && (pb = e.Inflictor.FindInventory("ParriedBuff")) && pb.bAMBUSH)) )
|
||||
tk.special1 = 1;
|
||||
else tk.special1 = -1;
|
||||
}
|
||||
// barrel destruction
|
||||
if ( (e.Thing is 'ExplosiveBarrel') && (e.Thing.Health <= 0) )
|
||||
SWWMUtility.AchievementProgressInc("barrel",1,e.DamageSource.player);
|
||||
s.AddDamageDealt(e.Damage);
|
||||
if ( e.Damage > s.topdealt ) s.topdealt = e.Damage;
|
||||
}
|
||||
SWWMFlyTracker.Track(e.Thing,e.DamageSource);
|
||||
if ( e.Thing.bBOSS || e.Thing.FindInventory("BossMarker") )
|
||||
{
|
||||
let tk = e.Thing.FindInventory("DeepImpactOnlyToken");
|
||||
if ( !tk )
|
||||
{
|
||||
tk = Inventory(Actor.Spawn("DeepImpactOnlyToken"));
|
||||
tk.AttachToOwner(e.Thing);
|
||||
tk.special1 = 0;
|
||||
}
|
||||
Inventory pb;
|
||||
if ( (tk.special1 != -1) && ((e.DamageType == 'Push') || (e.Inflictor && (pb = e.Inflictor.FindInventory("ParriedBuff")) && pb.bAMBUSH)) )
|
||||
tk.special1 = 1;
|
||||
else tk.special1 = -1;
|
||||
}
|
||||
// barrel destruction
|
||||
if ( (e.Thing is 'ExplosiveBarrel') && (e.Thing.Health <= 0) )
|
||||
SWWMUtility.AchievementProgressInc("barrel",1,e.DamageSource.player);
|
||||
}
|
||||
|
||||
// combat hit chatter
|
||||
|
|
@ -272,7 +259,7 @@ extend Class SWWMHandler
|
|||
}
|
||||
SWWMScoreObj scr = null;
|
||||
if ( src.player == players[consoleplayer] )
|
||||
scr = SWWMScoreObj.Spawn(score,e.Thing.Vec3Offset(0,0,e.Thing.Height/2));
|
||||
scr = SWWMScoreObj.SpawnFromHandler(self,score,e.Thing.Vec3Offset(0,0,e.Thing.Height/2));
|
||||
int ofs = 0;
|
||||
if ( e.DamageType == 'Push' )
|
||||
{
|
||||
|
|
@ -335,7 +322,7 @@ extend Class SWWMHandler
|
|||
SWWMCredits.Give(src.player,1000);
|
||||
if ( src.player == players[consoleplayer] ) Console.Printf(StringTable.Localize("$SWWM_LASTMONSTER"),1000);
|
||||
else Console.Printf(StringTable.Localize("$SWWM_LASTMONSTERREM"),src.player.GetUserName(),1000);
|
||||
SWWMScoreObj.Spawn(1000,src.Vec3Offset(0,0,src.Height/2));
|
||||
SWWMScoreObj.SpawnFromHandler(self,1000,src.Vec3Offset(0,0,src.Height/2));
|
||||
SWWMUtility.AchievementProgressInc("allkills",1,src.player);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ extend Class SWWMHandler
|
|||
lastkill[e.playernumber] = int.min;
|
||||
// reset combat tracker
|
||||
if ( !swwm_notrack )
|
||||
SWWMCombatTracker.Spawn(players[e.playernumber].mo);
|
||||
SWWMCombatTracker.Spawn(self,players[e.playernumber].mo,true);
|
||||
// reset score (optional) if inventory should be cleared
|
||||
if ( swwm_resetscore && level.info.flags2&LEVEL2_RESETINVENTORY && !e.IsReturn )
|
||||
c.credits = 0;
|
||||
|
|
@ -154,6 +154,6 @@ extend Class SWWMHandler
|
|||
lastkill[e.playernumber] = int.min;
|
||||
// reset combat tracker
|
||||
if ( !swwm_notrack )
|
||||
SWWMCombatTracker.Spawn(players[e.playernumber].mo);
|
||||
SWWMCombatTracker.Spawn(self,players[e.playernumber].mo,true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ extend Class SWWMHandler
|
|||
while ( a = Actor(ti.Next()) )
|
||||
{
|
||||
if ( (!a.bSHOOTABLE && !a.bISMONSTER) || (a is 'LampMoth') || (a is 'CompanionLamp') ) continue;
|
||||
let trk = SWWMCombatTracker.Spawn(a,true);
|
||||
let trk = SWWMCombatTracker.Spawn(self,a,true);
|
||||
if ( !a.player ) trk.maxhealth = max(a.health,a.GetSpawnHealth());
|
||||
}
|
||||
n = (trackers_cnt-n);
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ extend Class SWWMHandler
|
|||
for ( int i=0; i<con.Size(); i++ )
|
||||
lpos += SWWMUtility.UseLinePos(con[i]);
|
||||
lpos /= con.Size();
|
||||
SWWMInterest.Spawn(lpos,theline:l,theexit:exittype);
|
||||
SWWMInterest.Spawn(self,lpos,theline:l,theexit:exittype);
|
||||
}
|
||||
// spawn loot
|
||||
if ( !deathmatch ) Chancebox.SpawnChanceboxes();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ extend Class SWWMHandler
|
|||
if ( profiling ) ProfileTick();
|
||||
// reattach combat tracker
|
||||
if ( !swwm_notrack && (e.Thing.bSHOOTABLE || e.Thing.bISMONSTER) && !(e.Thing is 'LampMoth') && !(e.Thing is 'CompanionLamp') )
|
||||
SWWMCombatTracker.Spawn(e.Thing);
|
||||
SWWMCombatTracker.Spawn(self,e.Thing,true);
|
||||
// reattach headpats
|
||||
if ( SWWMUtility.IdentifyingDog(e.Thing) || SWWMUtility.IdentifyingCaco(e.Thing)
|
||||
|| SWWMUtility.IdentifyingDrug(e.Thing) || SWWMUtility.IdentifyingDoubleBoi(e.Thing) )
|
||||
|
|
@ -232,19 +232,20 @@ extend Class SWWMHandler
|
|||
// for gibber throttling
|
||||
if ( e.Thing is 'mkBloodDrop' ) blods_realcnt--;
|
||||
else if ( e.Thing is 'mkFlyingGib' ) meats_realcnt--;
|
||||
if ( !e.Thing.default.bSHOOTABLE && !e.Thing.default.bMISSILE && !(e.Thing is 'Inventory') && !SWWMUtility.IsBeamProj(e.Thing) )
|
||||
if ( e.Thing.default.bSHOOTABLE || (e.Thing is 'Inventory') || SWWMUtility.ValidProjectile(e.Thing) )
|
||||
{
|
||||
if ( profiling ) ProfileTock(PT_WORLDTHINGDESTROYED);
|
||||
return;
|
||||
// remove from suckables
|
||||
int pos = suckableactors.Find(e.Thing);
|
||||
if ( pos < suckableactors.Size() )
|
||||
suckableactors.Delete(pos);
|
||||
}
|
||||
else if ( SWWMUtility.IsBeamProj(e.Thing) )
|
||||
{
|
||||
// remove from beams
|
||||
int pos = beams.Find(e.Thing);
|
||||
if ( pos < beams.Size() )
|
||||
beams.Delete(pos);
|
||||
}
|
||||
// remove from suckables
|
||||
int pos = suckableactors.Find(e.Thing);
|
||||
if ( pos < suckableactors.Size() )
|
||||
suckableactors.Delete(pos);
|
||||
// remove from beams
|
||||
pos = beams.Find(e.Thing);
|
||||
if ( pos < beams.Size() )
|
||||
beams.Delete(pos);
|
||||
if ( profiling ) ProfileTock(PT_WORLDTHINGDESTROYED);
|
||||
}
|
||||
|
||||
|
|
@ -280,7 +281,7 @@ extend Class SWWMHandler
|
|||
if ( e.Thing is 'Key' )
|
||||
{
|
||||
DoKeyTagFix(e.Thing);
|
||||
SWWMInterest.Spawn(thekey:Key(e.Thing));
|
||||
SWWMInterest.Spawn(self,thekey:Key(e.Thing));
|
||||
}
|
||||
if ( indoomvacation == -1 ) indoomvacation = SWWMUtility.InDoomVacation();
|
||||
if ( inultdoom2 == -1 ) inultdoom2 = SWWMUtility.IsUltDoom2();
|
||||
|
|
@ -403,13 +404,13 @@ extend Class SWWMHandler
|
|||
let hp = Actor.Spawn("HeadpatTracker",e.Thing.pos);
|
||||
hp.target = e.Thing;
|
||||
}
|
||||
SWWMCombatTracker trk;
|
||||
SWWMCombatTracker trk = null;
|
||||
if ( !swwm_notrack && (e.Thing.bSHOOTABLE || e.Thing.bISMONSTER) && !(e.Thing is 'LampMoth') && !(e.Thing is 'CompanionLamp') )
|
||||
trk = SWWMCombatTracker.Spawn(e.Thing);
|
||||
trk = SWWMCombatTracker.Spawn(self,e.Thing);
|
||||
if ( swwm_shadows && !(e.Thing is 'LampMoth') && (e.Thing.bSHOOTABLE || e.Thing.bISMONSTER || (e.Thing is 'Inventory') || (e.Thing is 'CompanionLamp')) && ((e.Thing is 'Demolitionist') || (e.Thing.SpawnState.sprite == e.Thing.GetSpriteIndex('XZW1'))) )
|
||||
SWWMShadow.Track(e.Thing);
|
||||
// Ynykron vortex optimization (faster than a thinker iterator)
|
||||
if ( e.Thing.bSHOOTABLE || SWWMUtility.ValidProjectile(e.Thing) || (e.Thing is 'Inventory') )
|
||||
if ( e.Thing.bSHOOTABLE || (e.Thing is 'Inventory') || SWWMUtility.ValidProjectile(e.Thing) )
|
||||
SuckableActors.Push(e.Thing);
|
||||
else if ( SWWMUtility.IsBeamProj(e.Thing) )
|
||||
Beams.Push(e.Thing);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ extend Class SWWMHandler
|
|||
{
|
||||
// manually refresh some tags if language has changed
|
||||
for ( SWWMCombatTracker t=trackers; t; t=t.next )
|
||||
t.UpdateTag();
|
||||
t.UpdateTag(self);
|
||||
for ( SWWMInterest p=intpoints; p; p=p.next )
|
||||
{
|
||||
if ( (p.type != INT_Key) || !p.trackedkey ) continue;
|
||||
|
|
@ -61,7 +61,7 @@ extend Class SWWMHandler
|
|||
SWWMUtility.AchievementProgressInc("allitems",1,players[i]);
|
||||
}
|
||||
SWWMCredits.Give(players[i],score);
|
||||
SWWMScoreObj.Spawn(score,players[i].mo.Vec3Offset(0,0,players[i].mo.Height/2));
|
||||
SWWMScoreObj.SpawnFromHandler(self,score,players[i].mo.Vec3Offset(0,0,players[i].mo.Height/2));
|
||||
lastitemcount[i] = players[i].itemcount;
|
||||
let s = SWWMStats.Find(players[i]);
|
||||
s.items++;
|
||||
|
|
@ -105,13 +105,14 @@ extend Class SWWMHandler
|
|||
if ( !a.player && !a.bISMONSTER ) continue;
|
||||
// ignore the dead
|
||||
if ( (a.Health <= 0) || a.bKILLED || a.bCORPSE ) continue;
|
||||
// ignore if not targetted
|
||||
if ( a.target != players[consoleplayer].mo ) continue;
|
||||
// ignore friends
|
||||
if ( a.IsFriend(players[consoleplayer].mo) ) continue;
|
||||
// ignore if not targetted or player can't see it
|
||||
if ( (a.target != players[consoleplayer].mo)
|
||||
|| !SWWMUtility.InPlayerFOV(players[consoleplayer],a) ) continue;
|
||||
// [HDoom] ignore cute girls
|
||||
if ( SWWMHDoomHandler.IsCuteGirl(a.target) ) continue;
|
||||
// ignore if player can't see it
|
||||
if ( !SWWMUtility.InPlayerFOV(players[consoleplayer],a) ) continue;
|
||||
// is it already in?
|
||||
bool addme = true;
|
||||
for ( int i=0; i<combatactors.Size(); i++ )
|
||||
|
|
@ -204,12 +205,12 @@ extend Class SWWMHandler
|
|||
if ( mapclearagain )
|
||||
{
|
||||
SWWMCredits.Give(players[i],500);
|
||||
SWWMScoreObj.Spawn(500,players[i].mo.Vec3Offset(0,0,players[i].mo.Height/2));
|
||||
SWWMScoreObj.SpawnFromHandler(self,500,players[i].mo.Vec3Offset(0,0,players[i].mo.Height/2));
|
||||
}
|
||||
else
|
||||
{
|
||||
SWWMCredits.Give(players[i],5000);
|
||||
SWWMScoreObj.Spawn(5000,players[i].mo.Vec3Offset(0,0,players[i].mo.Height/2));
|
||||
SWWMScoreObj.SpawnFromHandler(self,5000,players[i].mo.Vec3Offset(0,0,players[i].mo.Height/2));
|
||||
}
|
||||
}
|
||||
mapclearagain++;
|
||||
|
|
@ -333,7 +334,7 @@ extend Class SWWMHandler
|
|||
continue;
|
||||
if ( (a is 'Chancebox') && (a.CurState != a.SpawnState) )
|
||||
continue;
|
||||
SWWMSimpleTracker.Track(a);
|
||||
SWWMSimpleTracker.Track(self,a);
|
||||
}
|
||||
// we need to refer to the suckables array to find missiles
|
||||
for ( int i=0; i<suckableactors.Size(); i++ )
|
||||
|
|
@ -345,7 +346,7 @@ extend Class SWWMHandler
|
|||
continue;
|
||||
if ( !level.allmap && !(a.target && a.target.IsFriend(players[consoleplayer].mo)) && !players[consoleplayer].Camera.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
|
||||
continue;
|
||||
SWWMSimpleTracker.Track(a);
|
||||
SWWMSimpleTracker.Track(self,a);
|
||||
}
|
||||
for ( int i=0; i<beams.Size(); i++ )
|
||||
{
|
||||
|
|
@ -357,7 +358,7 @@ extend Class SWWMHandler
|
|||
continue;
|
||||
if ( !level.allmap && !(a.target && a.target.IsFriend(players[consoleplayer].mo)) && !players[consoleplayer].Camera.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
|
||||
continue;
|
||||
SWWMSimpleTracker.Track(a);
|
||||
SWWMSimpleTracker.Track(self,a);
|
||||
}
|
||||
bt.Destroy();
|
||||
if ( swwm_mm_portaloverlay && (psectors.Size() > 1) )
|
||||
|
|
@ -391,7 +392,7 @@ extend Class SWWMHandler
|
|||
continue;
|
||||
if ( (a is 'Chancebox') && (a.CurState != a.SpawnState) )
|
||||
continue;
|
||||
SWWMSimpleTracker.Track(a);
|
||||
SWWMSimpleTracker.Track(self,a);
|
||||
}
|
||||
// we need to refer to the suckables array to find missiles
|
||||
for ( int i=0; i<suckableactors.Size(); i++ )
|
||||
|
|
@ -403,7 +404,7 @@ extend Class SWWMHandler
|
|||
continue;
|
||||
if ( !level.allmap && !(a.target && a.target.IsFriend(players[consoleplayer].mo)) && !players[consoleplayer].Camera.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
|
||||
continue;
|
||||
SWWMSimpleTracker.Track(a);
|
||||
SWWMSimpleTracker.Track(self,a);
|
||||
}
|
||||
for ( int i=0; i<beams.Size(); i++ )
|
||||
{
|
||||
|
|
@ -415,7 +416,7 @@ extend Class SWWMHandler
|
|||
continue;
|
||||
if ( !level.allmap && !(a.target && a.target.IsFriend(players[consoleplayer].mo)) && !players[consoleplayer].Camera.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
|
||||
continue;
|
||||
SWWMSimpleTracker.Track(a);
|
||||
SWWMSimpleTracker.Track(self,a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,19 @@ Class SWWMScoreObj play
|
|||
else if ( (type > ST_SCORE) && !swwm_healthnums ) return null;
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( !hnd ) return null;
|
||||
return SpawnInternal(hnd,score,pos,type,acc,tcolor);
|
||||
}
|
||||
|
||||
static SWWMScoreObj SpawnFromHandler( SWWMHandler hnd, int score, Vector3 pos, int type = ST_Score, Actor acc = null, int tcolor = -1 )
|
||||
{
|
||||
// early checks
|
||||
if ( (type == ST_SCORE) && !swwm_scorenums ) return null;
|
||||
else if ( (type > ST_SCORE) && !swwm_healthnums ) return null;
|
||||
return SpawnInternal(hnd,score,pos,type,acc,tcolor);
|
||||
}
|
||||
|
||||
private static SWWMScoreObj SpawnInternal( SWWMHandler hnd, int score, Vector3 pos, int type = ST_Score, Actor acc = null, int tcolor = -1 )
|
||||
{
|
||||
let o = new("SWWMScoreObj");
|
||||
o.score = score;
|
||||
o.pos = pos;
|
||||
|
|
@ -117,10 +130,8 @@ Class SWWMInterest play
|
|||
SWWMInterest next;
|
||||
String keytag;
|
||||
|
||||
static SWWMInterest Spawn( Vector3 pos = (0,0,0), Key thekey = null, Line theline = null, int theexit = 0 )
|
||||
static SWWMInterest Spawn( SWWMHandler hnd, Vector3 pos = (0,0,0), Key thekey = null, Line theline = null, int theexit = 0 )
|
||||
{
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( !hnd ) return null;
|
||||
if ( (!thekey && !theline) || (thekey && theline) ) return null;
|
||||
let i = new("SWWMInterest");
|
||||
i.trackedkey = thekey;
|
||||
|
|
@ -259,11 +270,11 @@ Class SWWMCombatTracker play
|
|||
bool bUpdateMorph;
|
||||
String unmorphedtag;
|
||||
|
||||
void UpdateTag()
|
||||
void UpdateTag( SWWMHandler hnd )
|
||||
{
|
||||
if ( mytarget && (mytarget.player || mytarget.bISMONSTER || (mytarget is 'BossBrain') || (mytarget is 'SWWMHangingKeen') || (mytarget is 'Demolitionist')) )
|
||||
{
|
||||
String realtag = swwm_funtags?SWWMUtility.GetFunTag(mytarget,FallbackTag):mytarget.GetTag(FallbackTag);
|
||||
String realtag = swwm_funtags?SWWMUtility.GetFunTag(hnd,mytarget,FallbackTag):mytarget.GetTag(FallbackTag);
|
||||
if ( realtag == FallbackTag )
|
||||
{
|
||||
realtag = mytarget.GetClassName();
|
||||
|
|
@ -274,10 +285,8 @@ Class SWWMCombatTracker play
|
|||
else mytag = "";
|
||||
}
|
||||
|
||||
static SWWMCombatTracker Spawn( Actor target, bool update = false )
|
||||
static SWWMCombatTracker Spawn( SWWMHandler hnd, Actor target, bool update = false )
|
||||
{
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( !hnd ) return null;
|
||||
// NOTE: These are only ever called once a thing spawns, so we don't need to "check" if entries already exist
|
||||
// this check will only be performed in "update mode", i.e. when called from the swwmupdatetrackers netevent,
|
||||
// or when a monster is revived
|
||||
|
|
@ -289,7 +298,7 @@ Class SWWMCombatTracker play
|
|||
}
|
||||
t = new("SWWMCombatTracker");
|
||||
t.mytarget = target;
|
||||
t.UpdateTag();
|
||||
t.UpdateTag(hnd);
|
||||
if ( target.player )
|
||||
{
|
||||
t.lasthealth = target.health;
|
||||
|
|
@ -393,7 +402,8 @@ Class SWWMCombatTracker play
|
|||
mutated = true;
|
||||
Console.Printf(StringTable.Localize("$SWWM_LTFORM"),mytag);
|
||||
}
|
||||
}// voodoo dolls don't show as friendly
|
||||
}
|
||||
// voodoo dolls don't show as friendly
|
||||
bFRIENDLY = mytarget.IsFriend(players[consoleplayer].mo);
|
||||
if ( mytarget.Health < lasthealth ) firsthit = true;
|
||||
lasthealth = mytarget.Health;
|
||||
|
|
@ -516,10 +526,8 @@ Class SWWMSimpleTracker play
|
|||
expired = (target.Health<=0);
|
||||
}
|
||||
|
||||
static SWWMSimpleTracker Track( Actor target )
|
||||
static SWWMSimpleTracker Track( SWWMHandler hnd, Actor target )
|
||||
{
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( !hnd ) return null;
|
||||
SWWMSimpleTracker t;
|
||||
for ( t=hnd.strackers; t; t=t.next )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3009,6 +3009,7 @@ Class MykradvoX : GhostArtifactX
|
|||
{
|
||||
Super.PostBeginPlay();
|
||||
A_StartSound("powerup/mykradvoamb",CHAN_VOICE,CHANF_LOOP,attenuation:2.);
|
||||
WorldOffset = (0,0,16);
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
|
|
@ -3024,9 +3025,13 @@ Class MykradvoX : GhostArtifactX
|
|||
FloatBobPhase = target.FloatBobPhase;
|
||||
A_SetScale(.16+.01*sin(GetAge()*4));
|
||||
if ( !bsprite ) bsprite = GetSpriteIndex('XZW0');
|
||||
bool bOldInvis = bInvisible;
|
||||
bInvisible = target.bInvisible||(target.sprite!=bsprite);
|
||||
SetState(SpawnState+bInvisible);
|
||||
A_SoundVolume(CHAN_VOICE,bInvisible?0.:1.);
|
||||
if ( bInvisible != bOldInvis )
|
||||
{
|
||||
SetState(SpawnState+bInvisible);
|
||||
A_SoundVolume(CHAN_VOICE,bInvisible?0.:1.);
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
|
|
@ -3043,6 +3048,11 @@ Class MykradvoX2 : GhostArtifactX
|
|||
{
|
||||
+ROLLSPRITE;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
WorldOffset = (0,0,16+special2);
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
if ( !target )
|
||||
|
|
@ -3050,17 +3060,19 @@ Class MykradvoX2 : GhostArtifactX
|
|||
Destroy();
|
||||
return;
|
||||
}
|
||||
prev = target.prev+(0,0,16+special2);
|
||||
prev = target.prev;
|
||||
vel = target.vel;
|
||||
if ( (target.pos != pos+(0,0,16+special2)) || (target.vel != (0,0,0)) ) SetOrigin(target.pos+(0,0,16+special2)+vel,true);
|
||||
if ( (target.pos != pos) || (target.vel != (0,0,0)) ) SetOrigin(target.pos+vel,true);
|
||||
if ( angle != target.angle ) A_SetAngle(target.angle,SPF_INTERPOLATE);
|
||||
A_SetPitch(sin(GetAge()*special1*8)*5,SPF_INTERPOLATE);
|
||||
A_SetRoll(cos(GetAge()*special1*8)*5,SPF_INTERPOLATE);
|
||||
FloatBobPhase = target.FloatBobPhase;
|
||||
A_SetScale(1.+.05*cos(GetAge()*4)*special1);
|
||||
if ( !bsprite ) bsprite = GetSpriteIndex('XZW0');
|
||||
bool bOldInvis = bInvisible;
|
||||
bInvisible = target.bInvisible||(target.sprite!=bsprite);
|
||||
SetState(SpawnState+bInvisible);
|
||||
if ( bInvisible != bOldInvis )
|
||||
SetState(SpawnState+bInvisible);
|
||||
}
|
||||
States
|
||||
{
|
||||
|
|
@ -3429,6 +3441,7 @@ Class AngerySigilX : GhostArtifactX
|
|||
{
|
||||
Super.PostBeginPlay();
|
||||
A_StartSound("powerup/devastationamb",CHAN_VOICE,CHANF_LOOP,attenuation:2.);
|
||||
WorldOffset = (0,0,20);
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
|
|
@ -3437,15 +3450,19 @@ Class AngerySigilX : GhostArtifactX
|
|||
Destroy();
|
||||
return;
|
||||
}
|
||||
prev = target.prev+(0,0,20);
|
||||
prev = target.prev;
|
||||
vel = target.vel;
|
||||
if ( (target.pos != pos+(0,0,20)) || (target.vel != (0,0,0)) ) SetOrigin(target.pos+(0,0,20)+vel,true);
|
||||
if ( (target.pos != pos) || (target.vel != (0,0,0)) ) SetOrigin(target.pos+vel,true);
|
||||
if ( angle != target.angle ) A_SetAngle(target.angle,SPF_INTERPOLATE);
|
||||
FloatBobPhase = target.FloatBobPhase;
|
||||
if ( !bsprite ) bsprite = GetSpriteIndex('XZW1');
|
||||
bool bOldInvis = bInvisible;
|
||||
bInvisible = target.bInvisible||(target.sprite!=bsprite);
|
||||
SetState(SpawnState+bInvisible);
|
||||
A_SoundVolume(CHAN_VOICE,bInvisible?0.:1.);
|
||||
if ( bInvisible != bOldInvis )
|
||||
{
|
||||
SetState(SpawnState+bInvisible);
|
||||
A_SoundVolume(CHAN_VOICE,bInvisible?0.:1.);
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
|
|
@ -3701,6 +3718,7 @@ Class DivineSpriteX : GhostArtifactX
|
|||
{
|
||||
Super.PostBeginPlay();
|
||||
A_StartSound("powerup/divineamb",CHAN_VOICE,CHANF_LOOP,attenuation:2.);
|
||||
WorldOffset = (0,0,16);
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
|
|
@ -3709,15 +3727,19 @@ Class DivineSpriteX : GhostArtifactX
|
|||
Destroy();
|
||||
return;
|
||||
}
|
||||
prev = target.prev+(0,0,16);
|
||||
prev = target.prev;
|
||||
vel = target.vel;
|
||||
if ( (target.pos != pos+(0,0,16)) || (target.vel != (0,0,0)) ) SetOrigin(target.pos+(0,0,16)+vel,true);
|
||||
if ( (target.pos != pos) || (target.vel != (0,0,0)) ) SetOrigin(target.pos+vel,true);
|
||||
if ( angle != target.angle ) A_SetAngle(target.angle,SPF_INTERPOLATE);
|
||||
FloatBobPhase = target.FloatBobPhase;
|
||||
if ( !bsprite ) bsprite = GetSpriteIndex('XZW1');
|
||||
bool bOldInvis = bInvisible;
|
||||
bInvisible = target.bInvisible||(target.sprite!=bsprite);
|
||||
SetState(SpawnState+bInvisible);
|
||||
A_SoundVolume(CHAN_VOICE,bInvisible?0.:1.);
|
||||
if ( bOldInvis != bInvisible )
|
||||
{
|
||||
SetState(SpawnState+bInvisible);
|
||||
A_SoundVolume(CHAN_VOICE,bInvisible?0.:1.);
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,3 +34,171 @@ Class SWWMNothing : Actor
|
|||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class SWWMDamageAccumulator : Inventory
|
||||
{
|
||||
Actor inflictor, source;
|
||||
Array<Int> amounts;
|
||||
int total;
|
||||
Name type;
|
||||
bool dontgib;
|
||||
int flags;
|
||||
|
||||
override void DoEffect()
|
||||
{
|
||||
Super.DoEffect();
|
||||
// so many damn safeguards in this
|
||||
if ( !Owner || (Owner.Health <= 0) )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
int gibhealth = Owner.GetGibHealth();
|
||||
// お前はもう死んでいる
|
||||
if ( (Owner.health-total <= gibhealth) && !dontgib )
|
||||
{
|
||||
// safeguard for inflictors that have somehow ceased to exist, which apparently STILL CAN HAPPEN
|
||||
if ( inflictor ) inflictor.bEXTREMEDEATH = true;
|
||||
else type = 'Extreme';
|
||||
}
|
||||
// make sure accumulation isn't reentrant
|
||||
if ( inflictor && (inflictor is 'EvisceratorChunk') ) inflictor.bAMBUSH = true;
|
||||
// 何?
|
||||
for ( int i=0; i<amounts.Size(); i++ )
|
||||
{
|
||||
if ( !Owner ) break;
|
||||
Owner.DamageMobj(inflictor,source,amounts[i],type,DMG_THRUSTLESS|flags);
|
||||
}
|
||||
// clean up
|
||||
if ( inflictor )
|
||||
{
|
||||
if ( inflictor is 'EvisceratorChunk' ) inflictor.bAMBUSH = false;
|
||||
inflictor.bEXTREMEDEATH = false;
|
||||
}
|
||||
Destroy();
|
||||
}
|
||||
|
||||
static void Accumulate( Actor victim, int amount, Actor inflictor, Actor source, Name type, bool dontgib = false, int flags = 0 )
|
||||
{
|
||||
if ( !victim ) return;
|
||||
SWWMDamageAccumulator match = SWWMDamageAccumulator(victim.FindInventory("SWWMDamageAccumulator"));
|
||||
if ( !match )
|
||||
{
|
||||
match = SWWMDamageAccumulator(Spawn("SWWMDamageAccumulator"));
|
||||
match.AttachToOwner(victim);
|
||||
}
|
||||
match.amounts.Push(amount);
|
||||
match.total += amount;
|
||||
match.inflictor = inflictor;
|
||||
match.source = source;
|
||||
match.type = type;
|
||||
match.dontgib = dontgib;
|
||||
match.flags = flags;
|
||||
}
|
||||
|
||||
static clearscope int GetAmount( Actor victim )
|
||||
{
|
||||
let ti = ThinkerIterator.Create("SWWMDamageAccumulator",STAT_USER);
|
||||
SWWMDamageAccumulator match = SWWMDamageAccumulator(victim.FindInventory("SWWMDamageAccumulator"));
|
||||
if ( match )
|
||||
{
|
||||
if ( match.source && match.source.FindInventory("AngeryPower") )
|
||||
return (match.total>85899345)?int.max:(match.total*25);
|
||||
return match.total;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
default
|
||||
{
|
||||
+INVENTORY.UNTOSSABLE;
|
||||
+INVENTORY.UNDROPPABLE;
|
||||
+INVENTORY.UNCLEARABLE;
|
||||
}
|
||||
}
|
||||
|
||||
// Track last damage source to blame fall damage on
|
||||
Class SWWMWhoPushedMe : Inventory
|
||||
{
|
||||
Actor instigator;
|
||||
|
||||
static void SetInstigator( Actor b, Actor whomst )
|
||||
{
|
||||
if ( !b || !whomst ) return;
|
||||
SWWMWhoPushedMe ffd = SWWMWhoPushedMe(b.FindInventory("SWWMWhoPushedMe"));
|
||||
if ( ffd )
|
||||
{
|
||||
ffd.instigator = whomst;
|
||||
return;
|
||||
}
|
||||
ffd = SWWMWhoPushedMe(Spawn("SWWMWhoPushedMe"));
|
||||
ffd.AttachToOwner(b);
|
||||
ffd.instigator = whomst;
|
||||
}
|
||||
|
||||
static Actor RecallInstigator( Actor b )
|
||||
{
|
||||
if ( !b ) return null;
|
||||
SWWMWhoPushedMe ffd = SWWMWhoPushedMe(b.FindInventory("SWWMWhoPushedMe"));
|
||||
if ( ffd )
|
||||
{
|
||||
Actor whomst = ffd.instigator;
|
||||
ffd.Destroy();
|
||||
return whomst;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
default
|
||||
{
|
||||
+INVENTORY.UNTOSSABLE;
|
||||
+INVENTORY.UNDROPPABLE;
|
||||
+INVENTORY.UNCLEARABLE;
|
||||
}
|
||||
}
|
||||
|
||||
Class SWWMFlyTracker : Inventory
|
||||
{
|
||||
Actor instigator;
|
||||
Vector3 startpos, curpos;
|
||||
double maxdist;
|
||||
int gracepd;
|
||||
|
||||
static void Track( Actor b, Actor whomst )
|
||||
{
|
||||
if ( !b || !whomst ) return;
|
||||
SWWMFlyTracker ffd = SWWMFlyTracker(b.FindInventory("SWWMFlyTracker"));
|
||||
if ( ffd )
|
||||
{
|
||||
ffd.instigator = whomst;
|
||||
return;
|
||||
}
|
||||
ffd = SWWMFlyTracker(Spawn("SWWMFlyTracker"));
|
||||
ffd.AttachToOwner(b);
|
||||
ffd.instigator = whomst;
|
||||
ffd.curpos = ffd.startpos = b.pos;
|
||||
ffd.maxdist = 0;
|
||||
}
|
||||
|
||||
override void DoEffect()
|
||||
{
|
||||
maxdist = max(maxdist,level.Vec3Diff(startpos,curpos).length());
|
||||
if ( !Owner || Owner.bFLOAT || Owner.bNOGRAVITY || (Owner.waterlevel > 1) || (Owner.pos.z <= Owner.floorz) || !Owner.TestMobjZ(false) )
|
||||
{
|
||||
gracepd++;
|
||||
if ( gracepd < 10 ) return;
|
||||
if ( instigator ) SWWMUtility.AchievementProgress("flight",int(maxdist),instigator.player);
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
gracepd = 0;
|
||||
curpos = Owner.pos;
|
||||
}
|
||||
|
||||
default
|
||||
{
|
||||
+INVENTORY.UNTOSSABLE;
|
||||
+INVENTORY.UNDROPPABLE;
|
||||
+INVENTORY.UNCLEARABLE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -792,6 +792,17 @@ Class SWWMItemFog : Actor
|
|||
+FORCEXYBILLBOARD;
|
||||
FloatBobPhase 0;
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
if ( isFrozen() ) return;
|
||||
if ( !CheckNoDelay() || (tics == -1) ) return;
|
||||
if ( tics > 0 ) tics--;
|
||||
while ( !tics )
|
||||
{
|
||||
if ( !SetState(CurState.NextState) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
@ -856,6 +867,7 @@ Class SWWMTeleportSparkle : Actor
|
|||
A_FadeOut(specialf2);
|
||||
if ( vel != (0,0,0) )
|
||||
{
|
||||
prev = pos;
|
||||
SetOrigin(level.Vec3Offset(pos,vel),true);
|
||||
vel *= .98;
|
||||
}
|
||||
|
|
@ -967,6 +979,17 @@ Class SWWMTeleportFog : Actor
|
|||
Spawn("TeleLight",pos);
|
||||
if ( swwm_simplefog ) SetStateLabel("Simple");
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
if ( isFrozen() ) return;
|
||||
if ( !CheckNoDelay() || (tics == -1) ) return;
|
||||
if ( tics > 0 ) tics--;
|
||||
while ( !tics )
|
||||
{
|
||||
if ( !SetState(CurState.NextState) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
@ -1065,7 +1088,11 @@ Class SWWMPickupFlash : Actor
|
|||
}
|
||||
else if ( bINVISIBLE ) bINVISIBLE = false;
|
||||
// try to reduce calls to SetOrigin as much as possible, for performance
|
||||
if ( target.pos != invoker.lastitempos ) SetOrigin(target.Vec3Offset(0,0,16),true);
|
||||
if ( target.pos != invoker.lastitempos )
|
||||
{
|
||||
prev = pos;
|
||||
SetOrigin(target.Vec3Offset(0,0,16),true);
|
||||
}
|
||||
invoker.lastitempos = target.pos;
|
||||
if ( target.bFLOATBOB && !bFLOATBOB )
|
||||
{
|
||||
|
|
@ -1077,6 +1104,17 @@ Class SWWMPickupFlash : Actor
|
|||
A_SetScale(FRandom[ClientSparkles](.9,1.1)*(max(target.radius,target.height)/16.));
|
||||
alpha = FRandom[ClientSparkles](.9,1.)*clamp((max(0,Distance3DSquared(players[consoleplayer].Camera)-40000.)/160000000.)**.25,0.,1.);
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
if ( isFrozen() ) return;
|
||||
if ( !CheckNoDelay() || (tics == -1) ) return;
|
||||
if ( tics > 0 ) tics--;
|
||||
while ( !tics )
|
||||
{
|
||||
if ( !SetState(CurState.NextState) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
@ -1264,6 +1302,18 @@ Class SWWMPuff : Actor
|
|||
return Super.GetObituary(victim,inflictor,mod,playerattack);
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
if ( isFrozen() ) return;
|
||||
if ( !CheckNoDelay() || (tics == -1) ) return;
|
||||
if ( tics > 0 ) tics--;
|
||||
while ( !tics )
|
||||
{
|
||||
if ( !SetState(CurState.NextState) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
default
|
||||
{
|
||||
Radius .1;
|
||||
|
|
@ -1395,6 +1445,17 @@ Class SWWMBaseSplash : Actor
|
|||
+NOTELEPORT;
|
||||
FloatBobPhase 0;
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
if ( isFrozen() ) return;
|
||||
if ( !CheckNoDelay() || (tics == -1) ) return;
|
||||
if ( tics > 0 ) tics--;
|
||||
while ( !tics )
|
||||
{
|
||||
if ( !SetState(CurState.NextState) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ Class SWWMHandler : EventHandler
|
|||
int iwantdie;
|
||||
int indoomvacation;
|
||||
int inultdoom2;
|
||||
bool funtagsv;
|
||||
|
||||
// for checkreplacement
|
||||
bool hasdrlamonsters;
|
||||
|
|
@ -90,6 +91,9 @@ Class SWWMHandler : EventHandler
|
|||
bludtypes.Push(list[i]);
|
||||
}
|
||||
}
|
||||
// check if fun tag services actually exist (can reduce overhead severely on map load if they don't, due to combat tracker tag lookups)
|
||||
if ( ServiceIterator.Find("FunTagService").Next() )
|
||||
funtagsv = true;
|
||||
// start profiling
|
||||
if ( swwm_profstart <= 0 ) return;
|
||||
bprofiletics = profiletics = swwm_profstart;
|
||||
|
|
|
|||
|
|
@ -30,129 +30,6 @@ Class UglyBoyGetsFuckedUp : Thinker
|
|||
}
|
||||
}
|
||||
|
||||
// Track last damage source to blame fall damage on
|
||||
Class SWWMWhoPushedMe : Thinker
|
||||
{
|
||||
Actor tracked, instigator;
|
||||
|
||||
static void SetInstigator( Actor b, Actor whomst )
|
||||
{
|
||||
if ( !b || !whomst ) return;
|
||||
let ti = ThinkerIterator.Create("SWWMWhoPushedMe",STAT_INFO);
|
||||
SWWMWhoPushedMe ffd;
|
||||
while ( ffd = SWWMWhoPushedMe(ti.Next()) )
|
||||
{
|
||||
if ( ffd.tracked != b ) continue;
|
||||
ffd.instigator = whomst;
|
||||
return;
|
||||
}
|
||||
ffd = new("SWWMWhoPushedMe");
|
||||
ffd.ChangeStatNum(STAT_INFO);
|
||||
ffd.tracked = b;
|
||||
ffd.instigator = whomst;
|
||||
}
|
||||
|
||||
static Actor RecallInstigator( Actor b )
|
||||
{
|
||||
if ( !b ) return null;
|
||||
let ti = ThinkerIterator.Create("SWWMWhoPushedMe",STAT_INFO);
|
||||
SWWMWhoPushedMe ffd;
|
||||
while ( ffd = SWWMWhoPushedMe(ti.Next()) )
|
||||
{
|
||||
if ( ffd.tracked != b ) continue;
|
||||
Actor whomst = ffd.instigator;
|
||||
ffd.Destroy();
|
||||
return whomst;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Class SWWMDamageAccumulator : Thinker
|
||||
{
|
||||
Actor victim, inflictor, source;
|
||||
Array<Int> amounts;
|
||||
int total;
|
||||
Name type;
|
||||
bool dontgib;
|
||||
int flags;
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
// so many damn safeguards in this
|
||||
if ( !victim || (victim.Health <= 0) )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
int gibhealth = victim.GetGibHealth();
|
||||
// お前はもう死んでいる
|
||||
if ( (victim.health-total <= gibhealth) && !dontgib )
|
||||
{
|
||||
// safeguard for inflictors that have somehow ceased to exist, which apparently STILL CAN HAPPEN
|
||||
if ( inflictor ) inflictor.bEXTREMEDEATH = true;
|
||||
else type = 'Extreme';
|
||||
}
|
||||
// make sure accumulation isn't reentrant
|
||||
if ( inflictor && (inflictor is 'EvisceratorChunk') ) inflictor.bAMBUSH = true;
|
||||
// 何?
|
||||
for ( int i=0; i<amounts.Size(); i++ )
|
||||
{
|
||||
if ( !victim ) break;
|
||||
victim.DamageMobj(inflictor,source,amounts[i],type,DMG_THRUSTLESS|flags);
|
||||
}
|
||||
// clean up
|
||||
if ( inflictor )
|
||||
{
|
||||
if ( inflictor is 'EvisceratorChunk' ) inflictor.bAMBUSH = false;
|
||||
inflictor.bEXTREMEDEATH = false;
|
||||
}
|
||||
Destroy();
|
||||
}
|
||||
|
||||
static void Accumulate( Actor victim, int amount, Actor inflictor, Actor source, Name type, bool dontgib = false, int flags = 0 )
|
||||
{
|
||||
if ( !victim ) return;
|
||||
let ti = ThinkerIterator.Create("SWWMDamageAccumulator",STAT_USER);
|
||||
SWWMDamageAccumulator a, match = null;
|
||||
while ( a = SWWMDamageAccumulator(ti.Next()) )
|
||||
{
|
||||
if ( a.victim != victim ) continue;
|
||||
match = a;
|
||||
break;
|
||||
}
|
||||
if ( !match )
|
||||
{
|
||||
match = new("SWWMDamageAccumulator");
|
||||
match.ChangeStatNum(STAT_USER);
|
||||
match.victim = victim;
|
||||
match.amounts.Clear();
|
||||
}
|
||||
match.amounts.Push(amount);
|
||||
match.total += amount;
|
||||
match.inflictor = inflictor;
|
||||
match.source = source;
|
||||
match.type = type;
|
||||
match.dontgib = dontgib;
|
||||
match.flags = flags;
|
||||
}
|
||||
|
||||
static clearscope int GetAmount( Actor victim )
|
||||
{
|
||||
let ti = ThinkerIterator.Create("SWWMDamageAccumulator",STAT_USER);
|
||||
SWWMDamageAccumulator a, match = null;
|
||||
while ( a = SWWMDamageAccumulator(ti.Next()) )
|
||||
{
|
||||
if ( a.victim != victim ) continue;
|
||||
if ( a.source && a.source.FindInventory("AngeryPower") )
|
||||
return (a.total>85899345)?int.max:(a.total*25);
|
||||
return a.total;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ensures a polyobj stays out of bounds FOREVER
|
||||
Class SWWMBustedPolyobj : swwm_PolyobjectEffector
|
||||
{
|
||||
|
|
@ -421,46 +298,3 @@ Class SWWMCorpseCleaner : Thinker
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Class SWWMFlyTracker : Thinker
|
||||
{
|
||||
Actor tracked, instigator;
|
||||
Vector3 startpos, curpos;
|
||||
double maxdist;
|
||||
int gracepd;
|
||||
|
||||
static void Track( Actor b, Actor whomst )
|
||||
{
|
||||
if ( !b || !whomst ) return;
|
||||
let ti = ThinkerIterator.Create("SWWMFlyTracker",STAT_USER);
|
||||
SWWMFlyTracker ffd;
|
||||
while ( ffd = SWWMFlyTracker(ti.Next()) )
|
||||
{
|
||||
if ( ffd.tracked != b ) continue;
|
||||
ffd.instigator = whomst;
|
||||
return;
|
||||
}
|
||||
ffd = new("SWWMFlyTracker");
|
||||
ffd.ChangeStatNum(STAT_USER);
|
||||
ffd.tracked = b;
|
||||
ffd.instigator = whomst;
|
||||
ffd.curpos = ffd.startpos = b.pos;
|
||||
ffd.maxdist = 0;
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
maxdist = max(maxdist,level.Vec3Diff(startpos,curpos).length());
|
||||
if ( !tracked || tracked.bFLOAT || tracked.bNOGRAVITY || (tracked.waterlevel > 1) || (tracked.pos.z <= tracked.floorz) || !tracked.TestMobjZ(false) )
|
||||
{
|
||||
gracepd++;
|
||||
if ( gracepd < 10 ) return;
|
||||
if ( instigator ) SWWMUtility.AchievementProgress("flight",int(maxdist),instigator.player);
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
gracepd = 0;
|
||||
curpos = tracked.pos;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -865,20 +865,23 @@ Class SWWMUtility
|
|||
}
|
||||
|
||||
// because GetTag() returns the localized string, we need to do things the hard way
|
||||
static play String GetFunTag( Actor a, String defstr = "" )
|
||||
static play String GetFunTag( SWWMHandler hnd, Actor a, String defstr = "" )
|
||||
{
|
||||
// look up any fun tag services
|
||||
let si = ServiceIterator.Find("FunTagService");
|
||||
Service sv;
|
||||
String res;
|
||||
while ( sv = si.Next() )
|
||||
// look up fun tag services if available
|
||||
if ( hnd.funtagsv )
|
||||
{
|
||||
res = sv.GetString("GetFunTag",objectArg:a);
|
||||
if ( res == "" ) continue;
|
||||
let si = ServiceIterator.Find("FunTagService");
|
||||
Service sv;
|
||||
String res;
|
||||
while ( sv = si.Next() )
|
||||
{
|
||||
res = sv.GetString("GetFunTag",objectArg:a);
|
||||
if ( res == "" ) continue;
|
||||
si.Destroy();
|
||||
return res;
|
||||
}
|
||||
si.Destroy();
|
||||
return res;
|
||||
}
|
||||
si.Destroy();
|
||||
int ntags = 1;
|
||||
String basetag = "";
|
||||
switch ( a.GetClassName() )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue