mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 08:31:45 +00:00
Merge branch 'master' into scripting
Conflicts: src/m_cheat.cpp src/p_acs.cpp src/thingdef/thingdef_codeptr.cpp src/thingdef/thingdef_properties.cpp
This commit is contained in:
commit
646c135eff
12 changed files with 106 additions and 126 deletions
|
@ -643,6 +643,11 @@ public:
|
||||||
// Removes the item from the inventory list.
|
// Removes the item from the inventory list.
|
||||||
virtual void RemoveInventory (AInventory *item);
|
virtual void RemoveInventory (AInventory *item);
|
||||||
|
|
||||||
|
// Take the amount value of an item from the inventory list.
|
||||||
|
// If nothing is left, the item may be destroyed.
|
||||||
|
// Returns true if the initial item count is positive.
|
||||||
|
virtual bool TakeInventory (PClassActor *itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false);
|
||||||
|
|
||||||
// Uses an item and removes it from the inventory.
|
// Uses an item and removes it from the inventory.
|
||||||
virtual bool UseInventory (AInventory *item);
|
virtual bool UseInventory (AInventory *item);
|
||||||
|
|
||||||
|
|
|
@ -137,14 +137,9 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp
|
||||||
hxarmor->Slots[3] = 0;
|
hxarmor->Slots[3] = 0;
|
||||||
hxarmor->Slots[4] = spawntype->HexenArmor[0];
|
hxarmor->Slots[4] = spawntype->HexenArmor[0];
|
||||||
}
|
}
|
||||||
else if (item->ItemFlags & IF_KEEPDEPLETED)
|
|
||||||
{
|
|
||||||
// Set depletable armor to 0 (this includes BasicArmor).
|
|
||||||
item->Amount = 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->Destroy ();
|
item->DepleteOrDestroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item = next;
|
item = next;
|
||||||
|
|
|
@ -1177,6 +1177,32 @@ void AInventory::Destroy ()
|
||||||
if (SendItemDrop == this) SendItemDrop = NULL;
|
if (SendItemDrop == this) SendItemDrop = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// AInventory :: DepleteOrDestroy
|
||||||
|
//
|
||||||
|
// If the item is depleted, just change its amount to 0, otherwise it's destroyed.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void AInventory::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 (ItemFlags & IF_KEEPDEPLETED)
|
||||||
|
{
|
||||||
|
Amount = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// AInventory :: GetBlend
|
// AInventory :: GetBlend
|
||||||
|
|
|
@ -155,6 +155,7 @@ public:
|
||||||
virtual void MarkPrecacheSounds() const;
|
virtual void MarkPrecacheSounds() const;
|
||||||
virtual void BeginPlay ();
|
virtual void BeginPlay ();
|
||||||
virtual void Destroy ();
|
virtual void Destroy ();
|
||||||
|
virtual void DepleteOrDestroy ();
|
||||||
virtual void Tick ();
|
virtual void Tick ();
|
||||||
virtual bool ShouldRespawn ();
|
virtual bool ShouldRespawn ();
|
||||||
virtual bool ShouldStay ();
|
virtual bool ShouldStay ();
|
||||||
|
|
|
@ -769,10 +769,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
||||||
static_cast<PClassActor *>(type)->GetReplacement()->IsDescendantOf(RUNTIME_CLASS(ADehackedPickup))))
|
static_cast<PClassActor *>(type)->GetReplacement()->IsDescendantOf(RUNTIME_CLASS(ADehackedPickup))))
|
||||||
{
|
{
|
||||||
// Give the weapon only if it belongs to the current game or
|
// Give the weapon only if it belongs to the current game or
|
||||||
// is in a weapon slot.
|
if (player->weapons.LocateWeapon(static_cast<PClassWeapon*>(type), NULL, NULL))
|
||||||
if (static_cast<PClassActor *>(type)->GameFilter == GAME_Any ||
|
|
||||||
(static_cast<PClassActor *>(type)->GameFilter & gameinfo.gametype) ||
|
|
||||||
player->weapons.LocateWeapon(static_cast<PClassWeapon *>(type), NULL, NULL))
|
|
||||||
{
|
{
|
||||||
AWeapon *def = (AWeapon*)GetDefaultByType (type);
|
AWeapon *def = (AWeapon*)GetDefaultByType (type);
|
||||||
if (giveall == ALL_YESYES || !(def->WeaponFlags & WIF_CHEATNOTWEAPON))
|
if (giveall == ALL_YESYES || !(def->WeaponFlags & WIF_CHEATNOTWEAPON))
|
||||||
|
@ -854,7 +851,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
||||||
void cht_Take (player_t *player, const char *name, int amount)
|
void cht_Take (player_t *player, const char *name, int amount)
|
||||||
{
|
{
|
||||||
bool takeall;
|
bool takeall;
|
||||||
PClass *type;
|
PClassActor *type;
|
||||||
|
|
||||||
if (player->mo == NULL || player->health <= 0)
|
if (player->mo == NULL || player->health <= 0)
|
||||||
{
|
{
|
||||||
|
@ -1045,7 +1042,7 @@ void cht_Take (player_t *player, const char *name, int amount)
|
||||||
if (takeall)
|
if (takeall)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
type = PClass::FindClass (name);
|
type = PClass::FindActor (name);
|
||||||
if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS (AInventory)))
|
if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS (AInventory)))
|
||||||
{
|
{
|
||||||
if (player == &players[consoleplayer])
|
if (player == &players[consoleplayer])
|
||||||
|
@ -1053,24 +1050,7 @@ void cht_Take (player_t *player, const char *name, int amount)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AInventory *inventory = player->mo->FindInventory(static_cast<PClassActor *>(type));
|
player->mo->TakeInventory(type, amount ? amount : 1);
|
||||||
|
|
||||||
if (inventory != NULL)
|
|
||||||
{
|
|
||||||
inventory->Amount -= amount ? amount : 1;
|
|
||||||
|
|
||||||
if (inventory->Amount <= 0)
|
|
||||||
{
|
|
||||||
if (inventory->ItemFlags & IF_KEEPDEPLETED)
|
|
||||||
{
|
|
||||||
inventory->Amount = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
inventory->Destroy ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1131,40 +1131,6 @@ static void GiveInventory (AActor *activator, const char *type, int amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// DoTakeInv
|
|
||||||
//
|
|
||||||
// Takes an item from a single actor.
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
static void DoTakeInv (AActor *actor, PClassActor *info, int amount)
|
|
||||||
{
|
|
||||||
AInventory *item = actor->FindInventory (info);
|
|
||||||
if (item != NULL)
|
|
||||||
{
|
|
||||||
item->Amount -= amount;
|
|
||||||
if (item->Amount <= 0)
|
|
||||||
{
|
|
||||||
// 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 (item->ItemFlags & IF_KEEPDEPLETED)
|
|
||||||
{
|
|
||||||
item->Amount = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item->Destroy ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// TakeInventory
|
// TakeInventory
|
||||||
|
@ -1199,12 +1165,12 @@ static void TakeInventory (AActor *activator, const char *type, int amount)
|
||||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
DoTakeInv (players[i].mo, info, amount);
|
players[i].mo->TakeInventory(info, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DoTakeInv (activator, info, amount);
|
activator->TakeInventory(info, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2302,8 +2268,8 @@ void FBehavior::LoadScriptsDirectory ()
|
||||||
}
|
}
|
||||||
|
|
||||||
// [EP] Clang 3.5.0 optimizer miscompiles this function and causes random
|
// [EP] Clang 3.5.0 optimizer miscompiles this function and causes random
|
||||||
// crashes in the program. I hope that Clang 3.5.x will fix this.
|
// crashes in the program. This is fixed in 3.5.1 onwards.
|
||||||
#if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ >= 5
|
#if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 5 && __clang_patchlevel__ == 0
|
||||||
asm("" : "+g" (NumScripts));
|
asm("" : "+g" (NumScripts));
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < NumScripts; ++i)
|
for (i = 0; i < NumScripts; ++i)
|
||||||
|
@ -4781,8 +4747,8 @@ static void SetActorTeleFog(AActor *activator, int tid, FString telefogsrc, FStr
|
||||||
FActorIterator iterator(tid);
|
FActorIterator iterator(tid);
|
||||||
AActor *actor;
|
AActor *actor;
|
||||||
|
|
||||||
PClassActor * src = telefogsrc.IsNotEmpty() ? PClass::FindActor(telefogsrc) : NULL;
|
PClassActor * src = PClass::FindActor(telefogsrc);
|
||||||
PClassActor * dest = telefogdest.IsNotEmpty() ? PClass::FindActor(telefogdest) : NULL;
|
PClassActor * dest = PClass::FindActor(telefogdest);
|
||||||
while ((actor = iterator.Next()))
|
while ((actor = iterator.Next()))
|
||||||
{
|
{
|
||||||
if (telefogsrc.IsNotEmpty())
|
if (telefogsrc.IsNotEmpty())
|
||||||
|
|
|
@ -649,22 +649,7 @@ static void TakeStrifeItem (player_t *player, PClassActor *itemtype, int amount)
|
||||||
if (itemtype == RUNTIME_CLASS(ASigil))
|
if (itemtype == RUNTIME_CLASS(ASigil))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AInventory *item = player->mo->FindInventory (itemtype);
|
player->mo->TakeInventory(itemtype, amount);
|
||||||
if (item != NULL)
|
|
||||||
{
|
|
||||||
item->Amount -= amount;
|
|
||||||
if (item->Amount <= 0)
|
|
||||||
{
|
|
||||||
if (item->ItemFlags & IF_KEEPDEPLETED)
|
|
||||||
{
|
|
||||||
item->Amount = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item->Destroy ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE)
|
CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE)
|
||||||
|
|
|
@ -944,13 +944,13 @@ bool P_LoadGLNodes(MapData * map)
|
||||||
result=true;
|
result=true;
|
||||||
for(unsigned i=0; i<4;i++)
|
for(unsigned i=0; i<4;i++)
|
||||||
{
|
{
|
||||||
if (strnicmp(f_gwa->GetLump(i+1)->Name, check[i], 8))
|
if (strnicmp(f_gwa->GetLump(li+i+1)->Name, check[i], 8))
|
||||||
{
|
{
|
||||||
result=false;
|
result=false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gwalumps[i] = f_gwa->GetLump(i+1)->NewReader();
|
gwalumps[i] = f_gwa->GetLump(li+i+1)->NewReader();
|
||||||
}
|
}
|
||||||
if (result) result = DoLoadGLNodes(gwalumps);
|
if (result) result = DoLoadGLNodes(gwalumps);
|
||||||
}
|
}
|
||||||
|
|
|
@ -799,10 +799,7 @@ static int UseHealthItems(TArray<AInventory *> &Items, int &saveHealth)
|
||||||
saveHealth -= maxhealth;
|
saveHealth -= maxhealth;
|
||||||
if (--Items[index]->Amount == 0)
|
if (--Items[index]->Amount == 0)
|
||||||
{
|
{
|
||||||
if (!(Items[index]->ItemFlags & IF_KEEPDEPLETED))
|
Items[index]->DepleteOrDestroy ();
|
||||||
{
|
|
||||||
Items[index]->Destroy ();
|
|
||||||
}
|
|
||||||
Items.Delete(index);
|
Items.Delete(index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -685,6 +685,57 @@ void AActor::RemoveInventory(AInventory *item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// AActor :: TakeInventory
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate, bool notakeinfinite)
|
||||||
|
{
|
||||||
|
AInventory *item = FindInventory(itemclass);
|
||||||
|
|
||||||
|
if (item == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!fromdecorate)
|
||||||
|
{
|
||||||
|
item->Amount -= amount;
|
||||||
|
if (item->Amount <= 0)
|
||||||
|
{
|
||||||
|
item->DepleteOrDestroy();
|
||||||
|
}
|
||||||
|
// It won't be used in non-decorate context, so return false here
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
if (item->Amount > 0)
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->IsKindOf(RUNTIME_CLASS(AHexenArmor)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Do not take ammo if the "no take infinite/take as ammo depletion" flag is set
|
||||||
|
// and infinite ammo is on
|
||||||
|
if (notakeinfinite &&
|
||||||
|
((dmflags & DF_INFINITE_AMMO) || (player && player->cheats & CF_INFINITEAMMO)) &&
|
||||||
|
item->IsKindOf(RUNTIME_CLASS(AAmmo)))
|
||||||
|
{
|
||||||
|
// Nothing to do here, except maybe res = false;? Would it make sense?
|
||||||
|
}
|
||||||
|
else if (!amount || amount>=item->Amount)
|
||||||
|
{
|
||||||
|
item->DepleteOrDestroy();
|
||||||
|
}
|
||||||
|
else item->Amount-=amount;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// AActor :: DestroyAllInventory
|
// AActor :: DestroyAllInventory
|
||||||
|
@ -752,9 +803,9 @@ bool AActor::UseInventory (AInventory *item)
|
||||||
if (dmflags2 & DF2_INFINITE_INVENTORY)
|
if (dmflags2 & DF2_INFINITE_INVENTORY)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (--item->Amount <= 0 && !(item->ItemFlags & IF_KEEPDEPLETED))
|
if (--item->Amount <= 0)
|
||||||
{
|
{
|
||||||
item->Destroy ();
|
item->DepleteOrDestroy ();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1996,34 +1996,8 @@ int DoTakeInventory(AActor *receiver, bool orresult, VM_ARGS)
|
||||||
return numret;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool res = false;
|
bool res = receiver->TakeInventory(itemtype, amount, true, (flags & TIF_NOTAKEINFINITE) != 0);
|
||||||
|
|
||||||
AInventory *inv = receiver->FindInventory(itemtype);
|
|
||||||
|
|
||||||
if (inv && !inv->IsKindOf(RUNTIME_CLASS(AHexenArmor)))
|
|
||||||
{
|
|
||||||
if (inv->Amount > 0)
|
|
||||||
{
|
|
||||||
res = true;
|
|
||||||
}
|
|
||||||
// Do not take ammo if the "no take infinite/take as ammo depletion" flag is set
|
|
||||||
// and infinite ammo is on
|
|
||||||
if (flags & TIF_NOTAKEINFINITE &&
|
|
||||||
((dmflags & DF_INFINITE_AMMO) || (receiver->player->cheats & CF_INFINITEAMMO)) &&
|
|
||||||
inv->IsKindOf(RUNTIME_CLASS(AAmmo)))
|
|
||||||
{
|
|
||||||
// Nothing to do here, except maybe res = false;? Would it make sense?
|
|
||||||
}
|
|
||||||
else if (!amount || amount>=inv->Amount)
|
|
||||||
{
|
|
||||||
if (inv->ItemFlags&IF_KEEPDEPLETED) inv->Amount=0;
|
|
||||||
else inv->Destroy();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
inv->Amount -= amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!orresult)
|
if (!orresult)
|
||||||
{
|
{
|
||||||
ACTION_SET_RESULT(res);
|
ACTION_SET_RESULT(res);
|
||||||
|
|
|
@ -1448,8 +1448,8 @@ DEFINE_PROPERTY(stamina, I, Actor)
|
||||||
DEFINE_PROPERTY(telefogsourcetype, S, Actor)
|
DEFINE_PROPERTY(telefogsourcetype, S, Actor)
|
||||||
{
|
{
|
||||||
PROP_STRING_PARM(str, 0);
|
PROP_STRING_PARM(str, 0);
|
||||||
if (!stricmp(str, "") || !stricmp(str, "none")) defaults->TeleFogSourceType = NULL;
|
|
||||||
else defaults->TeleFogSourceType = FindClassTentative(str, RUNTIME_CLASS(AActor));
|
defaults->TeleFogSourceType = FindClassTentative(str, RUNTIME_CLASS(AActor));
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1458,8 +1458,8 @@ DEFINE_PROPERTY(telefogsourcetype, S, Actor)
|
||||||
DEFINE_PROPERTY(telefogdesttype, S, Actor)
|
DEFINE_PROPERTY(telefogdesttype, S, Actor)
|
||||||
{
|
{
|
||||||
PROP_STRING_PARM(str, 0);
|
PROP_STRING_PARM(str, 0);
|
||||||
if (!stricmp(str, "") || !stricmp(str, "none")) defaults->TeleFogDestType = NULL;
|
|
||||||
else defaults->TeleFogDestType = FindClassTentative(str, RUNTIME_CLASS(AActor));
|
defaults->TeleFogDestType = FindClassTentative(str, RUNTIME_CLASS(AActor));
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
Loading…
Reference in a new issue