lotta macro work
Some checks reported errors
studiorailgun/Renderer/pipeline/head Something is wrong with the build of this commit

This commit is contained in:
austin 2025-05-11 13:17:51 -04:00
parent 9ba0e7d881
commit b1c6ac6a4e
11 changed files with 193 additions and 5 deletions

View File

@ -1716,6 +1716,12 @@ Macro sim triggers character to try to get mats to build structure
(05/11/2025) (05/11/2025)
Fix inventory handling in creature templates Fix inventory handling in creature templates
Fix character data associated ids serialization bug Fix character data associated ids serialization bug
Block generation doesn't generate structures that are repairable
Fix character template inventory not clearing
Character data tracks associated player id
Player characters not simulated at macro level
Macro simulation inventory utilities
Build structure goal properly working from macro sim

View File

@ -7,6 +7,7 @@ import org.joml.Vector3d;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.state.attach.AttachUtils; import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.state.hitbox.HitboxCollectionState; import electrosphere.entity.state.hitbox.HitboxCollectionState;
import electrosphere.entity.state.server.ServerCharacterData;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
@ -165,6 +166,9 @@ public class ServerEntityUtils {
if(Globals.aiManager != null){ if(Globals.aiManager != null){
Globals.aiManager.removeAI(entity); Globals.aiManager.removeAI(entity);
} }
if(ServerCharacterData.hasServerCharacterDataTree(entity)){
Globals.characterService.removeEntity(ServerCharacterData.getServerCharacterData(entity).getCharacterData());
}
// //
//deregister all behavior trees //deregister all behavior trees

View File

@ -1,5 +1,6 @@
package electrosphere.entity.state.server; package electrosphere.entity.state.server;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.server.macro.character.Character; import electrosphere.server.macro.character.Character;
@ -37,6 +38,7 @@ public class ServerCharacterData {
public static void attachServerCharacterData(Entity entity, Character charaData){ public static void attachServerCharacterData(Entity entity, Character charaData){
ServerCharacterData tree = new ServerCharacterData(entity, charaData); ServerCharacterData tree = new ServerCharacterData(entity, charaData);
entity.putData(EntityDataStrings.TREE_SERVERCHARACTERDATA, tree); entity.putData(EntityDataStrings.TREE_SERVERCHARACTERDATA, tree);
Globals.characterService.setEntity(charaData, entity);
} }
/** /**

View File

@ -154,5 +154,29 @@ public class CreatureInventoryData {
return naturalIdMap.get(slot); return naturalIdMap.get(slot);
} }
/**
* Gets all items in the inventory data
* @return The list of all items
*/
public List<EntitySerialization> getAllItems(){
List<EntitySerialization> rVal = new LinkedList<EntitySerialization>();
rVal.addAll(this.naturalItems);
rVal.addAll(this.equipItemMap.values());
rVal.addAll(this.toolbarItemMap.values());
return rVal;
}
/**
* Clears the serialization
*/
public void clear(){
this.naturalIdMap.clear();
this.equippedIdMap.clear();
this.toolbarIdMap.clear();
this.naturalItems.clear();
this.equipItemMap.clear();
this.toolbarItemMap.clear();
}
} }

View File

