diff --git a/robocode.battle/src/main/java/net/sf/robocode/battle/peer/RobotPeer.java b/robocode.battle/src/main/java/net/sf/robocode/battle/peer/RobotPeer.java index bbc88b6aa..404133bfd 100644 --- a/robocode.battle/src/main/java/net/sf/robocode/battle/peer/RobotPeer.java +++ b/robocode.battle/src/main/java/net/sf/robocode/battle/peer/RobotPeer.java @@ -856,6 +856,12 @@ private void fireBullets(List bulletCommands) { println("SYSTEM: You cannot call fire(NaN)"); continue; } + // Skip commands that have already fired: the command list is shared + // across turns, so a robot that stops executing would otherwise + // re-fire the same command (and its bullet id) on every cooldown. + if (bulletCmd.isConsumed()) { + continue; + } if (gunHeat > 0 || energy == 0) { return; } @@ -877,6 +883,9 @@ private void fireBullets(List bulletCommands) { } newBullet.setX(x); newBullet.setY(y); + + // Mark consumed so this command cannot fire again on a later cooldown. + bulletCmd.consume(); } // there is only last bullet in one turn if (newBullet != null) { diff --git a/robocode.core/src/main/java/net/sf/robocode/peer/BulletCommand.java b/robocode.core/src/main/java/net/sf/robocode/peer/BulletCommand.java index 22482aa08..dcfa5558a 100644 --- a/robocode.core/src/main/java/net/sf/robocode/peer/BulletCommand.java +++ b/robocode.core/src/main/java/net/sf/robocode/peer/BulletCommand.java @@ -33,6 +33,19 @@ public BulletCommand(double power, boolean fireAssistValid, double fireAssistAng private final double fireAssistAngle; private final int bulletId; + // Battle-side only: marks that this command has already fired a bullet, so it + // is not fired again on a later cooldown when the command list persists across + // turns (e.g. after the robot stops executing). Not part of the wire format. + private transient boolean consumed; + + public boolean isConsumed() { + return consumed; + } + + public void consume() { + consumed = true; + } + public boolean isFireAssistValid() { return fireAssistValid; }