Skip to content

Commit 3ab7e19

Browse files
Merge remote-tracking branch 'origin/schema' into client-release
2 parents d94a972 + 85935bb commit 3ab7e19

File tree

28 files changed

+316
-1073
lines changed

28 files changed

+316
-1073
lines changed

.github/workflows/release-engine.yml

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -92,79 +92,79 @@ jobs:
9292
9393
- name: Upload specs
9494
run: gsutil -m rsync -a $OBJECT_ACL -r ./specs gs://$GCS_BUCKET/specs/${RELEASE_ARTIFACT_ID}/$RELEASE_VERSION
95-
release-python:
96-
name: Release Python
97-
runs-on: ubuntu-latest
98-
permissions:
99-
contents: read
100-
id-token: write
101-
102-
steps:
103-
- uses: conda-incubator/setup-miniconda@v3
104-
with:
105-
python-version: 3.12
106-
107-
- name: Checkout branch
108-
uses: actions/checkout@v3
109-
110-
- name: Inject release version
111-
run: |
112-
release_version=${GITHUB_REF#refs/*/}
113-
release_version=${release_version#engine.}
114-
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
115-
echo "The release version is $release_version"
116-
117-
- name: Authenticate to Google Cloud Platform
118-
uses: google-github-actions/auth@v1
119-
with:
120-
create_credentials_file: true
121-
workload_identity_provider: projects/830784087321/locations/global/workloadIdentityPools/releases/providers/github-workflow
122-
service_account: [email protected]
123-
124-
- name: Set up Google Cloud SDK
125-
uses: 'google-github-actions/setup-gcloud@v1'
126-
127-
- name: Clone private maps
128-
if: ${{ env.IS_PUBLIC != 'YES' }}
129-
uses: actions/checkout@v3
130-
with:
131-
repository: battlecode/private-maps
132-
token: ${{ secrets.CI_REPOSITORY_CLONE_PAT }}
133-
path: private-maps
95+
# release-python:
96+
# name: Release Python
97+
# runs-on: ubuntu-latest
98+
# permissions:
99+
# contents: read
100+
# id-token: write
101+
102+
# steps:
103+
# - uses: conda-incubator/setup-miniconda@v3
104+
# with:
105+
# python-version: 3.12
106+
107+
# - name: Checkout branch
108+
# uses: actions/checkout@v3
109+
110+
# - name: Inject release version
111+
# run: |
112+
# release_version=${GITHUB_REF#refs/*/}
113+
# release_version=${release_version#engine.}
114+
# echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
115+
# echo "The release version is $release_version"
116+
117+
# - name: Authenticate to Google Cloud Platform
118+
# uses: google-github-actions/auth@v1
119+
# with:
120+
# create_credentials_file: true
121+
# workload_identity_provider: projects/830784087321/locations/global/workloadIdentityPools/releases/providers/github-workflow
122+
# service_account: [email protected]
123+
124+
# - name: Set up Google Cloud SDK
125+
# uses: 'google-github-actions/setup-gcloud@v1'
126+
127+
# - name: Clone private maps
128+
# if: ${{ env.IS_PUBLIC != 'YES' }}
129+
# uses: actions/checkout@v3
130+
# with:
131+
# repository: battlecode/private-maps
132+
# token: ${{ secrets.CI_REPOSITORY_CLONE_PAT }}
133+
# path: private-maps
134134

135-
- name: Inject private maps
136-
if: ${{ env.IS_PUBLIC != 'YES' }}
137-
run: |
138-
source="private-maps/$RELEASE_ARTIFACT_ID"
139-
dest="$RELEASE_ARTIFACT_ID/maps"
140-
if [ -d "$source" ]; then
141-
cp -r -i "$source/." "$dest/" < /dev/null &> private-maps-copy-log
142-
if [ -s "private-maps-copy-log" ]; then
143-
echo "FAILED! Public and private maps should not intersect."
144-
cat private-maps-copy-log
145-
exit 1
146-
fi
147-
fi
135+
# - name: Inject private maps
136+
# if: ${{ env.IS_PUBLIC != 'YES' }}
137+
# run: |
138+
# source="private-maps/$RELEASE_ARTIFACT_ID"
139+
# dest="$RELEASE_ARTIFACT_ID/maps"
140+
# if [ -d "$source" ]; then
141+
# cp -r -i "$source/." "$dest/" < /dev/null &> private-maps-copy-log
142+
# if [ -s "private-maps-copy-log" ]; then
143+
# echo "FAILED! Public and private maps should not intersect."
144+
# cat private-maps-copy-log
145+
# exit 1
146+
# fi
147+
# fi
148148

149-
- name: Build python package
150-
shell: bash -el {0} # Make sure conda is activated
151-
run: |
152-
conda info
153-
python --version
154-
pip install --upgrade build
155-
SETUPTOOLS_SCM_PRETEND_VERSION=${RELEASE_VERSION} python -m build
156-
157-
- name: Determine access control
158-
run: |
159-
[[ "$IS_PUBLIC" = "YES" ]] && acl="public-read" || acl="project-private"
160-
echo "OBJECT_ACL=$acl" >> $GITHUB_ENV
161-
echo "Objects will be uploaded with ACL $acl"
162-
163-
- name: Upload python package to remote repository
164-
run: |
165-
mv *.tar.gz battlecode.tar.gz
166-
gsutil -m cp -a $OBJECT_ACL battlecode.tar.gz gs://$GCS_BUCKET/maven/org/battlecode/${RELEASE_ARTIFACT_ID}-python/${RELEASE_VERSION}/
167-
working-directory: ./dist
149+
# - name: Build python package
150+
# shell: bash -el {0} # Make sure conda is activated
151+
# run: |
152+
# conda info
153+
# python --version
154+
# pip install --upgrade build
155+
# SETUPTOOLS_SCM_PRETEND_VERSION=${RELEASE_VERSION} python -m build
156+
157+
# - name: Determine access control
158+
# run: |
159+
# [[ "$IS_PUBLIC" = "YES" ]] && acl="public-read" || acl="project-private"
160+
# echo "OBJECT_ACL=$acl" >> $GITHUB_ENV
161+
# echo "Objects will be uploaded with ACL $acl"
162+
163+
# - name: Upload python package to remote repository
164+
# run: |
165+
# mv *.tar.gz battlecode.tar.gz
166+
# gsutil -m cp -a $OBJECT_ACL battlecode.tar.gz gs://$GCS_BUCKET/maven/org/battlecode/${RELEASE_ARTIFACT_ID}-python/${RELEASE_VERSION}/
167+
# working-directory: ./dist
168168

169169
# TODO: docs?
170170
#- name: Upload javadocs

client/icons/icon.icns

1.04 KB
Binary file not shown.

client/icons/icon.ico

-158 KB
Binary file not shown.

client/icons/icon.png

658 Bytes
Loading

client/src/components/sidebar/map-editor/MapGenerator.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Game, { Team } from '../../../playback/Game'
33
import Match from '../../../playback/Match'
44
import { CurrentMap, StaticMap } from '../../../playback/Map'
55
import Round from '../../../playback/Round'
6-
import Bodies from '../../../playback/Bodies'
6+
import Bodies, { Body } from '../../../playback/Bodies'
77
import { BATTLECODE_YEAR, DIRECTIONS, TEAM_COLOR_NAMES } from '../../../constants'
88
import { nativeAPI } from '../runner/native-api-wrapper'
99
import { Vector } from '../../../playback/Vector'
@@ -180,6 +180,13 @@ function verifyMap(map: CurrentMap, bodies: Bodies): string {
180180
`>= 3 away`
181181
)
182182
}
183+
184+
if (body.robotType === schema.RobotType.CAT) {
185+
if (!map.staticMap.catWaypoints.get(body.id) || map.staticMap.catWaypoints.get(body.id)?.length === 0) {
186+
return `Cat with id ${body.id} has no waypoints`
187+
}
188+
}
189+
183190
}
184191

