From d77c5f453f353a1936a5b0df6f6d20d90631740c Mon Sep 17 00:00:00 2001 From: Credence Date: Fri, 6 Sep 2024 20:52:06 +0100 Subject: [PATCH] contracts: limit realm buildable hex (#1284) Co-authored-by: Bob Co-authored-by: aymericdelab --- .DS_Store | Bin 8196 -> 0 bytes client/src/dojo/modelManager/TileManager.ts | 51 +++++++++++++-- .../manifests/dev/deployment/manifest.json | 58 +++++++++++++++--- .../src/systems/buildings/contracts.cairo | 15 ++++- sdk/packages/eternum/src/provider/index.ts | 10 +-- sdk/packages/eternum/src/types/provider.ts | 5 +- 6 files changed, 110 insertions(+), 29 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index f02628e940e01b8b1512a98cd6ff6fad22ee366f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMU2GIp6h3EKV6LTdfzo!il&n+%%c@%nRcI{RcFV5>?6&j=be-K9=!EG^yED6s zG}R`?h>7A)^idOI;)78F4;rKKfkX|wXo7@j^uY)8!51{qXyS|K&Yh*Sz+0mv%uVh+ z_ndpqy>rfdXKwBt0KlH2(FV{604h~Mc?~r;DPmmI8;TN2s)-`mgEx`0-5hZr=O%8@ zjs#Hzq6kD0h$0Y0Ad0~45CPh=MNx0D@5|AsjUo_5;Es%d_&&s`3YrS(jHJP*gPPz7 zKvWz7fRIz;0kO@(wuQW~Lx(v+w)#qfxM(wyY+P%jnI8A+u%V0iezaAgcnC>X3x z^Tz{qz?7s>8$}?Bz>N_Q=~D$caKX=&uRp)rmggsvmr<#zUbJ|Lx)N?WU(X%1%yO33^}3F)TaH->3@pPWmBT}pW4PrWx9AvNV4INxDpOgO z*H29)6Y-AC?bC_))YeVZ-`w6YJ%LVo)4FeZS-#98w|3`U=Rm#hAMAShl@FDvS|5F2Wza+;_R?N55Lbf#43i$KVrd1 zix$@oiILudNv)x(fq1=kKO6AK5tZvwF~J^W1IOq!GVV!98*A4FZ9Qk&j2qIdgFT`R zl|pa%UMcKkk7~ntcYK^&^vHvR6sNQv?MbonW4h<>pD-QqROjSapSDvQ^~UsqxxY+E zQu%o)-$U}?EzyWD>oY9hEzmOuA&F}TRCPp5*=-o6ajCYUvA#c}kp;J$l1131mmnd` zFRH5Al4_M83S!%mN=mM79+^4iE?a~XSk}rqmdZna^4|AXLCA_;+CU2H6u^l^i?fzf#<@=>UhOAgww`xtx zh6grvbf&H$NkXrJw(Bt*0Cx`D1KBZex^9ygFpNwlk67 z90EQT>rK;4=lB8u^&NO0&cG+|1p)Ok`~W|}RRSjvI62k_0Byo%T!-s%1GZuUw_pc8 zj9Uq+Y3#!txC{3XPzMOALpXvt%%eeYb#VeG(ZeEv^;w+3=kR$vg|857Uk_pXE`Bf% zhI{715I>)VVJTB^Y}YwTk_u?&Do5M`MxaX0)hN#YeYd{ 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(); + + 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 []; +} diff --git a/contracts/manifests/dev/deployment/manifest.json b/contracts/manifests/dev/deployment/manifest.json index 1210c7f53..2f460eeec 100644 --- a/contracts/manifests/dev/deployment/manifest.json +++ b/contracts/manifests/dev/deployment/manifest.json @@ -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::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" } ] }, @@ -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", @@ -1784,8 +1824,8 @@ "type": "core::integer::u32" }, { - "name": "building_coord", - "type": "eternum::models::position::Coord" + "name": "directions", + "type": "core::array::Span::" }, { "name": "building_category", diff --git a/contracts/src/systems/buildings/contracts.cairo b/contracts/src/systems/buildings/contracts.cairo index 8899b90a2..40eebd3fc 100644 --- a/contracts/src/systems/buildings/contracts.cairo +++ b/contracts/src/systems/buildings/contracts.cairo @@ -5,7 +5,7 @@ trait IBuildingContract { fn create( ref world: IWorldDispatcher, entity_id: ID, - building_coord: eternum::models::position::Coord, + directions: Span, building_category: eternum::models::buildings::BuildingCategory, produce_resource_type: Option ); @@ -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} }; @@ -29,10 +29,19 @@ mod building_systems { fn create( ref world: IWorldDispatcher, entity_id: ID, - building_coord: Coord, + mut directions: Span, building_category: BuildingCategory, produce_resource_type: Option, ) { + 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() { diff --git a/sdk/packages/eternum/src/provider/index.ts b/sdk/packages/eternum/src/provider/index.ts index f9288ca7c..ee8ac1b9f 100644 --- a/sdk/packages/eternum/src/provider/index.ts +++ b/sdk/packages/eternum/src/provider/index.ts @@ -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]), }); } diff --git a/sdk/packages/eternum/src/types/provider.ts b/sdk/packages/eternum/src/types/provider.ts index caefa0914..af3eaac57 100644 --- a/sdk/packages/eternum/src/types/provider.ts +++ b/sdk/packages/eternum/src/types/provider.ts @@ -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; }