Classes:BasicArmorPickup

From ZDoom Wiki
Jump to navigation Jump to search
Note: Wait! Stop! Before you copy this actor's definition into your mod, remember the following things:
  1. You do NOT need to copy that actor, since it is already defined.
  2. In fact, it's not just useless, it will cause problems.
  3. If you want to modify it, or use a modified version, using inheritance is the way to go.
  4. The actor definitions here are put on the wiki for reference purpose only. Learn from them, don't copy them.
Basic armor pickup
Actor type Internal Game MiniZDoomLogoIcon.png (ZDoom)
DoomEd Number None Class Name BasicArmorPickup


Classes: InventoryArmorBasicArmorPickup
 →BlueArmor
 →EnchantedShield
 →GreenArmor
 →LeatherArmor
 →MetalArmor
 →SilverShield


BasicArmorPickups are armor items that replace any existing armor with themselves if the player's armor points are less than this item provides. The base class BasicArmorPickup is never used directly. It is always the base class for predefined items (like Doom's {[class|GreenArmor}}) or for items defined in ZScript/DECORATE. BasicArmorPickup items can be placed in the inventory. If that is done they will activate automatically when the previous armor has worn off.

BasicArmorPickup sets the Inventory.AUTOACTIVATE flag by default. However, if you want to define an item that doesn't automatically activate you can clear this flag again.

Using in ZScript and DECORATE

BasicArmorPickups use the basic Inventory properties to define their behavior as inventory items. They also define a few new properties to define their behavior as armor.

  • Armor.SaveAmount amount
The amount of armor that this item gives.
  • Armor.SavePercent percentage
The percentage of damage that the armor absorbs.
Percentage is specified as a floating point value between 0.0 and 100.0 which is converted internally to a floating point value between 0.0 and 1.0
  • Armor.MaxFullAbsorb amount
The amount of damage that this armor will fully absorb per tic.
  • Armor.MaxAbsorb amount
The maximum amount of damage (after adjustment) that this armor will absorb per tic.

In addition, the DamageFactor property can be used to make protective armors (or potentially, cursed armors). The armor first absorbs damage normally, as determined by its SavePercent, MaxAbsorb and MaxFullAbsorb properties, and the damage factor is applied to the remaining damage. In doing so, the damage factor does not protect the armor itself, but only the wearer.

Examples

This armor will absorb the first 50 damage dealt at 100%, and will absorb 75% of the remaining damage done:

class RedArmor : BasicArmorPickup
{
  Default
  {
    Inventory.PickupMessage "Picked up the HyperArmor!"; // This is an example. It's recommended to use LANGUAGE for player-facing strings.
    Inventory.Icon "ARM5A0";
    Armor.SaveAmount 300;
    Armor.SavePercent 75;
    Armor.MaxFullAbsorb 50;
  }
  States
  {
  Spawn:
    ARM5 A 6;
    ARM5 B 7 bright;
    loop;
  }
}

For example, if the player wearing this had 300% armor and 100% health, and was hit with an attack totalling 70 damage, the armor would take the first 50, leaving 20 left. Of that 20, the armor would take an additional 15 damage, and the player would take only 5 damage. After the attack, he would have 235% armor and 95% health left.

This armor will absorb at a 50% rate, but will only absorb up to 25 damage per tic:

class WeakArmor : BasicArmorPickup
{
  Default
  {
    Inventory.PickupMessage "Picked up some mediocre armor."; // This is an example. It's recommended to use LANGUAGE for player-facing strings.
    Inventory.Icon "ARM7A0";
    Armor.SaveAmount 75;
    Armor.SavePercent 50;
    Armor.MaxAbsorb 25;
  }
  states
  {
  Spawn:
    ARM7 A 6
    ARM7 B 7 bright
    loop
  }
}

For example, if the player wearing this had 75% armor and 100% health, and was hit with an attack totalling 70 damage, the armor would absorb 25 and the player would take the remaining 45 damage. After such an attack he would have 50% armor and 55% health.

If, however, he were to take only 30 damage, the armor would absorb 50% of it (15) and the health would take the other 15; even though the armor didn't reach its maxabsorb value, the savepercent is only 50.