@ -555,6 +555,7 @@ public class CreatureUtils {
public static CreatureTemplate getCreatureTemplate(Entity e){ public static CreatureTemplate getCreatureTemplate(Entity e){
CreatureTemplate template = (CreatureTemplate)e.getData(EntityDataStrings.CREATURE_TEMPLATE); CreatureTemplate template = (CreatureTemplate)e.getData(EntityDataStrings.CREATURE_TEMPLATE);
CreatureInventoryData inventoryData = template.getInventoryData(); CreatureInventoryData inventoryData = template.getInventoryData();
inventoryData.clear();
if(ServerEquipState.hasEquipState(e)){ if(ServerEquipState.hasEquipState(e)){
ServerEquipState serverEquipState = ServerEquipState.getEquipState(e); ServerEquipState serverEquipState = ServerEquipState.getEquipState(e);
for(String point : serverEquipState.equippedPoints()){ for(String point : serverEquipState.equippedPoints()){

View File

@ -19,6 +19,11 @@ public class Character implements MacroObject {
*/ */
int id; int id;
/**
* The associated player's id
*/
int playerId;
/** /**
* Data stored on the character * Data stored on the character
*/ */
@ -51,6 +56,22 @@ public class Character implements MacroObject {
this.id = id; this.id = id;
} }
/**
* Gets the associated player's id
* @return The id of the associated player
*/
public int getPlayerId(){
return playerId;
}
/**
* Sets the id of the associated player
* @param id The id of the associated player
*/
public void setPlayerId(int id){
this.playerId = id;
}
/** /**
* Puts data on the character * Puts data on the character
* @param key The key for the data * @param key The key for the data

View File

@ -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.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);

View File

@ -40,6 +40,11 @@ public class CharacterService extends SignalServiceImpl {
*/ */
Map<Integer,Character> loadedCharacterMap = new HashMap<Integer,Character>(); Map<Integer,Character> loadedCharacterMap = new HashMap<Integer,Character>();
/**
* Map of character -> entity
*/
Map<Character,Entity> characterEntityMap = new HashMap<Character,Entity>();
/** /**
* Lock for thread-safe-ing the service * Lock for thread-safe-ing the service
*/ */
@ -63,6 +68,7 @@ public class CharacterService extends SignalServiceImpl {
} }
lock.lock(); lock.lock();
Character toStore = new Character(template); Character toStore = new Character(template);
toStore.setPlayerId(playerId);
DatabaseResult result = Globals.dbController.executePreparedQuery( DatabaseResult result = Globals.dbController.executePreparedQuery(
"INSERT INTO charaData (playerId,dataVal) VALUES (?,?) RETURNING id;", "INSERT INTO charaData (playerId,dataVal) VALUES (?,?) RETURNING id;",
playerId, playerId,
@ -92,7 +98,7 @@ public class CharacterService extends SignalServiceImpl {
return rVal; return rVal;
} }
Character charData = null; Character charData = null;
DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT id, dataVal FROM charaData WHERE id=?;", characterId); DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT id, playerId, dataVal FROM charaData WHERE id=?;", characterId);
if(!result.hasResult()){ if(!result.hasResult()){
LoggerInterface.loggerDB.WARNING("Failed to locate creature template for characterId=" + characterId); LoggerInterface.loggerDB.WARNING("Failed to locate creature template for characterId=" + characterId);
lock.unlock(); lock.unlock();
@ -101,6 +107,7 @@ public class CharacterService extends SignalServiceImpl {
for(DatabaseResultRow row : result){ for(DatabaseResultRow row : result){
charData = SerializationUtils.deserialize(row.getAsString("dataVal"),Character.class); charData = SerializationUtils.deserialize(row.getAsString("dataVal"),Character.class);
charData.setId(row.getAsInteger("id")); charData.setId(row.getAsInteger("id"));
charData.setPlayerId(row.getAsInteger("playerId"));
} }
loadedCharacterMap.put(charData.getId(),charData); loadedCharacterMap.put(charData.getId(),charData);
lock.unlock(); lock.unlock();
@ -114,7 +121,7 @@ public class CharacterService extends SignalServiceImpl {
*/ */
public List<Character> getCharacters(int playerId){ public List<Character> getCharacters(int playerId){
lock.lock(); lock.lock();
DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT id, dataVal FROM charaData WHERE playerId=?;",playerId); DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT id, playerId, dataVal FROM charaData WHERE playerId=?;",playerId);
List<Character> rVal = new LinkedList<Character>(); List<Character> rVal = new LinkedList<Character>();
if(result.hasResult()){ if(result.hasResult()){
//if we get a valid response from the database, check that it actually matches hashes //if we get a valid response from the database, check that it actually matches hashes
@ -125,6 +132,7 @@ public class CharacterService extends SignalServiceImpl {
} else { } else {
Character description = SerializationUtils.deserialize(row.getAsString("dataVal"),Character.class); Character description = SerializationUtils.deserialize(row.getAsString("dataVal"),Character.class);
description.setId(id); description.setId(id);
description.setPlayerId(row.getAsInteger("playerId"));
loadedCharacterMap.put(description.getId(),description); loadedCharacterMap.put(description.getId(),description);
rVal.add(description); rVal.add(description);
} }
@ -166,7 +174,7 @@ public class CharacterService extends SignalServiceImpl {
*/ */
public List<Character> getAllCharacters(){ public List<Character> getAllCharacters(){
lock.lock(); lock.lock();
DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT id, dataVal FROM charaData"); DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT id, playerId, dataVal FROM charaData");
List<Character> rVal = new LinkedList<Character>(); List<Character> rVal = new LinkedList<Character>();
if(result.hasResult()){ if(result.hasResult()){
//if we get a valid response from the database, check that it actually matches hashes //if we get a valid response from the database, check that it actually matches hashes
@ -177,6 +185,7 @@ public class CharacterService extends SignalServiceImpl {
} else { } else {
Character description = SerializationUtils.deserialize(row.getAsString("dataVal"),Character.class); Character description = SerializationUtils.deserialize(row.getAsString("dataVal"),Character.class);
description.setId(id); description.setId(id);
description.setPlayerId(row.getAsInteger("playerId"));
loadedCharacterMap.put(description.getId(),description); loadedCharacterMap.put(description.getId(),description);
rVal.add(description); rVal.add(description);
} }
@ -202,4 +211,41 @@ public class CharacterService extends SignalServiceImpl {
return rVal; return rVal;
} }
/**
* Associates an entity to a character
* @param character The character
* @param entity The entity
*/
public void setEntity(Character character, Entity entity){
lock.lock();
if(this.characterEntityMap.containsKey(character)){
lock.unlock();
throw new Error("Entity already set!");
}
this.characterEntityMap.put(character, entity);
lock.unlock();
}
/**
* Gets the entity associated with a character
* @param character The character
* @return The associated entity if it exists, null otherwise
*/
public Entity getEntity(Character character){
lock.lock();
Entity rVal = this.characterEntityMap.get(character);
lock.unlock();
return rVal;
}
/**
* Removes an entity association with a character
* @param character The character
*/
public void removeEntity(Character character){
lock.lock();
this.characterEntityMap.remove(character);
lock.unlock();
}
} }

View File

@ -17,6 +17,8 @@ import electrosphere.server.macro.character.goal.CharacterGoal.CharacterGoalType
import electrosphere.server.macro.structure.Structure; import electrosphere.server.macro.structure.Structure;
import electrosphere.server.macro.utils.StructurePlacementUtils; import electrosphere.server.macro.utils.StructurePlacementUtils;
import electrosphere.server.macro.utils.StructureRepairUtils; import electrosphere.server.macro.utils.StructureRepairUtils;
import electrosphere.server.service.CharacterService;
import electrosphere.server.simulation.chara.CharaInventoryUtils;
import electrosphere.util.FileUtils; import electrosphere.util.FileUtils;
/** /**
@ -36,6 +38,9 @@ public class MacroSimulation {
List<Character> characters = Globals.characterService.getAllCharacters(); List<Character> characters = Globals.characterService.getAllCharacters();
if(characters != null && characters.size() > 0){ if(characters != null && characters.size() > 0){
for(Character character : Globals.characterService.getAllCharacters()){ for(Character character : Globals.characterService.getAllCharacters()){
if(character.getPlayerId() != CharacterService.NO_PLAYER){
continue;
}
//do something //do something
MacroSimulation.checkForShelter(realm, character); MacroSimulation.checkForShelter(realm, character);
MacroSimulation.checkTownMembership(character); MacroSimulation.checkTownMembership(character);
@ -80,8 +85,12 @@ public class MacroSimulation {
Structure shelter = CharacterUtils.getShelter(macroData,chara); Structure shelter = CharacterUtils.getShelter(macroData,chara);
if(shelter.isRepairable()){ if(shelter.isRepairable()){
String repairMat = StructureRepairUtils.getNextRepairMat(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)); CharacterGoal.setCharacterGoal(chara, new CharacterGoal(CharacterGoalType.ACQUIRE_ITEM, repairMat));
} }
}
// Vector2i charPos = CharacterUtils.getDiscretePosition(chara); // Vector2i charPos = CharacterUtils.getDiscretePosition(chara);
// Town nearbyTown = Town.getTownAtPosition(charPos.x,charPos.y); // Town nearbyTown = Town.getTownAtPosition(charPos.x,charPos.y);
// if(nearbyTown != null){ // if(nearbyTown != null){

View File

@ -0,0 +1,55 @@
package electrosphere.server.simulation.chara;
import java.util.List;
import java.util.stream.Collectors;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.types.creature.CreatureInventoryData;
import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.server.entity.serialization.EntitySerialization;
import electrosphere.server.macro.character.Character;
/**
* Checks if a character has an inventory item
*/
public class CharaInventoryUtils {
/**
* Gets all items in the character's inventories
* @param chara The character
* @return The list of all items in the character's inventories
*/
public static List<EntitySerialization> getInventoryContents(Character chara){
CreatureTemplate template = chara.getCreatureTemplate();
if(CharaMacroUtils.isMicroSim(chara)){
Entity creature = Globals.characterService.getEntity(chara);
template = CreatureUtils.getCreatureTemplate(creature);
}
CreatureInventoryData inventoryData = template.getInventoryData();
return inventoryData.getAllItems();
}
/**
* Gets the list of all inventory contents by their item ids
* @param chara The character
* @return The list of all item ids
*/
public static List<String> getInventoryContentIds(Character chara){
return CharaInventoryUtils.getInventoryContents(chara).stream().map((EntitySerialization serialization) -> {
return serialization.getSubtype();
}).collect(Collectors.toList());
}
/**
* Checks if the character contains a given type of item
* @param chara The character
* @param itemId The item id
* @return true if the character contains that item type, false otherwise
*/
public static boolean containsItem(Character chara, String itemId){
return CharaInventoryUtils.getInventoryContentIds(chara).contains(itemId);
}
}

View File

@ -0,0 +1,20 @@
package electrosphere.server.simulation.chara;
import electrosphere.engine.Globals;
import electrosphere.server.macro.character.Character;
/**
* Most basic utilities for working with characters in macro simulation
*/
public class CharaMacroUtils {
/**
* Checks if a character is being handled by micro simulation
* @param chara The character
* @return true if it is being handled by micro simulation, false otherwise
*/
public static boolean isMicroSim(Character chara){
return Globals.characterService.getEntity(chara) != null;
}
}