fix lotta bugs
This commit is contained in:
parent
3df3beafba
commit
d733b3c46f
@ -1727,6 +1727,10 @@ Fix viewport loading
|
||||
Database warning handling
|
||||
In memory database support
|
||||
Fix test utils creating characters
|
||||
Fix server simulation starting prior to database connection
|
||||
Scaffolding macro character simulation
|
||||
Fix block generation thread filtering repairable structures
|
||||
Catch errors in pathfinding threads
|
||||
|
||||
|
||||
|
||||
|
||||
@ -73,14 +73,14 @@ public class MacroCharacterGoalNode implements AITreeNode {
|
||||
case BUILD_STRUCTURE: {
|
||||
Object targetRaw = goal.getTarget();
|
||||
if(!(targetRaw instanceof Structure)){
|
||||
throw new Error("Target is not a structure " + targetRaw);
|
||||
return AITreeNodeResult.FAILURE;
|
||||
}
|
||||
BeginStructureNode.setStructureTarget(blackboard, (Structure)goal.getTarget());
|
||||
} break;
|
||||
case ACQUIRE_ITEM: {
|
||||
Object targetRaw = goal.getTarget();
|
||||
if(!(targetRaw instanceof String)){
|
||||
throw new Error("Target is not a string " + targetRaw);
|
||||
return AITreeNodeResult.FAILURE;
|
||||
}
|
||||
blackboard.put(BlackboardKeys.GOAL_ITEM_ACQUISITION_TARGET, targetRaw);
|
||||
} break;
|
||||
|
||||
@ -32,10 +32,16 @@ public class PathfindingService implements AIService {
|
||||
public PathingProgressiveData queuePathfinding(Vector3d start, Vector3d end, VoxelPathfinder pathfinder, VoxelCellManager voxelCellManager){
|
||||
PathingProgressiveData rVal = new PathingProgressiveData(end);
|
||||
executorService.submit(() -> {
|
||||
List<Vector3d> points = pathfinder.findPath(voxelCellManager, start, end, VoxelPathfinder.DEFAULT_MAX_COST);
|
||||
points.add(end);
|
||||
rVal.setPoints(points);
|
||||
rVal.setReady(true);
|
||||
try {
|
||||
List<Vector3d> points = pathfinder.findPath(voxelCellManager, start, end, VoxelPathfinder.DEFAULT_MAX_COST);
|
||||
points.add(end);
|
||||
rVal.setPoints(points);
|
||||
rVal.setReady(true);
|
||||
} catch(Error e){
|
||||
e.printStackTrace();
|
||||
} catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -257,7 +257,7 @@ public class Realm {
|
||||
|
||||
//
|
||||
//macro data simulation
|
||||
if(this.macroData != null){
|
||||
if(this.macroData != null && Globals.dbController != null && Globals.dbController.isConnected()){
|
||||
MacroSimulation.simulate(this);
|
||||
}
|
||||
|
||||
|
||||
@ -1233,4 +1233,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
return this.groundDataCells.values().contains(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBlocksAtPosition(Vector3i worldPosition) {
|
||||
return this.serverWorldData.getServerBlockManager().hasChunk(worldPosition.x, worldPosition.y, worldPosition.z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -59,6 +59,13 @@ public interface VoxelCellManager {
|
||||
*/
|
||||
public BlockChunkData getBlocksAtPosition(Vector3i worldPosition);
|
||||
|
||||
/**
|
||||
* Checks if the manager has already-generated blocks at a given position
|
||||
* @param worldPosition The position
|
||||
* @return true if there are blocks at the position, false otherwise
|
||||
*/
|
||||
public boolean hasBlocksAtPosition(Vector3i worldPosition);
|
||||
|
||||
/**
|
||||
* Edits a single block voxel
|
||||
* @param worldPosition The world position of the block to edit
|
||||
|
||||
@ -10,6 +10,7 @@ import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
|
||||
import electrosphere.server.macro.character.diety.Diety;
|
||||
import electrosphere.server.macro.character.goal.CharacterGoal;
|
||||
import electrosphere.server.macro.race.Race;
|
||||
import electrosphere.server.macro.town.Town;
|
||||
|
||||
@ -34,10 +35,16 @@ public class CharacterDataSerializer implements JsonDeserializer<CharacterData>,
|
||||
}
|
||||
|
||||
//a structure
|
||||
case CharacterDataStrings.STRUCTURE_ID: {
|
||||
case CharacterDataStrings.STRUCTURE_ID:
|
||||
case CharacterDataStrings.SHELTER: {
|
||||
return context.deserialize(json, CharacterAssociatedId.class);
|
||||
}
|
||||
|
||||
//goal
|
||||
case CharacterDataStrings.ENTITY_GOAL: {
|
||||
return context.deserialize(json, CharacterGoal.class);
|
||||
}
|
||||
|
||||
//a town
|
||||
case CharacterDataStrings.TOWN: {
|
||||
return context.deserialize(json, Town.class);
|
||||
@ -64,11 +71,7 @@ public class CharacterDataSerializer implements JsonDeserializer<CharacterData>,
|
||||
}
|
||||
|
||||
//a structure
|
||||
case CharacterDataStrings.STRUCTURE_ID: {
|
||||
return context.serialize((CharacterAssociatedId)src);
|
||||
}
|
||||
|
||||
//a structure
|
||||
case CharacterDataStrings.STRUCTURE_ID:
|
||||
case CharacterDataStrings.SHELTER: {
|
||||
return context.serialize((CharacterAssociatedId)src);
|
||||
}
|
||||
@ -78,6 +81,11 @@ public class CharacterDataSerializer implements JsonDeserializer<CharacterData>,
|
||||
return context.serialize((Town)src);
|
||||
}
|
||||
|
||||
//goal
|
||||
case CharacterDataStrings.ENTITY_GOAL: {
|
||||
return context.serialize((CharacterGoal)src);
|
||||
}
|
||||
|
||||
default: {
|
||||
throw new Error("Failed to serialize datatype: " + src.getDataType());
|
||||
}
|
||||
|
||||
@ -64,6 +64,10 @@ public class StructureRepairUtils {
|
||||
public static String getNextRepairMat(Realm realm, Structure struct){
|
||||
Vector3i repairPos = StructureRepairUtils.getRepairablePosition(realm, struct);
|
||||
|
||||
if(repairPos == null){
|
||||
return null;
|
||||
}
|
||||
|
||||
//get the id of item entity type for the block we need
|
||||
BlockFab fab = struct.getFab();
|
||||
short blockTypeId = fab.getType(repairPos.x, repairPos.y, repairPos.z);
|
||||
@ -131,6 +135,8 @@ public class StructureRepairUtils {
|
||||
);
|
||||
Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(offsetPos);
|
||||
Vector3i blockPos = ServerWorldData.convertRealToLocalBlockSpace(offsetPos);
|
||||
|
||||
//check existing blocks
|
||||
BlockChunkData blockChunkData = griddedDataCellManager.getBlocksAtPosition(chunkPos);
|
||||
short existingBlockType = blockChunkData.getType(blockPos.x, blockPos.y, blockPos.z);
|
||||
short desiredType = fab.getType(x, y, z);
|
||||
|
||||
@ -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<Structure> filtered = macroData.getStructures().stream().filter((Structure struct) -> {return struct.isRepairable() || struct.getAABB().testAABB(localAABB);}).collect(Collectors.toList());
|
||||
List<Structure> filtered = macroData.getStructures().stream().filter((Structure 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);
|
||||
|
||||
@ -147,6 +147,17 @@ public class ServerBlockManager {
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is an already-generated chunk at the position
|
||||
* @param worldX The world x coordinate
|
||||
* @param worldY The world y coordinate
|
||||
* @param worldZ The world z coordinate
|
||||
* @return true if the chunk exists, false otherwise
|
||||
*/
|
||||
public boolean hasChunk(int worldX, int worldY, int worldZ){
|
||||
return chunkDiskMap.containsBlocksAtPosition(worldX, worldY, worldZ) || chunkCache.containsChunk(worldX, worldY, worldZ, BlockChunkData.LOD_FULL_RES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a given position's chunk to disk.
|
||||
* Uses the current global save name
|
||||
|
||||
@ -165,6 +165,9 @@ public class SaveUtils {
|
||||
//write server structures
|
||||
Globals.realmManager.save(saveName);
|
||||
|
||||
//store character service
|
||||
Globals.characterService.saveAll();
|
||||
|
||||
LoggerInterface.loggerEngine.WARNING("Finished saving " + saveName);
|
||||
}
|
||||
|
||||
|
||||
@ -248,4 +248,31 @@ public class CharacterService extends SignalServiceImpl {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the character service
|
||||
*/
|
||||
public void saveAll(){
|
||||
lock.lock();
|
||||
for(Character chara : this.loadedCharacterMap.values()){
|
||||
CreatureTemplate template = chara.getCreatureTemplate();
|
||||
if(this.characterEntityMap.containsKey(chara)){
|
||||
Entity characterEntity = this.characterEntityMap.get(chara);
|
||||
template = CreatureUtils.getCreatureTemplate(characterEntity);
|
||||
chara.setCreatureTemplate(template);
|
||||
chara.setPos(EntityUtils.getPosition(characterEntity));
|
||||
}
|
||||
|
||||
//serialize
|
||||
String toStore = SerializationUtils.serialize(chara);
|
||||
|
||||
//store a serialization to associate with the character
|
||||
Globals.dbController.executePreparedStatement(
|
||||
"UPDATE charaData SET dataVal=? WHERE id=?;",
|
||||
toStore,
|
||||
chara.getId()
|
||||
);
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,24 +2,11 @@ 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;
|
||||
import electrosphere.server.simulation.chara.CharaSimulation;
|
||||
|
||||
/**
|
||||
* Performs the macro-level (ie virtual, non-physics based) simulation
|
||||
@ -41,9 +28,12 @@ public class MacroSimulation {
|
||||
if(character.getPlayerId() != CharacterService.NO_PLAYER){
|
||||
continue;
|
||||
}
|
||||
//do something
|
||||
MacroSimulation.checkForShelter(realm, character);
|
||||
MacroSimulation.checkTownMembership(character);
|
||||
//update the goal of the character
|
||||
CharaSimulation.setGoal(realm, character);
|
||||
//if the character doesn't have an entity, simulate it at the macro level
|
||||
if(Globals.characterService.getEntity(character) == null){
|
||||
CharaSimulation.performGoal(realm, character);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,147 +53,5 @@ public class MacroSimulation {
|
||||
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<Structure> nearbyPopulatedStructures = new LinkedList<Structure>();
|
||||
// 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);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@ -0,0 +1,193 @@
|
||||
package electrosphere.server.simulation.chara;
|
||||
|
||||
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.util.FileUtils;
|
||||
|
||||
/**
|
||||
* Methods for simulating characters
|
||||
*/
|
||||
public class CharaSimulation {
|
||||
|
||||
|
||||
/**
|
||||
* Sets the goal of the character
|
||||
* @param realm The realm
|
||||
* @param chara The character
|
||||
*/
|
||||
public static void setGoal(Realm realm, Character chara){
|
||||
CharaSimulation.checkForShelter(realm, chara);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum attempts to place a structure
|
||||
*/
|
||||
static final int MAX_PLACE_ATTEMPTS = 10;
|
||||
|
||||
/**
|
||||
* Checks if the character has shelter
|
||||
* @param realm The realm
|
||||
* @param chara The character
|
||||
*/
|
||||
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<Structure> nearbyPopulatedStructures = new LinkedList<Structure>();
|
||||
// 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);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Performs whatever the current goal of the character is
|
||||
* @param realm The realm
|
||||
* @param chara The character
|
||||
*/
|
||||
public static void performGoal(Realm realm, Character chara){
|
||||
//todo -- acquire item logic
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user