class PyroArmor : BasicArmorPickup
{
  Default
  {
    Inventory.PickupMessage "Picked up a fire-resistant armor."; // This is an example. It's recommended to use LANGUAGE for player-facing strings.
    Inventory.Icon "ARM9A0";
    DamageFactor 'Fire', 0.0;
    Armor.SaveAmount 150;
    Armor.SavePercent 75;
  }
}

For example, if the player wearing wearing this had 150% armor and 100% health, and was hit by an attack inflicting 80 fire damage, the armor would absorb 75% of the damage normally (so 60 points), and since the remaining 20 points of damage are of the "fire" type against which it protects completely, the player would lose no health. After the attack, he would therefore have 90% armor and 100% health. A second identical attack would leave him with armor 30% and health 100%; and after a third attack the armor would be entirely depleted absorbing the first 30 points of damage and would no longer protect him against the 50 remaining points of the attack, he would thus be left with armor 0% and health 50%.

ZScript definition

Note: The ZScript definition below is for reference and may be different in the current version of GZDoom.The most up-to-date version of this code can be found on GZDoom GitHub.
class BasicArmorPickup : Armor
{

	double SavePercent;
	int MaxAbsorb;
	int MaxFullAbsorb;
	int SaveAmount;

	property prefix: Armor;
	property SaveAmount : SaveAmount;
	property SavePercent: SavePercent;
	property MaxAbsorb: MaxAbsorb;
	property MaxFullAbsorb: MaxFullAbsorb;

	Default
	{
		+Inventory.AUTOACTIVATE;
		Inventory.MaxAmount 0;
	}
	
	//===========================================================================
	//
	// ABasicArmorPickup :: CreateCopy
	//
	//===========================================================================

	override Inventory CreateCopy (Actor other)
	{
		let copy = BasicArmorPickup(Super.CreateCopy (other));
		copy.SavePercent = SavePercent;
		copy.SaveAmount = SaveAmount;
		copy.MaxAbsorb = MaxAbsorb;
		copy.MaxFullAbsorb = MaxFullAbsorb;

		return copy;
	}
	
	//===========================================================================
	//
	// ABasicArmorPickup :: Use
	//
	// Either gives you new armor or replaces the armor you already have (if
	// the SaveAmount is greater than the amount of armor you own). When the
	// item is auto-activated, it will only be activated if its max amount is 0
	// or if you have no armor active already.
	//
	//===========================================================================

	override bool Use (bool pickup)
	{
		int SaveAmount = GetSaveAmount();
		let armor = BasicArmor(Owner.FindInventory("BasicArmor"));

		// This should really never happen but let's be prepared for a broken inventory.
		if (armor == null)
		{
			armor = BasicArmor(Spawn("BasicArmor"));
			armor.BecomeItem ();
			Owner.AddInventory (armor);
		}
		else
		{
			// If you already have more armor than this item gives you, you can't
			// use it.
			if (armor.Amount >= SaveAmount + armor.BonusCount)
			{
				return false;
			}
			// Don't use it if you're picking it up and already have some.
			if (pickup && armor.Amount > 0 && MaxAmount > 0)
			{
				return false;
			}
		}
		
		armor.SavePercent = clamp(SavePercent, 0, 100) / 100;
		armor.Amount = SaveAmount + armor.BonusCount;
		armor.MaxAmount = SaveAmount;
		armor.Icon = Icon;
		armor.MaxAbsorb = MaxAbsorb;
		armor.MaxFullAbsorb = MaxFullAbsorb;
		armor.ArmorType = GetClassName();
		armor.ActualSaveAmount = SaveAmount;
		return true;
	}
	
	override void SetGiveAmount(Actor receiver, int amount, bool bycheat)
	{
		SaveAmount *= amount;
	}
	
	int GetSaveAmount ()
	{
		return !bIgnoreSkill ? int(SaveAmount * G_SkillPropertyFloat(SKILLP_ArmorFactor)) : SaveAmount;
	}
}

DECORATE definition

Note: This is legacy code, kept for archival purposes only. DECORATE is deprecated in GZDoom and is completely superseded by ZScript. GZDoom internally uses the ZScript definition above.
ACTOR BasicArmorPickup : Armor native
{
  +INVENTORY.AUTOACTIVATE
  Inventory.MaxAmount 0
}