swwmgz_m/zscript/items/swwm_basehealth.zsc
Marisa the Magician 80db58b0d0 Bump zscript ver to 4.14.1, plus a whole lot of stuff.
- Try to get rid of all implicit casts from string to name, color or class.
 - Use FindClass where needed.
 - Used a map in a case where a dictionary was unneeded.
 - Use new bounce flags where needed.
 - Replace Legacy of Rust weapons/ammo.
2025-03-13 14:50:58 +01:00

172 lines
5.4 KiB
Text

// Base class for all SWWM Health
Class SWWMHealth : Inventory abstract
{
Mixin SWWMAutoUseFix;
Mixin SWWMUseToPickup;
Mixin SWWMOverlapPickupSound;
Mixin SWWMRespawn;
Mixin SWWMRotatingPickup;
Mixin SWWMPickupGlow;
Mixin SWWMUnrealStyleDrop;
// can't use the Health class for whatever reason
// nice parser you got there I guess?
meta Class<Inventory> giveme;
Property GiveHealth : giveme;
transient int lastautousetic; // accumulated damage can make the use sounds stack
override void AttachToOwner( Actor other )
{
Super.AttachToOwner(other);
// find last health item that's better than us
Inventory found = null;
for ( Inventory i=other.Inv; i; i=i.Inv )
{
if ( !(i is 'SWWMHealth') || (i == self) || (GetDefaultByType(SWWMHealth(i).giveme).Amount < GetDefaultByType(giveme).Amount) ) continue;
found = i;
}
if ( !found )
{
// find first item with health that's worse than us after it
for ( Inventory i=other.Inv; i; i=i.Inv )
{
if ( (i == self) || !(i.Inv is 'SWWMHealth') ) continue;
if ( GetDefaultByType(SWWMHealth(i.Inv).giveme).Amount > GetDefaultByType(giveme).Amount ) continue;
found = i;
break;
}
}
if ( !found )
{
// find last armor item, plating or collar
for ( Inventory i=other.Inv; i; i=i.Inv )
{
if ( !(i is 'SWWMArmor') ) continue;
found = i;
}
}
if ( !found )
{
// check if the first item in inventory is a sandwich
if ( other.Inv is 'GrilledCheeseSandwich' )
{
// we're good
return;
}
// find first item next to a sandwich
for ( Inventory i=other.Inv; i; i=i.Inv )
{
if ( (i == self) || !(i.Inv is 'GrilledCheeseSandwich') ) continue;
found = i;
break;
}
}
if ( !found ) return;
// place ourselves right after it
Inventory saved = found.Inv;
found.Inv = self;
other.Inv = Inv;
Inv = saved;
}
override bool Use( bool pickup )
{
if ( Owner.Health >= GetDefaultByType(giveme).MaxAmount ) return false;
// healing items won't get auto-used on pickup if their healing could "be wasted", unless they're powerup health (e.g. Refresher) or bonus health
if ( pickup && !bBIGPOWERUP && (default.MaxAmount > 0) && (Owner.Health+GetDefaultByType(giveme).Amount > GetDefaultByType(giveme).MaxAmount) ) return false;
if ( pickup && ((Owner.player == players[consoleplayer]) || bBigPowerup) )
{
bool bPlayMe = true;
if ( self is 'HealthNuggetItem' )
{
let hnd = SWWMHandler(EventHandler.Find('SWWMHandler'));
if ( hnd )
{
if ( hnd.lastnuggettic[Owner.PlayerNumber()] == gametic )
bPlayMe = false; // don't play if picked up on the same exact tic (overlapping items)
hnd.lastnuggettic[Owner.PlayerNumber()] = gametic;
}
}
if ( bPlayMe ) Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA,CHANF_OVERLAP);
}
SWWMHandler.HealthFlash(Owner.PlayerNumber());
Owner.GiveInventory(giveme,GetDefaultByType(giveme).Amount);
if ( Owner.player == players[consoleplayer] )
SWWMScoreObj.SpawnAtActorBunch(GetDefaultByType(giveme).Amount,Owner,Font.CR_BLUE);
AutoUseExtra(false);
return true;
}
// additional effects when automatically used
// recursive: if true, the auto-use was called on another copy of the
// item in a "stacked" heal. can be used to prevent certain
// effects from happening multiple times in one go
virtual void AutoUseExtra( bool recursive )
{
}
override void DoEffect()
{
Super.DoEffect();
if ( Amount <= 0 ) DepleteOrDestroy();
}
override void AbsorbDamage( int damage, Name damageType, int &newdamage, Actor inflictor, Actor source, int flags )
{
if ( Owner.ApplyDamageFactor(damageType,damage) <= 0 )
return; // this damage type is ignored by the player, so it does not affect us
if ( damageType == 'EndLevel' )
return; // don't trigger on endlevel damage
if ( (Owner.Health-damage <= (GetDefaultByType(giveme).MaxAmount-GetDefaultByType(giveme).Amount)) )
{
newdamage = damage;
// lesser healing items can't prevent lethal damage
// bigger healing items only autoactivate on lethal damage
if ( !bBIGPOWERUP && (Owner.Health-damage <= 0) )
return;
else if ( bBIGPOWERUP && (Owner.Health-damage > 0) )
return;
if ( (swwm_strictuntouchable == 1) && Owner.player )
{
let hnd = SWWMHandler(EventHandler.Find('SWWMHandler'));
if ( hnd ) hnd.tookdamage[Owner.PlayerNumber()] = true;
}
if ( ((Owner.player == players[consoleplayer]) || bBigPowerup) && (lastautousetic < gametic) )
{
Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA,CHANF_OVERLAP);
lastautousetic = gametic;
}
int tgive = 0;
bool morethanonce = false;
while ( (Amount > 0) && (newdamage > 0) )
{
newdamage = newdamage-GetDefaultByType(giveme).Amount;
if ( Owner.player == players[consoleplayer] )
SWWMScoreObj.SpawnAtActorBunch(GetDefaultByType(giveme).Amount,Owner,Font.CR_BLUE);
if ( newdamage < 0 ) Owner.GiveBody(-newdamage,GetDefaultByType(giveme).MaxAmount);
newdamage = max(0,newdamage);
if ( !morethanonce ) SWWMHandler.HealthFlash(Owner.PlayerNumber());
AutoUseExtra(morethanonce);
morethanonce = true;
Amount--;
}
}
else newdamage = damage;
}
Default
{
+INVENTORY.INVBAR;
+INVENTORY.ISHEALTH;
+INVENTORY.AUTOACTIVATE;
+DONTGIB;
Inventory.MaxAmount 5;
Inventory.InterHubAmount 5;
Inventory.UseSound "misc/health_pkup";
Inventory.PickupFlash 'SWWMBluePickupFlash';
+FLOATBOB;
FloatBobStrength 0.25;
}
}