mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
- scriptified GiveInventory and made the interface a bit more configurable by mods.
Now a child type can decide for itself how to treat 'amount'. The scripting interfaces to this function in ACS and FraggleScript have been consolidated and also scriptified.
This commit is contained in:
parent
a426655d61
commit
eb47fb9adc
10 changed files with 158 additions and 173 deletions
|
@ -746,10 +746,6 @@ public:
|
|||
// APlayerPawn for some specific handling for players. None of this
|
||||
// should ever be overridden by custom classes.
|
||||
|
||||
// Give an item to the actor and pick it up.
|
||||
// Returns true if the item pickup succeeded.
|
||||
bool GiveInventory (PClassActor *type, int amount, bool givecheat = false);
|
||||
|
||||
// Removes the item from the inventory list.
|
||||
virtual void RemoveInventory (AInventory *item);
|
||||
|
||||
|
|
|
@ -2405,34 +2405,6 @@ void FParser::SF_IsPlayerObj(void)
|
|||
//============================================================================
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// DoGiveInv
|
||||
//
|
||||
// Gives an item to a single actor.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static void FS_GiveInventory (AActor *actor, const char * type, int amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (strcmp (type, "Armor") == 0)
|
||||
{
|
||||
type = "BasicArmorPickup";
|
||||
}
|
||||
auto info = PClass::FindActor (type);
|
||||
if (info == NULL || !info->IsDescendantOf(RUNTIME_CLASS(AInventory)))
|
||||
{
|
||||
Printf ("Unknown inventory item: %s\n", type);
|
||||
return;
|
||||
}
|
||||
|
||||
actor->GiveInventory(info, amount);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// DoTakeInv
|
||||
|
@ -2509,9 +2481,9 @@ static int FS_CheckInventory (AActor *activator, const char *type)
|
|||
|
||||
void FParser::SF_PlayerKeys(void)
|
||||
{
|
||||
static const char * const DoomKeys[]={"BlueCard", "YellowCard", "RedCard", "BlueSkull", "YellowSkull", "RedSkull"};
|
||||
static const ENamedName DoomKeys[]={NAME_BlueCard, NAME_YellowCard, NAME_RedCard, NAME_BlueSkull, NAME_YellowSkull, NAME_RedSkull};
|
||||
int playernum, keynum, givetake;
|
||||
const char * keyname;
|
||||
FName keyname;
|
||||
|
||||
if (CheckArgs(2))
|
||||
{
|
||||
|
@ -2535,7 +2507,7 @@ void FParser::SF_PlayerKeys(void)
|
|||
else
|
||||
{
|
||||
givetake = intvalue(t_argv[2]);
|
||||
if(givetake) FS_GiveInventory(players[playernum].mo, keyname, 1);
|
||||
if(givetake) ScriptUtil::Exec(NAME_GiveInventory, players[playernum].mo, keyname.GetIndex(), 1);
|
||||
else FS_TakeInventory(players[playernum].mo, keyname, 1);
|
||||
t_return.type = svt_int;
|
||||
t_return.value.i = 0;
|
||||
|
@ -2745,7 +2717,7 @@ void FParser::SF_GiveInventory(void)
|
|||
|
||||
if(t_argc == 2) count=1;
|
||||
else count=intvalue(t_argv[2]);
|
||||
FS_GiveInventory(players[playernum].mo, stringvalue(t_argv[1]), count);
|
||||
ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, players[playernum].mo, FName(stringvalue(t_argv[1])).GetIndex(), count);
|
||||
t_return.type = svt_int;
|
||||
t_return.value.i = 0;
|
||||
}
|
||||
|
|
|
@ -992,6 +992,7 @@ xx(snd_resampler)
|
|||
xx(ScriptUtil)
|
||||
xx(SetMarineWeapon)
|
||||
xx(SetMarineSprite)
|
||||
xx(GiveInventory)
|
||||
|
||||
// Weapon member fields that need direct access
|
||||
xx(Ammo1)
|
||||
|
@ -1009,4 +1010,11 @@ xx(bDehAmmo)
|
|||
xx(FOVScale)
|
||||
xx(YAdjust)
|
||||
xx(Crosshair)
|
||||
xx(WeaponFlags)
|
||||
xx(WeaponFlags)
|
||||
|
||||
xx(BlueCard)
|
||||
xx(YellowCard)
|
||||
xx(RedCard)
|
||||
xx(BlueSkull)
|
||||
xx(YellowSkull)
|
||||
xx(RedSkull)
|
||||
|
|
|
@ -1747,49 +1747,6 @@ static void ClearInventory (AActor *activator)
|
|||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// GiveInventory
|
||||
//
|
||||
// Gives an item to one or more actors.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static void GiveInventory (AActor *activator, const char *type, int amount)
|
||||
{
|
||||
PClassActor *info;
|
||||
|
||||
if (amount <= 0 || type == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (stricmp (type, "Armor") == 0)
|
||||
{
|
||||
type = "BasicArmorPickup";
|
||||
}
|
||||
info = PClass::FindActor(type);
|
||||
if (info == NULL)
|
||||
{
|
||||
Printf ("ACS: I don't know what %s is.\n", type);
|
||||
}
|
||||
else if (!info->IsDescendantOf (RUNTIME_CLASS(AInventory)))
|
||||
{
|
||||
Printf ("ACS: %s is not an inventory item.\n", type);
|
||||
}
|
||||
else if (activator == NULL)
|
||||
{
|
||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (playeringame[i])
|
||||
players[i].mo->GiveInventory(info, amount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
activator->GiveInventory(info, amount);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// TakeInventory
|
||||
|
@ -9325,34 +9282,41 @@ scriptwait:
|
|||
break;
|
||||
|
||||
case PCD_GIVEINVENTORY:
|
||||
GiveInventory (activator, FBehavior::StaticLookupString (STACK(2)), STACK(1));
|
||||
{
|
||||
int typeindex = FName(FBehavior::StaticLookupString(STACK(2))).GetIndex();
|
||||
ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, activator, ScriptUtil::Int, typeindex, ScriptUtil::Int, STACK(1), ScriptUtil::End);
|
||||
sp -= 2;
|
||||
break;
|
||||
}
|
||||
|
||||
case PCD_GIVEACTORINVENTORY:
|
||||
{
|
||||
int typeindex = FName(FBehavior::StaticLookupString(STACK(2))).GetIndex();
|
||||
FName type = FName(FBehavior::StaticLookupString(STACK(2)));
|
||||
if (STACK(3) == 0)
|
||||
{
|
||||
const char *type = FBehavior::StaticLookupString(STACK(2));
|
||||
if (STACK(3) == 0)
|
||||
{
|
||||
GiveInventory(NULL, FBehavior::StaticLookupString(STACK(2)), STACK(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
FActorIterator it(STACK(3));
|
||||
AActor *actor;
|
||||
for (actor = it.Next(); actor != NULL; actor = it.Next())
|
||||
{
|
||||
GiveInventory(actor, type, STACK(1));
|
||||
}
|
||||
}
|
||||
sp -= 3;
|
||||
ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, nullptr, ScriptUtil::Int, typeindex, ScriptUtil::Int, STACK(1), ScriptUtil::End);
|
||||
}
|
||||
else
|
||||
{
|
||||
FActorIterator it(STACK(3));
|
||||
AActor *actor;
|
||||
for (actor = it.Next(); actor != NULL; actor = it.Next())
|
||||
{
|
||||
ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, actor, ScriptUtil::Int, typeindex, ScriptUtil::Int, STACK(1), ScriptUtil::End);
|
||||
}
|
||||
}
|
||||
sp -= 3;
|
||||
break;
|
||||
}
|
||||
|
||||
case PCD_GIVEINVENTORYDIRECT:
|
||||
GiveInventory (activator, FBehavior::StaticLookupString (TAGSTR(uallong(pc[0]))), uallong(pc[1]));
|
||||
{
|
||||
int typeindex = FName(FBehavior::StaticLookupString(TAGSTR(uallong(pc[0])))).GetIndex();
|
||||
ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, activator, ScriptUtil::Int, typeindex, ScriptUtil::Int, uallong(pc[1]), ScriptUtil::End);
|
||||
pc += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
case PCD_TAKEINVENTORY:
|
||||
TakeInventory (activator, FBehavior::StaticLookupString (STACK(2)), STACK(1));
|
||||
|
|
|
@ -753,81 +753,6 @@ DEFINE_ACTION_FUNCTION(AActor, SetState)
|
|||
ACTION_RETURN_BOOL(self->SetState(state, nofunction));
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AActor :: GiveInventory
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
bool AActor::GiveInventory(PClassActor *type, int amount, bool givecheat)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if (type == nullptr || !type->IsDescendantOf(RUNTIME_CLASS(AInventory))) return false;
|
||||
|
||||
auto savedPendingWeap = player != NULL ? player->PendingWeapon : NULL;
|
||||
bool hadweap = player != NULL ? player->ReadyWeapon != NULL : true;
|
||||
|
||||
AInventory *item;
|
||||
if (!givecheat)
|
||||
{
|
||||
item = static_cast<AInventory *>(Spawn (type));
|
||||
}
|
||||
else
|
||||
{
|
||||
item = static_cast<AInventory *>(Spawn (type, Pos(), NO_REPLACE));
|
||||
if (item == NULL) return false;
|
||||
}
|
||||
|
||||
// This shouldn't count for the item statistics!
|
||||
item->ClearCounters();
|
||||
if (!givecheat || amount > 0)
|
||||
{
|
||||
if (type->IsDescendantOf(NAME_BasicArmorPickup) || type->IsDescendantOf(NAME_BasicArmorBonus))
|
||||
{
|
||||
item->IntVar(NAME_SaveAmount) *= amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (givecheat)
|
||||
{
|
||||
const AInventory *const haveitem = FindInventory(type);
|
||||
|
||||
item->Amount = MIN(amount, nullptr == haveitem
|
||||
? static_cast<AInventory*>(GetDefaultByType(type))->MaxAmount
|
||||
: haveitem->MaxAmount);
|
||||
}
|
||||
else
|
||||
{
|
||||
item->Amount = amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!item->CallTryPickup (this))
|
||||
{
|
||||
item->Destroy ();
|
||||
result = false;
|
||||
}
|
||||
// If the item was a weapon, don't bring it up automatically
|
||||
// unless the player was not already using a weapon.
|
||||
// Don't bring it up automatically if this is called by the give cheat.
|
||||
if (!givecheat && player != NULL && savedPendingWeap != NULL && hadweap)
|
||||
{
|
||||
player->PendingWeapon = savedPendingWeap;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GiveInventory)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_CLASS(type, AInventory);
|
||||
PARAM_INT(amount);
|
||||
PARAM_BOOL(givecheat);
|
||||
ACTION_RETURN_BOOL(self->GiveInventory(type, amount, givecheat));
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AActor :: RemoveInventory
|
||||
|
|
|
@ -744,7 +744,6 @@ class Actor : Thinker native
|
|||
native void RemoveInventory(Inventory inv);
|
||||
native void ClearInventory();
|
||||
protected native void DestroyAllInventory(); // This is not supposed to be called by user code!
|
||||
native bool GiveInventory(class<Inventory> type, int amount, bool givecheat = false);
|
||||
native bool SetInventory(class<Inventory> itemclass, int amount, bool beyondMax = false);
|
||||
native bool TakeInventory(class<Inventory> itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false);
|
||||
native clearscope Inventory FindInventory(class<Inventory> itemtype, bool subclass = false) const;
|
||||
|
|
|
@ -31,4 +31,53 @@ extend class Actor
|
|||
Inv.InventoryID = InventoryID++;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AActor :: GiveInventory
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
bool GiveInventory(Class<Inventory> type, int amount, bool givecheat = false)
|
||||
{
|
||||
bool result = true;
|
||||
let player = self.player;
|
||||
|
||||
// This can be called from places which do not check the given item's type.
|
||||
if (type == null || !(type is 'Inventory')) return false;
|
||||
|
||||
Weapon savedPendingWeap = player != NULL ? player.PendingWeapon : NULL;
|
||||
bool hadweap = player != NULL ? player.ReadyWeapon != NULL : true;
|
||||
|
||||
Inventory item;
|
||||
if (!givecheat)
|
||||
{
|
||||
item = Inventory(Spawn (type));
|
||||
}
|
||||
else
|
||||
{
|
||||
item = Inventory(Spawn (type, Pos, NO_REPLACE));
|
||||
if (item == NULL) return false;
|
||||
}
|
||||
|
||||
// This shouldn't count for the item statistics.
|
||||
item.ClearCounters();
|
||||
if (!givecheat || amount > 0)
|
||||
{
|
||||
item.SetGiveAmount(self, amount, givecheat);
|
||||
}
|
||||
if (!item.CallTryPickup (self))
|
||||
{
|
||||
item.Destroy ();
|
||||
result = false;
|
||||
}
|
||||
// If the item was a weapon, don't bring it up automatically
|
||||
// unless the player was not already using a weapon.
|
||||
// Don't bring it up automatically if this is called by the give cheat.
|
||||
if (!givecheat && player != NULL && savedPendingWeap != NULL && hadweap)
|
||||
{
|
||||
player.PendingWeapon = savedPendingWeap;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -340,6 +340,10 @@ class BasicArmorBonus : Armor
|
|||
}
|
||||
|
||||
|
||||
override void SetGiveAmount(Actor receiver, int amount, bool bycheat)
|
||||
{
|
||||
SaveAmount *= amount;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -440,6 +444,12 @@ class BasicArmorPickup : Armor
|
|||
armor.ActualSaveAmount = SaveAmount;
|
||||
return true;
|
||||
}
|
||||
|
||||
override void SetGiveAmount(Actor receiver, int amount, bool bycheat)
|
||||
{
|
||||
SaveAmount *= amount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -1016,6 +1016,27 @@ class Inventory : Actor native
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Modifies the amount based on what an item should contain if given
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
virtual void SetGiveAmount(Actor receiver, int amount, bool givecheat)
|
||||
{
|
||||
if (givecheat)
|
||||
{
|
||||
let haveitem = receiver.FindInventory(GetClass());
|
||||
self.Amount = MIN(amount, haveitem == null? self.Default.MaxAmount : haveitem.MaxAmount);
|
||||
}
|
||||
else
|
||||
{
|
||||
self.Amount = amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -4,6 +4,47 @@
|
|||
class ScriptUtil play
|
||||
{
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// GiveInventory
|
||||
//
|
||||
// Gives an item to one or more actors.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
static void GiveInventory (Actor activator, Name type, int amount)
|
||||
{
|
||||
if (amount <= 0 || type == 'none')
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (type == 'Armor')
|
||||
{
|
||||
type = "BasicArmorPickup";
|
||||
}
|
||||
Class<Actor> info = type;
|
||||
if (info == NULL)
|
||||
{
|
||||
Console.Printf ("GiveInventory: Unknown item type %s.\n", type);
|
||||
}
|
||||
else if (!(info is 'Inventory'))
|
||||
{
|
||||
Console.Printf ("GiveInventory: %s is not an inventory item.\n", type);
|
||||
}
|
||||
else if (activator == NULL)
|
||||
{
|
||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (playeringame[i])
|
||||
players[i].mo.GiveInventory((class<Inventory>)(info), amount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
activator.GiveInventory((class<Inventory>)(info), amount);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue