mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-23 04:11:53 +00:00
7c6542e595
- scriptification of CustomInventory.
405 lines
11 KiB
Text
405 lines
11 KiB
Text
struct VisStyle
|
|
{
|
|
bool Invert;
|
|
float Alpha;
|
|
int RenderStyle;
|
|
}
|
|
|
|
class Inventory : Actor native
|
|
{
|
|
const BLINKTHRESHOLD = (4*32);
|
|
|
|
native Actor Owner; // Who owns self item? NULL if it's still a pickup.
|
|
native int Amount; // Amount of item self instance has
|
|
native int MaxAmount; // Max amount of item self instance can have
|
|
native int InterHubAmount; // Amount of item that can be kept between hubs or levels
|
|
native int RespawnTics; // Tics from pickup time to respawn time
|
|
native TextureID Icon; // Icon to show on status bar or HUD
|
|
native int DropTime; // Countdown after dropping
|
|
native Class<Actor> SpawnPointClass; // For respawning like Heretic's mace
|
|
native Class<Actor> PickupFlash; // actor to spawn as pickup flash
|
|
native Sound PickupSound;
|
|
native bool bPickupGood;
|
|
native bool bCreateCopyMoved;
|
|
native bool bInitEffectFailed;
|
|
|
|
Default
|
|
{
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 1;
|
|
Inventory.InterHubAmount 1;
|
|
Inventory.UseSound "misc/invuse";
|
|
Inventory.PickupSound "misc/i_pkup";
|
|
Inventory.PickupMessage "$TXT_DEFAULTPICKUPMSG";
|
|
}
|
|
|
|
virtual native color GetBlend ();
|
|
virtual native bool HandlePickup(Inventory item);
|
|
virtual native Inventory CreateCopy(Actor other);
|
|
virtual native bool SpecialDropAction (Actor dropper);
|
|
virtual native String PickupMessage();
|
|
virtual native bool ShouldStay();
|
|
virtual native void PlayPickupSound(Actor user);
|
|
|
|
native bool DoRespawn();
|
|
native bool GoAway();
|
|
native void GoAwayAndDie();
|
|
native void BecomeItem();
|
|
native void BecomePickup();
|
|
|
|
// In this case the caller function is more than a simple wrapper around the virtual method and
|
|
// is what must be actually called to pick up an item.
|
|
native bool, Actor CallTryPickup(Actor toucher);
|
|
native bool CallStateChain (Actor actor, State state);
|
|
|
|
States(Actor, Overlay, Weapon, Item)
|
|
{
|
|
HideDoomish:
|
|
TNT1 A 1050;
|
|
TNT1 A 0 A_RestoreSpecialPosition;
|
|
TNT1 A 1 A_RestoreSpecialDoomThing;
|
|
Stop;
|
|
HideSpecial:
|
|
ACLO E 1400;
|
|
ACLO A 0 A_RestoreSpecialPosition;
|
|
ACLO A 4 A_RestoreSpecialThing1;
|
|
ACLO BABCBCDC 4;
|
|
ACLO D 4 A_RestoreSpecialThing2;
|
|
Stop;
|
|
Held:
|
|
TNT1 A -1;
|
|
Stop;
|
|
HoldAndDestroy:
|
|
TNT1 A 1;
|
|
Stop;
|
|
}
|
|
|
|
// These are regular functions for the item itself.
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// PROC A_RestoreSpecialThing1
|
|
//
|
|
// Make a special thing visible again.
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
void A_RestoreSpecialThing1()
|
|
{
|
|
bInvisible = false;
|
|
if (DoRespawn ())
|
|
{
|
|
A_PlaySound ("misc/spawn", CHAN_VOICE);
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// PROC A_RestoreSpecialThing2
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
void A_RestoreSpecialThing2()
|
|
{
|
|
bSpecial = true;
|
|
if (!Default.bNoGravity)
|
|
{
|
|
bNoGravity = false;
|
|
}
|
|
SetState (SpawnState);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// PROC A_RestoreSpecialDoomThing
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
void A_RestoreSpecialDoomThing()
|
|
{
|
|
bInvisible = false;
|
|
bSpecial = true;
|
|
if (!Default.bNoGravity)
|
|
{
|
|
bNoGravity = false;
|
|
}
|
|
if (DoRespawn ())
|
|
{
|
|
SetState (SpawnState);
|
|
A_PlaySound ("misc/spawn", CHAN_VOICE);
|
|
Spawn ("ItemFog", Pos, ALLOW_REPLACE);
|
|
}
|
|
}
|
|
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory :: CallHandlePickup
|
|
//
|
|
// Runs all HandlePickup methods in the chain
|
|
//
|
|
//===========================================================================
|
|
|
|
private bool CallHandlePickup(Inventory item)
|
|
{
|
|
let me = self;
|
|
while (me != null)
|
|
{
|
|
if (me.HandlePickup(item)) return true;
|
|
me = me.Inv;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory :: TryPickup
|
|
//
|
|
//===========================================================================
|
|
|
|
virtual protected bool TryPickup (in out Actor toucher)
|
|
{
|
|
Actor newtoucher = toucher; // in case changed by the powerup
|
|
|
|
// If HandlePickup() returns true, it will set the IF_PICKUPGOOD flag
|
|
// to indicate that self item has been picked up. If the item cannot be
|
|
// picked up, then it leaves the flag cleared.
|
|
|
|
bPickupGood = false;
|
|
if (toucher.Inv != NULL && toucher.Inv.CallHandlePickup (self))
|
|
{
|
|
// Let something else the player is holding intercept the pickup.
|
|
if (!bPickupGood)
|
|
{
|
|
return false;
|
|
}
|
|
bPickupGood = false;
|
|
GoAwayAndDie ();
|
|
}
|
|
else if (MaxAmount > 0)
|
|
{
|
|
// Add the item to the inventory. It is not already there, or HandlePickup
|
|
// would have already taken care of it.
|
|
let copy = CreateCopy (toucher);
|
|
if (copy == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
// Some powerups cannot activate absolutely, for
|
|
// example, PowerMorph; fail the pickup if so.
|
|
if (copy.bInitEffectFailed)
|
|
{
|
|
if (copy != self) copy.Destroy();
|
|
else bInitEffectFailed;
|
|
return false;
|
|
}
|
|
// Handle owner-changing powerups
|
|
if (copy.bCreateCopyMoved)
|
|
{
|
|
newtoucher = copy.Owner;
|
|
copy.Owner = NULL;
|
|
bCreateCopyMoved = false;
|
|
}
|
|
// Continue onwards with the rest
|
|
copy.AttachToOwner (newtoucher);
|
|
if (bAutoActivate)
|
|
{
|
|
if (copy.Use (true))
|
|
{
|
|
if (--copy.Amount <= 0)
|
|
{
|
|
copy.bSpecial = false;
|
|
copy.SetStateLabel ("HoldAndDestroy");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (bAutoActivate)
|
|
{
|
|
// Special case: If an item's MaxAmount is 0, you can still pick it
|
|
// up if it is autoactivate-able.
|
|
|
|
// The item is placed in the inventory just long enough to be used.
|
|
toucher.AddInventory(self);
|
|
bool usegood = Use(true);
|
|
toucher.RemoveInventory(self);
|
|
|
|
if (usegood)
|
|
{
|
|
GoAwayAndDie();
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory :: TryPickupRestricted
|
|
//
|
|
//===========================================================================
|
|
|
|
virtual bool TryPickupRestricted (in out Actor toucher)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory :: AttachToOwner
|
|
//
|
|
//===========================================================================
|
|
|
|
virtual void AttachToOwner (Actor other)
|
|
{
|
|
BecomeItem ();
|
|
other.AddInventory (self);
|
|
}
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory :: DetachFromOwner
|
|
//
|
|
// Performs any special work needed when the item leaves an inventory,
|
|
// either through destruction or becoming a pickup.
|
|
//
|
|
//===========================================================================
|
|
|
|
virtual void DetachFromOwner ()
|
|
{
|
|
}
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory::CreateTossable
|
|
//
|
|
// Creates a copy of the item suitable for dropping. If this actor embodies
|
|
// only one item, then it is tossed out itself. Otherwise, the count drops
|
|
// by one and a new item with an amount of 1 is spawned.
|
|
//
|
|
//===========================================================================
|
|
|
|
virtual Inventory CreateTossable ()
|
|
{
|
|
// If self actor lacks a SpawnState, don't drop it. (e.g. A base weapon
|
|
// like the fist can't be dropped because you'll never see it.)
|
|
if (SpawnState == GetDefaultByType("Actor").SpawnState || SpawnState == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
if (bUndroppable || bUntossable || Owner == NULL || Amount <= 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
if (Amount == 1 && !bKeepDepleted)
|
|
{
|
|
BecomePickup ();
|
|
DropTime = 30;
|
|
bSpecial = bSolid = false;
|
|
return self;
|
|
}
|
|
let copy = Inventory(Spawn (GetClass(), Owner.Pos, NO_REPLACE));
|
|
if (copy != NULL)
|
|
{
|
|
copy.MaxAmount = MaxAmount;
|
|
copy.Amount = 1;
|
|
copy.DropTime = 30;
|
|
copy.bSpecial = copy.bSolid = false;
|
|
Amount--;
|
|
}
|
|
return copy;
|
|
}
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory :: DepleteOrDestroy
|
|
//
|
|
// If the item is depleted, just change its amount to 0, otherwise it's destroyed.
|
|
//
|
|
//===========================================================================
|
|
|
|
virtual void DepleteOrDestroy ()
|
|
{
|
|
// If it's not ammo or an internal armor, destroy it.
|
|
// Ammo needs to stick around, even when it's zero for the benefit
|
|
// of the weapons that use it and to maintain the maximum ammo
|
|
// amounts a backpack might have given.
|
|
// Armor shouldn't be removed because they only work properly when
|
|
// they are the last items in the inventory.
|
|
if (bKeepDepleted)
|
|
{
|
|
Amount = 0;
|
|
}
|
|
else
|
|
{
|
|
Destroy();
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory :: Travelled
|
|
//
|
|
// Called when an item in somebody's inventory is carried over to another
|
|
// map, in case it needs to do special reinitialization.
|
|
//
|
|
//===========================================================================
|
|
|
|
virtual void Travelled() {}
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory :: DoEffect
|
|
//
|
|
// Handles any effect an item might apply to its owner
|
|
// Normally only used by subclasses of Powerup
|
|
//
|
|
//===========================================================================
|
|
|
|
virtual void DoEffect() {}
|
|
|
|
|
|
virtual bool Use (bool pickup) { return false; }
|
|
virtual double GetSpeedFactor() { return 1; }
|
|
virtual bool GetNoTeleportFreeze() { return false; }
|
|
virtual void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive) {}
|
|
virtual void AlterWeaponSprite(VisStyle vis, in out int changed) {}
|
|
virtual void OwnerDied() {}
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory :: DrawPowerup
|
|
//
|
|
// Gives self item a chance to draw a special status indicator on the screen.
|
|
// Returns false if it didn't draw anything.
|
|
//
|
|
//===========================================================================
|
|
|
|
virtual bool DrawPowerup(int x, int y) { return false; }
|
|
|
|
//===========================================================================
|
|
//
|
|
// AInventory :: AbsorbDamage
|
|
//
|
|
// Allows inventory items (primarily armor) to reduce the amount of damage
|
|
// taken. Damage is the amount of damage that would be done without armor,
|
|
// and newdamage is the amount that should be done after the armor absorbs
|
|
// it.
|
|
//
|
|
//===========================================================================
|
|
|
|
virtual void AbsorbDamage (int damage, Name damageType, out int newdamage) {}
|
|
|
|
}
|
|
|
|
class DehackedPickup : Inventory native
|
|
{
|
|
}
|
|
|
|
class FakeInventory : Inventory native
|
|
{
|
|
native bool Respawnable;
|
|
}
|