From 19917f14145043f7458a19ad310dd7383e78dd41 Mon Sep 17 00:00:00 2001 From: Jasper Geurtz Date: Sat, 31 Oct 2026 12:40:26 +0100 Subject: [PATCH 1/8] fix BuildingPlacer division before substraction and default case fallthrough bugs --- src/main/java/bwapi/BuildingPlacer.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/bwapi/BuildingPlacer.java b/src/main/java/bwapi/BuildingPlacer.java index 0aaaa9a4..549e9796 100644 --- a/src/main/java/bwapi/BuildingPlacer.java +++ b/src/main/java/bwapi/BuildingPlacer.java @@ -244,8 +244,7 @@ private static void ReserveAllStructures(final PlacementReserve reserve, final U } private static void ReserveExistingAddonPlacement(final PlacementReserve reserve, final TilePosition desiredPosition, final Game game) { - final TilePosition start = desiredPosition.subtract(new TilePosition(MAX_RANGE, MAX_RANGE)).divide(2); - + final TilePosition start = desiredPosition.subtract(new TilePosition(MAX_RANGE, MAX_RANGE).divide(2)); //Exclude addon placement locations reserve.backup(); game.self().getUnits().stream() @@ -274,15 +273,14 @@ private static void ReserveDefault(final PlacementReserve reserve, final UnitTyp case Terran_Missile_Turret: case Protoss_Robotics_Facility: case Protoss_Gateway: - case Protoss_Photon_Cannon: + default: + ReserveStructure(reserve, it, 2, type, desiredPosition); + break; case Terran_Barracks: case Terran_Bunker: case Zerg_Creep_Colony: ReserveStructure(reserve, it, 1, type, desiredPosition); break; - default: - ReserveStructure(reserve, it, 2, type, desiredPosition); - break; } } From d0fd63e01404579203e10c30863bdbf0434803f4 Mon Sep 17 00:00:00 2001 From: Jasper Geurtz Date: Sat, 31 Oct 2026 12:56:55 +0100 Subject: [PATCH 2/8] nit: IsTransport should not have capitalized P, keep for backwards compat --- src/main/java/bwapi/UnitFilter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/bwapi/UnitFilter.java b/src/main/java/bwapi/UnitFilter.java index a50c2533..3dfe3e13 100644 --- a/src/main/java/bwapi/UnitFilter.java +++ b/src/main/java/bwapi/UnitFilter.java @@ -3,7 +3,9 @@ import java.util.function.Predicate; public interface UnitFilter extends Predicate { - UnitFilter IsTransPort = u -> u.getType().spaceProvided() > 0 && u.getType() != UnitType.Terran_Bunker; + UnitFilter IsTransport = u -> u.getType().spaceProvided() > 0 && u.getType() != UnitType.Terran_Bunker; + @Deprecated // backwards compatible + UnitFilter IsTransPort = IsTransport; UnitFilter CanProduce = u -> u.getType().canProduce(); UnitFilter CanAttack = u -> u.getType().canAttack(); UnitFilter CanMove = u -> u.getType().canMove(); From 27226c139f7817099d59bed49b2067a84707cf40 Mon Sep 17 00:00:00 2001 From: Jasper Geurtz Date: Sat, 31 Oct 2026 13:17:01 +0100 Subject: [PATCH 3/8] setMap should return false on empty mapFileName not throw --- src/main/java/bwapi/Game.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/bwapi/Game.java b/src/main/java/bwapi/Game.java index 17a5a3ca..336cdcad 100644 --- a/src/main/java/bwapi/Game.java +++ b/src/main/java/bwapi/Game.java @@ -2380,10 +2380,9 @@ public int getLastEventTime() { * parameter. */ final public boolean setMap(final String mapFileName) { - if (mapFileName == null || mapFileName.length() >= 260 || mapFileName.charAt(0) == 0) { + if (mapFileName == null || mapFileName.isEmpty() || mapFileName.length() >= 260 || mapFileName.charAt(0) == 0) { return false; } - addCommand(CommandType.SetMap, mapFileName, 0); return true; } From b514493167b2a803cbda525a0aff637e4e9d0f5e Mon Sep 17 00:00:00 2001 From: Jasper Geurtz Date: Sat, 31 Oct 2026 13:37:46 +0100 Subject: [PATCH 4/8] fix getUnitX conditions --- src/main/java/bwapi/Game.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/bwapi/Game.java b/src/main/java/bwapi/Game.java index 336cdcad..9ea1034e 100644 --- a/src/main/java/bwapi/Game.java +++ b/src/main/java/bwapi/Game.java @@ -680,10 +680,12 @@ public List getUnitsOnTile(final int tileX, final int tileY) { * given build tile. */ public List getUnitsOnTile(final int tileX, final int tileY, final UnitFilter pred) { - return getAllUnits().stream().filter(u -> { - final TilePosition tp = u.getTilePosition(); - return tp.x == tileX && tp.y == tileY && pred.test(u); - }).collect(Collectors.toList()); + final TilePosition tile = new TilePosition(tileX, tileY); + if (!tile.isValid(this)) { + return Collections.emptyList(); + } + final Position p = tile.toPosition(); + return getUnitsInRectangle(p.x, p.y, p.x + 32, p.y + 32, pred); } public List getUnitsInRectangle(final int left, final int top, final int right, final int bottom) { @@ -740,7 +742,7 @@ public List getUnitsInRadius(final Position center, final int radius) { public List getUnitsInRadius(final Position center, final int radius, final UnitFilter pred) { return getAllUnits().stream() - .filter(u -> center.getApproxDistance(u.getPosition()) <= radius && pred.test(u)) + .filter(u -> u.getDistance(center) <= radius && pred.test(u)) .collect(Collectors.toList()); } From d5367bb24a2f941cc3f6dbec16b510264e58198b Mon Sep 17 00:00:00 2001 From: Jasper Geurtz Date: Sat, 31 Oct 2026 13:44:05 +0100 Subject: [PATCH 5/8] fix getUnitsInWeaponRange boolean condition --- src/main/java/bwapi/Unit.java | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/main/java/bwapi/Unit.java b/src/main/java/bwapi/Unit.java index 9c9ee612..1ba81783 100644 --- a/src/main/java/bwapi/Unit.java +++ b/src/main/java/bwapi/Unit.java @@ -1301,30 +1301,28 @@ public List getUnitsInWeaponRange(final WeaponType weapon, final UnitFilte getRight() + max, getBottom() + max, u -> { - if (!pred.test(u)) { - return false; - } // Unit check and unit status if (u == this || u.isInvincible()) { return false; } - // Weapon distance check final int dist = getDistance(u); if ((weapon.minRange() != 0 && dist < weapon.minRange()) || dist > max) { return false; } - // Weapon behavioural checks final UnitType ut = u.getType(); - return (!weapon.targetsOwn() || u.getPlayer().equals(getPlayer())) && - (weapon.targetsAir() || u.isFlying()) && - (weapon.targetsGround() || !u.isFlying()) && - (!weapon.targetsMechanical() || !ut.isMechanical()) && - (!weapon.targetsOrganic() || !ut.isOrganic()) && - (!weapon.targetsNonBuilding() || ut.isBuilding()) && - (!weapon.targetsNonRobotic() || ut.isRobotic()) && - (!weapon.targetsOrgOrMech() || (!ut.isOrganic() && !ut.isMechanical())); + if ((weapon.targetsOwn() && !u.getPlayer().equals(getPlayer())) || + (!weapon.targetsAir() && !u.isFlying()) || + (!weapon.targetsGround() && u.isFlying()) || + (weapon.targetsMechanical() && ut.isMechanical()) || + (weapon.targetsOrganic() && ut.isOrganic()) || + (weapon.targetsNonBuilding() && !ut.isBuilding()) || + (weapon.targetsNonRobotic() && !ut.isRobotic()) || + (weapon.targetsOrgOrMech() && (ut.isOrganic() || ut.isMechanical()))) { + return false; + } + return pred.test(u); }); } From b4649214bef25a554cc439cc5faec68531fc6bb6 Mon Sep 17 00:00:00 2001 From: Jasper Geurtz Date: Sat, 31 Oct 2026 14:11:37 +0100 Subject: [PATCH 6/8] fix player color --- src/main/java/bwapi/Player.java | 4 ++-- src/main/java/bwapi/Unit.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/bwapi/Player.java b/src/main/java/bwapi/Player.java index a2cd0ca0..57b27b50 100644 --- a/src/main/java/bwapi/Player.java +++ b/src/main/java/bwapi/Player.java @@ -551,7 +551,7 @@ public Text getTextColor() { return Text.Blue; case 159: // teal return Text.Teal; - case 164: // purp + case 164: // purple return Text.Purple; case 156: // orange with fix from @n00byEdge return Text.Orange; @@ -561,7 +561,7 @@ public Text getTextColor() { return Text.PlayerWhite; case 135: // yellow return Text.PlayerYellow; - case 185: // green p9 + case 117: // green return Text.DarkGreen; case 136: // p10 return Text.LightYellow; diff --git a/src/main/java/bwapi/Unit.java b/src/main/java/bwapi/Unit.java index 1ba81783..57a29c9c 100644 --- a/src/main/java/bwapi/Unit.java +++ b/src/main/java/bwapi/Unit.java @@ -4685,7 +4685,7 @@ public boolean canGather(Unit targetUnit, boolean checkCanTargetUnit, boolean ch return false; } - if (!hasPath(getPosition())) { + if (!hasPath(targetUnit.getPosition())) { return false; } @@ -6135,7 +6135,7 @@ public boolean canUseTechUnit(TechType tech, Unit targetUnit, boolean checkCanTa if (!targetType.isOrganic() || targetType.isFlyer()) { return false; } - if (!targetUnit.getPlayer().isNeutral() && getPlayer().isEnemy(getPlayer())) { + if (!targetUnit.getPlayer().isNeutral() && getPlayer().isEnemy(targetUnit.getPlayer())) { return false; } break; From b50dc42ddd81b80c0862450098c8856125e20a85 Mon Sep 17 00:00:00 2001 From: Jasper Geurtz Date: Sun, 1 Nov 2026 21:01:50 +0100 Subject: [PATCH 7/8] Exclude self from units in radius --- src/main/java/bwapi/Unit.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bwapi/Unit.java b/src/main/java/bwapi/Unit.java index 57a29c9c..84b6db06 100644 --- a/src/main/java/bwapi/Unit.java +++ b/src/main/java/bwapi/Unit.java @@ -1270,7 +1270,7 @@ public List getUnitsInRadius(final int radius, final UnitFilter pred) { getTop() - radius, getRight() + radius, getBottom() + radius, - u -> getDistance(u) <= radius && pred.test(u)); + u -> u != this && getDistance(u) <= radius && pred.test(u)); } public List getUnitsInWeaponRange(final WeaponType weapon) { From 687dc8a44df6d0f7418f07651c2d379f08db1d6f Mon Sep 17 00:00:00 2001 From: Jasper Geurtz Date: Sun, 1 Nov 2026 21:28:20 +0100 Subject: [PATCH 8/8] Fix more unit vs targetUnit bugs --- src/main/java/bwapi/Unit.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/bwapi/Unit.java b/src/main/java/bwapi/Unit.java index 84b6db06..97cc01d2 100644 --- a/src/main/java/bwapi/Unit.java +++ b/src/main/java/bwapi/Unit.java @@ -3877,7 +3877,7 @@ public boolean canAttackUnitGrouped(Unit targetUnit, boolean checkCanTargetUnit, return false; } - if (isInvincible()) { + if (targetUnit.isInvincible()) { return false; } @@ -4688,9 +4688,7 @@ public boolean canGather(Unit targetUnit, boolean checkCanTargetUnit, boolean ch if (!hasPath(targetUnit.getPosition())) { return false; } - - return !uType.isRefinery() || getPlayer().equals(game.self()); - + return !targetUnit.getType().isRefinery() || targetUnit.getPlayer().equals(game.self()); } public boolean canReturnCargo() {