- scriptified FilterCoopRespawnInventory.

This commit is contained in:
Christoph Oelckers 2018-11-24 20:58:33 +01:00
parent c14b7f58d3
commit 3d892d3970
6 changed files with 124 additions and 125 deletions

View file

@ -101,8 +101,7 @@ public:
AWeapon *PickNewWeapon (PClassActor *ammotype);
AWeapon *BestWeapon (PClassActor *ammotype);
void GiveDeathmatchInventory ();
void FilterCoopRespawnInventory (APlayerPawn *oldplayer);
void GiveDefaultInventory ();
// These are virtual on the script side only.

View file

@ -597,8 +597,9 @@ class CommandDrawSwitchableImage : public CommandDrawImage
auto armor = statusBar->CPlayer->mo->FindInventory(NAME_BasicArmor);
if(armor != NULL)
{
bool matches1 = armor->NameVar(NAME_ArmorType).GetIndex() == armorType[0] && EvaluateOperation(conditionalOperator[0], conditionalValue[0], armor->Amount);
bool matches2 = armor->NameVar(NAME_ArmorType).GetIndex() == armorType[1] && EvaluateOperation(conditionalOperator[1], conditionalValue[1], armor->Amount);
auto n = armor->NameVar(NAME_ArmorType).GetIndex();
bool matches1 = n == armorType[0] && EvaluateOperation(conditionalOperator[0], conditionalValue[0], armor->Amount);
bool matches2 = n == armorType[1] && EvaluateOperation(conditionalOperator[1], conditionalValue[1], armor->Amount);
drawAlt = 1;
if(conditionAnd)

View file

@ -1071,6 +1071,12 @@ void AActor::DestroyAllInventory ()
}
}
DEFINE_ACTION_FUNCTION(AActor, DestroyAllInventory)
{
PARAM_SELF_PROLOGUE(AActor);
self->DestroyAllInventory();
return 0;
}
//============================================================================
//
// AActor :: FirstInv
@ -5711,7 +5717,11 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
else if ((multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN) || sv_singleplayerrespawn ||
!!G_SkillProperty(SKILLP_PlayerRespawn)) && state == PST_REBORN && oldactor != NULL)
{ // Special inventory handling for respawning in coop
p->mo->FilterCoopRespawnInventory (oldactor);
IFVM(PlayerPawn, FilterCoopRespawnInventory)
{
VMValue params[] = { p->mo, oldactor };
VMCall(func, params, 2, nullptr, 0);
}
}
if (oldactor != NULL)
{ // Remove any inventory left from the old actor. Coop handles

View file

@ -1092,125 +1092,6 @@ void APlayerPawn::GiveDeathmatchInventory()
}
}
//===========================================================================
//
// APlayerPawn :: FilterCoopRespawnInventory
//
// When respawning in coop, this function is called to walk through the dead
// player's inventory and modify it according to the current game flags so
// that it can be transferred to the new live player. This player currently
// has the default inventory, and the oldplayer has the inventory at the time
// of death.
//
//===========================================================================
void APlayerPawn::FilterCoopRespawnInventory (APlayerPawn *oldplayer)
{
AInventory *item, *next, *defitem;
// If we're losing everything, this is really simple.
if (dmflags & DF_COOP_LOSE_INVENTORY)
{
oldplayer->DestroyAllInventory();
return;
}
if (dmflags & (DF_COOP_LOSE_KEYS |
DF_COOP_LOSE_WEAPONS |
DF_COOP_LOSE_AMMO |
DF_COOP_HALVE_AMMO |
DF_COOP_LOSE_ARMOR |
DF_COOP_LOSE_POWERUPS))
{
// Walk through the old player's inventory and destroy or modify
// according to dmflags.
for (item = oldplayer->Inventory; item != NULL; item = next)
{
next = item->Inventory;
// If this item is part of the default inventory, we never want
// to destroy it, although we might want to copy the default
// inventory amount.
defitem = FindInventory (item->GetClass());
if ((dmflags & DF_COOP_LOSE_KEYS) &&
defitem == NULL &&
item->IsKindOf(NAME_Key))
{
item->Destroy();
}
else if ((dmflags & DF_COOP_LOSE_WEAPONS) &&
defitem == NULL &&
item->IsKindOf(NAME_Weapon))
{
item->Destroy();
}
else if ((dmflags & DF_COOP_LOSE_ARMOR) &&
item->IsKindOf(NAME_Armor))
{
if (defitem == NULL)
{
item->Destroy();
}
else if (item->IsKindOf(NAME_BasicArmor))
{
item->IntVar(NAME_SavePercent) = defitem->IntVar(NAME_SavePercent);
item->Amount = defitem->Amount;
}
else if (item->IsKindOf(NAME_HexenArmor))
{
double *SlotsTo = (double*)item->ScriptVar(NAME_Slots, nullptr);
double *SlotsFrom = (double*)defitem->ScriptVar(NAME_Slots, nullptr);
memcpy(SlotsTo, SlotsFrom, 4 * sizeof(double));
}
}
else if ((dmflags & DF_COOP_LOSE_POWERUPS) &&
defitem == NULL &&
item->IsKindOf(NAME_PowerupGiver))
{
item->Destroy();
}
else if ((dmflags & (DF_COOP_LOSE_AMMO | DF_COOP_HALVE_AMMO)) &&
item->IsKindOf(NAME_Ammo))
{
if (defitem == NULL)
{
if (dmflags & DF_COOP_LOSE_AMMO)
{
// Do NOT destroy the ammo, because a weapon might reference it.
item->Amount = 0;
}
else if (item->Amount > 1)
{
item->Amount /= 2;
}
}
else
{
// When set to lose ammo, you get to keep all your starting ammo.
// When set to halve ammo, you won't be left with less than your starting amount.
if (dmflags & DF_COOP_LOSE_AMMO)
{
item->Amount = defitem->Amount;
}
else if (item->Amount > 1)
{
item->Amount = MAX(item->Amount / 2, defitem->Amount);
}
}
}
}
}
// Now destroy the default inventory this player is holding and move
// over the old player's remaining inventory.
DestroyAllInventory();
ObtainInventory (oldplayer);
player->ReadyWeapon = NULL;
PickNewWeapon (NULL);
}
//===========================================================================
//
// APlayerPawn :: GetSoundClass
@ -1350,7 +1231,7 @@ void APlayerPawn::GiveDefaultInventory ()
VMCall(func, params, 1, nullptr, 0);
}
}
//===========================================================================
//
// A_PlayerScream

