swwmgz_m/zscript/swwm_common.zsc
Marisa the Magician 6825146e51 A whole fat load of micro-optimizations.
Okuplok still lags like fuck, unfortunately.
2022-06-17 22:36:51 +02:00

266 lines
6.6 KiB
Text

// common code goes here
// extra sound channels for the mod
enum ESWWMGZChannels
{
CHAN_YOUDONEFUCKEDUP = 63200, // exception handler
CHAN_DEMOVOICE = 63201, // demolitionist voices
CHAN_FOOTSTEP = 63202, // footstep sounds and others
CHAN_WEAPONEXTRA = 63203, // additional weapon sounds (usually loops)
CHAN_POWERUP = 63204, // powerup sounds
CHAN_POWERUPEXTRA = 63205, // additional powerup sounds
CHAN_JETPACK = 63206, // jetpack sound
CHAN_ITEMEXTRA = 63207, // additional item sounds
CHAN_WEAPONEXTRA2 = 63208, // additional weapon sound slot
CHAN_WEAPONEXTRA3 = 63209, // additional weapon sound slot (again)
CHAN_DAMAGE = 63210, // used for impact/hit sounds
CHAN_AMBEXTRA = 63211, // player ambience when submerged
CHAN_DEMOVOICEAUX = 63212, // extra channel to make oneliner voices louder
CHAN_DEMOVOICEAUX2 = 63213, // how many more channels do I need???
CHAN_DEMOVOICEAUX3 = 63214, // oh god, the loudening
CHAN_FUELREGEN = 63215 // sound of fuel regenerating
};
const FallbackTag = "AWESOME IT'S PENIS"; // used on tag processing, please don't mind the actual string used)
const MaxBouncePerTic = 40; // maximum simultaneous bounces in one tic for a lightweight actor before we consider it's stuck
// basic "does nothing" actor, used to remove stuff in CheckReplacement
Class SWWMNothing : Actor
{
States
{
Spawn:
TNT1 A 1;
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;
}
}
// fractic-compatible interpolators, with double value
Class SmoothLinearValueInterpolator
{
private double val, oldval, diff;
static SmoothLinearValueInterpolator Create( double val, double diff )
{
let v = new("SmoothLinearValueInterpolator");
v.oldval = v.val = val;
v.diff = diff;
return v;
}
void Reset( double newval )
{
oldval = val = newval;
}
void Update( double newval )
{
oldval = val;
if ( abs(newval-val) < diff ) val = newval;
else if ( val > newval ) val = max(newval,val-diff);
else val = min(newval,val+diff);
}
double GetValue( double fractic = 1. )
{
return SWWMUtility.Lerp(oldval,val,fractic);
}
}
Class SmoothDynamicValueInterpolator
{
private double val, oldval, factor, mindiff, maxdiff;
static SmoothDynamicValueInterpolator Create( double val, double factor, double mindiff, double maxdiff )
{
let v = new("SmoothDynamicValueInterpolator");
v.oldval = v.val = val;
v.factor = factor;
v.mindiff = mindiff;
v.maxdiff = maxdiff;
return v;
}
void Reset( double newval )
{
oldval = val = newval;
}
void Update( double newval )
{
oldval = val;
if ( abs(newval-val) < mindiff ) val = newval;
else
{
double diff = min(abs(newval-val)*factor,maxdiff);
if ( val > newval ) val = max(newval,val-diff);
else val = min(newval,val+diff);
}
}
double GetValue( double fractic = 1. )
{
return SWWMUtility.Lerp(oldval,val,fractic);
}
}