From 8adb553d72ed8a55b055f5cc20b08c6d6b451bd2 Mon Sep 17 00:00:00 2001 From: dk1a Date: Sat, 10 Feb 2024 15:39:19 +0300 Subject: [PATCH 1/2] refactor LibPlayer and LibEntity --- .../{LibEntity.sol => LibMachineBuild.sol} | 60 ++++++++++++------- .../contracts/src/libraries/LibPlayer.sol | 45 +++++++++++--- .../contracts/src/libraries/Libraries.sol | 2 +- .../contracts/src/systems/dev/WarpSystem.sol | 6 +- .../systems/machine-network/BuildSystem.sol | 9 +-- .../systems/machine-network/ConnectSystem.sol | 4 +- .../systems/machine-network/DestroySystem.sol | 6 +- .../machine-network/DisconnectSystem.sol | 4 +- .../systems/machine-network/ResolveSystem.sol | 4 +- .../src/systems/order/DepotSystem.sol | 8 +-- .../src/systems/order/OrderSystem.sol | 8 +-- .../src/systems/progression/NameSystem.sol | 4 +- .../src/systems/progression/SpawnSystem.sol | 7 +-- .../src/systems/progression/StartSystem.sol | 12 ++-- 14 files changed, 107 insertions(+), 72 deletions(-) rename packages/contracts/src/libraries/{LibEntity.sol => LibMachineBuild.sol} (54%) diff --git a/packages/contracts/src/libraries/LibEntity.sol b/packages/contracts/src/libraries/LibMachineBuild.sol similarity index 54% rename from packages/contracts/src/libraries/LibEntity.sol rename to packages/contracts/src/libraries/LibMachineBuild.sol index a997de50..7beef19f 100644 --- a/packages/contracts/src/libraries/LibEntity.sol +++ b/packages/contracts/src/libraries/LibMachineBuild.sol @@ -1,26 +1,46 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.24; import { getUniqueEntity } from "@latticexyz/world-modules/src/modules/uniqueentity/getUniqueEntity.sol"; -import { EntityType, MachineType, BuildIndex, IncomingConnections, OutgoingConnections } from "../codegen/index.sol"; +import { EntityType, MachineType, BuildIndex, IncomingConnections, OutgoingConnections, TutorialLevel, GameConfig, SpawnIndex } from "../codegen/index.sol"; import { ENTITY_TYPE, MACHINE_TYPE } from "../codegen/common.sol"; -library LibEntity { +library LibMachineBuild { /** - * @notice Creates a new machine entity of the specified type. + * @notice Creates a new machine entity of the specified buildable type. * @param _machineType The type of machine to create, specified by the MACHINE_TYPE enum. * @return entity The identifier for the newly created machine entity. */ - function create(MACHINE_TYPE _machineType) internal returns (bytes32) { - bytes32 entity = getUniqueEntity(); - EntityType.set(entity, ENTITY_TYPE.MACHINE); - MachineType.set(entity, _machineType); + function build(MACHINE_TYPE _machineType) internal returns (bytes32 entity) { + require(isBuildableMachineType(_machineType), "not buildable"); + entity = getUniqueEntity(); + create(_machineType, entity); + } + + /** + * @notice Creates records for a new machine entity of the specified type. + * @param _machineType The type of machine to create, specified by the MACHINE_TYPE enum. + * @return entity The identifier for the newly created machine entity. + */ + function create(MACHINE_TYPE _machineType) internal returns (bytes32 entity) { + entity = getUniqueEntity(); + create(_machineType, entity); + } + + /** + * @notice Creates records for a new machine of the specified type, using the provided entity. + * @param _machineType The type of machine to create, specified by the MACHINE_TYPE enum. + * @param _entity The identifier to be used for the machine entity creation. + */ + function create(MACHINE_TYPE _machineType, bytes32 _entity) internal { + EntityType.set(_entity, ENTITY_TYPE.MACHINE); + MachineType.set(_entity, _machineType); // Set ports on machine // - - - - - - - - - - - - // NONE: 0 IN, 0 OUT // INLET: 0 IN, 1 OUT // OUTLET: 1 IN, 0 OUT - // PLAYER: 1 IN, 2 OUT (created at spawn) + // PLAYER: 1 IN, 2 OUT // SPLITTER: 1 IN, 2 OUT // MIXER: 2 IN, 1 OUT // WETTER: 1 IN, 1 OUT @@ -29,23 +49,21 @@ library LibEntity { // COOLER: 1 IN, 1 OUT if (_machineType == MACHINE_TYPE.INLET) { - IncomingConnections.set(entity, new bytes32[](0)); - OutgoingConnections.set(entity, new bytes32[](1)); + IncomingConnections.set(_entity, new bytes32[](0)); + OutgoingConnections.set(_entity, new bytes32[](1)); } else if (_machineType == MACHINE_TYPE.OUTLET) { - IncomingConnections.set(entity, new bytes32[](1)); - OutgoingConnections.set(entity, new bytes32[](0)); - } else if (_machineType == MACHINE_TYPE.SPLITTER) { - IncomingConnections.set(entity, new bytes32[](1)); - OutgoingConnections.set(entity, new bytes32[](2)); + IncomingConnections.set(_entity, new bytes32[](1)); + OutgoingConnections.set(_entity, new bytes32[](0)); + } else if (_machineType == MACHINE_TYPE.SPLITTER || _machineType == MACHINE_TYPE.PLAYER) { + IncomingConnections.set(_entity, new bytes32[](1)); + OutgoingConnections.set(_entity, new bytes32[](2)); } else if (_machineType == MACHINE_TYPE.MIXER) { - IncomingConnections.set(entity, new bytes32[](2)); - OutgoingConnections.set(entity, new bytes32[](1)); + IncomingConnections.set(_entity, new bytes32[](2)); + OutgoingConnections.set(_entity, new bytes32[](1)); } else { - IncomingConnections.set(entity, new bytes32[](1)); - OutgoingConnections.set(entity, new bytes32[](1)); + IncomingConnections.set(_entity, new bytes32[](1)); + OutgoingConnections.set(_entity, new bytes32[](1)); } - - return entity; } /** diff --git a/packages/contracts/src/libraries/LibPlayer.sol b/packages/contracts/src/libraries/LibPlayer.sol index e434e43d..f4b97982 100644 --- a/packages/contracts/src/libraries/LibPlayer.sol +++ b/packages/contracts/src/libraries/LibPlayer.sol @@ -1,20 +1,47 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.24; +import { WorldContextConsumerLib } from "@latticexyz/world/src/WorldContext.sol"; import { TutorialLevel, EntityType, MachineType, OutgoingConnections, IncomingConnections, GameConfig, SpawnIndex } from "../codegen/index.sol"; import { ENTITY_TYPE, MACHINE_TYPE } from "../codegen/common.sol"; +import { LibMachineBuild } from "./LibMachineBuild.sol"; +import { LibUtils } from "./LibUtils.sol"; library LibPlayer { - function spawn(bytes32 _playerEntity) internal { - EntityType.set(_playerEntity, ENTITY_TYPE.MACHINE); - MachineType.set(_playerEntity, MACHINE_TYPE.PLAYER); - TutorialLevel.set(_playerEntity, 0); + /** + * @notice Returns the current player entity (based on World's _msgSender) + */ + function _getPlayerEntity() private view returns (bytes32) { + return LibUtils.addressToEntityKey(WorldContextConsumerLib._msgSender()); + } + + /** + * @notice Returns whether the records for the player entity have been spawned + */ + function _isPlayerSpawned(bytes32 _playerEntity) private view returns (bool) { + return EntityType.get(_playerEntity) != ENTITY_TYPE.NONE; + } + + /** + * @notice Returns the current player entity (based on World's _msgSender), reverts if plater is not spawned + */ + function getSpawnedPlayerEntity() internal view returns (bytes32 playerEntity) { + playerEntity = LibUtils.addressToEntityKey(WorldContextConsumerLib._msgSender()); + require(_isPlayerSpawned(playerEntity), "player not spawned"); + } + + /** + * @notice Spawns records for the current player entity (based on World's msgSender). + * @return playerEntity The identifier for the newly created player entity. + */ + function spawn() internal returns (bytes32 playerEntity) { + playerEntity = _getPlayerEntity(); + require(!_isPlayerSpawned(playerEntity), "player already spawned"); + LibMachineBuild.create(MACHINE_TYPE.PLAYER, playerEntity); + + TutorialLevel.set(playerEntity, 0); uint32 newSpawnIndex = GameConfig.getGlobalSpawnIndex() + 1; GameConfig.setGlobalSpawnIndex(newSpawnIndex); - SpawnIndex.set(_playerEntity, newSpawnIndex); - - // Player has 1 input and 2 outputs - IncomingConnections.set(_playerEntity, new bytes32[](1)); - OutgoingConnections.set(_playerEntity, new bytes32[](2)); + SpawnIndex.set(playerEntity, newSpawnIndex); } } diff --git a/packages/contracts/src/libraries/Libraries.sol b/packages/contracts/src/libraries/Libraries.sol index 5f116fbc..e3d14e39 100644 --- a/packages/contracts/src/libraries/Libraries.sol +++ b/packages/contracts/src/libraries/Libraries.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.24; import { LibUtils } from "./LibUtils.sol"; import { LibPod } from "./LibPod.sol"; import { LibPlayer } from "./LibPlayer.sol"; -import { LibEntity } from "./LibEntity.sol"; +import { LibMachineBuild } from "./LibMachineBuild.sol"; import { LibNetwork } from "./LibNetwork.sol"; import { LibMachine } from "./LibMachine.sol"; import { LibDepot } from "./LibDepot.sol"; diff --git a/packages/contracts/src/systems/dev/WarpSystem.sol b/packages/contracts/src/systems/dev/WarpSystem.sol index 5918007d..341078e9 100644 --- a/packages/contracts/src/systems/dev/WarpSystem.sol +++ b/packages/contracts/src/systems/dev/WarpSystem.sol @@ -2,14 +2,14 @@ pragma solidity >=0.8.24; import { System } from "@latticexyz/world/src/System.sol"; import { TutorialLevel, CurrentOrder, TutorialOrders, CarriedBy, DepotsInPod, Amount, MaterialType, Order, Tutorial, Name } from "../../codegen/index.sol"; -import { LibUtils, LibToken } from "../../libraries/Libraries.sol"; +import { LibPlayer, LibToken } from "../../libraries/Libraries.sol"; contract WarpSystem is System { /** * @dev Used in testing to fast forward the tutorial level. NOTE: disable for production. */ function warp(uint32 _level) public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); // Set level TutorialLevel.set(playerEntity, _level); @@ -24,7 +24,7 @@ contract WarpSystem is System { * @dev Used in testing to skip tutorial levels. NOTE: disable for production. */ function graduate() public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); TutorialLevel.deleteRecord(playerEntity); diff --git a/packages/contracts/src/systems/machine-network/BuildSystem.sol b/packages/contracts/src/systems/machine-network/BuildSystem.sol index 9566a4de..3dc2c3b3 100644 --- a/packages/contracts/src/systems/machine-network/BuildSystem.sol +++ b/packages/contracts/src/systems/machine-network/BuildSystem.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.24; import { System } from "@latticexyz/world/src/System.sol"; import { CarriedBy, BuildIndex, MachinesInPod } from "../../codegen/index.sol"; import { MACHINE_TYPE, ENTITY_TYPE } from "../../codegen/common.sol"; -import { LibUtils, LibEntity, LibPod } from "../../libraries/Libraries.sol"; +import { LibPlayer, LibMachineBuild, LibPod } from "../../libraries/Libraries.sol"; contract BuildSystem is System { /** @@ -12,14 +12,11 @@ contract BuildSystem is System { * @return machineEntity The identifier for the newly created machine entity. */ function build(MACHINE_TYPE _machineType) public returns (bytes32) { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); - require(LibEntity.isBuildableMachineType(_machineType), "not buildable"); - // Create machine entity - bytes32 machineEntity = LibEntity.create(_machineType); + bytes32 machineEntity = LibMachineBuild.build(_machineType); // Get player's pod entity - bytes32 podEntity = CarriedBy.get(playerEntity); + bytes32 podEntity = CarriedBy.get(LibPlayer.getSpawnedPlayerEntity()); // Place in same pod as the player CarriedBy.set(machineEntity, podEntity); diff --git a/packages/contracts/src/systems/machine-network/ConnectSystem.sol b/packages/contracts/src/systems/machine-network/ConnectSystem.sol index 409439cb..c95e4286 100644 --- a/packages/contracts/src/systems/machine-network/ConnectSystem.sol +++ b/packages/contracts/src/systems/machine-network/ConnectSystem.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.24; import { System } from "@latticexyz/world/src/System.sol"; import { EntityType, GameConfig, GameConfigData, IncomingConnections, OutgoingConnections, CarriedBy } from "../../codegen/index.sol"; import { ENTITY_TYPE, PORT_INDEX } from "../../codegen/common.sol"; -import { LibUtils, LibNetwork } from "../../libraries/Libraries.sol"; +import { LibPlayer, LibNetwork } from "../../libraries/Libraries.sol"; contract ConnectSystem is System { /** @@ -13,7 +13,7 @@ contract ConnectSystem is System { * @param _portIndex The port index on the source machine which determines the position (FIRST or SECOND) to write in the outgoing connections array. */ function connect(bytes32 _sourceMachine, bytes32 _targetMachine, PORT_INDEX _portIndex) public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); require(CarriedBy.get(_sourceMachine) == podEntity && CarriedBy.get(_targetMachine) == podEntity, "not in pod"); diff --git a/packages/contracts/src/systems/machine-network/DestroySystem.sol b/packages/contracts/src/systems/machine-network/DestroySystem.sol index 23992de4..d4e7450f 100644 --- a/packages/contracts/src/systems/machine-network/DestroySystem.sol +++ b/packages/contracts/src/systems/machine-network/DestroySystem.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.24; import { System } from "@latticexyz/world/src/System.sol"; import { GameConfig, GameConfigData, CarriedBy, EntityType, MachinesInPod, IncomingConnections, OutgoingConnections } from "../../codegen/index.sol"; import { MACHINE_TYPE, ENTITY_TYPE } from "../../codegen/common.sol"; -import { LibUtils, LibEntity, LibNetwork } from "../../libraries/Libraries.sol"; +import { LibUtils, LibPlayer, LibMachineBuild, LibNetwork } from "../../libraries/Libraries.sol"; contract DestroySystem is System { /** @@ -11,7 +11,7 @@ contract DestroySystem is System { * @param _machineEntity The identifier for the machine entity to be destroyed. */ function destroy(bytes32 _machineEntity) public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); require(CarriedBy.get(_machineEntity) == podEntity, "not in pod"); @@ -69,7 +69,7 @@ contract DestroySystem is System { } // Destroy machine entity - LibEntity.destroy(_machineEntity); + LibMachineBuild.destroy(_machineEntity); // Remove it from the list of machines MachinesInPod.set(podEntity, LibUtils.removeFromArray(MachinesInPod.get(podEntity), _machineEntity)); diff --git a/packages/contracts/src/systems/machine-network/DisconnectSystem.sol b/packages/contracts/src/systems/machine-network/DisconnectSystem.sol index 46b0ebc0..7b77172f 100644 --- a/packages/contracts/src/systems/machine-network/DisconnectSystem.sol +++ b/packages/contracts/src/systems/machine-network/DisconnectSystem.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.24; import { System } from "@latticexyz/world/src/System.sol"; import { EntityType, GameConfig, GameConfigData, IncomingConnections, OutgoingConnections, CarriedBy } from "../../codegen/index.sol"; import { ENTITY_TYPE, PORT_INDEX } from "../../codegen/common.sol"; -import { LibUtils, LibNetwork } from "../../libraries/Libraries.sol"; +import { LibPlayer, LibNetwork } from "../../libraries/Libraries.sol"; contract DisconnectSystem is System { /** @@ -12,7 +12,7 @@ contract DisconnectSystem is System { * @param _portIndex The port index on the source machine which determines which connection to disconnect. */ function disconnect(bytes32 _sourceMachine, PORT_INDEX _portIndex) public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); require(CarriedBy.get(_sourceMachine) == podEntity, "not in pod"); diff --git a/packages/contracts/src/systems/machine-network/ResolveSystem.sol b/packages/contracts/src/systems/machine-network/ResolveSystem.sol index d1059bb9..71a4162b 100644 --- a/packages/contracts/src/systems/machine-network/ResolveSystem.sol +++ b/packages/contracts/src/systems/machine-network/ResolveSystem.sol @@ -2,11 +2,11 @@ pragma solidity >=0.8.24; import { System } from "@latticexyz/world/src/System.sol"; import { CarriedBy } from "../../codegen/index.sol"; -import { LibUtils, LibNetwork } from "../../libraries/Libraries.sol"; +import { LibPlayer, LibNetwork } from "../../libraries/Libraries.sol"; contract ResolveSystem is System { function resolve() public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); LibNetwork.resolve(podEntity); } diff --git a/packages/contracts/src/systems/order/DepotSystem.sol b/packages/contracts/src/systems/order/DepotSystem.sol index 8bd6f4b8..a1a01820 100644 --- a/packages/contracts/src/systems/order/DepotSystem.sol +++ b/packages/contracts/src/systems/order/DepotSystem.sol @@ -3,11 +3,11 @@ pragma solidity >=0.8.24; import { System } from "@latticexyz/world/src/System.sol"; import { EntityType, CarriedBy, MaterialType, MachineType, Amount, DepotConnection, FixedEntities } from "../../codegen/index.sol"; import { ENTITY_TYPE, MATERIAL_TYPE, MACHINE_TYPE } from "../../codegen/common.sol"; -import { LibUtils, LibPod, LibNetwork } from "../../libraries/Libraries.sol"; +import { LibPlayer, LibPod, LibNetwork } from "../../libraries/Libraries.sol"; contract DepotSystem is System { function attachDepot(bytes32 _depotEntity, MACHINE_TYPE _machineType) public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); require(CarriedBy.get(_depotEntity) == podEntity, "not in pod"); @@ -32,7 +32,7 @@ contract DepotSystem is System { } function detachDepot(MACHINE_TYPE _machineType) public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); require(_machineType == MACHINE_TYPE.INLET || _machineType == MACHINE_TYPE.OUTLET, "not inlet/outlet"); @@ -53,7 +53,7 @@ contract DepotSystem is System { } function clearDepot(bytes32 _depotEntity) public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); require(CarriedBy.get(_depotEntity) == podEntity, "not in pod"); diff --git a/packages/contracts/src/systems/order/OrderSystem.sol b/packages/contracts/src/systems/order/OrderSystem.sol index 6f54d68b..cb2c5375 100644 --- a/packages/contracts/src/systems/order/OrderSystem.sol +++ b/packages/contracts/src/systems/order/OrderSystem.sol @@ -4,7 +4,7 @@ import { console } from "forge-std/console.sol"; import { System } from "@latticexyz/world/src/System.sol"; import { EntityType, CarriedBy, MaterialType, Order, Amount, CurrentOrder, DepotConnection, Tutorial, TutorialLevel, TutorialOrders, CompletedPlayers, FixedEntities, DepotsInPod } from "../../codegen/index.sol"; import { MACHINE_TYPE, ENTITY_TYPE, MATERIAL_TYPE } from "../../codegen/common.sol"; -import { LibUtils, LibOrder, LibToken } from "../../libraries/Libraries.sol"; +import { LibPlayer, LibOrder, LibToken } from "../../libraries/Libraries.sol"; contract OrderSystem is System { function create( @@ -33,7 +33,7 @@ contract OrderSystem is System { } function fill(bytes32 _depotEntity) public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); require(CarriedBy.get(_depotEntity) == podEntity, "not in pod"); @@ -91,7 +91,7 @@ contract OrderSystem is System { } function accept(bytes32 _orderEntity) public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); bytes32 podEntity = CarriedBy.get(playerEntity); require(CurrentOrder.get(podEntity) == bytes32(0), "order in progress"); @@ -113,7 +113,7 @@ contract OrderSystem is System { function buy() public { require(LibToken.getTokenBalance(_msgSender()) >= 100, "insufficient balance"); - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); // Get player's pod entity bytes32 podEntity = CarriedBy.get(playerEntity); diff --git a/packages/contracts/src/systems/progression/NameSystem.sol b/packages/contracts/src/systems/progression/NameSystem.sol index 835e8253..b1b658c3 100644 --- a/packages/contracts/src/systems/progression/NameSystem.sol +++ b/packages/contracts/src/systems/progression/NameSystem.sol @@ -2,11 +2,11 @@ pragma solidity >=0.8.24; import { System } from "@latticexyz/world/src/System.sol"; import { Tutorial, Name } from "../../codegen/index.sol"; -import { LibUtils, LibNetwork } from "../../libraries/Libraries.sol"; +import { LibUtils, LibNetwork, LibPlayer } from "../../libraries/Libraries.sol"; contract NameSystem is System { function name(string memory _name) public { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); // Only allow naming when tutorial is completed require(Tutorial.get(playerEntity) != false, "not completed"); require(!LibUtils.stringEq(_name, ""), "name empty"); diff --git a/packages/contracts/src/systems/progression/SpawnSystem.sol b/packages/contracts/src/systems/progression/SpawnSystem.sol index fc29bdbe..9e8cb61d 100644 --- a/packages/contracts/src/systems/progression/SpawnSystem.sol +++ b/packages/contracts/src/systems/progression/SpawnSystem.sol @@ -6,12 +6,7 @@ import { LibUtils, LibPlayer } from "../../libraries/Libraries.sol"; contract SpawnSystem is System { function spawn() public returns (bytes32) { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); - // @todo: check if already spawned - // Create player entity - LibPlayer.spawn(playerEntity); - - return playerEntity; + return LibPlayer.spawn(); } } diff --git a/packages/contracts/src/systems/progression/StartSystem.sol b/packages/contracts/src/systems/progression/StartSystem.sol index d1f9a31e..14ab9445 100644 --- a/packages/contracts/src/systems/progression/StartSystem.sol +++ b/packages/contracts/src/systems/progression/StartSystem.sol @@ -4,21 +4,19 @@ import { console } from "forge-std/console.sol"; import { System } from "@latticexyz/world/src/System.sol"; import { TutorialLevel, CarriedBy, EntityType, MachinesInPod, FixedEntities, FixedEntitiesData, DepotsInPod, MaterialType, Amount, Order, TutorialOrders, CurrentOrder, Tutorial } from "../../codegen/index.sol"; import { MACHINE_TYPE, MATERIAL_TYPE, ENTITY_TYPE } from "../../codegen/common.sol"; -import { LibUtils, LibPod, LibEntity, LibDepot, LibToken } from "../../libraries/Libraries.sol"; +import { LibPlayer, LibPod, LibMachineBuild, LibDepot, LibToken } from "../../libraries/Libraries.sol"; contract StartSystem is System { function start() public returns (bytes32) { - bytes32 playerEntity = LibUtils.addressToEntityKey(_msgSender()); - - // todo: check that player is spawned + bytes32 playerEntity = LibPlayer.getSpawnedPlayerEntity(); // Create pod bytes32 podEntity = LibPod.create(); // Create inlet entities bytes32[] memory inletEntities = new bytes32[](2); - inletEntities[0] = LibEntity.create(MACHINE_TYPE.INLET); - inletEntities[1] = LibEntity.create(MACHINE_TYPE.INLET); + inletEntities[0] = LibMachineBuild.create(MACHINE_TYPE.INLET); + inletEntities[1] = LibMachineBuild.create(MACHINE_TYPE.INLET); for (uint i; i < inletEntities.length; i++) { CarriedBy.set(inletEntities[i], podEntity); MachinesInPod.push(podEntity, inletEntities[i]); @@ -29,7 +27,7 @@ contract StartSystem is System { MachinesInPod.push(podEntity, playerEntity); // Create Outlet - bytes32 outletEntity = LibEntity.create(MACHINE_TYPE.OUTLET); + bytes32 outletEntity = LibMachineBuild.create(MACHINE_TYPE.OUTLET); CarriedBy.set(outletEntity, podEntity); MachinesInPod.push(podEntity, outletEntity); From cae208895802bebbb4b20ec9e50bc59c91447732 Mon Sep 17 00:00:00 2001 From: dk1a Date: Sat, 10 Feb 2024 17:21:49 +0300 Subject: [PATCH 2/2] testPlayerNotSpawned --- .../systems/machine-network/BuildSystem.t.sol | 12 ++++++++++ .../machine-network/ConnectSystem.t.sol | 23 +++++++++++++++++- .../machine-network/DestroySystem.t.sol | 21 ++++++++++++++++ .../machine-network/DisconnectSystem.t.sol | 24 +++++++++++++++++++ .../machine-network/ResolveSystem.t.sol | 15 ++++++++++++ 5 files changed, 94 insertions(+), 1 deletion(-) diff --git a/packages/contracts/test/systems/machine-network/BuildSystem.t.sol b/packages/contracts/test/systems/machine-network/BuildSystem.t.sol index e9fdc81f..321eeb54 100644 --- a/packages/contracts/test/systems/machine-network/BuildSystem.t.sol +++ b/packages/contracts/test/systems/machine-network/BuildSystem.t.sol @@ -24,6 +24,18 @@ contract BuildSystemTest is BaseTest { assertEq(CarriedBy.get(machineEntity), CarriedBy.get(playerEntity)); } + function testRevertNotSpawned() public { + setUp(); + + vm.startPrank(alice); + + // Create a new entity + vm.expectRevert("player not spawned"); + world.build(MACHINE_TYPE.SPLITTER); + + vm.stopPrank(); + } + function testRevertNotBuildable() public { setUp(); diff --git a/packages/contracts/test/systems/machine-network/ConnectSystem.t.sol b/packages/contracts/test/systems/machine-network/ConnectSystem.t.sol index 87969d24..20cd25bd 100644 --- a/packages/contracts/test/systems/machine-network/ConnectSystem.t.sol +++ b/packages/contracts/test/systems/machine-network/ConnectSystem.t.sol @@ -27,6 +27,27 @@ contract ConnectSystemTest is BaseTest { assertEq(IncomingConnections.get(splitterEntity)[0], playerEntity); } + function testRevertNotSpawned() public { + setUp(); + + vm.startPrank(alice); + + bytes32 playerEntity = world.spawn(); + world.start(); + + // Build a splitter + bytes32 splitterEntity = world.build(MACHINE_TYPE.SPLITTER); + + // Destroy player + world.destroy(playerEntity); + + // Connect player (first output == piss) to splitter + vm.expectRevert("player not spawned"); + world.connect(playerEntity, splitterEntity, PORT_INDEX.FIRST); + + vm.stopPrank(); + } + function testRevertNoInputs() public { setUp(); @@ -83,7 +104,7 @@ contract ConnectSystemTest is BaseTest { bytes32 playerEntity = world.spawn(); world.start(); - // Connect dryer to splitter + // Connect player to self vm.expectRevert("source and target are same"); world.connect(playerEntity, playerEntity, PORT_INDEX.FIRST); diff --git a/packages/contracts/test/systems/machine-network/DestroySystem.t.sol b/packages/contracts/test/systems/machine-network/DestroySystem.t.sol index eb8ba679..c0c03906 100644 --- a/packages/contracts/test/systems/machine-network/DestroySystem.t.sol +++ b/packages/contracts/test/systems/machine-network/DestroySystem.t.sol @@ -62,4 +62,25 @@ contract DestroySystemTest is BaseTest { vm.stopPrank(); } + + function testDestroyPlayer() public { + setUp(); + + vm.startPrank(alice); + + world.spawn(); + world.start(); + + bytes32 playerEntity = LibUtils.addressToEntityKey(alice); + + // Destroy player + world.destroy(playerEntity); + + // Check that the machine was destroyed + assertEq(uint8(EntityType.get(playerEntity)), uint8(ENTITY_TYPE.NONE)); + + // Build a dryer + vm.expectRevert("player not spawned"); + world.build(MACHINE_TYPE.SPLITTER); + } } diff --git a/packages/contracts/test/systems/machine-network/DisconnectSystem.t.sol b/packages/contracts/test/systems/machine-network/DisconnectSystem.t.sol index b1074cf6..9b6d5f73 100644 --- a/packages/contracts/test/systems/machine-network/DisconnectSystem.t.sol +++ b/packages/contracts/test/systems/machine-network/DisconnectSystem.t.sol @@ -34,6 +34,30 @@ contract DiconnectSystemTest is BaseTest { vm.stopPrank(); } + function testRevertNotSpawned() public { + setUp(); + + vm.startPrank(alice); + + bytes32 playerEntity = world.spawn(); + world.start(); + + // Build a splitter + bytes32 splitterEntity = world.build(MACHINE_TYPE.SPLITTER); + + // Connect player (first output == piss) to splitter + world.connect(playerEntity, splitterEntity, PORT_INDEX.FIRST); + + // Destroy player + world.destroy(playerEntity); + + // Disconnect player from splitter + vm.expectRevert("player not spawned"); + world.disconnect(playerEntity, PORT_INDEX.FIRST); + + vm.stopPrank(); + } + function testDisconnectSecondConnection() public { setUp(); diff --git a/packages/contracts/test/systems/machine-network/ResolveSystem.t.sol b/packages/contracts/test/systems/machine-network/ResolveSystem.t.sol index 3ae3b08d..3964064a 100644 --- a/packages/contracts/test/systems/machine-network/ResolveSystem.t.sol +++ b/packages/contracts/test/systems/machine-network/ResolveSystem.t.sol @@ -190,4 +190,19 @@ contract ResolveSystemTest is BaseTest { checkProcessing(blocksToWait, divisor, initialInletAmount, MATERIAL_TYPE.BUG, MATERIAL_TYPE.PISS); } + + function testRevertNotSpawned() public { + setUp(); + + vm.startPrank(alice); + + // Destroy player + world.destroy(playerEntity); + + // Resolve + vm.expectRevert("player not spawned"); + world.resolve(); + + vm.stopPrank(); + } }