diff --git a/client/src/playback/Actions.ts b/client/src/playback/Actions.ts index ced8d666..643df838 100644 --- a/client/src/playback/Actions.ts +++ b/client/src/playback/Actions.ts @@ -189,12 +189,19 @@ export const ACTION_DEFINITIONS: Record { - int action = RatNap.createRatNap(builder, grabberRobotID); + int action = RatNap.createRatNap(builder, nappedID); builder.addAction(action, Action.RatNap); }); } diff --git a/engine/src/main/battlecode/world/GameWorld.java b/engine/src/main/battlecode/world/GameWorld.java index 68351553..cfda5e5a 100644 --- a/engine/src/main/battlecode/world/GameWorld.java +++ b/engine/src/main/battlecode/world/GameWorld.java @@ -509,14 +509,15 @@ public void spawnCheese(CheeseMine mine) { // corresponding one if (spawn) { - addCheese(ogSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT); - addCheese(pairedSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT); mine.setLastRound(this.currentRound); pairedMine.setLastRound(this.currentRound); matchMaker.addCheeseSpawnAction(ogSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT + this.getCheeseAmount(ogSpawnLoc)); matchMaker.addCheeseSpawnAction(pairedSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT + this.getCheeseAmount(pairedSpawnLoc)); + + addCheese(ogSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT); + addCheese(pairedSpawnLoc, GameConstants.CHEESE_SPAWN_AMOUNT); } } diff --git a/engine/src/main/battlecode/world/InternalRobot.java b/engine/src/main/battlecode/world/InternalRobot.java index c1e8a4d4..2ab99aeb 100644 --- a/engine/src/main/battlecode/world/InternalRobot.java +++ b/engine/src/main/battlecode/world/InternalRobot.java @@ -585,7 +585,7 @@ public void bite(MapLocation loc, int cheeseConsumed) { if (cheeseConsumed > 0) { this.addCheese(-cheeseConsumed); - damage += (int) Math.ceil(Math.log(cheeseConsumed)); + damage += (int) Math.ceil(Math.sqrt(cheeseConsumed)); } targetRobot.addHealth(-damage); @@ -617,7 +617,7 @@ public void scratch(MapLocation loc) { public void grabRobot(MapLocation loc) { this.robotBeingCarried = this.gameWorld.getRobot(loc); this.robotBeingCarried.getGrabbed(this); // Notify the grabbed robot that it has been picked up - this.gameWorld.getMatchMaker().addRatNapAction(this.getID()); + this.gameWorld.getMatchMaker().addRatNapAction(this.robotBeingCarried.getID()); if (this.robotBeingCarried.getTeam() != this.getTeam()) { this.gameWorld.isCooperation = false; @@ -650,11 +650,10 @@ private void swapGrabber() { this.gameWorld.removeRobot(dropLoc); this.gameWorld.addRobot(dropLoc, this); - this.gameWorld.getMatchMaker().addRatNapAction(this.ID); + this.gameWorld.getMatchMaker().addRatNapAction(this.ID); // expand this rat + this.gameWorld.getMatchMaker().addRatNapAction(grabber.ID); // shrink carrier rat - if (grabber.getTeam() != this.getTeam()) { - grabber.remainingCarriedDuration = GameConstants.MAX_CARRY_DURATION; - } + grabber.remainingCarriedDuration = GameConstants.MAX_CARRY_DURATION; } private void getGrabbed(InternalRobot grabber) { @@ -668,9 +667,7 @@ private void getGrabbed(InternalRobot grabber) { this.setInternalLocationOnly(grabber.getLocation()); - if (grabber.getTeam() != this.getTeam()) { - this.remainingCarriedDuration = GameConstants.MAX_CARRY_DURATION; - } + this.remainingCarriedDuration = GameConstants.MAX_CARRY_DURATION; } @@ -688,18 +685,11 @@ private void getThrown(Direction dir) { this.thrownDir = dir; this.remainingThrowDuration = 4; - MapLocation nextLoc = this.getLocation().add(dir); + this.setInternalLocationOnly(this.getLocation()); + this.gameWorld.removeRobot(this.getLocation()); - // Cat feeding! - if (this.gameWorld.getRobot(nextLoc) != null) { // there's a cat here - this.addHealth(-this.getHealth()); // rat dies :( - // put cat to sleep - this.gameWorld.getRobot(nextLoc).sleepTimeRemaining = GameConstants.CAT_SLEEP_TIME; - this.gameWorld.getMatchMaker().addCatFeedAction(this.getID()); - } else { - this.setInternalLocationOnly(this.getLocation().add(dir)); - this.gameWorld.removeRobot(this.getLocation()); - } + this.travelFlying(true); + this.travelFlying(false); } public void getDropped(MapLocation loc) { @@ -714,6 +704,8 @@ public void getDropped(MapLocation loc) { this.grabbedByRobot = null; this.remainingCarriedDuration = 0; this.setInternalLocationOnly(loc); + + this.gameWorld.getMatchMaker().addRatNapAction(this.getID()); if (this.getHealth() > 0) this.gameWorld.addRobot(this.getLocation(), this); @@ -729,6 +721,8 @@ public void hitGround() { this.addHealth(-damage); this.gameWorld.getMatchMaker().addDamageAction(this.ID, damage); + this.gameWorld.getMatchMaker().addRatNapAction(this.getID()); + if (this.health > 0) { this.gameWorld.addRobot(this.location, this); @@ -760,6 +754,7 @@ public void hitTarget(boolean isSecondMove) { setActionCooldownTurns(this.actionCooldownTurns + GameConstants.HIT_TARGET_COOLDOWN); setTurningCooldownTurns(this.turningCooldownTurns + GameConstants.HIT_TARGET_COOLDOWN); this.gameWorld.getMatchMaker().addDamageAction(this.ID, damage); + this.gameWorld.getMatchMaker().addRatNapAction(this.getID()); this.gameWorld.getMatchMaker().addStunAction(this.ID, GameConstants.HIT_TARGET_COOLDOWN); } @@ -1053,8 +1048,7 @@ public void processBeginningOfTurn() { this.gameWorld.runCheeseMines(); // if rat is being carried - if (this.getType() == UnitType.BABY_RAT && this.isGrabbedByRobot() - && this.getGrabbedByRobot().getTeam() != this.getTeam()) { + if (this.getType() == UnitType.BABY_RAT && this.isGrabbedByRobot()) { // check if grabber has died if (this.getGrabbedByRobot().getHealth() <= 0) { diff --git a/engine/src/main/battlecode/world/RobotControllerImpl.java b/engine/src/main/battlecode/world/RobotControllerImpl.java index 3c753c63..07c7bc33 100644 --- a/engine/src/main/battlecode/world/RobotControllerImpl.java +++ b/engine/src/main/battlecode/world/RobotControllerImpl.java @@ -950,12 +950,14 @@ private void assertCanAttackRat(MapLocation loc, int cheeseConsumed) throws Game assertIsActionReady(); // Attack is limited to vision radius assertCanActLocation(loc, this.getType().getVisionRadiusSquared()); + if (!this.getLocation().isAdjacentTo(loc)) { throw new GameActionException(CANT_DO_THAT, "Rats can only attack adjacent squares!"); } - if (!this.gameWorld.isPassable(loc)) + if (!this.gameWorld.isPassable(loc)) { throw new GameActionException(CANT_DO_THAT, "Rats cannot attack squares with walls or dirt on them!"); + } if (this.gameWorld.getTeamInfo().getCheese(this.getTeam()) + this.getAllCheese() < cheeseConsumed) { throw new GameActionException(CANT_DO_THAT, "Not enough cheese to bite!"); @@ -964,13 +966,29 @@ private void assertCanAttackRat(MapLocation loc, int cheeseConsumed) throws Game if (this.getType() == UnitType.CAT) { throw new GameActionException(CANT_DO_THAT, "Unit must be a baby rat or rat king to bite!"); } + + if (cheeseConsumed < 0) { + throw new GameActionException(CANT_DO_THAT, "Cheese consumed must be non-negative!"); + } + + if (this.gameWorld.getRobot(loc) == null) { + throw new GameActionException(CANT_DO_THAT, "No robot to attack at the specified location!"); + } } private void assertCanAttackCat(MapLocation loc) throws GameActionException { assertIsActionReady(); assertCanActLocation(loc, this.getType().getVisionRadiusSquared()); - if (!this.gameWorld.isPassable(loc)) + + if (!this.gameWorld.isPassable(loc)) { throw new GameActionException(CANT_DO_THAT, "Cats cannot attack squares with walls or dirt on them!"); + } + if (this.gameWorld.getRobot(loc) == null) { + throw new GameActionException(CANT_DO_THAT, "No robot to attack at the specified location!"); + } + if (this.gameWorld.getRobot(loc) != null && this.gameWorld.getRobot(loc).getID() == this.robot.getID()) { + throw new GameActionException(CANT_DO_THAT, "Cannot attack self"); + } } private void assertCanAttack(MapLocation loc, int cheeseConsumed) throws GameActionException { @@ -1316,7 +1334,7 @@ public void assertCanCarryRat(MapLocation loc) throws GameActionException { } // adjacency - if (!loc.isAdjacentTo(this.getLocation())) { + if (!loc.isAdjacentTo(this.getLocation()) && !this.getLocation().equals(loc)) { throw new GameActionException(CANT_DO_THAT, "A rat can only grab adjacent robots!"); }