187 lines
5.5 KiB
Text
187 lines
5.5 KiB
Text
// Base class for all SWWM Armors
|
|
Class SWWMArmor : Armor abstract
|
|
{
|
|
meta int priority;
|
|
meta String drainmsg;
|
|
meta Class<SWWMSpareArmor> parent;
|
|
private int SArmorFlags;
|
|
|
|
Property ArmorPriority : priority;
|
|
Property DrainMessage : drainmsg;
|
|
Property GiverArmor : parent;
|
|
|
|
FlagDef NoHitFlash : SArmorFlags, 0; // doesn't flash when taking damage
|
|
FlagDef NoHitSound : SArmorFlags, 1; // doesn't play a sound when taking damage
|
|
FlagDef NoDrain : SArmorFlags, 2; // amount is not drained, will always reduce as long as amount is non-zero
|
|
// useful for powerup-given armors
|
|
|
|
transient int lastautousetic; // accumulated damage can make the use sounds stack
|
|
transient int lasthittic; // same here
|
|
|
|
Default
|
|
{
|
|
+INVENTORY.AUTOACTIVATE;
|
|
+INVENTORY.UNTOSSABLE;
|
|
+INVENTORY.UNDROPPABLE;
|
|
+INVENTORY.KEEPDEPLETED;
|
|
+INVENTORY.ALWAYSPICKUP;
|
|
}
|
|
override void AttachToOwner( Actor other )
|
|
{
|
|
Super.AttachToOwner(other);
|
|
// find last armor that's better than us
|
|
Inventory found = null;
|
|
for ( Inventory i=other.Inv; i; i=i.Inv )
|
|
{
|
|
if ( !(i is 'SWWMArmor') || (i == self) || (SWWMArmor(i).priority < priority) ) continue;
|
|
found = i;
|
|
}
|
|
if ( !found )
|
|
{
|
|
// find first item with an armor worse than us after it
|
|
for ( Inventory i=other.Inv; i; i=i.Inv )
|
|
{
|
|
if ( (i == self) || !(i.Inv is 'SWWMArmor') ) continue;
|
|
if ( SWWMArmor(i.Inv).priority > priority ) continue;
|
|
found = i;
|
|
break;
|
|
}
|
|
}
|
|
if ( !found )
|
|
{
|
|
// check if first item in inventory is health or a sandwich
|
|
if ( (other.Inv is 'SWWMHealth') || (other.Inv is 'GrilledCheeseSandwich') )
|
|
{
|
|
// we're good
|
|
return;
|
|
}
|
|
// find first item with health or sandwich after it
|
|
for ( Inventory i=other.Inv; i; i=i.Inv )
|
|
{
|
|
if ( (i == self) || (!(i.Inv is 'SWWMHealth' ) && !(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;
|
|
}
|
|
// for subclasses
|
|
virtual int HandleDamage( int damage, Name damageType, int flags )
|
|
{
|
|
return damage;
|
|
}
|
|
override void AbsorbDamage( int damage, Name damageType, out int newdamage, Actor inflictor, Actor source, int flags )
|
|
{
|
|
int saved;
|
|
if ( (amount <= 0) || DamageTypeDefinition.IgnoreArmor(damageType) || (damage <= 0) )
|
|
return;
|
|
if ( !bNOHITFLASH ) SWWMHandler.DoFlash(Owner,Color(int(clamp(damage*.15,1,16)),255,224,192),3);
|
|
if ( !bNOHITSOUND && (lasthittic < gametic) )
|
|
{
|
|
Owner.A_StartSound("armor/hit",CHAN_DAMAGE,CHANF_OVERLAP,clamp(damage*.03,0.,1.),2.5);
|
|
lasthittic = gametic;
|
|
}
|
|
saved = HandleDamage(damage,damageType,flags);
|
|
int healed = max(0,saved-damage);
|
|
saved = min(saved,damage);
|
|
if ( !bNODRAIN && (amount <= saved) ) saved = amount;
|
|
newdamage -= saved;
|
|
if ( healed > 0 ) Owner.GiveBody(healed);
|
|
if ( (swwm_strictuntouchable == 1) && (saved > 0) && Owner.player )
|
|
{
|
|
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
|
if ( hnd ) hnd.tookdamage[Owner.PlayerNumber()] = true;
|
|
}
|
|
if ( !bNODRAIN ) amount -= saved;
|
|
damage = newdamage;
|
|
if ( (amount <= (MaxAmount-default.Amount)) && (Owner.CountInv(parent) > 0) )
|
|
{
|
|
if ( GetDefaultByType(parent).UseSound && (lastautousetic < gametic) )
|
|
{
|
|
Owner.A_StartSound(GetDefaultByType(parent).UseSound,CHAN_ITEMEXTRA,CHANF_OVERLAP,.6);
|
|
lastautousetic = gametic;
|
|
}
|
|
int tgive = 0;
|
|
while ( (amount <= (MaxAmount-default.Amount)) && (Owner.CountInv(parent) > 0) )
|
|
{
|
|
Amount += default.Amount;
|
|
Owner.TakeInventory(parent,1);
|
|
// absorb the extra damage too
|
|
saved = HandleDamage(damage,damageType,flags);
|
|
healed = max(0,saved-damage);
|
|
saved = min(saved,damage);
|
|
if ( amount <= saved ) saved = amount;
|
|
newdamage -= saved;
|
|
if ( healed > 0 ) Owner.GiveBody(healed);
|
|
amount -= saved;
|
|
damage = newdamage;
|
|
}
|
|
}
|
|
else if ( amount <= 0 )
|
|
{
|
|
if ( Owner.CheckLocalView() && (drainmsg != "") ) Console.Printf(StringTable.Localize(drainmsg));
|
|
DepleteOrDestroy();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// gives armor when used
|
|
Class SWWMSpareArmor : Inventory abstract
|
|
{
|
|
Mixin SWWMAutoUseFix;
|
|
Mixin SWWMUseToPickup;
|
|
Mixin SWWMOverlapPickupSound;
|
|
Mixin SWWMRespawn;
|
|
Mixin SWWMRotatingPickup;
|
|
Mixin SWWMPickupGlow;
|
|
|
|
meta Class<SWWMArmor> giveme;
|
|
|
|
Property GiveArmor : giveme;
|
|
|
|
override bool Use( bool pickup )
|
|
{
|
|
let cur = Owner.FindInventory(giveme);
|
|
if ( !cur || (!pickup && (cur.Amount < cur.MaxAmount)) || (GetDefaultByType(giveme).Amount+cur.Amount <= cur.MaxAmount) || ((default.MaxAmount <= 0) && (cur.Amount < cur.MaxAmount)) )
|
|
{
|
|
if ( pickup && ((Owner.player == players[consoleplayer]) || bBigPowerup) )
|
|
{
|
|
bool bPlayMe = true;
|
|
if ( self is 'ArmorNuggetItem' )
|
|
{
|
|
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);
|
|
}
|
|
Owner.GiveInventory(giveme,GetDefaultByType(giveme).Amount);
|
|
SWWMHandler.ArmorFlash(Owner.PlayerNumber());
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Default
|
|
{
|
|
+INVENTORY.INVBAR;
|
|
+INVENTORY.ISARMOR;
|
|
+INVENTORY.AUTOACTIVATE;
|
|
Inventory.MaxAmount 5;
|
|
Inventory.InterHubAmount 5;
|
|
Inventory.PickupFlash "SWWMGreenPickupFlash";
|
|
+FLOATBOB;
|
|
+DONTGIB;
|
|
FloatBobStrength 0.25;
|
|
}
|
|
}
|