Classes:HexenArmor

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.
Hexen armor
Actor type Internal Game MiniHexenLogoIcon.png (Hexen)
DoomEd Number None Class Name HexenArmor


Classes: InventoryArmorHexenArmor
 →AmuletOfWarding
 →FalconShield
 →MeshArmor
 →PlatinumHelm

HexenArmor is a variation of the BasicArmor class used specifically in Hexen. Much like BasicArmor, this class is present in the player's inventory from the start of the game (even if they're not playing Hexen), and various armor pickups that the player receives interact with it and modify its values.

Mechanics

Hexen armor works differently from armor in other games:

  • Hexen armor pickups are based on the HexenArmor class directly (in contrast to armor pickups in other games, which are based on special classes like BasicArmorPickup and BasicArmorBonus).
  • Hexen armor consits of 5 "pieces" that can be "worn" at the same time. 4 of them correspond to armor pickups, while the 5th is the player's "natural armor" that they always have.
  • Hexen armor pickups don't define amount, saveamount or savepercent values. The only meaningful value in them is health, which determines the "armor class" of the pickup, from 0 (the strongest) to 3 (the weakest).
  • The amount of armor provided by HexenArmor pickups is not (and can not) be defined in the pickup itself, it's defined in the player class.

The protection offered by HexenArmor pickups depends on the PlayerClass definition, through the following line:

Player.HexenArmor base value, armor value, shield value, helm value, amulet value

The values given here must be multiple of five, as they are divided by five on the HUD.

The armor values are stored in the array called Slots defined in the HexenArmor class. The array has a fixed size of 5. Whenever a Hexen armor pickup is received, it modifies the value of the element in that array that corresponds to its "class" (which is determined by the value of health of the pickup). The classes correspond to the array elements as follows:

Because of the way Hexen Armor works, it is not possible to create meaningful new armor items, although it is possible to create classes gaining different numerical benefits from them. It may be possible to create new items that, like the Dragonskin Bracers, enhance the character's armor class through a different method. The bracers give a 20% (+4) armor class bonus to all classes, up to the class's maximum (which is equal to a fully-armored character using the bracers once). For reference, here is a table showing the different AC values for the different Hexen player classes:

Hexen Armor Classes: Total (Displayed)
Class Name Unarmored Mesh Armor Falcon Shield Platinum Helm Amulet Of Warding Fully Armored Maximum Total
Baratus the Fighter 15 (3) 25 (5) 20 (4) 15 (3) 5 (1) 80 (16) 100 (20)
Parias the Cleric 10 (2) 10 (2) 25 (5) 5 (1) 20 (4) 70 (14) 90 (18)
Daedolon the Mage 5 (1) 5 (1) 15 (3) 10 (2) 25 (5) 60 (12) 80 (16)

It is also important to note that Hexen armor items don't define a Inventory.icon and they don't modify the icon field on the base HexenArmor class when they're picked up. As such, it's not possible to meaningfully determine what kind of icon to display if you want to draw the armor icon(s) in a custom HUD, aside from iterating through all existing HexenArmor items and lifting their spawnstate sprite with GetSpriteTexture().

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 HexenArmor : Armor
{
	
	double Slots[5];
	double SlotsIncrement[4];
	
	Default
	{
		+Inventory.KEEPDEPLETED
		+Inventory.UNTOSSABLE
	}
	
	//===========================================================================
	//
	// AHexenArmor :: CreateCopy
	//
	//===========================================================================

	override Inventory CreateCopy (Actor other)
	{
		// Like BasicArmor, HexenArmor is used in the inventory but not the map.
		// health is the slot this armor occupies.
		// Amount is the quantity to give (0 = normal max).
		let copy = HexenArmor(Spawn("HexenArmor"));
		copy.AddArmorToSlot (health, Amount);
		GoAwayAndDie ();
		return copy;
	}

	//===========================================================================
	//
	// AHexenArmor :: CreateTossable
	//
	// Since this isn't really a single item, you can't drop it. Ever.
	//
	//===========================================================================

	override Inventory CreateTossable (int amount)
	{
		return NULL;
	}

	//===========================================================================
	//
	// AHexenArmor :: HandlePickup
	//
	//===========================================================================

	override bool HandlePickup (Inventory item)
	{
		if (item is "HexenArmor")
		{
			if (AddArmorToSlot (item.health, item.Amount))
			{
				item.bPickupGood = true;
			}
			return true;
		}
		return false;
	}

	//===========================================================================
	//
	// AHexenArmor :: AddArmorToSlot
	//
	//===========================================================================

	protected bool AddArmorToSlot (int slot, int amount)
	{
		double hits;

		if (slot < 0 || slot > 3)
		{
			return false;
		}
		if (amount <= 0)
		{
			hits = SlotsIncrement[slot];
			if (Slots[slot] < hits)
			{
				Slots[slot] = hits;
				return true;
			}
		}
		else
		{
			hits = amount * 5;
			let total = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4];
			let max = SlotsIncrement[0] + SlotsIncrement[1] + SlotsIncrement[2] + SlotsIncrement[3] + Slots[4] + 4 * 5;
			if (total < max)
			{
				Slots[slot] += hits;
				return true;
			}
		}
		return false;
	}

	//===========================================================================
	//
	// AHexenArmor :: AbsorbDamage
	//
	//===========================================================================

	override void AbsorbDamage (int damage, Name damageType, out int newdamage, Actor inflictor, Actor source, int flags)
	{
		if (!DamageTypeDefinition.IgnoreArmor(damageType))
		{
			double savedPercent = Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4];

			if (savedPercent)
			{ // armor absorbed some damage
				if (savedPercent > 100)
				{
					savedPercent = 100;
				}
				for (int i = 0; i < 4; i++)
				{
					if (Slots[i])
					{
						// 300 damage always wipes out the armor unless some was added
						// with the dragon skin bracers.
						if (damage < 10000)
						{
							Slots[i] -= damage * SlotsIncrement[i] / 300.;
							if (Slots[i] < 2)
							{
								Slots[i] = 0;
							}
						}
						else
						{
							Slots[i] = 0;
						}
					}
				}
				int saved = int(damage * savedPercent / 100.);
				if (saved > savedPercent*2)
				{	
					saved = int(savedPercent*2);
				}
				newdamage -= saved;
				damage = newdamage;
			}
		}
	}

	//===========================================================================
	//
	// AHexenArmor :: DepleteOrDestroy
	//
	//===========================================================================

	override void DepleteOrDestroy()
	{
		for (int i = 0; i < 4; i++)
		{
			Slots[i] = 0;
		}
	}	
}

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 HexenArmor : Armor native
{
  +INVENTORY.KEEPDEPLETED
  +INVENTORY.UNDROPPABLE
}

Related Classes

ArtiBoostArmor, called in-game the Dragonskin Bracers, enhances a character's Hexen Armor class.