recursive recipe solver
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-05-04 19:01:06 -04:00
parent d29f51c509
commit c0627bf3fb
6 changed files with 104 additions and 42 deletions

View File

@ -1675,6 +1675,7 @@ Terrain items
Digging produces terrain item form
Terrain items can be placed to place terrain
Recipe adjustment + voxel work
Recursive recipe item sourcing solver that keeps searching if a recipe fails to source

View File

@ -81,10 +81,20 @@ public class ItemSourcingTree {
return this.itemSourceMap.get(this.rootItemId);
}
String currentRootId = this.rootItemId;
while(currentRootId != null){
ItemSourcingData sourcingData = this.itemSourceMap.get(currentRootId);
return this.getCurrentDependencyRecursive(entity,itemIds,currentRootId);
}
/**
* Gets the sourcing data for the current dependency
* @param entity The entity to check
* @param inventoryIds The contents of the entity's inventory
* @param currentRoot The current root item to search for
* @return The sourcing data for the current dependency
*/
private ItemSourcingData getCurrentDependencyRecursive(Entity entity, List<String> inventoryIds, String currentRoot){
ItemSourcingData sourcingData = this.itemSourceMap.get(currentRoot);
if(sourcingData == null){
throw new Error("Failed to find sourcing data for " + currentRootId);
throw new Error("Failed to find sourcing data for " + currentRoot);
}
if(sourcingData.harvestTargets.size() > 0){
return sourcingData;
@ -92,38 +102,56 @@ public class ItemSourcingTree {
if(sourcingData.trees.size() > 0){
//if we don't have an axe in inventory, consider it a dependency
if(!InventoryUtils.serverHasTool(entity, CommonEntityTokens.TOKEN_AXE)){
currentRootId = ItemIdStrings.ITEM_STONE_AXE;
continue;
ItemSourcingData axeSource = this.getCurrentDependencyRecursive(entity, inventoryIds, ItemIdStrings.ITEM_STONE_AXE);
return axeSource;
}
//we have an axe, return this sourcing data
return sourcingData;
}
currentRootId = null;
if(sourcingData.recipes.size() > 0){
boolean foundAllIngredients = true;
//the ingredient to source if we don't have all ingredients
ItemSourcingData ingredientToSource = null;
//whether we have all ingredients already or not
boolean foundAllIngredients = false;
//whether the recipe is source-able at all
boolean recipeIsSourceable = true;
//the recipe
RecipeData craftableRecipe = null;
for(RecipeData recipeData : sourcingData.recipes){
//check if we have all the ingredients to craft this item
foundAllIngredients = true;
recipeIsSourceable = true;
ingredientToSource = null;
for(RecipeIngredientData ingredient : recipeData.getIngredients()){
if(!itemIds.contains(ingredient.getItemType())){
//ingredient is not in inventory
foundAllIngredients = false;
currentRootId = ingredient.getItemType();
ItemSourcingData sourcingForCurrentReagent = this.getCurrentDependencyRecursive(entity, inventoryIds, ingredient.getItemType());
if(sourcingForCurrentReagent == null){
recipeIsSourceable = false;
break;
}
if(!inventoryIds.contains(ingredient.getItemType())){
//ingredient is not in inventory
foundAllIngredients = false;
ingredientToSource = sourcingForCurrentReagent;
}
}
if(!recipeIsSourceable){
continue;
}
if(foundAllIngredients){
craftableRecipe = recipeData;
break;
} else {
return ingredientToSource;
}
}
if(craftableRecipe != null){
return sourcingData;
}
}
}
//unable to source this item
return null;
}

View File

@ -39,7 +39,7 @@ public class SolveSourcingTreeNode implements AITreeNode {
ItemSourcingTree sourcingTree = SolveSourcingTreeNode.getItemSourcingTree(blackboard);
ItemSourcingData sourcingData = sourcingTree.getCurrentDependency(entity);
if(sourcingData == null){
throw new Error("Source data is null!");
throw new Error("Source data is null! " + itemId);
}
//set the type to harvest if this is a harvest type
if(sourcingData.getHarvestTargets().size() > 0){

View File

@ -48,10 +48,9 @@ public class CharacterService {
public static CreatureTemplate getTemplate(int playerId, int characterId){
DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT id, dataVal FROM charaData WHERE playerId=? AND id=?;",playerId, characterId);
if(result.hasResult()){
Gson gson = new Gson();
//if we get a valid response from the database, check that it actually matches hashes
for(DatabaseResultRow row : result){
CreatureTemplate template = gson.fromJson(row.getAsString("dataVal"),CreatureTemplate.class);
CreatureTemplate template = SerializationUtils.deserialize(row.getAsString("dataVal"),CreatureTemplate.class);
return template;
}
}
@ -66,13 +65,12 @@ public class CharacterService {
*/
public static List<CharacterDescription> getCharacters(int playerId){
DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT id, dataVal FROM charaData WHERE playerId=?;",playerId);
Gson gson = new Gson();
List<CharacterDescription> rVal = new LinkedList<CharacterDescription>();
if(result.hasResult()){
//if we get a valid response from the database, check that it actually matches hashes
for(DatabaseResultRow row : result){
CharacterDescription description = new CharacterDescription();
CreatureTemplate template = gson.fromJson(row.getAsString("dataVal"),CreatureTemplate.class);
CreatureTemplate template = SerializationUtils.deserialize(row.getAsString("dataVal"),CreatureTemplate.class);
description.setTemplate(template);
description.setId(row.getAsInteger("id") + "");
rVal.add(description);
@ -150,4 +148,24 @@ public class CharacterService {
);
}
/**
* Gets all characters
* @return The list of all characters
*/
public static List<CharacterDescription> getAllCharacters(){
DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT id, dataVal FROM charaData");
List<CharacterDescription> rVal = new LinkedList<CharacterDescription>();
if(result.hasResult()){
//if we get a valid response from the database, check that it actually matches hashes
for(DatabaseResultRow row : result){
CharacterDescription description = new CharacterDescription();
CreatureTemplate template = SerializationUtils.deserialize(row.getAsString("dataVal"),CreatureTemplate.class);
description.setTemplate(template);
description.setId(row.getAsInteger("id") + "");
rVal.add(description);
}
}
return rVal;
}
}

View File

@ -21,7 +21,6 @@ import electrosphere.util.FileUtils;
import java.util.Random;
import org.joml.Vector3d;
import org.joml.Vector3i;
/**

View File

@ -1,8 +1,12 @@
package electrosphere.server.macro;
import java.io.File;
import java.util.List;
import electrosphere.client.entity.character.CharacterDescription;
import electrosphere.game.data.block.BlockFab;
import electrosphere.server.character.CharacterService;
import electrosphere.server.macro.character.Character;
import electrosphere.server.macro.structure.Structure;
import electrosphere.util.FileUtils;
@ -33,6 +37,18 @@ public class MacroDataLoader {
structure.setFab(fab);
}
//inject characters from character service
List<CharacterDescription> characters = CharacterService.getAllCharacters();
for(CharacterDescription desc : characters){
int targetId = Integer.parseInt(desc.getId());
Character macroCharacter = rVal.getCharacter(targetId);
if(macroCharacter == null){
macroCharacter = new Character();
macroCharacter.setId(targetId);
rVal.characters.add(macroCharacter);
}
}
return rVal;
}