Skip to content

Commit

Permalink
contracts: limit realm buildable hex (#1284)
Browse files Browse the repository at this point in the history
Co-authored-by: Bob <[email protected]>
Co-authored-by: aymericdelab <[email protected]>
  • Loading branch information
3 people authored Sep 6, 2024
1 parent bd71269 commit d77c5f4
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 29 deletions.
Binary file removed .DS_Store
Binary file not shown.
51 changes: 46 additions & 5 deletions client/src/dojo/modelManager/TileManager.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { HexPosition } from "@/types";
import { FELT_CENTER } from "@/ui/config";
import { getEntityIdFromKeys } from "@/ui/utils/utils";
import { BuildingType, ID, StructureType } from "@bibliothecadao/eternum";
import { BuildingType, Direction, getNeighborHexes, ID, StructureType } from "@bibliothecadao/eternum";
import { Has, HasValue, NotValue, getComponentValue, runQuery } from "@dojoengine/recs";
import { uuid } from "@latticexyz/utils";
import { CairoOption, CairoOptionVariant } from "starknet";
import { SetupResult } from "../setup";
import { BUILDINGS_CENTER } from "@/three/scenes/constants";

export class TileManager {
private col: number;
Expand Down Expand Up @@ -145,17 +146,20 @@ export class TileManager {
if (!entityId) throw new Error("TileManager: Not Owner of the Tile");
const { col, row } = hexCoords;

const startingPosition: [number, number] = [BUILDINGS_CENTER[0], BUILDINGS_CENTER[1]];
const endPosition: [number, number] = [col, row];
const directions = getDirectionsArray(startingPosition, endPosition);

// add optimistic rendering
let overrideId = this._optimisticBuilding(entityId, col, row, buildingType, resourceType);

// const directions = [0, 0];

await this.setup.systemCalls
.create_building({
signer: this.setup.network.burnerManager.account!,
entity_id: entityId,
building_coord: {
x: col,
y: row,
},
directions: directions,
building_category: buildingType,
produce_resource_type:
buildingType == BuildingType.Resource && resourceType
Expand Down Expand Up @@ -233,3 +237,40 @@ export class TileManager {
}
};
}

function getDirectionBetweenAdjacentHexes(
from: { col: number; row: number },
to: { col: number; row: number },
): Direction | null {
const neighbors = getNeighborHexes(from.col, from.row);
return neighbors.find((n) => n.col === to.col && n.row === to.row)?.direction ?? null;
}

function getDirectionsArray(start: [number, number], end: [number, number]): Direction[] {
const [startCol, startRow] = start;
const [endCol, endRow] = end;

const queue: { col: number; row: number; path: Direction[] }[] = [{ col: startCol, row: startRow, path: [] }];
const visited = new Set<string>();

while (queue.length > 0) {
const { col, row, path } = queue.shift()!;

if (col === endCol && row === endRow) {
return path;
}

const key = `${col},${row}`;
if (visited.has(key)) continue;
visited.add(key);

for (const { col: neighborCol, row: neighborRow } of getNeighborHexes(col, row)) {
const direction = getDirectionBetweenAdjacentHexes({ col, row }, { col: neighborCol, row: neighborRow });
if (direction !== null) {
queue.push({ col: neighborCol, row: neighborRow, path: [...path, direction] });
}
}
}

return [];
}
58 changes: 49 additions & 9 deletions contracts/manifests/dev/deployment/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1682,16 +1682,42 @@
"interface_name": "eternum::systems::buildings::contracts::IBuildingContract"
},
{
"type": "struct",
"name": "eternum::models::position::Coord",
"members": [
"type": "enum",
"name": "eternum::models::position::Direction",
"variants": [
{
"name": "x",
"type": "core::integer::u32"
"name": "East",
"type": "()"
},
{
"name": "y",
"type": "core::integer::u32"
"name": "NorthEast",
"type": "()"
},
{
"name": "NorthWest",
"type": "()"
},
{
"name": "West",
"type": "()"
},
{
"name": "SouthWest",
"type": "()"
},
{
"name": "SouthEast",
"type": "()"
}
]
},
{
"type": "struct",
"name": "core::array::Span::<eternum::models::position::Direction>",
"members": [
{
"name": "snapshot",
"type": "@core::array::Array::<eternum::models::position::Direction>"
}
]
},
Expand Down Expand Up @@ -1771,6 +1797,20 @@
}
]
},
{
"type": "struct",
"name": "eternum::models::position::Coord",
"members": [
{
"name": "x",
"type": "core::integer::u32"
},
{
"name": "y",
"type": "core::integer::u32"
}
]
},
{
"type": "interface",
"name": "eternum::systems::buildings::contracts::IBuildingContract",
Expand All @@ -1784,8 +1824,8 @@
"type": "core::integer::u32"
},
{
"name": "building_coord",
"type": "eternum::models::position::Coord"
"name": "directions",
"type": "core::array::Span::<eternum::models::position::Direction>"
},
{
"name": "building_category",
Expand Down
15 changes: 12 additions & 3 deletions contracts/src/systems/buildings/contracts.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ trait IBuildingContract<TContractState> {
fn create(
ref world: IWorldDispatcher,
entity_id: ID,
building_coord: eternum::models::position::Coord,
directions: Span<eternum::models::position::Direction>,
building_category: eternum::models::buildings::BuildingCategory,
produce_resource_type: Option<u8>
);
Expand All @@ -19,7 +19,7 @@ mod building_systems {
use eternum::alias::ID;
use eternum::models::{
resources::{Resource, ResourceCost}, owner::{EntityOwner, EntityOwnerCustomTrait}, order::Orders,
position::{Coord, Position, PositionCustomTrait, Direction},
position::{Coord, CoordTrait, Position, PositionCustomTrait, Direction},
buildings::{BuildingCategory, Building, BuildingCustomImpl}, production::{Production, ProductionRateTrait},
realm::{Realm, RealmCustomImpl}
};
Expand All @@ -29,10 +29,19 @@ mod building_systems {
fn create(
ref world: IWorldDispatcher,
entity_id: ID,
building_coord: Coord,
mut directions: Span<eternum::models::position::Direction>,
building_category: BuildingCategory,
produce_resource_type: Option<u8>,
) {
assert!(directions.len() <= 4, "cannot build on selected tile");
let mut building_coord: Coord = BuildingCustomImpl::center();
loop {
match directions.pop_front() {
Option::Some(direction) => { building_coord = building_coord.neighbor(*direction); },
Option::None => { break; }
}
};

let realm: Realm = get!(world, entity_id, Realm);
assert!(realm.realm_id != 0, "entity is not a realm");
if produce_resource_type.is_some() {
Expand Down
10 changes: 2 additions & 8 deletions sdk/packages/eternum/src/provider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,18 +369,12 @@ export class EternumProvider extends EnhancedDojoProvider {
}

public async create_building(props: SystemProps.CreateBuildingProps) {
const { entity_id, building_coord, building_category, produce_resource_type, signer } = props;
const { entity_id, directions, building_category, produce_resource_type, signer } = props;

return this.executeAndCheckTransaction(signer, {
contractAddress: getContractByName(this.manifest, `${NAMESPACE}-building_systems`),
entrypoint: "create",
calldata: CallData.compile([
entity_id,
building_coord.x,
building_coord.y,
building_category,
produce_resource_type,
]),
calldata: CallData.compile([entity_id, directions, building_category, produce_resource_type]),
});
}

Expand Down
5 changes: 1 addition & 4 deletions sdk/packages/eternum/src/types/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,7 @@ export interface TransferItemsFromMultipleProps extends SystemSigner {

export interface CreateBuildingProps extends SystemSigner {
entity_id: num.BigNumberish;
building_coord: {
x: num.BigNumberish;
y: num.BigNumberish;
};
directions: num.BigNumberish[];
building_category: BuildingType;
produce_resource_type: CairoOption<Number>;
}
Expand Down

0 comments on commit d77c5f4

Please sign in to comment.