Skip to content

Commit

Permalink
Merge branch 'master' into public-release
Browse files Browse the repository at this point in the history
  • Loading branch information
TheApplePieGod committed Jan 8, 2025
2 parents 9dcdf59 + d836ec1 commit 6c7f358
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 16 deletions.
2 changes: 2 additions & 0 deletions client/src/client-config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const DEFAULT_CONFIG = {
showAllRobotRadii: false,
showTimelineMarkers: true,
showHealthBars: true,
showPaintBars: false,
showPaintMarkers: true,
showMapXY: true,
enableFancyPaint: true,
Expand All @@ -28,6 +29,7 @@ const configDescription: Record<keyof ClientConfig, string> = {
showAllRobotRadii: 'Show all robot view and attack radii',
showTimelineMarkers: 'Show user-generated markers on the timeline',
showHealthBars: 'Show health bars below all robots',
showPaintBars: 'Show paint bars below all robots',
showPaintMarkers: 'Show paint markers created using mark()',
showMapXY: 'Show X,Y when hovering a tile',
enableFancyPaint: 'Enable fancy paint rendering',
Expand Down
2 changes: 1 addition & 1 deletion client/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const CLIENT_VERSION = '1.1.1'
export const CLIENT_VERSION = '1.2.0'
export const SPEC_VERSION = '1'
export const BATTLECODE_YEAR: number = 2025
export const MAP_SIZE_RANGE = {
Expand Down
18 changes: 18 additions & 0 deletions client/src/playback/Bodies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,9 @@ export class Body {
if (focused || config.showHealthBars) {
this.drawHealthBar(match, overlayCtx)
}
if (focused || config.showPaintBars) {
this.drawPaintBar(match, overlayCtx, config.showHealthBars)
}
}
}

Expand Down Expand Up @@ -435,6 +438,21 @@ export class Body {
ctx.fillRect(hpBarX, hpBarY, hpBarWidth * (this.hp / this.maxHp), hpBarHeight)
}

private drawPaintBar(match: Match, ctx: CanvasRenderingContext2D, healthVisible: boolean): void {
const dimension = match.currentRound.map.staticMap.dimension
const interpCoords = this.getInterpolatedCoords(match)
const renderCoords = renderUtils.getRenderCoords(interpCoords.x, interpCoords.y, dimension)
const paintBarWidth = 0.8
const paintBarHeight = 0.1
const paintBarYOffset = 0.4 + (healthVisible ? 0.11 : 0)
const paintBarX = renderCoords.x + 0.5 - paintBarWidth / 2
const paintBarY = renderCoords.y + 0.5 + paintBarYOffset
ctx.fillStyle = 'rgba(0,0,0,.3)'
ctx.fillRect(paintBarX, paintBarY, paintBarWidth, paintBarHeight)
ctx.fillStyle = '#c515ed'
ctx.fillRect(paintBarX, paintBarY, paintBarWidth * (this.paint / this.maxPaint), paintBarHeight)
}

protected drawLevel(match: Match, ctx: CanvasRenderingContext2D) {
if (this.level <= 1) return

Expand Down
9 changes: 9 additions & 0 deletions engine/src/main/battlecode/common/RobotController.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ public interface RobotController {
*/
int getMoney();

/**
* Alias for getMoney
*
* @return the amount of money this robot's team has
*
* @battlecode.doc.costlymethod
*/
int getChips();

/**
* Returns what UnitType this robot is.
*
Expand Down
10 changes: 5 additions & 5 deletions engine/src/main/battlecode/common/UnitType.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package battlecode.common;

public enum UnitType {
SOLDIER(200, 250, 5, 250, -1, 200, 10, 20, 20, -1, 0, 0),
SPLASHER(300, 400, 50, 150, -1, 300, 50, 9, -1, 50, 0, 0),
SOLDIER(200, 250, 5, 250, -1, 200, 10, 9, 20, -1, 0, 0),
SPLASHER(300, 400, 50, 150, -1, 300, 50, 8, -1, 50, 0, 0),
MOPPER(100, 300, 0, 50, -1, 100, 30, 2, -1, -1, 0, 0),

LEVEL_ONE_PAINT_TOWER(0, 25, 0, 1000, 1, 1000, 10, 9, 20, 10, 5, 0),
LEVEL_ONE_PAINT_TOWER(0, 100, 0, 1000, 1, 1000, 10, 9, 20, 10, 5, 0),
LEVEL_TWO_PAINT_TOWER(0, 250, 0, 1500, 2, 1000, 10, 9, 20, 10, 10, 0),
LEVEL_THREE_PAINT_TOWER(0, 500, 0, 2000, 3, 1000, 10, 9, 20, 10, 15, 0),

LEVEL_ONE_MONEY_TOWER(0, 25, 0, 1000, 1, 1000, 10, 9, 20, 10, 0, 10),
LEVEL_ONE_MONEY_TOWER(0, 100, 0, 1000, 1, 1000, 10, 9, 20, 10, 0, 10),
LEVEL_TWO_MONEY_TOWER(0, 250, 0, 1500, 2, 1000, 10, 9, 20, 10, 0, 15),
LEVEL_THREE_MONEY_TOWER(0, 500, 0, 2000, 3, 1000, 10, 9, 20, 10, 0, 20),

LEVEL_ONE_DEFENSE_TOWER(0, 25, 0, 2500, 1, 1000, 10, 20, 60, 30, 0, 0),
LEVEL_ONE_DEFENSE_TOWER(0, 100, 0, 2500, 1, 1000, 10, 20, 60, 30, 0, 0),
LEVEL_TWO_DEFENSE_TOWER(0, 250, 0, 3000, 2, 1000, 10, 20, 65, 35, 0, 0),
LEVEL_THREE_DEFENSE_TOWER(0, 500, 0, 3500, 3, 1000, 10, 20, 70, 40, 0, 0);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ battlecode/common/RobotController/getAllLocationsWithinRadiusSquared 100 tru
battlecode/common/RobotController/getHealth 1 true
battlecode/common/RobotController/getID 1 true
battlecode/common/RobotController/getPaint 1 true
battlecode/common/RobotController/getChips 1 true
battlecode/common/RobotController/getMoney 1 true
battlecode/common/RobotController/getType 1 true
battlecode/common/RobotController/getLocation 1 true
Expand Down
16 changes: 15 additions & 1 deletion engine/src/main/battlecode/world/GameMapIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public static LiveMap deserialize(battlecode.schema.GameMap raw, boolean teamsRe
int[] patternArray = new int[4];
for (int i = 0; i < wallArray.length; i++) {
wallArray[i] = raw.walls(i);
paintArray[i] = raw.paint(i);
paintArray[i] = possiblyReversePaint(raw.paint(i), teamsReversed);
}
for (int i = 0; i < patternArray.length; i++){
patternArray[i] = raw.paintPatterns(i);
Expand Down Expand Up @@ -294,6 +294,7 @@ public static int serialize(FlatBufferBuilder builder, LiveMap gameMap) {
bodyTypes.add(FlatHelpers.getRobotTypeFromUnitType(robot.type));
bodyLocsXs.add(robot.location.x);
bodyLocsYs.add(robot.location.y);
ruinArray[gameMap.locationToIndex(robot.location)] = true;
}

for (int i = 0; i < gameMap.getWidth() * gameMap.getHeight(); i++) {
Expand Down Expand Up @@ -365,6 +366,19 @@ private static void initInitialBodiesFromSchemaBodyTable(InitialBodyTable bodyTa
}
}

// No color = 0, Team A color 1 = 1, Team A color 2 = 2, Team B color 1 = 3, Team B color 2 = 4
private static byte possiblyReversePaint(byte originalPaint, boolean teamsReversed){
if (!teamsReversed)
return originalPaint;
switch (originalPaint){
case 1: return 3;
case 2: return 4;
case 3: return 1;
case 4: return 2;
default: return originalPaint;
}
}

private static int createSpawnActionsVector(FlatBufferBuilder builder, ArrayList<Integer> ids, ArrayList<Integer> xs, ArrayList<Integer> ys, ArrayList<Byte> teams, ArrayList<Byte> types){
InitialBodyTable.startSpawnActionsVector(builder, ids.size());
for (int i = 0; i < ids.size(); i++){
Expand Down
18 changes: 15 additions & 3 deletions engine/src/main/battlecode/world/GameWorld.java
Original file line number Diff line number Diff line change
Expand Up @@ -576,12 +576,24 @@ public int getTowerPattern(UnitType towerType) {
return this.patternArray[towerTypeToPatternIndex(towerType)];
}

public boolean isValidPatternCenter(MapLocation loc) {
return !(loc.x < GameConstants.PATTERN_SIZE / 2
public boolean isValidPatternCenter(MapLocation loc, boolean isTower) {
return (!(loc.x < GameConstants.PATTERN_SIZE / 2
|| loc.y < GameConstants.PATTERN_SIZE / 2
|| loc.x >= gameMap.getWidth() - (GameConstants.PATTERN_SIZE - 1) / 2
|| loc.y >= gameMap.getHeight() - (GameConstants.PATTERN_SIZE - 1) / 2
);
)) && (isTower || areaIsPaintable(loc)) ;
}

// checks that location has no walls/ruins in the surrounding 5x5 area
public boolean areaIsPaintable(MapLocation loc){
for (int dx = -GameConstants.PATTERN_SIZE / 2; dx < (GameConstants.PATTERN_SIZE + 1) / 2; dx++) {
for (int dy = -GameConstants.PATTERN_SIZE / 2; dy < (GameConstants.PATTERN_SIZE + 1) / 2; dy++) {
MapLocation newLoc = loc.translate(dx, dy);
if (!isPaintable(newLoc))
return false;
}
}
return true;
}

public boolean isPassable(MapLocation loc) {
Expand Down
38 changes: 32 additions & 6 deletions engine/src/main/battlecode/world/RobotControllerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ public int getMoney() {
return this.gameWorld.getTeamInfo().getMoney(getTeam());
}

@Override
public int getChips() {
return this.getMoney();
}

@Override
public UnitType getType(){
return this.robot.getType();
Expand Down Expand Up @@ -578,7 +583,7 @@ private void assertCanMarkTowerPattern(UnitType type, MapLocation loc) throws Ga
+ ") because the center is not a ruin");
}

if (!this.gameWorld.isValidPatternCenter(loc)) {
if (!this.gameWorld.isValidPatternCenter(loc, true)) {
throw new GameActionException(CANT_DO_THAT,
"Cannot mark tower pattern centered at (" + loc.x + ", " + loc.y
+ ") because it is too close to the edge of the map");
Expand Down Expand Up @@ -673,10 +678,10 @@ private void assertCanMarkResourcePattern(MapLocation loc) throws GameActionExce
assertIsRobotType(this.robot.getType());
assertCanActLocation(loc, GameConstants.RESOURCE_PATTERN_RADIUS_SQUARED);

if (!this.gameWorld.isValidPatternCenter(loc)) {
if (!this.gameWorld.isValidPatternCenter(loc, false)) {
throw new GameActionException(CANT_DO_THAT,
"Cannot mark resource pattern centered at (" + loc.x + ", " + loc.y
+ ") because it is too close to the edge of the map");
+ ") because it is blocked or too close to the edge of the map");
}

if (this.robot.getPaint() < GameConstants.MARK_PATTERN_PAINT_COST){
Expand Down Expand Up @@ -708,6 +713,20 @@ public void markResourcePattern(MapLocation loc, int rotationAngle, boolean refl
this.gameWorld.markResourcePattern(getTeam(), loc, rotationAngle, reflect);
}

private UnitType getBaseUnitType(UnitType type){
UnitType baseType;
switch (type){
case LEVEL_TWO_DEFENSE_TOWER: baseType = UnitType.LEVEL_ONE_DEFENSE_TOWER; break;
case LEVEL_THREE_DEFENSE_TOWER: baseType = UnitType.LEVEL_ONE_DEFENSE_TOWER; break;
case LEVEL_TWO_MONEY_TOWER: baseType = UnitType.LEVEL_ONE_MONEY_TOWER; break;
case LEVEL_THREE_MONEY_TOWER: baseType = UnitType.LEVEL_ONE_MONEY_TOWER; break;
case LEVEL_TWO_PAINT_TOWER: baseType = UnitType.LEVEL_ONE_PAINT_TOWER; break;
case LEVEL_THREE_PAINT_TOWER: baseType = UnitType.LEVEL_ONE_PAINT_TOWER; break;
default: baseType = type;
}
return baseType;
}

private void assertCanCompleteTowerPattern(UnitType type, MapLocation loc) throws GameActionException {
assertIsRobotType(this.robot.getType());
assertIsTowerType(type);
Expand All @@ -725,7 +744,13 @@ private void assertCanCompleteTowerPattern(UnitType type, MapLocation loc) throw
+ ") because the center is not a ruin");
}

if (!this.gameWorld.isValidPatternCenter(loc)) {
if (getMoney() < getBaseUnitType(type).moneyCost){
throw new GameActionException(CANT_DO_THAT,
"Cannot complete tower pattern centered at (" + loc.x + ", " + loc.y
+ ") because the team does not have enough money!");
}

if (!this.gameWorld.isValidPatternCenter(loc, true)) {
throw new GameActionException(CANT_DO_THAT,
"Cannot complete tower pattern centered at (" + loc.x + ", " + loc.y
+ ") because it is too close to the edge of the map");
Expand Down Expand Up @@ -768,6 +793,7 @@ public void completeTowerPattern(UnitType type, MapLocation loc) throws GameActi
assertCanCompleteTowerPattern(type, loc);
this.gameWorld.completeTowerPattern(getTeam(), type, loc);
InternalRobot tower = this.gameWorld.getRobot(loc);
this.gameWorld.getTeamInfo().addMoney(getTeam(), -getBaseUnitType(type).moneyCost);
this.gameWorld.getMatchMaker().addSpawnAction(tower.getID(), loc, tower.getTeam(), type);
this.gameWorld.getMatchMaker().addBuildAction(tower.getID());
}
Expand All @@ -776,10 +802,10 @@ private void assertCanCompleteResourcePattern(MapLocation loc) throws GameAction
assertIsRobotType(this.robot.getType());
assertCanActLocation(loc, GameConstants.RESOURCE_PATTERN_RADIUS_SQUARED);

if (!this.gameWorld.isValidPatternCenter(loc)) {
if (!this.gameWorld.isValidPatternCenter(loc, false)) {
throw new GameActionException(CANT_DO_THAT,
"Cannot complete resource pattern centered at (" + loc.x + ", " + loc.y
+ ") because it is too close to the edge of the map");
+ ") because it is blocked or too close to the edge of the map");
}

boolean valid = this.gameWorld.checkResourcePattern(this.robot.getTeam(), loc);
Expand Down

0 comments on commit 6c7f358

Please sign in to comment.