Initial macro simulation work
This commit is contained in:
parent
581de4f58a
commit
78ac717283
@ -17,7 +17,7 @@ CREATE INDEX charaDataIDIndex ON charaData (charID);
|
||||
|
||||
--towns
|
||||
--positions
|
||||
CREATE TABLE townWorldPositions (id INTEGER PRIMARY KEY, townID INTEGER, posX INTEGER, posY INTEGER, bbRadiusX INTEGER, bbRadiusY INTEGER);
|
||||
CREATE TABLE townWorldPositions (id INTEGER PRIMARY KEY, townID INTEGER, posX INTEGER, posY INTEGER);
|
||||
CREATE INDEX townWorldPositionsIDIndex ON townWorldPositions (townID);
|
||||
CREATE INDEX townWorldPositionsPosIndex ON townWorldPositions (posX, posY);
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
|
||||
--positions
|
||||
INSERT INTO townWorldPositions (townID,posX,posY,bbRadiusX,bbRadiusY) VALUES (0,10,10,1,1);
|
||||
INSERT INTO townWorldPositions (townID,posX,posY) VALUES (0,10,10);
|
||||
|
||||
--data
|
||||
INSERT INTO townData(townID,propName,propValue) VALUES(0,"name","someTown");
|
||||
|
||||
@ -1 +1,2 @@
|
||||
SELECT * FROM townWorldPositions WHERE posX = 10 AND posY = 10;
|
||||
--given x=10, y=11
|
||||
SELECT townID FROM townWorldPositions WHERE posX = 10 AND posY = 11;
|
||||
@ -349,7 +349,7 @@ public class LoadingThread extends Thread {
|
||||
int chunkSize = Globals.serverTerrainManager.getChunkWidth();
|
||||
Globals.spawnPoint = new Vector3f(townLoc.x * chunkSize, (float)Globals.serverTerrainManager.getHeightAtPosition(townLoc.x * chunkSize,townLoc.y * chunkSize), townLoc.y * chunkSize);
|
||||
// System.out.println("Setting spawn point @ " + Globals.spawnPoint);
|
||||
Town.createTown(townLoc.x,townLoc.y);
|
||||
// Town.createTown(townLoc.x,townLoc.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class Character {
|
||||
static int entity_id_iterator = 0;
|
||||
static int character_id_iterator = 0;
|
||||
|
||||
int id;
|
||||
|
||||
|
||||
@ -11,5 +11,7 @@ public class CharacterDataStrings {
|
||||
public static final String PERSONALTIY_BASIC = "personalityBasic";
|
||||
public static final String PERSONALITY_ADVANCED = "personalityAdvanced";
|
||||
public static final String RACE = "race";
|
||||
public static final String SHELTER = "shelter";
|
||||
public static final String HOMETOWN = "hometown";
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,8 @@ package electrosphere.game.server.character;
|
||||
import electrosphere.game.server.character.Character;
|
||||
import electrosphere.game.server.character.diety.Diety;
|
||||
import electrosphere.game.server.race.model.Race;
|
||||
import electrosphere.game.server.structure.virtual.Structure;
|
||||
import electrosphere.game.server.town.Town;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
/**
|
||||
@ -35,4 +37,20 @@ public class CharacterUtils {
|
||||
return (Race)character.getData(CharacterDataStrings.RACE);
|
||||
}
|
||||
|
||||
public static void addShelter(Character character, Structure shelter){
|
||||
character.putData(CharacterDataStrings.SHELTER, shelter);
|
||||
}
|
||||
|
||||
public static Structure getShelter(Character character){
|
||||
return (Structure)character.getData(CharacterDataStrings.SHELTER);
|
||||
}
|
||||
|
||||
public static void addHometown(Character character, Town town){
|
||||
character.putData(CharacterDataStrings.HOMETOWN, town);
|
||||
}
|
||||
|
||||
public static Town getHometown(Character character){
|
||||
return (Town)character.getData(CharacterDataStrings.HOMETOWN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
package electrosphere.game.server.structure.virtual;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
@ -10,6 +14,10 @@ public class Structure {
|
||||
float locationX;
|
||||
float locationY;
|
||||
String type;
|
||||
|
||||
HashMap<String,Object> data = new HashMap();
|
||||
|
||||
LinkedList<String> dataKeys = new LinkedList();
|
||||
|
||||
public Structure(int worldX, int worldY, float locationX, float locationY, String type) {
|
||||
this.worldX = worldX;
|
||||
@ -18,6 +26,19 @@ public class Structure {
|
||||
this.locationY = locationY;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void putData(String key, Object o){
|
||||
data.put(key,o);
|
||||
dataKeys.add(key);
|
||||
}
|
||||
|
||||
public List<String> getDataKeys(){
|
||||
return dataKeys;
|
||||
}
|
||||
|
||||
public Object getData(String key){
|
||||
return data.get(key);
|
||||
}
|
||||
|
||||
public int getWorldX() {
|
||||
return worldX;
|
||||
@ -40,4 +61,5 @@ public class Structure {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
package electrosphere.game.server.structure.virtual;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
*/
|
||||
public class StructureDataStrings {
|
||||
|
||||
public static final String RESIDENTS = "residents";
|
||||
|
||||
}
|
||||
@ -3,20 +3,25 @@ package electrosphere.game.server.structure.virtual;
|
||||
import electrosphere.entity.types.structure.StructureUtils;
|
||||
import electrosphere.game.config.structure.type.model.StructureType;
|
||||
import electrosphere.main.Globals;
|
||||
import electrosphere.game.server.character.Character;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class StructurePlacer {
|
||||
public class VirtualStructureUtils {
|
||||
|
||||
|
||||
public static Structure placeStructureAtPoint(float posX, float posY, String type){
|
||||
int worldX = Globals.serverWorldData.convertRealToChunkSpace(posX);
|
||||
int worldY = Globals.serverWorldData.convertRealToChunkSpace(posY);
|
||||
Structure rVal = new Structure(worldX,worldY,posX,posY,type);
|
||||
Globals.macroData.addStructure(rVal);
|
||||
|
||||
double centerHeight = Globals.serverTerrainManager.getHeightAtPosition(posX, posY);
|
||||
StructureType currentTypeObject = Globals.gameConfigCurrent.getStructureTypeMap().getType(type);
|
||||
@ -35,4 +40,33 @@ public class StructurePlacer {
|
||||
StructureUtils.spawnBasicStructure(type, new Vector3f(posX,(float)centerHeight + 2.4f,posY), new Quaternionf());
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static boolean validStructurePlacementPosition(float posX, float posY, String type){
|
||||
StructureType toPlaceType = Globals.gameConfigCurrent.getStructureTypeMap().getType(type);
|
||||
Vector2f toPlacePos = new Vector2f(posX, posY);
|
||||
for(Structure virtualStruct : Globals.macroData.getStructures()){
|
||||
StructureType existantType = Globals.gameConfigCurrent.getStructureTypeMap().getType(virtualStruct.getType());
|
||||
Vector2f existantPos = new Vector2f(virtualStruct.getLocationX(),virtualStruct.getLocationY());
|
||||
if(existantPos.distance(toPlacePos) < toPlaceType.getRadius() + existantType.getRadius()){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static void addResident(Structure structure, Character character){
|
||||
List<Character> residents = null;
|
||||
if(structure.getDataKeys().contains(StructureDataStrings.RESIDENTS)){
|
||||
residents = (List)structure.getData(StructureDataStrings.RESIDENTS);
|
||||
} else {
|
||||
residents = new LinkedList();
|
||||
structure.putData(StructureDataStrings.RESIDENTS, residents);
|
||||
}
|
||||
residents.add(character);
|
||||
}
|
||||
|
||||
public static List<Character> getResidents(Structure structure){
|
||||
return (List)structure.getData(StructureDataStrings.RESIDENTS);
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,19 @@
|
||||
package electrosphere.game.server.town;
|
||||
|
||||
import electrosphere.game.server.structure.virtual.StructurePlacer;
|
||||
import electrosphere.game.server.db.DatabaseResult;
|
||||
import electrosphere.game.server.structure.virtual.Structure;
|
||||
import electrosphere.game.server.structure.virtual.VirtualStructureUtils;
|
||||
import electrosphere.game.server.terrain.manager.ServerTerrainChunk;
|
||||
import electrosphere.game.server.character.Character;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.main.Globals;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
/**
|
||||
@ -15,7 +25,13 @@ public class Town {
|
||||
int id;
|
||||
static int idIncrementer = 0;
|
||||
|
||||
List<Vector2i> positions = new LinkedList();
|
||||
|
||||
List<Structure> structures = new LinkedList();
|
||||
List<Character> residents = new LinkedList();
|
||||
|
||||
final static int avgDiffThreshold = 10;
|
||||
|
||||
public static Vector2i findValidTownLocation(){
|
||||
for(int x = 0; x < Globals.serverTerrainManager.getWorldDiscreteSize(); x++){
|
||||
for(int y = 0; y < Globals.serverTerrainManager.getWorldDiscreteSize(); y++){
|
||||
@ -54,13 +70,58 @@ public class Town {
|
||||
|
||||
public static Town createTown(int x, int y){
|
||||
Town rVal = new Town();
|
||||
Random rand = new Random();
|
||||
int structCount = (rand.nextInt(3) + 2);
|
||||
int chunkSize = Globals.serverTerrainManager.getChunkWidth();
|
||||
for(int i = 0; i < structCount; i++){
|
||||
StructurePlacer.placeStructureAtPoint(x * chunkSize + rand.nextFloat() * 100, y * chunkSize + rand.nextFloat() * 100, "building1");
|
||||
rVal.positions.add(new Vector2i(x,y));
|
||||
Globals.macroData.addTown(rVal);
|
||||
// Random rand = new Random();
|
||||
// int structCount = (rand.nextInt(3) + 2);
|
||||
// int chunkSize = Globals.serverTerrainManager.getChunkWidth();
|
||||
// for(int i = 0; i < structCount; i++){
|
||||
// StructurePlacer.placeStructureAtPoint(x * chunkSize + rand.nextFloat() * 100, y * chunkSize + rand.nextFloat() * 100, "building1");
|
||||
// }
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static Town getTownAtPosition(int x, int y){
|
||||
Town rVal = null;
|
||||
// DatabaseResult locationLookupResult = Globals.dbController.executeQuery("SELECT townID FROM townWorldPositions WHERE posX = " + x + " AND posY = " + y + ";");
|
||||
// if(locationLookupResult.hasResultSet()){
|
||||
// ResultSet rs = locationLookupResult.getResultSet();
|
||||
// int townID = -1;
|
||||
// try {
|
||||
// if(rs.next()){
|
||||
// townID = rs.getInt("townID");
|
||||
// }
|
||||
// } catch (SQLException ex) {
|
||||
// LoggerInterface.loggerEngine.ERROR("Error reading result set from getTownAtPosition", ex);
|
||||
// }
|
||||
// if(townID != -1){
|
||||
//
|
||||
// }
|
||||
// }
|
||||
for(Town town : Globals.macroData.getTowns()){
|
||||
for(Vector2i position : town.positions){
|
||||
if(position.x == x && position.y == y){
|
||||
return town;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public void addStructure(Structure structure){
|
||||
structures.add(structure);
|
||||
}
|
||||
|
||||
public List<Structure> getStructures(){
|
||||
return structures;
|
||||
}
|
||||
|
||||
public void addResident(Character resident){
|
||||
residents.add(resident);
|
||||
}
|
||||
|
||||
public List<Character> getResidents(){
|
||||
return residents;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
package electrosphere.game.server.town;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
*/
|
||||
public class TownUtils {
|
||||
|
||||
}
|
||||
@ -6,9 +6,12 @@ import electrosphere.game.server.character.Character;
|
||||
import electrosphere.game.server.character.CharacterDataStrings;
|
||||
import electrosphere.game.server.character.CharacterUtils;
|
||||
import electrosphere.game.server.character.diety.Diety;
|
||||
import electrosphere.game.server.civilization.Civilization;
|
||||
import electrosphere.game.server.race.model.Race;
|
||||
import electrosphere.game.server.race.model.RaceMap;
|
||||
import electrosphere.game.server.structure.virtual.Structure;
|
||||
import electrosphere.game.server.symbolism.model.Symbol;
|
||||
import electrosphere.game.server.town.Town;
|
||||
import electrosphere.main.Globals;
|
||||
import java.util.Random;
|
||||
import org.joml.Vector2i;
|
||||
@ -23,6 +26,9 @@ public class MacroData {
|
||||
List<Race> races = new LinkedList();
|
||||
List<Character> characters = new LinkedList();
|
||||
List<Character> aliveCharacters = new LinkedList();
|
||||
List<Civilization> civilizations = new LinkedList();
|
||||
List<Town> towns = new LinkedList();
|
||||
List<Structure> structures = new LinkedList();
|
||||
|
||||
|
||||
static Character generateInitialDiety(long seed){
|
||||
@ -109,6 +115,30 @@ public class MacroData {
|
||||
return aliveCharacters;
|
||||
}
|
||||
|
||||
public List<Civilization> getCivilizations(){
|
||||
return civilizations;
|
||||
}
|
||||
|
||||
public void addCivilization(Civilization civilization){
|
||||
civilizations.add(civilization);
|
||||
}
|
||||
|
||||
public List<Town> getTowns(){
|
||||
return towns;
|
||||
}
|
||||
|
||||
public void addTown(Town town){
|
||||
towns.add(town);
|
||||
}
|
||||
|
||||
public List<Structure> getStructures(){
|
||||
return structures;
|
||||
}
|
||||
|
||||
public void addStructure(Structure structure){
|
||||
structures.add(structure);
|
||||
}
|
||||
|
||||
public void describeWorld(){
|
||||
System.out.println("Initial dieties");
|
||||
System.out.println("==========================");
|
||||
|
||||
@ -10,10 +10,17 @@ import electrosphere.game.server.structure.virtual.Structure;
|
||||
import electrosphere.game.server.town.Town;
|
||||
import electrosphere.main.Globals;
|
||||
import electrosphere.game.server.character.Character;
|
||||
import electrosphere.game.server.character.CharacterDataStrings;
|
||||
import electrosphere.game.server.character.CharacterUtils;
|
||||
import electrosphere.game.server.structure.virtual.StructureDataStrings;
|
||||
import electrosphere.game.server.structure.virtual.VirtualStructureUtils;
|
||||
import electrosphere.util.FileLoadingUtils;
|
||||
import electrosphere.util.Utilities;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
public class MacroSimulation {
|
||||
|
||||
@ -39,6 +46,121 @@ public class MacroSimulation {
|
||||
public void simulate(){
|
||||
for(Character character : Globals.macroData.getAliveCharacters()){
|
||||
//do something
|
||||
checkForShelter();
|
||||
checkTownMembership();
|
||||
}
|
||||
}
|
||||
|
||||
static final int MAX_PLACE_ATTEMPTS = 10;
|
||||
|
||||
static void checkForShelter(){
|
||||
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(!chara.getDataKeys().contains(CharacterDataStrings.SHELTER)){
|
||||
Vector2i charPos = CharacterUtils.getDiscretePosition(chara);
|
||||
Town nearbyTown = Town.getTownAtPosition(charPos.x,charPos.y);
|
||||
if(nearbyTown != null){
|
||||
//if town has a place to day
|
||||
if(false){
|
||||
|
||||
} else {
|
||||
//try to find a place to put down a structure
|
||||
|
||||
}
|
||||
} else {
|
||||
//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){
|
||||
System.out.println("Added shelter");
|
||||
Structure placedStructure = VirtualStructureUtils.placeStructureAtPoint(placementPos.x, placementPos.y, buildingTypeToPlace);
|
||||
CharacterUtils.addShelter(chara, placedStructure);
|
||||
VirtualStructureUtils.addResident(placedStructure, chara);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void checkTownMembership(){
|
||||
//TODO: eventually exclude people who shouldn't belong to a town (traders, bandits, etc)
|
||||
for(Character chara : Globals.macroData.getAliveCharacters()){
|
||||
boolean hasHometown = chara.getDataKeys().contains(CharacterDataStrings.HOMETOWN);
|
||||
boolean hasShelter = chara.getDataKeys().contains(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();
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void checkInitCombat(){
|
||||
for(Character chara : Globals.macroData.getAliveCharacters()){
|
||||
Vector2i position = CharacterUtils.getDiscretePosition(chara);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ import electrosphere.game.client.ClientFunctions;
|
||||
import electrosphere.game.config.UserSettings;
|
||||
import electrosphere.game.server.terrain.manager.ServerTerrainManager;
|
||||
import electrosphere.game.server.world.MacroData;
|
||||
import electrosphere.game.server.world.ServerWorldData;
|
||||
import electrosphere.game.state.MacroSimulation;
|
||||
import electrosphere.game.state.MicroSimulation;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
@ -121,13 +122,19 @@ public class Main {
|
||||
//gen terrain
|
||||
Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0);
|
||||
Globals.serverTerrainManager.load();
|
||||
Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
|
||||
//gen world
|
||||
MacroData world = MacroData.generateWorld(0);
|
||||
world.describeWorld();
|
||||
Globals.macroData = MacroData.generateWorld(0);
|
||||
Globals.macroData.describeWorld();
|
||||
boolean run = true;
|
||||
Globals.macroSimulation = new MacroSimulation();
|
||||
while(run){
|
||||
Globals.macroSimulation.simulate();
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(1000);
|
||||
} catch (InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//debug: create terrain/world viewer
|
||||
|
||||
Loading…
Reference in New Issue
Block a user