fix lotta bugs
This commit is contained in:
parent
3df3beafba
commit
d733b3c46f
@ -1727,6 +1727,10 @@ Fix viewport loading
|
|||||||
Database warning handling
|
Database warning handling
|
||||||
In memory database support
|
In memory database support
|
||||||
Fix test utils creating characters
|
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: {
|
case BUILD_STRUCTURE: {
|
||||||
Object targetRaw = goal.getTarget();
|
Object targetRaw = goal.getTarget();
|
||||||
if(!(targetRaw instanceof Structure)){
|
if(!(targetRaw instanceof Structure)){
|
||||||
throw new Error("Target is not a structure " + targetRaw);
|
return AITreeNodeResult.FAILURE;
|
||||||
}
|
}
|
||||||
BeginStructureNode.setStructureTarget(blackboard, (Structure)goal.getTarget());
|
BeginStructureNode.setStructureTarget(blackboard, (Structure)goal.getTarget());
|
||||||
} break;
|
} break;
|
||||||
case ACQUIRE_ITEM: {
|
case ACQUIRE_ITEM: {
|
||||||
Object targetRaw = goal.getTarget();
|
Object targetRaw = goal.getTarget();
|
||||||
if(!(targetRaw instanceof String)){
|
if(!(targetRaw instanceof String)){
|
||||||
throw new Error("Target is not a string " + targetRaw);
|
return AITreeNodeResult.FAILURE;
|
||||||
}
|
}
|
||||||
blackboard.put(BlackboardKeys.GOAL_ITEM_ACQUISITION_TARGET, targetRaw);
|
blackboard.put(BlackboardKeys.GOAL_ITEM_ACQUISITION_TARGET, targetRaw);
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@ -32,10 +32,16 @@ public class PathfindingService implements AIService {
|
|||||||
public PathingProgressiveData queuePathfinding(Vector3d start, Vector3d end, VoxelPathfinder pathfinder, VoxelCellManager voxelCellManager){
|
public PathingProgressiveData queuePathfinding(Vector3d start, Vector3d end, VoxelPathfinder pathfinder, VoxelCellManager voxelCellManager){
|
||||||
PathingProgressiveData rVal = new PathingProgressiveData(end);
|
PathingProgressiveData rVal = new PathingProgressiveData(end);
|
||||||
executorService.submit(() -> {
|
executorService.submit(() -> {
|
||||||
|
try {
|
||||||
List<Vector3d> points = pathfinder.findPath(voxelCellManager, start, end, VoxelPathfinder.DEFAULT_MAX_COST);
|
List<Vector3d> points = pathfinder.findPath(voxelCellManager, start, end, VoxelPathfinder.DEFAULT_MAX_COST);
|
||||||
points.add(end);
|
points.add(end);
|
||||||
rVal.setPoints(points);
|
rVal.setPoints(points);
|
||||||
rVal.setReady(true);
|
rVal.setReady(true);
|
||||||
|
} catch(Error e){
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -257,7 +257,7 @@ public class Realm {
|
|||||||
|
|
||||||
//
|
//
|
||||||
//macro data simulation
|
//macro data simulation
|
||||||
if(this.macroData != null){
|
if(this.macroData != null && Globals.dbController != null && Globals.dbController.isConnected()){
|
||||||
MacroSimulation.simulate(this);
|
MacroSimulation.simulate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1233,4 +1233,9 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
return this.groundDataCells.values().contains(cell);
|
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);
|
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
|
* Edits a single block voxel
|
||||||
* @param worldPosition The world position of the block to edit
|
* @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 com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
import electrosphere.server.macro.character.diety.Diety;
|
import electrosphere.server.macro.character.diety.Diety;
|
||||||
|
import electrosphere.server.macro.character.goal.CharacterGoal;
|
||||||
import electrosphere.server.macro.race.Race;
|
import electrosphere.server.macro.race.Race;
|
||||||
import electrosphere.server.macro.town.Town;
|
import electrosphere.server.macro.town.Town;
|
||||||
|
|
||||||
@ -34,10 +35,16 @@ public class CharacterDataSerializer implements JsonDeserializer<CharacterData>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//a structure
|
//a structure
|
||||||
case CharacterDataStrings.STRUCTURE_ID: {
|
case CharacterDataStrings.STRUCTURE_ID:
|
||||||
|
case CharacterDataStrings.SHELTER: {
|
||||||
return context.deserialize(json, CharacterAssociatedId.class);
|
return context.deserialize(json, CharacterAssociatedId.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//goal
|
||||||
|
case CharacterDataStrings.ENTITY_GOAL: {
|
||||||
|
return context.deserialize(json, CharacterGoal.class);
|
||||||
|
}
|
||||||
|
|
||||||
//a town
|
//a town
|
||||||
case CharacterDataStrings.TOWN: {
|
case CharacterDataStrings.TOWN: {
|
||||||
return context.deserialize(json, Town.class);
|
return context.deserialize(json, Town.class);
|
||||||
@ -64,11 +71,7 @@ public class CharacterDataSerializer implements JsonDeserializer<CharacterData>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//a structure
|
//a structure
|
||||||
case CharacterDataStrings.STRUCTURE_ID: {
|
case CharacterDataStrings.STRUCTURE_ID:
|
||||||
return context.serialize((CharacterAssociatedId)src);
|
|
||||||
}
|
|
||||||
|
|
||||||
//a structure
|
|
||||||
case CharacterDataStrings.SHELTER: {
|
case CharacterDataStrings.SHELTER: {
|
||||||
return context.serialize((CharacterAssociatedId)src);
|
return context.serialize((CharacterAssociatedId)src);
|
||||||
}
|
}
|
||||||
@ -78,6 +81,11 @@ public class CharacterDataSerializer implements JsonDeserializer<CharacterData>,
|
|||||||
return context.serialize((Town)src);
|
return context.serialize((Town)src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//goal
|
||||||
|
case CharacterDataStrings.ENTITY_GOAL: {
|
||||||
|
return context.serialize((CharacterGoal)src);
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
throw new Error("Failed to serialize datatype: " + src.getDataType());
|
throw new Error("Failed to serialize datatype: " + src.getDataType());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,6 +64,10 @@ public class StructureRepairUtils {
|
|||||||
public static String getNextRepairMat(Realm realm, Structure struct){
|
public static String getNextRepairMat(Realm realm, Structure struct){
|
||||||
Vector3i repairPos = StructureRepairUtils.getRepairablePosition(realm, struct);
|
Vector3i repairPos = StructureRepairUtils.getRepairablePosition(realm, struct);
|
||||||
|
|
||||||
|
if(repairPos == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
//get the id of item entity type for the block we need
|
//get the id of item entity type for the block we need
|
||||||
BlockFab fab = struct.getFab();
|
BlockFab fab = struct.getFab();
|
||||||
short blockTypeId = fab.getType(repairPos.x, repairPos.y, repairPos.z);
|
short blockTypeId = fab.getType(repairPos.x, repairPos.y, repairPos.z);
|
||||||
@ -131,6 +135,8 @@ public class StructureRepairUtils {
|
|||||||
);
|
);
|
||||||
Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(offsetPos);
|
Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(offsetPos);
|
||||||
Vector3i blockPos = ServerWorldData.convertRealToLocalBlockSpace(offsetPos);
|
Vector3i blockPos = ServerWorldData.convertRealToLocalBlockSpace(offsetPos);
|
||||||
|
|
||||||
|
//check existing blocks
|
||||||
BlockChunkData blockChunkData = griddedDataCellManager.getBlocksAtPosition(chunkPos);
|
BlockChunkData blockChunkData = griddedDataCellManager.getBlocksAtPosition(chunkPos);
|
||||||
short existingBlockType = blockChunkData.getType(blockPos.x, blockPos.y, blockPos.z);
|
short existingBlockType = blockChunkData.getType(blockPos.x, blockPos.y, blockPos.z);
|
||||||
short desiredType = fab.getType(x, y, 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
|
//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));
|
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){
|
if(filtered.size() > 0){
|
||||||
Vector3i chunkPos = new Vector3i(worldX, worldY, worldZ);
|
Vector3i chunkPos = new Vector3i(worldX, worldY, worldZ);
|
||||||
Vector3i blockPos = new Vector3i(0,0,0);
|
Vector3i blockPos = new Vector3i(0,0,0);
|
||||||
|
|||||||
@ -147,6 +147,17 @@ public class ServerBlockManager {
|
|||||||
Globals.profiler.endCpuSample();
|
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.
|
* Saves a given position's chunk to disk.
|
||||||
* Uses the current global save name
|
* Uses the current global save name
|
||||||
|
|||||||
@ -165,6 +165,9 @@ public class SaveUtils {
|
|||||||
//write server structures
|
//write server structures
|
||||||
Globals.realmManager.save(saveName);
|
Globals.realmManager.save(saveName);
|
||||||
|
|
||||||
|
//store character service
|
||||||
|
Globals.characterService.saveAll();
|
||||||
|
|
||||||
LoggerInterface.loggerEngine.WARNING("Finished saving " + saveName);
|
LoggerInterface.loggerEngine.WARNING("Finished saving " + saveName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -248,4 +248,31 @@ public class CharacterService extends SignalServiceImpl {
|
|||||||
lock.unlock();
|
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 java.util.List;
|
||||||
|
|
||||||
import org.joml.Vector3d;
|
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.game.data.block.BlockFab;
|
|
||||||
import electrosphere.game.data.struct.StructureData;
|
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.macro.MacroData;
|
|
||||||
import electrosphere.server.macro.character.Character;
|
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.service.CharacterService;
|
||||||
import electrosphere.server.simulation.chara.CharaInventoryUtils;
|
import electrosphere.server.simulation.chara.CharaSimulation;
|
||||||
import electrosphere.util.FileUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the macro-level (ie virtual, non-physics based) simulation
|
* Performs the macro-level (ie virtual, non-physics based) simulation
|
||||||
@ -41,9 +28,12 @@ public class MacroSimulation {
|
|||||||
if(character.getPlayerId() != CharacterService.NO_PLAYER){
|
if(character.getPlayerId() != CharacterService.NO_PLAYER){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//do something
|
//update the goal of the character
|
||||||
MacroSimulation.checkForShelter(realm, character);
|
CharaSimulation.setGoal(realm, character);
|
||||||
MacroSimulation.checkTownMembership(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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,146 +54,4 @@ public class MacroSimulation {
|
|||||||
return 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