Skip to content

Commit

Permalink
Fixed building on top of unit
Browse files Browse the repository at this point in the history
  • Loading branch information
bananu7 committed Jun 13, 2024
1 parent 60b1033 commit 39d39a2
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 9 deletions.
11 changes: 9 additions & 2 deletions packages/server/src/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { isBuildPlacementOk, mapEmptyForBuilding, tilesTakenByBuilding } from '.

import { getHpComponent, getMoveComponent, getAttackerComponent, getHarvesterComponent, getProducerComponent, getBuilderComponent, getVisionComponent, getBuildingComponent } from './game/components.js'
import { findPositionForProducedUnit } from './game/produce.js'
import { spiral, willAcceptCommand, getUnitReferencePosition, unitDistance, findClosestEmptySpot } from './game/util.js'
import { spiral, willAcceptCommand, getUnitReferencePosition, unitDistance, findClosestEmptyTile } from './game/util.js'

// TODO include building&unit size in this distance
const UNIT_FOLLOW_DISTANCE = 0.5;
Expand Down Expand Up @@ -698,6 +698,11 @@ function updateUnit(dt: Milliseconds, g: Game, unit: Unit, presence: PresenceMap
if (p.productionState.timeLeft < 0) {
const producedUnitPosition = findPositionForProducedUnit(g, unit, p.productionState.unitType, presence, buildings);

if (!producedUnitPosition){
p.productionState = undefined;
throw new Error("Cannot produce unit because of insufficient space");
}

// TODO - automatic counter
g.lastUnitId += 1;
g.units.push(createUnit(
Expand Down Expand Up @@ -778,8 +783,10 @@ function updateUnit(dt: Milliseconds, g: Game, unit: Unit, presence: PresenceMap
presence = presenceNew;
buildings = buildingsNew;

const teleportPosition = findClosestEmptySpot(g, unit.position, presence, buildings);
const teleportPosition = findClosestEmptyTile(g, unit.position, presence, buildings);
if (teleportPosition) {
teleportPosition.x += 0.5;
teleportPosition.y += 0.5;
V.vecSet(unit.position, teleportPosition);
} else {
throw new Error("Cannot find a good place to teleport a unit after building")
Expand Down
11 changes: 10 additions & 1 deletion packages/server/src/game/produce.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import { Position, Unit, Game, PresenceMap, BuildingMap } from '../types'
import { getUnitReferencePosition, findClosestEmptyTile } from './util.js'

export function findPositionForProducedUnit(g: Game, unit: Unit, type: string, presence: PresenceMap, buildings: BuildingMap): Position {
export function findPositionForProducedUnit(
g: Game,
unit: Unit,
type: string,
presence: PresenceMap,
buildings: BuildingMap
): Position | undefined {
const refPos = getUnitReferencePosition(unit);
const pos = findClosestEmptyTile(g, refPos, presence, buildings);

if (!pos)
return;

// position in the middle of a tile
pos.x += 0.5;
pos.y += 0.5;
Expand Down
2 changes: 0 additions & 2 deletions packages/server/src/game/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,13 @@ export function findClosestEmptyTile(
for (let i = 0; i < MAX_POSITIONS_TO_CHECK; i++) {
const p = concentric(pos, i);
if (!p) {
console.log("Spot not found")
return undefined;
}

const noBuilding = ! buildings.has(explode(p));
const noUnit = ! presence.has(explode(p));

if (noBuilding && noUnit) {
console.log("Found empty spot ", p)
return p;
}
}
Expand Down
20 changes: 16 additions & 4 deletions packages/server/test/behaviour.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,7 @@ describe('build action', () => {
expect(game.units[0].state.state).toBe('idle');
});

// TODO - currently the game allows placing the building on top of the harvester
// once this is fixed, the test will succeed!
// Checks if the unit can move after placing a building on top of itself
test('build on top', () => {
const game = createBasicGame({});

Expand All @@ -228,8 +227,21 @@ describe('build action', () => {
for (let i = 0; i < 20 * 10; i++)
tick(TICK_MS, game);

console.log(game.units)
expect(game.units.length).toBe(2);

console.log("[test] telling the unit to move")
command({
command: { typ: 'Move', target: { x: 15, y: 15 }},
unitIds: [1],
shift: false,
},
game,
1
);

expect(game.units.length).toBe(1);
tick(TICK_MS, game);

expect(game.units[0].state.state).toBe('active');
expect(game.units[0].state.action).toBe('Moving');
});
});

0 comments on commit 39d39a2

Please sign in to comment.