185192
return ''

client/src/playback/Actions.ts

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,40 @@ export const ACTION_DEFINITIONS: Record<schema.Action, typeof Action<ActionUnion
183183
}
184184
},
185185
[schema.Action.RatNap]: class RatNapAction extends Action<schema.RatNap> {
186+
private static readonly OFFSET = { x: -0.35, y: 0 }
186187
apply(round: Round): void {
187188
// move the target onto the source adjust target's size using scale factor
188189
const src = round.bodies.getById(this.robotId)
189190
const target = round.bodies.getById(this.actionData.id()) // rat getting napped
191+
192+
target.lastPos = { ...target.pos }
193+
target.pos = { x: src.pos.x + RatNapAction.OFFSET.x, y: src.pos.y + RatNapAction.OFFSET.y }
194+
target.size = 0.6
190195
}
191196
draw(match: Match, ctx: CanvasRenderingContext2D): void {
192197
//target rat moves onto src rat, circle around carried group thing
193-
const src = match.currentRound.bodies.getById(this.robotId)
194-
const target = match.currentRound.bodies.getById(this.actionData.id()) // rat getting napped
198+
const src = match.currentRound.bodies.getById(this.robotId)
199+
const srcCoords = renderUtils.getRenderCoords(src.pos.x, src.pos.y, match.map.dimension, true)
200+
const t = match.getInterpolationFactor()
201+
const bump = Math.sin(t * Math.PI * 8) * 0.03
202+
const half = 0.5 + bump
203+
const radius = 0.08 // corner radius
204+
205+
ctx.save()
206+
ctx.shadowBlur = 12
207+
ctx.shadowColor = src.team.color
208+
ctx.strokeStyle = src.team.color
209+
ctx.globalAlpha = 0.7
210+
ctx.lineWidth = 0.04
211+
ctx.beginPath()
212+
ctx.moveTo(srcCoords.x - half + radius, srcCoords.y - half)
213+
ctx.arcTo(srcCoords.x + half, srcCoords.y - half, srcCoords.x + half, srcCoords.y + half, radius)
214+
ctx.arcTo(srcCoords.x + half, srcCoords.y + half, srcCoords.x - half, srcCoords.y + half, radius)
215+
ctx.arcTo(srcCoords.x - half, srcCoords.y + half, srcCoords.x - half, srcCoords.y - half, radius)
216+
ctx.arcTo(srcCoords.x - half, srcCoords.y - half, srcCoords.x + half, srcCoords.y - half, radius)
217+
ctx.stroke()
218+
ctx.restore()
219+
ctx.restore()
195220
}
196221
},
197222
[schema.Action.RatCollision]: class RatCollisionAction extends Action<schema.RatCollision> {
@@ -200,6 +225,33 @@ export const ACTION_DEFINITIONS: Record<schema.Action, typeof Action<ActionUnion
200225
const src = match.currentRound.bodies.getById(this.robotId)
201226
const pos = match.map.indexToLocation(this.actionData.loc())
202227
const coords = renderUtils.getRenderCoords(pos.x, pos.y, match.map.dimension, true)
228+
const t = match.getInterpolationFactor()
229+
230+
ctx.save()
231+
// dusty base color that fills the cell and fades out
232+
const baseAlpha = 0.4 * (1 - t)
233+
ctx.fillStyle = `rgba(150,130,110,${baseAlpha})`
234+
ctx.fillRect(coords.x - 0.5, coords.y - 0.5, 1, 1)
235+
236+
// these are the random rocks that fill the cell
237+
const rockCount = 10
238+
for (let i = 0; i < rockCount; i++) {
239+
const rx = coords.x - 0.5 + Math.random() * 1
240+
const ry = coords.y - 0.5 + Math.random() * 1
241+
const size = 0.08 + Math.random() * 0.15
242+
const shade = 90 + Math.floor(Math.random() * 50)
243+
const alpha = 0.7 * (1 - t)
244+
ctx.fillStyle = `rgba(${shade},${shade - 10},${shade - 20},${alpha})`
245+
ctx.fillRect(rx, ry, size, size)
246+
}
247+
248+
// ring outside the cell (also fades out)
249+
ctx.strokeStyle = src.team.color
250+
ctx.globalAlpha = 0.35 * (1 - t)
251+
ctx.lineWidth = 0.04
252+
ctx.strokeRect(coords.x - 0.5, coords.y - 0.5, 1, 1)
253+
ctx.restore()
254+
203255
}
204256
},
205257
[schema.Action.PlaceDirt]: class PlaceDirtAction extends Action<schema.PlaceDirt> {
@@ -284,8 +336,8 @@ export const ACTION_DEFINITIONS: Record<schema.Action, typeof Action<ActionUnion
284336
const target = round.bodies.getById(this.actionData.id())
285337
const amount = this.actionData.amount()
286338

287-
body.cheese -= amount
288-
target.cheese += amount
339+
body.cheese -= Math.min(body.cheese, amount)
340+
target.cheese += Math.min(body.cheese, amount)
289341
}
290342
draw(match: Match, ctx: CanvasRenderingContext2D): void {
291343
const srcBody = match.currentRound.bodies.getById(this.robotId)

client/src/playback/Bodies.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,8 @@ export default class Bodies {
9999

100100
return body
101101
}
102+
102103
checkBodyCollisionAtLocation(type: schema.RobotType, pos: Vector): boolean {
103-
const bodyClass = BODY_DEFINITIONS[type] ?? assert.fail(`Body type ${type} not found in BODY_DEFINITIONS`)
104-
const tempBody = new bodyClass(this.game, pos, this.game.getTeamByID(1), 0)
105-
const bodySize = tempBody.size
106104
const occupiedSpaces: Vector[] = []
107105

108106
for (const otherBody of this.bodies.values()) {
@@ -154,6 +152,34 @@ export default class Bodies {
154152
return false
155153
}
156154

155+
checkBodyOutofBoundsAtLocation(type: schema.RobotType, pos: Vector): boolean {
156+
const map = this.game.currentMatch?.map
157+
if(!map) return false
158+
159+
const dimension = map.dimension
160+
const occupiedSpaces: Vector[] = []
161+
162+
if (type == schema.RobotType.RAT) {
163+
if(!map.inBounds(pos.x, pos.y)) return false
164+
}
165+
if (type == schema.RobotType.CAT) {
166+
for (let xoff = 0; xoff <= 1; xoff++) {
167+
for (let yoff = 0; yoff <= 1; yoff++) {
168+
if(!map.inBounds(pos.x+xoff, pos.y+yoff)) return false
169+
}
170+
}
171+
}
172+
if (type == schema.RobotType.RAT_KING) {
173+
for (let xoff = -1; xoff <= 1; xoff++) {
174+
for (let yoff = -1; yoff <= 1; yoff++) {
175+
if(!map.inBounds(pos.x+xoff, pos.y+yoff)) return false
176+
}
177+
}
178+
}
179+
180+
return true
181+
}
182+
157183
markBodyAsDead(id: number): void {
158184
const body = this.getById(id)
159185
body.dead = true

client/src/playback/Brushes.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,12 @@ export class CatBrush extends SymmetricMapEditorBrush<StaticMap> {
546546
const add = (x: number, y: number, team: Team) => {
547547
const pos = { x, y }
548548

549-
if (this.bodies.checkBodyCollisionAtLocation(schema.RobotType.CAT, pos)) return null
549+
if (
550+
this.bodies.checkBodyCollisionAtLocation(schema.RobotType.CAT, pos)||
551+
!this.bodies.checkBodyOutofBoundsAtLocation(schema.RobotType.CAT, pos)
552+
) {
553+
return null
554+
}
550555

551556
const id = this.bodies.getNextID()
552557
this.bodies.spawnBodyFromValues(id, schema.RobotType.CAT, team, pos, 0, robotOne ? 0 : 1)
@@ -650,7 +655,8 @@ export class RatKingBrush extends SymmetricMapEditorBrush<StaticMap> {
650655
const pos = { x, y }
651656
if (
652657
this.bodies.getBodyAtLocation(x, y) ||
653-
this.bodies.checkBodyCollisionAtLocation(schema.RobotType.RAT_KING, pos)
658+
this.bodies.checkBodyCollisionAtLocation(schema.RobotType.RAT_KING, pos) ||
659+
!this.bodies.checkBodyOutofBoundsAtLocation(schema.RobotType.RAT_KING, pos)
654660
) {
655661
return null
656662
}

client/src/playback/GameRenderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ class GameRendererClass {
185185
const ctx = this.ctx(CanvasLayers.Background)
186186
const match = GameRunner.match
187187
if (!match || !ctx) return
188-
match.currentRound.map.staticMap.draw(ctx)
188+
match.currentRound.map.staticMap.draw(ctx, GameConfig.config)
189189
this.render()
190190
}
191191

0 commit comments

Comments
 (0)