diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 3dbac8bb..24f5ee29 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1869,6 +1869,7 @@ Config saving Structure data saving Validate race data Shuffle entity data package +Rename structure -> virtualstructure diff --git a/src/main/java/electrosphere/server/ai/nodes/actions/move/FaceTargetNode.java b/src/main/java/electrosphere/server/ai/nodes/actions/move/FaceTargetNode.java index 57603678..256538be 100644 --- a/src/main/java/electrosphere/server/ai/nodes/actions/move/FaceTargetNode.java +++ b/src/main/java/electrosphere/server/ai/nodes/actions/move/FaceTargetNode.java @@ -9,7 +9,7 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.server.ai.blackboard.Blackboard; import electrosphere.server.ai.nodes.AITreeNode; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.util.math.SpatialMathUtils; /** @@ -41,8 +41,8 @@ public class FaceTargetNode implements AITreeNode { targetPos = (Vector3d)targetRaw; } else if(targetRaw instanceof Entity){ targetPos = EntityUtils.getPosition((Entity)targetRaw); - } else if(targetRaw instanceof Structure){ - targetPos = ((Structure)targetRaw).getPos(); + } else if(targetRaw instanceof VirtualStructure){ + targetPos = ((VirtualStructure)targetRaw).getPos(); } else { throw new Error("Unsupported target type " + targetRaw); } diff --git a/src/main/java/electrosphere/server/ai/nodes/checks/macro/HasShelter.java b/src/main/java/electrosphere/server/ai/nodes/checks/macro/HasShelter.java index c243ac1d..999f2953 100644 --- a/src/main/java/electrosphere/server/ai/nodes/checks/macro/HasShelter.java +++ b/src/main/java/electrosphere/server/ai/nodes/checks/macro/HasShelter.java @@ -8,7 +8,7 @@ import electrosphere.server.ai.nodes.AITreeNode; import electrosphere.server.datacell.Realm; import electrosphere.server.macro.character.Character; import electrosphere.server.macro.character.CharacterUtils; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; /** * Checks if the character has shelter @@ -23,7 +23,7 @@ public class HasShelter implements AITreeNode { if(character == null){ throw new Error("Character is null"); } - Structure shelter = CharacterUtils.getShelter(realm.getMacroData(),character); + VirtualStructure shelter = CharacterUtils.getShelter(realm.getMacroData(),character); if(shelter == null){ return AITreeNodeResult.FAILURE; } diff --git a/src/main/java/electrosphere/server/ai/nodes/checks/spatial/BeginStructureNode.java b/src/main/java/electrosphere/server/ai/nodes/checks/spatial/BeginStructureNode.java index 70aa0eff..874c73a2 100644 --- a/src/main/java/electrosphere/server/ai/nodes/checks/spatial/BeginStructureNode.java +++ b/src/main/java/electrosphere/server/ai/nodes/checks/spatial/BeginStructureNode.java @@ -12,7 +12,7 @@ import electrosphere.server.ai.blackboard.BlackboardKeys; import electrosphere.server.ai.nodes.AITreeNode; import electrosphere.server.datacell.Realm; import electrosphere.server.macro.MacroData; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.server.macro.utils.StructurePlacementUtils; import electrosphere.util.FileUtils; @@ -46,7 +46,7 @@ public class BeginStructureNode implements AITreeNode { Vector3d placementPos = StructurePlacementUtils.getPlacementPosition(macroData, structureData, position); //add to macro data - Structure struct = Structure.createStructure(macroData, structureData, placementPos); + VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, placementPos); struct.setRepairable(true); struct.setFab(BlockFab.read(FileUtils.getAssetFile(struct.getFabPath()))); // macroData.getStructures().add(struct); @@ -61,7 +61,7 @@ public class BeginStructureNode implements AITreeNode { * @param blackboard The blackboard * @param structure The structure to target */ - public static void setStructureTarget(Blackboard blackboard, Structure structure){ + public static void setStructureTarget(Blackboard blackboard, VirtualStructure structure){ blackboard.put(BlackboardKeys.STRUCTURE_TARGET, structure); } @@ -78,8 +78,8 @@ public class BeginStructureNode implements AITreeNode { * @param blackboard The blackboard * @return The structure if it exists, null otherwise */ - public static Structure getStructureTarget(Blackboard blackboard){ - return (Structure)blackboard.get(BlackboardKeys.STRUCTURE_TARGET); + public static VirtualStructure getStructureTarget(Blackboard blackboard){ + return (VirtualStructure)blackboard.get(BlackboardKeys.STRUCTURE_TARGET); } /** diff --git a/src/main/java/electrosphere/server/ai/nodes/checks/spatial/TargetRangeCheckNode.java b/src/main/java/electrosphere/server/ai/nodes/checks/spatial/TargetRangeCheckNode.java index 553f6850..b88cf643 100644 --- a/src/main/java/electrosphere/server/ai/nodes/checks/spatial/TargetRangeCheckNode.java +++ b/src/main/java/electrosphere/server/ai/nodes/checks/spatial/TargetRangeCheckNode.java @@ -6,7 +6,7 @@ import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; import electrosphere.server.ai.blackboard.Blackboard; import electrosphere.server.ai.nodes.AITreeNode; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; /** * Checks if the target is inside a given range of the entity @@ -44,8 +44,8 @@ public class TargetRangeCheckNode implements AITreeNode { targetPos = (Vector3d)targetRaw; } else if(targetRaw instanceof Entity){ targetPos = EntityUtils.getPosition((Entity)targetRaw); - } else if(targetRaw instanceof Structure){ - targetPos = ((Structure)targetRaw).getPos(); + } else if(targetRaw instanceof VirtualStructure){ + targetPos = ((VirtualStructure)targetRaw).getPos(); } else { throw new Error("Unsupported target type " + targetRaw); } diff --git a/src/main/java/electrosphere/server/ai/nodes/macro/MacroCharacterGoalNode.java b/src/main/java/electrosphere/server/ai/nodes/macro/MacroCharacterGoalNode.java index 17022bd4..6278a2f9 100644 --- a/src/main/java/electrosphere/server/ai/nodes/macro/MacroCharacterGoalNode.java +++ b/src/main/java/electrosphere/server/ai/nodes/macro/MacroCharacterGoalNode.java @@ -12,7 +12,7 @@ import electrosphere.server.ai.nodes.checks.spatial.BeginStructureNode; import electrosphere.server.macro.character.Character; import electrosphere.server.macro.character.goal.CharacterGoal; import electrosphere.server.macro.character.goal.CharacterGoal.CharacterGoalType; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; /** * Node for interacting with macro character goals @@ -72,10 +72,10 @@ public class MacroCharacterGoalNode implements AITreeNode { } break; case BUILD_STRUCTURE: { Object targetRaw = goal.getTarget(); - if(!(targetRaw instanceof Structure)){ + if(!(targetRaw instanceof VirtualStructure)){ return AITreeNodeResult.FAILURE; } - BeginStructureNode.setStructureTarget(blackboard, (Structure)goal.getTarget()); + BeginStructureNode.setStructureTarget(blackboard, (VirtualStructure)goal.getTarget()); } break; case ACQUIRE_ITEM: { Object targetRaw = goal.getTarget(); diff --git a/src/main/java/electrosphere/server/ai/nodes/plan/PathfindingNode.java b/src/main/java/electrosphere/server/ai/nodes/plan/PathfindingNode.java index ea17c268..082cb440 100644 --- a/src/main/java/electrosphere/server/ai/nodes/plan/PathfindingNode.java +++ b/src/main/java/electrosphere/server/ai/nodes/plan/PathfindingNode.java @@ -11,7 +11,7 @@ import electrosphere.server.ai.blackboard.BlackboardKeys; import electrosphere.server.ai.nodes.AITreeNode; import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.interfaces.PathfindingManager; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.server.pathfinding.recast.PathingProgressiveData; /** @@ -61,8 +61,8 @@ public class PathfindingNode implements AITreeNode { targetPos = (Vector3d)targetRaw; } else if(targetRaw instanceof Entity){ targetPos = EntityUtils.getPosition((Entity)targetRaw); - } else if(targetRaw instanceof Structure){ - targetPos = ((Structure)targetRaw).getPos(); + } else if(targetRaw instanceof VirtualStructure){ + targetPos = ((VirtualStructure)targetRaw).getPos(); } else { throw new Error("Unsupported target type " + targetRaw); } @@ -83,8 +83,8 @@ public class PathfindingNode implements AITreeNode { targetPos = (Vector3d)targetRaw; } else if(targetRaw instanceof Entity){ targetPos = EntityUtils.getPosition((Entity)targetRaw); - } else if(targetRaw instanceof Structure){ - targetPos = ((Structure)targetRaw).getPos(); + } else if(targetRaw instanceof VirtualStructure){ + targetPos = ((VirtualStructure)targetRaw).getPos(); } else { throw new Error("Unsupported target type " + targetRaw); } @@ -143,8 +143,8 @@ public class PathfindingNode implements AITreeNode { targetPos = (Vector3d)targetRaw; } else if(targetRaw instanceof Entity){ targetPos = EntityUtils.getPosition((Entity)targetRaw); - } else if(targetRaw instanceof Structure){ - targetPos = ((Structure)targetRaw).getPos(); + } else if(targetRaw instanceof VirtualStructure){ + targetPos = ((VirtualStructure)targetRaw).getPos(); } else { throw new Error("Unsupported target type " + targetRaw); } diff --git a/src/main/java/electrosphere/server/ai/nodes/solvers/SolveBuildMaterialNode.java b/src/main/java/electrosphere/server/ai/nodes/solvers/SolveBuildMaterialNode.java index ed35907d..23955165 100644 --- a/src/main/java/electrosphere/server/ai/nodes/solvers/SolveBuildMaterialNode.java +++ b/src/main/java/electrosphere/server/ai/nodes/solvers/SolveBuildMaterialNode.java @@ -15,7 +15,7 @@ import electrosphere.server.ai.nodes.AITreeNode; import electrosphere.server.ai.nodes.checks.spatial.BeginStructureNode; import electrosphere.server.ai.trees.struct.BuildStructureTree; import electrosphere.server.datacell.Realm; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.server.macro.utils.StructureRepairUtils; /** @@ -26,7 +26,7 @@ public class SolveBuildMaterialNode implements AITreeNode { @Override public AITreeNodeResult evaluate(Entity entity, Blackboard blackboard) { if(!BuildStructureTree.hasCurrentMaterial(blackboard)){ - Structure struct = BeginStructureNode.getStructureTarget(blackboard); + VirtualStructure struct = BeginStructureNode.getStructureTarget(blackboard); if(!struct.isRepairable()){ return AITreeNodeResult.FAILURE; } diff --git a/src/main/java/electrosphere/server/macro/MacroData.java b/src/main/java/electrosphere/server/macro/MacroData.java index 32acc0b0..bb8e784b 100644 --- a/src/main/java/electrosphere/server/macro/MacroData.java +++ b/src/main/java/electrosphere/server/macro/MacroData.java @@ -12,7 +12,7 @@ import electrosphere.server.macro.civilization.Civilization; import electrosphere.server.macro.race.Race; import electrosphere.server.macro.race.RaceMap; import electrosphere.server.macro.spatial.MacroAreaObject; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.server.macro.town.Town; import electrosphere.util.FileUtils; @@ -46,7 +46,7 @@ public class MacroData { /** * List of structures */ - List structures = new LinkedList(); + List structures = new LinkedList(); /** * Generates a world @@ -201,7 +201,7 @@ public class MacroData { * Gets the list of structures * @return The list of structures */ - public List getStructures(){ + public List getStructures(){ return structures; } @@ -210,8 +210,8 @@ public class MacroData { * @param id The id of the structure * @return The structure if it exists, null otherwise */ - public Structure getStructure(int id){ - for(Structure struct : structures){ + public VirtualStructure getStructure(int id){ + for(VirtualStructure struct : structures){ if(struct.getId() == id){ return struct; } @@ -223,7 +223,7 @@ public class MacroData { * Adds a structure * @param structure The structure */ - public void addStructure(Structure structure){ + public void addStructure(VirtualStructure structure){ structures.add(structure); } diff --git a/src/main/java/electrosphere/server/macro/MacroDataLoader.java b/src/main/java/electrosphere/server/macro/MacroDataLoader.java index f916a429..fafe7947 100644 --- a/src/main/java/electrosphere/server/macro/MacroDataLoader.java +++ b/src/main/java/electrosphere/server/macro/MacroDataLoader.java @@ -3,7 +3,7 @@ package electrosphere.server.macro; import java.io.File; import electrosphere.data.block.fab.BlockFab; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.util.FileUtils; /** @@ -21,7 +21,7 @@ public class MacroDataLoader { MacroData rVal = FileUtils.loadObjectFromSavePath(saveName, "macro.json", MacroData.class); //preload and assign structure fabs - for(Structure structure : rVal.getStructures()){ + for(VirtualStructure structure : rVal.getStructures()){ File fabFile = FileUtils.getAssetFile(structure.getFabPath()); if(!fabFile.exists()){ throw new Error("Failed to locate structure that does not exist! " + fabFile.getAbsolutePath()); diff --git a/src/main/java/electrosphere/server/macro/character/CharacterUtils.java b/src/main/java/electrosphere/server/macro/character/CharacterUtils.java index a0666ea7..2c5b393a 100644 --- a/src/main/java/electrosphere/server/macro/character/CharacterUtils.java +++ b/src/main/java/electrosphere/server/macro/character/CharacterUtils.java @@ -11,7 +11,7 @@ import electrosphere.server.macro.character.data.CharacterAssociatedId; import electrosphere.server.macro.character.data.CharacterDataStrings; import electrosphere.server.macro.character.diety.Diety; import electrosphere.server.macro.race.Race; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.server.macro.town.Town; import electrosphere.server.service.CharacterService; @@ -48,7 +48,7 @@ public class CharacterUtils { * @param character The character * @param shelter The shelter */ - public static void addShelter(Character character, Structure shelter){ + public static void addShelter(Character character, VirtualStructure shelter){ character.putData(CharacterDataStrings.SHELTER, new CharacterAssociatedId(CharacterDataStrings.SHELTER, shelter.getId())); } @@ -58,7 +58,7 @@ public class CharacterUtils { * @param character The character * @return The shelter if it exists, null otherwise */ - public static Structure getShelter(MacroData macroData, Character character){ + public static VirtualStructure getShelter(MacroData macroData, Character character){ if(!character.containsKey(CharacterDataStrings.SHELTER)){ return null; } diff --git a/src/main/java/electrosphere/server/macro/structure/Structure.java b/src/main/java/electrosphere/server/macro/structure/VirtualStructure.java similarity index 92% rename from src/main/java/electrosphere/server/macro/structure/Structure.java rename to src/main/java/electrosphere/server/macro/structure/VirtualStructure.java index 3d464968..6d428d3f 100644 --- a/src/main/java/electrosphere/server/macro/structure/Structure.java +++ b/src/main/java/electrosphere/server/macro/structure/VirtualStructure.java @@ -12,7 +12,7 @@ import electrosphere.util.annotation.Exclude; /** * Server representation of a structure */ -public class Structure implements MacroAreaObject { +public class VirtualStructure implements MacroAreaObject { /** * The id of the structure @@ -57,8 +57,8 @@ public class Structure implements MacroAreaObject { * @param position The position * @return The structure */ - public static Structure createStructure(MacroData macroData, StructureData data, Vector3d position){ - Structure rVal = new Structure(); + public static VirtualStructure createStructure(MacroData macroData, StructureData data, Vector3d position){ + VirtualStructure rVal = new VirtualStructure(); rVal.fabPath = data.getFabPath(); rVal.type = data.getId(); rVal.position = position; diff --git a/src/main/java/electrosphere/server/macro/town/Town.java b/src/main/java/electrosphere/server/macro/town/Town.java index 53c46356..a3f472b7 100644 --- a/src/main/java/electrosphere/server/macro/town/Town.java +++ b/src/main/java/electrosphere/server/macro/town/Town.java @@ -4,7 +4,7 @@ import electrosphere.server.macro.character.Character; import electrosphere.server.macro.character.data.CharacterData; import electrosphere.server.macro.character.data.CharacterDataStrings; import electrosphere.server.macro.spatial.MacroAreaObject; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; import java.util.LinkedList; import java.util.List; @@ -40,7 +40,7 @@ public class Town extends CharacterData implements MacroAreaObject { /** * The structures inside the town */ - private List structures = new LinkedList(); + private List structures = new LinkedList(); /** * The residents of the town @@ -73,7 +73,7 @@ public class Town extends CharacterData implements MacroAreaObject { * Adds a structure to the town * @param structure The structure */ - public void addStructure(Structure structure){ + public void addStructure(VirtualStructure structure){ structures.add(structure); } @@ -81,7 +81,7 @@ public class Town extends CharacterData implements MacroAreaObject { * Gets the structures that are a part of the town * @return The list of structures */ - public List getStructures(){ + public List getStructures(){ return structures; } diff --git a/src/main/java/electrosphere/server/macro/utils/StructureRepairUtils.java b/src/main/java/electrosphere/server/macro/utils/StructureRepairUtils.java index bed2be54..f8aef5d9 100644 --- a/src/main/java/electrosphere/server/macro/utils/StructureRepairUtils.java +++ b/src/main/java/electrosphere/server/macro/utils/StructureRepairUtils.java @@ -11,7 +11,7 @@ import electrosphere.engine.Globals; import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.datacell.gridded.GriddedDataCellManager; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; /** * Utilities for repairing a structure @@ -24,7 +24,7 @@ public class StructureRepairUtils { * @param struct The structure * @return The next position that can be repaired if it exists, null otherwise */ - public static Vector3i getRepairablePosition(Realm realm, Structure struct){ + public static Vector3i getRepairablePosition(Realm realm, VirtualStructure struct){ //error checking if(!(realm.getDataCellManager() instanceof GriddedDataCellManager)){ throw new Error("Realm is not a gridded realm!"); @@ -61,7 +61,7 @@ public class StructureRepairUtils { * @param struct The structure * @return The id of the item to use to repair */ - public static String getNextRepairMat(Realm realm, Structure struct){ + public static String getNextRepairMat(Realm realm, VirtualStructure struct){ Vector3i repairPos = StructureRepairUtils.getRepairablePosition(realm, struct); if(repairPos == null){ @@ -82,7 +82,7 @@ public class StructureRepairUtils { * @param realm The realm the structure is within * @param struct The structure */ - public static void updateRepairableStatus(Realm realm, Structure struct){ + public static void updateRepairableStatus(Realm realm, VirtualStructure struct){ //error checking if(!(realm.getDataCellManager() instanceof GriddedDataCellManager)){ throw new Error("Realm is not a gridded realm!"); @@ -116,7 +116,7 @@ public class StructureRepairUtils { * @param struct The structure * @return true if the structure is actaully repairable, false otherwise */ - public static boolean validateRepairable(Realm realm, Structure struct){ + public static boolean validateRepairable(Realm realm, VirtualStructure struct){ //error checking if(!(realm.getDataCellManager() instanceof GriddedDataCellManager)){ throw new Error("Realm is not a gridded realm!"); diff --git a/src/main/java/electrosphere/server/physics/block/manager/ServerBlockChunkGenerationThread.java b/src/main/java/electrosphere/server/physics/block/manager/ServerBlockChunkGenerationThread.java index d8829dde..748f2e1e 100644 --- a/src/main/java/electrosphere/server/physics/block/manager/ServerBlockChunkGenerationThread.java +++ b/src/main/java/electrosphere/server/physics/block/manager/ServerBlockChunkGenerationThread.java @@ -15,7 +15,7 @@ import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; import electrosphere.server.datacell.ServerWorldData; import electrosphere.server.macro.MacroData; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.server.physics.block.diskmap.ServerBlockChunkDiskMap; /** @@ -164,7 +164,7 @@ public class ServerBlockChunkGenerationThread implements Runnable { } //check if this chunk intersects any macro data AABBd localAABB = new AABBd(ServerWorldData.convertChunkToRealSpace(worldX,worldY,worldZ),ServerWorldData.convertChunkToRealSpace(worldX+1,worldY+1,worldZ+1)); - List filtered = macroData.getStructures().stream().filter((Structure struct) -> {return !struct.isRepairable() && struct.getAABB().testAABB(localAABB);}).collect(Collectors.toList()); + List filtered = macroData.getStructures().stream().filter((VirtualStructure struct) -> {return !struct.isRepairable() && struct.getAABB().testAABB(localAABB);}).collect(Collectors.toList()); if(filtered.size() > 0){ Vector3i chunkPos = new Vector3i(worldX, worldY, worldZ); Vector3i blockPos = new Vector3i(0,0,0); @@ -179,7 +179,7 @@ public class ServerBlockChunkGenerationThread implements Runnable { //try placing a structure block blockPos.set(x,y,z); Vector3d currRealPoint = ServerWorldData.convertLocalBlockToRealSpace(chunkPos, blockPos); - for(Structure struct : filtered){ + for(VirtualStructure struct : filtered){ if(struct.getAABB().testPoint(currRealPoint.x, currRealPoint.y, currRealPoint.z)){ localBlockPos.set( (int)((chunkRealPos.x + (x * BlockChunkData.BLOCK_SIZE_MULTIPLIER) - struct.getStartPos().x) / BlockChunkData.BLOCK_SIZE_MULTIPLIER), diff --git a/src/main/java/electrosphere/server/simulation/chara/CharaSimulation.java b/src/main/java/electrosphere/server/simulation/chara/CharaSimulation.java index f5424fbb..f9015397 100644 --- a/src/main/java/electrosphere/server/simulation/chara/CharaSimulation.java +++ b/src/main/java/electrosphere/server/simulation/chara/CharaSimulation.java @@ -12,7 +12,7 @@ import electrosphere.server.macro.character.CharacterUtils; import electrosphere.server.macro.character.data.CharacterDataStrings; import electrosphere.server.macro.character.goal.CharacterGoal; import electrosphere.server.macro.character.goal.CharacterGoal.CharacterGoalType; -import electrosphere.server.macro.structure.Structure; +import electrosphere.server.macro.structure.VirtualStructure; import electrosphere.server.macro.utils.StructurePlacementUtils; import electrosphere.server.macro.utils.StructureRepairUtils; import electrosphere.util.FileUtils; @@ -54,7 +54,7 @@ public class CharaSimulation { fashion makeshift shelter */ if(CharacterUtils.getShelter(macroData,chara) != null){ - Structure shelter = CharacterUtils.getShelter(macroData,chara); + VirtualStructure shelter = CharacterUtils.getShelter(macroData,chara); if(shelter.isRepairable()){ if(StructureRepairUtils.validateRepairable(realm, shelter)){ String repairMat = StructureRepairUtils.getNextRepairMat(realm, shelter); @@ -75,7 +75,7 @@ public class CharaSimulation { Vector3d placementPos = StructurePlacementUtils.getPlacementPosition(macroData, structureData, position); //add to macro data - Structure struct = Structure.createStructure(macroData, structureData, placementPos); + VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, placementPos); struct.setRepairable(true); struct.setFab(BlockFab.read(FileUtils.getAssetFile(struct.getFabPath()))); CharacterUtils.addShelter(chara, struct);