Improved key sharing functionality

Localized functionality to an inventory function so that any item can make use of sharing. Added flag to avoid infinite recursions. HandlePickup() will now also share keys (for more complete handling). PuzzleItems are now included in sharing.
This commit is contained in:
Boondorl 2024-01-28 18:04:04 -05:00
parent 1c7f195353
commit c3f26b5405
2 changed files with 46 additions and 22 deletions

View file

@ -33,6 +33,7 @@ class Key : Inventory
Default
{
+DONTGIB; // Don't disappear due to a crusher
+INVENTORY.ISKEYITEM;
Inventory.InterHubAmount 0;
Inventory.PickupSound "misc/k_pkup";
}
@ -59,28 +60,6 @@ class Key : Inventory
return false;
}
override void AttachToOwner(Actor other)
{
Super.AttachToOwner(other);
if (multiplayer && !deathmatch && sv_coopsharekeys)
{
for (int i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i])
{
let pmo = players[i].mo;
if (pmo == other)
continue;
if (!pmo.FindInventory(GetClass()))
pmo.GiveInventoryType(GetClass());
}
}
}
}
override bool ShouldStay ()
{
return !!multiplayer;
@ -127,6 +106,7 @@ class PuzzleItem : Inventory
{
+NOGRAVITY
+INVENTORY.INVBAR
+INVENTORY.ISKEYITEM
Inventory.DefMaxAmount;
Inventory.UseSound "PuzzleSuccess";
Inventory.PickupSound "misc/i_pkup";

View file

@ -10,6 +10,8 @@ class Inventory : Actor
const BLINKTHRESHOLD = (4*32);
const BONUSADD = 6;
private bool bSharingItem; // Currently being shared (avoid infinite recursions).
deprecated("3.7") private int ItemFlags;
Actor Owner; // Who owns this item? NULL if it's still a pickup.
int Amount; // Amount of item this instance has
@ -65,6 +67,7 @@ class Inventory : Actor
flagdef IsHealth: ItemFlags, 22;
flagdef AlwaysPickup: ItemFlags, 23;
flagdef Unclearable: ItemFlags, 24;
flagdef IsKeyItem: ItemFlags, 26;
flagdef ForceRespawnInSurvival: none, 0;
flagdef PickupFlash: none, 6;
@ -255,6 +258,43 @@ class Inventory : Actor
}
}
protected void ShareItemWithPlayers(Actor giver)
{
if (bSharingItem)
return;
class<Inventory> type = GetClass();
int skip = giver && giver.player ? giver.PlayerNumber() : -1;
for (int i; i < MAXPLAYERS; ++i)
{
if (!playerInGame[i] || i == skip)
continue;
let item = Inventory(Spawn(type));
if (!item)
continue;
item.bSharingItem = true;
if (!item.CallTryPickup(players[i].mo))
{
item.Destroy();
continue;
}
item.bSharingItem = false;
if (!bQuiet)
{
PlayPickupSound(players[i].mo);
if (!bNoScreenFlash && players[i].PlayerState != PST_DEAD)
players[i].BonusCount = BONUSADD;
}
}
if (!bQuiet && consoleplayer != skip)
PrintPickupMessage(true, PickupMessage());
}
//===========================================================================
//
// Inventory :: DoRespawn
@ -647,6 +687,10 @@ class Inventory : Actor
}
// [AA] Let the toucher do something with the item they've just received:
toucher.HasReceived(self);
// If the item can be shared, make sure every player gets a copy.
if (multiplayer && !deathmatch && sv_coopsharekeys && bIsKeyItem)
ShareItemWithPlayers(toucher);
}
return res, toucher;
}