From c3f26b540509ab449f8009e0046282e9ad923cca Mon Sep 17 00:00:00 2001 From: Boondorl Date: Sun, 28 Jan 2024 18:04:04 -0500 Subject: [PATCH] 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. --- .../zscript/actors/inventory/inv_misc.zs | 24 +--------- .../zscript/actors/inventory/inventory.zs | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/wadsrc/static/zscript/actors/inventory/inv_misc.zs b/wadsrc/static/zscript/actors/inventory/inv_misc.zs index 5fc4e3fe2..318d29491 100644 --- a/wadsrc/static/zscript/actors/inventory/inv_misc.zs +++ b/wadsrc/static/zscript/actors/inventory/inv_misc.zs @@ -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"; diff --git a/wadsrc/static/zscript/actors/inventory/inventory.zs b/wadsrc/static/zscript/actors/inventory/inventory.zs index ddcbb68be..343ce227a 100644 --- a/wadsrc/static/zscript/actors/inventory/inventory.zs +++ b/wadsrc/static/zscript/actors/inventory/inventory.zs @@ -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 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; }