From caf0ab581d5f26c05437ded618d506edefba11f4 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 30 Jun 2024 10:28:01 -0400 Subject: [PATCH] Item deposit cooldown rule (default: 0.5 sec) --- core/src/mindustry/entities/comp/PlayerComp.java | 1 + core/src/mindustry/game/Rules.java | 2 ++ core/src/mindustry/graphics/OverlayRenderer.java | 4 +++- core/src/mindustry/input/InputHandler.java | 11 ++++++++++- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/entities/comp/PlayerComp.java b/core/src/mindustry/entities/comp/PlayerComp.java index 50ce197306..f970cfe23b 100644 --- a/core/src/mindustry/entities/comp/PlayerComp.java +++ b/core/src/mindustry/entities/comp/PlayerComp.java @@ -47,6 +47,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra transient float deathTimer; transient String lastText = ""; transient float textFadeTime; + transient Ratekeeper itemDepositRate = new Ratekeeper(); transient private Unit lastReadUnit = Nulls.unit; transient private int wrongReadUnits; diff --git a/core/src/mindustry/game/Rules.java b/core/src/mindustry/game/Rules.java index e2850f0124..bd405c793e 100644 --- a/core/src/mindustry/game/Rules.java +++ b/core/src/mindustry/game/Rules.java @@ -107,6 +107,8 @@ public class Rules{ public boolean cleanupDeadTeams = true; /** If true, items can only be deposited in the core. */ public boolean onlyDepositCore = false; + /** Cooldown, in seconds, of item depositing for players. */ + public float itemDepositCooldown = 0.5f; /** If true, every enemy block in the radius of the (enemy) core is destroyed upon death. Used for campaign maps. */ public boolean coreDestroyClear = false; /** If true, banned blocks are hidden from the build menu. */ diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index b9dc661054..8346eb94d6 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -241,7 +241,9 @@ public class OverlayRenderer{ Draw.reset(); Building build = world.buildWorld(v.x, v.y); - if(input.canDropItem() && build != null && build.interactable(player.team()) && build.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(build, itemTransferRange)){ + if(input.canDropItem() && build != null && build.interactable(player.team()) && build.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(build, itemTransferRange) && + input.itemDepositCooldown <= 0f){ + boolean invalid = (state.rules.onlyDepositCore && !(build instanceof CoreBuild)); Lines.stroke(3f, Pal.gray); diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index b280a958be..a23af33bb1 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -83,6 +83,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ public boolean overrideLineRotation; public int rotation; public boolean droppingItem; + public float itemDepositCooldown; public Group uiGroup; public boolean isBuilding = true, buildWasAutoPaused = false, wasShooting = false; public @Nullable UnitType controlledType; @@ -142,6 +143,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ Events.on(ResetEvent.class, e -> { logicCutscene = false; + itemDepositCooldown = 0f; Arrays.fill(controlGroups, null); }); } @@ -423,6 +425,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ if(player == null || build == null || !player.within(build, itemTransferRange) || build.items == null || player.dead() || (state.rules.onlyDepositCore && !(build instanceof CoreBuild))) return; if(net.server() && (player.unit().stack.amount <= 0 || !Units.canInteract(player, build) || + //to avoid rejecting deposit packets that happen to overlap due to packet speed differences, the actual cap is double the cooldown with 2 deposits. + (!player.isLocal() && !player.itemDepositRate.allow((long)(state.rules.itemDepositCooldown * 1000 * 2), 2)) || + !netServer.admins.allowAction(player, ActionType.depositItem, build.tile, action -> { action.itemAmount = player.unit().stack.amount; action.item = player.unit().item(); @@ -796,6 +801,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ logicCutsceneZoom = -1f; } + itemDepositCooldown -= Time.delta / 60f; + commandBuildings.removeAll(b -> !b.isValid()); if(!commandMode){ @@ -1859,8 +1866,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ if(build != null && build.acceptStack(stack.item, stack.amount, player.unit()) > 0 && build.interactable(player.team()) && build.block.hasItems && player.unit().stack().amount > 0 && build.interactable(player.team())){ - if(!(state.rules.onlyDepositCore && !(build instanceof CoreBuild))){ + + if(!(state.rules.onlyDepositCore && !(build instanceof CoreBuild)) && itemDepositCooldown <= 0f){ Call.transferInventory(player, build); + itemDepositCooldown = state.rules.itemDepositCooldown; } }else{ Call.dropItem(player.angleTo(x, y));