public EntityGroupBandits(ChunkStructure home, List <Entity> entities = null, EconomicInventory inventory = null) : base(home.ChunkPos, entities, inventory)
    {
        Vec2i deltaPosition = GenerationRandom.RNG.RandomVec2i(-64, 64);

        Vec2i tChunk = home.ChunkPos + deltaPosition;

        NearGroups = new List <EntityGroup>(20);

        Home = home;
        GenerateNewPath(tChunk);
    }
    /// <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 SettlementEconomy(SettlementShell shell, EconomyData data)
    {
        shell.Economy        = this;
        Inventory            = data.Inventory;
        UsePerTick           = data.UsePerTick;
        RawProductionPerTick = data.RawProductionPerTick;
        ProductionAbility    = data.ProductionAbility;
        DesiredItemStock     = data.DesiredItemStock;
        EconomicProduction   = data.EconomicProduction;

        RequiredImports = new Dictionary <EconomicItem, int>();
        // DesiredImports = new Dictionary<EconomicItem, int>();
        Surplus            = new Dictionary <EconomicItem, int>();
        SurlusByExportType = new Dictionary <EconomicItemType, Dictionary <EconomicItem, int> >();
        SurplusByTypeCount = new Dictionary <EconomicItemType, int>();

        CurrentActiveGroups = new List <EntityGroup>();
    }
Example #4
0
 /// <summary>
 /// Creates a entity group that aims to travel from the start chunk to the end chunk
 /// </summary>
 /// <param name="startChunk"></param>
 /// <param name="endChunk"></param>
 /// <param name="entities"></param>
 public EntityGroup(Vec2i startChunk, List <Entity> entities = null, EconomicInventory inventory = null)
 {
     ShouldDestroy     = false;
     StartChunk        = startChunk;
     CurrentPosition   = startChunk.AsVector2();
     GroupEntityIDs    = new List <int>();
     GroupInventory    = new Inventory();
     EconomicInventory = inventory == null?new EconomicInventory(): inventory;
     if (entities != null)
     {
         foreach (Entity e in entities)
         {
             GroupEntityIDs.Add(e.ID);
             GroupInventory.AddAll(e.Inventory);
             CombatStrength += e.CombatManager.CalculateEntityCombatStrength();
         }
     }
 }
    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>
    /// Spawns an entity group that exports a set type of good from a village, and takes it to the
    /// nearest valid settlement to sell.
    /// </summary>
    /// <param name="home"></param>
    /// <param name="exportType"></param>
    /// <param name="export"></param>
    /// <param name="groupEntities"></param>
    /// <returns></returns>
    public EntityGroup SpawnVillageTrader(SettlementEconomy economy, EconomicItemType exportType, EconomicInventory export, List <Entity> groupEntities)
    {
        Debug.Log("Spawning village trader");
        SettlementEconomy target = null;
        int nearestDist          = -1;

        //We iterate the near settlements in an attempt to find a settlement to import these goods
        foreach (int id in economy.NearSettlementsIDs)
        {
            Settlement set = World.Instance.GetSettlement(id);
            if (set == null)
            {
                continue;
            }
            //We skip other villages
            if (set.SettlementType == SettlementType.VILLAGE)
            {
                continue;
            }

            if (!set.Economy.CanImport(exportType))
            {
                continue;
            }
            int dist = Vec2i.QuickDistance(economy.Settlement.BaseChunk, set.BaseChunk);
            if (nearestDist == -1 || dist < nearestDist)
            {
                nearestDist = dist;
                target      = set.Economy;
            }
        }
        //If a valid settlement is not found to be close,
        if (target == null)
        {
            //We search all settlements
            target = GetNearestImportingSettlement(economy.Settlement, exportType);
            //This should never happen
            if (target == null)
            {
                //in future, the only way this could happen would be if a kingdom cannot trade with any other kingdoms.
                Debug.LogError("Could not find Settlement to import " + exportType + " near to " + economy.Settlement);
                return(null);
            }
        }

        EntityGroup.GroupType groupType = exportType.GetTypeFromExport();

        VillageTraderTask task = new VillageTraderTask();

        task.Start            = economy;
        task.End              = target;
        task.DesiredPurchases = economy.RequiredImports;
        task.ToSell           = export;
        EntityGroup group = new EntityGroupVillageTrader(task, groupType, groupEntities);

        AddEntityGroup(group);
        return(group);
    }
Example #7
0
    /// <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);
    }
Example #8
0
    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
    }