Classes:CustomInventory

From ZDoom Wiki
(Redirected from CustomInventory)
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's actually harmful as it can 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.
  5. There is only one exception: if what you want is changing Ammo capacity, you need to create a new type from Ammo.
Custom inventory
Actor type Internal Game MiniZDoomLogoIcon.png (ZDoom)
DoomEd Number None Class Name CustomInventory


Classes: InventoryStateProviderCustomInventory
 →ArtiBoostMana
 →ArtiEgg
 →ArtiPork
 →Berserk
 →Mana3
 →Megasphere

CustomInventory items are special items that allow some very primitive scripted functionality using its states. The base class CustomInventory is never used directly. It is always the base class for items defined in DECORATE.

Note: This class is unnecessary in ZScript outside of very specific use cases, like drawing Psprite layers outside of a weapon. Custom inventory items in ZScript should instead inherit from Inventory or one of its other subclasses, and override its virtual functions. CustomInventory was created as a way to work around the lack of a scripting language before ZScript existed, and is full of idiosyncrasies that one must be aware of when using it.

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 CustomInventory : StateProvider
{
	Default
	{
		DefaultStateUsage SUF_ACTOR|SUF_OVERLAY|SUF_ITEM;
	}
	
	//---------------------------------------------------------------------------
	//
	//
	//---------------------------------------------------------------------------

	// This is only here, because these functions were originally exported on Inventory, despite only working for weapons, so this is here to satisfy some potential old mods having called it through CustomInventory.
	deprecated("2.3", "must be called from Weapon") action void A_GunFlash(statelabel flash = null, int flags = 0) {}
	deprecated("2.3", "must be called from Weapon") action void A_Lower() {}
	deprecated("2.3", "must be called from Weapon") action void A_Raise() {}
	deprecated("2.3", "must be called from Weapon") action void A_CheckReload() {}
	deprecated("3.7", "must be called from Weapon") action void A_WeaponReady(int flags = 0) {}	// this was somehow missed in 2.3 ...
	native bool CallStateChain (Actor actor, State state);
		
	//===========================================================================
	//
	// ACustomInventory :: SpecialDropAction
	//
	//===========================================================================

	override bool SpecialDropAction (Actor dropper)
	{
		return CallStateChain (dropper, FindState('Drop'));
	}

	//===========================================================================
	//
	// ACustomInventory :: Use
	//
	//===========================================================================

	override bool Use (bool pickup)
	{
		return CallStateChain (Owner, FindState('Use'));
	}

	//===========================================================================
	//
	// ACustomInventory :: TryPickup
	//
	//===========================================================================

	override bool TryPickup (in out Actor toucher)
	{
		let pickupstate = FindState('Pickup');
		bool useok = CallStateChain (toucher, pickupstate);
		if ((useok || pickupstate == NULL) && FindState('Use') != NULL)
		{
			useok = Super.TryPickup (toucher);
		}
		else if (useok)
		{
			GoAwayAndDie();
		}
		return useok;
	}
}

DECORATE definition

Note: This is legacy code, kept here for reference only. DECORATE is still supported but no longer used by GZDoom. GZDoom internally uses the ZScript definition above.
ACTOR CustomInventory : Inventory native {}

Using in DECORATE

CustomInventory only uses the basic Inventory properties, but defines 3 new states:

  • Pickup.
  • Use.
  • Drop.
Ktip.png Tip: Players, Monsters and pretty much everything else can obtain a CustomInventory and be affected by its Pickup state. Inventory items can also receive CustomInventory items to execute behaviors, given by ACS or DECORATE.

The behavior is as follows:

  • All code pointers in the Pickup state sequence are called when the item is being picked up. The sequence is successful when the last called function in the state doesn't return failure explicitly; you can also use ACS_ExecuteWithResult to set the result from ACS. Success can be overridden by terminating the state sequence with fail instead of stop.
  • Anonymous Functions can utilize return int and return bool to succeed or fail a custominventory chain. An int of 0 or a false boolean fails a function (and possibly the chain), while any other number succeeds the chain.
Ktip.png Tip: Jumping functions always set success to false.
  • If the Pickup sequence returns successfully the behavior depends on the presence of the Use state:
    • If there is no Use state the item will be removed from the map and not be placed in the actor's inventory.
    • If there is a Use state the item will be placed in the actor's inventory.
  • If the item has a Use state and is being used by the player the Use state sequence is called. Failure or success are determined the same way as for the Pickup state. If the sequence returns successfully the item is removed from the inventory. Note that due to this special behavior, the Use and Pickup states will ignore all frame durations and shouldn't be looped, attempts to do to so may result in the sequence being interrupted by the engine; every frame will execute within the same tic.
  • If the item is being dropped by a monster the Drop state sequence will be executed and the item will never be spawned. This is mostly there for special actions that can be taken by Strife conversation scripts. For regular monster death actions there are better and more flexible way to achieve the same.

Notes:

  • State jumps should use an actual string instead of an offset number to perform the jump to guarantee it does what it's supposed to do for the Use state.
  • To make an item that's able to be picked up with conditions (excluding the Inventory.MaxAmount property), the inventory item will have to perform a function such as A_RailWait last in the state, especially after jump functions. The +INVENTORY.ALWAYSPICKUP flag should not be used in this case, because even if the sequence fails, the item will still disappear. Instead, after all conditions are met, you should perform a function akin to the described above to signify success.
  • User variables can be used with some conditions.
  • A jump to the Use state will NOT be treated the same as the actor actually activating it. For this, the +INVENTORY.AUTOACTIVATE flag must be present if it's for anything non-player related.
  • CustomInventory items cannot be used to "fetch" variables directly. They can perform jumps based upon the current actor's variables that are defined, and execute DECORATE action functions and ACS scripts accordingly, and they can modify that actor's variables in particular, but nothing else. Once used, the CustomInventory item loses access to its variables, gaining direct access to the owner's variables instead.

Examples

actor BigBoost : CustomInventory 10492
{
  Inventory.PickupMessage "Energy Boost!!!"
  Inventory.PickupSound "misc/p_pkup"
  +COUNTITEM
  states
  {
  Spawn:
    AWI3 A -1
    stop
  Pickup:
    TNT1 A 0 A_GiveInventory ("Soulsphere", 2)
    TNT1 A 0 A_GiveInventory ("BFG9000")
    stop
  }
}