From b6f631f6e98804306543b625577a8fcd6effefca Mon Sep 17 00:00:00 2001 From: Marisa the Magician Date: Fri, 17 Jun 2022 22:36:51 +0200 Subject: [PATCH] A whole fat load of micro-optimizations. Okuplok still lags like fuck, unfortunately. --- language.version | 4 +- zscript/handler/swwm_handler_cheats.zsc | 2 +- zscript/handler/swwm_handler_damage.zsc | 73 ++++---- zscript/handler/swwm_handler_playerevents.zsc | 4 +- zscript/handler/swwm_handler_process.zsc | 2 +- zscript/handler/swwm_handler_worldload.zsc | 2 +- zscript/handler/swwm_handler_worldthings.zsc | 33 ++-- zscript/handler/swwm_handler_worldtick.zsc | 27 +-- zscript/hud/swwm_hudobjects.zsc | 34 ++-- zscript/items/swwm_powerups.zsc | 48 +++-- zscript/swwm_common.zsc | 168 ++++++++++++++++++ zscript/swwm_common_fx.zsc | 63 ++++++- zscript/swwm_handler.zsc | 4 + zscript/swwm_thinkers.zsc | 166 ----------------- zscript/utility/swwm_utility.zsc | 23 +-- 15 files changed, 371 insertions(+), 282 deletions(-) diff --git a/language.version b/language.version index 51806c890..ac23f54ec 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.2.26 r5 \cu(Fri 17 Jun 23:04:16 CEST 2022)\c-"; -SWWM_SHORTVER="\cw1.2.26 r5 \cu(2022-06-17 23:04:16)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.2.27 \cu(Fri 17 Jun 23:28:04 CEST 2022)\c-"; +SWWM_SHORTVER="\cw1.2.27 \cu(2022-06-17 23:28:04)\c-"; diff --git a/zscript/handler/swwm_handler_cheats.zsc b/zscript/handler/swwm_handler_cheats.zsc index cf6501fe1..b52e179f0 100644 --- a/zscript/handler/swwm_handler_cheats.zsc +++ b/zscript/handler/swwm_handler_cheats.zsc @@ -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" ) { diff --git a/zscript/handler/swwm_handler_damage.zsc b/zscript/handler/swwm_handler_damage.zsc index 9f4295e91..267b3d4a3 100644 --- a/zscript/handler/swwm_handler_damage.zsc +++ b/zscript/handler/swwm_handler_damage.zsc @@ -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); } } diff --git a/zscript/handler/swwm_handler_playerevents.zsc b/zscript/handler/swwm_handler_playerevents.zsc index 9d658beae..592c71058 100644 --- a/zscript/handler/swwm_handler_playerevents.zsc +++ b/zscript/handler/swwm_handler_playerevents.zsc @@ -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); } } diff --git a/zscript/handler/swwm_handler_process.zsc b/zscript/handler/swwm_handler_process.zsc index 01da67453..121e745ee 100644 --- a/zscript/handler/swwm_handler_process.zsc +++ b/zscript/handler/swwm_handler_process.zsc @@ -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); diff --git a/zscript/handler/swwm_handler_worldload.zsc b/zscript/handler/swwm_handler_worldload.zsc index 61e32e681..20f91043d 100644 --- a/zscript/handler/swwm_handler_worldload.zsc +++ b/zscript/handler/swwm_handler_worldload.zsc @@ -364,7 +364,7 @@ extend Class SWWMHandler for ( int i=0; i 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 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 ) { diff --git a/zscript/items/swwm_powerups.zsc b/zscript/items/swwm_powerups.zsc index 79142f62a..c52f5c57a 100644 --- a/zscript/items/swwm_powerups.zsc +++ b/zscript/items/swwm_powerups.zsc @@ -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 { diff --git a/zscript/swwm_common.zsc b/zscript/swwm_common.zsc index 13064b4c3..88922480e 100644 --- a/zscript/swwm_common.zsc +++ b/zscript/swwm_common.zsc @@ -34,3 +34,171 @@ Class SWWMNothing : Actor Stop; } } + +Class SWWMDamageAccumulator : Inventory +{ + Actor inflictor, source; + Array 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; i85899345)?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; + } +} diff --git a/zscript/swwm_common_fx.zsc b/zscript/swwm_common_fx.zsc index 156c750a6..1c82ba68b 100644 --- a/zscript/swwm_common_fx.zsc +++ b/zscript/swwm_common_fx.zsc @@ -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: diff --git a/zscript/swwm_handler.zsc b/zscript/swwm_handler.zsc index 0f7c580e4..ee06f0c68 100644 --- a/zscript/swwm_handler.zsc +++ b/zscript/swwm_handler.zsc @@ -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; diff --git a/zscript/swwm_thinkers.zsc b/zscript/swwm_thinkers.zsc index e044cdf6d..ec808d785 100644 --- a/zscript/swwm_thinkers.zsc +++ b/zscript/swwm_thinkers.zsc @@ -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 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; i85899345)?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; - } - -} diff --git a/zscript/utility/swwm_utility.zsc b/zscript/utility/swwm_utility.zsc index 920f6d75e..11bcff58b 100644 --- a/zscript/utility/swwm_utility.zsc +++ b/zscript/utility/swwm_utility.zsc @@ -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() )