View file

@ -727,6 +727,7 @@ class Actor : Thinker native
native void AddInventory(Inventory inv);
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);

View file

@ -615,6 +615,113 @@ class PlayerPawn : Actor native
}
}
}
//===========================================================================
//
// APlayerPawn :: FilterCoopRespawnInventory
//
// When respawning in coop, this function is called to walk through the dead
// player's inventory and modify it according to the current game flags so
// that it can be transferred to the new live player. This player currently
// has the default inventory, and the oldplayer has the inventory at the time
// of death.
//
//===========================================================================
void FilterCoopRespawnInventory (PlayerPawn oldplayer)
{
// If we're losing everything, this is really simple.
if (sv_cooploseinventory)
{
oldplayer.DestroyAllInventory();
return;
}
// Walk through the old player's inventory and destroy or modify
// according to dmflags.
Inventory next;
for (Inventory item = oldplayer.Inv; item != NULL; item = next)
{
next = item.Inv;
// If this item is part of the default inventory, we never want
// to destroy it, although we might want to copy the default
// inventory amount.
let defitem = FindInventory (item.GetClass());
if (sv_cooplosekeys && defitem == NULL && item is 'Key')
{
item.Destroy();
}
else if (sv_cooploseweapons && defitem == NULL && item is 'Weapon')
{
item.Destroy();
}
else if (sv_cooplosearmor && item is 'Armor')
{
if (defitem == NULL)
{
item.Destroy();
}
else if (item is 'BasicArmor')
{
BasicArmor(item).SavePercent = BasicArmor(defitem).SavePercent;
item.Amount = defitem.Amount;
}
else if (item is 'HexenArmor')
{
let to = HexenArmor(item);
let from = HexenArmor(defitem);
to.Slots[0] = from.Slots[0];
to.Slots[1] = from.Slots[1];
to.Slots[2] = from.Slots[2];
to.Slots[3] = from.Slots[3];
}
}
else if (sv_cooplosepowerups && defitem == NULL && item is 'Powerup')
{
item.Destroy();
}
else if ((sv_cooploseammo || sv_coophalveammo) && item is 'Ammo')
{
if (defitem == NULL)
{
if (sv_cooploseammo)
{
// Do NOT destroy the ammo, because a weapon might reference it.
item.Amount = 0;
}
else if (item.Amount > 1)
{
item.Amount /= 2;
}
}
else
{
// When set to lose ammo, you get to keep all your starting ammo.
// When set to halve ammo, you won't be left with less than your starting amount.
if (sv_cooploseammo)
{
item.Amount = defitem.Amount;
}
else if (item.Amount > 1)
{
item.Amount = MAX(item.Amount / 2, defitem.Amount);
}
}
}
}
// Now destroy the default inventory this player is holding and move
// over the old player's remaining inventory.
DestroyAllInventory();
ObtainInventory (oldplayer);
player.ReadyWeapon = NULL;
PickNewWeapon (NULL);
}
//----------------------------------------------------------------------------
//
// PROC P_CheckFOV