Now let's make the entities do something. In this step, we'll add an initial action method to move entities around on the map.
We only want the owner of an entity to be able to move the entity around the map, so we add a onlyEntityOwner modifier to verify the OwnedBy component.
Entites should only be able to move one tile at a time, so we add a onlyAdjacent modifier to check the manhattan distance.
Lastly only entities having the Movable component should be able to move, so we add a check for presence of the Movable component.
After adding a client side function to call the action method, we can verify the functionality by calling the method from the developer console on the Lattice Launcher.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createWorld } from "@latticexyz/mobx-ecs";
|
|
1
|
+
import { createWorld, Entity } from "@latticexyz/mobx-ecs";
|
|
2
2
|
import { createMapping, loadEvents, setupContracts, setupMappings } from "../packages/lattice-eth-middleware";
|
|
3
3
|
import { setupPhaser } from "@latticexyz/phaser-middleware";
|
|
4
4
|
import {
|
|
@@ -88,6 +88,10 @@ export async function createGame(contractAddress: string, privateKey: string, ch
|
|
|
88
88
|
txExecutor.sendTx((c) => c.spawn(coord));
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
async function action(entity: Entity, target: Coord) {
|
|
92
|
+
await txExecutor.sendTx((contract) => contract.action(entity, target));
|
|
93
|
+
}
|
|
94
|
+
|
|
91
95
|
const context = {
|
|
92
96
|
world,
|
|
93
97
|
phaser,
|
|
@@ -96,7 +100,7 @@ export async function createGame(contractAddress: string, privateKey: string, ch
|
|
|
96
100
|
signer,
|
|
97
101
|
txExecutor,
|
|
98
102
|
personaId,
|
|
99
|
-
api: { spawn },
|
|
103
|
+
api: { spawn, action },
|
|
100
104
|
};
|
|
101
105
|
|
|
102
106
|
/*****************************************
|
|
@@ -10,6 +10,7 @@ import { StringComponent } from './components/StringComponent.sol';
|
|
|
10
10
|
import { AddressComponent } from './components/AddressComponent.sol';
|
|
11
11
|
import { BoolComponent } from './components/BoolComponent.sol';
|
|
12
12
|
import { TupleComponent } from './components/TupleComponent.sol';
|
|
13
|
+
import { manhattan } from './utils.sol';
|
|
13
14
|
|
|
14
15
|
struct Components {
|
|
15
16
|
CoordComponent position;
|
|
@@ -42,6 +43,15 @@ contract Game {
|
|
|
42
43
|
require(msg.sender == owner, 'only contract owner');
|
|
43
44
|
_;
|
|
44
45
|
}
|
|
46
|
+
modifier onlyEntityOwner(uint256 entity) {
|
|
47
|
+
require(c.ownedBy.getValue(entity) == msg.sender, 'invalid owner');
|
|
48
|
+
_;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
modifier onlyAdjacent(uint256 entity, Coord memory target) {
|
|
52
|
+
require(manhattan(c.position.getValue(entity), target) == 1, 'not adjacent');
|
|
53
|
+
_;
|
|
54
|
+
}
|
|
45
55
|
|
|
46
56
|
constructor(address _world) {
|
|
47
57
|
owner = msg.sender;
|
|
@@ -124,4 +134,13 @@ contract Game {
|
|
|
124
134
|
}
|
|
125
135
|
}
|
|
126
136
|
}
|
|
137
|
+
|
|
138
|
+
function action(uint256 entity, Coord memory target) public onlyEntityOwner(entity) onlyAdjacent(entity, target) {
|
|
139
|
+
// If the enity can move, move the entity
|
|
140
|
+
if (c.movable.has(entity)) {
|
|
141
|
+
return c.position.set(entity, target);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
revert('Invalid action');
|
|
145
|
+
}
|
|
127
146
|
}
|