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 c5680e05e..4108650a4 100644 --- a/wadsrc/static/zscript/actors/inventory/inventory.zs +++ b/wadsrc/static/zscript/actors/inventory/inventory.zs @@ -10,6 +10,7 @@ class Inventory : Actor const BLINKTHRESHOLD = (4*32); const BONUSADD = 6; + private bool bSharingItem; // Currently being shared (avoid infinite recursions). private bool pickedUp[MAXPLAYERS]; // If items are set to local, track who already picked it up. deprecated("3.7") private int ItemFlags; @@ -68,6 +69,7 @@ class Inventory : Actor flagdef AlwaysPickup: ItemFlags, 23; flagdef Unclearable: ItemFlags, 24; flagdef NeverLocal: ItemFlags, 25; + flagdef IsKeyItem: ItemFlags, 26; flagdef ForceRespawnInSurvival: none, 0; flagdef PickupFlash: none, 6; @@ -258,6 +260,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 @@ -650,6 +689,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; }