/// <summary> /// Attempts to export produce for a village. /// We first check if a group exporting this produce type exists /// If so, then we do not send another /// If not, then we remove the exported items from the settlement inventory, and add /// them to the traders inventory. We then send this data to /// </summary> private void VillageExport(EconomicItemType type) { EntityGroup.GroupType groupType = type.GetTypeFromExport(); if (HasEntityGroupOfType(groupType)) { return; } EconomicInventory traderInventory = new EconomicInventory(); //We iterate the surplus and add any relevent items to the inventory foreach (KeyValuePair <EconomicItem, int> surplus in Surplus) { //If the surplus item is of correct type if (surplus.Key.ExportType == type) { //We add to the trader inventory, remove it from the settlement inventory traderInventory.AddItem(surplus.Key, surplus.Value); Inventory.RemoveItem(surplus.Key, surplus.Value); //And then finally remove from the surplus //Surplus.Remove(surplus.Key); } } //Create the group //TODO - decide which entities will form the group EntityGroup group = WorldEventManager.Instance.SpawnVillageTrader(this, type, traderInventory, null); if (group != null) { Debug.Log("Group of type " + group.Type + " exporting from " + Settlement); } else { Debug.Log("Null group"); } if (group == null) { Inventory.AddAll(traderInventory.GetAllItems()); } else { CurrentActiveGroups.Add(group); foreach (KeyValuePair <EconomicItem, int> kvp in traderInventory.GetAllItems()) { Surplus.Remove(kvp.Key); } } }
public override bool OnReachDestination(Vec2i position) { //If we haven't sold yet, then we are at our desitnation and must sell produce if (!HasSold) { Debug.Log("Village trader has sold"); //We sell all items to the settlement int income = Task.End.Import(EconomicInventory.GetAllItems()); //We then iterate each desired purchase and attempt to buy from settlement foreach (KeyValuePair <EconomicItem, int> desiredPurch in Task.DesiredPurchases) { //We attempt to buy if (Task.End.AttemptExport(desiredPurch.Key, desiredPurch.Value, income, out float remainingMoney, out int totalPurched)) { EconomicInventory.AddItem(desiredPurch.Key, totalPurched); income = (int)remainingMoney; } } Debug.Log("Finding path back home"); //After we have sold, we set the path as heading back to the home settlement. GenerateNewPath(Task.Start.Settlement.BaseChunk); HasSold = true; return(true); } else { Debug.Log("back home"); //if we have reached the destination now, we are back at our home settlement foreach (var kvp in EconomicInventory.GetAllItems()) { Task.Start.Inventory.AddItem(kvp.Key, kvp.Value); } //As the task is complete, this group should be destoryed ShouldDestroy = true; Task.Start.EntityGroupReturn(this); return(false); } }
/// <summary> /// Updates the settlement economy for this tick. /// First adds all raw production to the settlement inventory, /// we then subtract all the required use per tick /// Then attempts to run all productions available, taking from the inventory /// its produce will then be added to the inventory /// </summary> public void Tick() { //We first iterate all the raw production and add to inventory foreach (KeyValuePair <EconomicItem, int> kvp in RawProductionPerTick) { Inventory.AddItem(kvp.Key, kvp.Value); } //We then interate all the use per tick andsubtract from the inventory foreach (KeyValuePair <EconomicItem, int> kvp in UsePerTick) { int rem = Inventory.RemoveItem(kvp.Key, kvp.Value); if (rem < 0) { // Debug.Log(World.Instance.GetSettlement(SettlementID).ToString() + " has run out of " + kvp.Key); // Debug.Log("RUN OUT OF " + kvp.Key); } } //We iterate all the productions, and calculate their productions foreach (KeyValuePair <EconomicProduction, int> prod in EconomicProduction) { CalculateEconomicProduction(prod.Key, prod.Value); } Surplus.Clear(); SurlusByExportType.Clear(); SurplusByTypeCount.Clear(); //We order our surplus by item type - ready for exports int surplusCount = 0; RequiredImports.Clear(); //We iterate all the items in our inventory foreach (KeyValuePair <EconomicItem, int> allItems in Inventory.GetAllItems()) { int itemCount = allItems.Value; //If this item has a desired stock level if (DesiredItemStock.TryGetValue(allItems.Key, out int desiredStock)) { //We calculate our surplus int surplus = itemCount - desiredStock; //if negative, then we add to required imports if (surplus < 0) { if (!RequiredImports.ContainsKey(allItems.Key)) { RequiredImports.Add(allItems.Key, 0); } RequiredImports[allItems.Key] -= surplus; } else {//if positive, we add to surplus if (!Surplus.ContainsKey(allItems.Key)) { Surplus.Add(allItems.Key, 0); } Surplus[allItems.Key] += surplus; surplusCount += surplus; //We check if we already have included a surplus of this export type if (!SurplusByTypeCount.ContainsKey(allItems.Key.ExportType)) { SurplusByTypeCount.Add(allItems.Key.ExportType, 0); } SurplusByTypeCount[allItems.Key.ExportType] += surplus; } } else { if (!Surplus.ContainsKey(allItems.Key)) { Surplus.Add(allItems.Key, 0); } //We check if we already have included a surplus of this export type if (!SurplusByTypeCount.ContainsKey(allItems.Key.ExportType)) { SurplusByTypeCount.Add(allItems.Key.ExportType, 0); } Surplus[allItems.Key] += allItems.Value; SurplusByTypeCount[allItems.Key.ExportType] += allItems.Value; } } //If this settlement is a village, then we desire to export any surplus produce to near by places if (Settlement.SettlementType == SettlementType.VILLAGE) { int foodSurplus = 0; int animalSurplus = 0; int oreSurplus = 0; int woodSurplus = 0; SurplusByTypeCount.TryGetValue(EconomicItemType.food, out foodSurplus); SurplusByTypeCount.TryGetValue(EconomicItemType.animalProduce, out animalSurplus); SurplusByTypeCount.TryGetValue(EconomicItemType.ore, out oreSurplus); SurplusByTypeCount.TryGetValue(EconomicItemType.wood, out woodSurplus); if (foodSurplus > 2000) { VillageExport(EconomicItemType.food); } if (animalSurplus > 1000) { VillageExport(EconomicItemType.animalProduce); } if (oreSurplus > 1000) { VillageExport(EconomicItemType.ore); } if (woodSurplus > 1000) { VillageExport(EconomicItemType.wood); } } //if this settlemet is a village, then we check how much surplus stuff we have }
/// <summary> /// Calculates the economic item production per tick for this village based on the resources in the eclcosed chunks /// Adds building plans based on these production amounts /// Calculates the economic items used per tick /// Calculates the start inventory, and the desired amounts to keep in the inventory /// </summary> /// <param name="settlementResources"></param> /// <param name="shell"></param> private void GenerateVillageEconomy(Dictionary <ChunkResource, float> settlementResources, SettlementShell shell) { List <BuildingPlan> reqBuildings = new List <BuildingPlan>(); //A measure of how much of each resource is produced per tick Dictionary <EconomicItem, int> producePerTick = new Dictionary <EconomicItem, int>(); //How much of each item is used per tick Dictionary <EconomicItem, int> usePerTick = new Dictionary <EconomicItem, int>(); EconomicInventory economicInventory = new EconomicInventory(); Dictionary <EconomicItem, int> DesiredInventoryAmounts = new Dictionary <EconomicItem, int>(); //Villages only take raw production (of farms and wood) if (settlementResources.TryGetValue(ChunkResource.wheatFarm, out float v) && v > 1) { reqBuildings.Add(Building.WHEATFARM); foreach (EconomicItem it in ChunkResource.wheatFarm.GetEconomicItem()) { if (!producePerTick.ContainsKey(it)) { producePerTick.Add(it, 0); } producePerTick[it] += ((int)v * 10); } } if (settlementResources.TryGetValue(ChunkResource.vegetableFarm, out float v0) && v0 > 1) { reqBuildings.Add(Building.VEGFARM); foreach (EconomicItem it in ChunkResource.vegetableFarm.GetEconomicItem()) { if (!producePerTick.ContainsKey(it)) { producePerTick.Add(it, 0); } producePerTick[it] += ((int)v * 10); } } if (settlementResources.TryGetValue(ChunkResource.silkFarm, out float v1) && v1 > 1) { reqBuildings.Add(Building.SILKFARM); foreach (EconomicItem it in ChunkResource.silkFarm.GetEconomicItem()) { if (!producePerTick.ContainsKey(it)) { producePerTick.Add(it, 0); } producePerTick[it] += ((int)v1 * 4); } } if (settlementResources.TryGetValue(ChunkResource.cattleFarm, out float v2) && v2 > 1) { reqBuildings.Add(Building.CATTLEFARM); foreach (EconomicItem it in ChunkResource.cattleFarm.GetEconomicItem()) { if (!producePerTick.ContainsKey(it)) { producePerTick.Add(it, 0); } producePerTick[it] += ((int)v2); } } if (settlementResources.TryGetValue(ChunkResource.sheepFarm, out float v3) && v3 > 1) { reqBuildings.Add(Building.SHEEPFARM); foreach (EconomicItem it in ChunkResource.sheepFarm.GetEconomicItem()) { if (!producePerTick.ContainsKey(it)) { producePerTick.Add(it, 0); } producePerTick[it] += ((int)v3); } } if (settlementResources.TryGetValue(ChunkResource.wood, out float v4) && v4 > 1) { reqBuildings.Add(Building.WOODCUTTER); foreach (EconomicItem it in ChunkResource.wood.GetEconomicItem()) { if (!producePerTick.ContainsKey(it)) { producePerTick.Add(it, 0); } producePerTick[it] += ((int)v4); } } if (settlementResources.TryGetValue(ChunkResource.ironOre, out float v5) && v5 > 1) { reqBuildings.Add(Building.IRONMINE); foreach (EconomicItem it in ChunkResource.ironOre.GetEconomicItem()) { if (!producePerTick.ContainsKey(it)) { producePerTick.Add(it, 0); } producePerTick[it] += ((int)v5); } } if (settlementResources.TryGetValue(ChunkResource.silverOre, out float v6) && v6 > 1) { reqBuildings.Add(Building.SILVERMINE); foreach (EconomicItem it in ChunkResource.silverOre.GetEconomicItem()) { if (!producePerTick.ContainsKey(it)) { producePerTick.Add(it, 0); } producePerTick[it] += ((int)v6); } } if (settlementResources.TryGetValue(ChunkResource.goldOre, out float v7) && v7 > 1) { reqBuildings.Add(Building.GOLDMINE); foreach (EconomicItem it in ChunkResource.goldOre.GetEconomicItem()) { if (!producePerTick.ContainsKey(it)) { producePerTick.Add(it, 0); } producePerTick[it] += ((int)v7); } } usePerTick.Add(Economy.Bread, 5); usePerTick.Add(Economy.Vegetables, 5); usePerTick.Add(Economy.Clothes, 1); //Calculates the amount foreach (KeyValuePair <EconomicItem, int> kvp in usePerTick) { DesiredInventoryAmounts.Add(kvp.Key, kvp.Value * Economy.KEEP_IN_INVENTORY_MULT); economicInventory.AddItem(kvp.Key, DesiredInventoryAmounts[kvp.Key]); } shell.RequiredBuildings = reqBuildings; EconomyData data = new EconomyData(); data.Inventory = economicInventory; data.UsePerTick = usePerTick; data.RawProductionPerTick = producePerTick; data.DesiredItemStock = DesiredInventoryAmounts; data.EconomicProduction = new Dictionary <EconomicProduction, int>(); SettlementEconomy econ = new SettlementEconomy(shell, data); }
private void GenerateTownEconomy(Dictionary <ChunkResource, float> settlementResources, SettlementShell shell) { List <BuildingPlan> reqBuildings = new List <BuildingPlan>(); //A measure of how much of each resource is produced per tick Dictionary <EconomicItem, int> rawProductionPerTick = new Dictionary <EconomicItem, int>(); //A measure of how much can be produced by industry Dictionary <EconomicProduction, int> productionPerTick = new Dictionary <EconomicProduction, int>(); //How much of each item is used per tick (excluding economy) Dictionary <EconomicItem, int> usePerTick = new Dictionary <EconomicItem, int>(); EconomicInventory economicInventory = new EconomicInventory(); Dictionary <EconomicItem, int> desiredStock = new Dictionary <EconomicItem, int>(); usePerTick.Add(Economy.Bread, 15); usePerTick.Add(Economy.Vegetables, 10); usePerTick.Add(Economy.Clothes, 3); //Use a small amount of weapons and armour per tick usePerTick.Add(Economy.LeatherArmour, 1); usePerTick.Add(Economy.IronWeapons, 1); SettlementProductionAbility productionAbility = new SettlementProductionAbility(); //All towns will have a bakery, this will produce bread from wheat reqBuildings.Add(Building.BAKERY); productionPerTick.Add(Economy.WheatToBread, 50); economicInventory.AddItem(Economy.Wheat, 500); productionAbility.HasButcher = true; productionPerTick.Add(Economy.CowToBeef, 5); productionPerTick.Add(Economy.SheepToMutton, 5); //If we are in a forrest, then the town till cut wood & make into planks if (settlementResources.TryGetValue(ChunkResource.wood, out float v) && v > 1) { reqBuildings.Add(Building.WOODCUTTER); reqBuildings.Add(Building.LUMBERMILL); int rawProduce = (int)v * 2; rawProductionPerTick.Add(ChunkResource.wood.GetEconomicItem()[0], rawProduce); //Takes 1 log and make 3 planks //We set the production such that it wished to import as much wood as possible productionPerTick.Add(Economy.WoodLogToPlank, (int)(rawProduce * GenRan.Random(2, 4))); productionAbility.HasLumberMill = true; } bool hasSmelt = false; if (settlementResources.TryGetValue(ChunkResource.ironOre, out float v1) && v1 > 1) { hasSmelt = true; reqBuildings.Add(Building.SMELTER); reqBuildings.Add(Building.BLACKSMITH); //We add some planks to start so we can produce weapons from start economicInventory.AddItem(Economy.WoodPlank, 5000); rawProductionPerTick.Add(Economy.IronOre, (int)v1); productionAbility.HasSmelter = true; productionPerTick.Add(Economy.Iron_OreToBar, (int)(v1 * GenRan.Random(2, 4))); productionPerTick.Add(Economy.IronToWeapon, 3); productionPerTick.Add(Economy.LeatherToArmour, 3); } if (settlementResources.TryGetValue(ChunkResource.silverOre, out float v2) && v2 > 1) { if (!hasSmelt) { reqBuildings.Add(Building.SMELTER); } rawProductionPerTick.Add(Economy.SilverOre, (int)v2); productionAbility.HasSmelter = true; productionPerTick.Add(Economy.Silver_OreToBar, (int)(v2 * GenRan.Random(2, 4))); } if (settlementResources.TryGetValue(ChunkResource.goldOre, out float v3) && v3 > 1) { if (!hasSmelt) { reqBuildings.Add(Building.SMELTER); } rawProductionPerTick.Add(Economy.GoldOre, (int)v3); productionAbility.HasSmelter = true; productionPerTick.Add(Economy.Gold_OreToBar, (int)(v3 * GenRan.Random(2, 4))); } //Calculates the amount foreach (KeyValuePair <EconomicItem, int> kvp in usePerTick) { int amount = kvp.Value * Economy.KEEP_IN_INVENTORY_MULT; desiredStock.Add(kvp.Key, amount); economicInventory.AddItem(kvp.Key, amount); } EconomyData data = new EconomyData(); data.Inventory = economicInventory; data.UsePerTick = usePerTick; data.RawProductionPerTick = rawProductionPerTick; data.DesiredItemStock = desiredStock; data.EconomicProduction = new Dictionary <EconomicProduction, int>(); data.ProductionAbility = productionAbility; SettlementEconomy econ = new SettlementEconomy(shell, data); shell.RequiredBuildings = reqBuildings; //Set the economy }