package electrosphere.server.simulation; import java.util.List; import org.joml.Vector3d; import electrosphere.engine.Globals; import electrosphere.game.data.block.BlockFab; import electrosphere.game.data.struct.StructureData; import electrosphere.server.datacell.Realm; import electrosphere.server.macro.MacroData; import electrosphere.server.macro.character.Character; 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.utils.StructurePlacementUtils; import electrosphere.server.macro.utils.StructureRepairUtils; import electrosphere.server.service.CharacterService; import electrosphere.server.simulation.chara.CharaInventoryUtils; import electrosphere.util.FileUtils; /** * Performs the macro-level (ie virtual, non-physics based) simulation */ public class MacroSimulation { /** * Tracks whether the macro simulation is ready or not */ private boolean isReady = false; /** * Iterates the macro simulation */ public static void simulate(Realm realm){ List characters = Globals.characterService.getAllCharacters(); if(characters != null && characters.size() > 0){ for(Character character : Globals.characterService.getAllCharacters()){ if(character.getPlayerId() != CharacterService.NO_PLAYER){ continue; } //do something MacroSimulation.checkForShelter(realm, character); MacroSimulation.checkTownMembership(character); } } } /** * Sets whether the macro simulation is ready or not * @param status true for ready, false otherwise */ public void setReady(boolean status){ isReady = status; } /** * Gets whether the macro simulation is ready or not * @return true for ready, false otherwise */ public boolean isReady(){ return isReady; } /** * Maximum attempts to place a structure */ static final int MAX_PLACE_ATTEMPTS = 10; protected static void checkForShelter(Realm realm, Character chara){ MacroData macroData = realm.getMacroData(); // for(Character chara : Globals.macroData.getAliveCharacters()){ /* If doesn’t have shelter, check if in town If in town, check if there’s an inn/church/friendly family if so, try to stay there if can’t find place to stay, fashion makeshift shelter If no town fashion makeshift shelter */ if(CharacterUtils.getShelter(macroData,chara) != null){ Structure shelter = CharacterUtils.getShelter(macroData,chara); if(shelter.isRepairable()){ if(StructureRepairUtils.validateRepairable(realm, shelter)){ String repairMat = StructureRepairUtils.getNextRepairMat(realm, shelter); if(CharaInventoryUtils.containsItem(chara, repairMat)){ CharacterGoal.setCharacterGoal(chara, new CharacterGoal(CharacterGoalType.BUILD_STRUCTURE, shelter)); } else { CharacterGoal.setCharacterGoal(chara, new CharacterGoal(CharacterGoalType.ACQUIRE_ITEM, repairMat)); } } else { shelter.setRepairable(false); } } // Vector2i charPos = CharacterUtils.getDiscretePosition(chara); // Town nearbyTown = Town.getTownAtPosition(charPos.x,charPos.y); // if(nearbyTown != null){ // //if town has a place to stay // if(false){ // } else { // //try to find a place to put down a structure // } } else { Vector3d position = chara.getPos(); StructureData structureData = Globals.gameConfigCurrent.getStructureData().getTypes().iterator().next(); //solve where to place Vector3d placementPos = StructurePlacementUtils.getPlacementPosition(macroData, structureData, position); //add to macro data Structure struct = Structure.createStructure(macroData, structureData, placementPos); struct.setRepairable(true); struct.setFab(BlockFab.read(FileUtils.getAssetFile(struct.getFabPath()))); CharacterUtils.addShelter(chara, struct); //target the struct CharacterGoal.setCharacterGoal(chara, new CharacterGoal(CharacterGoalType.BUILD_STRUCTURE, struct)); // //cry // //TODO: Get building type to place // String buildingTypeToPlace = "building1"; // //try to find a place to put down a structure // // int dynamicInterpRatio = Globals.serverTerrainManager.getDynamicInterpolationRatio(); // // Vector2f placementPos = new Vector2f( // // (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio), // // (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio) // // ); // // int attempts = 0; // // while(!VirtualStructureUtils.validStructurePlacementPosition(placementPos.x, placementPos.y, buildingTypeToPlace)){ // // placementPos = new Vector2f( // // (float)(charPos.x * dynamicInterpRatio + Math.random() * dynamicInterpRatio), // // (float)(charPos.y * dynamicInterpRatio + Math.random() * dynamicInterpRatio) // // ); // // attempts++; // // if(attempts > MAX_PLACE_ATTEMPTS){ // // placementPos = null; // // break; // // } // // } // // if(placementPos != null){ // // // Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace); // // // CharacterUtils.addShelter(chara, placedStructure); // // // VirtualStructureUtils.addResident(placedStructure, chara); // // } // } } // } } protected static void checkTownMembership(Character chara){ //TODO: eventually exclude people who shouldn't belong to a town (traders, bandits, etc) // for(Character chara : Globals.macroData.getAliveCharacters()){ boolean hasHometown = chara.containsKey(CharacterDataStrings.HOMETOWN); boolean hasShelter = chara.containsKey(CharacterDataStrings.SHELTER); //if has structure & no hometown if(!hasHometown && hasShelter){ // Structure shelter = CharacterUtils.getShelter(chara); //if there's at least one other structure nearby // Vector2i shelterDiscretePos = new Vector2i(shelter.getWorldX(),shelter.getWorldY()); // List nearbyPopulatedStructures = new LinkedList(); // for(Structure currentStruct : Globals.macroData.getStructures()){ // if(currentStruct.getWorldX() == shelterDiscretePos.x && currentStruct.getWorldY() == shelterDiscretePos.y && currentStruct != shelter){ // //if has a resident // if(shelter.getDataKeys().contains(StructureDataStrings.RESIDENTS) && VirtualStructureUtils.getResidents(shelter).size() > 0){ // boolean noTown = true; // for(Town town : Globals.macroData.getTowns()){ // if(town.getStructures().contains(currentStruct)){ // noTown = false; // } // } // if(noTown){ // nearbyPopulatedStructures.add(currentStruct); // } // } // } // } // if(nearbyPopulatedStructures.size() > 0){ // int numStructures = 0; // int numResidents = 0; // //form town // Town newTown = Town.createTown(shelterDiscretePos.x, shelterDiscretePos.y); // for(Structure structure : nearbyPopulatedStructures){ // numStructures++; // newTown.addStructure(structure); // for(Character resident : VirtualStructureUtils.getResidents(structure)){ // numResidents++; // newTown.addResident(resident); // CharacterUtils.addHometown(resident, newTown); // } // } // newTown.addStructure(shelter); // newTown.addResident(chara); // CharacterUtils.addHometown(chara, newTown); // System.out.println("Formed town with " + numStructures + " structures and " + numResidents + " residents"); // } } // } } // private static void checkInitCombat(){ // for(Character chara : Globals.macroData.getAliveCharacters()){ // // Vector2i position = CharacterUtils.getDiscretePosition(chara); // } // } }