This commit is contained in:
parent
48622bb08f
commit
f0ff713413
@ -1634,6 +1634,8 @@ AI work
|
||||
Many new AI trees
|
||||
- AI can seek out items
|
||||
- AI can harvest entities
|
||||
- AI can pick up items
|
||||
- AI can craft
|
||||
|
||||
|
||||
|
||||
|
||||
@ -735,12 +735,12 @@ public class InventoryUtils {
|
||||
rVal.addAll(equipInventory.getItems());
|
||||
}
|
||||
if(InventoryUtils.hasNaturalInventory(creature)){
|
||||
UnrelationalInventoryState equipInventory = InventoryUtils.getNaturalInventory(creature);
|
||||
rVal.addAll(equipInventory.getItems());
|
||||
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(creature);
|
||||
rVal.addAll(naturalInventory.getItems());
|
||||
}
|
||||
if(InventoryUtils.hasToolbarInventory(creature)){
|
||||
RelationalInventoryState equipInventory = InventoryUtils.getToolbarInventory(creature);
|
||||
rVal.addAll(equipInventory.getItems());
|
||||
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(creature);
|
||||
rVal.addAll(toolbarInventory.getItems());
|
||||
}
|
||||
//filter null items
|
||||
rVal = rVal.stream().filter((Entity el) -> {return el != null;}).collect(Collectors.toList());
|
||||
|
||||
@ -27,7 +27,16 @@ public class ItemSourcingData {
|
||||
* Fell a tree
|
||||
*/
|
||||
TREE,
|
||||
/**
|
||||
* Pick up the item off the floor
|
||||
*/
|
||||
PICKUP,
|
||||
}
|
||||
|
||||
/**
|
||||
* The goal item type
|
||||
*/
|
||||
String goalItem;
|
||||
|
||||
/**
|
||||
* The list of recipes that create this item
|
||||
@ -46,11 +55,13 @@ public class ItemSourcingData {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param goalItem The item that this object stores sources of (ie if this is rocks, all the source lists should contain ways to get rocks)
|
||||
* @param recipes The recipes to source from
|
||||
* @param harvestTargets The objects to harvest from
|
||||
* @param trees The trees to drop from
|
||||
*/
|
||||
public ItemSourcingData(List<RecipeData> recipes, List<CommonEntityType> harvestTargets, List<FoliageType> trees){
|
||||
public ItemSourcingData(String goalItem, List<RecipeData> recipes, List<CommonEntityType> harvestTargets, List<FoliageType> trees){
|
||||
this.goalItem = goalItem;
|
||||
this.recipes = recipes;
|
||||
this.harvestTargets = harvestTargets;
|
||||
this.trees = trees;
|
||||
@ -80,6 +91,14 @@ public class ItemSourcingData {
|
||||
return trees;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item that this object stores sources of (ie if this is rocks, all the source lists should contain ways to get rocks)
|
||||
* @return The item type id
|
||||
*/
|
||||
public String getGoalItem(){
|
||||
return goalItem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ public class ItemSourcingMap {
|
||||
}
|
||||
|
||||
//store the sourcing data
|
||||
ItemSourcingData sourcingData = new ItemSourcingData(recipes, harvestTargets, trees);
|
||||
ItemSourcingData sourcingData = new ItemSourcingData(item.getId(), recipes, harvestTargets, trees);
|
||||
sourcingMap.itemSourcingDataMap.put(item.getId(),sourcingData);
|
||||
}
|
||||
|
||||
|
||||
@ -1,27 +1,15 @@
|
||||
package electrosphere.net.server.protocol;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||
import electrosphere.entity.state.inventory.RelationalInventoryState;
|
||||
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
|
||||
import electrosphere.entity.state.item.ServerChargeState;
|
||||
import electrosphere.game.data.crafting.RecipeData;
|
||||
import electrosphere.game.data.crafting.RecipeIngredientData;
|
||||
import electrosphere.game.data.item.Item;
|
||||
import electrosphere.game.data.item.ItemDataMap;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||
import electrosphere.net.server.ServerConnectionHandler;
|
||||
import electrosphere.net.template.ServerProtocolTemplate;
|
||||
import electrosphere.server.datacell.ServerDataCell;
|
||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||
import electrosphere.server.player.CraftingActions;
|
||||
import electrosphere.server.player.PlayerActions;
|
||||
|
||||
/**
|
||||
@ -108,7 +96,7 @@ public class InventoryProtocol implements ServerProtocolTemplate<InventoryMessag
|
||||
Entity workshopEntity = EntityLookupUtils.getEntityById(message.getstationId());
|
||||
RecipeData recipe = Globals.gameConfigCurrent.getRecipeMap().getType(message.getrecipeId());
|
||||
if(target != null && recipe != null){
|
||||
this.attemptCraft(target,workshopEntity,recipe);
|
||||
CraftingActions.attemptCraft(target,workshopEntity,recipe);
|
||||
// System.out.println(message.getentityId() + " " + message.getstationId() + " " + message.getrecipeId());
|
||||
// InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
||||
}
|
||||
@ -122,148 +110,4 @@ public class InventoryProtocol implements ServerProtocolTemplate<InventoryMessag
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to craft an item
|
||||
* @param crafter The entity performing the crafting
|
||||
* @param station The (optional) station for crafting
|
||||
* @param recipe The recipe to craft
|
||||
*/
|
||||
private void attemptCraft(Entity crafter, Entity station, RecipeData recipe){
|
||||
if(InventoryUtils.serverGetInventoryState(crafter) == null){
|
||||
return;
|
||||
}
|
||||
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(crafter);
|
||||
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(crafter);
|
||||
|
||||
//get data obj
|
||||
ItemDataMap itemMap = Globals.gameConfigCurrent.getItemMap();
|
||||
|
||||
//get reagents
|
||||
List<Entity> reagentList = new LinkedList<Entity>();
|
||||
boolean hasReagents = true;
|
||||
Map<String,Integer> ingredientTargetMap = new HashMap<String,Integer>();
|
||||
Map<String,Integer> ingredientAccretionMap = new HashMap<String,Integer>();
|
||||
//find the reagents we're going to use to craft
|
||||
for(RecipeIngredientData ingredient : recipe.getIngredients()){
|
||||
ingredientTargetMap.put(ingredient.getItemType(),ingredient.getCount());
|
||||
ingredientAccretionMap.put(ingredient.getItemType(),0);
|
||||
int found = 0;
|
||||
if(naturalInventory != null){
|
||||
for(Entity itemEnt : naturalInventory.getItems()){
|
||||
if(itemMap.getItem(itemEnt).getId().matches(ingredient.getItemType())){
|
||||
if(ServerChargeState.hasServerChargeState(itemEnt)){
|
||||
ServerChargeState serverChargeState = ServerChargeState.getServerChargeState(itemEnt);
|
||||
found = found + serverChargeState.getCharges();
|
||||
} else {
|
||||
found++;
|
||||
}
|
||||
reagentList.add(itemEnt);
|
||||
}
|
||||
if(found >= ingredient.getCount()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
for(Entity itemEnt : toolbarInventory.getItems()){
|
||||
if(itemEnt == null){
|
||||
continue;
|
||||
}
|
||||
if(itemMap.getItem(itemEnt).getId().matches(ingredient.getItemType())){
|
||||
if(ServerChargeState.hasServerChargeState(itemEnt)){
|
||||
ServerChargeState serverChargeState = ServerChargeState.getServerChargeState(itemEnt);
|
||||
found = found + serverChargeState.getCharges();
|
||||
} else {
|
||||
found++;
|
||||
}
|
||||
reagentList.add(itemEnt);
|
||||
}
|
||||
if(found >= ingredient.getCount()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(found < ingredient.getCount()){
|
||||
hasReagents = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(hasReagents){
|
||||
for(Entity reagentEnt : reagentList){
|
||||
|
||||
//determine how many we need to still remove
|
||||
Item itemData = itemMap.getItem(reagentEnt);
|
||||
int targetToRemove = ingredientTargetMap.get(itemData.getId());
|
||||
int alreadyFound = ingredientAccretionMap.get(itemData.getId());
|
||||
if(alreadyFound > targetToRemove){
|
||||
throw new Error("Removed too many ingredients! " + targetToRemove + " " + alreadyFound);
|
||||
} else if(alreadyFound == targetToRemove){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(ServerChargeState.hasServerChargeState(reagentEnt)){
|
||||
ServerChargeState serverChargeState = ServerChargeState.getServerChargeState(reagentEnt);
|
||||
int available = serverChargeState.getCharges();
|
||||
|
||||
if(available > targetToRemove - alreadyFound){
|
||||
int chargesToRemove = targetToRemove - alreadyFound;
|
||||
serverChargeState.attemptAddCharges(-chargesToRemove);
|
||||
//just remove charges
|
||||
ingredientAccretionMap.put(itemData.getId(),alreadyFound + chargesToRemove);
|
||||
} else {
|
||||
//remove item entirely (consuming all charges)
|
||||
if(naturalInventory != null){
|
||||
naturalInventory.removeItem(reagentEnt);
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
toolbarInventory.tryRemoveItem(reagentEnt);
|
||||
}
|
||||
this.deleteItemInInventory(crafter, reagentEnt);
|
||||
ingredientAccretionMap.put(itemData.getId(),alreadyFound + available);
|
||||
}
|
||||
} else {
|
||||
if(naturalInventory != null){
|
||||
naturalInventory.removeItem(reagentEnt);
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
toolbarInventory.tryRemoveItem(reagentEnt);
|
||||
}
|
||||
this.deleteItemInInventory(crafter, reagentEnt);
|
||||
ingredientAccretionMap.put(itemData.getId(),alreadyFound + 1);
|
||||
}
|
||||
}
|
||||
for(RecipeIngredientData product : recipe.getProducts()){
|
||||
Item productType = itemMap.getItem(product.getItemType());
|
||||
if(productType == null){
|
||||
throw new Error("Could not locate product definition! " + productType + " " + product.getItemType());
|
||||
}
|
||||
InventoryUtils.serverCreateInventoryItem(crafter, product.getItemType(), product.getCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete an item that is in an inventory
|
||||
* @param parent The parent entity that contains the in-inventory item
|
||||
* @param itemEnt The item that is in an inventory
|
||||
*/
|
||||
private void deleteItemInInventory(Entity parent, Entity inInventory){
|
||||
//the parent entity's data cell
|
||||
ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(parent);
|
||||
//broadcast destroy entity
|
||||
dataCell.broadcastNetworkMessage(InventoryMessage.constructremoveItemFromInventoryMessage(inInventory.getId()));
|
||||
//remove the inventories
|
||||
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
|
||||
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
|
||||
if(naturalInventory != null){
|
||||
naturalInventory.removeItem(inInventory);
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
toolbarInventory.tryRemoveItem(inInventory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -50,6 +50,11 @@ public class BlackboardKeys {
|
||||
*/
|
||||
public static final String ITEM_SOURCING_DATA = "itemSourcingData";
|
||||
|
||||
/**
|
||||
* The category of item to target
|
||||
*/
|
||||
public static final String ITEM_TARGET_CATEGORY = "itemTargetCategory";
|
||||
|
||||
/**
|
||||
* The type of entity to try to harvest
|
||||
*/
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package electrosphere.server.ai.nodes.actions.interact;
|
||||
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.game.data.crafting.RecipeData;
|
||||
import electrosphere.game.data.item.source.ItemSourcingData;
|
||||
import electrosphere.server.ai.blackboard.Blackboard;
|
||||
import electrosphere.server.ai.nodes.AITreeNode;
|
||||
import electrosphere.server.ai.nodes.plan.SolveSourcingTreeNode;
|
||||
import electrosphere.server.player.CraftingActions;
|
||||
|
||||
/**
|
||||
* Tries to craft an item
|
||||
*/
|
||||
public class CraftNode implements AITreeNode {
|
||||
|
||||
@Override
|
||||
public AITreeNodeResult evaluate(Entity entity, Blackboard blackboard) {
|
||||
ItemSourcingData sourcingData = SolveSourcingTreeNode.getItemSourcingData(blackboard);
|
||||
for(RecipeData recipe : sourcingData.getRecipes()){
|
||||
if(CraftingActions.canCraft(entity, null, recipe)){
|
||||
CraftingActions.attemptCraft(entity, null, recipe);
|
||||
return AITreeNodeResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
return AITreeNodeResult.FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,11 +1,17 @@
|
||||
package electrosphere.server.ai.nodes.checks.inventory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||
import electrosphere.game.data.item.source.ItemSourcingData;
|
||||
import electrosphere.game.data.item.source.ItemSourcingData.SourcingType;
|
||||
import electrosphere.server.ai.blackboard.Blackboard;
|
||||
import electrosphere.server.ai.nodes.AITreeNode;
|
||||
import electrosphere.server.ai.nodes.plan.SolveSourcingTreeNode;
|
||||
import electrosphere.server.ai.services.NearbyEntityService;
|
||||
|
||||
/**
|
||||
* Checks if the supplied type of sourcing is the path for the current target item to acquire
|
||||
@ -17,12 +23,19 @@ public class SourcingTypeNode implements AITreeNode {
|
||||
*/
|
||||
SourcingType sourcingType;
|
||||
|
||||
/**
|
||||
* The blackboard key storing the target entity type id
|
||||
*/
|
||||
String targetTypeKey;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param targetTypeKey The blackboard key storing the target entity type id
|
||||
* @param sourcingType The type of sourcing to check
|
||||
*/
|
||||
public SourcingTypeNode(SourcingType sourcingType){
|
||||
public SourcingTypeNode(SourcingType sourcingType, String targetTypeKey){
|
||||
this.sourcingType = sourcingType;
|
||||
this.targetTypeKey = targetTypeKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -38,6 +51,15 @@ public class SourcingTypeNode implements AITreeNode {
|
||||
|
||||
//succeed based on the type of sourcing that this node is set for
|
||||
switch(this.sourcingType){
|
||||
case PICKUP: {
|
||||
//see if the entity is in the vicinity
|
||||
String targetEntityType = (String)blackboard.get(this.targetTypeKey);
|
||||
Collection<Entity> nearbyEntities = NearbyEntityService.getNearbyEntities(blackboard);
|
||||
List<String> types = nearbyEntities.stream().map((Entity ent) -> {return CommonEntityUtils.getEntitySubtype(ent);}).collect(Collectors.toList());
|
||||
if(types.contains(targetEntityType)){
|
||||
return AITreeNodeResult.SUCCESS;
|
||||
}
|
||||
} break;
|
||||
case RECIPE: {
|
||||
if(sourcingData.getRecipes().size() > 0){
|
||||
return AITreeNodeResult.SUCCESS;
|
||||
|
||||
@ -46,6 +46,7 @@ public class SolveSourcingTreeNode implements AITreeNode {
|
||||
HarvestNode.setHarvestTargetType(blackboard, sourcingData.getHarvestTargets().get(0).getId());
|
||||
}
|
||||
SolveSourcingTreeNode.setItemSourcingData(blackboard, sourcingData);
|
||||
SolveSourcingTreeNode.setItemTargetCategory(blackboard, sourcingData.getGoalItem());
|
||||
return AITreeNodeResult.SUCCESS;
|
||||
}
|
||||
|
||||
@ -103,4 +104,31 @@ public class SolveSourcingTreeNode implements AITreeNode {
|
||||
return (ItemSourcingData)blackboard.get(BlackboardKeys.ITEM_SOURCING_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the item target category of the blackboard
|
||||
* @param blackboard The blackboard
|
||||
* @param tree The data
|
||||
*/
|
||||
public static void setItemTargetCategory(Blackboard blackboard, String data){
|
||||
blackboard.put(BlackboardKeys.ITEM_TARGET_CATEGORY, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the blackboard has an item target category
|
||||
* @param blackboard The blackboard
|
||||
* @return The item sourcing data
|
||||
*/
|
||||
public static boolean hasItemTargetCategory(Blackboard blackboard){
|
||||
return blackboard.has(BlackboardKeys.ITEM_TARGET_CATEGORY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item target category of the blackboard
|
||||
* @param blackboard The blackboard
|
||||
* @return The item target category
|
||||
*/
|
||||
public static String getItemTargetCategory(Blackboard blackboard){
|
||||
return (String)blackboard.get(BlackboardKeys.ITEM_TARGET_CATEGORY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@ import electrosphere.collision.CollisionEngine;
|
||||
import electrosphere.game.data.item.source.ItemSourcingData.SourcingType;
|
||||
import electrosphere.server.ai.blackboard.BlackboardKeys;
|
||||
import electrosphere.server.ai.nodes.AITreeNode;
|
||||
import electrosphere.server.ai.nodes.actions.interact.CollectItemNode;
|
||||
import electrosphere.server.ai.nodes.actions.interact.CraftNode;
|
||||
import electrosphere.server.ai.nodes.actions.interact.HarvestNode;
|
||||
import electrosphere.server.ai.nodes.checks.inventory.SourcingTypeNode;
|
||||
import electrosphere.server.ai.nodes.meta.collections.SelectorNode;
|
||||
@ -35,17 +37,27 @@ public class AcquireItemTree {
|
||||
//solve how we're going to get this top level item
|
||||
new SolveSourcingTreeNode(blackboardKey),
|
||||
new SelectorNode(
|
||||
new SequenceNode(
|
||||
new PublishStatusNode("Pick up an item"),
|
||||
//check if we should be sourcing this item by picking it up
|
||||
new SourcingTypeNode(SourcingType.PICKUP, BlackboardKeys.ITEM_TARGET_CATEGORY),
|
||||
//logic to pick up the item
|
||||
new TargetEntityCategoryNode(BlackboardKeys.ITEM_TARGET_CATEGORY),
|
||||
MoveToTarget.create(CollisionEngine.DEFAULT_INTERACT_DISTANCE, BlackboardKeys.ENTITY_TARGET),
|
||||
new CollectItemNode(),
|
||||
new RunnerNode(null)
|
||||
),
|
||||
new SequenceNode(
|
||||
new PublishStatusNode("Craft an item"),
|
||||
//check if we should be sourcing this from a recipe
|
||||
new SourcingTypeNode(SourcingType.RECIPE),
|
||||
//TODO: logic to craft a recipe
|
||||
new SourcingTypeNode(SourcingType.RECIPE, blackboardKey),
|
||||
new CraftNode(),
|
||||
new RunnerNode(null)
|
||||
),
|
||||
new SequenceNode(
|
||||
new PublishStatusNode("Harvest an item"),
|
||||
//check if we should be sourcing this from harvesting foliage
|
||||
new SourcingTypeNode(SourcingType.HARVEST),
|
||||
new SourcingTypeNode(SourcingType.HARVEST, blackboardKey),
|
||||
new TargetEntityCategoryNode(BlackboardKeys.HARVEST_TARGET_TYPE),
|
||||
MoveToTarget.create(CollisionEngine.DEFAULT_INTERACT_DISTANCE, BlackboardKeys.ENTITY_TARGET),
|
||||
new HarvestNode(),
|
||||
@ -54,7 +66,7 @@ public class AcquireItemTree {
|
||||
new SequenceNode(
|
||||
new PublishStatusNode("Fell a tree"),
|
||||
//check if we should be sourcing this from felling a tree
|
||||
new SourcingTypeNode(SourcingType.TREE),
|
||||
new SourcingTypeNode(SourcingType.TREE, blackboardKey),
|
||||
//TODO: logic to fell a tree
|
||||
new RunnerNode(null)
|
||||
)
|
||||
|
||||
216
src/main/java/electrosphere/server/player/CraftingActions.java
Normal file
216
src/main/java/electrosphere/server/player/CraftingActions.java
Normal file
@ -0,0 +1,216 @@
|
||||
package electrosphere.server.player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||
import electrosphere.entity.state.inventory.RelationalInventoryState;
|
||||
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
|
||||
import electrosphere.entity.state.item.ServerChargeState;
|
||||
import electrosphere.game.data.crafting.RecipeData;
|
||||
import electrosphere.game.data.crafting.RecipeIngredientData;
|
||||
import electrosphere.game.data.item.Item;
|
||||
import electrosphere.game.data.item.ItemDataMap;
|
||||
|
||||
/**
|
||||
* Actions around crafting
|
||||
*/
|
||||
public class CraftingActions {
|
||||
|
||||
/**
|
||||
* Attempts to craft an item
|
||||
* @param crafter The entity performing the crafting
|
||||
* @param station The (optional) station for crafting
|
||||
* @param recipe The recipe to craft
|
||||
*/
|
||||
public static void attemptCraft(Entity crafter, Entity station, RecipeData recipe){
|
||||
if(InventoryUtils.serverGetInventoryState(crafter) == null){
|
||||
return;
|
||||
}
|
||||
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(crafter);
|
||||
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(crafter);
|
||||
|
||||
//get data obj
|
||||
ItemDataMap itemMap = Globals.gameConfigCurrent.getItemMap();
|
||||
|
||||
//get reagents
|
||||
List<Entity> reagentList = new LinkedList<Entity>();
|
||||
boolean hasReagents = true;
|
||||
Map<String,Integer> ingredientTargetMap = new HashMap<String,Integer>();
|
||||
Map<String,Integer> ingredientAccretionMap = new HashMap<String,Integer>();
|
||||
//find the reagents we're going to use to craft
|
||||
for(RecipeIngredientData ingredient : recipe.getIngredients()){
|
||||
ingredientTargetMap.put(ingredient.getItemType(),ingredient.getCount());
|
||||
ingredientAccretionMap.put(ingredient.getItemType(),0);
|
||||
int found = 0;
|
||||
if(naturalInventory != null){
|
||||
for(Entity itemEnt : naturalInventory.getItems()){
|
||||
if(itemMap.getItem(itemEnt).getId().matches(ingredient.getItemType())){
|
||||
if(ServerChargeState.hasServerChargeState(itemEnt)){
|
||||
ServerChargeState serverChargeState = ServerChargeState.getServerChargeState(itemEnt);
|
||||
found = found + serverChargeState.getCharges();
|
||||
} else {
|
||||
found++;
|
||||
}
|
||||
reagentList.add(itemEnt);
|
||||
}
|
||||
if(found >= ingredient.getCount()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
for(Entity itemEnt : toolbarInventory.getItems()){
|
||||
if(itemEnt == null){
|
||||
continue;
|
||||
}
|
||||
if(itemMap.getItem(itemEnt).getId().matches(ingredient.getItemType())){
|
||||
if(ServerChargeState.hasServerChargeState(itemEnt)){
|
||||
ServerChargeState serverChargeState = ServerChargeState.getServerChargeState(itemEnt);
|
||||
found = found + serverChargeState.getCharges();
|
||||
} else {
|
||||
found++;
|
||||
}
|
||||
reagentList.add(itemEnt);
|
||||
}
|
||||
if(found >= ingredient.getCount()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(found < ingredient.getCount()){
|
||||
hasReagents = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(hasReagents){
|
||||
for(Entity reagentEnt : reagentList){
|
||||
|
||||
//determine how many we need to still remove
|
||||
Item itemData = itemMap.getItem(reagentEnt);
|
||||
int targetToRemove = ingredientTargetMap.get(itemData.getId());
|
||||
int alreadyFound = ingredientAccretionMap.get(itemData.getId());
|
||||
if(alreadyFound > targetToRemove){
|
||||
throw new Error("Removed too many ingredients! " + targetToRemove + " " + alreadyFound);
|
||||
} else if(alreadyFound == targetToRemove){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(ServerChargeState.hasServerChargeState(reagentEnt)){
|
||||
ServerChargeState serverChargeState = ServerChargeState.getServerChargeState(reagentEnt);
|
||||
int available = serverChargeState.getCharges();
|
||||
|
||||
if(available > targetToRemove - alreadyFound){
|
||||
int chargesToRemove = targetToRemove - alreadyFound;
|
||||
serverChargeState.attemptAddCharges(-chargesToRemove);
|
||||
//just remove charges
|
||||
ingredientAccretionMap.put(itemData.getId(),alreadyFound + chargesToRemove);
|
||||
} else {
|
||||
//remove item entirely (consuming all charges)
|
||||
if(naturalInventory != null){
|
||||
naturalInventory.removeItem(reagentEnt);
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
toolbarInventory.tryRemoveItem(reagentEnt);
|
||||
}
|
||||
InventoryUtils.serverDestroyInventoryItem(reagentEnt);
|
||||
ingredientAccretionMap.put(itemData.getId(),alreadyFound + available);
|
||||
}
|
||||
} else {
|
||||
if(naturalInventory != null){
|
||||
naturalInventory.removeItem(reagentEnt);
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
toolbarInventory.tryRemoveItem(reagentEnt);
|
||||
}
|
||||
InventoryUtils.serverDestroyInventoryItem(reagentEnt);
|
||||
ingredientAccretionMap.put(itemData.getId(),alreadyFound + 1);
|
||||
}
|
||||
}
|
||||
for(RecipeIngredientData product : recipe.getProducts()){
|
||||
Item productType = itemMap.getItem(product.getItemType());
|
||||
if(productType == null){
|
||||
throw new Error("Could not locate product definition! " + productType + " " + product.getItemType());
|
||||
}
|
||||
InventoryUtils.serverCreateInventoryItem(crafter, product.getItemType(), product.getCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the item can be crafted
|
||||
* @param crafter The entity performing the crafting
|
||||
* @param workstation The workstation to perform the crafting at
|
||||
* @param recipe The recipe to craft
|
||||
* @return true if it can perform the recipe, false otherwise
|
||||
*/
|
||||
public static boolean canCraft(Entity crafter, Entity workstation, RecipeData recipe){
|
||||
if(InventoryUtils.serverGetInventoryState(crafter) == null){
|
||||
return false;
|
||||
}
|
||||
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(crafter);
|
||||
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(crafter);
|
||||
|
||||
//get data obj
|
||||
ItemDataMap itemMap = Globals.gameConfigCurrent.getItemMap();
|
||||
|
||||
//get reagents
|
||||
List<Entity> reagentList = new LinkedList<Entity>();
|
||||
boolean hasReagents = true;
|
||||
Map<String,Integer> ingredientTargetMap = new HashMap<String,Integer>();
|
||||
Map<String,Integer> ingredientAccretionMap = new HashMap<String,Integer>();
|
||||
//find the reagents we're going to use to craft
|
||||
for(RecipeIngredientData ingredient : recipe.getIngredients()){
|
||||
ingredientTargetMap.put(ingredient.getItemType(),ingredient.getCount());
|
||||
ingredientAccretionMap.put(ingredient.getItemType(),0);
|
||||
int found = 0;
|
||||
if(naturalInventory != null){
|
||||
for(Entity itemEnt : naturalInventory.getItems()){
|
||||
if(itemMap.getItem(itemEnt).getId().matches(ingredient.getItemType())){
|
||||
if(ServerChargeState.hasServerChargeState(itemEnt)){
|
||||
ServerChargeState serverChargeState = ServerChargeState.getServerChargeState(itemEnt);
|
||||
found = found + serverChargeState.getCharges();
|
||||
} else {
|
||||
found++;
|
||||
}
|
||||
reagentList.add(itemEnt);
|
||||
}
|
||||
if(found >= ingredient.getCount()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
for(Entity itemEnt : toolbarInventory.getItems()){
|
||||
if(itemEnt == null){
|
||||
continue;
|
||||
}
|
||||
if(itemMap.getItem(itemEnt).getId().matches(ingredient.getItemType())){
|
||||
if(ServerChargeState.hasServerChargeState(itemEnt)){
|
||||
ServerChargeState serverChargeState = ServerChargeState.getServerChargeState(itemEnt);
|
||||
found = found + serverChargeState.getCharges();
|
||||
} else {
|
||||
found++;
|
||||
}
|
||||
reagentList.add(itemEnt);
|
||||
}
|
||||
if(found >= ingredient.getCount()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(found < ingredient.getCount()){
|
||||
hasReagents = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hasReagents;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user