diff --git a/examples/basic-world/packages/world/buildDeployHandler.tsx b/examples/basic-world/packages/world/buildDeployHandler.tsx index 289410e94..eec3507d2 100644 --- a/examples/basic-world/packages/world/buildDeployHandler.tsx +++ b/examples/basic-world/packages/world/buildDeployHandler.tsx @@ -23,7 +23,7 @@ if (!action) { if (action == "build") { // List of dev commands - const setRegistryAddressCommand = `node ../../../../scripts/setAddress.js ${chainId} ../../../../packages/registry/worlds.json src/Constants.sol REGISTRY_ADDRESS`; + const setRegistryAddressCommand = `node ../../../../scripts/setAddress.js ${chainId} ../../../../packages/registry/worlds.json ../../../../packages/base-world/src/Constants.sol REGISTRY_ADDRESS`; const setSimAddressCommand = `node ../../../../scripts/setAddress.js ${chainId} ../simulator/worlds.json src/Constants.sol SIMULATOR_ADDRESS`; const devCommands = [setRegistryAddressCommand, setSimAddressCommand, "yarn run initialize"]; diff --git a/examples/basic-world/packages/world/src/Constants.sol b/examples/basic-world/packages/world/src/Constants.sol index d30ec939d..16f980508 100644 --- a/examples/basic-world/packages/world/src/Constants.sol +++ b/examples/basic-world/packages/world/src/Constants.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -address constant REGISTRY_ADDRESS = 0x057ef64E23666F000b34aE31332854aCBd1c8544; address constant SIMULATOR_ADDRESS = 0x5FbDB2315678afecb367f032d93F642f64180aa3; uint256 constant NUM_MAX_OBJECTS_INTERACTION_RUN = 100; diff --git a/examples/basic-world/packages/world/src/systems/ObjectInteractionSystem.sol b/examples/basic-world/packages/world/src/systems/ObjectInteractionSystem.sol index e0e16cc11..6ac4f600f 100644 --- a/examples/basic-world/packages/world/src/systems/ObjectInteractionSystem.sol +++ b/examples/basic-world/packages/world/src/systems/ObjectInteractionSystem.sol @@ -4,14 +4,10 @@ pragma solidity >=0.8.0; import { IStore } from "@latticexyz/store/src/IStore.sol"; import { System } from "@latticexyz/world/src/System.sol"; -import { REGISTRY_ADDRESS, SIMULATOR_ADDRESS, NUM_MAX_OBJECTS_INTERACTION_RUN } from "@tenet-world/src/Constants.sol"; +import { SIMULATOR_ADDRESS, NUM_MAX_OBJECTS_INTERACTION_RUN } from "@tenet-world/src/Constants.sol"; import { ObjectInteractionSystem as ObjectInteractionProtoSystem } from "@tenet-base-world/src/systems/ObjectInteractionSystem.sol"; contract ObjectInteractionSystem is ObjectInteractionProtoSystem { - function getRegistryAddress() internal pure override returns (address) { - return REGISTRY_ADDRESS; - } - function getSimulatorAddress() internal pure override returns (address) { return SIMULATOR_ADDRESS; } diff --git a/examples/basic-world/packages/world/src/systems/ObjectSystem.sol b/examples/basic-world/packages/world/src/systems/ObjectSystem.sol index 1f106dfff..a8b7ad2da 100644 --- a/examples/basic-world/packages/world/src/systems/ObjectSystem.sol +++ b/examples/basic-world/packages/world/src/systems/ObjectSystem.sol @@ -6,14 +6,9 @@ import { System } from "@latticexyz/world/src/System.sol"; import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS } from "@tenet-world/src/Constants.sol"; import { ObjectSystem as ObjectProtoSystem } from "@tenet-base-world/src/systems/ObjectSystem.sol"; contract ObjectSystem is ObjectProtoSystem { - function getRegistryAddress() internal pure override returns (address) { - return REGISTRY_ADDRESS; - } - function enterWorld( bytes32 objectTypeId, VoxelCoord memory coord, diff --git a/examples/basic-world/packages/world/src/systems/objects/AirObjectSystem.sol b/examples/basic-world/packages/world/src/systems/objects/AirObjectSystem.sol index efdba6ad3..43ae58953 100644 --- a/examples/basic-world/packages/world/src/systems/objects/AirObjectSystem.sol +++ b/examples/basic-world/packages/world/src/systems/objects/AirObjectSystem.sol @@ -17,8 +17,10 @@ contract AirObjectSystem is ObjectType { IWorld(world).world_AirObjectSystem_exitWorld.selector, IWorld(world).world_AirObjectSystem_eventHandler.selector, IWorld(world).world_AirObjectSystem_neighbourEventHandler.selector, - "Air", - "" + 0, + 0, + 0, + "Air" ); } diff --git a/examples/basic-world/packages/world/src/systems/objects/BedrockObjectSystem.sol b/examples/basic-world/packages/world/src/systems/objects/BedrockObjectSystem.sol index 0c2a0a48a..157cf721c 100644 --- a/examples/basic-world/packages/world/src/systems/objects/BedrockObjectSystem.sol +++ b/examples/basic-world/packages/world/src/systems/objects/BedrockObjectSystem.sol @@ -17,8 +17,10 @@ contract BedrockObjectSystem is ObjectType { IWorld(world).world_BedrockObjectSys_exitWorld.selector, IWorld(world).world_BedrockObjectSys_eventHandler.selector, IWorld(world).world_BedrockObjectSys_neighbourEventHandler.selector, - "Bedrock", - "" + 99, + 0, + 0, + "Bedrock" ); } diff --git a/examples/basic-world/packages/world/src/systems/objects/DirtObjectSystem.sol b/examples/basic-world/packages/world/src/systems/objects/DirtObjectSystem.sol index 98b71d22f..a3ba791bf 100644 --- a/examples/basic-world/packages/world/src/systems/objects/DirtObjectSystem.sol +++ b/examples/basic-world/packages/world/src/systems/objects/DirtObjectSystem.sol @@ -17,8 +17,10 @@ contract DirtObjectSystem is ObjectType { IWorld(world).world_DirtObjectSystem_exitWorld.selector, IWorld(world).world_DirtObjectSystem_eventHandler.selector, IWorld(world).world_DirtObjectSystem_neighbourEventHandler.selector, - "Dirt", - "" + 99, + 0, + 0, + "Dirt" ); } diff --git a/examples/basic-world/packages/world/src/systems/objects/GrassObjectSystem.sol b/examples/basic-world/packages/world/src/systems/objects/GrassObjectSystem.sol index 14f703eec..60aa5c5ae 100644 --- a/examples/basic-world/packages/world/src/systems/objects/GrassObjectSystem.sol +++ b/examples/basic-world/packages/world/src/systems/objects/GrassObjectSystem.sol @@ -17,8 +17,10 @@ contract GrassObjectSystem is ObjectType { IWorld(world).world_GrassObjectSyste_exitWorld.selector, IWorld(world).world_GrassObjectSyste_eventHandler.selector, IWorld(world).world_GrassObjectSyste_neighbourEventHandler.selector, - "Grass", - "" + 99, + 0, + 0, + "Grass" ); } diff --git a/examples/basic-world/packages/world/src/systems/objects/agents/BuilderObjectSystem.sol b/examples/basic-world/packages/world/src/systems/objects/agents/BuilderObjectSystem.sol index 0e82de10f..b8c0946a1 100644 --- a/examples/basic-world/packages/world/src/systems/objects/agents/BuilderObjectSystem.sol +++ b/examples/basic-world/packages/world/src/systems/objects/agents/BuilderObjectSystem.sol @@ -17,8 +17,10 @@ contract BuilderObjectSystem is AgentType { IWorld(world).world_BuilderObjectSys_exitWorld.selector, IWorld(world).world_BuilderObjectSys_eventHandler.selector, IWorld(world).world_BuilderObjectSys_neighbourEventHandler.selector, - "Builder", - "" + 1, + 0, + 0, + "Builder" ); } diff --git a/examples/everlon/README.md b/examples/everlon/README.md index 4d849500f..d8910a3aa 100644 --- a/examples/everlon/README.md +++ b/examples/everlon/README.md @@ -2,9 +2,6 @@ ## Simulator -The following is an overview diagram of the rules and constraints currently in Everlon. -![everlon constraints rules](./everlon-constraints-rules.jpg) - ### Running locally `./t run dev everlon --with-extensions ` diff --git a/examples/everlon/everlon-constraints-rules.jpg b/examples/everlon/everlon-constraints-rules.jpg deleted file mode 100644 index 471e2330d..000000000 Binary files a/examples/everlon/everlon-constraints-rules.jpg and /dev/null differ diff --git a/examples/everlon/packages/derived/src/Constants.sol b/examples/everlon/packages/derived/src/Constants.sol index eb5ed616a..9e0511cae 100644 --- a/examples/everlon/packages/derived/src/Constants.sol +++ b/examples/everlon/packages/derived/src/Constants.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -address constant REGISTRY_ADDRESS = 0x057ef64E23666F000b34aE31332854aCBd1c8544; -address constant WORLD_ADDRESS = 0x99dBE4AEa58E518C50a1c04aE9b48C9F6354612f; -address constant SIMULATOR_ADDRESS = 0x5FbDB2315678afecb367f032d93F642f64180aa3; +address constant REGISTRY_ADDRESS = 0x5FbDB2315678afecb367f032d93F642f64180aa3; +address constant WORLD_ADDRESS = 0xde2Bd2ffEA002b8E84ADeA96e5976aF664115E2c; +address constant SIMULATOR_ADDRESS = 0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44; diff --git a/examples/everlon/packages/pretty/.env b/examples/everlon/packages/pretty/.env index 5090fa22b..0f8cc4a30 100644 --- a/examples/everlon/packages/pretty/.env +++ b/examples/everlon/packages/pretty/.env @@ -5,4 +5,4 @@ # development. Please do not commit changes to this file! # # Anvil default private key: -PRIVATE_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a +PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 diff --git a/examples/everlon/packages/pretty/deployPrettyObjects.tsx b/examples/everlon/packages/pretty/deployPrettyObjects.tsx index e2feca241..430cf2232 100644 --- a/examples/everlon/packages/pretty/deployPrettyObjects.tsx +++ b/examples/everlon/packages/pretty/deployPrettyObjects.tsx @@ -152,8 +152,10 @@ async function main() { exitWorldSelector, eventHandlerSelector, neighbourEventHandlerSelector, - objectTypeDisplayName, - "" + 99, + 0, + 0, + objectTypeDisplayName ); // Check the status of each transaction diff --git a/examples/everlon/packages/pretty/src/systems/objects/PrettyObjectSystem.sol b/examples/everlon/packages/pretty/src/systems/objects/PrettyObjectSystem.sol index 70a9a3db7..8d33beb00 100644 --- a/examples/everlon/packages/pretty/src/systems/objects/PrettyObjectSystem.sol +++ b/examples/everlon/packages/pretty/src/systems/objects/PrettyObjectSystem.sol @@ -17,8 +17,10 @@ contract PrettyObjectSystem is ObjectType { IWorld(world).pretty_PrettyObjectSyst_exitWorld.selector, IWorld(world).pretty_PrettyObjectSyst_eventHandler.selector, IWorld(world).pretty_PrettyObjectSyst_neighbourEventHandler.selector, - "Pretty Template", - "" + 99, + 0, + 0, + "Pretty Template" ); } diff --git a/examples/everlon/packages/simulator/src/Constants.sol b/examples/everlon/packages/simulator/src/Constants.sol index 907863c12..817a3d459 100644 --- a/examples/everlon/packages/simulator/src/Constants.sol +++ b/examples/everlon/packages/simulator/src/Constants.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -address constant REGISTRY_ADDRESS = 0x057ef64E23666F000b34aE31332854aCBd1c8544; +address constant REGISTRY_ADDRESS = 0x5FbDB2315678afecb367f032d93F642f64180aa3; uint256 constant MAX_AGENT_HEALTH = 100; uint256 constant MAX_AGENT_STAMINA = 200000; diff --git a/examples/everlon/packages/simulator/src/systems/rules/VelocityRuleSystem.sol b/examples/everlon/packages/simulator/src/systems/rules/VelocityRuleSystem.sol index a4c7670ad..3d73d8f68 100644 --- a/examples/everlon/packages/simulator/src/systems/rules/VelocityRuleSystem.sol +++ b/examples/everlon/packages/simulator/src/systems/rules/VelocityRuleSystem.sol @@ -126,7 +126,9 @@ contract VelocityRuleSystem is System { InventoryObject.getObjectProperties(IStore(worldAddress), inventoryIds[i][0]), (ObjectProperties) ); - inventoryMass += objectProperties.mass; + inventoryMass += + (objectProperties.mass) * + InventoryObject.getNumObjects(IStore(worldAddress), inventoryIds[i][0]); } // add inventory mass to resourceRequired resourceRequired += (inventoryMass / 50); diff --git a/examples/everlon/packages/world/buildDeployHandler.tsx b/examples/everlon/packages/world/buildDeployHandler.tsx index 289410e94..eec3507d2 100644 --- a/examples/everlon/packages/world/buildDeployHandler.tsx +++ b/examples/everlon/packages/world/buildDeployHandler.tsx @@ -23,7 +23,7 @@ if (!action) { if (action == "build") { // List of dev commands - const setRegistryAddressCommand = `node ../../../../scripts/setAddress.js ${chainId} ../../../../packages/registry/worlds.json src/Constants.sol REGISTRY_ADDRESS`; + const setRegistryAddressCommand = `node ../../../../scripts/setAddress.js ${chainId} ../../../../packages/registry/worlds.json ../../../../packages/base-world/src/Constants.sol REGISTRY_ADDRESS`; const setSimAddressCommand = `node ../../../../scripts/setAddress.js ${chainId} ../simulator/worlds.json src/Constants.sol SIMULATOR_ADDRESS`; const devCommands = [setRegistryAddressCommand, setSimAddressCommand, "yarn run initialize"]; diff --git a/examples/everlon/packages/world/mud.config.ts b/examples/everlon/packages/world/mud.config.ts index c7fc36512..936af5316 100644 --- a/examples/everlon/packages/world/mud.config.ts +++ b/examples/everlon/packages/world/mud.config.ts @@ -58,6 +58,46 @@ export default tenetMudConfig({ }, }, systems: { + RecipeSystem: { + name: "RecipeSystem", + openAccess: true, + registerAsRoot: true, + }, + RecipeSystemTwo: { + name: "RecipeSystemTwo", + openAccess: true, + registerAsRoot: true, + }, + RecipeSysThree: { + name: "RecipeSysThree", + openAccess: true, + registerAsRoot: true, + }, + RecipeSysDye: { + name: "RecipeSysDye", + openAccess: true, + registerAsRoot: true, + }, + RecipeColorOak: { + name: "RecipeColorOak", + openAccess: true, + registerAsRoot: true, + }, + RecipeColorCott: { + name: "RecipeColorCott", + openAccess: true, + registerAsRoot: true, + }, + RecipeColorGlass: { + name: "RecipeColorGlass", + openAccess: true, + registerAsRoot: true, + }, + RecipeStations: { + name: "RecipeStations", + openAccess: true, + registerAsRoot: true, + }, FaucetSystem: { name: "FaucetSystem", openAccess: true, diff --git a/examples/everlon/packages/world/script/PostDeploy.s.sol b/examples/everlon/packages/world/script/PostDeploy.s.sol index 7318cbcbb..23a506cfc 100644 --- a/examples/everlon/packages/world/script/PostDeploy.s.sol +++ b/examples/everlon/packages/world/script/PostDeploy.s.sol @@ -14,6 +14,15 @@ contract PostDeploy is Script { IWorld world = IWorld(worldAddress); + world.initRecipes(); + world.initRecipesTwo(); + world.initRecipesThree(); + world.initRecipeSysDye(); + world.initRecipeColorOak(); + world.initRecipeColorCott(); + world.initRecipeColorGlass(); + world.initRecipeStations(); + world.world_AirObjectSystem_registerObject(); world.world_SnowObjectSystem_registerObject(); @@ -33,6 +42,7 @@ contract PostDeploy is Script { world.world_OakLogObjectSyst_registerObject(); world.world_OakLeafObjectSys_registerObject(); + world.world_OakLumberObjectS_registerObject(); world.world_BirchLogObjectSy_registerObject(); world.world_BirchLeafObjectS_registerObject(); world.world_SakuraLogObjectS_registerObject(); @@ -63,6 +73,11 @@ contract PostDeploy is Script { world.world_LavaObjectSystem_registerObject(); world.world_BedrockObjectSys_registerObject(); + world.world_ChestObjectSyste_registerObject(); + + // Items + world.world_WoodenPickObject_registerObject(); + // Agents world.world_BuilderObjectSys_registerObject(); world.world_FaucetObjectSyst_registerObject(); diff --git a/examples/everlon/packages/world/src/Constants.sol b/examples/everlon/packages/world/src/Constants.sol index 2a54610e6..28a51fbff 100644 --- a/examples/everlon/packages/world/src/Constants.sol +++ b/examples/everlon/packages/world/src/Constants.sol @@ -1,40 +1,95 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -address constant REGISTRY_ADDRESS = 0x057ef64E23666F000b34aE31332854aCBd1c8544; -address constant SIMULATOR_ADDRESS = 0x5FbDB2315678afecb367f032d93F642f64180aa3; +import { REGISTRY_ADDRESS } from "@tenet-base-world/src/Constants.sol"; + +address constant SIMULATOR_ADDRESS = 0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44; uint256 constant NUM_MAX_OBJECTS_INTERACTION_RUN = 1000; uint256 constant NUM_MAX_UNIQUE_OBJECT_EVENT_HANDLERS_RUN = 15; uint256 constant NUM_MAX_SAME_OBJECT_EVENT_HANDLERS_RUN = 25; int32 constant NUM_MAX_AGENT_ACTION_RADIUS = 5; +uint8 constant NUM_BLOCK_STACKABLE = 99; + +uint256 constant MAX_CHEST_SLOTS = 12; + bytes32 constant AirObjectID = bytes32(keccak256("air")); bytes32 constant SnowObjectID = bytes32(keccak256("snow")); bytes32 constant AsphaltObjectID = bytes32(keccak256("asphalt")); bytes32 constant BasaltObjectID = bytes32(keccak256("basalt")); +bytes32 constant PaperObjectID = bytes32(keccak256("paper")); +bytes32 constant BasaltBrickObjectID = bytes32(keccak256("basalt-brick")); +bytes32 constant BasaltCarvedObjectID = bytes32(keccak256("basalt-carved")); +bytes32 constant BasaltPolishedObjectID = bytes32(keccak256("basalt-polished")); +bytes32 constant BasaltShinglesObjectID = bytes32(keccak256("basalt-shingles")); bytes32 constant ClayBrickObjectID = bytes32(keccak256("clay-brick")); +bytes32 constant ClayCarvedObjectID = bytes32(keccak256("clay-carved")); +bytes32 constant ClayPolishedObjectID = bytes32(keccak256("clay-polished")); +bytes32 constant ClayShinglesObjectID = bytes32(keccak256("clay-shingles")); bytes32 constant CottonObjectID = bytes32(keccak256("cotton")); +bytes32 constant CottonBlockObjectID = bytes32(keccak256("cotton-block")); bytes32 constant StoneObjectID = bytes32(keccak256("stone")); +bytes32 constant StoneAxeObjectID = bytes32(keccak256("stone-axe")); +bytes32 constant StonePickObjectID = bytes32(keccak256("stone-pick")); +bytes32 constant StoneWhackerObjectID = bytes32(keccak256("stone-pick")); +bytes32 constant StoneShinglesObjectID = bytes32(keccak256("stone-shingles")); +bytes32 constant PolishedStoneObjectID = bytes32(keccak256("polished-stone")); +bytes32 constant StoneCarvedObjectID = bytes32(keccak256("stone-carved")); +bytes32 constant StoneBrickObjectID = bytes32(keccak256("stone-brick")); +bytes32 constant RubbleObjectID = bytes32(keccak256("rubble")); bytes32 constant EmberstoneObjectID = bytes32(keccak256("emberstone")); bytes32 constant CobblestoneObjectID = bytes32(keccak256("cobblestone")); bytes32 constant MoonstoneObjectID = bytes32(keccak256("moonstone")); bytes32 constant GraniteObjectID = bytes32(keccak256("granite")); bytes32 constant QuartziteObjectID = bytes32(keccak256("quartzite")); +bytes32 constant QuartziteBrickObjectID = bytes32(keccak256("quartzite-brick")); +bytes32 constant QuartziteCarvedObjectID = bytes32(keccak256("quartzite-carved")); +bytes32 constant QuartzitePolishedObjectID = bytes32(keccak256("quartzite-polished")); +bytes32 constant QuartziteShinglesObjectID = bytes32(keccak256("quartzite-shingles")); bytes32 constant LimestoneObjectID = bytes32(keccak256("limestone")); +bytes32 constant LimestoneBrickObjectID = bytes32(keccak256("limestone-brick")); +bytes32 constant LimestoneCarvedObjectID = bytes32(keccak256("limestone-carved")); +bytes32 constant LimestonePolishedObjectID = bytes32(keccak256("limestone-polished")); +bytes32 constant LimestoneShinglesObjectID = bytes32(keccak256("limestone-shingles")); bytes32 constant SunstoneObjectID = bytes32(keccak256("sunstone")); bytes32 constant SoilObjectID = bytes32(keccak256("soil")); +bytes32 constant SandObjectID = bytes32(keccak256("sand")); +bytes32 constant GlassObjectID = bytes32(keccak256("glass")); bytes32 constant GravelObjectID = bytes32(keccak256("gravel")); bytes32 constant ClayObjectID = bytes32(keccak256("clay")); bytes32 constant BedrockObjectID = bytes32(keccak256("bedrock")); bytes32 constant LavaObjectID = bytes32(keccak256("lava")); bytes32 constant DiamondOreObjectID = bytes32(keccak256("diamond-ore")); +bytes32 constant DiamondObjectID = bytes32(keccak256("diamond")); bytes32 constant GoldOreObjectID = bytes32(keccak256("gold-ore")); +bytes32 constant GoldBarObjectID = bytes32(keccak256("gold-bar")); +bytes32 constant GoldCubeObjectID = bytes32(keccak256("gold-cube")); +bytes32 constant GoldAxeObjectID = bytes32(keccak256("gold-axe")); +bytes32 constant GoldPickObjectID = bytes32(keccak256("gold-pick")); +bytes32 constant NeptuniumAxeObjectID = bytes32(keccak256("neptunium-axe")); +bytes32 constant NeptuniumPickObjectID = bytes32(keccak256("neptunium-pick")); bytes32 constant CoalOreObjectID = bytes32(keccak256("coal-ore")); bytes32 constant SilverOreObjectID = bytes32(keccak256("silver-ore")); +bytes32 constant SilverBarObjectID = bytes32(keccak256("silver-ore")); +bytes32 constant SilverCubeObjectID = bytes32(keccak256("silver-cube")); +bytes32 constant SilverAxeObjectID = bytes32(keccak256("silver-axe")); +bytes32 constant SilverPickObjectID = bytes32(keccak256("silver-pick")); +bytes32 constant SilverWhackerObjectID = bytes32(keccak256("silver-whacker")); bytes32 constant NeptuniumOreObjectID = bytes32(keccak256("neptunium-ore")); +bytes32 constant NeptuniumBarObjectID = bytes32(keccak256("neptunium-bar")); +bytes32 constant NeptuniumCubeObjectID = bytes32(keccak256("neptunium-cube")); bytes32 constant GrassObjectID = bytes32(keccak256("grass")); +bytes32 constant HempObjectID = bytes32(keccak256("hemp")); +bytes32 constant LilacObjectID = bytes32(keccak256("lilac")); +bytes32 constant DandelionObjectID = bytes32(keccak256("dandelion")); bytes32 constant MuckGrassObjectID = bytes32(keccak256("muck-grass")); +bytes32 constant MuckshroomObjectID = bytes32(keccak256("muckshroom")); +bytes32 constant RedMushroomObjectID = bytes32(keccak256("red-mushroom")); +bytes32 constant RedMushroomSporesObjectID = bytes32(keccak256("red-mushroom-spores")); +bytes32 constant MushroomLeatherBlockObjectID = bytes32(keccak256("mushroom-leather")); +bytes32 constant BellflowerObjectID = bytes32(keccak256("bellflower")); +bytes32 constant BlueMushroomSporeObjectID = bytes32(keccak256("blue-mushroom-spore")); bytes32 constant DirtObjectID = bytes32(keccak256("dirt")); bytes32 constant MuckDirtObjectID = bytes32(keccak256("muck-dirt")); bytes32 constant MossObjectID = bytes32(keccak256("moss")); @@ -42,13 +97,95 @@ bytes32 constant CottonBushObjectID = bytes32(keccak256("cotton-bush")); bytes32 constant MossGrassObjectID = bytes32(keccak256("moss-grass")); bytes32 constant SwitchGrassObjectID = bytes32(keccak256("switch-grass")); bytes32 constant OakLogObjectID = bytes32(keccak256("oak-log")); +bytes32 constant OakLumberObjectID = bytes32(keccak256("oak-lumber")); +bytes32 constant MuckshroomSporesObjectID = bytes32(keccak256("muckshroom-spores")); +bytes32 constant ReinforcedOakLumberObjectID = bytes32(keccak256("reinforced-oak-lumber")); +bytes32 constant SakuraLumberObjectID = bytes32(keccak256("sakura-lumber")); +bytes32 constant RubberLogObjectID = bytes32(keccak256("rubber-log")); +bytes32 constant RubberLumberObjectID = bytes32(keccak256("rubber-lumber")); +bytes32 constant ReinforcedRubberLumberObjectID = bytes32(keccak256("reinforced-rubber-lumber")); +bytes32 constant GraniteBrickObjectID = bytes32(keccak256("granite-brick")); +bytes32 constant GraniteCarvedObjectID = bytes32(keccak256("granite-carved")); +bytes32 constant GraniteShinglesObjectID = bytes32(keccak256("granite-shingles")); +bytes32 constant GranitePolishedObjectID = bytes32(keccak256("granite-polished")); bytes32 constant BirchLogObjectID = bytes32(keccak256("birch-log")); +bytes32 constant BirchLumberObjectID = bytes32(keccak256("birch-lumber")); +bytes32 constant ReinforcedBirchLumberObjectID = bytes32(keccak256("reinforced-birch-lumber")); bytes32 constant SakuraLogObjectID = bytes32(keccak256("sakura-log")); -bytes32 constant RubberLogObjectID = bytes32(keccak256("rubber-log")); bytes32 constant OakLeafObjectID = bytes32(keccak256("oak-leaf")); bytes32 constant BirchLeafObjectID = bytes32(keccak256("birch-leaf")); bytes32 constant SakuraLeafObjectID = bytes32(keccak256("sakura-leaf")); bytes32 constant RubberLeafObjectID = bytes32(keccak256("rubber-leaf")); +bytes32 constant DaylilyObjectID = bytes32(keccak256("daylily")); +bytes32 constant AzaleaObjectID = bytes32(keccak256("azalea")); +bytes32 constant RoseObjectID = bytes32(keccak256("rose")); +bytes32 constant ChestObjectID = bytes32(keccak256("chest")); +bytes32 constant ThermoblasterObjectID = bytes32(keccak256("thermoblaster")); +bytes32 constant WorkbenchObjectID = bytes32(keccak256("workbench")); +bytes32 constant DyeomaticObjectID = bytes32(keccak256("dye-o-matic")); +bytes32 constant CobblestoneBrickObjectID = bytes32(keccak256("cobblestone-brick")); +bytes32 constant WoodenPickObjectID = bytes32(keccak256("wooden-pick")); +bytes32 constant WoodenAxeObjectID = bytes32(keccak256("wooden-axe")); +bytes32 constant WoodenWhackerObjectID = bytes32(keccak256("wooden-whacker")); +bytes32 constant DiamondAxeObjectID = bytes32(keccak256("diamond-axe")); +bytes32 constant DiamondPickObjectID = bytes32(keccak256("diamond-axe")); +bytes32 constant DiamondCubeObjectID = bytes32(keccak256("diamond-cube")); +bytes32 constant BlueDyeObjectID = bytes32(keccak256("blue-dye")); +bytes32 constant BrownDyeObjectID = bytes32(keccak256("brown-dye")); +bytes32 constant GreenDyeObjectID = bytes32(keccak256("green-dye")); +bytes32 constant MagentaDyeObjectID = bytes32(keccak256("magenta-dye")); +bytes32 constant OrangeDyeObjectID = bytes32(keccak256("orange-dye")); +bytes32 constant PinkDyeObjectID = bytes32(keccak256("pink-dye")); +bytes32 constant PurpleDyeObjectID = bytes32(keccak256("purple-dye")); +bytes32 constant RedDyeObjectID = bytes32(keccak256("red-dye")); +bytes32 constant TanDyeObjectID = bytes32(keccak256("tan-dye")); +bytes32 constant WhiteDyeObjectID = bytes32(keccak256("white-dye")); +bytes32 constant YellowDyeObjectID = bytes32(keccak256("yellow-dye")); +bytes32 constant BlackDyeObjectID = bytes32(keccak256("black-dye")); +bytes32 constant SilverDyeObjectID = bytes32(keccak256("silver-dye")); + +bytes32 constant BlueOakLumberObjectID = bytes32(keccak256("blue-oak-lumber")); +bytes32 constant BrownOakLumberObjectID = bytes32(keccak256("brown-oak-lumber")); +bytes32 constant GreenOakLumberObjectID = bytes32(keccak256("green-oak-lumber")); +bytes32 constant MagentaOakLumberObjectID = bytes32(keccak256("magenta-oak-lumber")); +bytes32 constant OrangeOakLumberObjectID = bytes32(keccak256("orange-oak-lumber")); +bytes32 constant PinkOakLumberObjectID = bytes32(keccak256("pink-oak-lumber")); +bytes32 constant PurpleOakLumberObjectID = bytes32(keccak256("purple-oak-lumber")); +bytes32 constant RedOakLumberObjectID = bytes32(keccak256("red-oak-lumber")); +bytes32 constant TanOakLumberObjectID = bytes32(keccak256("tan-oak-lumber")); +bytes32 constant WhiteOakLumberObjectID = bytes32(keccak256("white-oak-lumber")); +bytes32 constant YellowOakLumberObjectID = bytes32(keccak256("yellow-oak-lumber")); +bytes32 constant BlackOakLumberObjectID = bytes32(keccak256("black-oak-lumber")); +bytes32 constant SilverOakLumberObjectID = bytes32(keccak256("silver-oak-lumber")); + +bytes32 constant BlueCottonBlockObjectID = bytes32(keccak256("blue-cotton-block")); +bytes32 constant BrownCottonBlockObjectID = bytes32(keccak256("brown-cotton-block")); +bytes32 constant GreenCottonBlockObjectID = bytes32(keccak256("green-cotton-block")); +bytes32 constant MagentaCottonBlockObjectID = bytes32(keccak256("magenta-cotton-block")); +bytes32 constant OrangeCottonBlockObjectID = bytes32(keccak256("orange-cotton-block")); +bytes32 constant PinkCottonBlockObjectID = bytes32(keccak256("pink-cotton-block")); +bytes32 constant PurpleCottonBlockObjectID = bytes32(keccak256("purple-cotton-block")); +bytes32 constant RedCottonBlockObjectID = bytes32(keccak256("red-cotton-block")); +bytes32 constant TanCottonBlockObjectID = bytes32(keccak256("tan-cotton-block")); +bytes32 constant WhiteCottonBlockObjectID = bytes32(keccak256("white-cotton-block")); +bytes32 constant YellowCottonBlockObjectID = bytes32(keccak256("yellow-cotton-block")); +bytes32 constant BlackCottonBlockObjectID = bytes32(keccak256("black-cotton-block")); +bytes32 constant SilverCottonBlockObjectID = bytes32(keccak256("silver-cotton-block")); + +bytes32 constant BlueGlassObjectID = bytes32(keccak256("blue-glass")); +bytes32 constant BrownGlassObjectID = bytes32(keccak256("brown-glass")); +bytes32 constant GreenGlassObjectID = bytes32(keccak256("green-glass")); +bytes32 constant MagentaGlassObjectID = bytes32(keccak256("magenta-glass")); +bytes32 constant OrangeGlassObjectID = bytes32(keccak256("orange-glass")); +bytes32 constant PinkGlassObjectID = bytes32(keccak256("pink-glass")); +bytes32 constant PurpleGlassObjectID = bytes32(keccak256("purple-glass")); +bytes32 constant RedGlassObjectID = bytes32(keccak256("red-glass")); +bytes32 constant TanGlassObjectID = bytes32(keccak256("tan-glass")); +bytes32 constant WhiteGlassObjectID = bytes32(keccak256("white-glass")); +bytes32 constant YellowGlassObjectID = bytes32(keccak256("yellow-glass")); +bytes32 constant BlackGlassObjectID = bytes32(keccak256("black-glass")); +bytes32 constant SilverGlassObjectID = bytes32(keccak256("silver-glass")); + // Agents bytes32 constant BuilderObjectID = bytes32(keccak256("builder")); @@ -60,7 +197,7 @@ uint256 constant PLAYER_MASS = 10; uint256 constant AIR_MASS = 0; uint256 constant SOIL_MASS = 3; uint256 constant GRAVEL_MASS = 5; -uint256 constant CLAY_MASS = 6; +uint256 constant CLAY_MASS = 16; uint256 constant LAVA_MASS = 2; uint256 constant BEDROCK_MASS = 1000; uint256 constant MOSS_GRASS_MASS = 1; @@ -69,41 +206,199 @@ uint256 constant COTTON_BUSH_MASS = 1; uint256 constant MOSS_MASS = 4; uint256 constant MUCK_GRASS_MASS = 4; uint256 constant GRASS_MASS = 4; +uint256 constant HEMP_MASS = 1; +uint256 constant LILAC_MASS = 1; +uint256 constant DANDELION_MASS = 1; +uint256 constant ROSE_MASS = 1; +uint256 constant DAYLILY_MASS = 1; +uint256 constant AZALEA_MASS = 1; + uint256 constant MUCK_DIRT_MASS = 4; uint256 constant DIRT_MASS = 4; uint256 constant COAL_ORE_MASS = 7; uint256 constant SILVER_ORE_MASS = 9; +uint256 constant SILVER_BAR_MASS = 36; //9*4 = 36 +uint256 constant SILVER_CUBE_MASS = 288; //36*8 = 288 +uint256 constant SILVER_AXE_MASS = 160; //36*4 + 4*4 = 160 +uint256 constant SILVER_PICK_MASS = 160; //36*4 + 4*4 = 160 +uint256 constant SILVER_WHACKER_MASS = 216; //36*6 = 216 + uint256 constant GOLD_ORE_MASS = 10; +uint256 constant GOLD_BAR_MASS = 40; +uint256 constant GOLD_CUBE_MASS = 320; +uint256 constant GOLD_AXE_MASS = 176; +uint256 constant GOLD_PICK_MASS = 176; + uint256 constant DIAMOND_ORE_MASS = 15; +uint256 constant DIAMOND_MASS = 60; +uint256 constant DIAMOND_CUBE_MASS = 480; //60 * 8 = 480 + uint256 constant NEPTUNIUM_ORE_MASS = 20; +uint256 constant NEPTUNIUM_BAR_MASS = 80; +uint256 constant NEPTUNIUM_CUBE_MASS = 640; //80 * 8 = 640 uint256 constant SNOW_MASS = 1; uint256 constant ASPHALT_MASS = 8; uint256 constant BASALT_MASS = 9; -uint256 constant CLAY_BRICK_MASS = 8; uint256 constant COTTON_MASS = 1; +uint256 constant SAND_MASS = 2; +uint256 constant GLASS_MASS = 11; uint256 constant STONE_MASS = 7; +uint256 constant STONE_AXE_MASS = 72; //56 + 16 = 72 +uint256 constant STONE_PICK_MASS = 72; //56 + 16 = 72 +uint256 constant STONE_WHACKER_MASS = 36; //7*4 + 4*2 = 36 + +uint256 constant POLISHED_STONE_MASS = 7; +uint256 constant STONE_CARVED_MASS = 7; +uint256 constant STONE_BRICK_MASS = 7; +uint256 constant STONE_SHINGLES_MASS = 7; + +uint256 constant RUBBLE_MASS = 2; uint256 constant COBBLESTONE_MASS = 7; uint256 constant GRANITE_MASS = 11; +uint256 constant GRANITE_BRICK_MASS = 11; +uint256 constant GRANITE_CARVED_MASS = 11; +uint256 constant GRANITE_POLISHED_MASS = 11; +uint256 constant GRANITE_SHINGLES_MASS = 11; + uint256 constant LIMESTONE_MASS = 7; +uint256 constant LIMESTONE_BRICK_MASS = 7; +uint256 constant LIMESTONE_CARVED_MASS = 7; +uint256 constant LIMESTONE_POLISHED_MASS = 7; +uint256 constant LIMESTONE_SHINGLES_MASS = 7; -uint256 constant EMBERSTONE_MASS = 15; -uint256 constant MOONSTONE_MASS = 15; +uint256 constant EMBERSTONE_MASS = 14; uint256 constant QUARTZITE_MASS = 10; -uint256 constant SUNSTONE_MASS = 15; + +uint256 constant QUARTZITE_BRICK_MASS = 10; +uint256 constant QUARTZITE_CARVED_MASS = 10; +uint256 constant QUARTZITE_POLISHED_MASS = 10; +uint256 constant QUARTZITE_SHINGLES_MASS = 10; + +uint256 constant SUNSTONE_MASS = 14; +uint256 constant MOONSTONE_MASS = 17; uint256 constant OAK_LOG_MASS = 4; uint256 constant BIRCH_LOG_MASS = 4; uint256 constant SAKURA_LOG_MASS = 4; +uint256 constant SAKURA_LUMBER_MASS = 1; + uint256 constant RUBBER_LOG_MASS = 4; +uint256 constant RUBBER_LUMBER_MASS = 1; +uint256 constant REINFORCED_RUBBER_LUMBER_MASS = 3; + +uint256 constant OAK_LUMBER_MASS = 1; +uint256 constant REINFORCED_OAK_LUMBER_MASS = 3; + +uint256 constant BIRCH_LUMBER_MASS = 1; + uint256 constant OAK_LEAF_MASS = 1; uint256 constant BIRCH_LEAF_MASS = 1; uint256 constant SAKURA_LEAF_MASS = 1; uint256 constant RUBBER_LEAF_MASS = 1; +uint256 constant CHEST_MASS = 24; +uint256 constant THERMOBLASTER_MASS = 63; //7 * 9 = 63 +uint256 constant WORKBENCH_MASS = 20; //4 * 5 = 20 +uint256 constant DYE_O_MATIC_MASS = 68; + +uint256 constant BLUE_OAK_LUMBER_MASS = 2; +uint256 constant BROWN_OAK_LUMBER_MASS = 2; +uint256 constant GREEN_OAK_LUMBER_MASS = 2; +uint256 constant MAGENTA_OAK_LUMBER_MASS = 2; +uint256 constant ORANGE_OAK_LUMBER_MASS = 2; +uint256 constant PINK_OAK_LUMBER_MASS = 2; +uint256 constant PURPLE_OAK_LUMBER_MASS = 2; +uint256 constant RED_OAK_LUMBER_MASS = 2; +uint256 constant TAN_OAK_LUMBER_MASS = 2; +uint256 constant WHITE_OAK_LUMBER_MASS = 2; +uint256 constant YELLOW_OAK_LUMBER_MASS = 2; +uint256 constant BLACK_OAK_LUMBER_MASS = 2; +uint256 constant SILVER_OAK_LUMBER_MASS = 2; + +uint256 constant BLUE_COTTON_BLOCK_MASS = 5; +uint256 constant BROWN_COTTON_BLOCK_MASS = 5; +uint256 constant GREEN_COTTON_BLOCK_MASS = 5; +uint256 constant MAGENTA_COTTON_BLOCK_MASS = 5; +uint256 constant ORANGE_COTTON_BLOCK_MASS = 5; +uint256 constant PINK_COTTON_BLOCK_MASS = 5; +uint256 constant PURPLE_COTTON_BLOCK_MASS = 5; +uint256 constant RED_COTTON_BLOCK_MASS = 5; +uint256 constant TAN_COTTON_BLOCK_MASS = 5; +uint256 constant WHITE_COTTON_BLOCK_MASS = 5; +uint256 constant YELLOW_COTTON_BLOCK_MASS = 5; +uint256 constant BLACK_COTTON_BLOCK_MASS = 5; +uint256 constant SILVER_COTTON_BLOCK_MASS = 5; + +uint256 constant BLUE_GLASS_MASS = 5; +uint256 constant BROWN_GLASS_MASS = 5; +uint256 constant GREEN_GLASS_MASS = 5; +uint256 constant MAGENTA_GLASS_MASS = 5; +uint256 constant ORANGE_GLASS_MASS = 5; +uint256 constant PINK_GLASS_MASS = 5; +uint256 constant PURPLE_GLASS_MASS = 5; +uint256 constant RED_GLASS_MASS = 5; +uint256 constant TAN_GLASS_MASS = 5; +uint256 constant WHITE_GLASS_MASS = 5; +uint256 constant YELLOW_GLASS_MASS = 5; +uint256 constant BLACK_GLASS_MASS = 5; +uint256 constant SILVER_GLASS_MASS = 5; + +uint256 constant WOODEN_PICK_MASS = 16; +uint256 constant WOODEN_AXE_MASS = 16; +uint256 constant WOODEN_WHACKER_MASS = 32; + +uint256 constant DIAMOND_AXE_MASS = 196; +uint256 constant DIAMOND_PICK_MASS = 196; + +uint256 constant NEPTUNIUM_AXE_MASS = 336; +uint256 constant NEPTUNIUM_PICK_MASS = 336; + +uint256 constant PAPER_MASS = 1; +uint256 constant BASALT_BRICK_MASS = 10; +uint256 constant BASALT_CARVED_MASS = 11; +uint256 constant BASALT_POLISHED_MASS = 11; +uint256 constant BASALT_SHINGLES_MASS = 11; + +uint256 constant REINFORCED_BIRCH_LUMBER_MASS = 3; + +uint256 constant MUCKSHROOM_MASS = 1; +uint256 constant MUCKSHROOM_SPORES_MASS = 6; + +uint256 constant BELLFLOWER_MASS = 1; + +uint256 constant BLUE_DYE_MASS = 1; +uint256 constant BROWN_DYE_MASS = 1; +uint256 constant GREEN_DYE_MASS = 1; +uint256 constant MAGENTA_DYE_MASS = 1; +uint256 constant ORANGE_DYE_MASS = 1; +uint256 constant PINK_DYE_MASS = 1; +uint256 constant PURPLE_DYE_MASS = 1; +uint256 constant RED_DYE_MASS = 1; +uint256 constant TAN_DYE_MASS = 1; +uint256 constant WHITE_DYE_MASS = 1; +uint256 constant YELLOW_DYE_MASS = 1; +uint256 constant BLACK_DYE_MASS = 1; +uint256 constant SILVER_DYE_MASS = 1; + +uint256 constant BLUE_MUSHROOM_SPORE_MASS = 5; + +uint256 constant RED_MUSHROOM = 2; +uint256 constant RED_MUSHROOM_SPORES_MASS = 1; + +uint256 constant MUSHROOM_LEATHER_BLOCK_MASS = 8; + +uint256 constant CLAY_BRICK_MASS = 16; +uint256 constant CLAY_CARVED_MASS = 16; +uint256 constant CLAY_POLISHED_MASS = 16; +uint256 constant CLAY_SHINGLES_MASS = 16; + +uint256 constant COBBLESTONE_BRICK_MASS = 7; +uint256 constant COTTON_BLOCK_MASS = 4; + // Terrain enum Biome { Mountains, diff --git a/examples/everlon/packages/world/src/systems/CraftSystem.sol b/examples/everlon/packages/world/src/systems/CraftSystem.sol new file mode 100644 index 000000000..e48eeb455 --- /dev/null +++ b/examples/everlon/packages/world/src/systems/CraftSystem.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { CraftSystem as CraftProtoSystem } from "@tenet-base-world/src/systems/CraftSystem.sol"; + +contract CraftSystem is CraftProtoSystem { + function craft(bytes32 actingObjectEntityId, bytes32 recipeId, bytes32[] memory ingredientIds) public override { + super.craft(actingObjectEntityId, recipeId, ingredientIds); + } +} diff --git a/examples/everlon/packages/world/src/systems/InternalInventorySystem.sol b/examples/everlon/packages/world/src/systems/InternalInventorySystem.sol new file mode 100644 index 000000000..fd887c53c --- /dev/null +++ b/examples/everlon/packages/world/src/systems/InternalInventorySystem.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { InternalInventorySystem as InternalInventoryProtoSystem } from "@tenet-base-world/src/systems/InternalInventorySystem.sol"; +import { getKeysWithValue } from "@latticexyz/world/src/modules/keyswithvalue/getKeysWithValue.sol"; + +import { hasKey } from "@latticexyz/world/src/modules/haskeys/hasKey.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject, InventoryObjectData } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; +import { ChestObjectID, AirObjectID, MAX_CHEST_SLOTS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_MAX_INVENTORY_SLOTS } from "@tenet-base-world/src/Constants.sol"; +import { getObjectType } from "@tenet-base-world/src/Utils.sol"; + +contract InternalInventorySystem is InternalInventoryProtoSystem { + function isInventoryFull(bytes32 objectEntityId) public view override returns (bool) { + bytes32[][] memory inventoryIds = getKeysWithValue(InventoryTableId, Inventory.encode(objectEntityId)); + if (hasKey(OwnedByTableId, OwnedBy.encodeKeyTuple(objectEntityId))) { + return inventoryIds.length >= NUM_MAX_INVENTORY_SLOTS; + } + + bytes32 objectTypeId = getObjectType(IStore(_world()), objectEntityId); + if (objectTypeId == ChestObjectID) { + return inventoryIds.length >= MAX_CHEST_SLOTS; + } + + return false; + } + + function useEquipped(bytes32 actingObjectEntityId) public override { + super.useEquipped(actingObjectEntityId); + } + + function addObjectToInventory( + bytes32 objectEntityId, + bytes32 objectTypeId, + uint8 numObjectsToAdd, + ObjectProperties memory objectProperties + ) public override { + super.addObjectToInventory(objectEntityId, objectTypeId, numObjectsToAdd, objectProperties); + } + + function removeObjectFromInventory(bytes32 inventoryId, uint8 numObjectsToRemove) public override { + super.removeObjectFromInventory(inventoryId, numObjectsToRemove); + } +} diff --git a/examples/everlon/packages/world/src/systems/InventorySystem.sol b/examples/everlon/packages/world/src/systems/InventorySystem.sol new file mode 100644 index 000000000..db7dbce69 --- /dev/null +++ b/examples/everlon/packages/world/src/systems/InventorySystem.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { InventorySystem as InventoryProtoSystem } from "@tenet-base-world/src/systems/InventorySystem.sol"; +import { getObjectType } from "@tenet-base-world/src/Utils.sol"; +import { hasKey } from "@latticexyz/world/src/modules/haskeys/hasKey.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { ChestObjectID, AirObjectID } from "@tenet-world/src/Constants.sol"; + +contract InventorySystem is InventoryProtoSystem { + function equip(bytes32 actingObjectEntityId, bytes32 inventoryId) public override { + super.equip(actingObjectEntityId, inventoryId); + } + + function unequip(bytes32 actingObjectEntityId) public override { + super.unequip(actingObjectEntityId); + } + + function transfer( + bytes32 srcObjectEntityId, + VoxelCoord memory dstCoord, + bytes32 inventoryId, + uint8 transferAmount + ) public override { + super.transfer(srcObjectEntityId, dstCoord, inventoryId, transferAmount); + } + + function isValidSource(bytes32 srcObjectEntityId) internal view override returns (bool) { + if (hasKey(OwnedByTableId, OwnedBy.encodeKeyTuple(srcObjectEntityId))) { + require(OwnedBy.get(srcObjectEntityId) == _msgSender(), "InventorySystem: caller does not own entity"); + return true; + } + + bytes32 srcObjectTypeId = getObjectType(IStore(_world()), srcObjectEntityId); + if (srcObjectTypeId == ChestObjectID) { + return true; + } + + return false; + } + + function isValidDestination(bytes32 dstObjectEntityId) internal view override returns (bool) { + if (hasKey(OwnedByTableId, OwnedBy.encodeKeyTuple(dstObjectEntityId))) { + return true; + } + + bytes32 dstObjectTypeId = getObjectType(IStore(_world()), dstObjectEntityId); + if (dstObjectTypeId == ChestObjectID || dstObjectTypeId == AirObjectID) { + return true; + } + + return false; + } +} diff --git a/examples/everlon/packages/world/src/systems/LibTerrainSystem.sol b/examples/everlon/packages/world/src/systems/LibTerrainSystem.sol index fffd6ee85..7cdcde479 100644 --- a/examples/everlon/packages/world/src/systems/LibTerrainSystem.sol +++ b/examples/everlon/packages/world/src/systems/LibTerrainSystem.sol @@ -422,7 +422,7 @@ contract LibTerrainSystem is System { } uint16 hash1 = getCoordHash(x, z); - uint16 hash2 = getCoordHash(y, z + z); + uint16 hash2 = getCoordHash(y, x + z); if (hash1 > 10 && hash1 <= 60 && hash2 > 10 && hash2 <= 60) { if (biome == uint8(Biome.Mountains)) { properties.mass = COAL_ORE_MASS; @@ -482,7 +482,7 @@ contract LibTerrainSystem is System { } uint16 hash1 = getCoordHash(x, z); - uint16 hash2 = getCoordHash(y, z + z); + uint16 hash2 = getCoordHash(y, x + z); if (hash1 <= 10 || hash1 > 50) { if (hash1 <= 10 && hash2 <= 10) { properties.mass = DIAMOND_ORE_MASS; @@ -506,6 +506,7 @@ contract LibTerrainSystem is System { } } + properties.mass = CLAY_MASS; return TerrainData({ objectTypeId: ClayObjectID, properties: properties }); } diff --git a/examples/everlon/packages/world/src/systems/ObjectInteractionSystem.sol b/examples/everlon/packages/world/src/systems/ObjectInteractionSystem.sol index 8c46f95c0..9f5d2d164 100644 --- a/examples/everlon/packages/world/src/systems/ObjectInteractionSystem.sol +++ b/examples/everlon/packages/world/src/systems/ObjectInteractionSystem.sol @@ -7,14 +7,10 @@ import { System } from "@latticexyz/world/src/System.sol"; import { ObjectMetadata, ObjectMetadataTableId } from "@tenet-world/src/codegen/tables/ObjectMetadata.sol"; import { KeysInTable } from "@latticexyz/world/src/modules/keysintable/tables/KeysInTable.sol"; -import { REGISTRY_ADDRESS, SIMULATOR_ADDRESS, NUM_MAX_OBJECTS_INTERACTION_RUN, NUM_MAX_UNIQUE_OBJECT_EVENT_HANDLERS_RUN, NUM_MAX_SAME_OBJECT_EVENT_HANDLERS_RUN } from "@tenet-world/src/Constants.sol"; +import { SIMULATOR_ADDRESS, NUM_MAX_OBJECTS_INTERACTION_RUN, NUM_MAX_UNIQUE_OBJECT_EVENT_HANDLERS_RUN, NUM_MAX_SAME_OBJECT_EVENT_HANDLERS_RUN } from "@tenet-world/src/Constants.sol"; import { ObjectInteractionSystem as ObjectInteractionProtoSystem } from "@tenet-base-world/src/systems/ObjectInteractionSystem.sol"; contract ObjectInteractionSystem is ObjectInteractionProtoSystem { - function getRegistryAddress() internal pure override returns (address) { - return REGISTRY_ADDRESS; - } - function getSimulatorAddress() internal pure override returns (address) { return SIMULATOR_ADDRESS; } diff --git a/examples/everlon/packages/world/src/systems/ObjectSystem.sol b/examples/everlon/packages/world/src/systems/ObjectSystem.sol index 1f106dfff..a8b7ad2da 100644 --- a/examples/everlon/packages/world/src/systems/ObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/ObjectSystem.sol @@ -6,14 +6,9 @@ import { System } from "@latticexyz/world/src/System.sol"; import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS } from "@tenet-world/src/Constants.sol"; import { ObjectSystem as ObjectProtoSystem } from "@tenet-base-world/src/systems/ObjectSystem.sol"; contract ObjectSystem is ObjectProtoSystem { - function getRegistryAddress() internal pure override returns (address) { - return REGISTRY_ADDRESS; - } - function enterWorld( bytes32 objectTypeId, VoxelCoord memory coord, diff --git a/examples/everlon/packages/world/src/systems/RecipeColorCott.sol b/examples/everlon/packages/world/src/systems/RecipeColorCott.sol new file mode 100644 index 000000000..72ab3145e --- /dev/null +++ b/examples/everlon/packages/world/src/systems/RecipeColorCott.sol @@ -0,0 +1,436 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/keysintable/hasKey.sol"; +import { getKeysInTable } from "@latticexyz/world/src/modules/keysintable/getKeysInTable.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; + +import { Recipes, RecipesData, RecipesTableId } from "@tenet-world/src/codegen/tables/Recipes.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; + +import { initializeBytes32Array } from "@tenet-utils/src/ArrayUtils.sol"; +import { BlueCottonBlockObjectID, BLUE_COTTON_BLOCK_MASS, +BrownCottonBlockObjectID, BROWN_COTTON_BLOCK_MASS, +GreenCottonBlockObjectID, GREEN_COTTON_BLOCK_MASS, +MagentaCottonBlockObjectID, MAGENTA_COTTON_BLOCK_MASS, +OrangeCottonBlockObjectID, ORANGE_COTTON_BLOCK_MASS, +PinkCottonBlockObjectID, PINK_COTTON_BLOCK_MASS, +PurpleCottonBlockObjectID, PURPLE_COTTON_BLOCK_MASS, +RedCottonBlockObjectID, RED_COTTON_BLOCK_MASS, +TanCottonBlockObjectID, TAN_COTTON_BLOCK_MASS, +WhiteCottonBlockObjectID, WHITE_COTTON_BLOCK_MASS, +YellowCottonBlockObjectID, YELLOW_COTTON_BLOCK_MASS, +BlackCottonBlockObjectID, BLACK_COTTON_BLOCK_MASS, +SilverCottonBlockObjectID, SILVER_COTTON_BLOCK_MASS, + DandelionObjectID, RoseObjectID, LilacObjectID, PinkDyeObjectID, PINK_DYE_MASS, PurpleDyeObjectID, PURPLE_DYE_MASS, RedDyeObjectID, RED_DYE_MASS, TanDyeObjectID, TAN_DYE_MASS, WhiteDyeObjectID, WHITE_DYE_MASS, YellowDyeObjectID, YELLOW_DYE_MASS, BlackDyeObjectID, BLACK_DYE_MASS, SilverDyeObjectID, SILVER_DYE_MASS, AzaleaObjectID, OrangeDyeObjectID, ORANGE_DYE_MASS, DaylilyObjectID, LilacObjectID, HempObjectID, BlueDyeObjectID, BLUE_DYE_MASS, BrownDyeObjectID, BROWN_DYE_MASS, GreenDyeObjectID, GREEN_DYE_MASS, MagentaDyeObjectID, MAGENTA_DYE_MASS, OrangeDyeObjectID, ORANGE_DYE_MASS, StoneShinglesObjectID, STONE_SHINGLES_MASS, POLISHED_STONE_MASS, STONE_CARVED_MASS, STONE_BRICK_MASS, PolishedStoneObjectID, StoneCarvedObjectID, StoneBrickObjectID, StoneWhackerObjectID, STONE_WHACKER_MASS, StonePickObjectID, STONE_PICK_MASS, StoneAxeObjectID, STONE_AXE_MASS, WoodenWhackerObjectID, WOODEN_WHACKER_MASS, WoodenAxeObjectID, WOODEN_AXE_MASS, SunstoneObjectID, SUNSTONE_MASS, SilverWhackerObjectID, SILVER_WHACKER_MASS, SilverPickObjectID, SILVER_PICK_MASS, SilverAxeObjectID, SILVER_AXE_MASS, SilverCubeObjectID, SILVER_CUBE_MASS, SILVER_BAR_MASS, SilverBarObjectID, SakuraLogObjectID, SakuraLumberObjectID, SAKURA_LUMBER_MASS, RubbleObjectID, RUBBLE_MASS, ReinforcedRubberLumberObjectID, REINFORCED_RUBBER_LUMBER_MASS, RubberLogObjectID, RUBBER_LUMBER_MASS, RedMushroomSporesObjectID, RED_MUSHROOM_SPORES_MASS, QuartziteShinglesObjectID, QUARTZITE_SHINGLES_MASS, QuartzitePolishedObjectID, QUARTZITE_POLISHED_MASS, QuartziteCarvedObjectID, QUARTZITE_CARVED_MASS, QuartziteBrickObjectID, QUARTZITE_BRICK_MASS, MuckshroomSporesObjectID, MUCKSHROOM_SPORES_MASS, ReinforcedOakLumberObjectID, REINFORCED_OAK_LUMBER_MASS, NeptuniumPickObjectID, MOONSTONE_MASS, NeptuniumAxeObjectID, NEPTUNIUM_AXE_MASS, NEPTUNIUM_PICK_MASS, NeptuniumCubeObjectID, NEPTUNIUM_CUBE_MASS, NeptuniumOreObjectID, NEPTUNIUM_BAR_MASS, NeptuniumBarObjectID, RedMushroomObjectID, MushroomLeatherBlockObjectID, MUSHROOM_LEATHER_BLOCK_MASS, MoonstoneObjectID, QuartziteObjectID, LIMESTONE_CARVED_MASS, LIMESTONE_SHINGLES_MASS, LIMESTONE_POLISHED_MASS, LimestoneShinglesObjectID, LimestonePolishedObjectID, LimestoneCarvedObjectID, LimestoneObjectID, LimestoneBrickObjectID, LIMESTONE_BRICK_MASS, GRANITE_SHINGLES_MASS, GraniteShinglesObjectID, GranitePolishedObjectID, GRANITE_POLISHED_MASS, GRANITE_CARVED_MASS, GraniteCarvedObjectID, GRANITE_BRICK_MASS, GraniteBrickObjectID, GraniteObjectID, SakuraLumberObjectID, RubberLumberObjectID, GoldPickObjectID, GOLD_PICK_MASS, GoldAxeObjectID, GOLD_AXE_MASS, GOLD_CUBE_MASS, GoldCubeObjectID, GOLD_BAR_MASS, GoldBarObjectID, GoldOreObjectID, GlassObjectID, GLASS_MASS, SandObjectID, EMBERSTONE_MASS, EmberstoneObjectID, StoneObjectID, CoalOreObjectID, DIAMOND_PICK_MASS, DiamondPickObjectID, DIAMOND_CUBE_MASS, DiamondCubeObjectID, DIAMOND_AXE_MASS, DiamondAxeObjectID, DIAMOND_MASS, DiamondObjectID, DiamondOreObjectID, COTTON_BLOCK_MASS, CottonBlockObjectID, CottonObjectID, COBBLESTONE_BRICK_MASS, CobblestoneBrickObjectID, CobblestoneObjectID, ChestObjectID, CHEST_MASS, ClayShinglesObjectID, CLAY_SHINGLES_MASS, CLAY_POLISHED_MASS, ClayPolishedObjectID, CLAY_CARVED_MASS, ClayCarvedObjectID, CLAY_BRICK_MASS, ClayBrickObjectID, DirtObjectID, ClayObjectID, CLAY_MASS, MuckshroomObjectID, BellflowerObjectID, BlueMushroomSporeObjectID, BLUE_MUSHROOM_SPORE_MASS, BirchLogObjectID, ReinforcedBirchLumberObjectID, REINFORCED_BIRCH_LUMBER_MASS, BirchLumberObjectID, SilverOreObjectID, BIRCH_LUMBER_MASS, OakLogObjectID, OakLumberObjectID, OAK_LUMBER_MASS, BASALT_BRICK_MASS, BASALT_CARVED_MASS, BASALT_POLISHED_MASS, BASALT_SHINGLES_MASS, WoodenPickObjectID, WOODEN_PICK_MASS, BasaltObjectID, PaperObjectID, BasaltBrickObjectID, BasaltCarvedObjectID, BasaltPolishedObjectID, BasaltShinglesObjectID, PAPER_MASS } from "@tenet-world/src/Constants.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; + + +contract RecipeColorCott is System { + function initRecipeColorCott() public { + + // recipeBlueCottonBlock + + bytes32[] memory inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = BlueDyeObjectID; + uint8[] memory inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Blue Dye + + bytes32[] memory outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BlueCottonBlockObjectID; // TODO: Define BlueCottonBlockObjectID + uint8[] memory outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Blue Oak Lumber + + ObjectProperties[] memory outputObjectProperties = new ObjectProperties[](1); + ObjectProperties memory outputOutputProperties; + outputOutputProperties.mass = BLUE_COTTON_BLOCK_MASS; // TODO: Define BLUE_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + bytes32 newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBrownCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = BrownDyeObjectID; // Assuming BrownDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Brown Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BrownCottonBlockObjectID; // TODO: Define BrownCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Brown Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BROWN_COTTON_BLOCK_MASS; // TODO: Define BROWN_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeGreenCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = GreenDyeObjectID; // Assuming GreenDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Green Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GreenCottonBlockObjectID; // TODO: Define GreenCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Green Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GREEN_COTTON_BLOCK_MASS; // TODO: Define GREEN_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeMagentaCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = MagentaDyeObjectID; // Assuming MagentaDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Magenta Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = MagentaCottonBlockObjectID; // TODO: Define MagentaCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Magenta Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = MAGENTA_COTTON_BLOCK_MASS; // TODO: Define MAGENTA_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeOrangeCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = OrangeDyeObjectID; // Assuming OrangeDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Orange Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = OrangeCottonBlockObjectID; // TODO: Define OrangeCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Orange Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = ORANGE_COTTON_BLOCK_MASS; // TODO: Define ORANGE_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipePinkCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = PinkDyeObjectID; // Assuming PinkDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Pink Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = PinkCottonBlockObjectID; // TODO: Define PinkCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Pink Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = PINK_COTTON_BLOCK_MASS; // TODO: Define PINK_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipePurpleCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = PurpleDyeObjectID; // Assuming PurpleDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Purple Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = PurpleCottonBlockObjectID; // TODO: Define PurpleCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Purple Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = PURPLE_COTTON_BLOCK_MASS; // TODO: Define PURPLE_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeRedCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = RedDyeObjectID; // Assuming RedDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Red Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = RedCottonBlockObjectID; // TODO: Define RedCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Red Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = RED_COTTON_BLOCK_MASS; // TODO: Define RED_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeTanCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = TanDyeObjectID; // TODO: Define TanDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Tan Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = TanCottonBlockObjectID; // TODO: Define TanCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Tan Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = TAN_COTTON_BLOCK_MASS; // TODO: Define TAN_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeWhiteCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = WhiteDyeObjectID; // TODO: Define WhiteDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 White Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = WhiteCottonBlockObjectID; // TODO: Define WhiteCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 White Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = WHITE_COTTON_BLOCK_MASS; // TODO: Define WHITE_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeYellowCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = YellowDyeObjectID; // TODO: Define YellowDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Yellow Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = YellowCottonBlockObjectID; // TODO: Define YellowCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Yellow Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = YELLOW_COTTON_BLOCK_MASS; // TODO: Define YELLOW_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBlackCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = BlackDyeObjectID; // TODO: Define BlackDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Black Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BlackCottonBlockObjectID; // TODO: Define BlackCottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Black Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BLACK_COTTON_BLOCK_MASS; // TODO: Define BLACK_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeSilverCottonBlock + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CottonBlockObjectID; + inputObjectTypeIds[1] = SilverDyeObjectID; // TODO: Define SilverDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Silver Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SilverCottonBlockObjectID; // TODO: Define SilverCottonBlocObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Silver Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = SILVER_COTTON_BLOCK_MASS; // TODO: Define SILVER_COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + + + + + + } +} \ No newline at end of file diff --git a/examples/everlon/packages/world/src/systems/RecipeColorGlass.sol b/examples/everlon/packages/world/src/systems/RecipeColorGlass.sol new file mode 100644 index 000000000..08a27ffe6 --- /dev/null +++ b/examples/everlon/packages/world/src/systems/RecipeColorGlass.sol @@ -0,0 +1,436 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/keysintable/hasKey.sol"; +import { getKeysInTable } from "@latticexyz/world/src/modules/keysintable/getKeysInTable.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; + +import { Recipes, RecipesData, RecipesTableId } from "@tenet-world/src/codegen/tables/Recipes.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; + +import { initializeBytes32Array } from "@tenet-utils/src/ArrayUtils.sol"; +import { BlueGlassObjectID, BLUE_GLASS_MASS, +BrownGlassObjectID, BROWN_GLASS_MASS, +GreenGlassObjectID, GREEN_GLASS_MASS, +MagentaGlassObjectID, MAGENTA_GLASS_MASS, +OrangeGlassObjectID, ORANGE_GLASS_MASS, +PinkGlassObjectID, PINK_GLASS_MASS, +PurpleGlassObjectID, PURPLE_GLASS_MASS, +RedGlassObjectID, RED_GLASS_MASS, +TanGlassObjectID, TAN_GLASS_MASS, +WhiteGlassObjectID, WHITE_GLASS_MASS, +YellowGlassObjectID, YELLOW_GLASS_MASS, +BlackGlassObjectID, BLACK_GLASS_MASS, +SilverGlassObjectID, SILVER_GLASS_MASS, + DandelionObjectID, RoseObjectID, LilacObjectID, PinkDyeObjectID, PINK_DYE_MASS, PurpleDyeObjectID, PURPLE_DYE_MASS, RedDyeObjectID, RED_DYE_MASS, TanDyeObjectID, TAN_DYE_MASS, WhiteDyeObjectID, WHITE_DYE_MASS, YellowDyeObjectID, YELLOW_DYE_MASS, BlackDyeObjectID, BLACK_DYE_MASS, SilverDyeObjectID, SILVER_DYE_MASS, AzaleaObjectID, OrangeDyeObjectID, ORANGE_DYE_MASS, DaylilyObjectID, LilacObjectID, HempObjectID, BlueDyeObjectID, BLUE_DYE_MASS, BrownDyeObjectID, BROWN_DYE_MASS, GreenDyeObjectID, GREEN_DYE_MASS, MagentaDyeObjectID, MAGENTA_DYE_MASS, OrangeDyeObjectID, ORANGE_DYE_MASS, StoneShinglesObjectID, STONE_SHINGLES_MASS, POLISHED_STONE_MASS, STONE_CARVED_MASS, STONE_BRICK_MASS, PolishedStoneObjectID, StoneCarvedObjectID, StoneBrickObjectID, StoneWhackerObjectID, STONE_WHACKER_MASS, StonePickObjectID, STONE_PICK_MASS, StoneAxeObjectID, STONE_AXE_MASS, WoodenWhackerObjectID, WOODEN_WHACKER_MASS, WoodenAxeObjectID, WOODEN_AXE_MASS, SunstoneObjectID, SUNSTONE_MASS, SilverWhackerObjectID, SILVER_WHACKER_MASS, SilverPickObjectID, SILVER_PICK_MASS, SilverAxeObjectID, SILVER_AXE_MASS, SilverCubeObjectID, SILVER_CUBE_MASS, SILVER_BAR_MASS, SilverBarObjectID, SakuraLogObjectID, SakuraLumberObjectID, SAKURA_LUMBER_MASS, RubbleObjectID, RUBBLE_MASS, ReinforcedRubberLumberObjectID, REINFORCED_RUBBER_LUMBER_MASS, RubberLogObjectID, RUBBER_LUMBER_MASS, RedMushroomSporesObjectID, RED_MUSHROOM_SPORES_MASS, QuartziteShinglesObjectID, QUARTZITE_SHINGLES_MASS, QuartzitePolishedObjectID, QUARTZITE_POLISHED_MASS, QuartziteCarvedObjectID, QUARTZITE_CARVED_MASS, QuartziteBrickObjectID, QUARTZITE_BRICK_MASS, MuckshroomSporesObjectID, MUCKSHROOM_SPORES_MASS, ReinforcedOakLumberObjectID, REINFORCED_OAK_LUMBER_MASS, NeptuniumPickObjectID, MOONSTONE_MASS, NeptuniumAxeObjectID, NEPTUNIUM_AXE_MASS, NEPTUNIUM_PICK_MASS, NeptuniumCubeObjectID, NEPTUNIUM_CUBE_MASS, NeptuniumOreObjectID, NEPTUNIUM_BAR_MASS, NeptuniumBarObjectID, RedMushroomObjectID, MushroomLeatherBlockObjectID, MUSHROOM_LEATHER_BLOCK_MASS, MoonstoneObjectID, QuartziteObjectID, LIMESTONE_CARVED_MASS, LIMESTONE_SHINGLES_MASS, LIMESTONE_POLISHED_MASS, LimestoneShinglesObjectID, LimestonePolishedObjectID, LimestoneCarvedObjectID, LimestoneObjectID, LimestoneBrickObjectID, LIMESTONE_BRICK_MASS, GRANITE_SHINGLES_MASS, GraniteShinglesObjectID, GranitePolishedObjectID, GRANITE_POLISHED_MASS, GRANITE_CARVED_MASS, GraniteCarvedObjectID, GRANITE_BRICK_MASS, GraniteBrickObjectID, GraniteObjectID, SakuraLumberObjectID, RubberLumberObjectID, GoldPickObjectID, GOLD_PICK_MASS, GoldAxeObjectID, GOLD_AXE_MASS, GOLD_CUBE_MASS, GoldCubeObjectID, GOLD_BAR_MASS, GoldBarObjectID, GoldOreObjectID, GlassObjectID, GLASS_MASS, SandObjectID, EMBERSTONE_MASS, EmberstoneObjectID, StoneObjectID, CoalOreObjectID, DIAMOND_PICK_MASS, DiamondPickObjectID, DIAMOND_CUBE_MASS, DiamondCubeObjectID, DIAMOND_AXE_MASS, DiamondAxeObjectID, DIAMOND_MASS, DiamondObjectID, DiamondOreObjectID, COTTON_BLOCK_MASS, CottonBlockObjectID, CottonObjectID, COBBLESTONE_BRICK_MASS, CobblestoneBrickObjectID, CobblestoneObjectID, ChestObjectID, CHEST_MASS, ClayShinglesObjectID, CLAY_SHINGLES_MASS, CLAY_POLISHED_MASS, ClayPolishedObjectID, CLAY_CARVED_MASS, ClayCarvedObjectID, CLAY_BRICK_MASS, ClayBrickObjectID, DirtObjectID, ClayObjectID, CLAY_MASS, MuckshroomObjectID, BellflowerObjectID, BlueMushroomSporeObjectID, BLUE_MUSHROOM_SPORE_MASS, BirchLogObjectID, ReinforcedBirchLumberObjectID, REINFORCED_BIRCH_LUMBER_MASS, BirchLumberObjectID, SilverOreObjectID, BIRCH_LUMBER_MASS, OakLogObjectID, OakLumberObjectID, OAK_LUMBER_MASS, BASALT_BRICK_MASS, BASALT_CARVED_MASS, BASALT_POLISHED_MASS, BASALT_SHINGLES_MASS, WoodenPickObjectID, WOODEN_PICK_MASS, BasaltObjectID, PaperObjectID, BasaltBrickObjectID, BasaltCarvedObjectID, BasaltPolishedObjectID, BasaltShinglesObjectID, PAPER_MASS } from "@tenet-world/src/Constants.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; + + +contract RecipeColorGlass is System { + function initRecipeColorGlass() public { + + // recipeBlueGlass + + bytes32[] memory inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = BlueDyeObjectID; + uint8[] memory inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Blue Dye + + bytes32[] memory outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BlueGlassObjectID; // TODO: Define BlueGlassObjectID + uint8[] memory outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Blue Oak Lumber + + ObjectProperties[] memory outputObjectProperties = new ObjectProperties[](1); + ObjectProperties memory outputOutputProperties; + outputOutputProperties.mass = BLUE_GLASS_MASS; // TODO: Define BLUE_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + bytes32 newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBrownGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = BrownDyeObjectID; // Assuming BrownDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Brown Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BrownGlassObjectID; // TODO: Define BrownGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Brown Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BROWN_GLASS_MASS; // TODO: Define BROWN_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeGreenGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = GreenDyeObjectID; // Assuming GreenDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Green Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GreenGlassObjectID; // TODO: Define GreenGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Green Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GREEN_GLASS_MASS; // TODO: Define GREEN_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeMagentaGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = MagentaDyeObjectID; // Assuming MagentaDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Magenta Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = MagentaGlassObjectID; // TODO: Define MagentaGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Magenta Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = MAGENTA_GLASS_MASS; // TODO: Define MAGENTA_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeOrangeGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = OrangeDyeObjectID; // Assuming OrangeDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Orange Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = OrangeGlassObjectID; // TODO: Define OrangeGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Orange Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = ORANGE_GLASS_MASS; // TODO: Define ORANGE_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipePinkGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = PinkDyeObjectID; // Assuming PinkDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Pink Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = PinkGlassObjectID; // TODO: Define PinkGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Pink Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = PINK_GLASS_MASS; // TODO: Define PINK_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipePurpleGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = PurpleDyeObjectID; // Assuming PurpleDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Purple Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = PurpleGlassObjectID; // TODO: Define PurpleGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Purple Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = PURPLE_GLASS_MASS; // TODO: Define PURPLE_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeRedGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = RedDyeObjectID; // Assuming RedDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Red Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = RedGlassObjectID; // TODO: Define RedGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Red Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = RED_GLASS_MASS; // TODO: Define RED_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeTanGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = TanDyeObjectID; // TODO: Define TanDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Tan Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = TanGlassObjectID; // TODO: Define TanGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Tan Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = TAN_GLASS_MASS; // TODO: Define TAN_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeWhiteGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = WhiteDyeObjectID; // TODO: Define WhiteDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 White Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = WhiteGlassObjectID; // TODO: Define WhiteGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 White Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = WHITE_GLASS_MASS; // TODO: Define WHITE_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeYellowGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = YellowDyeObjectID; // TODO: Define YellowDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Yellow Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = YellowGlassObjectID; // TODO: Define YellowGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Yellow Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = YELLOW_GLASS_MASS; // TODO: Define YELLOW_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBlackGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = BlackDyeObjectID; // TODO: Define BlackDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Black Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BlackGlassObjectID; // TODO: Define BlackGlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Black Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BLACK_GLASS_MASS; // TODO: Define BLACK_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeSilverGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GlassObjectID; + inputObjectTypeIds[1] = SilverDyeObjectID; // TODO: Define SilverDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Silver Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SilverGlassObjectID; // TODO: Define SilverCottonBlocObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Silver Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = SILVER_GLASS_MASS; // TODO: Define SILVER_GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + + + + + + } +} \ No newline at end of file diff --git a/examples/everlon/packages/world/src/systems/RecipeColorOak.sol b/examples/everlon/packages/world/src/systems/RecipeColorOak.sol new file mode 100644 index 000000000..06fa06d5e --- /dev/null +++ b/examples/everlon/packages/world/src/systems/RecipeColorOak.sol @@ -0,0 +1,436 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/keysintable/hasKey.sol"; +import { getKeysInTable } from "@latticexyz/world/src/modules/keysintable/getKeysInTable.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; + +import { Recipes, RecipesData, RecipesTableId } from "@tenet-world/src/codegen/tables/Recipes.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; + +import { initializeBytes32Array } from "@tenet-utils/src/ArrayUtils.sol"; +import { BlueOakLumberObjectID, BLUE_OAK_LUMBER_MASS, +BrownOakLumberObjectID, BROWN_OAK_LUMBER_MASS, +GreenOakLumberObjectID, GREEN_OAK_LUMBER_MASS, +MagentaOakLumberObjectID, MAGENTA_OAK_LUMBER_MASS, +OrangeOakLumberObjectID, ORANGE_OAK_LUMBER_MASS, +PinkOakLumberObjectID, PINK_OAK_LUMBER_MASS, +PurpleOakLumberObjectID, PURPLE_OAK_LUMBER_MASS, +RedOakLumberObjectID, RED_OAK_LUMBER_MASS, +TanOakLumberObjectID, TAN_OAK_LUMBER_MASS, +WhiteOakLumberObjectID, WHITE_OAK_LUMBER_MASS, +YellowOakLumberObjectID, YELLOW_OAK_LUMBER_MASS, +BlackOakLumberObjectID, BLACK_OAK_LUMBER_MASS, +SilverOakLumberObjectID, SILVER_OAK_LUMBER_MASS, + DandelionObjectID, RoseObjectID, LilacObjectID, PinkDyeObjectID, PINK_DYE_MASS, PurpleDyeObjectID, PURPLE_DYE_MASS, RedDyeObjectID, RED_DYE_MASS, TanDyeObjectID, TAN_DYE_MASS, WhiteDyeObjectID, WHITE_DYE_MASS, YellowDyeObjectID, YELLOW_DYE_MASS, BlackDyeObjectID, BLACK_DYE_MASS, SilverDyeObjectID, SILVER_DYE_MASS, AzaleaObjectID, OrangeDyeObjectID, ORANGE_DYE_MASS, DaylilyObjectID, LilacObjectID, HempObjectID, BlueDyeObjectID, BLUE_DYE_MASS, BrownDyeObjectID, BROWN_DYE_MASS, GreenDyeObjectID, GREEN_DYE_MASS, MagentaDyeObjectID, MAGENTA_DYE_MASS, OrangeDyeObjectID, ORANGE_DYE_MASS, StoneShinglesObjectID, STONE_SHINGLES_MASS, POLISHED_STONE_MASS, STONE_CARVED_MASS, STONE_BRICK_MASS, PolishedStoneObjectID, StoneCarvedObjectID, StoneBrickObjectID, StoneWhackerObjectID, STONE_WHACKER_MASS, StonePickObjectID, STONE_PICK_MASS, StoneAxeObjectID, STONE_AXE_MASS, WoodenWhackerObjectID, WOODEN_WHACKER_MASS, WoodenAxeObjectID, WOODEN_AXE_MASS, SunstoneObjectID, SUNSTONE_MASS, SilverWhackerObjectID, SILVER_WHACKER_MASS, SilverPickObjectID, SILVER_PICK_MASS, SilverAxeObjectID, SILVER_AXE_MASS, SilverCubeObjectID, SILVER_CUBE_MASS, SILVER_BAR_MASS, SilverBarObjectID, SakuraLogObjectID, SakuraLumberObjectID, SAKURA_LUMBER_MASS, RubbleObjectID, RUBBLE_MASS, ReinforcedRubberLumberObjectID, REINFORCED_RUBBER_LUMBER_MASS, RubberLogObjectID, RUBBER_LUMBER_MASS, RedMushroomSporesObjectID, RED_MUSHROOM_SPORES_MASS, QuartziteShinglesObjectID, QUARTZITE_SHINGLES_MASS, QuartzitePolishedObjectID, QUARTZITE_POLISHED_MASS, QuartziteCarvedObjectID, QUARTZITE_CARVED_MASS, QuartziteBrickObjectID, QUARTZITE_BRICK_MASS, MuckshroomSporesObjectID, MUCKSHROOM_SPORES_MASS, ReinforcedOakLumberObjectID, REINFORCED_OAK_LUMBER_MASS, NeptuniumPickObjectID, MOONSTONE_MASS, NeptuniumAxeObjectID, NEPTUNIUM_AXE_MASS, NEPTUNIUM_PICK_MASS, NeptuniumCubeObjectID, NEPTUNIUM_CUBE_MASS, NeptuniumOreObjectID, NEPTUNIUM_BAR_MASS, NeptuniumBarObjectID, RedMushroomObjectID, MushroomLeatherBlockObjectID, MUSHROOM_LEATHER_BLOCK_MASS, MoonstoneObjectID, QuartziteObjectID, LIMESTONE_CARVED_MASS, LIMESTONE_SHINGLES_MASS, LIMESTONE_POLISHED_MASS, LimestoneShinglesObjectID, LimestonePolishedObjectID, LimestoneCarvedObjectID, LimestoneObjectID, LimestoneBrickObjectID, LIMESTONE_BRICK_MASS, GRANITE_SHINGLES_MASS, GraniteShinglesObjectID, GranitePolishedObjectID, GRANITE_POLISHED_MASS, GRANITE_CARVED_MASS, GraniteCarvedObjectID, GRANITE_BRICK_MASS, GraniteBrickObjectID, GraniteObjectID, SakuraLumberObjectID, RubberLumberObjectID, GoldPickObjectID, GOLD_PICK_MASS, GoldAxeObjectID, GOLD_AXE_MASS, GOLD_CUBE_MASS, GoldCubeObjectID, GOLD_BAR_MASS, GoldBarObjectID, GoldOreObjectID, GlassObjectID, GLASS_MASS, SandObjectID, EMBERSTONE_MASS, EmberstoneObjectID, StoneObjectID, CoalOreObjectID, DIAMOND_PICK_MASS, DiamondPickObjectID, DIAMOND_CUBE_MASS, DiamondCubeObjectID, DIAMOND_AXE_MASS, DiamondAxeObjectID, DIAMOND_MASS, DiamondObjectID, DiamondOreObjectID, COTTON_BLOCK_MASS, CottonBlockObjectID, CottonObjectID, COBBLESTONE_BRICK_MASS, CobblestoneBrickObjectID, CobblestoneObjectID, ChestObjectID, CHEST_MASS, ClayShinglesObjectID, CLAY_SHINGLES_MASS, CLAY_POLISHED_MASS, ClayPolishedObjectID, CLAY_CARVED_MASS, ClayCarvedObjectID, CLAY_BRICK_MASS, ClayBrickObjectID, DirtObjectID, ClayObjectID, CLAY_MASS, MuckshroomObjectID, BellflowerObjectID, BlueMushroomSporeObjectID, BLUE_MUSHROOM_SPORE_MASS, BirchLogObjectID, ReinforcedBirchLumberObjectID, REINFORCED_BIRCH_LUMBER_MASS, BirchLumberObjectID, SilverOreObjectID, BIRCH_LUMBER_MASS, OakLogObjectID, OakLumberObjectID, OAK_LUMBER_MASS, BASALT_BRICK_MASS, BASALT_CARVED_MASS, BASALT_POLISHED_MASS, BASALT_SHINGLES_MASS, WoodenPickObjectID, WOODEN_PICK_MASS, BasaltObjectID, PaperObjectID, BasaltBrickObjectID, BasaltCarvedObjectID, BasaltPolishedObjectID, BasaltShinglesObjectID, PAPER_MASS } from "@tenet-world/src/Constants.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; + + +contract RecipeColorOak is System { + function initRecipeColorOak() public { + + // recipeBlueOakLumber + + bytes32[] memory inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = BlueDyeObjectID; + uint8[] memory inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Blue Dye + + bytes32[] memory outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BlueOakLumberObjectID; // TODO: Define BlueOakLumberObjectID + uint8[] memory outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Blue Oak Lumber + + ObjectProperties[] memory outputObjectProperties = new ObjectProperties[](1); + ObjectProperties memory outputOutputProperties; + outputOutputProperties.mass = BLUE_OAK_LUMBER_MASS; // TODO: Define BLUE_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + bytes32 newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBrownOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = BrownDyeObjectID; // Assuming BrownDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Brown Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BrownOakLumberObjectID; // TODO: Define BrownOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Brown Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BROWN_OAK_LUMBER_MASS; // TODO: Define BROWN_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeGreenOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = GreenDyeObjectID; // Assuming GreenDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Green Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GreenOakLumberObjectID; // TODO: Define GreenOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Green Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GREEN_OAK_LUMBER_MASS; // TODO: Define GREEN_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeMagentaOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = MagentaDyeObjectID; // Assuming MagentaDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Magenta Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = MagentaOakLumberObjectID; // TODO: Define MagentaOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Magenta Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = MAGENTA_OAK_LUMBER_MASS; // TODO: Define MAGENTA_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeOrangeOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = OrangeDyeObjectID; // Assuming OrangeDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Orange Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = OrangeOakLumberObjectID; // TODO: Define OrangeOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Orange Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = ORANGE_OAK_LUMBER_MASS; // TODO: Define ORANGE_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipePinkOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = PinkDyeObjectID; // Assuming PinkDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Pink Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = PinkOakLumberObjectID; // TODO: Define PinkOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Pink Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = PINK_OAK_LUMBER_MASS; // TODO: Define PINK_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipePurpleOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = PurpleDyeObjectID; // Assuming PurpleDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Purple Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = PurpleOakLumberObjectID; // TODO: Define PurpleOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Purple Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = PURPLE_OAK_LUMBER_MASS; // TODO: Define PURPLE_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeRedOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = RedDyeObjectID; // Assuming RedDyeObjectID is defined + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Red Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = RedOakLumberObjectID; // TODO: Define RedOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Red Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = RED_OAK_LUMBER_MASS; // TODO: Define RED_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeTanOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = TanDyeObjectID; // TODO: Define TanDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Tan Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = TanOakLumberObjectID; // TODO: Define TanOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Tan Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = TAN_OAK_LUMBER_MASS; // TODO: Define TAN_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeWhiteOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = WhiteDyeObjectID; // TODO: Define WhiteDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 White Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = WhiteOakLumberObjectID; // TODO: Define WhiteOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 White Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = WHITE_OAK_LUMBER_MASS; // TODO: Define WHITE_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeYellowOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = YellowDyeObjectID; // TODO: Define YellowDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Yellow Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = YellowOakLumberObjectID; // TODO: Define YellowOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Yellow Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = YELLOW_OAK_LUMBER_MASS; // TODO: Define YELLOW_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBlackOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = BlackDyeObjectID; // TODO: Define BlackDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Black Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BlackOakLumberObjectID; // TODO: Define BlackOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Black Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BLACK_OAK_LUMBER_MASS; // TODO: Define BLACK_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeSilverOakLumber + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeIds[1] = SilverDyeObjectID; // TODO: Define SilverDyeObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 1; // 1 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Silver Dye + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SilverOakLumberObjectID; // TODO: Define SilverOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Silver Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = SILVER_OAK_LUMBER_MASS; // TODO: Define SILVER_OAK_LUMBER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + + + + + + } +} \ No newline at end of file diff --git a/examples/everlon/packages/world/src/systems/RecipeStations.sol b/examples/everlon/packages/world/src/systems/RecipeStations.sol new file mode 100644 index 000000000..315d71fdd --- /dev/null +++ b/examples/everlon/packages/world/src/systems/RecipeStations.sol @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/keysintable/hasKey.sol"; +import { getKeysInTable } from "@latticexyz/world/src/modules/keysintable/getKeysInTable.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; + +import { Recipes, RecipesData, RecipesTableId } from "@tenet-world/src/codegen/tables/Recipes.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; + +import { initializeBytes32Array } from "@tenet-utils/src/ArrayUtils.sol"; +import { DyeomaticObjectID, DYE_O_MATIC_MASS, WorkbenchObjectID, WORKBENCH_MASS, ThermoblasterObjectID, THERMOBLASTER_MASS, DandelionObjectID, RoseObjectID, LilacObjectID, PinkDyeObjectID, PINK_DYE_MASS, PurpleDyeObjectID, PURPLE_DYE_MASS, RedDyeObjectID, RED_DYE_MASS, TanDyeObjectID, TAN_DYE_MASS, WhiteDyeObjectID, WHITE_DYE_MASS, YellowDyeObjectID, YELLOW_DYE_MASS, BlackDyeObjectID, BLACK_DYE_MASS, SilverDyeObjectID, SILVER_DYE_MASS, AzaleaObjectID, OrangeDyeObjectID, ORANGE_DYE_MASS, DaylilyObjectID, LilacObjectID, HempObjectID, BlueDyeObjectID, BLUE_DYE_MASS, BrownDyeObjectID, BROWN_DYE_MASS, GreenDyeObjectID, GREEN_DYE_MASS, MagentaDyeObjectID, MAGENTA_DYE_MASS, OrangeDyeObjectID, ORANGE_DYE_MASS, StoneShinglesObjectID, STONE_SHINGLES_MASS, POLISHED_STONE_MASS, STONE_CARVED_MASS, STONE_BRICK_MASS, PolishedStoneObjectID, StoneCarvedObjectID, StoneBrickObjectID, StoneWhackerObjectID, STONE_WHACKER_MASS, StonePickObjectID, STONE_PICK_MASS, StoneAxeObjectID, STONE_AXE_MASS, WoodenWhackerObjectID, WOODEN_WHACKER_MASS, WoodenAxeObjectID, WOODEN_AXE_MASS, SunstoneObjectID, SUNSTONE_MASS, SilverWhackerObjectID, SILVER_WHACKER_MASS, SilverPickObjectID, SILVER_PICK_MASS, SilverAxeObjectID, SILVER_AXE_MASS, SilverCubeObjectID, SILVER_CUBE_MASS, SILVER_BAR_MASS, SilverBarObjectID, SakuraLogObjectID, SakuraLumberObjectID, SAKURA_LUMBER_MASS, RubbleObjectID, RUBBLE_MASS, ReinforcedRubberLumberObjectID, REINFORCED_RUBBER_LUMBER_MASS, RubberLogObjectID, RUBBER_LUMBER_MASS, RedMushroomSporesObjectID, RED_MUSHROOM_SPORES_MASS, QuartziteShinglesObjectID, QUARTZITE_SHINGLES_MASS, QuartzitePolishedObjectID, QUARTZITE_POLISHED_MASS, QuartziteCarvedObjectID, QUARTZITE_CARVED_MASS, QuartziteBrickObjectID, QUARTZITE_BRICK_MASS, MuckshroomSporesObjectID, MUCKSHROOM_SPORES_MASS, ReinforcedOakLumberObjectID, REINFORCED_OAK_LUMBER_MASS, NeptuniumPickObjectID, MOONSTONE_MASS, NeptuniumAxeObjectID, NEPTUNIUM_AXE_MASS, NEPTUNIUM_PICK_MASS, NeptuniumCubeObjectID, NEPTUNIUM_CUBE_MASS, NeptuniumOreObjectID, NEPTUNIUM_BAR_MASS, NeptuniumBarObjectID, RedMushroomObjectID, MushroomLeatherBlockObjectID, MUSHROOM_LEATHER_BLOCK_MASS, MoonstoneObjectID, QuartziteObjectID, LIMESTONE_CARVED_MASS, LIMESTONE_SHINGLES_MASS, LIMESTONE_POLISHED_MASS, LimestoneShinglesObjectID, LimestonePolishedObjectID, LimestoneCarvedObjectID, LimestoneObjectID, LimestoneBrickObjectID, LIMESTONE_BRICK_MASS, GRANITE_SHINGLES_MASS, GraniteShinglesObjectID, GranitePolishedObjectID, GRANITE_POLISHED_MASS, GRANITE_CARVED_MASS, GraniteCarvedObjectID, GRANITE_BRICK_MASS, GraniteBrickObjectID, GraniteObjectID, SakuraLumberObjectID, RubberLumberObjectID, GoldPickObjectID, GOLD_PICK_MASS, GoldAxeObjectID, GOLD_AXE_MASS, GOLD_CUBE_MASS, GoldCubeObjectID, GOLD_BAR_MASS, GoldBarObjectID, GoldOreObjectID, GlassObjectID, GLASS_MASS, SandObjectID, EMBERSTONE_MASS, EmberstoneObjectID, StoneObjectID, CoalOreObjectID, DIAMOND_PICK_MASS, DiamondPickObjectID, DIAMOND_CUBE_MASS, DiamondCubeObjectID, DIAMOND_AXE_MASS, DiamondAxeObjectID, DIAMOND_MASS, DiamondObjectID, DiamondOreObjectID, COTTON_BLOCK_MASS, CottonBlockObjectID, CottonObjectID, COBBLESTONE_BRICK_MASS, CobblestoneBrickObjectID, CobblestoneObjectID, ChestObjectID, CHEST_MASS, ClayShinglesObjectID, CLAY_SHINGLES_MASS, CLAY_POLISHED_MASS, ClayPolishedObjectID, CLAY_CARVED_MASS, ClayCarvedObjectID, CLAY_BRICK_MASS, ClayBrickObjectID, DirtObjectID, ClayObjectID, CLAY_MASS, MuckshroomObjectID, BellflowerObjectID, BlueMushroomSporeObjectID, BLUE_MUSHROOM_SPORE_MASS, BirchLogObjectID, ReinforcedBirchLumberObjectID, REINFORCED_BIRCH_LUMBER_MASS, BirchLumberObjectID, SilverOreObjectID, BIRCH_LUMBER_MASS, OakLogObjectID, OakLumberObjectID, OAK_LUMBER_MASS, BASALT_BRICK_MASS, BASALT_CARVED_MASS, BASALT_POLISHED_MASS, BASALT_SHINGLES_MASS, WoodenPickObjectID, WOODEN_PICK_MASS, BasaltObjectID, PaperObjectID, BasaltBrickObjectID, BasaltCarvedObjectID, BasaltPolishedObjectID, BasaltShinglesObjectID, PAPER_MASS } from "@tenet-world/src/Constants.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; + + +contract RecipeStations is System { + function initRecipeStations() public { + + // recipeThermoblaster + + bytes32[] memory inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = StoneObjectID; + uint8[] memory inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 9; // 9 Stone + + bytes32[] memory outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ThermoblasterObjectID; // TODO + uint8[] memory outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; + + ObjectProperties[] memory outputObjectProperties = new ObjectProperties[](1); + ObjectProperties memory outputOutputProperties; + outputOutputProperties.mass = THERMOBLASTER_MASS; // TODO + outputObjectProperties[0] = outputOutputProperties; + + bytes32 newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeWorkbench + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = OakLogObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 5; // 5 Oak Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = WorkbenchObjectID; // TODO + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = WORKBENCH_MASS; // TODO + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeDyeOMatic + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = ClayObjectID; + inputObjectTypeIds[1] = SandObjectID; + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; + inputObjectTypeAmounts[1] = 2; + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = DyeomaticObjectID; // TODO + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = DYE_O_MATIC_MASS; // TODO + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + } +} \ No newline at end of file diff --git a/examples/everlon/packages/world/src/systems/RecipeSysDye.sol b/examples/everlon/packages/world/src/systems/RecipeSysDye.sol new file mode 100644 index 000000000..0e7a32dd8 --- /dev/null +++ b/examples/everlon/packages/world/src/systems/RecipeSysDye.sol @@ -0,0 +1,396 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/keysintable/hasKey.sol"; +import { getKeysInTable } from "@latticexyz/world/src/modules/keysintable/getKeysInTable.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; + +import { Recipes, RecipesData, RecipesTableId } from "@tenet-world/src/codegen/tables/Recipes.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; + +import { initializeBytes32Array } from "@tenet-utils/src/ArrayUtils.sol"; +import { DandelionObjectID, RoseObjectID, LilacObjectID, PinkDyeObjectID, PINK_DYE_MASS, PurpleDyeObjectID, PURPLE_DYE_MASS, RedDyeObjectID, RED_DYE_MASS, TanDyeObjectID, TAN_DYE_MASS, WhiteDyeObjectID, WHITE_DYE_MASS, YellowDyeObjectID, YELLOW_DYE_MASS, BlackDyeObjectID, BLACK_DYE_MASS, SilverDyeObjectID, SILVER_DYE_MASS, AzaleaObjectID, OrangeDyeObjectID, ORANGE_DYE_MASS, DaylilyObjectID, LilacObjectID, HempObjectID, BlueDyeObjectID, BLUE_DYE_MASS, BrownDyeObjectID, BROWN_DYE_MASS, GreenDyeObjectID, GREEN_DYE_MASS, MagentaDyeObjectID, MAGENTA_DYE_MASS, OrangeDyeObjectID, ORANGE_DYE_MASS, StoneShinglesObjectID, STONE_SHINGLES_MASS, POLISHED_STONE_MASS, STONE_CARVED_MASS, STONE_BRICK_MASS, PolishedStoneObjectID, StoneCarvedObjectID, StoneBrickObjectID, StoneWhackerObjectID, STONE_WHACKER_MASS, StonePickObjectID, STONE_PICK_MASS, StoneAxeObjectID, STONE_AXE_MASS, WoodenWhackerObjectID, WOODEN_WHACKER_MASS, WoodenAxeObjectID, WOODEN_AXE_MASS, SunstoneObjectID, SUNSTONE_MASS, SilverWhackerObjectID, SILVER_WHACKER_MASS, SilverPickObjectID, SILVER_PICK_MASS, SilverAxeObjectID, SILVER_AXE_MASS, SilverCubeObjectID, SILVER_CUBE_MASS, SILVER_BAR_MASS, SilverBarObjectID, SakuraLogObjectID, SakuraLumberObjectID, SAKURA_LUMBER_MASS, RubbleObjectID, RUBBLE_MASS, ReinforcedRubberLumberObjectID, REINFORCED_RUBBER_LUMBER_MASS, RubberLogObjectID, RUBBER_LUMBER_MASS, RedMushroomSporesObjectID, RED_MUSHROOM_SPORES_MASS, QuartziteShinglesObjectID, QUARTZITE_SHINGLES_MASS, QuartzitePolishedObjectID, QUARTZITE_POLISHED_MASS, QuartziteCarvedObjectID, QUARTZITE_CARVED_MASS, QuartziteBrickObjectID, QUARTZITE_BRICK_MASS, MuckshroomSporesObjectID, MUCKSHROOM_SPORES_MASS, ReinforcedOakLumberObjectID, REINFORCED_OAK_LUMBER_MASS, NeptuniumPickObjectID, MOONSTONE_MASS, NeptuniumAxeObjectID, NEPTUNIUM_AXE_MASS, NEPTUNIUM_PICK_MASS, NeptuniumCubeObjectID, NEPTUNIUM_CUBE_MASS, NeptuniumOreObjectID, NEPTUNIUM_BAR_MASS, NeptuniumBarObjectID, RedMushroomObjectID, MushroomLeatherBlockObjectID, MUSHROOM_LEATHER_BLOCK_MASS, MoonstoneObjectID, QuartziteObjectID, LIMESTONE_CARVED_MASS, LIMESTONE_SHINGLES_MASS, LIMESTONE_POLISHED_MASS, LimestoneShinglesObjectID, LimestonePolishedObjectID, LimestoneCarvedObjectID, LimestoneObjectID, LimestoneBrickObjectID, LIMESTONE_BRICK_MASS, GRANITE_SHINGLES_MASS, GraniteShinglesObjectID, GranitePolishedObjectID, GRANITE_POLISHED_MASS, GRANITE_CARVED_MASS, GraniteCarvedObjectID, GRANITE_BRICK_MASS, GraniteBrickObjectID, GraniteObjectID, SakuraLumberObjectID, RubberLumberObjectID, GoldPickObjectID, GOLD_PICK_MASS, GoldAxeObjectID, GOLD_AXE_MASS, GOLD_CUBE_MASS, GoldCubeObjectID, GOLD_BAR_MASS, GoldBarObjectID, GoldOreObjectID, GlassObjectID, GLASS_MASS, SandObjectID, EMBERSTONE_MASS, EmberstoneObjectID, StoneObjectID, CoalOreObjectID, DIAMOND_PICK_MASS, DiamondPickObjectID, DIAMOND_CUBE_MASS, DiamondCubeObjectID, DIAMOND_AXE_MASS, DiamondAxeObjectID, DIAMOND_MASS, DiamondObjectID, DiamondOreObjectID, COTTON_BLOCK_MASS, CottonBlockObjectID, CottonObjectID, COBBLESTONE_BRICK_MASS, CobblestoneBrickObjectID, CobblestoneObjectID, ChestObjectID, CHEST_MASS, ClayShinglesObjectID, CLAY_SHINGLES_MASS, CLAY_POLISHED_MASS, ClayPolishedObjectID, CLAY_CARVED_MASS, ClayCarvedObjectID, CLAY_BRICK_MASS, ClayBrickObjectID, DirtObjectID, ClayObjectID, CLAY_MASS, MuckshroomObjectID, BellflowerObjectID, BlueMushroomSporeObjectID, BLUE_MUSHROOM_SPORE_MASS, BirchLogObjectID, ReinforcedBirchLumberObjectID, REINFORCED_BIRCH_LUMBER_MASS, BirchLumberObjectID, SilverOreObjectID, BIRCH_LUMBER_MASS, OakLogObjectID, OakLumberObjectID, OAK_LUMBER_MASS, BASALT_BRICK_MASS, BASALT_CARVED_MASS, BASALT_POLISHED_MASS, BASALT_SHINGLES_MASS, WoodenPickObjectID, WOODEN_PICK_MASS, BasaltObjectID, PaperObjectID, BasaltBrickObjectID, BasaltCarvedObjectID, BasaltPolishedObjectID, BasaltShinglesObjectID, PAPER_MASS } from "@tenet-world/src/Constants.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; + + +contract RecipeSysDye is System { + function initRecipeSysDye() public { + + // recipeBlueDye + + bytes32[] memory inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = BellflowerObjectID; // TODO: Define BellflowerObjectID + uint8[] memory inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 10; // 10 Bellflower + + bytes32[] memory outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BlueDyeObjectID; // TODO: Define BlueDyeObjectID + uint8[] memory outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 10; // 10 Blue Dye + + ObjectProperties[] memory outputObjectProperties = new ObjectProperties[](1); + ObjectProperties memory outputOutputProperties; + outputOutputProperties.mass = BLUE_DYE_MASS; // TODO: Define BLUE_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + bytes32 newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBrownDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = SakuraLumberObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 10; // 10 Sakura Lumber + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BrownDyeObjectID; // TODO: Define BrownDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 10; // 16 Brown Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BROWN_DYE_MASS; // TODO: Define BROWN_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeGreenDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = HempObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 10; // 10 Hemp + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GreenDyeObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 10; // 10 Green Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GREEN_DYE_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeMagentaDye + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = LilacObjectID; // TODO: Define LilacObjectID + inputObjectTypeIds[1] = AzaleaObjectID; // TODO: Define LilacObjectID + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 5; // 10 Lilac + inputObjectTypeAmounts[1] = 5; // 10 Azalea + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = MagentaDyeObjectID; // TODO: Define MagentaDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 10; // 10 Magenta Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = MAGENTA_DYE_MASS; // TODO: Define MAGENTA_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeOrangeDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = DaylilyObjectID; // TODO: Define DaylilyObjectID + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 10; // 10 Daylily + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = OrangeDyeObjectID; // TODO: Define OrangeDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 10; // 10 Orange Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = ORANGE_DYE_MASS; // TODO: Define ORANGE_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipePinkDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = AzaleaObjectID; // TODO: Define AzaleaObjectID + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 10; // 10 Azalea + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = PinkDyeObjectID; // TODO: Define PinkDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 10; // 10 Pink Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = PINK_DYE_MASS; // TODO: Define PINK_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipePurpleDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = LilacObjectID; // Assuming LilacObjectID is defined + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 10; // 10 Lilac + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = PurpleDyeObjectID; // TODO: Define PurpleDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 10; // 10 Purple Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = PURPLE_DYE_MASS; // TODO: Define PURPLE_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeRedDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = RoseObjectID; // TODO: Define RoseObjectID + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 10; // 12 Rose + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = RedDyeObjectID; // TODO: Define RedDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 10; // 10 Red Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = RED_DYE_MASS; // TODO: Define RED_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeTanDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = SandObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 5; // 5 Sand + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = TanDyeObjectID; // TODO: Define TanDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 10; // 10 Tan Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = TAN_DYE_MASS; // TODO: Define TAN_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeWhiteDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = CottonBlockObjectID; // TODO: Define CottonBlockObjectID + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 2; // 2 Cotton Block + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = WhiteDyeObjectID; // TODO: Define WhiteDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 8; // 8 White Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = WHITE_DYE_MASS; // TODO: Define WHITE_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeYellowDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = DandelionObjectID; // TODO: Define DandelionObjectID + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 10; // 10 Dandelion + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = YellowDyeObjectID; // TODO: Define YellowDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 10; // 10 Yellow Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = YELLOW_DYE_MASS; // TODO: Define YELLOW_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeBlackDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = NeptuniumOreObjectID; // TODO: Define NeptuniumNuggetObjectID + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 1; // 1 Neptunium Nugget + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BlackDyeObjectID; // TODO: Define BlackDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 20; // 20 Black Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BLACK_DYE_MASS; // TODO: Define BLACK_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeSilverDye + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = SilverOreObjectID; // TODO: Define SilverOreObjectID + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 1; // 1 Silver Ore + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SilverDyeObjectID; // TODO: Define SilverDyeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 9; // 9 Silver Dye + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = SILVER_DYE_MASS; // TODO: Define SILVER_DYE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + } +} \ No newline at end of file diff --git a/examples/everlon/packages/world/src/systems/RecipeSysThree.sol b/examples/everlon/packages/world/src/systems/RecipeSysThree.sol new file mode 100644 index 000000000..4958bd963 --- /dev/null +++ b/examples/everlon/packages/world/src/systems/RecipeSysThree.sol @@ -0,0 +1,458 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/keysintable/hasKey.sol"; +import { getKeysInTable } from "@latticexyz/world/src/modules/keysintable/getKeysInTable.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; + +import { Recipes, RecipesData, RecipesTableId } from "@tenet-world/src/codegen/tables/Recipes.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; + +import { initializeBytes32Array } from "@tenet-utils/src/ArrayUtils.sol"; +import { StoneShinglesObjectID, STONE_SHINGLES_MASS, POLISHED_STONE_MASS, STONE_CARVED_MASS, STONE_BRICK_MASS, PolishedStoneObjectID, StoneCarvedObjectID, StoneBrickObjectID, StoneWhackerObjectID, STONE_WHACKER_MASS, StonePickObjectID, STONE_PICK_MASS, StoneAxeObjectID, STONE_AXE_MASS, WoodenWhackerObjectID, WOODEN_WHACKER_MASS, WoodenAxeObjectID, WOODEN_AXE_MASS, SunstoneObjectID, SUNSTONE_MASS, SilverWhackerObjectID, SILVER_WHACKER_MASS, SilverPickObjectID, SILVER_PICK_MASS, SilverAxeObjectID, SILVER_AXE_MASS, SilverCubeObjectID, SILVER_CUBE_MASS, SILVER_BAR_MASS, SilverBarObjectID, SakuraLogObjectID, SakuraLumberObjectID, SAKURA_LUMBER_MASS, RubbleObjectID, RUBBLE_MASS, ReinforcedRubberLumberObjectID, REINFORCED_RUBBER_LUMBER_MASS, RubberLogObjectID, RUBBER_LUMBER_MASS, RedMushroomSporesObjectID, RED_MUSHROOM_SPORES_MASS, QuartziteShinglesObjectID, QUARTZITE_SHINGLES_MASS, QuartzitePolishedObjectID, QUARTZITE_POLISHED_MASS, QuartziteCarvedObjectID, QUARTZITE_CARVED_MASS, QuartziteBrickObjectID, QUARTZITE_BRICK_MASS, MuckshroomSporesObjectID, MUCKSHROOM_SPORES_MASS, ReinforcedOakLumberObjectID, REINFORCED_OAK_LUMBER_MASS, NeptuniumPickObjectID, MOONSTONE_MASS, NeptuniumAxeObjectID, NEPTUNIUM_AXE_MASS, NEPTUNIUM_PICK_MASS, NeptuniumCubeObjectID, NEPTUNIUM_CUBE_MASS, NeptuniumOreObjectID, NEPTUNIUM_BAR_MASS, NeptuniumBarObjectID, RedMushroomObjectID, MushroomLeatherBlockObjectID, MUSHROOM_LEATHER_BLOCK_MASS, MoonstoneObjectID, QuartziteObjectID, LIMESTONE_CARVED_MASS, LIMESTONE_SHINGLES_MASS, LIMESTONE_POLISHED_MASS, LimestoneShinglesObjectID, LimestonePolishedObjectID, LimestoneCarvedObjectID, LimestoneObjectID, LimestoneBrickObjectID, LIMESTONE_BRICK_MASS, GRANITE_SHINGLES_MASS, GraniteShinglesObjectID, GranitePolishedObjectID, GRANITE_POLISHED_MASS, GRANITE_CARVED_MASS, GraniteCarvedObjectID, GRANITE_BRICK_MASS, GraniteBrickObjectID, GraniteObjectID, SakuraLumberObjectID, RubberLumberObjectID, GoldPickObjectID, GOLD_PICK_MASS, GoldAxeObjectID, GOLD_AXE_MASS, GOLD_CUBE_MASS, GoldCubeObjectID, GOLD_BAR_MASS, GoldBarObjectID, GoldOreObjectID, GlassObjectID, GLASS_MASS, SandObjectID, EMBERSTONE_MASS, EmberstoneObjectID, StoneObjectID, CoalOreObjectID, DIAMOND_PICK_MASS, DiamondPickObjectID, DIAMOND_CUBE_MASS, DiamondCubeObjectID, DIAMOND_AXE_MASS, DiamondAxeObjectID, DIAMOND_MASS, DiamondObjectID, DiamondOreObjectID, COTTON_BLOCK_MASS, CottonBlockObjectID, CottonObjectID, COBBLESTONE_BRICK_MASS, CobblestoneBrickObjectID, CobblestoneObjectID, ChestObjectID, CHEST_MASS, ClayShinglesObjectID, CLAY_SHINGLES_MASS, CLAY_POLISHED_MASS, ClayPolishedObjectID, CLAY_CARVED_MASS, ClayCarvedObjectID, CLAY_BRICK_MASS, ClayBrickObjectID, DirtObjectID, ClayObjectID, CLAY_MASS, MuckshroomObjectID, BellflowerObjectID, BlueMushroomSporeObjectID, BLUE_MUSHROOM_SPORE_MASS, BirchLogObjectID, ReinforcedBirchLumberObjectID, REINFORCED_BIRCH_LUMBER_MASS, BirchLumberObjectID, SilverOreObjectID, BIRCH_LUMBER_MASS, OakLogObjectID, OakLumberObjectID, OAK_LUMBER_MASS, BASALT_BRICK_MASS, BASALT_CARVED_MASS, BASALT_POLISHED_MASS, BASALT_SHINGLES_MASS, WoodenPickObjectID, WOODEN_PICK_MASS, BasaltObjectID, PaperObjectID, BasaltBrickObjectID, BasaltCarvedObjectID, BasaltPolishedObjectID, BasaltShinglesObjectID, PAPER_MASS } from "@tenet-world/src/Constants.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; + + +contract RecipeSysThree is System { + function initRecipesThree() public { + + // recipeSilverBar + + bytes32[] memory inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = SilverOreObjectID; // Assuming SilverOreObjectID represents "silver nugget" + uint8[] memory inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Silver Nugget + + bytes32[] memory outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SilverBarObjectID; // TODO: Define SilverBarObjectID + uint8[] memory outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Silver Bar + + ObjectProperties[] memory outputObjectProperties = new ObjectProperties[](1); + ObjectProperties memory outputOutputProperties; + outputOutputProperties.mass = SILVER_BAR_MASS; // TODO: Define SILVER_BAR_MASS + outputObjectProperties[0] = outputOutputProperties; + + bytes32 newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeSilverAxe + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = SilverBarObjectID; // From Silver Bar recipe + inputObjectTypeIds[1] = OakLogObjectID; // Assuming OakLogObjectID for "log", adjust if necessary + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Silver Bar + inputObjectTypeAmounts[1] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SilverAxeObjectID; // TODO: Define SilverAxeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Silver Axe + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = SILVER_AXE_MASS; // TODO: Define SILVER_AXE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeSilverCube + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = SilverBarObjectID; // From Silver Bar recipe + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 8; // 8 Silver Bar + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SilverCubeObjectID; // TODO: Define SilverCubeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Silver Cube + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = SILVER_CUBE_MASS; // TODO: Define SILVER_CUBE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeSilverPick + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = SilverBarObjectID; // From Silver Bar recipe + inputObjectTypeIds[1] = OakLogObjectID; // Assuming OakLogObjectID for "log", adjust if necessary + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Silver Bar + inputObjectTypeAmounts[1] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SilverPickObjectID; // TODO: Define SilverPickObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Silver Pick + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = SILVER_PICK_MASS; // TODO: Define SILVER_PICK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeSilverWhacker + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = SilverBarObjectID; // From Silver Bar recipe + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 6; // 6 Silver Bar + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SilverWhackerObjectID; // TODO: Define SilverWhackerObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Silver Whacker + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = SILVER_WHACKER_MASS; // TODO: Define SILVER_WHACKER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeSunstone + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CoalOreObjectID; // Assuming CoalOreObjectID for "coal nuggets" + inputObjectTypeIds[1] = LimestoneObjectID; // Assuming LimestoneObjectID is correct + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Coal Nuggets + inputObjectTypeAmounts[1] = 4; // 4 Limestone + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SunstoneObjectID; // Assuming SunstoneObjectID needs to be defined + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Sunstone + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = SUNSTONE_MASS; // Assuming SUNSTONE_MASS needs to be defined + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeWoodenAxe + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = OakLogObjectID; // Using OakLogObjectID as a placeholder for "log" + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = WoodenAxeObjectID; // Assuming WoodenAxeObjectID needs to be defined + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Wooden Axe + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = WOODEN_AXE_MASS; // Assuming WOODEN_AXE_MASS needs to be defined + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeWoodenWhacker + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = OakLogObjectID; // Using OakLogObjectID as a placeholder for "log" + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 8; // 8 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = WoodenWhackerObjectID; // Assuming WoodenWhackerObjectID needs to be defined + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Wooden Whacker + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = WOODEN_WHACKER_MASS; // Assuming WOODEN_WHACKER_MASS needs to be defined + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeStoneAxe + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = StoneObjectID; // Defined earlier + inputObjectTypeIds[1] = OakLogObjectID; // Using OakLogObjectID as a placeholder for "log" + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 8; // 8 Stone + inputObjectTypeAmounts[1] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = StoneAxeObjectID; // TODO: Define StoneAxeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Stone Axe + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = STONE_AXE_MASS; // TODO: Define STONE_AXE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeStonePick + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = StoneObjectID; // Defined earlier + inputObjectTypeIds[1] = OakLogObjectID; // Using OakLogObjectID as a placeholder for "log" + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 8; // 8 Stone + inputObjectTypeAmounts[1] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = StonePickObjectID; // TODO: Define StonePickObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Stone Pick + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = STONE_PICK_MASS; // TODO: Define STONE_PICK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeStoneWhacker + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = StoneObjectID; // Defined earlier + inputObjectTypeIds[1] = OakLogObjectID; // Using OakLogObjectID for "log" + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Stone + inputObjectTypeAmounts[1] = 2; // 2 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = StoneWhackerObjectID; // TODO: Define StoneWhackerObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Stone Whacker + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = STONE_WHACKER_MASS; // TODO: Define STONE_WHACKER_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeStoneBrick + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = StoneObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Stone + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = StoneBrickObjectID; // TODO: Define StoneBrickObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Stone Brick + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = STONE_BRICK_MASS; // TODO: Define STONE_BRICK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeStoneCarved + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = StoneObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Stone + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = StoneCarvedObjectID; // TODO: Define StoneCarvedObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Stone Carved + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = STONE_CARVED_MASS; // TODO: Define STONE_CARVED_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeStonePolished + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = StoneObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Stone + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = PolishedStoneObjectID; // TODO: Define PolishedStoneObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Polished Stone + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = POLISHED_STONE_MASS; // TODO: Define POLISHED_STONE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeStoneShingles + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = StoneBrickObjectID; // Assuming StoneBrickObjectID is for "stone brick" + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Stone Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = StoneShinglesObjectID; // TODO: Define StoneShinglesObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Stone Shingles + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = STONE_SHINGLES_MASS; // TODO: Define STONE_SHINGLES_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + } +} \ No newline at end of file diff --git a/examples/everlon/packages/world/src/systems/RecipeSystem.sol b/examples/everlon/packages/world/src/systems/RecipeSystem.sol new file mode 100644 index 000000000..e97a6de22 --- /dev/null +++ b/examples/everlon/packages/world/src/systems/RecipeSystem.sol @@ -0,0 +1,844 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/keysintable/hasKey.sol"; +import { getKeysInTable } from "@latticexyz/world/src/modules/keysintable/getKeysInTable.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; + +import { Recipes, RecipesData, RecipesTableId } from "@tenet-world/src/codegen/tables/Recipes.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; + +import { initializeBytes32Array } from "@tenet-utils/src/ArrayUtils.sol"; +import { GRANITE_SHINGLES_MASS, GraniteShinglesObjectID, GranitePolishedObjectID, GRANITE_POLISHED_MASS, GRANITE_CARVED_MASS, GraniteCarvedObjectID, GRANITE_BRICK_MASS, GraniteBrickObjectID, GraniteObjectID, SakuraLumberObjectID, RubberLumberObjectID, GoldPickObjectID, GOLD_PICK_MASS, GoldAxeObjectID, GOLD_AXE_MASS, GOLD_CUBE_MASS, GoldCubeObjectID, GOLD_BAR_MASS, GoldBarObjectID, GoldOreObjectID, GlassObjectID, GLASS_MASS, SandObjectID, EMBERSTONE_MASS, EmberstoneObjectID, StoneObjectID, CoalOreObjectID, DIAMOND_PICK_MASS, DiamondPickObjectID, DIAMOND_CUBE_MASS, DiamondCubeObjectID, DIAMOND_AXE_MASS, DiamondAxeObjectID, DIAMOND_MASS, DiamondObjectID, DiamondOreObjectID, COTTON_BLOCK_MASS, CottonBlockObjectID, CottonObjectID, COBBLESTONE_BRICK_MASS, CobblestoneBrickObjectID, CobblestoneObjectID, ChestObjectID, CHEST_MASS, ClayShinglesObjectID, CLAY_SHINGLES_MASS, CLAY_POLISHED_MASS, ClayPolishedObjectID, CLAY_CARVED_MASS, ClayCarvedObjectID, CLAY_BRICK_MASS, ClayBrickObjectID, DirtObjectID, ClayObjectID, CLAY_MASS, MuckshroomObjectID, BellflowerObjectID, BlueMushroomSporeObjectID, BLUE_MUSHROOM_SPORE_MASS, BirchLogObjectID, ReinforcedBirchLumberObjectID, REINFORCED_BIRCH_LUMBER_MASS, BirchLumberObjectID, SilverOreObjectID, BIRCH_LUMBER_MASS, OakLogObjectID, OakLumberObjectID, OAK_LUMBER_MASS, BASALT_BRICK_MASS, BASALT_CARVED_MASS, BASALT_POLISHED_MASS, BASALT_SHINGLES_MASS, WoodenPickObjectID, WOODEN_PICK_MASS, BasaltObjectID, PaperObjectID, BasaltBrickObjectID, BasaltCarvedObjectID, BasaltPolishedObjectID, BasaltShinglesObjectID, PAPER_MASS } from "@tenet-world/src/Constants.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; + +contract RecipeSystem is System { + // TODO: Make this only callable once + function initRecipes() public { + // 1 Oak Log -> 4 Oak Lumber + + // Recipe inputs + bytes32[] memory inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = OakLogObjectID; + uint8[] memory inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 1; + + // Recipe outputs + bytes32[] memory outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = OakLumberObjectID; + uint8[] memory outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; + ObjectProperties[] memory outputObjectProperties = new ObjectProperties[](1); + ObjectProperties memory outputOutputProperties; + outputOutputProperties.mass = OAK_LUMBER_MASS; + outputObjectProperties[0] = outputOutputProperties; + + bytes32 newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // Oak Log 4 -> 1 Wooden Pick + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = OakLogObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = WoodenPickObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = WOODEN_PICK_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // 8 Oak Lumber -> 1 Chest + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = OakLumberObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 8; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ChestObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = CHEST_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // 8 Birch Lumber -> 1 Chest + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = BirchLumberObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 8; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ChestObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = CHEST_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // 8 Rubber Lumber -> 1 Chest + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = RubberLumberObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 8; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ChestObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = CHEST_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // 8 Sakura Lumber -> 1 Chest + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = SakuraLumberObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 8; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ChestObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = CHEST_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBasaltBrick + + // Recipe inputs + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = BasaltObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BasaltBrickObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BASALT_BRICK_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBasaltCarved + + // Recipe inputs + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = BasaltBrickObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BasaltCarvedObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BASALT_CARVED_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBasaltPolished + + // Identical structure to recipeBasaltCarved, with adjusted output type + // Recipe inputs + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = BasaltBrickObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BasaltPolishedObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BASALT_POLISHED_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBasaltShingles + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = BasaltBrickObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BasaltShinglesObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BASALT_SHINGLES_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBirchLumber + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = BirchLogObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 1; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = BirchLumberObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = BIRCH_LUMBER_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeBirchReinforced + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = BirchLumberObjectID; // Adjust if there's a specific ID + inputObjectTypeIds[1] = SilverOreObjectID; + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; + inputObjectTypeAmounts[1] = 1; + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ReinforcedBirchLumberObjectID; // Define this ID if not already defined + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = REINFORCED_BIRCH_LUMBER_MASS; // Define this mass if not already defined + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeClay + + // Recipe inputs + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = DirtObjectID; // This is defined earlier, no TODO needed here + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Dirt + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ClayObjectID; // This is defined earlier, no TODO needed here + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Clay + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = CLAY_MASS; // This is defined earlier, no TODO needed here + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeClayBrick + + // Recipe inputs + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = ClayObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Clay + + // Recipe outputs + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ClayBrickObjectID; // Defined earlier + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Clay Brick + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = CLAY_BRICK_MASS; // Defined earlier + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeClayCarved + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = ClayBrickObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Clay Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ClayCarvedObjectID; // TODO: Define ClayCarvedObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Clay Carved + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = CLAY_CARVED_MASS; // TODO: Define CLAY_CARVED_MASS + outputObjectProperties[0] = outputOutputProperties; + + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeClayPolished + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = ClayBrickObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Clay Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ClayPolishedObjectID; // TODO: Define ClayPolishedObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Clay Polished + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = CLAY_POLISHED_MASS; // TODO: Define CLAY_POLISHED_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeClayShingles + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = ClayBrickObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Clay Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ClayShinglesObjectID; // TODO: Define ClayShinglesObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Clay Shingles + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = CLAY_SHINGLES_MASS; // TODO: Define CLAY_SHINGLES_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeCobblestoneBrick + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = CobblestoneObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Rubble + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = CobblestoneBrickObjectID; // TODO: Define CobblestoneBrickObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Cobblestone Brick + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = COBBLESTONE_BRICK_MASS; // TODO: Define COBBLESTONE_BRICK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeCottonBlock + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = CottonObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Cottonball + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = CottonBlockObjectID; // TODO: Define CottonBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Cottonblock + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = COTTON_BLOCK_MASS; // TODO: Define COTTON_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeDiamondGem + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = DiamondOreObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = DiamondObjectID; // TODO: Define DiamondObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Diamond + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = DIAMOND_MASS; // TODO: Define DIAMOND_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeDiamondAxe + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = DiamondObjectID; // TODO: Define DiamondObjectID if not defined + inputObjectTypeIds[1] = OakLogObjectID; // Assuming OakLogObjectID for "log", adjust if necessary + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Diamond Gem + inputObjectTypeAmounts[1] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = DiamondAxeObjectID; // TODO: Define DiamondAxeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Axe + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = DIAMOND_AXE_MASS; // TODO: Define DIAMOND_AXE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeDiamondCube + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = DiamondObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 8; // 8 Diamond Gem + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = DiamondCubeObjectID; // TODO: Define DiamondCubeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Diamond Cube + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = DIAMOND_CUBE_MASS; // TODO: Define DIAMOND_CUBE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeDiamondPick + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = DiamondObjectID; // TODO: Define DiamondObjectID if not defined + inputObjectTypeIds[1] = OakLogObjectID; // Assuming OakLogObjectID for "log", adjust if necessary + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Diamond Gem + inputObjectTypeAmounts[1] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = DiamondPickObjectID; // TODO: Define DiamondPickObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Pick + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = DIAMOND_PICK_MASS; // TODO: Define DIAMOND_PICK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeEmberstone + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = CoalOreObjectID; // Assuming CoalOreObjectID for "coal nuggets", adjust if necessary + inputObjectTypeIds[1] = StoneObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Coal Nuggets + inputObjectTypeAmounts[1] = 4; // 4 Stone + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = EmberstoneObjectID; // Defined earlier + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Emberstone + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = EMBERSTONE_MASS; // Defined earlier + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeGlass + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = SandObjectID; // TODO: Define SandObjectID + inputObjectTypeIds[1] = CoalOreObjectID; // Assuming CoalOreObjectID for "coal", adjust if necessary + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 2; // 2 Sand + inputObjectTypeAmounts[1] = 1; // 1 Coal + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GlassObjectID; // TODO: Define GlassObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Glass + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GLASS_MASS; // TODO: Define GLASS_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeGoldBar + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = GoldOreObjectID; // TODO: Define GoldNuggetObjectID if using a different ID for "gold nugget" + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Gold Nugget + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GoldBarObjectID; // TODO: Define GoldBarObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Gold Bar + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GOLD_BAR_MASS; // TODO: Define GOLD_BAR_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeGoldCube + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = GoldBarObjectID; + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 8; // 8 Gold Bar + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GoldCubeObjectID; // TODO: Define GoldCubeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Gold Cube + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GOLD_CUBE_MASS; // TODO: Define GOLD_CUBE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeGoldAxe + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GoldBarObjectID; // TODO: Define GoldBarObjectID + inputObjectTypeIds[1] = OakLogObjectID; // Assuming OakLogObjectID for "log", adjust if necessary + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Gold Bar + inputObjectTypeAmounts[1] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GoldAxeObjectID; // TODO: Define GoldAxeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Axe + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GOLD_AXE_MASS; // TODO: Define GOLD_AXE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + } + +} \ No newline at end of file diff --git a/examples/everlon/packages/world/src/systems/RecipeSystemTwo.sol b/examples/everlon/packages/world/src/systems/RecipeSystemTwo.sol new file mode 100644 index 000000000..f1d6b5c50 --- /dev/null +++ b/examples/everlon/packages/world/src/systems/RecipeSystemTwo.sol @@ -0,0 +1,714 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/keysintable/hasKey.sol"; +import { getKeysInTable } from "@latticexyz/world/src/modules/keysintable/getKeysInTable.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; + +import { Recipes, RecipesData, RecipesTableId } from "@tenet-world/src/codegen/tables/Recipes.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; + +import { initializeBytes32Array } from "@tenet-utils/src/ArrayUtils.sol"; +import { SilverWhackerObjectID, SILVER_WHACKER_MASS, SilverPickObjectID, SILVER_PICK_MASS, SilverAxeObjectID, SILVER_AXE_MASS, SilverCubeObjectID, SILVER_CUBE_MASS, SILVER_BAR_MASS, SilverBarObjectID, SakuraLogObjectID, SakuraLumberObjectID, SAKURA_LUMBER_MASS, RubbleObjectID, RUBBLE_MASS, ReinforcedRubberLumberObjectID, REINFORCED_RUBBER_LUMBER_MASS, RubberLogObjectID, RUBBER_LUMBER_MASS, RedMushroomSporesObjectID, RED_MUSHROOM_SPORES_MASS, QuartziteShinglesObjectID, QUARTZITE_SHINGLES_MASS, QuartzitePolishedObjectID, QUARTZITE_POLISHED_MASS, QuartziteCarvedObjectID, QUARTZITE_CARVED_MASS, QuartziteBrickObjectID, QUARTZITE_BRICK_MASS, MuckshroomSporesObjectID, MUCKSHROOM_SPORES_MASS, ReinforcedOakLumberObjectID, REINFORCED_OAK_LUMBER_MASS, NeptuniumPickObjectID, MOONSTONE_MASS, NeptuniumAxeObjectID, NEPTUNIUM_AXE_MASS, NEPTUNIUM_PICK_MASS, NeptuniumCubeObjectID, NEPTUNIUM_CUBE_MASS, NeptuniumOreObjectID, NEPTUNIUM_BAR_MASS, NeptuniumBarObjectID, RedMushroomObjectID, MushroomLeatherBlockObjectID, MUSHROOM_LEATHER_BLOCK_MASS, MoonstoneObjectID, QuartziteObjectID, LIMESTONE_CARVED_MASS, LIMESTONE_SHINGLES_MASS, LIMESTONE_POLISHED_MASS, LimestoneShinglesObjectID, LimestonePolishedObjectID, LimestoneCarvedObjectID, LimestoneObjectID, LimestoneBrickObjectID, LIMESTONE_BRICK_MASS, GRANITE_SHINGLES_MASS, GraniteShinglesObjectID, GranitePolishedObjectID, GRANITE_POLISHED_MASS, GRANITE_CARVED_MASS, GraniteCarvedObjectID, GRANITE_BRICK_MASS, GraniteBrickObjectID, GraniteObjectID, SakuraLumberObjectID, RubberLumberObjectID, GoldPickObjectID, GOLD_PICK_MASS, GoldAxeObjectID, GOLD_AXE_MASS, GOLD_CUBE_MASS, GoldCubeObjectID, GOLD_BAR_MASS, GoldBarObjectID, GoldOreObjectID, GlassObjectID, GLASS_MASS, SandObjectID, EMBERSTONE_MASS, EmberstoneObjectID, StoneObjectID, CoalOreObjectID, DIAMOND_PICK_MASS, DiamondPickObjectID, DIAMOND_CUBE_MASS, DiamondCubeObjectID, DIAMOND_AXE_MASS, DiamondAxeObjectID, DIAMOND_MASS, DiamondObjectID, DiamondOreObjectID, COTTON_BLOCK_MASS, CottonBlockObjectID, CottonObjectID, COBBLESTONE_BRICK_MASS, CobblestoneBrickObjectID, CobblestoneObjectID, ChestObjectID, CHEST_MASS, ClayShinglesObjectID, CLAY_SHINGLES_MASS, CLAY_POLISHED_MASS, ClayPolishedObjectID, CLAY_CARVED_MASS, ClayCarvedObjectID, CLAY_BRICK_MASS, ClayBrickObjectID, DirtObjectID, ClayObjectID, CLAY_MASS, MuckshroomObjectID, BellflowerObjectID, BlueMushroomSporeObjectID, BLUE_MUSHROOM_SPORE_MASS, BirchLogObjectID, ReinforcedBirchLumberObjectID, REINFORCED_BIRCH_LUMBER_MASS, BirchLumberObjectID, SilverOreObjectID, BIRCH_LUMBER_MASS, OakLogObjectID, OakLumberObjectID, OAK_LUMBER_MASS, BASALT_BRICK_MASS, BASALT_CARVED_MASS, BASALT_POLISHED_MASS, BASALT_SHINGLES_MASS, WoodenPickObjectID, WOODEN_PICK_MASS, BasaltObjectID, PaperObjectID, BasaltBrickObjectID, BasaltCarvedObjectID, BasaltPolishedObjectID, BasaltShinglesObjectID, PAPER_MASS } from "@tenet-world/src/Constants.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; + + +contract RecipeSystemTwo is System { + function initRecipesTwo() public { + + // recipeGraniteBrick + + bytes32[] memory inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = GraniteObjectID; // Defined earlier + uint8[] memory inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Granite + + bytes32[] memory outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GraniteBrickObjectID; // TODO: Define GraniteBrickObjectID + uint8[] memory outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Granite Brick + + ObjectProperties[] memory outputObjectProperties = new ObjectProperties[](1); + ObjectProperties memory outputOutputProperties; + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GRANITE_BRICK_MASS; // TODO: Define GRANITE_BRICK_MASS + outputObjectProperties[0] = outputOutputProperties; + + bytes32 newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeGraniteCarved + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = GraniteBrickObjectID; // Defined in the previous recipe + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Granite Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GraniteCarvedObjectID; // TODO: Define GraniteCarvedObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Granite Carved + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GRANITE_CARVED_MASS; // TODO: Define GRANITE_CARVED_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeGranitePolished + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = GraniteBrickObjectID; // From Granite Brick recipe + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Granite Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GranitePolishedObjectID; + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Granite Polished + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GRANITE_POLISHED_MASS; + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeGraniteShingles + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = GraniteBrickObjectID; // From Granite Brick recipe + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Granite Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GraniteShinglesObjectID; // TODO: Define GraniteShinglesObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Granite Shingles + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GRANITE_SHINGLES_MASS; // TODO: Define GRANITE_SHINGLES_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeGoldPick + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = GoldBarObjectID; // TODO: Define GoldBarObjectID + inputObjectTypeIds[1] = OakLogObjectID; // Assuming OakLogObjectID for "log", adjust if necessary + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Gold Bar + inputObjectTypeAmounts[1] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = GoldPickObjectID; // TODO: Define GoldPickObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Pick + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = GOLD_PICK_MASS; // TODO: Define GOLD_PICK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeLimestoneBrick + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = LimestoneObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Limestone + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = LimestoneBrickObjectID; // TODO: Define LimestoneBrickObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Limestone Brick + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = LIMESTONE_BRICK_MASS; // TODO: Define LIMESTONE_BRICK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeLimestoneCarved + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = LimestoneBrickObjectID; // From Limestone Brick recipe + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Limestone Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = LimestoneCarvedObjectID; // TODO: Define LimestoneCarvedObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Limestone Carved + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = LIMESTONE_CARVED_MASS; // TODO: Define LIMESTONE_CARVED_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeLimestonePolished + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = LimestoneBrickObjectID; // From Limestone Brick recipe + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Limestone Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = LimestonePolishedObjectID; // TODO: Define LimestonePolishedObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Limestone Polished + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = LIMESTONE_POLISHED_MASS; // TODO: Define LIMESTONE_POLISHED_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeLimestoneShingles + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = LimestoneBrickObjectID; // From Limestone Brick recipe + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Limestone Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = LimestoneShinglesObjectID; // TODO: Define LimestoneShinglesObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Limestone Shingles + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = LIMESTONE_SHINGLES_MASS; // TODO: Define LIMESTONE_SHINGLES_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeMoonstone + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = QuartziteObjectID; // Defined earlier + inputObjectTypeIds[1] = CoalOreObjectID; // Assuming this represents "coal nuggets" + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Quartzite + inputObjectTypeAmounts[1] = 4; // 4 Coal Nuggets + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = MoonstoneObjectID; // Defined earlier + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Moonstone + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = MOONSTONE_MASS; // Defined earlier + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeMushroomLeatherBlock + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = RedMushroomObjectID; // TODO: Define RedMushroomObjectID + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Red Mushroom + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = MushroomLeatherBlockObjectID; // TODO: Define MushroomLeatherBlockObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Mushroom Leather Block + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = MUSHROOM_LEATHER_BLOCK_MASS; // TODO: Define MUSHROOM_LEATHER_BLOCK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeNeptuniumBar + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = NeptuniumOreObjectID; // Assuming this represents "neptunium nugget" + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Neptunium Nugget + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = NeptuniumBarObjectID; // TODO: Define NeptuniumBarObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Neptunium Bar + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = NEPTUNIUM_BAR_MASS; // TODO: Define NEPTUNIUM_BAR_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeNeptuniumCube + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = NeptuniumBarObjectID; // From Neptunium Bar recipe + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 8; // 8 Neptunium Bar + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = NeptuniumCubeObjectID; // TODO: Define NeptuniumCubeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Neptunium Cube + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = NEPTUNIUM_CUBE_MASS; // TODO: Define NEPTUNIUM_CUBE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + + // recipeNeptuniumAxe + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = NeptuniumBarObjectID; // From Neptunium Bar recipe + inputObjectTypeIds[1] = OakLogObjectID; // Assuming OakLogObjectID for "log", adjust if necessary + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Neptunium Bar + inputObjectTypeAmounts[1] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = NeptuniumAxeObjectID; // TODO: Define NeptuniumAxeObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Neptunium Axe + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = NEPTUNIUM_AXE_MASS; // TODO: Define NEPTUNIUM_AXE_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeNeptuniumPick + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = NeptuniumBarObjectID; // From Neptunium Bar recipe + inputObjectTypeIds[1] = OakLogObjectID; // Assuming OakLogObjectID for "log", adjust if necessary + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Neptunium Bar + inputObjectTypeAmounts[1] = 4; // 4 Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = NeptuniumPickObjectID; // TODO: Define NeptuniumPickObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 1; // 1 Neptunium Pick + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = NEPTUNIUM_PICK_MASS; // TODO: Define NEPTUNIUM_PICK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeOakReinforced + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = OakLumberObjectID; // Assuming OakLumberObjectID is defined + inputObjectTypeIds[1] = SilverOreObjectID; // Assuming SilverOreObjectID for "silver nugget", adjust if different + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Oak Lumber + inputObjectTypeAmounts[1] = 1; // 1 Silver Nugget + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ReinforcedOakLumberObjectID; // TODO: Define ReinforcedOakLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Reinforced Oak Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = REINFORCED_OAK_LUMBER_MASS; // TODO: Define mass for Reinforced Oak Lumber + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeQuartziteBrick + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = QuartziteObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Quartzite + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = QuartziteBrickObjectID; // TODO: Define QuartziteBrickObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Quartzite Brick + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = QUARTZITE_BRICK_MASS; // TODO: Define QUARTZITE_BRICK_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeQuartziteCarved + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = QuartziteBrickObjectID; // From Quartzite Brick recipe + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Quartzite Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = QuartziteCarvedObjectID; // TODO: Define QuartziteCarvedObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Quartzite Carved + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = QUARTZITE_CARVED_MASS; // TODO: Define QUARTZITE_CARVED_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeQuartzitePolished + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = QuartziteBrickObjectID; // TODO: Ensure QuartziteBrickObjectID is defined + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Quartzite Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = QuartzitePolishedObjectID; // TODO: Define QuartzitePolishedObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Quartzite Polished + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = QUARTZITE_POLISHED_MASS; // TODO: Define QUARTZITE_POLISHED_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeQuartziteShingles + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = QuartziteBrickObjectID; // TODO: Ensure QuartziteBrickObjectID is defined + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 4; // 4 Quartzite Brick + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = QuartziteShinglesObjectID; // TODO: Define QuartziteShinglesObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Quartzite Shingles + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = QUARTZITE_SHINGLES_MASS; // TODO: Define QUARTZITE_SHINGLES_MASS + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeRubberLumber + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = RubberLogObjectID; // Assuming RubberLogObjectID is defined + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 1; // 1 Rubber Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = RubberLumberObjectID; // TODO: Define RubberLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Rubber Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = RUBBER_LUMBER_MASS; // TODO: Define mass for Rubber Lumber + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeRubberReinforced + + inputObjectTypeIds = new bytes32[](2); + inputObjectTypeIds[0] = RubberLumberObjectID; // From Rubber Lumber recipe + inputObjectTypeIds[1] = SilverOreObjectID; // Assuming SilverOreObjectID represents "silver nugget" + inputObjectTypeAmounts = new uint8[](2); + inputObjectTypeAmounts[0] = 4; // 4 Rubber Lumber + inputObjectTypeAmounts[1] = 1; // 1 Silver Nugget + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = ReinforcedRubberLumberObjectID; // TODO: Define ReinforcedRubberLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Reinforced Rubber Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = REINFORCED_RUBBER_LUMBER_MASS; // TODO: Define mass for Reinforced Rubber Lumber + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeRubble + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = StoneObjectID; // Defined earlier + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 1; // 1 Stone + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = RubbleObjectID; // TODO: Define RubbleObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Rubble + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = RUBBLE_MASS; // TODO: Define mass for Rubble + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + // recipeSakuraLumber + + inputObjectTypeIds = new bytes32[](1); + inputObjectTypeIds[0] = SakuraLogObjectID; // Assuming SakuraLogObjectID is defined + inputObjectTypeAmounts = new uint8[](1); + inputObjectTypeAmounts[0] = 1; // 1 Sakura Log + + outputObjectTypeIds = new bytes32[](1); + outputObjectTypeIds[0] = SakuraLumberObjectID; // TODO: Define SakuraLumberObjectID + outputObjectTypeAmounts = new uint8[](1); + outputObjectTypeAmounts[0] = 4; // 4 Sakura Lumber + + outputObjectProperties = new ObjectProperties[](1); + outputOutputProperties.mass = SAKURA_LUMBER_MASS; // TODO: Define mass for Sakura Lumber + outputObjectProperties[0] = outputOutputProperties; + + newRecipeId = getUniqueEntity(); + Recipes.set( + newRecipeId, + RecipesData({ + inputObjectTypeIds: inputObjectTypeIds, + inputObjectTypeAmounts: inputObjectTypeAmounts, + outputObjectTypeIds: outputObjectTypeIds, + outputObjectTypeAmounts: outputObjectTypeAmounts, + outputObjectProperties: abi.encode(outputObjectProperties) + }) + ); + + } +} \ No newline at end of file diff --git a/examples/everlon/packages/world/src/systems/objects/AirObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/AirObjectSystem.sol index a94471aab..49579161c 100644 --- a/examples/everlon/packages/world/src/systems/objects/AirObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/AirObjectSystem.sol @@ -17,8 +17,10 @@ contract AirObjectSystem is ObjectType { IWorld(world).world_AirObjectSystem_exitWorld.selector, IWorld(world).world_AirObjectSystem_eventHandler.selector, IWorld(world).world_AirObjectSystem_neighbourEventHandler.selector, - "Air", - "" + 0, + 0, + 0, + "Air" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/AsphaltObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/AsphaltObjectSystem.sol index 85356c1c1..2fcd5b638 100644 --- a/examples/everlon/packages/world/src/systems/objects/AsphaltObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/AsphaltObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, AsphaltObjectID, ASPHALT_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, AsphaltObjectID, ASPHALT_MASS } from "@tenet-world/src/Constants.sol"; contract AsphaltObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract AsphaltObjectSystem is ObjectType { IWorld(world).world_AsphaltObjectSys_exitWorld.selector, IWorld(world).world_AsphaltObjectSys_eventHandler.selector, IWorld(world).world_AsphaltObjectSys_neighbourEventHandler.selector, - "Asphalt", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Asphalt" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/BasaltObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/BasaltObjectSystem.sol index a00a95bb7..f07d629c9 100644 --- a/examples/everlon/packages/world/src/systems/objects/BasaltObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/BasaltObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, BasaltObjectID, BASALT_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, BasaltObjectID, BASALT_MASS } from "@tenet-world/src/Constants.sol"; contract BasaltObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract BasaltObjectSystem is ObjectType { IWorld(world).world_BasaltObjectSyst_exitWorld.selector, IWorld(world).world_BasaltObjectSyst_eventHandler.selector, IWorld(world).world_BasaltObjectSyst_neighbourEventHandler.selector, - "Basalt", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Basalt" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/BedrockObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/BedrockObjectSystem.sol index 458f1a643..c749bbfac 100644 --- a/examples/everlon/packages/world/src/systems/objects/BedrockObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/BedrockObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, BedrockObjectID, BEDROCK_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, BedrockObjectID, BEDROCK_MASS } from "@tenet-world/src/Constants.sol"; contract BedrockObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract BedrockObjectSystem is ObjectType { IWorld(world).world_BedrockObjectSys_exitWorld.selector, IWorld(world).world_BedrockObjectSys_eventHandler.selector, IWorld(world).world_BedrockObjectSys_neighbourEventHandler.selector, - "Bedrock", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Bedrock" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/BirchLeafObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/BirchLeafObjectSystem.sol index b6e0bb73c..8944142ee 100644 --- a/examples/everlon/packages/world/src/systems/objects/BirchLeafObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/BirchLeafObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, BirchLeafObjectID, BIRCH_LEAF_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, BirchLeafObjectID, BIRCH_LEAF_MASS } from "@tenet-world/src/Constants.sol"; contract BirchLeafObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract BirchLeafObjectSystem is ObjectType { IWorld(world).world_BirchLeafObjectS_exitWorld.selector, IWorld(world).world_BirchLeafObjectS_eventHandler.selector, IWorld(world).world_BirchLeafObjectS_neighbourEventHandler.selector, - "Birch Leaf", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Birch Leaf" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/BirchLogObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/BirchLogObjectSystem.sol index 3cfdd64fa..eda79c7c2 100644 --- a/examples/everlon/packages/world/src/systems/objects/BirchLogObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/BirchLogObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, BirchLogObjectID, BIRCH_LOG_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, BirchLogObjectID, BIRCH_LOG_MASS } from "@tenet-world/src/Constants.sol"; contract BirchLogObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract BirchLogObjectSystem is ObjectType { IWorld(world).world_BirchLogObjectSy_exitWorld.selector, IWorld(world).world_BirchLogObjectSy_eventHandler.selector, IWorld(world).world_BirchLogObjectSy_neighbourEventHandler.selector, - "Birch Log", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Birch Log" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/ChestObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/ChestObjectSystem.sol new file mode 100644 index 000000000..f8a7f5ceb --- /dev/null +++ b/examples/everlon/packages/world/src/systems/objects/ChestObjectSystem.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; +import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; +import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, ChestObjectID, CHEST_MASS } from "@tenet-world/src/Constants.sol"; + +contract ChestObjectSystem is ObjectType { + function registerObject() public { + address world = _world(); + IObjectRegistrySystem(REGISTRY_ADDRESS).registerObjectType( + ChestObjectID, + world, + IWorld(world).world_ChestObjectSyste_enterWorld.selector, + IWorld(world).world_ChestObjectSyste_exitWorld.selector, + IWorld(world).world_ChestObjectSyste_eventHandler.selector, + IWorld(world).world_ChestObjectSyste_neighbourEventHandler.selector, + 1, + 0, + 0, + "Chest" + ); + } + + function enterWorld( + bytes32 objectEntityId, + VoxelCoord memory coord + ) public override returns (ObjectProperties memory) { + ObjectProperties memory objectProperties; + objectProperties.mass = CHEST_MASS; + return objectProperties; + } + + function exitWorld(bytes32 objectEntityId, VoxelCoord memory coord) public override {} + + function eventHandler( + bytes32 centerObjectEntityId, + bytes32[] memory neighbourObjectEntityIds + ) public override returns (Action[] memory) { + return new Action[](0); + } + + function neighbourEventHandler( + bytes32 neighbourObjectEntityId, + bytes32 centerObjectEntityId + ) public override returns (bool, Action[] memory) { + return (false, new Action[](0)); + } +} diff --git a/examples/everlon/packages/world/src/systems/objects/ClayBrickObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/ClayBrickObjectSystem.sol index 002028f11..2f089ad98 100644 --- a/examples/everlon/packages/world/src/systems/objects/ClayBrickObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/ClayBrickObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, ClayBrickObjectID, CLAY_BRICK_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, ClayBrickObjectID, CLAY_BRICK_MASS } from "@tenet-world/src/Constants.sol"; contract ClayBrickObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract ClayBrickObjectSystem is ObjectType { IWorld(world).world_ClayBrickObjectS_exitWorld.selector, IWorld(world).world_ClayBrickObjectS_eventHandler.selector, IWorld(world).world_ClayBrickObjectS_neighbourEventHandler.selector, - "Clay Brick", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Clay Brick" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/ClayObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/ClayObjectSystem.sol index 45bf3981a..aee5735b0 100644 --- a/examples/everlon/packages/world/src/systems/objects/ClayObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/ClayObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, ClayObjectID, CLAY_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, ClayObjectID, CLAY_MASS } from "@tenet-world/src/Constants.sol"; contract ClayObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract ClayObjectSystem is ObjectType { IWorld(world).world_ClayObjectSystem_exitWorld.selector, IWorld(world).world_ClayObjectSystem_eventHandler.selector, IWorld(world).world_ClayObjectSystem_neighbourEventHandler.selector, - "Clay", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Clay" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/CoalOreObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/CoalOreObjectSystem.sol index 3bd8fab13..262cc6aa5 100644 --- a/examples/everlon/packages/world/src/systems/objects/CoalOreObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/CoalOreObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, CoalOreObjectID, COAL_ORE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, CoalOreObjectID, COAL_ORE_MASS } from "@tenet-world/src/Constants.sol"; contract CoalOreObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract CoalOreObjectSystem is ObjectType { IWorld(world).world_CoalOreObjectSys_exitWorld.selector, IWorld(world).world_CoalOreObjectSys_eventHandler.selector, IWorld(world).world_CoalOreObjectSys_neighbourEventHandler.selector, - "Coal Ore", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Coal Ore" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/CobblestoneObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/CobblestoneObjectSystem.sol index eecfe4ae3..f280680a3 100644 --- a/examples/everlon/packages/world/src/systems/objects/CobblestoneObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/CobblestoneObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, CobblestoneObjectID, COBBLESTONE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, CobblestoneObjectID, COBBLESTONE_MASS } from "@tenet-world/src/Constants.sol"; contract CobblestoneObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract CobblestoneObjectSystem is ObjectType { IWorld(world).world_CobblestoneObjec_exitWorld.selector, IWorld(world).world_CobblestoneObjec_eventHandler.selector, IWorld(world).world_CobblestoneObjec_neighbourEventHandler.selector, - "Cobblestone", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Cobblestone" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/CottonBushObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/CottonBushObjectSystem.sol index 473b37b00..eb84d4466 100644 --- a/examples/everlon/packages/world/src/systems/objects/CottonBushObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/CottonBushObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, CottonBushObjectID, COTTON_BUSH_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, CottonBushObjectID, COTTON_BUSH_MASS } from "@tenet-world/src/Constants.sol"; contract CottonBushObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract CottonBushObjectSystem is ObjectType { IWorld(world).world_CottonBushObject_exitWorld.selector, IWorld(world).world_CottonBushObject_eventHandler.selector, IWorld(world).world_CottonBushObject_neighbourEventHandler.selector, - "Cotton Bush", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Cotton Bush" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/CottonObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/CottonObjectSystem.sol index c79b55785..eb599fac0 100644 --- a/examples/everlon/packages/world/src/systems/objects/CottonObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/CottonObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, CottonObjectID, COTTON_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, CottonObjectID, COTTON_MASS } from "@tenet-world/src/Constants.sol"; contract CottonObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract CottonObjectSystem is ObjectType { IWorld(world).world_CottonObjectSyst_exitWorld.selector, IWorld(world).world_CottonObjectSyst_eventHandler.selector, IWorld(world).world_CottonObjectSyst_neighbourEventHandler.selector, - "Cotton", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Cotton" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/DiamondOreObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/DiamondOreObjectSystem.sol index b8731d935..9648e59a4 100644 --- a/examples/everlon/packages/world/src/systems/objects/DiamondOreObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/DiamondOreObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, DiamondOreObjectID, DIAMOND_ORE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, DiamondOreObjectID, DIAMOND_ORE_MASS } from "@tenet-world/src/Constants.sol"; contract DiamondOreObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract DiamondOreObjectSystem is ObjectType { IWorld(world).world_DiamondOreObject_exitWorld.selector, IWorld(world).world_DiamondOreObject_eventHandler.selector, IWorld(world).world_DiamondOreObject_neighbourEventHandler.selector, - "Diamond Ore", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Diamond Ore" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/DirtObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/DirtObjectSystem.sol index eef5f477c..a4d80a6f6 100644 --- a/examples/everlon/packages/world/src/systems/objects/DirtObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/DirtObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, DirtObjectID, DIRT_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, DirtObjectID, DIRT_MASS } from "@tenet-world/src/Constants.sol"; contract DirtObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract DirtObjectSystem is ObjectType { IWorld(world).world_DirtObjectSystem_exitWorld.selector, IWorld(world).world_DirtObjectSystem_eventHandler.selector, IWorld(world).world_DirtObjectSystem_neighbourEventHandler.selector, - "Dirt", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Dirt" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/EmberstoneObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/EmberstoneObjectSystem.sol index ca50b0b7b..1c3ed1c63 100644 --- a/examples/everlon/packages/world/src/systems/objects/EmberstoneObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/EmberstoneObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, EmberstoneObjectID, EMBERSTONE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, EmberstoneObjectID, EMBERSTONE_MASS } from "@tenet-world/src/Constants.sol"; contract EmberstoneObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract EmberstoneObjectSystem is ObjectType { IWorld(world).world_EmberstoneObject_exitWorld.selector, IWorld(world).world_EmberstoneObject_eventHandler.selector, IWorld(world).world_EmberstoneObject_neighbourEventHandler.selector, - "Emberstone", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Emberstone" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/GoldOreObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/GoldOreObjectSystem.sol index 6ad5fa0c1..e2df6a60a 100644 --- a/examples/everlon/packages/world/src/systems/objects/GoldOreObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/GoldOreObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, GoldOreObjectID, GOLD_ORE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, GoldOreObjectID, GOLD_ORE_MASS } from "@tenet-world/src/Constants.sol"; contract GoldOreObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract GoldOreObjectSystem is ObjectType { IWorld(world).world_GoldOreObjectSys_exitWorld.selector, IWorld(world).world_GoldOreObjectSys_eventHandler.selector, IWorld(world).world_GoldOreObjectSys_neighbourEventHandler.selector, - "Gold Ore", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Gold Ore" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/GraniteObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/GraniteObjectSystem.sol index 50eeb7037..e9d678278 100644 --- a/examples/everlon/packages/world/src/systems/objects/GraniteObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/GraniteObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, GraniteObjectID, GRANITE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, GraniteObjectID, GRANITE_MASS } from "@tenet-world/src/Constants.sol"; contract GraniteObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract GraniteObjectSystem is ObjectType { IWorld(world).world_GraniteObjectSys_exitWorld.selector, IWorld(world).world_GraniteObjectSys_eventHandler.selector, IWorld(world).world_GraniteObjectSys_neighbourEventHandler.selector, - "Granite", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Granite" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/GrassObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/GrassObjectSystem.sol index 1123678be..18d93b6ed 100644 --- a/examples/everlon/packages/world/src/systems/objects/GrassObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/GrassObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, GrassObjectID, GRASS_MASS } from "@tenet-world/src/Constants.sol"; +import { NUM_BLOCK_STACKABLE, REGISTRY_ADDRESS, GrassObjectID, GRASS_MASS } from "@tenet-world/src/Constants.sol"; contract GrassObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract GrassObjectSystem is ObjectType { IWorld(world).world_GrassObjectSyste_exitWorld.selector, IWorld(world).world_GrassObjectSyste_eventHandler.selector, IWorld(world).world_GrassObjectSyste_neighbourEventHandler.selector, - "Grass", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Grass" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/GravelObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/GravelObjectSystem.sol index 0f3c9d0b8..918de0e6e 100644 --- a/examples/everlon/packages/world/src/systems/objects/GravelObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/GravelObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, GravelObjectID, GRAVEL_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, GravelObjectID, GRAVEL_MASS } from "@tenet-world/src/Constants.sol"; contract GravelObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract GravelObjectSystem is ObjectType { IWorld(world).world_GravelObjectSyst_exitWorld.selector, IWorld(world).world_GravelObjectSyst_eventHandler.selector, IWorld(world).world_GravelObjectSyst_neighbourEventHandler.selector, - "Gravel", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Gravel" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/LavaObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/LavaObjectSystem.sol index 7432d4038..6673c5485 100644 --- a/examples/everlon/packages/world/src/systems/objects/LavaObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/LavaObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, LavaObjectID, LAVA_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, LavaObjectID, LAVA_MASS } from "@tenet-world/src/Constants.sol"; contract LavaObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract LavaObjectSystem is ObjectType { IWorld(world).world_LavaObjectSystem_exitWorld.selector, IWorld(world).world_LavaObjectSystem_eventHandler.selector, IWorld(world).world_LavaObjectSystem_neighbourEventHandler.selector, - "Lava", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Lava" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/LimestoneObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/LimestoneObjectSystem.sol index fb60c18b9..bed53ea34 100644 --- a/examples/everlon/packages/world/src/systems/objects/LimestoneObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/LimestoneObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, LimestoneObjectID, LIMESTONE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, LimestoneObjectID, LIMESTONE_MASS } from "@tenet-world/src/Constants.sol"; contract LimestoneObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract LimestoneObjectSystem is ObjectType { IWorld(world).world_LimestoneObjectS_exitWorld.selector, IWorld(world).world_LimestoneObjectS_eventHandler.selector, IWorld(world).world_LimestoneObjectS_neighbourEventHandler.selector, - "Limestone", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Limestone" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/MoonstoneObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/MoonstoneObjectSystem.sol index 275eb673e..54bc3e737 100644 --- a/examples/everlon/packages/world/src/systems/objects/MoonstoneObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/MoonstoneObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, MoonstoneObjectID, MOONSTONE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, MoonstoneObjectID, MOONSTONE_MASS } from "@tenet-world/src/Constants.sol"; contract MoonstoneObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract MoonstoneObjectSystem is ObjectType { IWorld(world).world_MoonstoneObjectS_exitWorld.selector, IWorld(world).world_MoonstoneObjectS_eventHandler.selector, IWorld(world).world_MoonstoneObjectS_neighbourEventHandler.selector, - "Moonstone", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Moonstone" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/MossGrassObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/MossGrassObjectSystem.sol index 911672892..f4f79f1d8 100644 --- a/examples/everlon/packages/world/src/systems/objects/MossGrassObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/MossGrassObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, MossGrassObjectID, MOSS_GRASS_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, MossGrassObjectID, MOSS_GRASS_MASS } from "@tenet-world/src/Constants.sol"; contract MossGrassObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract MossGrassObjectSystem is ObjectType { IWorld(world).world_MossGrassObjectS_exitWorld.selector, IWorld(world).world_MossGrassObjectS_eventHandler.selector, IWorld(world).world_MossGrassObjectS_neighbourEventHandler.selector, - "Moss Grass", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Moss Grass" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/MossObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/MossObjectSystem.sol index a1a0b3583..76e6d8798 100644 --- a/examples/everlon/packages/world/src/systems/objects/MossObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/MossObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, MossObjectID, MOSS_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, MossObjectID, MOSS_MASS } from "@tenet-world/src/Constants.sol"; contract MossObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract MossObjectSystem is ObjectType { IWorld(world).world_MossObjectSystem_exitWorld.selector, IWorld(world).world_MossObjectSystem_eventHandler.selector, IWorld(world).world_MossObjectSystem_neighbourEventHandler.selector, - "Moss", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Moss" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/MuckDirtObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/MuckDirtObjectSystem.sol index 8eb0060b9..798bf8c4f 100644 --- a/examples/everlon/packages/world/src/systems/objects/MuckDirtObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/MuckDirtObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, MuckDirtObjectID, MUCK_DIRT_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, MuckDirtObjectID, MUCK_DIRT_MASS } from "@tenet-world/src/Constants.sol"; contract MuckDirtObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract MuckDirtObjectSystem is ObjectType { IWorld(world).world_MuckDirtObjectSy_exitWorld.selector, IWorld(world).world_MuckDirtObjectSy_eventHandler.selector, IWorld(world).world_MuckDirtObjectSy_neighbourEventHandler.selector, - "Muck Dirt", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Muck Dirt" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/MuckGrassObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/MuckGrassObjectSystem.sol index bf9ef5199..58f901c21 100644 --- a/examples/everlon/packages/world/src/systems/objects/MuckGrassObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/MuckGrassObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, MuckGrassObjectID, MUCK_GRASS_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, MuckGrassObjectID, MUCK_GRASS_MASS } from "@tenet-world/src/Constants.sol"; contract MuckGrassObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract MuckGrassObjectSystem is ObjectType { IWorld(world).world_MuckGrassObjectS_exitWorld.selector, IWorld(world).world_MuckGrassObjectS_eventHandler.selector, IWorld(world).world_MuckGrassObjectS_neighbourEventHandler.selector, - "Muck Grass", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Muck Grass" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/NeptuniumOreObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/NeptuniumOreObjectSystem.sol index dfdbca0e6..152f3fdde 100644 --- a/examples/everlon/packages/world/src/systems/objects/NeptuniumOreObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/NeptuniumOreObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, NeptuniumOreObjectID, NEPTUNIUM_ORE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, NeptuniumOreObjectID, NEPTUNIUM_ORE_MASS } from "@tenet-world/src/Constants.sol"; contract NeptuniumOreObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract NeptuniumOreObjectSystem is ObjectType { IWorld(world).world_NeptuniumOreObje_exitWorld.selector, IWorld(world).world_NeptuniumOreObje_eventHandler.selector, IWorld(world).world_NeptuniumOreObje_neighbourEventHandler.selector, - "Neptunium Ore", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Neptunium Ore" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/OakLeafObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/OakLeafObjectSystem.sol index 331008d4e..6a92f3c27 100644 --- a/examples/everlon/packages/world/src/systems/objects/OakLeafObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/OakLeafObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, OakLeafObjectID, OAK_LEAF_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, OakLeafObjectID, OAK_LEAF_MASS } from "@tenet-world/src/Constants.sol"; contract OakLeafObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract OakLeafObjectSystem is ObjectType { IWorld(world).world_OakLeafObjectSys_exitWorld.selector, IWorld(world).world_OakLeafObjectSys_eventHandler.selector, IWorld(world).world_OakLeafObjectSys_neighbourEventHandler.selector, - "Oak Leaf", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Oak Leaf" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/OakLogObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/OakLogObjectSystem.sol index c662f2f68..3b7ab9c5b 100644 --- a/examples/everlon/packages/world/src/systems/objects/OakLogObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/OakLogObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, OakLogObjectID, OAK_LOG_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, OakLogObjectID, OAK_LOG_MASS } from "@tenet-world/src/Constants.sol"; contract OakLogObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract OakLogObjectSystem is ObjectType { IWorld(world).world_OakLogObjectSyst_exitWorld.selector, IWorld(world).world_OakLogObjectSyst_eventHandler.selector, IWorld(world).world_OakLogObjectSyst_neighbourEventHandler.selector, - "Oak Log", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Oak Log" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/OakLumberObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/OakLumberObjectSystem.sol new file mode 100644 index 000000000..98eeced60 --- /dev/null +++ b/examples/everlon/packages/world/src/systems/objects/OakLumberObjectSystem.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; +import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; +import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, OakLumberObjectID, OAK_LUMBER_MASS } from "@tenet-world/src/Constants.sol"; + +contract OakLumberObjectSystem is ObjectType { + function registerObject() public { + address world = _world(); + IObjectRegistrySystem(REGISTRY_ADDRESS).registerObjectType( + OakLumberObjectID, + world, + IWorld(world).world_OakLumberObjectS_enterWorld.selector, + IWorld(world).world_OakLumberObjectS_exitWorld.selector, + IWorld(world).world_OakLumberObjectS_eventHandler.selector, + IWorld(world).world_OakLumberObjectS_neighbourEventHandler.selector, + NUM_BLOCK_STACKABLE, + 0, + 0, + "Oak Lumber" + ); + } + + function enterWorld( + bytes32 objectEntityId, + VoxelCoord memory coord + ) public override returns (ObjectProperties memory) { + ObjectProperties memory objectProperties; + objectProperties.mass = OAK_LUMBER_MASS; + return objectProperties; + } + + function exitWorld(bytes32 objectEntityId, VoxelCoord memory coord) public override {} + + function eventHandler( + bytes32 centerObjectEntityId, + bytes32[] memory neighbourObjectEntityIds + ) public override returns (Action[] memory) { + return new Action[](0); + } + + function neighbourEventHandler( + bytes32 neighbourObjectEntityId, + bytes32 centerObjectEntityId + ) public override returns (bool, Action[] memory) { + return (false, new Action[](0)); + } +} diff --git a/examples/everlon/packages/world/src/systems/objects/QuartziteObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/QuartziteObjectSystem.sol index b2b867f33..52516c29f 100644 --- a/examples/everlon/packages/world/src/systems/objects/QuartziteObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/QuartziteObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, QuartziteObjectID, QUARTZITE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, QuartziteObjectID, QUARTZITE_MASS } from "@tenet-world/src/Constants.sol"; contract QuartziteObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract QuartziteObjectSystem is ObjectType { IWorld(world).world_QuartziteObjectS_exitWorld.selector, IWorld(world).world_QuartziteObjectS_eventHandler.selector, IWorld(world).world_QuartziteObjectS_neighbourEventHandler.selector, - "Quartzite", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Quartzite" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/RubberLeafObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/RubberLeafObjectSystem.sol index 1dd6f9e3f..19b407337 100644 --- a/examples/everlon/packages/world/src/systems/objects/RubberLeafObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/RubberLeafObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, RubberLeafObjectID, RUBBER_LEAF_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, RubberLeafObjectID, RUBBER_LEAF_MASS } from "@tenet-world/src/Constants.sol"; contract RubberLeafObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract RubberLeafObjectSystem is ObjectType { IWorld(world).world_RubberLeafObject_exitWorld.selector, IWorld(world).world_RubberLeafObject_eventHandler.selector, IWorld(world).world_RubberLeafObject_neighbourEventHandler.selector, - "Rubber Leaf", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Rubber Leaf" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/RubberLogObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/RubberLogObjectSystem.sol index bf93a3340..dfb9db82b 100644 --- a/examples/everlon/packages/world/src/systems/objects/RubberLogObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/RubberLogObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, RubberLogObjectID, RUBBER_LOG_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, RubberLogObjectID, RUBBER_LOG_MASS } from "@tenet-world/src/Constants.sol"; contract RubberLogObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract RubberLogObjectSystem is ObjectType { IWorld(world).world_RubberLogObjectS_exitWorld.selector, IWorld(world).world_RubberLogObjectS_eventHandler.selector, IWorld(world).world_RubberLogObjectS_neighbourEventHandler.selector, - "Rubber Log", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Rubber Log" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/SakuraLeafObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/SakuraLeafObjectSystem.sol index aa2d03d09..882c8829a 100644 --- a/examples/everlon/packages/world/src/systems/objects/SakuraLeafObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/SakuraLeafObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, SakuraLeafObjectID, SAKURA_LEAF_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, SakuraLeafObjectID, SAKURA_LEAF_MASS } from "@tenet-world/src/Constants.sol"; contract SakuraLeafObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract SakuraLeafObjectSystem is ObjectType { IWorld(world).world_SakuraLeafObject_exitWorld.selector, IWorld(world).world_SakuraLeafObject_eventHandler.selector, IWorld(world).world_SakuraLeafObject_neighbourEventHandler.selector, - "Sakura Leaf", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Sakura Leaf" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/SakuraLogObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/SakuraLogObjectSystem.sol index 2a60b34c5..651b6decf 100644 --- a/examples/everlon/packages/world/src/systems/objects/SakuraLogObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/SakuraLogObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, SakuraLogObjectID, SAKURA_LOG_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, SakuraLogObjectID, SAKURA_LOG_MASS } from "@tenet-world/src/Constants.sol"; contract SakuraLogObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract SakuraLogObjectSystem is ObjectType { IWorld(world).world_SakuraLogObjectS_exitWorld.selector, IWorld(world).world_SakuraLogObjectS_eventHandler.selector, IWorld(world).world_SakuraLogObjectS_neighbourEventHandler.selector, - "Sakura Log", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Sakura Log" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/SilverOreObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/SilverOreObjectSystem.sol index 1a83c7b17..7ad86db63 100644 --- a/examples/everlon/packages/world/src/systems/objects/SilverOreObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/SilverOreObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, SilverOreObjectID, SILVER_ORE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, SilverOreObjectID, SILVER_ORE_MASS } from "@tenet-world/src/Constants.sol"; contract SilverOreObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract SilverOreObjectSystem is ObjectType { IWorld(world).world_SilverOreObjectS_exitWorld.selector, IWorld(world).world_SilverOreObjectS_eventHandler.selector, IWorld(world).world_SilverOreObjectS_neighbourEventHandler.selector, - "Silver Ore", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Silver Ore" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/SnowObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/SnowObjectSystem.sol index d972af1dc..50bedf695 100644 --- a/examples/everlon/packages/world/src/systems/objects/SnowObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/SnowObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, SnowObjectID, SNOW_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, SnowObjectID, SNOW_MASS } from "@tenet-world/src/Constants.sol"; contract SnowObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract SnowObjectSystem is ObjectType { IWorld(world).world_SnowObjectSystem_exitWorld.selector, IWorld(world).world_SnowObjectSystem_eventHandler.selector, IWorld(world).world_SnowObjectSystem_neighbourEventHandler.selector, - "Snow", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Snow" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/SoilObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/SoilObjectSystem.sol index 1f18c40ab..590ffa5dc 100644 --- a/examples/everlon/packages/world/src/systems/objects/SoilObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/SoilObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, SoilObjectID, SOIL_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, SoilObjectID, SOIL_MASS } from "@tenet-world/src/Constants.sol"; contract SoilObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract SoilObjectSystem is ObjectType { IWorld(world).world_SoilObjectSystem_exitWorld.selector, IWorld(world).world_SoilObjectSystem_eventHandler.selector, IWorld(world).world_SoilObjectSystem_neighbourEventHandler.selector, - "Soil", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Soil" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/StoneObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/StoneObjectSystem.sol index 7afb965c7..39d57b3c1 100644 --- a/examples/everlon/packages/world/src/systems/objects/StoneObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/StoneObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, StoneObjectID, STONE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, StoneObjectID, STONE_MASS } from "@tenet-world/src/Constants.sol"; contract StoneObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract StoneObjectSystem is ObjectType { IWorld(world).world_StoneObjectSyste_exitWorld.selector, IWorld(world).world_StoneObjectSyste_eventHandler.selector, IWorld(world).world_StoneObjectSyste_neighbourEventHandler.selector, - "Stone", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Stone" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/SunstoneObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/SunstoneObjectSystem.sol index da2d1f1df..19b609b8d 100644 --- a/examples/everlon/packages/world/src/systems/objects/SunstoneObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/SunstoneObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, SunstoneObjectID, SUNSTONE_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, SunstoneObjectID, SUNSTONE_MASS } from "@tenet-world/src/Constants.sol"; contract SunstoneObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract SunstoneObjectSystem is ObjectType { IWorld(world).world_SunstoneObjectSy_exitWorld.selector, IWorld(world).world_SunstoneObjectSy_eventHandler.selector, IWorld(world).world_SunstoneObjectSy_neighbourEventHandler.selector, - "Sunstone", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Sunstone" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/SwitchGrassObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/SwitchGrassObjectSystem.sol index cc77c187c..6000ed3dc 100644 --- a/examples/everlon/packages/world/src/systems/objects/SwitchGrassObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/SwitchGrassObjectSystem.sol @@ -5,7 +5,7 @@ import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; -import { REGISTRY_ADDRESS, SwitchGrassObjectID, SWITCH_GRASS_MASS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, SwitchGrassObjectID, SWITCH_GRASS_MASS } from "@tenet-world/src/Constants.sol"; contract SwitchGrassObjectSystem is ObjectType { function registerObject() public { @@ -17,8 +17,10 @@ contract SwitchGrassObjectSystem is ObjectType { IWorld(world).world_SwitchGrassObjec_exitWorld.selector, IWorld(world).world_SwitchGrassObjec_eventHandler.selector, IWorld(world).world_SwitchGrassObjec_neighbourEventHandler.selector, - "Switch Grass", - "" + NUM_BLOCK_STACKABLE, + 0, + 0, + "Switch Grass" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/agents/BuilderObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/agents/BuilderObjectSystem.sol index a3cac6dae..cb4aa3a15 100644 --- a/examples/everlon/packages/world/src/systems/objects/agents/BuilderObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/agents/BuilderObjectSystem.sol @@ -26,8 +26,10 @@ contract BuilderObjectSystem is AgentType { IWorld(world).world_BuilderObjectSys_exitWorld.selector, IWorld(world).world_BuilderObjectSys_eventHandler.selector, IWorld(world).world_BuilderObjectSys_neighbourEventHandler.selector, - "Builder", - "" + 1, + 0, + 0, + "Builder" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/agents/FaucetObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/agents/FaucetObjectSystem.sol index a55ac10e6..e07834ff7 100644 --- a/examples/everlon/packages/world/src/systems/objects/agents/FaucetObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/agents/FaucetObjectSystem.sol @@ -30,8 +30,10 @@ contract FaucetObjectSystem is AgentType { IWorld(world).world_FaucetObjectSyst_exitWorld.selector, IWorld(world).world_FaucetObjectSyst_eventHandler.selector, IWorld(world).world_FaucetObjectSyst_neighbourEventHandler.selector, - "Faucet", - "" + 1, + 0, + 0, + "Faucet" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/agents/RunnerObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/agents/RunnerObjectSystem.sol index 7d0a0c081..d8e11c4eb 100644 --- a/examples/everlon/packages/world/src/systems/objects/agents/RunnerObjectSystem.sol +++ b/examples/everlon/packages/world/src/systems/objects/agents/RunnerObjectSystem.sol @@ -22,8 +22,10 @@ contract RunnerObjectSystem is AgentType { IWorld(world).world_RunnerObjectSyst_exitWorld.selector, IWorld(world).world_RunnerObjectSyst_eventHandler.selector, IWorld(world).world_RunnerObjectSyst_neighbourEventHandler.selector, - "Runner", - "" + 1, + 0, + 0, + "Runner" ); } diff --git a/examples/everlon/packages/world/src/systems/objects/items/WoodenPickObjectSystem.sol b/examples/everlon/packages/world/src/systems/objects/items/WoodenPickObjectSystem.sol new file mode 100644 index 000000000..4360e87ef --- /dev/null +++ b/examples/everlon/packages/world/src/systems/objects/items/WoodenPickObjectSystem.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { ObjectType } from "@tenet-base-world/src/prototypes/ObjectType.sol"; +import { IObjectRegistrySystem } from "@tenet-registry/src/codegen/world/IObjectRegistrySystem.sol"; +import { VoxelCoord, ObjectProperties, Action } from "@tenet-utils/src/Types.sol"; +import { REGISTRY_ADDRESS, NUM_BLOCK_STACKABLE, WoodenPickObjectID, WOODEN_PICK_MASS } from "@tenet-world/src/Constants.sol"; + +contract WoodenPickObjectSystem is ObjectType { + function registerObject() public { + address world = _world(); + IObjectRegistrySystem(REGISTRY_ADDRESS).registerObjectType( + WoodenPickObjectID, + world, + IWorld(world).world_WoodenPickObject_enterWorld.selector, + IWorld(world).world_WoodenPickObject_exitWorld.selector, + IWorld(world).world_WoodenPickObject_eventHandler.selector, + IWorld(world).world_WoodenPickObject_neighbourEventHandler.selector, + 1, + 50, + 80, + "Wooden Pick" + ); + } + + function enterWorld( + bytes32 objectEntityId, + VoxelCoord memory coord + ) public override returns (ObjectProperties memory) { + ObjectProperties memory objectProperties; + objectProperties.mass = WOODEN_PICK_MASS; + return objectProperties; + } + + function exitWorld(bytes32 objectEntityId, VoxelCoord memory coord) public override {} + + function eventHandler( + bytes32 centerObjectEntityId, + bytes32[] memory neighbourObjectEntityIds + ) public override returns (Action[] memory) { + return new Action[](0); + } + + function neighbourEventHandler( + bytes32 neighbourObjectEntityId, + bytes32 centerObjectEntityId + ) public override returns (bool, Action[] memory) { + return (false, new Action[](0)); + } +} diff --git a/examples/everlon/packages/world/src/test/BuildMine.t.sol b/examples/everlon/packages/world/src/test/BuildMine.t.sol index 84f9e0587..314492b88 100644 --- a/examples/everlon/packages/world/src/test/BuildMine.t.sol +++ b/examples/everlon/packages/world/src/test/BuildMine.t.sol @@ -5,11 +5,13 @@ import "forge-std/Test.sol"; import { MudTest } from "@latticexyz/store/src/MudTest.sol"; import { IStore } from "@latticexyz/store/src/IStore.sol"; import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; import { getKeysWithValue } from "@latticexyz/world/src/modules/keyswithvalue/getKeysWithValue.sol"; +import { ObjectTypeRegistry, ObjectTypeRegistryTableId } from "@tenet-registry/src/codegen/tables/ObjectTypeRegistry.sol"; import { ObjectType, OwnedBy, ObjectEntity } from "@tenet-world/src/codegen/Tables.sol"; import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; -import { VoxelCoord } from "@tenet-utils/src/Types.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; import { getEntityAtCoord, getEntityPositionStrict, positionDataToVoxelCoord } from "@tenet-base-world/src/Utils.sol"; import { BuilderObjectID, RunnerObjectID, GrassObjectID, AirObjectID } from "@tenet-world/src/Constants.sol"; import { REGISTRY_ADDRESS, SIMULATOR_ADDRESS } from "@tenet-world/src/Constants.sol"; @@ -19,10 +21,12 @@ import { Energy } from "@tenet-simulator/src/codegen/tables/Energy.sol"; import { Health } from "@tenet-simulator/src/codegen/tables/Health.sol"; import { Stamina } from "@tenet-simulator/src/codegen/tables/Stamina.sol"; import { Velocity } from "@tenet-simulator/src/codegen/tables/Velocity.sol"; +import { NUM_MAX_INVENTORY_SLOTS } from "@tenet-base-world/src/Constants.sol"; contract BuildMineTest is MudTest { IWorld private world; IStore private store; + IStore private registryStore; IStore private simStore; address payable internal alice; VoxelCoord faucetAgentCoord = VoxelCoord(197, 27, 203); @@ -33,6 +37,7 @@ contract BuildMineTest is MudTest { super.setUp(); world = IWorld(worldAddress); store = IStore(worldAddress); + registryStore = IStore(REGISTRY_ADDRESS); simStore = IStore(SIMULATOR_ADDRESS); alice = payable(address(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)); } @@ -65,6 +70,10 @@ contract BuildMineTest is MudTest { bytes32 agentInventoryId = agentObjects[0][0]; bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); VoxelCoord memory buildCoord = VoxelCoord(initialAgentCoord.x - 1, initialAgentCoord.y, initialAgentCoord.z - 1); world.build(agentObjectEntityId, objectTypeId, buildCoord, agentInventoryId); @@ -82,6 +91,10 @@ contract BuildMineTest is MudTest { agentInventoryId = agentObjects[0][0]; agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); vm.stopPrank(); } @@ -101,17 +114,18 @@ contract BuildMineTest is MudTest { world.mine(agentObjectEntityId, objectTypeId1, mineCoord1); bytes32 objectTypeId2 = world.getTerrainObjectTypeId(mineCoord2); world.mine(agentObjectEntityId, objectTypeId2, mineCoord2); + assertTrue(objectTypeId1 == objectTypeId2, "Mined objects are not the same"); // get the inventory of the agent bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); - assertTrue(agentObjects.length == 2, "Agent does not have inventory"); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); bytes32 agentInventoryId1 = agentObjects[0][0]; bytes32 agentInventoryObjectTypeId1 = InventoryObject.getObjectTypeId(store, agentInventoryId1); assertTrue(agentInventoryObjectTypeId1 == objectTypeId1, "Agent does not have mined object in inventory"); - assertTrue(agentObjects[1].length == 1, "Agent does not have inventory"); - bytes32 agentInventoryId2 = agentObjects[1][0]; - bytes32 agentInventoryObjectTypeId2 = InventoryObject.getObjectTypeId(store, agentInventoryId2); - assertTrue(agentInventoryObjectTypeId2 == objectTypeId2, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId1) == 2, + "Agent does not have correct number of mined objects in inventory" + ); VoxelCoord memory newAgentCoord = VoxelCoord(initialAgentCoord.x, initialAgentCoord.y, initialAgentCoord.z - 1); world.move(agentObjectEntityId, agentObjectTypeId, initialAgentCoord, newAgentCoord); @@ -124,7 +138,7 @@ contract BuildMineTest is MudTest { assertTrue(agentObjects.length == 1, "Agent still has inventory"); VoxelCoord memory buildCoord2 = VoxelCoord(newAgentCoord.x - 1, newAgentCoord.y + 1, newAgentCoord.z - 1); - world.build(agentObjectEntityId, objectTypeId1, buildCoord2, agentInventoryId2); + world.build(agentObjectEntityId, objectTypeId1, buildCoord2, agentInventoryId1); bytes32 buildEntityId1 = getEntityAtCoord(store, buildCoord1); assertTrue(uint256(buildEntityId1) != 0, "Build object not found at coord"); diff --git a/examples/everlon/packages/world/src/test/Collision.t.sol b/examples/everlon/packages/world/src/test/Collision.t.sol deleted file mode 100644 index f77a21182..000000000 --- a/examples/everlon/packages/world/src/test/Collision.t.sol +++ /dev/null @@ -1,1009 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -import "forge-std/Test.sol"; -import { MudTest } from "@latticexyz/store/src/MudTest.sol"; -import { IStore } from "@latticexyz/store/src/IStore.sol"; -import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; -import { ObjectType, OwnedBy, ObjectEntity } from "@tenet-world/src/codegen/Tables.sol"; -import { VoxelCoord } from "@tenet-utils/src/Types.sol"; -import { getEntityAtCoord, getEntityPositionStrict, positionDataToVoxelCoord } from "@tenet-base-world/src/Utils.sol"; -import { BuilderObjectID, GrassObjectID, AirObjectID, RunnerObjectID } from "@tenet-world/src/Constants.sol"; -import { REGISTRY_ADDRESS, SIMULATOR_ADDRESS } from "@tenet-world/src/Constants.sol"; -import { console } from "forge-std/console.sol"; -import { Mass } from "@tenet-simulator/src/codegen/tables/Mass.sol"; -import { Energy } from "@tenet-simulator/src/codegen/tables/Energy.sol"; -import { Health } from "@tenet-simulator/src/codegen/tables/Health.sol"; -import { Stamina } from "@tenet-simulator/src/codegen/tables/Stamina.sol"; -import { Velocity } from "@tenet-simulator/src/codegen/tables/Velocity.sol"; - -contract CollisionTest is MudTest { - IWorld private world; - IStore private store; - IStore private simStore; - address payable internal alice; - address payable internal bob; - VoxelCoord faucetAgentCoord = VoxelCoord(197, 27, 203); - VoxelCoord agentCoord; - - function setUp() public override { - super.setUp(); - world = IWorld(worldAddress); - store = IStore(worldAddress); - simStore = IStore(SIMULATOR_ADDRESS); - alice = payable(address(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)); - bob = payable(address(0x70997970C51812dc3A010C7d01b50e0d17dc79C8)); - agentCoord = VoxelCoord({ x: faucetAgentCoord.x + 1, y: faucetAgentCoord.y, z: faucetAgentCoord.z }); - } - - function setupAgent() internal returns (bytes32, bytes32) { - bytes32 faucetEntityId = getEntityAtCoord(store, faucetAgentCoord); - assertTrue(uint256(faucetEntityId) != 0, "Agent not found at coord"); - bytes32 faucetObjectEntityId = ObjectEntity.get(store, faucetEntityId); - - bytes32 agentObjectTypeId = RunnerObjectID; - bytes32 agentEntityId = world.claimAgentFromFaucet(faucetObjectEntityId, agentObjectTypeId, agentCoord); - assertTrue(uint256(agentEntityId) != 0, "Agent not found at coord"); - bytes32 agentObjectEntityId = ObjectEntity.get(store, agentEntityId); - - // Move away from the flag and reset velocity - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z) - ); - agentCoord = VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z); - // Set velocity to 0 - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - return (agentEntityId, agentObjectEntityId); - } - - function testMoveSelf() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - - VoxelCoord memory newCoord = VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z); - world.move(agentObjectEntityId, RunnerObjectID, agentCoord, newCoord); - bytes32 newEntityId = getEntityAtCoord(store, newCoord); - bytes32 newCoordObjectEntityId = ObjectEntity.get(store, newEntityId); - assertTrue(newCoordObjectEntityId == agentObjectEntityId, "Agent not moved"); - assertTrue(ObjectType.get(store, newEntityId) == RunnerObjectID, "Agent not moved"); - - vm.stopPrank(); - } - - function testSimpleCollision() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - bytes32 massObjectEntityId; - VoxelCoord memory massCoord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 massEntityId = world.build(agentObjectEntityId, GrassObjectID, massCoord); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - Mass.set(simStore, worldAddress, massObjectEntityId, 1); - Energy.set(simStore, worldAddress, massObjectEntityId, 10); - } - // Move back one - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z) - ); - // Set velocity to 0 - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - uint256 healthBefore = Health.getHealth(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z), - agentCoord - ); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - assertTrue(Health.getHealth(simStore, worldAddress, agentObjectEntityId) == healthBefore, "Health reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 1 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 1,0,0"); - - // Mass should be at x + 1 coord - bytes32 massEntityId = getEntityAtCoord(store, VoxelCoord(massCoord.x + 1, massCoord.y, massCoord.z)); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - assertTrue(ObjectType.get(store, massEntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory massVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, massObjectEntityId), - (VoxelCoord) - ); - assertTrue(massVelocity.x == 1 && massVelocity.y == 0 && massVelocity.z == 0, "Mass velocity not 1,0,0"); - - vm.stopPrank(); - } - - function testCollisionBounceBack() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - bytes32 massObjectEntityId; - VoxelCoord memory massCoord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 massEntityId = world.build(agentObjectEntityId, GrassObjectID, massCoord); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - Mass.set(simStore, worldAddress, massObjectEntityId, 5); - Energy.set(simStore, worldAddress, massObjectEntityId, 10); - } - // Move back one - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z) - ); - // Set velocity to 4, 0, 0 - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 4, y: 0, z: 0 }))); - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - uint256 healthBefore = Health.getHealth(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z), - agentCoord - ); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - assertTrue(Health.getHealth(simStore, worldAddress, agentObjectEntityId) < healthBefore, "Health not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 4 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 4,0,0"); - - // Mass should be at x + 1 coord - bytes32 massEntityId = getEntityAtCoord(store, VoxelCoord(massCoord.x + 1, massCoord.y, massCoord.z)); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - assertTrue(ObjectType.get(store, massEntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory massVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, massObjectEntityId), - (VoxelCoord) - ); - assertTrue(massVelocity.x == 1 && massVelocity.y == 0 && massVelocity.z == 0, "Mass velocity not 1,0,0"); - - vm.stopPrank(); - } - - function testCollisionMultipleObjectsPushed() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - bytes32 massObjectEntityId; - VoxelCoord memory massCoord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z - 1 }); - { - bytes32 massEntityId = world.build(agentObjectEntityId, GrassObjectID, massCoord); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - Mass.set(simStore, worldAddress, massObjectEntityId, 5); - Energy.set(simStore, worldAddress, massObjectEntityId, 10); - Velocity.setVelocity(simStore, worldAddress, massObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 10 }))); - } - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - uint256 healthBefore = Health.getHealth(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z) - ); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - assertTrue(Health.getHealth(simStore, worldAddress, agentObjectEntityId) < healthBefore, "Health not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 1 && agentVelocity.y == 0 && agentVelocity.z == 2, "Agent velocity not 1,0,2"); - - // Mass should be at x + 1 coord - bytes32 massEntityId = getEntityAtCoord(store, VoxelCoord(massCoord.x, massCoord.y, massCoord.z - 2)); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - assertTrue(ObjectType.get(store, massEntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory massVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, massObjectEntityId), - (VoxelCoord) - ); - assertTrue(massVelocity.x == 0 && massVelocity.y == 0 && massVelocity.z == 8, "Mass velocity not 0,0,8"); - - vm.stopPrank(); - } - - function testCollisionMoveTwo() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - bytes32 mass1ObjectEntityId; - VoxelCoord memory mass1Coord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 mass1EntityId = world.build(agentObjectEntityId, GrassObjectID, mass1Coord); - mass1ObjectEntityId = ObjectEntity.get(store, mass1EntityId); - Mass.set(simStore, worldAddress, mass1ObjectEntityId, 5); - Energy.set(simStore, worldAddress, mass1ObjectEntityId, 10); - } - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z + 1) - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - bytes32 mass2ObjectEntityId; - VoxelCoord memory mass2Coord = VoxelCoord({ x: mass1Coord.x + 1, y: mass1Coord.y, z: mass1Coord.z }); - { - bytes32 mass2EntityId = world.build(agentObjectEntityId, GrassObjectID, mass2Coord); - mass2ObjectEntityId = ObjectEntity.get(store, mass2EntityId); - Mass.set(simStore, worldAddress, mass2ObjectEntityId, 1); - Energy.set(simStore, worldAddress, mass2ObjectEntityId, 10); - } - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z + 1), - agentCoord - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z) - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - Mass.set(simStore, worldAddress, mass1ObjectEntityId, 1); - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z), - agentCoord - ); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 1 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 1,0,0"); - - // Mass should be at x + 1 coord - bytes32 mass1EntityId = getEntityAtCoord(store, VoxelCoord(mass1Coord.x + 1, mass1Coord.y, mass1Coord.z)); - mass1ObjectEntityId = ObjectEntity.get(store, mass1EntityId); - assertTrue(ObjectType.get(store, mass1EntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory mass1Velocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, mass1ObjectEntityId), - (VoxelCoord) - ); - assertTrue(mass1Velocity.x == 1 && mass1Velocity.y == 0 && mass1Velocity.z == 0, "Mass velocity not 1,0,0"); - - // Mass should be at x + 1 coord - bytes32 mass2EntityId = getEntityAtCoord(store, VoxelCoord(mass2Coord.x + 1, mass2Coord.y, mass2Coord.z)); - mass2ObjectEntityId = ObjectEntity.get(store, mass2EntityId); - assertTrue(ObjectType.get(store, mass2EntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory mass2Velocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, mass2ObjectEntityId), - (VoxelCoord) - ); - assertTrue(mass2Velocity.x == 1 && mass2Velocity.y == 0 && mass2Velocity.z == 0, "Mass velocity not 1,0,0"); - - vm.stopPrank(); - } - - function testCollisionNoVelocityChange() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - bytes32 massObjectEntityId; - VoxelCoord memory massCoord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 massEntityId = world.build(agentObjectEntityId, GrassObjectID, massCoord); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - Mass.set(simStore, worldAddress, massObjectEntityId, 1); - Energy.set(simStore, worldAddress, massObjectEntityId, 10); - Velocity.setVelocity(simStore, worldAddress, massObjectEntityId, abi.encode(VoxelCoord({ x: 1, y: 0, z: 0 }))); - } - // Move back one - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z) - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z), - agentCoord - ); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 1 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 1,0,0"); - - bytes32 massEntityId = getEntityAtCoord(store, VoxelCoord(massCoord.x, massCoord.y, massCoord.z)); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - assertTrue(ObjectType.get(store, massEntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory massVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, massObjectEntityId), - (VoxelCoord) - ); - assertTrue(massVelocity.x == 1 && massVelocity.y == 0 && massVelocity.z == 0, "Mass velocity not 1,0,0"); - - vm.stopPrank(); - } - - function testCollisionSameDirection() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - bytes32 massObjectEntityId; - VoxelCoord memory massCoord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 massEntityId = world.build(agentObjectEntityId, GrassObjectID, massCoord); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - Mass.set(simStore, worldAddress, massObjectEntityId, 1); - Energy.set(simStore, worldAddress, massObjectEntityId, 10); - Velocity.setVelocity(simStore, worldAddress, massObjectEntityId, abi.encode(VoxelCoord({ x: 1, y: 0, z: 0 }))); - } - // Move back one - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z) - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 4, y: 0, z: 0 }))); - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z), - agentCoord - ); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 5 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 5,0,0"); - - bytes32 massEntityId = getEntityAtCoord(store, VoxelCoord(massCoord.x + 4, massCoord.y, massCoord.z)); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - assertTrue(ObjectType.get(store, massEntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory massVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, massObjectEntityId), - (VoxelCoord) - ); - assertTrue(massVelocity.x == 5 && massVelocity.y == 0 && massVelocity.z == 0, "Mass velocity not 5,0,0"); - - vm.stopPrank(); - } - - function testCollisionOppositeDirectionEqualVelocityDifferentMass() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - bytes32 massObjectEntityId; - VoxelCoord memory massCoord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 massEntityId = world.build(agentObjectEntityId, GrassObjectID, massCoord); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - Mass.set(simStore, worldAddress, massObjectEntityId, 1); - Energy.set(simStore, worldAddress, massObjectEntityId, 10); - Velocity.setVelocity(simStore, worldAddress, massObjectEntityId, abi.encode(VoxelCoord({ x: -1, y: 0, z: 0 }))); - } - // Move back one - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z) - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z), - agentCoord - ); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 1 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 1,0,0"); - - bytes32 massEntityId = getEntityAtCoord(store, VoxelCoord(massCoord.x + 2, massCoord.y, massCoord.z)); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - assertTrue(ObjectType.get(store, massEntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory massVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, massObjectEntityId), - (VoxelCoord) - ); - assertTrue(massVelocity.x == 1 && massVelocity.y == 0 && massVelocity.z == 0, "Mass velocity not 1,0,0"); - - vm.stopPrank(); - } - - function testCollisionOppositeDirectionEqualVelocityEqualMass() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - bytes32 massObjectEntityId; - VoxelCoord memory massCoord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 massEntityId = world.build(agentObjectEntityId, GrassObjectID, massCoord); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - Mass.set(simStore, worldAddress, massObjectEntityId, 5); - Energy.set(simStore, worldAddress, massObjectEntityId, 10); - Velocity.setVelocity(simStore, worldAddress, massObjectEntityId, abi.encode(VoxelCoord({ x: -1, y: 0, z: 0 }))); - } - // Move back one - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z) - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x - 1, agentCoord.y, agentCoord.z), - agentCoord - ); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 1 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 1,0,0"); - - bytes32 massEntityId = getEntityAtCoord(store, VoxelCoord(massCoord.x, massCoord.y, massCoord.z)); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - assertTrue(ObjectType.get(store, massEntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory massVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, massObjectEntityId), - (VoxelCoord) - ); - assertTrue(massVelocity.x == -1 && massVelocity.y == 0 && massVelocity.z == 0, "Mass velocity not -1,0,0"); - - vm.stopPrank(); - } - - function testMoveObject() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - VoxelCoord memory oldCoord = VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z); - bytes32 massEntityId = world.build(agentObjectEntityId, GrassObjectID, oldCoord); - bytes32 massObjectEntityId = ObjectEntity.get(store, massEntityId); - VoxelCoord memory newCoord = VoxelCoord(oldCoord.x + 1, oldCoord.y, oldCoord.z); - // Old coord should not be air - bytes32 moveObjectTypeId = ObjectType.get(store, getEntityAtCoord(store, oldCoord)); - assertTrue(moveObjectTypeId == GrassObjectID, "Old coord is air"); - // New coord should be air - assertTrue(world.getTerrainObjectTypeId(newCoord) == AirObjectID, "New coord not air"); - - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move(agentObjectEntityId, moveObjectTypeId, oldCoord, newCoord); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 0 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 0,0,0"); - - // Old coord should be air - assertTrue(ObjectType.get(store, getEntityAtCoord(store, oldCoord)) == AirObjectID, "Old coord not air"); - // New coord should be moving object - assertTrue(ObjectType.get(store, getEntityAtCoord(store, newCoord)) == moveObjectTypeId, "New coord is air"); - VoxelCoord memory massVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, massObjectEntityId), - (VoxelCoord) - ); - - assertTrue(massVelocity.x == 1 && massVelocity.y == 0 && massVelocity.z == 0, "Mass velocity not 1,0,0"); - - vm.stopPrank(); - } - - function testMoveObjectBounceBack() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z) - ); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z), - VoxelCoord(agentCoord.x + 2, agentCoord.y, agentCoord.z) - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - bytes32 mass1ObjectEntityId; - VoxelCoord memory mass1Coord = VoxelCoord({ x: agentCoord.x + 3, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 mass1EntityId = world.build(agentObjectEntityId, GrassObjectID, mass1Coord); - mass1ObjectEntityId = ObjectEntity.get(store, mass1EntityId); - Mass.set(simStore, worldAddress, mass1ObjectEntityId, 10); - Energy.set(simStore, worldAddress, mass1ObjectEntityId, 10); - Velocity.setVelocity(simStore, worldAddress, mass1ObjectEntityId, abi.encode(VoxelCoord({ x: -4, y: 0, z: 0 }))); - } - - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x + 2, agentCoord.y, agentCoord.z), - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z) - ); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z), - agentCoord - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - bytes32 mass2ObjectEntityId; - VoxelCoord memory mass2Coord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 mass2EntityId = world.build(agentObjectEntityId, GrassObjectID, mass2Coord); - mass2ObjectEntityId = ObjectEntity.get(store, mass2EntityId); - Mass.set(simStore, worldAddress, mass2ObjectEntityId, 5); - Energy.set(simStore, worldAddress, mass2ObjectEntityId, 10); - } - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - GrassObjectID, - mass2Coord, - VoxelCoord(mass2Coord.x + 1, mass2Coord.y, mass2Coord.z) - ); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 0 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 0,0,0"); - - bytes32 mass1EntityId = getEntityAtCoord(store, VoxelCoord(mass1Coord.x, mass1Coord.y, mass1Coord.z)); - mass1ObjectEntityId = ObjectEntity.get(store, mass1EntityId); - assertTrue(ObjectType.get(store, mass1EntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory mass1Velocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, mass1ObjectEntityId), - (VoxelCoord) - ); - assertTrue(mass1Velocity.x == -4 && mass1Velocity.y == 0 && mass1Velocity.z == 0, "Mass velocity not -4,0,0"); - - bytes32 mass2EntityId = getEntityAtCoord(store, VoxelCoord(mass2Coord.x, mass2Coord.y, mass2Coord.z)); - mass2ObjectEntityId = ObjectEntity.get(store, mass2EntityId); - assertTrue(ObjectType.get(store, mass2EntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory mass2Velocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, mass2ObjectEntityId), - (VoxelCoord) - ); - assertTrue(mass2Velocity.x == 0 && mass2Velocity.y == 0 && mass2Velocity.z == 0, "Mass velocity not 0,0,0"); - - vm.stopPrank(); - } - - function testMoveObjectCollisionPushedMultiple() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z) - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - bytes32 mass1ObjectEntityId; - VoxelCoord memory mass1Coord = VoxelCoord({ x: agentCoord.x + 2, y: agentCoord.y, z: agentCoord.z - 1 }); - { - bytes32 mass1EntityId = world.build(agentObjectEntityId, GrassObjectID, mass1Coord); - mass1ObjectEntityId = ObjectEntity.get(store, mass1EntityId); - Mass.set(simStore, worldAddress, mass1ObjectEntityId, 5); - Energy.set(simStore, worldAddress, mass1ObjectEntityId, 10); - Velocity.setVelocity(simStore, worldAddress, mass1ObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 10 }))); - } - - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z), - agentCoord - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - bytes32 mass2ObjectEntityId; - VoxelCoord memory mass2Coord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 mass2EntityId = world.build(agentObjectEntityId, GrassObjectID, mass2Coord); - mass2ObjectEntityId = ObjectEntity.get(store, mass2EntityId); - Mass.set(simStore, worldAddress, mass2ObjectEntityId, 5); - Energy.set(simStore, worldAddress, mass2ObjectEntityId, 10); - } - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - GrassObjectID, - mass2Coord, - VoxelCoord(mass2Coord.x + 1, mass2Coord.y, mass2Coord.z) - ); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 0 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 0,0,0"); - - bytes32 mass1EntityId = getEntityAtCoord(store, VoxelCoord(mass1Coord.x, mass1Coord.y, mass1Coord.z - 2)); - mass1ObjectEntityId = ObjectEntity.get(store, mass1EntityId); - assertTrue(ObjectType.get(store, mass1EntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory mass1Velocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, mass1ObjectEntityId), - (VoxelCoord) - ); - assertTrue(mass1Velocity.x == 0 && mass1Velocity.y == 0 && mass1Velocity.z == 8, "Mass velocity not 0,0,8"); - - bytes32 mass2EntityId = getEntityAtCoord(store, VoxelCoord(mass2Coord.x + 1, mass2Coord.y, mass2Coord.z + 2)); - mass2ObjectEntityId = ObjectEntity.get(store, mass2EntityId); - assertTrue(ObjectType.get(store, mass2EntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory mass2Velocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, mass2ObjectEntityId), - (VoxelCoord) - ); - assertTrue(mass2Velocity.x == 1 && mass2Velocity.y == 0 && mass2Velocity.z == 2, "Mass velocity not 1,0,2"); - - vm.stopPrank(); - } - - function testMoveAgent() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - bytes32 massObjectEntityId; - VoxelCoord memory massCoord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 massEntityId = world.build(agentObjectEntityId, RunnerObjectID, massCoord); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - Mass.set(simStore, worldAddress, massObjectEntityId, 5); - Energy.set(simStore, worldAddress, massObjectEntityId, 10); - Health.setHealth(simStore, worldAddress, massObjectEntityId, 100); - Stamina.setStamina(simStore, worldAddress, massObjectEntityId, 100); - - // Make the owner of the agent different from the one moving it - vm.startPrank(bob, bob); - world.claimAgent(massEntityId); - assertTrue(OwnedBy.get(store, massObjectEntityId) == bob, "Owner not bob"); - vm.stopPrank(); - vm.startPrank(alice, alice); - } - - VoxelCoord memory newMassCoord = VoxelCoord(massCoord.x + 1, massCoord.y, massCoord.z); - - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move(agentObjectEntityId, RunnerObjectID, massCoord, newMassCoord); - assertTrue(OwnedBy.get(store, massObjectEntityId) == bob, "Owner not bob"); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - assertTrue(Stamina.getStamina(simStore, worldAddress, massObjectEntityId) == 100, "Stamina reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 0 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 0,0,0"); - - // Old coord should be air - assertTrue(ObjectType.get(store, getEntityAtCoord(store, massCoord)) == AirObjectID, "Old coord not air"); - // New coord should be moving object - assertTrue(ObjectType.get(store, getEntityAtCoord(store, newMassCoord)) == RunnerObjectID, "New coord is air"); - VoxelCoord memory massVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, massObjectEntityId), - (VoxelCoord) - ); - assertTrue(massVelocity.x == 1 && massVelocity.y == 0 && massVelocity.z == 0, "Mass velocity not 1,0,0"); - - vm.stopPrank(); - } - - function testMoveAgentBounceBack() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z) - ); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z), - VoxelCoord(agentCoord.x + 2, agentCoord.y, agentCoord.z) - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - bytes32 mass1ObjectEntityId; - VoxelCoord memory mass1Coord = VoxelCoord({ x: agentCoord.x + 3, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 mass1EntityId = world.build(agentObjectEntityId, GrassObjectID, mass1Coord); - mass1ObjectEntityId = ObjectEntity.get(store, mass1EntityId); - Mass.set(simStore, worldAddress, mass1ObjectEntityId, 10); - Energy.set(simStore, worldAddress, mass1ObjectEntityId, 10); - Velocity.setVelocity(simStore, worldAddress, mass1ObjectEntityId, abi.encode(VoxelCoord({ x: -4, y: 0, z: 0 }))); - } - - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x + 2, agentCoord.y, agentCoord.z), - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z) - ); - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z), - agentCoord - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - bytes32 mass2ObjectEntityId; - VoxelCoord memory mass2Coord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 mass2EntityId = world.build(agentObjectEntityId, RunnerObjectID, mass2Coord); - mass2ObjectEntityId = ObjectEntity.get(store, mass2EntityId); - Mass.set(simStore, worldAddress, mass2ObjectEntityId, 5); - Energy.set(simStore, worldAddress, mass2ObjectEntityId, 10); - Health.setHealth(simStore, worldAddress, mass2ObjectEntityId, 100); - Stamina.setStamina(simStore, worldAddress, mass2ObjectEntityId, 100); - - // Make the owner of the agent different from the one moving it - vm.startPrank(bob, bob); - world.claimAgent(mass2EntityId); - assertTrue(OwnedBy.get(store, mass2ObjectEntityId) == bob, "Owner not bob"); - vm.stopPrank(); - vm.startPrank(alice, alice); - } - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - RunnerObjectID, - mass2Coord, - VoxelCoord(mass2Coord.x + 1, mass2Coord.y, mass2Coord.z) - ); - assertTrue(OwnedBy.get(store, mass2ObjectEntityId) == bob, "Owner not bob"); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - assertTrue(Stamina.getStamina(simStore, worldAddress, mass2ObjectEntityId) == 100, "Stamina reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 0 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 0,0,0"); - - bytes32 mass1EntityId = getEntityAtCoord(store, VoxelCoord(mass1Coord.x, mass1Coord.y, mass1Coord.z)); - mass1ObjectEntityId = ObjectEntity.get(store, mass1EntityId); - assertTrue(ObjectType.get(store, mass1EntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory mass1Velocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, mass1ObjectEntityId), - (VoxelCoord) - ); - assertTrue(mass1Velocity.x == -4 && mass1Velocity.y == 0 && mass1Velocity.z == 0, "Mass velocity not -4,0,0"); - - bytes32 mass2EntityId = getEntityAtCoord(store, VoxelCoord(mass2Coord.x, mass2Coord.y, mass2Coord.z)); - mass2ObjectEntityId = ObjectEntity.get(store, mass2EntityId); - assertTrue(ObjectType.get(store, mass2EntityId) == RunnerObjectID, "Mass not found"); - VoxelCoord memory mass2Velocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, mass2ObjectEntityId), - (VoxelCoord) - ); - assertTrue(mass2Velocity.x == 0 && mass2Velocity.y == 0 && mass2Velocity.z == 0, "Mass velocity not 0,0,0"); - - vm.stopPrank(); - } - - function testMoveAgentCollisionPushedMultiple() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - world.move( - agentObjectEntityId, - RunnerObjectID, - agentCoord, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z) - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - bytes32 mass1ObjectEntityId; - VoxelCoord memory mass1Coord = VoxelCoord({ x: agentCoord.x + 2, y: agentCoord.y, z: agentCoord.z - 1 }); - { - bytes32 mass1EntityId = world.build(agentObjectEntityId, GrassObjectID, mass1Coord); - mass1ObjectEntityId = ObjectEntity.get(store, mass1EntityId); - Mass.set(simStore, worldAddress, mass1ObjectEntityId, 5); - Energy.set(simStore, worldAddress, mass1ObjectEntityId, 10); - Velocity.setVelocity(simStore, worldAddress, mass1ObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 10 }))); - } - - world.move( - agentObjectEntityId, - RunnerObjectID, - VoxelCoord(agentCoord.x + 1, agentCoord.y, agentCoord.z), - agentCoord - ); - Velocity.setVelocity(simStore, worldAddress, agentObjectEntityId, abi.encode(VoxelCoord({ x: 0, y: 0, z: 0 }))); - - bytes32 mass2ObjectEntityId; - VoxelCoord memory mass2Coord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 mass2EntityId = world.build(agentObjectEntityId, RunnerObjectID, mass2Coord); - mass2ObjectEntityId = ObjectEntity.get(store, mass2EntityId); - Mass.set(simStore, worldAddress, mass2ObjectEntityId, 5); - Energy.set(simStore, worldAddress, mass2ObjectEntityId, 10); - Health.setHealth(simStore, worldAddress, mass2ObjectEntityId, 100); - Stamina.setStamina(simStore, worldAddress, mass2ObjectEntityId, 100); - - // Make the owner of the agent different from the one moving it - vm.startPrank(bob, bob); - world.claimAgent(mass2EntityId); - assertTrue(OwnedBy.get(store, mass2ObjectEntityId) == bob, "Owner not bob"); - vm.stopPrank(); - vm.startPrank(alice, alice); - } - - // Now move forward one - // This will cause the collision - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move( - agentObjectEntityId, - RunnerObjectID, - mass2Coord, - VoxelCoord(mass2Coord.x + 1, mass2Coord.y, mass2Coord.z) - ); - assertTrue(OwnedBy.get(store, mass2ObjectEntityId) == bob, "Owner not bob"); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - assertTrue(Stamina.getStamina(simStore, worldAddress, mass2ObjectEntityId) == 100, "Stamina reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 0 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 0,0,0"); - - bytes32 mass1EntityId = getEntityAtCoord(store, VoxelCoord(mass1Coord.x, mass1Coord.y, mass1Coord.z - 2)); - mass1ObjectEntityId = ObjectEntity.get(store, mass1EntityId); - assertTrue(ObjectType.get(store, mass1EntityId) == GrassObjectID, "Mass not found"); - VoxelCoord memory mass1Velocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, mass1ObjectEntityId), - (VoxelCoord) - ); - assertTrue(mass1Velocity.x == 0 && mass1Velocity.y == 0 && mass1Velocity.z == 8, "Mass velocity not 0,0,8"); - - bytes32 mass2EntityId = getEntityAtCoord(store, VoxelCoord(mass2Coord.x + 1, mass2Coord.y, mass2Coord.z + 2)); - mass2ObjectEntityId = ObjectEntity.get(store, mass2EntityId); - assertTrue(ObjectType.get(store, mass2EntityId) == RunnerObjectID, "Mass not found"); - VoxelCoord memory mass2Velocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, mass2ObjectEntityId), - (VoxelCoord) - ); - assertTrue(mass2Velocity.x == 1 && mass2Velocity.y == 0 && mass2Velocity.z == 2, "Mass velocity not 1,0,2"); - - vm.stopPrank(); - } - - function testMoveAgentThatStops() public { - vm.startPrank(alice, alice); - (, bytes32 agentObjectEntityId) = setupAgent(); - Mass.set(simStore, worldAddress, agentObjectEntityId, 5); - - bytes32 massObjectEntityId; - VoxelCoord memory massCoord = VoxelCoord({ x: agentCoord.x + 1, y: agentCoord.y, z: agentCoord.z }); - { - bytes32 massEntityId = world.build(agentObjectEntityId, BuilderObjectID, massCoord); - massObjectEntityId = ObjectEntity.get(store, massEntityId); - Mass.set(simStore, worldAddress, massObjectEntityId, 5); - Energy.set(simStore, worldAddress, massObjectEntityId, 10); - Health.setHealth(simStore, worldAddress, massObjectEntityId, 100); - Stamina.setStamina(simStore, worldAddress, massObjectEntityId, 100); - - // Make the owner of the agent different from the one moving it - vm.startPrank(bob, bob); - world.claimAgent(massEntityId); - assertTrue(OwnedBy.get(store, massObjectEntityId) == bob, "Owner not bob"); - vm.stopPrank(); - vm.startPrank(alice, alice); - } - - VoxelCoord memory newMassCoord = VoxelCoord(massCoord.x + 1, massCoord.y, massCoord.z); - - uint256 staminaBefore = Stamina.getStamina(simStore, worldAddress, agentObjectEntityId); - world.move(agentObjectEntityId, BuilderObjectID, massCoord, newMassCoord); - assertTrue(OwnedBy.get(store, massObjectEntityId) == bob, "Owner not bob"); - assertTrue(Stamina.getStamina(simStore, worldAddress, agentObjectEntityId) < staminaBefore, "Stamina not reduced"); - assertTrue(Stamina.getStamina(simStore, worldAddress, massObjectEntityId) < 100, "Stamina not reduced"); - VoxelCoord memory agentVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, agentObjectEntityId), - (VoxelCoord) - ); - assertTrue(agentVelocity.x == 0 && agentVelocity.y == 0 && agentVelocity.z == 0, "Agent velocity not 0,0,0"); - - // Old coord should be air - assertTrue(ObjectType.get(store, getEntityAtCoord(store, massCoord)) == AirObjectID, "Old coord not air"); - // New coord should be moving object - assertTrue(ObjectType.get(store, getEntityAtCoord(store, newMassCoord)) == BuilderObjectID, "New coord is air"); - VoxelCoord memory massVelocity = abi.decode( - Velocity.getVelocity(simStore, worldAddress, massObjectEntityId), - (VoxelCoord) - ); - assertTrue(massVelocity.x == 0 && massVelocity.y == 0 && massVelocity.z == 0, "Mass velocity not 0,0,0"); - - vm.stopPrank(); - } -} diff --git a/examples/everlon/packages/world/src/test/Craft.t.sol b/examples/everlon/packages/world/src/test/Craft.t.sol new file mode 100644 index 000000000..e0f27deac --- /dev/null +++ b/examples/everlon/packages/world/src/test/Craft.t.sol @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import "forge-std/Test.sol"; +import { MudTest } from "@latticexyz/store/src/MudTest.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { getKeysInTable } from "@latticexyz/world/src/modules/keysintable/getKeysInTable.sol"; +import { getKeysWithValue } from "@latticexyz/world/src/modules/keyswithvalue/getKeysWithValue.sol"; +import { ObjectType, OwnedBy, ObjectEntity, Recipes, RecipesData, RecipesTableId, Equipped } from "@tenet-world/src/codegen/Tables.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; +import { VoxelCoord } from "@tenet-utils/src/Types.sol"; +import { getEntityAtCoord, getEntityPositionStrict, positionDataToVoxelCoord } from "@tenet-base-world/src/Utils.sol"; +import { BuilderObjectID, RunnerObjectID, GrassObjectID, OakLogObjectID, OakLumberObjectID, AirObjectID } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, SIMULATOR_ADDRESS } from "@tenet-world/src/Constants.sol"; +import { console } from "forge-std/console.sol"; +import { Mass } from "@tenet-simulator/src/codegen/tables/Mass.sol"; +import { Energy } from "@tenet-simulator/src/codegen/tables/Energy.sol"; +import { Health } from "@tenet-simulator/src/codegen/tables/Health.sol"; +import { Stamina } from "@tenet-simulator/src/codegen/tables/Stamina.sol"; +import { Velocity } from "@tenet-simulator/src/codegen/tables/Velocity.sol"; + +contract CraftTest is MudTest { + IWorld private world; + IStore private store; + IStore private simStore; + address payable internal alice; + VoxelCoord faucetAgentCoord = VoxelCoord(197, 27, 203); + VoxelCoord initialAgentCoord; + bytes32 agentObjectTypeId = RunnerObjectID; + + function setUp() public override { + super.setUp(); + world = IWorld(worldAddress); + store = IStore(worldAddress); + simStore = IStore(SIMULATOR_ADDRESS); + alice = payable(address(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)); + } + + function setupAgent() internal returns (bytes32, bytes32) { + bytes32 faucetEntityId = getEntityAtCoord(store, faucetAgentCoord); + assertTrue(uint256(faucetEntityId) != 0, "Agent not found at coord"); + bytes32 faucetObjectEntityId = ObjectEntity.get(store, faucetEntityId); + + initialAgentCoord = VoxelCoord(faucetAgentCoord.x, faucetAgentCoord.y, faucetAgentCoord.z + 1); + bytes32 agentEntityId = world.claimAgentFromFaucet(faucetObjectEntityId, agentObjectTypeId, initialAgentCoord); + assertTrue(uint256(agentEntityId) != 0, "Agent not found at coord"); + bytes32 agentObjectEntityId = ObjectEntity.get(store, agentEntityId); + + return (agentEntityId, agentObjectEntityId); + } + + function testSingleInputMultipleOutputCraft() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + VoxelCoord memory mineCoord = VoxelCoord(198, 27, 208); // hard coded to oak log + bytes32 objectTypeId = world.getTerrainObjectTypeId(mineCoord); + assertTrue(objectTypeId == OakLogObjectID, "Terrain object is not oak log"); + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + // get the inventory of the agent + bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + bytes32 agentInventoryId = agentObjects[0][0]; + bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + bytes32[][] memory allRecipes = getKeysInTable(store, RecipesTableId); + // First recipe is for oak + assertTrue( + Recipes.get(allRecipes[0][0]).inputObjectTypeIds[0] == OakLogObjectID, + "First recipe is not for oak log" + ); + bytes32[] memory ingredientIds = new bytes32[](1); + ingredientIds[0] = agentInventoryId; + world.craft(agentObjectEntityId, allRecipes[0][0], ingredientIds); + + // Assert that the inventory has the crafted item + agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + agentInventoryId = agentObjects[0][0]; + agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == OakLumberObjectID, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 4, + "Agent does not have correct number of mined objects in inventory" + ); + + // Try crafting again + vm.expectRevert(); + world.craft(agentObjectEntityId, allRecipes[0][0], ingredientIds); + + vm.stopPrank(); + } + + function testInvalidRecipe() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + bytes32[] memory ingredientIds = new bytes32[](1); + + vm.expectRevert(); + world.craft(agentObjectEntityId, bytes32(uint256(300000)), ingredientIds); + + vm.stopPrank(); + } + + function testEquip() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + VoxelCoord memory mineCoord = VoxelCoord(198, 27, 208); // hard coded to oak log + bytes32 objectTypeId = world.getTerrainObjectTypeId(mineCoord); + assertTrue(objectTypeId == OakLogObjectID, "Terrain object is not oak log"); + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + // get the inventory of the agent + bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + bytes32 agentInventoryId = agentObjects[0][0]; + bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + world.equip(agentObjectEntityId, agentInventoryId); + assertTrue( + Equipped.get(store, agentObjectEntityId) == agentInventoryId, + "Agent is not equipped with the inventory" + ); + + world.unequip(agentObjectEntityId); + assertTrue( + Equipped.get(store, agentObjectEntityId) == bytes32(uint256(0)), + "Agent is still equipped with the inventory" + ); + + world.equip(agentObjectEntityId, agentInventoryId); + assertTrue( + Equipped.get(store, agentObjectEntityId) == agentInventoryId, + "Agent is not equipped with the inventory" + ); + + world.build( + agentObjectEntityId, + objectTypeId, + VoxelCoord(initialAgentCoord.x, initialAgentCoord.y, initialAgentCoord.z + 1), + agentInventoryId + ); + assertTrue( + Equipped.get(store, agentObjectEntityId) == bytes32(uint256(0)), + "Agent is still equipped with the inventory" + ); + + vm.expectRevert(); + world.equip(agentObjectEntityId, agentInventoryId); + + vm.stopPrank(); + } +} diff --git a/examples/everlon/packages/world/src/test/Gravity.t.sol b/examples/everlon/packages/world/src/test/Gravity.t.sol index 02bb29bbd..c651ee2bb 100644 --- a/examples/everlon/packages/world/src/test/Gravity.t.sol +++ b/examples/everlon/packages/world/src/test/Gravity.t.sol @@ -121,6 +121,10 @@ contract GravityTest is MudTest { bytes32 agentInventoryId = agentObjects[0][0]; bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); } // move agent away from faucet @@ -163,6 +167,10 @@ contract GravityTest is MudTest { bytes32 agentInventoryId = agentObjects[0][0]; bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); // try building in the spot where the agent died, where there is a dropped item // should fail because there is a dropped item diff --git a/examples/everlon/packages/world/src/test/Hit.t.sol b/examples/everlon/packages/world/src/test/Hit.t.sol index cf3511f2c..0abcae94a 100644 --- a/examples/everlon/packages/world/src/test/Hit.t.sol +++ b/examples/everlon/packages/world/src/test/Hit.t.sol @@ -107,6 +107,10 @@ contract HitTest is MudTest { bytes32 agentInventoryId = agentObjects[0][0]; bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); } vm.stopPrank(); @@ -162,6 +166,10 @@ contract HitTest is MudTest { bytes32 agentInventoryId = agentObjects[0][0]; bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); } vm.stopPrank(); diff --git a/examples/everlon/packages/world/src/test/Inventory.t.sol b/examples/everlon/packages/world/src/test/Inventory.t.sol new file mode 100644 index 000000000..279619470 --- /dev/null +++ b/examples/everlon/packages/world/src/test/Inventory.t.sol @@ -0,0 +1,556 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import "forge-std/Test.sol"; +import { MudTest } from "@latticexyz/store/src/MudTest.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { IWorld } from "@tenet-world/src/codegen/world/IWorld.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; +import { getKeysWithValue } from "@latticexyz/world/src/modules/keyswithvalue/getKeysWithValue.sol"; +import { ObjectTypeRegistry, ObjectTypeRegistryTableId } from "@tenet-registry/src/codegen/tables/ObjectTypeRegistry.sol"; +import { ObjectType, OwnedBy, ObjectEntity } from "@tenet-world/src/codegen/Tables.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; +import { getEntityAtCoord, getEntityPositionStrict, positionDataToVoxelCoord } from "@tenet-base-world/src/Utils.sol"; +import { BuilderObjectID, RunnerObjectID, GrassObjectID, AirObjectID, WoodenPickObjectID, ChestObjectID, MAX_CHEST_SLOTS } from "@tenet-world/src/Constants.sol"; +import { REGISTRY_ADDRESS, SIMULATOR_ADDRESS } from "@tenet-world/src/Constants.sol"; +import { console } from "forge-std/console.sol"; +import { Mass } from "@tenet-simulator/src/codegen/tables/Mass.sol"; +import { Energy } from "@tenet-simulator/src/codegen/tables/Energy.sol"; +import { Health } from "@tenet-simulator/src/codegen/tables/Health.sol"; +import { Stamina } from "@tenet-simulator/src/codegen/tables/Stamina.sol"; +import { Velocity } from "@tenet-simulator/src/codegen/tables/Velocity.sol"; +import { NUM_MAX_INVENTORY_SLOTS } from "@tenet-base-world/src/Constants.sol"; + +contract InventoryTest is MudTest { + IWorld private world; + IStore private store; + IStore private registryStore; + IStore private simStore; + address payable internal alice; + address payable internal bob; + VoxelCoord faucetAgentCoord = VoxelCoord(197, 27, 203); + VoxelCoord initialAgentCoord; + bytes32 agentObjectTypeId = RunnerObjectID; + + function setUp() public override { + super.setUp(); + world = IWorld(worldAddress); + store = IStore(worldAddress); + registryStore = IStore(REGISTRY_ADDRESS); + simStore = IStore(SIMULATOR_ADDRESS); + alice = payable(address(0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)); + bob = payable(address(0x70997970C51812dc3A010C7d01b50e0d17dc79C8)); + } + + function setupAgent() internal returns (bytes32, bytes32) { + bytes32 faucetEntityId = getEntityAtCoord(store, faucetAgentCoord); + assertTrue(uint256(faucetEntityId) != 0, "Agent not found at coord"); + bytes32 faucetObjectEntityId = ObjectEntity.get(store, faucetEntityId); + + initialAgentCoord = VoxelCoord(faucetAgentCoord.x, faucetAgentCoord.y, faucetAgentCoord.z - 1); + bytes32 agentEntityId = world.claimAgentFromFaucet(faucetObjectEntityId, agentObjectTypeId, initialAgentCoord); + assertTrue(uint256(agentEntityId) != 0, "Agent not found at coord"); + bytes32 agentObjectEntityId = ObjectEntity.get(store, agentEntityId); + + return (agentEntityId, agentObjectEntityId); + } + + function testMultipleStack() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + VoxelCoord memory mineCoord1 = VoxelCoord(initialAgentCoord.x, initialAgentCoord.y - 1, initialAgentCoord.z - 1); + VoxelCoord memory mineCoord2 = VoxelCoord( + initialAgentCoord.x - 1, + initialAgentCoord.y - 1, + initialAgentCoord.z - 1 + ); + bytes32 objectTypeId1 = world.getTerrainObjectTypeId(mineCoord1); + + ObjectTypeRegistry.setStackable(registryStore, objectTypeId1, 1); + + world.mine(agentObjectEntityId, objectTypeId1, mineCoord1); + + bytes32 objectTypeId2 = world.getTerrainObjectTypeId(mineCoord2); + world.mine(agentObjectEntityId, objectTypeId2, mineCoord2); + assertTrue(objectTypeId1 == objectTypeId2, "Mined objects are not the same"); + + // get the inventory of the agent + bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 2, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + bytes32 agentInventoryId1 = agentObjects[0][0]; + bytes32 agentInventoryObjectTypeId1 = InventoryObject.getObjectTypeId(store, agentInventoryId1); + assertTrue(agentInventoryObjectTypeId1 == objectTypeId1, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId1) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + assertTrue(agentObjects[1].length == 1, "Agent does not have inventory"); + bytes32 agentInventoryId2 = agentObjects[1][0]; + bytes32 agentInventoryObjectTypeId2 = InventoryObject.getObjectTypeId(store, agentInventoryId2); + assertTrue(agentInventoryObjectTypeId2 == objectTypeId2, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId2) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + vm.stopPrank(); + } + + function testFullInventory() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + VoxelCoord memory mineCoord = VoxelCoord(initialAgentCoord.x, initialAgentCoord.y - 1, initialAgentCoord.z - 1); + bytes32 objectTypeId = world.getTerrainObjectTypeId(mineCoord); + ObjectTypeRegistry.setStackable(registryStore, objectTypeId, 1); + + bytes32 inventoryId; + for (uint i = 0; i < NUM_MAX_INVENTORY_SLOTS; i++) { + inventoryId = getUniqueEntity(); + Inventory.set(inventoryId, agentObjectEntityId); + ObjectProperties memory objectProperties; + InventoryObject.set(inventoryId, objectTypeId, 1, 1, abi.encode(objectProperties)); + } + + vm.expectRevert(); + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + + world.build( + agentObjectEntityId, + objectTypeId, + VoxelCoord(initialAgentCoord.x, initialAgentCoord.y + 1, initialAgentCoord.z + 1), + inventoryId + ); + + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + + vm.stopPrank(); + } + + function testDurability() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + bytes32 inventoryId = getUniqueEntity(); + Inventory.set(inventoryId, agentObjectEntityId); + ObjectProperties memory objectProperties; + InventoryObject.set(inventoryId, WoodenPickObjectID, 1, 2, abi.encode(objectProperties)); + + VoxelCoord memory mineCoord = VoxelCoord(initialAgentCoord.x, initialAgentCoord.y - 1, initialAgentCoord.z - 1); + bytes32 objectTypeId = world.getTerrainObjectTypeId(mineCoord); + + world.equip(agentObjectEntityId, inventoryId); + + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + + // Check if the durability is reduced + assertTrue(InventoryObject.getNumUsesLeft(store, inventoryId) == 1, "Durability is not reduced"); + + mineCoord = VoxelCoord(initialAgentCoord.x + 1, initialAgentCoord.y - 1, initialAgentCoord.z - 1); + objectTypeId = world.getTerrainObjectTypeId(mineCoord); + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + + // Check if item is destroyed + bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + for (uint i = 0; i < agentObjects.length; i++) { + bytes32 inventoryId = agentObjects[i][0]; + bytes32 inventoryObjectTypeId = InventoryObject.getObjectTypeId(store, inventoryId); + assertTrue(inventoryObjectTypeId != WoodenPickObjectID, "Item is not destroyed"); + } + + vm.stopPrank(); + } + + function testDropItemIntoAirAndPickUp() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + VoxelCoord memory mineCoord = VoxelCoord(initialAgentCoord.x, initialAgentCoord.y - 1, initialAgentCoord.z - 1); + bytes32 objectTypeId = world.getTerrainObjectTypeId(mineCoord); + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + // get the inventory of the agent + bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + bytes32 agentInventoryId = agentObjects[0][0]; + bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + VoxelCoord memory dropCoord = VoxelCoord(initialAgentCoord.x + 1, initialAgentCoord.y, initialAgentCoord.z + 1); + assertTrue(world.getTerrainObjectTypeId(dropCoord) == AirObjectID, "Drop coord is not air"); + world.transfer(agentObjectEntityId, dropCoord, agentInventoryId, 1); + bytes32 dropEntityId = getEntityAtCoord(store, dropCoord); + assertTrue(uint256(dropEntityId) != 0, "Drop entity not found at coord"); + bytes32 dropObjectEntityId = ObjectEntity.get(store, dropEntityId); + assertTrue(dropObjectEntityId != bytes32(0), "Drop entity not found at coord"); + + // get the inventory of the agent + agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 0, "Agent has inventory"); + + bytes32[][] memory airObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(dropObjectEntityId)); + assertTrue(airObjects.length == 1, "Air does not have inventory"); + assertTrue(airObjects[0].length == 1, "Air does not have inventory"); + bytes32 airInventoryId = airObjects[0][0]; + bytes32 airInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, airInventoryId); + assertTrue(airInventoryObjectTypeId == objectTypeId, "Air does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, airInventoryId) == 1, + "Air does not have correct number of mined objects in inventory" + ); + + // Move into the air and pick up the item + world.move(agentObjectEntityId, agentObjectTypeId, initialAgentCoord, dropCoord); + agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + agentInventoryId = agentObjects[0][0]; + agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + airObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(dropObjectEntityId)); + assertTrue(airObjects.length == 0, "Air has inventory"); + + vm.stopPrank(); + } + + function testTransferTooFar() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + VoxelCoord memory mineCoord = VoxelCoord(initialAgentCoord.x, initialAgentCoord.y - 1, initialAgentCoord.z - 1); + bytes32 objectTypeId = world.getTerrainObjectTypeId(mineCoord); + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + // get the inventory of the agent + bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + bytes32 agentInventoryId = agentObjects[0][0]; + bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + VoxelCoord memory dropCoord = VoxelCoord(initialAgentCoord.x + 1, initialAgentCoord.y, initialAgentCoord.z + 3); + assertTrue(world.getTerrainObjectTypeId(dropCoord) == AirObjectID, "Drop coord is not air"); + + vm.expectRevert(); + world.transfer(agentObjectEntityId, dropCoord, agentInventoryId, 1); + + vm.stopPrank(); + } + + function testPickupFullInventory() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + VoxelCoord memory mineCoord = VoxelCoord(initialAgentCoord.x, initialAgentCoord.y - 1, initialAgentCoord.z - 1); + bytes32 objectTypeId = world.getTerrainObjectTypeId(mineCoord); + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + // get the inventory of the agent + bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + bytes32 agentInventoryId = agentObjects[0][0]; + bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + VoxelCoord memory dropCoord = VoxelCoord(initialAgentCoord.x + 1, initialAgentCoord.y, initialAgentCoord.z + 1); + assertTrue(world.getTerrainObjectTypeId(dropCoord) == AirObjectID, "Drop coord is not air"); + world.transfer(agentObjectEntityId, dropCoord, agentInventoryId, 1); + bytes32 dropEntityId = getEntityAtCoord(store, dropCoord); + assertTrue(uint256(dropEntityId) != 0, "Drop entity not found at coord"); + bytes32 dropObjectEntityId = ObjectEntity.get(store, dropEntityId); + assertTrue(dropObjectEntityId != bytes32(0), "Drop entity not found at coord"); + + // get the inventory of the agent + agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 0, "Agent has inventory"); + + bytes32[][] memory airObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(dropObjectEntityId)); + assertTrue(airObjects.length == 1, "Air does not have inventory"); + assertTrue(airObjects[0].length == 1, "Air does not have inventory"); + bytes32 airInventoryId = airObjects[0][0]; + bytes32 airInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, airInventoryId); + assertTrue(airInventoryObjectTypeId == objectTypeId, "Air does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, airInventoryId) == 1, + "Air does not have correct number of mined objects in inventory" + ); + + // fill up inventory + bytes32 inventoryId; + for (uint i = 0; i < NUM_MAX_INVENTORY_SLOTS; i++) { + inventoryId = getUniqueEntity(); + Inventory.set(inventoryId, agentObjectEntityId); + ObjectProperties memory objectProperties; + InventoryObject.set(inventoryId, GrassObjectID, 1, 1, abi.encode(objectProperties)); + } + + // Move into the air and pick up the item + vm.expectRevert(); + world.move(agentObjectEntityId, agentObjectTypeId, initialAgentCoord, dropCoord); + + vm.stopPrank(); + } + + function testTransferToChest() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + bytes32 inventoryId = getUniqueEntity(); + Inventory.set(inventoryId, agentObjectEntityId); + ObjectProperties memory objectProperties; + InventoryObject.set(inventoryId, ChestObjectID, 1, 0, abi.encode(objectProperties)); + + VoxelCoord memory chestCoord = VoxelCoord(initialAgentCoord.x, initialAgentCoord.y, initialAgentCoord.z - 1); + world.build(agentObjectEntityId, ChestObjectID, chestCoord, inventoryId); + bytes32 chestEntityId = getEntityAtCoord(store, chestCoord); + assertTrue(uint256(chestEntityId) != 0, "Chest not found at coord"); + bytes32 chestObjectEntityId = ObjectEntity.get(store, chestEntityId); + assertTrue(chestObjectEntityId != bytes32(0), "Chest not found at coord"); + + // Mine a block + VoxelCoord memory mineCoord = VoxelCoord(initialAgentCoord.x + 1, initialAgentCoord.y - 1, initialAgentCoord.z - 1); + bytes32 objectTypeId = world.getTerrainObjectTypeId(mineCoord); + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + // get the inventory of the agent + bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + bytes32 agentInventoryId = agentObjects[0][0]; + bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + bytes32[][] memory chestObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(chestObjectEntityId)); + assertTrue(chestObjects.length == 0, "Agent does not have inventory"); + + // Transfer to chest + world.transfer(agentObjectEntityId, chestCoord, agentInventoryId, 1); + + agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 0, "Agent has inventory"); + + chestObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(chestObjectEntityId)); + assertTrue(chestObjects.length == 1, "Agent does not have inventory"); + assertTrue(chestObjects[0].length == 1, "Agent does not have inventory"); + { + bytes32 chestInventoryId = chestObjects[0][0]; + bytes32 chestInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, chestInventoryId); + assertTrue(chestInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, chestInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + } + + // Mine the chest + world.mine(agentObjectEntityId, ChestObjectID, chestCoord); + // Air should be at the chest coord + chestObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(chestObjectEntityId)); + assertTrue(chestObjects.length == 1, "Agent does not have inventory"); + + // Move into the chest and pick up the item + world.move(agentObjectEntityId, agentObjectTypeId, initialAgentCoord, chestCoord); + agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 2, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + agentInventoryId = agentObjects[0][0]; + agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == ChestObjectID, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + assertTrue(agentObjects[1].length == 1, "Agent does not have inventory"); + agentInventoryId = agentObjects[1][0]; + agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + chestObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(chestObjectEntityId)); + assertTrue(chestObjects.length == 0, "Agent does not have inventory"); + + vm.stopPrank(); + } + + function testTransferToFullChest() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + bytes32 inventoryId = getUniqueEntity(); + Inventory.set(inventoryId, agentObjectEntityId); + ObjectProperties memory objectProperties; + InventoryObject.set(inventoryId, ChestObjectID, 1, 0, abi.encode(objectProperties)); + + VoxelCoord memory chestCoord = VoxelCoord(initialAgentCoord.x, initialAgentCoord.y, initialAgentCoord.z - 1); + world.build(agentObjectEntityId, ChestObjectID, chestCoord, inventoryId); + bytes32 chestEntityId = getEntityAtCoord(store, chestCoord); + assertTrue(uint256(chestEntityId) != 0, "Chest not found at coord"); + bytes32 chestObjectEntityId = ObjectEntity.get(store, chestEntityId); + assertTrue(chestObjectEntityId != bytes32(0), "Chest not found at coord"); + + // Mine a block + VoxelCoord memory mineCoord = VoxelCoord(initialAgentCoord.x + 1, initialAgentCoord.y - 1, initialAgentCoord.z - 1); + bytes32 objectTypeId = world.getTerrainObjectTypeId(mineCoord); + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + // get the inventory of the agent + bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + bytes32 agentInventoryId = agentObjects[0][0]; + bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + bytes32[][] memory chestObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(chestObjectEntityId)); + assertTrue(chestObjects.length == 0, "Agent does not have inventory"); + + // fill up inventory + for (uint i = 0; i < MAX_CHEST_SLOTS; i++) { + inventoryId = getUniqueEntity(); + Inventory.set(inventoryId, chestObjectEntityId); + ObjectProperties memory objectProperties; + InventoryObject.set(inventoryId, GrassObjectID, 1, 1, abi.encode(objectProperties)); + } + + // Transfer to chest + vm.expectRevert(); + world.transfer(agentObjectEntityId, chestCoord, agentInventoryId, 1); + + vm.stopPrank(); + } + + function testTransferFromChest() public { + vm.startPrank(alice, alice); + + (, bytes32 agentObjectEntityId) = setupAgent(); + + bytes32 inventoryId = getUniqueEntity(); + Inventory.set(inventoryId, agentObjectEntityId); + ObjectProperties memory objectProperties; + InventoryObject.set(inventoryId, ChestObjectID, 1, 0, abi.encode(objectProperties)); + + VoxelCoord memory chestCoord = VoxelCoord(initialAgentCoord.x, initialAgentCoord.y, initialAgentCoord.z - 1); + world.build(agentObjectEntityId, ChestObjectID, chestCoord, inventoryId); + bytes32 chestEntityId = getEntityAtCoord(store, chestCoord); + assertTrue(uint256(chestEntityId) != 0, "Chest not found at coord"); + bytes32 chestObjectEntityId = ObjectEntity.get(store, chestEntityId); + assertTrue(chestObjectEntityId != bytes32(0), "Chest not found at coord"); + + // Mine a block + VoxelCoord memory mineCoord = VoxelCoord(initialAgentCoord.x + 1, initialAgentCoord.y - 1, initialAgentCoord.z - 1); + bytes32 objectTypeId = world.getTerrainObjectTypeId(mineCoord); + world.mine(agentObjectEntityId, objectTypeId, mineCoord); + // get the inventory of the agent + bytes32[][] memory agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 1, "Agent does not have inventory"); + assertTrue(agentObjects[0].length == 1, "Agent does not have inventory"); + bytes32 agentInventoryId = agentObjects[0][0]; + { + bytes32 agentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, agentInventoryId); + assertTrue(agentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, agentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + } + + bytes32[][] memory chestObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(chestObjectEntityId)); + assertTrue(chestObjects.length == 0, "Agent does not have inventory"); + + // Transfer to chest + world.transfer(agentObjectEntityId, chestCoord, agentInventoryId, 1); + + agentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(agentObjectEntityId)); + assertTrue(agentObjects.length == 0, "Agent has inventory"); + + chestObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(chestObjectEntityId)); + assertTrue(chestObjects.length == 1, "Agent does not have inventory"); + assertTrue(chestObjects[0].length == 1, "Agent does not have inventory"); + bytes32 chestInventoryId = chestObjects[0][0]; + { + bytes32 chestInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, chestInventoryId); + assertTrue(chestInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, chestInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + } + + // move agent away + VoxelCoord memory newAgentCoord = VoxelCoord(initialAgentCoord.x + 1, initialAgentCoord.y, initialAgentCoord.z + 1); + world.move(agentObjectEntityId, agentObjectTypeId, initialAgentCoord, newAgentCoord); + + // Try taking from chest, should be too far + vm.expectRevert(); + world.transfer(chestObjectEntityId, newAgentCoord, chestInventoryId, 1); + + vm.stopPrank(); + + vm.startPrank(bob, bob); + (, bytes32 bobAgentObjectEntityId) = setupAgent(); + + bytes32[][] memory bobAgentObjects = getKeysWithValue( + store, + InventoryTableId, + Inventory.encode(bobAgentObjectEntityId) + ); + assertTrue(bobAgentObjects.length == 0, "Agent has inventory"); + + // Transfer from chest + world.transfer(chestObjectEntityId, initialAgentCoord, chestInventoryId, 1); + + bobAgentObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(bobAgentObjectEntityId)); + assertTrue(bobAgentObjects.length == 1, "Agent does not have inventory"); + assertTrue(bobAgentObjects[0].length == 1, "Agent does not have inventory"); + bytes32 bobAgentInventoryId = bobAgentObjects[0][0]; + bytes32 bobAgentInventoryObjectTypeId = InventoryObject.getObjectTypeId(store, bobAgentInventoryId); + assertTrue(bobAgentInventoryObjectTypeId == objectTypeId, "Agent does not have mined object in inventory"); + assertTrue( + InventoryObject.getNumObjects(store, bobAgentInventoryId) == 1, + "Agent does not have correct number of mined objects in inventory" + ); + + chestObjects = getKeysWithValue(store, InventoryTableId, Inventory.encode(chestObjectEntityId)); + assertTrue(chestObjects.length == 0, "Agent does not have inventory"); + + vm.stopPrank(); + } +} diff --git a/packages/base-world/src/Constants.sol b/packages/base-world/src/Constants.sol index c0517cd83..74b2d7b12 100644 --- a/packages/base-world/src/Constants.sol +++ b/packages/base-world/src/Constants.sol @@ -3,3 +3,9 @@ pragma solidity >=0.8.0; string constant WORLD_MOVE_SIG = "move(bytes32,bytes32,(int32,int32,int32),(int32,int32,int32))"; string constant WORLD_GET_OBJECT_PROPERTIES_SIG = "getObjectProperties(bytes32)"; + +uint256 constant NUM_MAX_INVENTORY_SLOTS = 35; + +address constant REGISTRY_ADDRESS = 0x5FbDB2315678afecb367f032d93F642f64180aa3; + +// TODO: Move SIMULATOR_ADDRESS to this file diff --git a/packages/base-world/src/Utils.sol b/packages/base-world/src/Utils.sol index 5a2289a34..626f8594d 100644 --- a/packages/base-world/src/Utils.sol +++ b/packages/base-world/src/Utils.sol @@ -10,7 +10,7 @@ import { ReversePosition, ReversePositionTableId } from "@tenet-base-world/src/c import { ObjectEntity, ObjectEntityTableId } from "@tenet-base-world/src/codegen/tables/ObjectEntity.sol"; import { ReverseObjectEntity, ReverseObjectEntityTableId } from "@tenet-base-world/src/codegen/tables/ReverseObjectEntity.sol"; -import { VoxelCoord } from "@tenet-utils/src/Types.sol"; +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; import { getVonNeumannNeighbours, getMooreNeighbours } from "@tenet-utils/src/VoxelCoordUtils.sol"; function positionDataToVoxelCoord(PositionData memory coord) pure returns (VoxelCoord memory) { diff --git a/packages/base-world/src/codegen/Tables.sol b/packages/base-world/src/codegen/Tables.sol index 3225d4bed..37f9447d2 100644 --- a/packages/base-world/src/codegen/Tables.sol +++ b/packages/base-world/src/codegen/Tables.sol @@ -11,5 +11,7 @@ import { ReverseObjectEntity, ReverseObjectEntityTableId } from "./tables/Revers import { OwnedBy, OwnedByTableId } from "./tables/OwnedBy.sol"; import { Inventory, InventoryTableId } from "./tables/Inventory.sol"; import { InventoryObject, InventoryObjectData, InventoryObjectTableId } from "./tables/InventoryObject.sol"; +import { Equipped, EquippedTableId } from "./tables/Equipped.sol"; +import { Recipes, RecipesData, RecipesTableId } from "./tables/Recipes.sol"; import { AgentMetadata, AgentMetadataData, AgentMetadataTableId } from "./tables/AgentMetadata.sol"; import { Mind, MindData, MindTableId } from "./tables/Mind.sol"; diff --git a/packages/base-world/src/codegen/tables/Equipped.sol b/packages/base-world/src/codegen/tables/Equipped.sol new file mode 100644 index 000000000..78f6ff390 --- /dev/null +++ b/packages/base-world/src/codegen/tables/Equipped.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/* Autogenerated file. Do not edit manually. */ + +// Import schema type +import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; + +// Import store internals +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; +import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; +import { Bytes } from "@latticexyz/store/src/Bytes.sol"; +import { Memory } from "@latticexyz/store/src/Memory.sol"; +import { SliceLib } from "@latticexyz/store/src/Slice.sol"; +import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; +import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; +import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; + +bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Equipped"))); +bytes32 constant EquippedTableId = _tableId; + +library Equipped { + /** Get the table's key schema */ + function getKeySchema() internal pure returns (Schema) { + SchemaType[] memory _schema = new SchemaType[](1); + _schema[0] = SchemaType.BYTES32; + + return SchemaLib.encode(_schema); + } + + /** Get the table's value schema */ + function getValueSchema() internal pure returns (Schema) { + SchemaType[] memory _schema = new SchemaType[](1); + _schema[0] = SchemaType.BYTES32; + + return SchemaLib.encode(_schema); + } + + /** Get the table's key names */ + function getKeyNames() internal pure returns (string[] memory keyNames) { + keyNames = new string[](1); + keyNames[0] = "objectEntityId"; + } + + /** Get the table's field names */ + function getFieldNames() internal pure returns (string[] memory fieldNames) { + fieldNames = new string[](1); + fieldNames[0] = "inventoryId"; + } + + /** Register the table's key schema, value schema, key names and value names */ + function register() internal { + StoreSwitch.registerTable(_tableId, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); + } + + /** Register the table's key schema, value schema, key names and value names (using the specified store) */ + function register(IStore _store) internal { + _store.registerTable(_tableId, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); + } + + /** Get inventoryId */ + function get(bytes32 objectEntityId) internal view returns (bytes32 inventoryId) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = objectEntityId; + + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 0, getValueSchema()); + return (Bytes.slice32(_blob, 0)); + } + + /** Get inventoryId (using the specified store) */ + function get(IStore _store, bytes32 objectEntityId) internal view returns (bytes32 inventoryId) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = objectEntityId; + + bytes memory _blob = _store.getField(_tableId, _keyTuple, 0, getValueSchema()); + return (Bytes.slice32(_blob, 0)); + } + + /** Set inventoryId */ + function set(bytes32 objectEntityId, bytes32 inventoryId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = objectEntityId; + + StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((inventoryId)), getValueSchema()); + } + + /** Set inventoryId (using the specified store) */ + function set(IStore _store, bytes32 objectEntityId, bytes32 inventoryId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = objectEntityId; + + _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((inventoryId)), getValueSchema()); + } + + /** Tightly pack full data using this table's schema */ + function encode(bytes32 inventoryId) internal pure returns (bytes memory) { + return abi.encodePacked(inventoryId); + } + + /** Encode keys as a bytes32 array using this table's schema */ + function encodeKeyTuple(bytes32 objectEntityId) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = objectEntityId; + + return _keyTuple; + } + + /* Delete all data for given keys */ + function deleteRecord(bytes32 objectEntityId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = objectEntityId; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, getValueSchema()); + } + + /* Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 objectEntityId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = objectEntityId; + + _store.deleteRecord(_tableId, _keyTuple, getValueSchema()); + } +} diff --git a/packages/base-world/src/codegen/tables/InventoryObject.sol b/packages/base-world/src/codegen/tables/InventoryObject.sol index f84c6e2d0..b2b047184 100644 --- a/packages/base-world/src/codegen/tables/InventoryObject.sol +++ b/packages/base-world/src/codegen/tables/InventoryObject.sol @@ -22,6 +22,8 @@ bytes32 constant InventoryObjectTableId = _tableId; struct InventoryObjectData { bytes32 objectTypeId; + uint8 numObjects; + uint16 numUsesLeft; bytes objectProperties; } @@ -36,9 +38,11 @@ library InventoryObject { /** Get the table's value schema */ function getValueSchema() internal pure returns (Schema) { - SchemaType[] memory _schema = new SchemaType[](2); + SchemaType[] memory _schema = new SchemaType[](4); _schema[0] = SchemaType.BYTES32; - _schema[1] = SchemaType.BYTES; + _schema[1] = SchemaType.UINT8; + _schema[2] = SchemaType.UINT16; + _schema[3] = SchemaType.BYTES; return SchemaLib.encode(_schema); } @@ -51,9 +55,11 @@ library InventoryObject { /** Get the table's field names */ function getFieldNames() internal pure returns (string[] memory fieldNames) { - fieldNames = new string[](2); + fieldNames = new string[](4); fieldNames[0] = "objectTypeId"; - fieldNames[1] = "objectProperties"; + fieldNames[1] = "numObjects"; + fieldNames[2] = "numUsesLeft"; + fieldNames[3] = "objectProperties"; } /** Register the table's key schema, value schema, key names and value names */ @@ -100,12 +106,80 @@ library InventoryObject { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((objectTypeId)), getValueSchema()); } + /** Get numObjects */ + function getNumObjects(bytes32 inventoryId) internal view returns (uint8 numObjects) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = inventoryId; + + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 1, getValueSchema()); + return (uint8(Bytes.slice1(_blob, 0))); + } + + /** Get numObjects (using the specified store) */ + function getNumObjects(IStore _store, bytes32 inventoryId) internal view returns (uint8 numObjects) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = inventoryId; + + bytes memory _blob = _store.getField(_tableId, _keyTuple, 1, getValueSchema()); + return (uint8(Bytes.slice1(_blob, 0))); + } + + /** Set numObjects */ + function setNumObjects(bytes32 inventoryId, uint8 numObjects) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = inventoryId; + + StoreSwitch.setField(_tableId, _keyTuple, 1, abi.encodePacked((numObjects)), getValueSchema()); + } + + /** Set numObjects (using the specified store) */ + function setNumObjects(IStore _store, bytes32 inventoryId, uint8 numObjects) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = inventoryId; + + _store.setField(_tableId, _keyTuple, 1, abi.encodePacked((numObjects)), getValueSchema()); + } + + /** Get numUsesLeft */ + function getNumUsesLeft(bytes32 inventoryId) internal view returns (uint16 numUsesLeft) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = inventoryId; + + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 2, getValueSchema()); + return (uint16(Bytes.slice2(_blob, 0))); + } + + /** Get numUsesLeft (using the specified store) */ + function getNumUsesLeft(IStore _store, bytes32 inventoryId) internal view returns (uint16 numUsesLeft) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = inventoryId; + + bytes memory _blob = _store.getField(_tableId, _keyTuple, 2, getValueSchema()); + return (uint16(Bytes.slice2(_blob, 0))); + } + + /** Set numUsesLeft */ + function setNumUsesLeft(bytes32 inventoryId, uint16 numUsesLeft) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = inventoryId; + + StoreSwitch.setField(_tableId, _keyTuple, 2, abi.encodePacked((numUsesLeft)), getValueSchema()); + } + + /** Set numUsesLeft (using the specified store) */ + function setNumUsesLeft(IStore _store, bytes32 inventoryId, uint16 numUsesLeft) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = inventoryId; + + _store.setField(_tableId, _keyTuple, 2, abi.encodePacked((numUsesLeft)), getValueSchema()); + } + /** Get objectProperties */ function getObjectProperties(bytes32 inventoryId) internal view returns (bytes memory objectProperties) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; - bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 1, getValueSchema()); + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 3, getValueSchema()); return (bytes(_blob)); } @@ -117,7 +191,7 @@ library InventoryObject { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; - bytes memory _blob = _store.getField(_tableId, _keyTuple, 1, getValueSchema()); + bytes memory _blob = _store.getField(_tableId, _keyTuple, 3, getValueSchema()); return (bytes(_blob)); } @@ -126,7 +200,7 @@ library InventoryObject { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; - StoreSwitch.setField(_tableId, _keyTuple, 1, bytes((objectProperties)), getValueSchema()); + StoreSwitch.setField(_tableId, _keyTuple, 3, bytes((objectProperties)), getValueSchema()); } /** Set objectProperties (using the specified store) */ @@ -134,7 +208,7 @@ library InventoryObject { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; - _store.setField(_tableId, _keyTuple, 1, bytes((objectProperties)), getValueSchema()); + _store.setField(_tableId, _keyTuple, 3, bytes((objectProperties)), getValueSchema()); } /** Get the length of objectProperties */ @@ -142,7 +216,7 @@ library InventoryObject { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; - uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 1, getValueSchema()); + uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 3, getValueSchema()); unchecked { return _byteLength / 1; } @@ -153,7 +227,7 @@ library InventoryObject { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; - uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 1, getValueSchema()); + uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 3, getValueSchema()); unchecked { return _byteLength / 1; } @@ -171,7 +245,7 @@ library InventoryObject { bytes memory _blob = StoreSwitch.getFieldSlice( _tableId, _keyTuple, - 1, + 3, getValueSchema(), _index * 1, (_index + 1) * 1 @@ -193,7 +267,7 @@ library InventoryObject { _keyTuple[0] = inventoryId; unchecked { - bytes memory _blob = _store.getFieldSlice(_tableId, _keyTuple, 1, getValueSchema(), _index * 1, (_index + 1) * 1); + bytes memory _blob = _store.getFieldSlice(_tableId, _keyTuple, 3, getValueSchema(), _index * 1, (_index + 1) * 1); return (bytes(_blob)); } } @@ -203,7 +277,7 @@ library InventoryObject { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; - StoreSwitch.pushToField(_tableId, _keyTuple, 1, bytes((_slice)), getValueSchema()); + StoreSwitch.pushToField(_tableId, _keyTuple, 3, bytes((_slice)), getValueSchema()); } /** Push a slice to objectProperties (using the specified store) */ @@ -211,7 +285,7 @@ library InventoryObject { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; - _store.pushToField(_tableId, _keyTuple, 1, bytes((_slice)), getValueSchema()); + _store.pushToField(_tableId, _keyTuple, 3, bytes((_slice)), getValueSchema()); } /** Pop a slice from objectProperties */ @@ -219,7 +293,7 @@ library InventoryObject { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; - StoreSwitch.popFromField(_tableId, _keyTuple, 1, 1, getValueSchema()); + StoreSwitch.popFromField(_tableId, _keyTuple, 3, 1, getValueSchema()); } /** Pop a slice from objectProperties (using the specified store) */ @@ -227,7 +301,7 @@ library InventoryObject { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; - _store.popFromField(_tableId, _keyTuple, 1, 1, getValueSchema()); + _store.popFromField(_tableId, _keyTuple, 3, 1, getValueSchema()); } /** @@ -239,7 +313,7 @@ library InventoryObject { _keyTuple[0] = inventoryId; unchecked { - StoreSwitch.updateInField(_tableId, _keyTuple, 1, _index * 1, bytes((_slice)), getValueSchema()); + StoreSwitch.updateInField(_tableId, _keyTuple, 3, _index * 1, bytes((_slice)), getValueSchema()); } } @@ -252,7 +326,7 @@ library InventoryObject { _keyTuple[0] = inventoryId; unchecked { - _store.updateInField(_tableId, _keyTuple, 1, _index * 1, bytes((_slice)), getValueSchema()); + _store.updateInField(_tableId, _keyTuple, 3, _index * 1, bytes((_slice)), getValueSchema()); } } @@ -275,8 +349,14 @@ library InventoryObject { } /** Set the full data using individual values */ - function set(bytes32 inventoryId, bytes32 objectTypeId, bytes memory objectProperties) internal { - bytes memory _data = encode(objectTypeId, objectProperties); + function set( + bytes32 inventoryId, + bytes32 objectTypeId, + uint8 numObjects, + uint16 numUsesLeft, + bytes memory objectProperties + ) internal { + bytes memory _data = encode(objectTypeId, numObjects, numUsesLeft, objectProperties); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; @@ -285,8 +365,15 @@ library InventoryObject { } /** Set the full data using individual values (using the specified store) */ - function set(IStore _store, bytes32 inventoryId, bytes32 objectTypeId, bytes memory objectProperties) internal { - bytes memory _data = encode(objectTypeId, objectProperties); + function set( + IStore _store, + bytes32 inventoryId, + bytes32 objectTypeId, + uint8 numObjects, + uint16 numUsesLeft, + bytes memory objectProperties + ) internal { + bytes memory _data = encode(objectTypeId, numObjects, numUsesLeft, objectProperties); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = inventoryId; @@ -296,12 +383,12 @@ library InventoryObject { /** Set the full data using the data struct */ function set(bytes32 inventoryId, InventoryObjectData memory _table) internal { - set(inventoryId, _table.objectTypeId, _table.objectProperties); + set(inventoryId, _table.objectTypeId, _table.numObjects, _table.numUsesLeft, _table.objectProperties); } /** Set the full data using the data struct (using the specified store) */ function set(IStore _store, bytes32 inventoryId, InventoryObjectData memory _table) internal { - set(_store, inventoryId, _table.objectTypeId, _table.objectProperties); + set(_store, inventoryId, _table.objectTypeId, _table.numObjects, _table.numUsesLeft, _table.objectProperties); } /** @@ -309,32 +396,41 @@ library InventoryObject { * Undefined behaviour for invalid blobs. */ function decode(bytes memory _blob) internal pure returns (InventoryObjectData memory _table) { - // 32 is the total byte length of static data - PackedCounter _encodedLengths = PackedCounter.wrap(Bytes.slice32(_blob, 32)); + // 35 is the total byte length of static data + PackedCounter _encodedLengths = PackedCounter.wrap(Bytes.slice32(_blob, 35)); _table.objectTypeId = (Bytes.slice32(_blob, 0)); + _table.numObjects = (uint8(Bytes.slice1(_blob, 32))); + + _table.numUsesLeft = (uint16(Bytes.slice2(_blob, 33))); + // Store trims the blob if dynamic fields are all empty - if (_blob.length > 32) { + if (_blob.length > 35) { // skip static data length + dynamic lengths word - uint256 _start = 64; + uint256 _start = 67; uint256 _end; unchecked { - _end = 64 + _encodedLengths.atIndex(0); + _end = 67 + _encodedLengths.atIndex(0); } _table.objectProperties = (bytes(SliceLib.getSubslice(_blob, _start, _end).toBytes())); } } /** Tightly pack full data using this table's schema */ - function encode(bytes32 objectTypeId, bytes memory objectProperties) internal pure returns (bytes memory) { + function encode( + bytes32 objectTypeId, + uint8 numObjects, + uint16 numUsesLeft, + bytes memory objectProperties + ) internal pure returns (bytes memory) { PackedCounter _encodedLengths; // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(bytes(objectProperties).length); } - return abi.encodePacked(objectTypeId, _encodedLengths.unwrap(), bytes((objectProperties))); + return abi.encodePacked(objectTypeId, numObjects, numUsesLeft, _encodedLengths.unwrap(), bytes((objectProperties))); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/base-world/src/codegen/tables/Recipes.sol b/packages/base-world/src/codegen/tables/Recipes.sol new file mode 100644 index 000000000..96913a401 --- /dev/null +++ b/packages/base-world/src/codegen/tables/Recipes.sol @@ -0,0 +1,1056 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/* Autogenerated file. Do not edit manually. */ + +// Import schema type +import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; + +// Import store internals +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; +import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; +import { Bytes } from "@latticexyz/store/src/Bytes.sol"; +import { Memory } from "@latticexyz/store/src/Memory.sol"; +import { SliceLib } from "@latticexyz/store/src/Slice.sol"; +import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; +import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; +import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; + +bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Recipes"))); +bytes32 constant RecipesTableId = _tableId; + +struct RecipesData { + bytes32[] inputObjectTypeIds; + uint8[] inputObjectTypeAmounts; + bytes32[] outputObjectTypeIds; + uint8[] outputObjectTypeAmounts; + bytes outputObjectProperties; +} + +library Recipes { + /** Get the table's key schema */ + function getKeySchema() internal pure returns (Schema) { + SchemaType[] memory _schema = new SchemaType[](1); + _schema[0] = SchemaType.BYTES32; + + return SchemaLib.encode(_schema); + } + + /** Get the table's value schema */ + function getValueSchema() internal pure returns (Schema) { + SchemaType[] memory _schema = new SchemaType[](5); + _schema[0] = SchemaType.BYTES32_ARRAY; + _schema[1] = SchemaType.UINT8_ARRAY; + _schema[2] = SchemaType.BYTES32_ARRAY; + _schema[3] = SchemaType.UINT8_ARRAY; + _schema[4] = SchemaType.BYTES; + + return SchemaLib.encode(_schema); + } + + /** Get the table's key names */ + function getKeyNames() internal pure returns (string[] memory keyNames) { + keyNames = new string[](1); + keyNames[0] = "recipeId"; + } + + /** Get the table's field names */ + function getFieldNames() internal pure returns (string[] memory fieldNames) { + fieldNames = new string[](5); + fieldNames[0] = "inputObjectTypeIds"; + fieldNames[1] = "inputObjectTypeAmounts"; + fieldNames[2] = "outputObjectTypeIds"; + fieldNames[3] = "outputObjectTypeAmounts"; + fieldNames[4] = "outputObjectProperties"; + } + + /** Register the table's key schema, value schema, key names and value names */ + function register() internal { + StoreSwitch.registerTable(_tableId, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); + } + + /** Register the table's key schema, value schema, key names and value names (using the specified store) */ + function register(IStore _store) internal { + _store.registerTable(_tableId, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); + } + + /** Get inputObjectTypeIds */ + function getInputObjectTypeIds(bytes32 recipeId) internal view returns (bytes32[] memory inputObjectTypeIds) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 0, getValueSchema()); + return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes32()); + } + + /** Get inputObjectTypeIds (using the specified store) */ + function getInputObjectTypeIds( + IStore _store, + bytes32 recipeId + ) internal view returns (bytes32[] memory inputObjectTypeIds) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = _store.getField(_tableId, _keyTuple, 0, getValueSchema()); + return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes32()); + } + + /** Set inputObjectTypeIds */ + function setInputObjectTypeIds(bytes32 recipeId, bytes32[] memory inputObjectTypeIds) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.setField(_tableId, _keyTuple, 0, EncodeArray.encode((inputObjectTypeIds)), getValueSchema()); + } + + /** Set inputObjectTypeIds (using the specified store) */ + function setInputObjectTypeIds(IStore _store, bytes32 recipeId, bytes32[] memory inputObjectTypeIds) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.setField(_tableId, _keyTuple, 0, EncodeArray.encode((inputObjectTypeIds)), getValueSchema()); + } + + /** Get the length of inputObjectTypeIds */ + function lengthInputObjectTypeIds(bytes32 recipeId) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 0, getValueSchema()); + unchecked { + return _byteLength / 32; + } + } + + /** Get the length of inputObjectTypeIds (using the specified store) */ + function lengthInputObjectTypeIds(IStore _store, bytes32 recipeId) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 0, getValueSchema()); + unchecked { + return _byteLength / 32; + } + } + + /** + * Get an item of inputObjectTypeIds + * (unchecked, returns invalid data if index overflows) + */ + function getItemInputObjectTypeIds(bytes32 recipeId, uint256 _index) internal view returns (bytes32) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + bytes memory _blob = StoreSwitch.getFieldSlice( + _tableId, + _keyTuple, + 0, + getValueSchema(), + _index * 32, + (_index + 1) * 32 + ); + return (Bytes.slice32(_blob, 0)); + } + } + + /** + * Get an item of inputObjectTypeIds (using the specified store) + * (unchecked, returns invalid data if index overflows) + */ + function getItemInputObjectTypeIds(IStore _store, bytes32 recipeId, uint256 _index) internal view returns (bytes32) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + bytes memory _blob = _store.getFieldSlice( + _tableId, + _keyTuple, + 0, + getValueSchema(), + _index * 32, + (_index + 1) * 32 + ); + return (Bytes.slice32(_blob, 0)); + } + } + + /** Push an element to inputObjectTypeIds */ + function pushInputObjectTypeIds(bytes32 recipeId, bytes32 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.pushToField(_tableId, _keyTuple, 0, abi.encodePacked((_element)), getValueSchema()); + } + + /** Push an element to inputObjectTypeIds (using the specified store) */ + function pushInputObjectTypeIds(IStore _store, bytes32 recipeId, bytes32 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.pushToField(_tableId, _keyTuple, 0, abi.encodePacked((_element)), getValueSchema()); + } + + /** Pop an element from inputObjectTypeIds */ + function popInputObjectTypeIds(bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.popFromField(_tableId, _keyTuple, 0, 32, getValueSchema()); + } + + /** Pop an element from inputObjectTypeIds (using the specified store) */ + function popInputObjectTypeIds(IStore _store, bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.popFromField(_tableId, _keyTuple, 0, 32, getValueSchema()); + } + + /** + * Update an element of inputObjectTypeIds at `_index` + * (checked only to prevent modifying other tables; can corrupt own data if index overflows) + */ + function updateInputObjectTypeIds(bytes32 recipeId, uint256 _index, bytes32 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + StoreSwitch.updateInField(_tableId, _keyTuple, 0, _index * 32, abi.encodePacked((_element)), getValueSchema()); + } + } + + /** + * Update an element of inputObjectTypeIds (using the specified store) at `_index` + * (checked only to prevent modifying other tables; can corrupt own data if index overflows) + */ + function updateInputObjectTypeIds(IStore _store, bytes32 recipeId, uint256 _index, bytes32 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + _store.updateInField(_tableId, _keyTuple, 0, _index * 32, abi.encodePacked((_element)), getValueSchema()); + } + } + + /** Get inputObjectTypeAmounts */ + function getInputObjectTypeAmounts(bytes32 recipeId) internal view returns (uint8[] memory inputObjectTypeAmounts) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 1, getValueSchema()); + return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint8()); + } + + /** Get inputObjectTypeAmounts (using the specified store) */ + function getInputObjectTypeAmounts( + IStore _store, + bytes32 recipeId + ) internal view returns (uint8[] memory inputObjectTypeAmounts) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = _store.getField(_tableId, _keyTuple, 1, getValueSchema()); + return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint8()); + } + + /** Set inputObjectTypeAmounts */ + function setInputObjectTypeAmounts(bytes32 recipeId, uint8[] memory inputObjectTypeAmounts) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.setField(_tableId, _keyTuple, 1, EncodeArray.encode((inputObjectTypeAmounts)), getValueSchema()); + } + + /** Set inputObjectTypeAmounts (using the specified store) */ + function setInputObjectTypeAmounts(IStore _store, bytes32 recipeId, uint8[] memory inputObjectTypeAmounts) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.setField(_tableId, _keyTuple, 1, EncodeArray.encode((inputObjectTypeAmounts)), getValueSchema()); + } + + /** Get the length of inputObjectTypeAmounts */ + function lengthInputObjectTypeAmounts(bytes32 recipeId) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 1, getValueSchema()); + unchecked { + return _byteLength / 1; + } + } + + /** Get the length of inputObjectTypeAmounts (using the specified store) */ + function lengthInputObjectTypeAmounts(IStore _store, bytes32 recipeId) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 1, getValueSchema()); + unchecked { + return _byteLength / 1; + } + } + + /** + * Get an item of inputObjectTypeAmounts + * (unchecked, returns invalid data if index overflows) + */ + function getItemInputObjectTypeAmounts(bytes32 recipeId, uint256 _index) internal view returns (uint8) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + bytes memory _blob = StoreSwitch.getFieldSlice( + _tableId, + _keyTuple, + 1, + getValueSchema(), + _index * 1, + (_index + 1) * 1 + ); + return (uint8(Bytes.slice1(_blob, 0))); + } + } + + /** + * Get an item of inputObjectTypeAmounts (using the specified store) + * (unchecked, returns invalid data if index overflows) + */ + function getItemInputObjectTypeAmounts( + IStore _store, + bytes32 recipeId, + uint256 _index + ) internal view returns (uint8) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + bytes memory _blob = _store.getFieldSlice(_tableId, _keyTuple, 1, getValueSchema(), _index * 1, (_index + 1) * 1); + return (uint8(Bytes.slice1(_blob, 0))); + } + } + + /** Push an element to inputObjectTypeAmounts */ + function pushInputObjectTypeAmounts(bytes32 recipeId, uint8 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.pushToField(_tableId, _keyTuple, 1, abi.encodePacked((_element)), getValueSchema()); + } + + /** Push an element to inputObjectTypeAmounts (using the specified store) */ + function pushInputObjectTypeAmounts(IStore _store, bytes32 recipeId, uint8 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.pushToField(_tableId, _keyTuple, 1, abi.encodePacked((_element)), getValueSchema()); + } + + /** Pop an element from inputObjectTypeAmounts */ + function popInputObjectTypeAmounts(bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.popFromField(_tableId, _keyTuple, 1, 1, getValueSchema()); + } + + /** Pop an element from inputObjectTypeAmounts (using the specified store) */ + function popInputObjectTypeAmounts(IStore _store, bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.popFromField(_tableId, _keyTuple, 1, 1, getValueSchema()); + } + + /** + * Update an element of inputObjectTypeAmounts at `_index` + * (checked only to prevent modifying other tables; can corrupt own data if index overflows) + */ + function updateInputObjectTypeAmounts(bytes32 recipeId, uint256 _index, uint8 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + StoreSwitch.updateInField(_tableId, _keyTuple, 1, _index * 1, abi.encodePacked((_element)), getValueSchema()); + } + } + + /** + * Update an element of inputObjectTypeAmounts (using the specified store) at `_index` + * (checked only to prevent modifying other tables; can corrupt own data if index overflows) + */ + function updateInputObjectTypeAmounts(IStore _store, bytes32 recipeId, uint256 _index, uint8 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + _store.updateInField(_tableId, _keyTuple, 1, _index * 1, abi.encodePacked((_element)), getValueSchema()); + } + } + + /** Get outputObjectTypeIds */ + function getOutputObjectTypeIds(bytes32 recipeId) internal view returns (bytes32[] memory outputObjectTypeIds) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 2, getValueSchema()); + return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes32()); + } + + /** Get outputObjectTypeIds (using the specified store) */ + function getOutputObjectTypeIds( + IStore _store, + bytes32 recipeId + ) internal view returns (bytes32[] memory outputObjectTypeIds) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = _store.getField(_tableId, _keyTuple, 2, getValueSchema()); + return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes32()); + } + + /** Set outputObjectTypeIds */ + function setOutputObjectTypeIds(bytes32 recipeId, bytes32[] memory outputObjectTypeIds) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.setField(_tableId, _keyTuple, 2, EncodeArray.encode((outputObjectTypeIds)), getValueSchema()); + } + + /** Set outputObjectTypeIds (using the specified store) */ + function setOutputObjectTypeIds(IStore _store, bytes32 recipeId, bytes32[] memory outputObjectTypeIds) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.setField(_tableId, _keyTuple, 2, EncodeArray.encode((outputObjectTypeIds)), getValueSchema()); + } + + /** Get the length of outputObjectTypeIds */ + function lengthOutputObjectTypeIds(bytes32 recipeId) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 2, getValueSchema()); + unchecked { + return _byteLength / 32; + } + } + + /** Get the length of outputObjectTypeIds (using the specified store) */ + function lengthOutputObjectTypeIds(IStore _store, bytes32 recipeId) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 2, getValueSchema()); + unchecked { + return _byteLength / 32; + } + } + + /** + * Get an item of outputObjectTypeIds + * (unchecked, returns invalid data if index overflows) + */ + function getItemOutputObjectTypeIds(bytes32 recipeId, uint256 _index) internal view returns (bytes32) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + bytes memory _blob = StoreSwitch.getFieldSlice( + _tableId, + _keyTuple, + 2, + getValueSchema(), + _index * 32, + (_index + 1) * 32 + ); + return (Bytes.slice32(_blob, 0)); + } + } + + /** + * Get an item of outputObjectTypeIds (using the specified store) + * (unchecked, returns invalid data if index overflows) + */ + function getItemOutputObjectTypeIds(IStore _store, bytes32 recipeId, uint256 _index) internal view returns (bytes32) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + bytes memory _blob = _store.getFieldSlice( + _tableId, + _keyTuple, + 2, + getValueSchema(), + _index * 32, + (_index + 1) * 32 + ); + return (Bytes.slice32(_blob, 0)); + } + } + + /** Push an element to outputObjectTypeIds */ + function pushOutputObjectTypeIds(bytes32 recipeId, bytes32 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.pushToField(_tableId, _keyTuple, 2, abi.encodePacked((_element)), getValueSchema()); + } + + /** Push an element to outputObjectTypeIds (using the specified store) */ + function pushOutputObjectTypeIds(IStore _store, bytes32 recipeId, bytes32 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.pushToField(_tableId, _keyTuple, 2, abi.encodePacked((_element)), getValueSchema()); + } + + /** Pop an element from outputObjectTypeIds */ + function popOutputObjectTypeIds(bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.popFromField(_tableId, _keyTuple, 2, 32, getValueSchema()); + } + + /** Pop an element from outputObjectTypeIds (using the specified store) */ + function popOutputObjectTypeIds(IStore _store, bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.popFromField(_tableId, _keyTuple, 2, 32, getValueSchema()); + } + + /** + * Update an element of outputObjectTypeIds at `_index` + * (checked only to prevent modifying other tables; can corrupt own data if index overflows) + */ + function updateOutputObjectTypeIds(bytes32 recipeId, uint256 _index, bytes32 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + StoreSwitch.updateInField(_tableId, _keyTuple, 2, _index * 32, abi.encodePacked((_element)), getValueSchema()); + } + } + + /** + * Update an element of outputObjectTypeIds (using the specified store) at `_index` + * (checked only to prevent modifying other tables; can corrupt own data if index overflows) + */ + function updateOutputObjectTypeIds(IStore _store, bytes32 recipeId, uint256 _index, bytes32 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + _store.updateInField(_tableId, _keyTuple, 2, _index * 32, abi.encodePacked((_element)), getValueSchema()); + } + } + + /** Get outputObjectTypeAmounts */ + function getOutputObjectTypeAmounts(bytes32 recipeId) internal view returns (uint8[] memory outputObjectTypeAmounts) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 3, getValueSchema()); + return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint8()); + } + + /** Get outputObjectTypeAmounts (using the specified store) */ + function getOutputObjectTypeAmounts( + IStore _store, + bytes32 recipeId + ) internal view returns (uint8[] memory outputObjectTypeAmounts) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = _store.getField(_tableId, _keyTuple, 3, getValueSchema()); + return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_uint8()); + } + + /** Set outputObjectTypeAmounts */ + function setOutputObjectTypeAmounts(bytes32 recipeId, uint8[] memory outputObjectTypeAmounts) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.setField(_tableId, _keyTuple, 3, EncodeArray.encode((outputObjectTypeAmounts)), getValueSchema()); + } + + /** Set outputObjectTypeAmounts (using the specified store) */ + function setOutputObjectTypeAmounts( + IStore _store, + bytes32 recipeId, + uint8[] memory outputObjectTypeAmounts + ) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.setField(_tableId, _keyTuple, 3, EncodeArray.encode((outputObjectTypeAmounts)), getValueSchema()); + } + + /** Get the length of outputObjectTypeAmounts */ + function lengthOutputObjectTypeAmounts(bytes32 recipeId) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 3, getValueSchema()); + unchecked { + return _byteLength / 1; + } + } + + /** Get the length of outputObjectTypeAmounts (using the specified store) */ + function lengthOutputObjectTypeAmounts(IStore _store, bytes32 recipeId) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 3, getValueSchema()); + unchecked { + return _byteLength / 1; + } + } + + /** + * Get an item of outputObjectTypeAmounts + * (unchecked, returns invalid data if index overflows) + */ + function getItemOutputObjectTypeAmounts(bytes32 recipeId, uint256 _index) internal view returns (uint8) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + bytes memory _blob = StoreSwitch.getFieldSlice( + _tableId, + _keyTuple, + 3, + getValueSchema(), + _index * 1, + (_index + 1) * 1 + ); + return (uint8(Bytes.slice1(_blob, 0))); + } + } + + /** + * Get an item of outputObjectTypeAmounts (using the specified store) + * (unchecked, returns invalid data if index overflows) + */ + function getItemOutputObjectTypeAmounts( + IStore _store, + bytes32 recipeId, + uint256 _index + ) internal view returns (uint8) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + bytes memory _blob = _store.getFieldSlice(_tableId, _keyTuple, 3, getValueSchema(), _index * 1, (_index + 1) * 1); + return (uint8(Bytes.slice1(_blob, 0))); + } + } + + /** Push an element to outputObjectTypeAmounts */ + function pushOutputObjectTypeAmounts(bytes32 recipeId, uint8 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.pushToField(_tableId, _keyTuple, 3, abi.encodePacked((_element)), getValueSchema()); + } + + /** Push an element to outputObjectTypeAmounts (using the specified store) */ + function pushOutputObjectTypeAmounts(IStore _store, bytes32 recipeId, uint8 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.pushToField(_tableId, _keyTuple, 3, abi.encodePacked((_element)), getValueSchema()); + } + + /** Pop an element from outputObjectTypeAmounts */ + function popOutputObjectTypeAmounts(bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.popFromField(_tableId, _keyTuple, 3, 1, getValueSchema()); + } + + /** Pop an element from outputObjectTypeAmounts (using the specified store) */ + function popOutputObjectTypeAmounts(IStore _store, bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.popFromField(_tableId, _keyTuple, 3, 1, getValueSchema()); + } + + /** + * Update an element of outputObjectTypeAmounts at `_index` + * (checked only to prevent modifying other tables; can corrupt own data if index overflows) + */ + function updateOutputObjectTypeAmounts(bytes32 recipeId, uint256 _index, uint8 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + StoreSwitch.updateInField(_tableId, _keyTuple, 3, _index * 1, abi.encodePacked((_element)), getValueSchema()); + } + } + + /** + * Update an element of outputObjectTypeAmounts (using the specified store) at `_index` + * (checked only to prevent modifying other tables; can corrupt own data if index overflows) + */ + function updateOutputObjectTypeAmounts(IStore _store, bytes32 recipeId, uint256 _index, uint8 _element) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + _store.updateInField(_tableId, _keyTuple, 3, _index * 1, abi.encodePacked((_element)), getValueSchema()); + } + } + + /** Get outputObjectProperties */ + function getOutputObjectProperties(bytes32 recipeId) internal view returns (bytes memory outputObjectProperties) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 4, getValueSchema()); + return (bytes(_blob)); + } + + /** Get outputObjectProperties (using the specified store) */ + function getOutputObjectProperties( + IStore _store, + bytes32 recipeId + ) internal view returns (bytes memory outputObjectProperties) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = _store.getField(_tableId, _keyTuple, 4, getValueSchema()); + return (bytes(_blob)); + } + + /** Set outputObjectProperties */ + function setOutputObjectProperties(bytes32 recipeId, bytes memory outputObjectProperties) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.setField(_tableId, _keyTuple, 4, bytes((outputObjectProperties)), getValueSchema()); + } + + /** Set outputObjectProperties (using the specified store) */ + function setOutputObjectProperties(IStore _store, bytes32 recipeId, bytes memory outputObjectProperties) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.setField(_tableId, _keyTuple, 4, bytes((outputObjectProperties)), getValueSchema()); + } + + /** Get the length of outputObjectProperties */ + function lengthOutputObjectProperties(bytes32 recipeId) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 4, getValueSchema()); + unchecked { + return _byteLength / 1; + } + } + + /** Get the length of outputObjectProperties (using the specified store) */ + function lengthOutputObjectProperties(IStore _store, bytes32 recipeId) internal view returns (uint256) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 4, getValueSchema()); + unchecked { + return _byteLength / 1; + } + } + + /** + * Get an item of outputObjectProperties + * (unchecked, returns invalid data if index overflows) + */ + function getItemOutputObjectProperties(bytes32 recipeId, uint256 _index) internal view returns (bytes memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + bytes memory _blob = StoreSwitch.getFieldSlice( + _tableId, + _keyTuple, + 4, + getValueSchema(), + _index * 1, + (_index + 1) * 1 + ); + return (bytes(_blob)); + } + } + + /** + * Get an item of outputObjectProperties (using the specified store) + * (unchecked, returns invalid data if index overflows) + */ + function getItemOutputObjectProperties( + IStore _store, + bytes32 recipeId, + uint256 _index + ) internal view returns (bytes memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + bytes memory _blob = _store.getFieldSlice(_tableId, _keyTuple, 4, getValueSchema(), _index * 1, (_index + 1) * 1); + return (bytes(_blob)); + } + } + + /** Push a slice to outputObjectProperties */ + function pushOutputObjectProperties(bytes32 recipeId, bytes memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.pushToField(_tableId, _keyTuple, 4, bytes((_slice)), getValueSchema()); + } + + /** Push a slice to outputObjectProperties (using the specified store) */ + function pushOutputObjectProperties(IStore _store, bytes32 recipeId, bytes memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.pushToField(_tableId, _keyTuple, 4, bytes((_slice)), getValueSchema()); + } + + /** Pop a slice from outputObjectProperties */ + function popOutputObjectProperties(bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.popFromField(_tableId, _keyTuple, 4, 1, getValueSchema()); + } + + /** Pop a slice from outputObjectProperties (using the specified store) */ + function popOutputObjectProperties(IStore _store, bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.popFromField(_tableId, _keyTuple, 4, 1, getValueSchema()); + } + + /** + * Update a slice of outputObjectProperties at `_index` + * (checked only to prevent modifying other tables; can corrupt own data if index overflows) + */ + function updateOutputObjectProperties(bytes32 recipeId, uint256 _index, bytes memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + StoreSwitch.updateInField(_tableId, _keyTuple, 4, _index * 1, bytes((_slice)), getValueSchema()); + } + } + + /** + * Update a slice of outputObjectProperties (using the specified store) at `_index` + * (checked only to prevent modifying other tables; can corrupt own data if index overflows) + */ + function updateOutputObjectProperties(IStore _store, bytes32 recipeId, uint256 _index, bytes memory _slice) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + unchecked { + _store.updateInField(_tableId, _keyTuple, 4, _index * 1, bytes((_slice)), getValueSchema()); + } + } + + /** Get the full data */ + function get(bytes32 recipeId) internal view returns (RecipesData memory _table) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = StoreSwitch.getRecord(_tableId, _keyTuple, getValueSchema()); + return decode(_blob); + } + + /** Get the full data (using the specified store) */ + function get(IStore _store, bytes32 recipeId) internal view returns (RecipesData memory _table) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + bytes memory _blob = _store.getRecord(_tableId, _keyTuple, getValueSchema()); + return decode(_blob); + } + + /** Set the full data using individual values */ + function set( + bytes32 recipeId, + bytes32[] memory inputObjectTypeIds, + uint8[] memory inputObjectTypeAmounts, + bytes32[] memory outputObjectTypeIds, + uint8[] memory outputObjectTypeAmounts, + bytes memory outputObjectProperties + ) internal { + bytes memory _data = encode( + inputObjectTypeIds, + inputObjectTypeAmounts, + outputObjectTypeIds, + outputObjectTypeAmounts, + outputObjectProperties + ); + + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + } + + /** Set the full data using individual values (using the specified store) */ + function set( + IStore _store, + bytes32 recipeId, + bytes32[] memory inputObjectTypeIds, + uint8[] memory inputObjectTypeAmounts, + bytes32[] memory outputObjectTypeIds, + uint8[] memory outputObjectTypeAmounts, + bytes memory outputObjectProperties + ) internal { + bytes memory _data = encode( + inputObjectTypeIds, + inputObjectTypeAmounts, + outputObjectTypeIds, + outputObjectTypeAmounts, + outputObjectProperties + ); + + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + } + + /** Set the full data using the data struct */ + function set(bytes32 recipeId, RecipesData memory _table) internal { + set( + recipeId, + _table.inputObjectTypeIds, + _table.inputObjectTypeAmounts, + _table.outputObjectTypeIds, + _table.outputObjectTypeAmounts, + _table.outputObjectProperties + ); + } + + /** Set the full data using the data struct (using the specified store) */ + function set(IStore _store, bytes32 recipeId, RecipesData memory _table) internal { + set( + _store, + recipeId, + _table.inputObjectTypeIds, + _table.inputObjectTypeAmounts, + _table.outputObjectTypeIds, + _table.outputObjectTypeAmounts, + _table.outputObjectProperties + ); + } + + /** + * Decode the tightly packed blob using this table's schema. + * Undefined behaviour for invalid blobs. + */ + function decode(bytes memory _blob) internal pure returns (RecipesData memory _table) { + // 0 is the total byte length of static data + PackedCounter _encodedLengths = PackedCounter.wrap(Bytes.slice32(_blob, 0)); + + // Store trims the blob if dynamic fields are all empty + if (_blob.length > 0) { + // skip static data length + dynamic lengths word + uint256 _start = 32; + uint256 _end; + unchecked { + _end = 32 + _encodedLengths.atIndex(0); + } + _table.inputObjectTypeIds = (SliceLib.getSubslice(_blob, _start, _end).decodeArray_bytes32()); + + _start = _end; + unchecked { + _end += _encodedLengths.atIndex(1); + } + _table.inputObjectTypeAmounts = (SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint8()); + + _start = _end; + unchecked { + _end += _encodedLengths.atIndex(2); + } + _table.outputObjectTypeIds = (SliceLib.getSubslice(_blob, _start, _end).decodeArray_bytes32()); + + _start = _end; + unchecked { + _end += _encodedLengths.atIndex(3); + } + _table.outputObjectTypeAmounts = (SliceLib.getSubslice(_blob, _start, _end).decodeArray_uint8()); + + _start = _end; + unchecked { + _end += _encodedLengths.atIndex(4); + } + _table.outputObjectProperties = (bytes(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + } + } + + /** Tightly pack full data using this table's schema */ + function encode( + bytes32[] memory inputObjectTypeIds, + uint8[] memory inputObjectTypeAmounts, + bytes32[] memory outputObjectTypeIds, + uint8[] memory outputObjectTypeAmounts, + bytes memory outputObjectProperties + ) internal pure returns (bytes memory) { + PackedCounter _encodedLengths; + // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits + unchecked { + _encodedLengths = PackedCounterLib.pack( + inputObjectTypeIds.length * 32, + inputObjectTypeAmounts.length * 1, + outputObjectTypeIds.length * 32, + outputObjectTypeAmounts.length * 1, + bytes(outputObjectProperties).length + ); + } + + return + abi.encodePacked( + _encodedLengths.unwrap(), + EncodeArray.encode((inputObjectTypeIds)), + EncodeArray.encode((inputObjectTypeAmounts)), + EncodeArray.encode((outputObjectTypeIds)), + EncodeArray.encode((outputObjectTypeAmounts)), + bytes((outputObjectProperties)) + ); + } + + /** Encode keys as a bytes32 array using this table's schema */ + function encodeKeyTuple(bytes32 recipeId) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + return _keyTuple; + } + + /* Delete all data for given keys */ + function deleteRecord(bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, getValueSchema()); + } + + /* Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 recipeId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = recipeId; + + _store.deleteRecord(_tableId, _keyTuple, getValueSchema()); + } +} diff --git a/packages/base-world/src/codegen/world/ICraftSystem.sol b/packages/base-world/src/codegen/world/ICraftSystem.sol new file mode 100644 index 000000000..51694ba50 --- /dev/null +++ b/packages/base-world/src/codegen/world/ICraftSystem.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/* Autogenerated file. Do not edit manually. */ + +interface ICraftSystem { + function craft(bytes32 actingObjectEntityId, bytes32 recipeId, bytes32[] memory ingredientIds) external; +} diff --git a/packages/base-world/src/codegen/world/IInternalInventorySystem.sol b/packages/base-world/src/codegen/world/IInternalInventorySystem.sol new file mode 100644 index 000000000..442f59aa8 --- /dev/null +++ b/packages/base-world/src/codegen/world/IInternalInventorySystem.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/* Autogenerated file. Do not edit manually. */ + +import { ObjectProperties } from "@tenet-utils/src/Types.sol"; + +interface IInternalInventorySystem { + function useEquipped(bytes32 actingObjectEntityId) external; + + function isInventoryFull(bytes32 objectEntityId) external view returns (bool); + + function addObjectToInventory( + bytes32 objectEntityId, + bytes32 objectTypeId, + uint8 numObjectsToAdd, + ObjectProperties memory objectProperties + ) external; + + function removeObjectFromInventory(bytes32 inventoryId, uint8 numObjectsToRemove) external; +} diff --git a/packages/base-world/src/codegen/world/IInventorySystem.sol b/packages/base-world/src/codegen/world/IInventorySystem.sol new file mode 100644 index 000000000..ba7e1f848 --- /dev/null +++ b/packages/base-world/src/codegen/world/IInventorySystem.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/* Autogenerated file. Do not edit manually. */ + +import { VoxelCoord } from "@tenet-utils/src/Types.sol"; + +interface IInventorySystem { + function equip(bytes32 actingObjectEntityId, bytes32 inventoryId) external; + + function unequip(bytes32 actingObjectEntityId) external; + + function transfer( + bytes32 srcObjectEntityId, + VoxelCoord memory dstCoord, + bytes32 inventoryId, + uint8 transferAmount + ) external; +} diff --git a/packages/base-world/src/codegen/world/IWorld.sol b/packages/base-world/src/codegen/world/IWorld.sol index 464b459dd..649a05b6e 100644 --- a/packages/base-world/src/codegen/world/IWorld.sol +++ b/packages/base-world/src/codegen/world/IWorld.sol @@ -9,8 +9,11 @@ import { IActionSystem } from "@tenet-base-world/src/codegen/world/IActionSystem import { IActivateSystem } from "@tenet-base-world/src/codegen/world/IActivateSystem.sol"; import { IAgentSystem } from "@tenet-base-world/src/codegen/world/IAgentSystem.sol"; import { IBuildSystem } from "@tenet-base-world/src/codegen/world/IBuildSystem.sol"; +import { ICraftSystem } from "@tenet-base-world/src/codegen/world/ICraftSystem.sol"; import { IEventApprovalsSystem } from "@tenet-base-world/src/codegen/world/IEventApprovalsSystem.sol"; import { IExternalObjectSystem } from "@tenet-base-world/src/codegen/world/IExternalObjectSystem.sol"; +import { IInternalInventorySystem } from "@tenet-base-world/src/codegen/world/IInternalInventorySystem.sol"; +import { IInventorySystem } from "@tenet-base-world/src/codegen/world/IInventorySystem.sol"; import { IMindSystem } from "@tenet-base-world/src/codegen/world/IMindSystem.sol"; import { IMineSystem } from "@tenet-base-world/src/codegen/world/IMineSystem.sol"; import { IMoveSystem } from "@tenet-base-world/src/codegen/world/IMoveSystem.sol"; @@ -28,8 +31,11 @@ interface IWorld is IActivateSystem, IAgentSystem, IBuildSystem, + ICraftSystem, IEventApprovalsSystem, IExternalObjectSystem, + IInternalInventorySystem, + IInventorySystem, IMindSystem, IMineSystem, IMoveSystem, diff --git a/packages/base-world/src/prototypes/ActivateEvent.sol b/packages/base-world/src/prototypes/ActivateEvent.sol index 62d45678d..de1687a51 100644 --- a/packages/base-world/src/prototypes/ActivateEvent.sol +++ b/packages/base-world/src/prototypes/ActivateEvent.sol @@ -63,6 +63,8 @@ abstract contract ActivateEvent is Event { require(ObjectType.get(eventEntityId) == objectTypeId, "ActivateEvent: object type id mismatch"); // Note: if we want objects to return some property data, we could do that here in the future + IWorld(_world()).useEquipped(actingObjectEntityId); + IWorldActivateEventSystem(getSimulatorAddress()).onActivateEvent( actingObjectEntityId, objectTypeId, diff --git a/packages/base-world/src/prototypes/BuildEvent.sol b/packages/base-world/src/prototypes/BuildEvent.sol index 4bc896265..2ad19fae2 100644 --- a/packages/base-world/src/prototypes/BuildEvent.sol +++ b/packages/base-world/src/prototypes/BuildEvent.sol @@ -2,13 +2,15 @@ pragma solidity >=0.8.0; import { IWorld } from "@tenet-base-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; import { Event } from "@tenet-base-world/src/prototypes/Event.sol"; import { getKeysWithValue } from "@latticexyz/world/src/modules/keyswithvalue/getKeysWithValue.sol"; import { ObjectType } from "@tenet-base-world/src/codegen/tables/ObjectType.sol"; import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; -import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; +import { InventoryObject, InventoryObjectData } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; +import { Equipped } from "@tenet-base-world/src/codegen/tables/Equipped.sol"; import { ObjectEntity } from "@tenet-base-world/src/codegen/tables/ObjectEntity.sol"; import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; import { IWorldBuildEventSystem } from "@tenet-base-simulator/src/codegen/world/IWorldBuildEventSystem.sol"; @@ -68,10 +70,13 @@ abstract contract BuildEvent is Event { ); } else { require(ObjectType.get(eventEntityId) == emptyObjectId(), "BuildEvent: Object type id is not empty"); - + } + address caller = _msgSender(); + if (caller != _world() && caller != getSimulatorAddress()) { bytes32[][] memory inventoryIds = getKeysWithValue(InventoryTableId, Inventory.encode(objectEntityId)); require(inventoryIds.length == 0, "BuildEvent: Cannot build where there are dropped items"); } + ObjectProperties memory requestedProperties = IWorld(_world()).enterWorld(objectTypeId, coord, objectEntityId); if (isNewEntity) { ObjectProperties memory properties = IWorld(_world()).getTerrainObjectProperties(coord, requestedProperties); @@ -80,11 +85,14 @@ abstract contract BuildEvent is Event { ObjectType.set(eventEntityId, objectTypeId); - address caller = _msgSender(); if (caller != _world() && caller != getSimulatorAddress()) { bytes32 inventoryId = getInventoryId(eventData); - Inventory.deleteRecord(inventoryId); - InventoryObject.deleteRecord(inventoryId); + IWorld(_world()).removeObjectFromInventory(inventoryId, 1); + + bytes32 equippedInventoryId = Equipped.get(actingObjectEntityId); + if (equippedInventoryId == inventoryId) { + Equipped.deleteRecord(actingObjectEntityId); + } } IWorldBuildEventSystem(getSimulatorAddress()).onBuildEvent( diff --git a/packages/base-world/src/prototypes/MineEvent.sol b/packages/base-world/src/prototypes/MineEvent.sol index 3400fe798..7f423f6a2 100644 --- a/packages/base-world/src/prototypes/MineEvent.sol +++ b/packages/base-world/src/prototypes/MineEvent.sol @@ -10,7 +10,7 @@ import { getKeysWithValue } from "@latticexyz/world/src/modules/keyswithvalue/ge import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; import { ObjectType } from "@tenet-base-world/src/codegen/tables/ObjectType.sol"; import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; -import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; +import { InventoryObject, InventoryObjectData } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; import { ObjectEntity } from "@tenet-base-world/src/codegen/tables/ObjectEntity.sol"; import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; import { IWorldMineEventSystem } from "@tenet-base-simulator/src/codegen/world/IWorldMineEventSystem.sol"; @@ -73,8 +73,6 @@ abstract contract MineEvent is Event { // Add to inventory if (actingObjectEntityId != bytes32(0)) { - bytes32 inventoryId = getUniqueEntity(); - Inventory.set(inventoryId, actingObjectEntityId); ObjectProperties memory inventoryObjectProperties; if (isNewEntity) { ObjectProperties memory requestedProperties = IWorld(_world()).enterWorld(objectTypeId, coord, objectEntityId); @@ -83,7 +81,10 @@ abstract contract MineEvent is Event { } else { inventoryObjectProperties = IWorld(_world()).getObjectProperties(objectEntityId); } - InventoryObject.set(inventoryId, objectTypeId, abi.encode(inventoryObjectProperties)); + + IWorld(_world()).addObjectToInventory(actingObjectEntityId, objectTypeId, 1, inventoryObjectProperties); + + IWorld(_world()).useEquipped(actingObjectEntityId); } IWorld(_world()).exitWorld(objectTypeId, coord, objectEntityId); diff --git a/packages/base-world/src/prototypes/MoveEvent.sol b/packages/base-world/src/prototypes/MoveEvent.sol index 6f41c4ae5..8609a8af6 100644 --- a/packages/base-world/src/prototypes/MoveEvent.sol +++ b/packages/base-world/src/prototypes/MoveEvent.sol @@ -127,6 +127,7 @@ abstract contract MoveEvent is Event { if (hasOwner) { for (uint256 i = 0; i < inventoryIds.length; i++) { bytes32 inventoryId = inventoryIds[i][0]; + require(!IWorld(_world()).isInventoryFull(oldObjectEntityId), "InventorySystem: inventory is full"); Inventory.set(inventoryId, oldObjectEntityId); } } else { diff --git a/packages/base-world/src/systems/CraftSystem.sol b/packages/base-world/src/systems/CraftSystem.sol new file mode 100644 index 000000000..54e45a63d --- /dev/null +++ b/packages/base-world/src/systems/CraftSystem.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-base-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/haskeys/hasKey.sol"; +import { getKeysInTable } from "@latticexyz/world/src/modules/keysintable/getKeysInTable.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; + +import { Recipes, RecipesData, RecipesTableId } from "@tenet-base-world/src/codegen/tables/Recipes.sol"; +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; + +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; + +abstract contract CraftSystem is System { + function craft(bytes32 actingObjectEntityId, bytes32 recipeId, bytes32[] memory ingredientIds) public virtual { + require(hasKey(OwnedByTableId, OwnedBy.encodeKeyTuple(actingObjectEntityId)), "CraftSystem: entity has no owner"); + require(OwnedBy.get(actingObjectEntityId) == _msgSender(), "CraftSystem: caller does not own entity"); + + RecipesData memory recipeData = Recipes.get(recipeId); + require(recipeData.inputObjectTypeIds.length > 0, "CraftSystem: recipe not found"); + + // Require that the acting object has all the ingredients in its inventory + // And delete the ingredients from the inventory as they are used + for (uint256 i = 0; i < recipeData.inputObjectTypeIds.length; i++) { + bool hasIngredient = false; + for (uint256 j = 0; j < ingredientIds.length; j++) { + if (Inventory.get(ingredientIds[j]) == actingObjectEntityId) { + bytes32 ingredientObjectTypeId = InventoryObject.getObjectTypeId(ingredientIds[j]); + if (ingredientObjectTypeId == recipeData.inputObjectTypeIds[i]) { + uint8 numObjects = InventoryObject.getNumObjects(ingredientIds[j]); + require(numObjects >= recipeData.inputObjectTypeAmounts[i], "CraftSystem: not enough ingredients"); + + hasIngredient = true; + IWorld(_world()).removeObjectFromInventory(ingredientIds[j], recipeData.inputObjectTypeAmounts[i]); + } + } + } + + require(hasIngredient, "CraftSystem: missing ingredient"); + } + + // Create the crafted objects + ObjectProperties[] memory outputObjectProperties = abi.decode( + recipeData.outputObjectProperties, + (ObjectProperties[]) + ); + for (uint256 i = 0; i < recipeData.outputObjectTypeIds.length; i++) { + IWorld(_world()).addObjectToInventory( + actingObjectEntityId, + recipeData.outputObjectTypeIds[i], + recipeData.outputObjectTypeAmounts[i], + outputObjectProperties[i] + ); + } + } +} diff --git a/packages/base-world/src/systems/EventApprovalsSystem.sol b/packages/base-world/src/systems/EventApprovalsSystem.sol index 09896888d..c85ddc05f 100644 --- a/packages/base-world/src/systems/EventApprovalsSystem.sol +++ b/packages/base-world/src/systems/EventApprovalsSystem.sol @@ -75,7 +75,8 @@ abstract contract EventApprovalsSystem is System { if (eventType == EventType.Build) { bytes32 inventoryId = getInventoryId(eventData); require( - InventoryObject.getObjectTypeId(inventoryId) == objectTypeId, + InventoryObject.getObjectTypeId(inventoryId) == objectTypeId && + InventoryObject.getNumObjects(inventoryId) > 0, "EventApprovalsSystem: Inventory object type id does not match" ); require( diff --git a/packages/base-world/src/systems/InternalInventorySystem.sol b/packages/base-world/src/systems/InternalInventorySystem.sol new file mode 100644 index 000000000..9213316c0 --- /dev/null +++ b/packages/base-world/src/systems/InternalInventorySystem.sol @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-base-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/haskeys/hasKey.sol"; +import { getUniqueEntity } from "@latticexyz/world/src/modules/uniqueentity/getUniqueEntity.sol"; +import { getKeysWithValue } from "@latticexyz/world/src/modules/keyswithvalue/getKeysWithValue.sol"; + +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject, InventoryObjectData } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; +import { Equipped } from "@tenet-base-world/src/codegen/tables/Equipped.sol"; + +import { REGISTRY_ADDRESS, NUM_MAX_INVENTORY_SLOTS } from "@tenet-base-world/src/Constants.sol"; +import { getStackable, getMaxUses } from "@tenet-registry/src/Utils.sol"; + +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; + +abstract contract InternalInventorySystem is System { + function useEquipped(bytes32 actingObjectEntityId) public virtual { + bytes32 equippedInventoryId = Equipped.get(actingObjectEntityId); + if (equippedInventoryId != bytes32(0)) { + InventoryObjectData memory equippedInventoryObjectData = InventoryObject.get(equippedInventoryId); + if (equippedInventoryObjectData.numUsesLeft > 0) { + if (equippedInventoryObjectData.numUsesLeft == 1) { + // Destroy equipped item + Equipped.deleteRecord(equippedInventoryId); + Inventory.deleteRecord(equippedInventoryId); + InventoryObject.deleteRecord(equippedInventoryId); + } else { + InventoryObject.setNumUsesLeft(equippedInventoryId, equippedInventoryObjectData.numUsesLeft - 1); + } + } // 0 = unlimited uses + } + } + + function isInventoryFull(bytes32 objectEntityId) public view virtual returns (bool); + + function addObjectToInventory( + bytes32 objectEntityId, + bytes32 objectTypeId, + uint8 numObjectsToAdd, + ObjectProperties memory objectProperties + ) public virtual { + bytes32[][] memory inventoryIds = getKeysWithValue(InventoryTableId, Inventory.encode(objectEntityId)); + + uint8 stackable = getStackable(IStore(REGISTRY_ADDRESS), objectTypeId); + require(stackable > 0, "InternalInventorySystem: Object type is not stackable"); + + uint16 numUsesLeft = getMaxUses(IStore(REGISTRY_ADDRESS), objectTypeId); + + // Check if this object type is already in the inventory, otherwise add a new one + uint8 remainingObjectsToAdd = numObjectsToAdd; + for (uint256 i = 0; i < inventoryIds.length; i++) { + bytes32 inventoryId = inventoryIds[i][0]; + InventoryObjectData memory inventoryObjectData = InventoryObject.get(inventoryId); + + if (inventoryObjectData.objectTypeId == objectTypeId && inventoryObjectData.numObjects < stackable) { + uint8 newNumObjects = inventoryObjectData.numObjects + remainingObjectsToAdd; + if (newNumObjects > stackable) { + newNumObjects = stackable; + remainingObjectsToAdd -= (stackable - inventoryObjectData.numObjects); + } else { + remainingObjectsToAdd = 0; + } + + InventoryObject.setNumObjects(inventoryId, newNumObjects); + } + + if (remainingObjectsToAdd == 0) { + break; + } + } + + while (remainingObjectsToAdd > 0) { + // add as manny new inventory slots per stackable limit to store the remaining objects + require(inventoryIds.length < NUM_MAX_INVENTORY_SLOTS, "InternalInventorySystem: Inventory is full"); + // Add new object to inventory + bytes32 inventoryId = getUniqueEntity(); + Inventory.set(inventoryId, objectEntityId); + uint8 newNumObjects = remainingObjectsToAdd; + if (remainingObjectsToAdd > stackable) { + newNumObjects = stackable; + remainingObjectsToAdd -= stackable; + inventoryIds = getKeysWithValue(InventoryTableId, Inventory.encode(objectEntityId)); + } else { + remainingObjectsToAdd = 0; + } + + InventoryObject.set(inventoryId, objectTypeId, newNumObjects, numUsesLeft, abi.encode(objectProperties)); + } + } + + function removeObjectFromInventory(bytes32 inventoryId, uint8 numObjectsToRemove) public virtual { + InventoryObjectData memory inventoryObjectData = InventoryObject.get(inventoryId); + require(inventoryObjectData.numObjects >= numObjectsToRemove, "InternalInventorySystem: Not enough objects"); + if (inventoryObjectData.numObjects > numObjectsToRemove) { + InventoryObject.setNumObjects(inventoryId, inventoryObjectData.numObjects - numObjectsToRemove); + } else { + Inventory.deleteRecord(inventoryId); + InventoryObject.deleteRecord(inventoryId); + } + } +} diff --git a/packages/base-world/src/systems/InventorySystem.sol b/packages/base-world/src/systems/InventorySystem.sol new file mode 100644 index 000000000..add37803d --- /dev/null +++ b/packages/base-world/src/systems/InventorySystem.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { IWorld } from "@tenet-base-world/src/codegen/world/IWorld.sol"; +import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { System } from "@latticexyz/world/src/System.sol"; +import { hasKey } from "@latticexyz/world/src/modules/haskeys/hasKey.sol"; + +import { OwnedBy, OwnedByTableId } from "@tenet-base-world/src/codegen/tables/OwnedBy.sol"; +import { Inventory, InventoryTableId } from "@tenet-base-world/src/codegen/tables/Inventory.sol"; +import { InventoryObject, InventoryObjectData } from "@tenet-base-world/src/codegen/tables/InventoryObject.sol"; +import { ObjectEntity } from "@tenet-base-world/src/codegen/tables/ObjectEntity.sol"; +import { Equipped } from "@tenet-base-world/src/codegen/tables/Equipped.sol"; + +import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; +import { inSurroundingCube } from "@tenet-utils/src/VoxelCoordUtils.sol"; +import { getEntityAtCoord, getVoxelCoord } from "@tenet-base-world/src/Utils.sol"; + +abstract contract InventorySystem is System { + function equip(bytes32 actingObjectEntityId, bytes32 inventoryId) public virtual { + require( + hasKey(OwnedByTableId, OwnedBy.encodeKeyTuple(actingObjectEntityId)), + "InventorySystem: entity has no owner" + ); + require(OwnedBy.get(actingObjectEntityId) == _msgSender(), "InventorySystem: caller does not own entity"); + + require(Inventory.get(inventoryId) == actingObjectEntityId, "InventorySystem: entity does not own inventory item"); + + Equipped.set(actingObjectEntityId, inventoryId); + } + + function unequip(bytes32 actingObjectEntityId) public virtual { + require( + hasKey(OwnedByTableId, OwnedBy.encodeKeyTuple(actingObjectEntityId)), + "InventorySystem: entity has no owner" + ); + require(OwnedBy.get(actingObjectEntityId) == _msgSender(), "InventorySystem: caller does not own entity"); + + Equipped.deleteRecord(actingObjectEntityId); + } + + function transfer( + bytes32 srcObjectEntityId, + VoxelCoord memory dstCoord, + bytes32 inventoryId, + uint8 transferAmount + ) public virtual { + require( + inSurroundingCube(getVoxelCoord(IStore(_world()), srcObjectEntityId), 1, dstCoord), + "InventorySystem: destination out of range" + ); + bytes32 dstEntityId = getEntityAtCoord(IStore(_world()), dstCoord); + if (dstEntityId == bytes32(0)) { + IWorld(_world()).buildTerrain(bytes32(0), dstCoord); + dstEntityId = getEntityAtCoord(IStore(_world()), dstCoord); + } + bytes32 dstObjectEntityId = ObjectEntity.get(dstEntityId); + require(dstObjectEntityId != bytes32(0), "InventorySystem: destination has no object entity"); + require(dstObjectEntityId != srcObjectEntityId, "InventorySystem: cannot transfer to self"); + + require(isValidSource(srcObjectEntityId), "InventorySystem: invalid source"); + require(isValidDestination(dstObjectEntityId), "InventorySystem: invalid destination"); + require(Inventory.get(inventoryId) == srcObjectEntityId, "InventorySystem: entity does not own inventory item"); + + InventoryObjectData memory inventoryObjectData = InventoryObject.get(inventoryId); + require(inventoryObjectData.numObjects >= transferAmount, "InventorySystem: insufficient inventory amount"); + + if (inventoryObjectData.numObjects == transferAmount) { + require(!IWorld(_world()).isInventoryFull(dstObjectEntityId), "InventorySystem: destination inventory is full"); + // transfer all + Inventory.set(inventoryId, dstObjectEntityId); + } else { + revert("InventorySystem: partial transfer not yet implemented"); + // TODO: implement partial transfer but keep durability + // IWorld(_world()).addObjectToInventory( + // dstObjectEntityId, + // inventoryObjectData.objectTypeId, + // transferAmount, + // abi.decode(inventoryObjectData.objectProperties, (ObjectProperties)) + // ); + // IWorld(_world()).removeObjectFromInventory(inventoryId, transferAmount); + } + } + + function isValidSource(bytes32 srcObjectEntityId) internal view virtual returns (bool); + + function isValidDestination(bytes32 dstObjectEntityId) internal view virtual returns (bool); +} diff --git a/packages/base-world/src/systems/ObjectInteractionSystem.sol b/packages/base-world/src/systems/ObjectInteractionSystem.sol index b4f21528c..a598dea90 100644 --- a/packages/base-world/src/systems/ObjectInteractionSystem.sol +++ b/packages/base-world/src/systems/ObjectInteractionSystem.sol @@ -12,10 +12,9 @@ import { VoxelCoord, EntityActionData, Action } from "@tenet-utils/src/Types.sol import { getEventHandlerSelector, getNeighbourEventHandlerSelector } from "@tenet-registry/src/Utils.sol"; import { getVonNeumannNeighbourEntities } from "@tenet-base-world/src/Utils.sol"; import { IWorldObjectEventSystem } from "@tenet-base-simulator/src/codegen/world/IWorldObjectEventSystem.sol"; +import { REGISTRY_ADDRESS } from "@tenet-base-world/src/Constants.sol"; abstract contract ObjectInteractionSystem is System { - function getRegistryAddress() internal pure virtual returns (address); - function getSimulatorAddress() internal pure virtual returns (address); function preRunInteraction(bytes32 centerObjectEntityId, bytes32[] memory neighbourObjectEntityIds) internal virtual { @@ -46,7 +45,7 @@ abstract contract ObjectInteractionSystem is System { return new Action[](0); } (address eventHandlerAddress, bytes4 eventHandlerSelector) = getEventHandlerSelector( - IStore(getRegistryAddress()), + IStore(REGISTRY_ADDRESS), centerObjectTypeId ); require( @@ -86,7 +85,7 @@ abstract contract ObjectInteractionSystem is System { bytes32 neighbourObjectTypeId = ObjectType.get(neighbourEntityIds[i]); (address neighbourEventHandlerAddress, bytes4 neighbourEventHandlerSelector) = getNeighbourEventHandlerSelector( - IStore(getRegistryAddress()), + IStore(REGISTRY_ADDRESS), neighbourObjectTypeId ); require( diff --git a/packages/base-world/src/systems/ObjectSystem.sol b/packages/base-world/src/systems/ObjectSystem.sol index ec733b358..40c890967 100644 --- a/packages/base-world/src/systems/ObjectSystem.sol +++ b/packages/base-world/src/systems/ObjectSystem.sol @@ -8,10 +8,9 @@ import { System } from "@latticexyz/world/src/System.sol"; import { VoxelCoord, ObjectProperties } from "@tenet-utils/src/Types.sol"; import { safeCall } from "@tenet-utils/src/CallUtils.sol"; import { getEnterWorldSelector, getExitWorldSelector } from "@tenet-registry/src/Utils.sol"; +import { REGISTRY_ADDRESS } from "@tenet-base-world/src/Constants.sol"; abstract contract ObjectSystem is System { - function getRegistryAddress() internal pure virtual returns (address); - function decodeToObjectProperties(bytes memory data) external pure returns (ObjectProperties memory) { return abi.decode(data, (ObjectProperties)); } @@ -22,7 +21,7 @@ abstract contract ObjectSystem is System { bytes32 objectEntityId ) public virtual returns (ObjectProperties memory requestedProperties) { (address objectAddress, bytes4 objectEnterWorldSelector) = getEnterWorldSelector( - IStore(getRegistryAddress()), + IStore(REGISTRY_ADDRESS), objectTypeId ); require( @@ -46,7 +45,7 @@ abstract contract ObjectSystem is System { function exitWorld(bytes32 objectTypeId, VoxelCoord memory coord, bytes32 objectEntityId) public virtual { (address objectAddress, bytes4 objectExitWorldSelector) = getEnterWorldSelector( - IStore(getRegistryAddress()), + IStore(REGISTRY_ADDRESS), objectTypeId ); require( diff --git a/packages/base-world/ts/mudConfig.ts b/packages/base-world/ts/mudConfig.ts index e27e45223..80667780c 100644 --- a/packages/base-world/ts/mudConfig.ts +++ b/packages/base-world/ts/mudConfig.ts @@ -85,9 +85,33 @@ const WORLD_TABLES: Record = { }, schema: { objectTypeId: "bytes32", + numObjects: "uint8", + numUsesLeft: "uint16", // 0 = infinite objectProperties: "bytes", // ObjectProperties }, }, + Equipped: { + registerAsRoot: true, + keySchema: { + objectEntityId: "bytes32", + }, + schema: { + inventoryId: "bytes32", + }, + }, + Recipes: { + registerAsRoot: true, + keySchema: { + recipeId: "bytes32", + }, + schema: { + inputObjectTypeIds: "bytes32[]", + inputObjectTypeAmounts: "uint8[]", + outputObjectTypeIds: "bytes32[]", + outputObjectTypeAmounts: "uint8[]", + outputObjectProperties: "bytes", // ObjectProperties[] + }, + }, AgentMetadata: { registerAsRoot: true, keySchema: { @@ -132,6 +156,12 @@ const WORLD_MODULES = [ root: true, args: [resolveTableId("OwnedBy")], }, + { + // TODO: This is only needed for tests, so we should remove it from production + name: "KeysInTableModule", + root: true, + args: [resolveTableId("Recipes")], + }, { name: "HasKeysModule", root: true, @@ -190,6 +220,22 @@ const WORLD_SYSTEMS = { openAccess: true, registerAsRoot: true, }, + InventorySystem: { + name: "InventorySystem", + openAccess: true, + registerAsRoot: true, + }, + CraftSystem: { + name: "CraftSystem", + openAccess: true, + registerAsRoot: true, + }, + InternalInventorySystem: { + name: "InternalInventor", + openAccess: false, + accessList: ["InventorySystem", "BuildSystem", "MineSystem", "MoveSystem", "ActivateSystem", "CraftSystem"], + registerAsRoot: true, + }, EventApprovalsSystem: { name: "EventApprovalSys", openAccess: false, diff --git a/packages/registry/.env b/packages/registry/.env index 130d11ecb..0f8cc4a30 100644 --- a/packages/registry/.env +++ b/packages/registry/.env @@ -5,4 +5,4 @@ # development. Please do not commit changes to this file! # # Anvil default private key: -PRIVATE_KEY=0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6 +PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 diff --git a/packages/registry/mud.config.ts b/packages/registry/mud.config.ts index 5fc4f7db8..901278832 100644 --- a/packages/registry/mud.config.ts +++ b/packages/registry/mud.config.ts @@ -14,8 +14,10 @@ export default mudConfig({ exitWorldSelector: "bytes4", eventHandlerSelector: "bytes4", neighbourEventHandlerSelector: "bytes4", + stackable: "uint8", + maxUses: "uint16", + damage: "uint16", name: "string", - description: "string", }, }, DecisionRuleRegistry: { diff --git a/packages/registry/src/Utils.sol b/packages/registry/src/Utils.sol index 652c090de..6c4a82dac 100644 --- a/packages/registry/src/Utils.sol +++ b/packages/registry/src/Utils.sol @@ -10,6 +10,14 @@ function getObjectAddress(IStore store, bytes32 objectTypeId) view returns (addr return ObjectTypeRegistry.getContractAddress(store, objectTypeId); } +function getStackable(IStore store, bytes32 objectTypeId) view returns (uint8) { + return ObjectTypeRegistry.getStackable(store, objectTypeId); +} + +function getMaxUses(IStore store, bytes32 objectTypeId) view returns (uint16) { + return ObjectTypeRegistry.getMaxUses(store, objectTypeId); +} + function getEnterWorldSelector(IStore store, bytes32 objectTypeId) view returns (address, bytes4) { return (getObjectAddress(store, objectTypeId), ObjectTypeRegistry.getEnterWorldSelector(store, objectTypeId)); } diff --git a/packages/registry/src/codegen/tables/ObjectTypeRegistry.sol b/packages/registry/src/codegen/tables/ObjectTypeRegistry.sol index f0a1e5f01..1dcb50d9c 100644 --- a/packages/registry/src/codegen/tables/ObjectTypeRegistry.sol +++ b/packages/registry/src/codegen/tables/ObjectTypeRegistry.sol @@ -27,8 +27,10 @@ struct ObjectTypeRegistryData { bytes4 exitWorldSelector; bytes4 eventHandlerSelector; bytes4 neighbourEventHandlerSelector; + uint8 stackable; + uint16 maxUses; + uint16 damage; string name; - string description; } library ObjectTypeRegistry { @@ -42,15 +44,17 @@ library ObjectTypeRegistry { /** Get the table's value schema */ function getValueSchema() internal pure returns (Schema) { - SchemaType[] memory _schema = new SchemaType[](8); + SchemaType[] memory _schema = new SchemaType[](10); _schema[0] = SchemaType.ADDRESS; _schema[1] = SchemaType.ADDRESS; _schema[2] = SchemaType.BYTES4; _schema[3] = SchemaType.BYTES4; _schema[4] = SchemaType.BYTES4; _schema[5] = SchemaType.BYTES4; - _schema[6] = SchemaType.STRING; - _schema[7] = SchemaType.STRING; + _schema[6] = SchemaType.UINT8; + _schema[7] = SchemaType.UINT16; + _schema[8] = SchemaType.UINT16; + _schema[9] = SchemaType.STRING; return SchemaLib.encode(_schema); } @@ -63,15 +67,17 @@ library ObjectTypeRegistry { /** Get the table's field names */ function getFieldNames() internal pure returns (string[] memory fieldNames) { - fieldNames = new string[](8); + fieldNames = new string[](10); fieldNames[0] = "creator"; fieldNames[1] = "contractAddress"; fieldNames[2] = "enterWorldSelector"; fieldNames[3] = "exitWorldSelector"; fieldNames[4] = "eventHandlerSelector"; fieldNames[5] = "neighbourEventHandlerSelector"; - fieldNames[6] = "name"; - fieldNames[7] = "description"; + fieldNames[6] = "stackable"; + fieldNames[7] = "maxUses"; + fieldNames[8] = "damage"; + fieldNames[9] = "name"; } /** Register the table's key schema, value schema, key names and value names */ @@ -303,216 +309,169 @@ library ObjectTypeRegistry { _store.setField(_tableId, _keyTuple, 5, abi.encodePacked((neighbourEventHandlerSelector)), getValueSchema()); } - /** Get name */ - function getName(bytes32 objectTypeId) internal view returns (string memory name) { + /** Get stackable */ + function getStackable(bytes32 objectTypeId) internal view returns (uint8 stackable) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 6, getValueSchema()); - return (string(_blob)); + return (uint8(Bytes.slice1(_blob, 0))); } - /** Get name (using the specified store) */ - function getName(IStore _store, bytes32 objectTypeId) internal view returns (string memory name) { + /** Get stackable (using the specified store) */ + function getStackable(IStore _store, bytes32 objectTypeId) internal view returns (uint8 stackable) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; bytes memory _blob = _store.getField(_tableId, _keyTuple, 6, getValueSchema()); - return (string(_blob)); + return (uint8(Bytes.slice1(_blob, 0))); } - /** Set name */ - function setName(bytes32 objectTypeId, string memory name) internal { + /** Set stackable */ + function setStackable(bytes32 objectTypeId, uint8 stackable) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - StoreSwitch.setField(_tableId, _keyTuple, 6, bytes((name)), getValueSchema()); + StoreSwitch.setField(_tableId, _keyTuple, 6, abi.encodePacked((stackable)), getValueSchema()); } - /** Set name (using the specified store) */ - function setName(IStore _store, bytes32 objectTypeId, string memory name) internal { + /** Set stackable (using the specified store) */ + function setStackable(IStore _store, bytes32 objectTypeId, uint8 stackable) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - _store.setField(_tableId, _keyTuple, 6, bytes((name)), getValueSchema()); + _store.setField(_tableId, _keyTuple, 6, abi.encodePacked((stackable)), getValueSchema()); } - /** Get the length of name */ - function lengthName(bytes32 objectTypeId) internal view returns (uint256) { + /** Get maxUses */ + function getMaxUses(bytes32 objectTypeId) internal view returns (uint16 maxUses) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 6, getValueSchema()); - unchecked { - return _byteLength / 1; - } + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 7, getValueSchema()); + return (uint16(Bytes.slice2(_blob, 0))); } - /** Get the length of name (using the specified store) */ - function lengthName(IStore _store, bytes32 objectTypeId) internal view returns (uint256) { + /** Get maxUses (using the specified store) */ + function getMaxUses(IStore _store, bytes32 objectTypeId) internal view returns (uint16 maxUses) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 6, getValueSchema()); - unchecked { - return _byteLength / 1; - } + bytes memory _blob = _store.getField(_tableId, _keyTuple, 7, getValueSchema()); + return (uint16(Bytes.slice2(_blob, 0))); } - /** - * Get an item of name - * (unchecked, returns invalid data if index overflows) - */ - function getItemName(bytes32 objectTypeId, uint256 _index) internal view returns (string memory) { + /** Set maxUses */ + function setMaxUses(bytes32 objectTypeId, uint16 maxUses) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - unchecked { - bytes memory _blob = StoreSwitch.getFieldSlice( - _tableId, - _keyTuple, - 6, - getValueSchema(), - _index * 1, - (_index + 1) * 1 - ); - return (string(_blob)); - } + StoreSwitch.setField(_tableId, _keyTuple, 7, abi.encodePacked((maxUses)), getValueSchema()); } - /** - * Get an item of name (using the specified store) - * (unchecked, returns invalid data if index overflows) - */ - function getItemName(IStore _store, bytes32 objectTypeId, uint256 _index) internal view returns (string memory) { + /** Set maxUses (using the specified store) */ + function setMaxUses(IStore _store, bytes32 objectTypeId, uint16 maxUses) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - unchecked { - bytes memory _blob = _store.getFieldSlice(_tableId, _keyTuple, 6, getValueSchema(), _index * 1, (_index + 1) * 1); - return (string(_blob)); - } + _store.setField(_tableId, _keyTuple, 7, abi.encodePacked((maxUses)), getValueSchema()); } - /** Push a slice to name */ - function pushName(bytes32 objectTypeId, string memory _slice) internal { + /** Get damage */ + function getDamage(bytes32 objectTypeId) internal view returns (uint16 damage) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - StoreSwitch.pushToField(_tableId, _keyTuple, 6, bytes((_slice)), getValueSchema()); + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 8, getValueSchema()); + return (uint16(Bytes.slice2(_blob, 0))); } - /** Push a slice to name (using the specified store) */ - function pushName(IStore _store, bytes32 objectTypeId, string memory _slice) internal { + /** Get damage (using the specified store) */ + function getDamage(IStore _store, bytes32 objectTypeId) internal view returns (uint16 damage) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - _store.pushToField(_tableId, _keyTuple, 6, bytes((_slice)), getValueSchema()); + bytes memory _blob = _store.getField(_tableId, _keyTuple, 8, getValueSchema()); + return (uint16(Bytes.slice2(_blob, 0))); } - /** Pop a slice from name */ - function popName(bytes32 objectTypeId) internal { + /** Set damage */ + function setDamage(bytes32 objectTypeId, uint16 damage) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - StoreSwitch.popFromField(_tableId, _keyTuple, 6, 1, getValueSchema()); + StoreSwitch.setField(_tableId, _keyTuple, 8, abi.encodePacked((damage)), getValueSchema()); } - /** Pop a slice from name (using the specified store) */ - function popName(IStore _store, bytes32 objectTypeId) internal { + /** Set damage (using the specified store) */ + function setDamage(IStore _store, bytes32 objectTypeId, uint16 damage) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - _store.popFromField(_tableId, _keyTuple, 6, 1, getValueSchema()); + _store.setField(_tableId, _keyTuple, 8, abi.encodePacked((damage)), getValueSchema()); } - /** - * Update a slice of name at `_index` - * (checked only to prevent modifying other tables; can corrupt own data if index overflows) - */ - function updateName(bytes32 objectTypeId, uint256 _index, string memory _slice) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = objectTypeId; - - unchecked { - StoreSwitch.updateInField(_tableId, _keyTuple, 6, _index * 1, bytes((_slice)), getValueSchema()); - } - } - - /** - * Update a slice of name (using the specified store) at `_index` - * (checked only to prevent modifying other tables; can corrupt own data if index overflows) - */ - function updateName(IStore _store, bytes32 objectTypeId, uint256 _index, string memory _slice) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = objectTypeId; - - unchecked { - _store.updateInField(_tableId, _keyTuple, 6, _index * 1, bytes((_slice)), getValueSchema()); - } - } - - /** Get description */ - function getDescription(bytes32 objectTypeId) internal view returns (string memory description) { + /** Get name */ + function getName(bytes32 objectTypeId) internal view returns (string memory name) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 7, getValueSchema()); + bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 9, getValueSchema()); return (string(_blob)); } - /** Get description (using the specified store) */ - function getDescription(IStore _store, bytes32 objectTypeId) internal view returns (string memory description) { + /** Get name (using the specified store) */ + function getName(IStore _store, bytes32 objectTypeId) internal view returns (string memory name) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - bytes memory _blob = _store.getField(_tableId, _keyTuple, 7, getValueSchema()); + bytes memory _blob = _store.getField(_tableId, _keyTuple, 9, getValueSchema()); return (string(_blob)); } - /** Set description */ - function setDescription(bytes32 objectTypeId, string memory description) internal { + /** Set name */ + function setName(bytes32 objectTypeId, string memory name) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - StoreSwitch.setField(_tableId, _keyTuple, 7, bytes((description)), getValueSchema()); + StoreSwitch.setField(_tableId, _keyTuple, 9, bytes((name)), getValueSchema()); } - /** Set description (using the specified store) */ - function setDescription(IStore _store, bytes32 objectTypeId, string memory description) internal { + /** Set name (using the specified store) */ + function setName(IStore _store, bytes32 objectTypeId, string memory name) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - _store.setField(_tableId, _keyTuple, 7, bytes((description)), getValueSchema()); + _store.setField(_tableId, _keyTuple, 9, bytes((name)), getValueSchema()); } - /** Get the length of description */ - function lengthDescription(bytes32 objectTypeId) internal view returns (uint256) { + /** Get the length of name */ + function lengthName(bytes32 objectTypeId) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 7, getValueSchema()); + uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 9, getValueSchema()); unchecked { return _byteLength / 1; } } - /** Get the length of description (using the specified store) */ - function lengthDescription(IStore _store, bytes32 objectTypeId) internal view returns (uint256) { + /** Get the length of name (using the specified store) */ + function lengthName(IStore _store, bytes32 objectTypeId) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 7, getValueSchema()); + uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 9, getValueSchema()); unchecked { return _byteLength / 1; } } /** - * Get an item of description + * Get an item of name * (unchecked, returns invalid data if index overflows) */ - function getItemDescription(bytes32 objectTypeId, uint256 _index) internal view returns (string memory) { + function getItemName(bytes32 objectTypeId, uint256 _index) internal view returns (string memory) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; @@ -520,7 +479,7 @@ library ObjectTypeRegistry { bytes memory _blob = StoreSwitch.getFieldSlice( _tableId, _keyTuple, - 7, + 9, getValueSchema(), _index * 1, (_index + 1) * 1 @@ -530,78 +489,74 @@ library ObjectTypeRegistry { } /** - * Get an item of description (using the specified store) + * Get an item of name (using the specified store) * (unchecked, returns invalid data if index overflows) */ - function getItemDescription( - IStore _store, - bytes32 objectTypeId, - uint256 _index - ) internal view returns (string memory) { + function getItemName(IStore _store, bytes32 objectTypeId, uint256 _index) internal view returns (string memory) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; unchecked { - bytes memory _blob = _store.getFieldSlice(_tableId, _keyTuple, 7, getValueSchema(), _index * 1, (_index + 1) * 1); + bytes memory _blob = _store.getFieldSlice(_tableId, _keyTuple, 9, getValueSchema(), _index * 1, (_index + 1) * 1); return (string(_blob)); } } - /** Push a slice to description */ - function pushDescription(bytes32 objectTypeId, string memory _slice) internal { + /** Push a slice to name */ + function pushName(bytes32 objectTypeId, string memory _slice) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - StoreSwitch.pushToField(_tableId, _keyTuple, 7, bytes((_slice)), getValueSchema()); + StoreSwitch.pushToField(_tableId, _keyTuple, 9, bytes((_slice)), getValueSchema()); } - /** Push a slice to description (using the specified store) */ - function pushDescription(IStore _store, bytes32 objectTypeId, string memory _slice) internal { + /** Push a slice to name (using the specified store) */ + function pushName(IStore _store, bytes32 objectTypeId, string memory _slice) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - _store.pushToField(_tableId, _keyTuple, 7, bytes((_slice)), getValueSchema()); + _store.pushToField(_tableId, _keyTuple, 9, bytes((_slice)), getValueSchema()); } - /** Pop a slice from description */ - function popDescription(bytes32 objectTypeId) internal { + /** Pop a slice from name */ + function popName(bytes32 objectTypeId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - StoreSwitch.popFromField(_tableId, _keyTuple, 7, 1, getValueSchema()); + StoreSwitch.popFromField(_tableId, _keyTuple, 9, 1, getValueSchema()); } - /** Pop a slice from description (using the specified store) */ - function popDescription(IStore _store, bytes32 objectTypeId) internal { + /** Pop a slice from name (using the specified store) */ + function popName(IStore _store, bytes32 objectTypeId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; - _store.popFromField(_tableId, _keyTuple, 7, 1, getValueSchema()); + _store.popFromField(_tableId, _keyTuple, 9, 1, getValueSchema()); } /** - * Update a slice of description at `_index` + * Update a slice of name at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function updateDescription(bytes32 objectTypeId, uint256 _index, string memory _slice) internal { + function updateName(bytes32 objectTypeId, uint256 _index, string memory _slice) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; unchecked { - StoreSwitch.updateInField(_tableId, _keyTuple, 7, _index * 1, bytes((_slice)), getValueSchema()); + StoreSwitch.updateInField(_tableId, _keyTuple, 9, _index * 1, bytes((_slice)), getValueSchema()); } } /** - * Update a slice of description (using the specified store) at `_index` + * Update a slice of name (using the specified store) at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function updateDescription(IStore _store, bytes32 objectTypeId, uint256 _index, string memory _slice) internal { + function updateName(IStore _store, bytes32 objectTypeId, uint256 _index, string memory _slice) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = objectTypeId; unchecked { - _store.updateInField(_tableId, _keyTuple, 7, _index * 1, bytes((_slice)), getValueSchema()); + _store.updateInField(_tableId, _keyTuple, 9, _index * 1, bytes((_slice)), getValueSchema()); } } @@ -632,8 +587,10 @@ library ObjectTypeRegistry { bytes4 exitWorldSelector, bytes4 eventHandlerSelector, bytes4 neighbourEventHandlerSelector, - string memory name, - string memory description + uint8 stackable, + uint16 maxUses, + uint16 damage, + string memory name ) internal { bytes memory _data = encode( creator, @@ -642,8 +599,10 @@ library ObjectTypeRegistry { exitWorldSelector, eventHandlerSelector, neighbourEventHandlerSelector, - name, - description + stackable, + maxUses, + damage, + name ); bytes32[] memory _keyTuple = new bytes32[](1); @@ -662,8 +621,10 @@ library ObjectTypeRegistry { bytes4 exitWorldSelector, bytes4 eventHandlerSelector, bytes4 neighbourEventHandlerSelector, - string memory name, - string memory description + uint8 stackable, + uint16 maxUses, + uint16 damage, + string memory name ) internal { bytes memory _data = encode( creator, @@ -672,8 +633,10 @@ library ObjectTypeRegistry { exitWorldSelector, eventHandlerSelector, neighbourEventHandlerSelector, - name, - description + stackable, + maxUses, + damage, + name ); bytes32[] memory _keyTuple = new bytes32[](1); @@ -692,8 +655,10 @@ library ObjectTypeRegistry { _table.exitWorldSelector, _table.eventHandlerSelector, _table.neighbourEventHandlerSelector, - _table.name, - _table.description + _table.stackable, + _table.maxUses, + _table.damage, + _table.name ); } @@ -708,8 +673,10 @@ library ObjectTypeRegistry { _table.exitWorldSelector, _table.eventHandlerSelector, _table.neighbourEventHandlerSelector, - _table.name, - _table.description + _table.stackable, + _table.maxUses, + _table.damage, + _table.name ); } @@ -718,8 +685,8 @@ library ObjectTypeRegistry { * Undefined behaviour for invalid blobs. */ function decode(bytes memory _blob) internal pure returns (ObjectTypeRegistryData memory _table) { - // 56 is the total byte length of static data - PackedCounter _encodedLengths = PackedCounter.wrap(Bytes.slice32(_blob, 56)); + // 61 is the total byte length of static data + PackedCounter _encodedLengths = PackedCounter.wrap(Bytes.slice32(_blob, 61)); _table.creator = (address(Bytes.slice20(_blob, 0))); @@ -733,21 +700,21 @@ library ObjectTypeRegistry { _table.neighbourEventHandlerSelector = (Bytes.slice4(_blob, 52)); + _table.stackable = (uint8(Bytes.slice1(_blob, 56))); + + _table.maxUses = (uint16(Bytes.slice2(_blob, 57))); + + _table.damage = (uint16(Bytes.slice2(_blob, 59))); + // Store trims the blob if dynamic fields are all empty - if (_blob.length > 56) { + if (_blob.length > 61) { // skip static data length + dynamic lengths word - uint256 _start = 88; + uint256 _start = 93; uint256 _end; unchecked { - _end = 88 + _encodedLengths.atIndex(0); + _end = 93 + _encodedLengths.atIndex(0); } _table.name = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); - - _start = _end; - unchecked { - _end += _encodedLengths.atIndex(1); - } - _table.description = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); } } @@ -759,13 +726,15 @@ library ObjectTypeRegistry { bytes4 exitWorldSelector, bytes4 eventHandlerSelector, bytes4 neighbourEventHandlerSelector, - string memory name, - string memory description + uint8 stackable, + uint16 maxUses, + uint16 damage, + string memory name ) internal pure returns (bytes memory) { PackedCounter _encodedLengths; // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { - _encodedLengths = PackedCounterLib.pack(bytes(name).length, bytes(description).length); + _encodedLengths = PackedCounterLib.pack(bytes(name).length); } return @@ -776,9 +745,11 @@ library ObjectTypeRegistry { exitWorldSelector, eventHandlerSelector, neighbourEventHandlerSelector, + stackable, + maxUses, + damage, _encodedLengths.unwrap(), - bytes((name)), - bytes((description)) + bytes((name)) ); } diff --git a/packages/registry/src/codegen/world/IObjectRegistrySystem.sol b/packages/registry/src/codegen/world/IObjectRegistrySystem.sol index 21535e717..be4ce36a0 100644 --- a/packages/registry/src/codegen/world/IObjectRegistrySystem.sol +++ b/packages/registry/src/codegen/world/IObjectRegistrySystem.sol @@ -11,7 +11,9 @@ interface IObjectRegistrySystem { bytes4 exitWorldSelector, bytes4 eventHandlerSelector, bytes4 neighbourEventHandlerSelector, - string memory name, - string memory description + uint8 stackable, + uint16 maxUses, + uint16 damage, + string memory name ) external; } diff --git a/packages/registry/src/systems/ObjectRegistrySystem.sol b/packages/registry/src/systems/ObjectRegistrySystem.sol index df6db29f2..d914d240c 100644 --- a/packages/registry/src/systems/ObjectRegistrySystem.sol +++ b/packages/registry/src/systems/ObjectRegistrySystem.sol @@ -13,8 +13,10 @@ contract ObjectRegistrySystem is System { bytes4 exitWorldSelector, bytes4 eventHandlerSelector, bytes4 neighbourEventHandlerSelector, - string memory name, - string memory description + uint8 stackable, + uint16 maxUses, + uint16 damage, + string memory name ) public { require( !hasKey(ObjectTypeRegistryTableId, ObjectTypeRegistry.encodeKeyTuple(objectTypeId)), @@ -33,8 +35,10 @@ contract ObjectRegistrySystem is System { exitWorldSelector: exitWorldSelector, eventHandlerSelector: eventHandlerSelector, neighbourEventHandlerSelector: neighbourEventHandlerSelector, - name: name, - description: description + stackable: stackable, + maxUses: maxUses, + damage: damage, + name: name }) ); } diff --git a/packages/utils/src/ArrayUtils.sol b/packages/utils/src/ArrayUtils.sol index 9f1707820..15688863c 100644 --- a/packages/utils/src/ArrayUtils.sol +++ b/packages/utils/src/ArrayUtils.sol @@ -10,7 +10,15 @@ function hasEntity(bytes32[] memory entities) pure returns (bool) { return false; } -function initializeArray(uint256 x, uint256 y) pure returns (uint256[][] memory) { +function initializeBytes32Array(uint256 x, uint256 y) pure returns (bytes32[][] memory) { + bytes32[][] memory arr = new bytes32[][](x); + for (uint256 i; i < x; i++) { + arr[i] = new bytes32[](y); + } + return arr; +} + +function initializeUint256Array(uint256 x, uint256 y) pure returns (uint256[][] memory) { uint256[][] memory arr = new uint256[][](x); for (uint256 i; i < x; i++) { arr[i] = new uint256[](y);