Ejemplo n.º 1
0
        protected override void ReadFrom(Game game, AI ai, string name, SaveReaderText reader)
        {
            base.ReadFrom(game, ai, name, reader);

            type          = reader.Value($"{name}.building_type").ReadBuilding();
            builtPosition = reader.Value($"{name}.built_position").ReadUInt();
        }
Ejemplo n.º 2
0
 public BuildingRef(Building building)
 {
     pos    = building.pos;
     empire = building.empire.id;
     type   = building.type;
     level  = building.level;
 }
Ejemplo n.º 3
0
 public void _on_Buildings_item_activated(int index)
 {
     Building.Type type = (Building.Type)index;
     if (Player.inventoryBuildings.GetItemCount(type) >= 1)
     {
         Player.BuildingSelected = type;
         Delay.StartDelay(this, 0.1f, () => Close(PlayerState.State.Build));
     }
 }
Ejemplo n.º 4
0
        bool CheckMaxInAreaOk(Map map, uint basePosition, int range, Building.Type buildingType, int maxInArea = int.MaxValue)
        {
            if (maxInArea == int.MaxValue)
            {
                return(true);
            }

            return(BuildingsInArea(map, basePosition, range, buildingType, FindBuilding, 1) < maxInArea);
        }
Ejemplo n.º 5
0
 private void InitBuildingSelector()
 {
     buildingSelector.Clear();
     for (int i = 0; i < Building.nbBuildings; i++)
     {
         Building.Type type = (Building.Type)i;
         buildingSelector.AddItem(type.ToString(), Building.textures[type]);
     }
 }
Ejemplo n.º 6
0
 public void _on_BuildingList_item_selected(int index)
 {
     if (index < Building.nbBuildings)
     {
         Building.Type type = (Building.Type)index;
         SetDescription(type);
         buildingSelected = type;
         RefreshBtnPrint();
     }
 }
Ejemplo n.º 7
0
        public AIStateBuildBuilding(Building.Type buildingType)
            : base(AI.State.BuildBuilding)
        {
            if (buildingType >= Building.Type.StoneMine && buildingType <= Building.Type.GoldMine)
            {
                throw new ExceptionFreeserf(ErrorSystemType.AI, "Mines are handled by AIStateFindMinerals");
            }

            type = buildingType;
        }
Ejemplo n.º 8
0
    //Enlever un batiment
    public bool Remove(Building.Type type, int nb)
    {
        bool res = false;

        if (storage[type] - nb >= 0)
        {
            res            = true;
            storage[type] -= nb;
        }
        return(res);
    }
Ejemplo n.º 9
0
    //ici les méthodes

    //Ajouter un batiment
    public bool Add(Building.Type type, int nb)
    {
        bool res = false;

        if (storage[type] + nb < max)
        {
            res            = true;
            storage[type] += nb;
        }
        return(res);
    }
Ejemplo n.º 10
0
 public void SetBuildingSaveStruct(SaveStruct st)
 {
     type            = st.type;
     healthMax       = st.healthMax;
     health          = st.health;
     id              = st.id;
     energy          = st.energy;
     energyMax       = st.energyMax;
     isLinked        = st.isLinked;
     energyhistory   = st.energyhistory;
     powerInhistory  = st.powerInhistory;
     powerOuthistory = st.powerOuthistory;
 }
Ejemplo n.º 11
0
 public BuildingType
 (
     Building.Type type, int occupyingSpace, int maxUnitsOccupyingSpace,
     string name, TimeSpan timeToBuild, TimeSpan timeToDestroy, List <ResourseBunch> necessaryResourses
 )
     : base(
         name, timeToBuild, timeToDestroy, necessaryResourses
         )
 {
     this.Type                   = type;
     this.OccupyingSpace         = occupyingSpace;
     this.MaxUnitsOccupyingSpace = maxUnitsOccupyingSpace;
 }
Ejemplo n.º 12
0
 protected ResourseBuildingType
 (
     double damageRate, double strengthMultipler, double enduranceMultipler,
     Building.Type type, int occupyingSpace, int maxUnitsOccupyingSpace,
     string name, TimeSpan timeToBuild, TimeSpan timeToDestroy, List <ResourseBunch> necessaryResourses
 )
     : base(
         type, occupyingSpace, maxUnitsOccupyingSpace,
         name, timeToBuild, timeToDestroy, necessaryResourses
         )
 {
     this.DamageRate         = damageRate;
     this.StrengthMultipler  = strengthMultipler;
     this.EnduranceMultipler = enduranceMultipler;
 }
 public Building GetBuildingByType(Building.Type type)
 {
     if (allNodes.Count <= 0)
     {
         return(null);
     }
     foreach (Node n in allNodes)
     {
         if (n.building != null && n.building.buildingType == type)
         {
             return(n.building);
         }
     }
     return(null);
 }
Ejemplo n.º 14
0
 private void SetDescription(Building.Type type)
 {
     imageDesc.Texture    = Building.textures[type];
     titleDesc.Text       = type.ToString();
     timeDesc.Text        = Building.times2Create[type].ToString() + "s";
     energyDesc.Text      = "-> " + (Building.times2Create[type] * Printer3D.power) + "e";
     descriptionDesc.Text = Building.descriptions[type];
     ClearItemsList();
     foreach (var loot in Building.crafts[type].loots)
     {
         Control it = (Control)itemBox.Instance();
         it.GetNode <TextureRect>("img").Texture = Item.textures[(int)loot.type];
         it.GetNode <Label>("texte").Text        = Player.inventoryItems.GetItemCount(loot.type) + "/" + loot.amount;
         itemListDesc.AddChild(it);
     }
 }
Ejemplo n.º 15
0
 public static void Revive()
 {
     if (health <= 0)
     {
         FillHealth();
         FillOxygene();
         FillEnergy();
         inventoryUsables   = new StorageUsables(inventoryUsablesSize);
         inventoryItems     = new StorageItems(inventoryItemsSize);
         inventoryLiquids   = new StorageLiquids(inventoryLiquidsSize);
         inventoryBuildings = new StorageBuildings(inventoryBuildingsSize);
         UsableSelected     = Usable.Type.Laser;
         BuildingSelected   = Building.Type.SolarPanel;
         PlayerMouvements.Teleport(World.spawn.x, World.spawn.y);
         PlayerMouvements.canMove = true;
     }
 }
Ejemplo n.º 16
0
        CheckResult NeedBuilding(AI ai, Game game, Player player, Building.Type type)
        {
            if (!ai.HasResourcesForBuilding(type))
            {
                return(CheckResult.NotNeeded);
            }

            var neededForBuilding = Building.Requests[(int)type];
            int inventory         = -1;

            if (type == Building.Type.Hut || type == Building.Type.Tower || type == Building.Type.Fortress)
            {
                if (game.GetFreeKnightCount(player) != 0)
                {
                    return(CheckResult.Needed);
                }
                else
                {
                    return(CheckResult.NeededButNoSpecialistOrResources);
                }
            }
            else
            {
                inventory = game.FindInventoryWithValidSpecialist(player, neededForBuilding.SerfType,
                                                                  neededForBuilding.ResourceType1, neededForBuilding.ResourceType2);
            }

            if (inventory != -1)
            {
                if (inventory > 0xffff)
                {
                    return(CheckResult.NeededButNoGenerics);
                }

                return(CheckResult.Needed);
            }

            if (player.GetResourceCount(neededForBuilding.ResourceType1) != 0 &&
                (neededForBuilding.ResourceType2 == Resource.Type.None || player.GetResourceCount(neededForBuilding.ResourceType2) != 0))
            {
                return(CheckResult.Needed);
            }

            return(CheckResult.NeededButNoSpecialistOrResources);
        }
Ejemplo n.º 17
0
        uint FindSpotNearBuilding(Game game, Player player, int intelligence, Building.Type buildingType, int maxInArea = int.MaxValue)
        {
            var buildings = game.GetPlayerBuildings(player).Where(building => building.BuildingType == buildingType).ToList();

            while (buildings.Count > 0)
            {
                var randomBuilding = buildings[game.RandomInt() % buildings.Count];

                if (CheckMaxInAreaOk(game.Map, randomBuilding.Position, 6, buildingType, maxInArea))
                {
                    return(FindSpotNear(game, player, randomBuilding.Position, 4));
                }

                buildings.Remove(randomBuilding);
            }

            return(Global.INVALID_MAPPOS);
        }
Ejemplo n.º 18
0
    private void ClickBuildState()
    {
        Vector2 playerPos = Convertion.Location2World(PlayerMouvements.instance.Position);
        bool    right     = playerPos.x - 1 < mousePos.x;
        bool    res       = mousePos.y > 0 && mousePos.y <= Chunk.height;

        if (res && MouseInRange(9, true))
        {
            Building.Type type = Player.BuildingSelected;
            if (Player.inventoryBuildings.GetItemCount(type) >= 1)
            {
                Building building = (Building)Building.prefabs[type].Instance();
                building.SetType(type);
                bool succeed = BasicPlacement.PlaceWithMouse(building, GetGlobalMousePosition(), right);
                if (succeed)
                {
                    Player.inventoryBuildings.Remove(type, 1);
                }
            }
        }
    }
Ejemplo n.º 19
0
        // Build a new building.
        public void BuildBuilding(Building.Type type)
        {
            if (AccessRights != Viewer.Access.Player)
            {
                return;
            }

            if (!Game.BuildBuilding(mapCursorPosition, type, player))
            {
                PlaySound(Freeserf.Audio.Audio.TypeSfx.NotAccepted);
                return;
            }

            PlaySound(Freeserf.Audio.Audio.TypeSfx.Accepted);
            ClosePopup();

            // Move cursor to flag.
            var flagPosition = Game.Map.MoveDownRight(mapCursorPosition);

            UpdateMapCursorPosition(flagPosition);
        }
Ejemplo n.º 20
0
    private void BuildState()
    {
        Vector2 vec = mousePos;
        int     x   = (int)mousePos.x;
        int     y   = (int)mousePos.y;
        bool    res = y > 0 && y <= Chunk.height;

        World.UIBlockTilemap.Clear();
        Vector2 playerPos = Convertion.Location2World(PlayerMouvements.instance.Position);
        bool    right     = playerPos.x - 1 < mousePos.x;

        Building.Type type         = Player.BuildingSelected;
        bool          haveBuilding = Player.inventoryBuildings.GetItemCount(type) >= 1;

        if (res && right)
        {
            if (haveBuilding && BasicPlacement.IsPlacableRight(x, y, 4, 4) && MouseInRange(9, true))
            {
                PrintBatRight(1);
            }
            else
            {
                PrintBatRight(0);
            }
        }
        else if (res)
        {
            if (haveBuilding && BasicPlacement.IsPlacableLeft(x, y, 4, 4) && MouseInRange(9, true))
            {
                PrintBatLeft(1);
            }
            else
            {
                PrintBatLeft(0);
            }
        }
    }
Ejemplo n.º 21
0
 public void SetType(Building.Type type)
 {
     this.type = type;
 }
Ejemplo n.º 22
0
 /// Recupere le nombre de batiments du type demandé
 public int GetItemCount(Building.Type type)
 {
     return(storage[type]);
 }
Ejemplo n.º 23
0
        CheckResult CheckBuilding(AI ai, Game game, Player player, int intelligence, Building.Type type)
        {
            int count = (int)player.GetTotalBuildingCount(type);

            if (count == 0)
            {
                switch (type)
                {
                // these are essential buildings
                case Building.Type.Lumberjack:
                case Building.Type.Sawmill:
                case Building.Type.Stonecutter:
                    return(NeedBuilding(ai, game, player, type));
                }
            }

            // Don't build new buildings while the emergency program is active.
            // The essential buildings are handled above.
            if (player.EmergencyProgramActive)
            {
                return(CheckResult.NotNeeded);
            }

            // Ensure there is a source for planks and stones before building more
            if (type != Building.Type.Lumberjack && type != Building.Type.Sawmill &&
                (player.GetCompletedBuildingCount(Building.Type.Sawmill) == 0 ||
                 player.GetCompletedBuildingCount(Building.Type.Lumberjack) == 0))
            {
                if ((ai.HardTimes && game.GetResourceAmountInInventories(player, Resource.Type.Plank) < 5) ||
                    player.GetIncompleteBuildingCount(Building.Type.Sawmill) == 0 ||
                    player.GetIncompleteBuildingCount(Building.Type.Lumberjack) == 0)
                {
                    return(CheckResult.NotNeeded);
                }
            }
            if (type != Building.Type.Stonecutter && type != Building.Type.StoneMine &&
                (player.GetCompletedBuildingCount(Building.Type.Stonecutter) == 0 &&
                 player.GetCompletedBuildingCount(Building.Type.StoneMine) == 0))
            {
                if ((ai.HardTimes && game.GetResourceAmountInInventories(player, Resource.Type.Plank) < 3) ||
                    (player.GetIncompleteBuildingCount(Building.Type.Stonecutter) == 0 &&
                     player.GetIncompleteBuildingCount(Building.Type.StoneMine) == 0))
                {
                    if (ai.GameTime < 10 * Global.TICKS_PER_MIN && player.GetResourceCount(Resource.Type.Stone) < 10 &&
                        game.Map.FindInTerritory(player.Index, FindStoneNear).Count > 0)
                    {
                        return(CheckResult.NotNeeded);
                    }
                }
            }

            // Don't build more than x building at the same time (x is 3 ~ 15)
            if (player.IncompleteBuildingCount > 3 + ai.BuildingFocus + Math.Min(10, ai.GameTime / (30 * Global.TICKS_PER_MIN)))
            {
                return(CheckResult.NotNeeded);
            }

            // Our focus must be to get a coal and iron mine running as we need steel.
            // We also need a food source.
            if (ai.HardTimes)
            {
                switch (type)
                {
                case Building.Type.Fisher:
                    if (count == 0 && game.HasAnyOfBuildingCompletedOrMaterialsAtPlace(player, Building.Type.Forester) &&
                        game.Map.FindInTerritory(player.Index, FindFishNear).Count > 0)     // fish present
                    {
                        return(CheckResult.Needed);
                    }
                    break;

                case Building.Type.Farm:
                    if (count == 0)
                    {
                        if (player.GetResourceCount(Resource.Type.Scythe) != 0 ||
                            player.GetSerfCount(Serf.Type.Farmer) != 0)
                        {
                            return(CheckResult.Needed);
                        }
                        else if (player.GetTotalBuildingCount(Building.Type.Fisher) == 0 &&
                                 game.Map.FindInTerritory(player.Index, FindFishNear).Count == 0)     // no fish
                        {
                            // First check if we can expand the territory.
                            // If not trying to craft a scythe is our last hope.
                            // Otherwise we can't do anything. If we are lucky
                            // there is a piece of coal and iron on the way to
                            // make a piece of steel.
                            if (game.GetPossibleFreeKnightCount(player) == 0)
                            {
                                return(CheckResult.NeededButNoSpecialistOrResources);
                            }
                        }
                    }
                    break;

                case Building.Type.Mill:
                    if (count == 0 && player.GetCompletedBuildingCount(Building.Type.Farm) != 0)
                    {
                        return(CheckResult.Needed);
                    }
                    break;

                case Building.Type.Baker:
                    if (count == 0 && player.GetTotalBuildingCount(Building.Type.Mill) != 0)
                    {
                        return(CheckResult.Needed);
                    }
                    break;

                case Building.Type.Hut:
                    if (player.GetIncompleteBuildingCount(Building.Type.Hut) == 0 &&
                        game.HasAnyOfBuildingCompletedOrMaterialsAtPlace(player, Building.Type.Forester) &&
                        !game.GetPlayerBuildings(player, Building.Type.Hut).Any(building => !building.HasKnight()) &&
                        ai.GameTime > count * 180 * Global.TICKS_PER_SEC && game.GetPossibleFreeKnightCount(player) > 0)
                    {
                        return(CheckResult.Needed);
                    }
                    break;

                case Building.Type.CoalMine:
                    if (count == 0)
                    {
                        return(CheckResult.Needed);
                    }
                    break;

                case Building.Type.IronMine:
                    if (count == 0)
                    {
                        return(CheckResult.Needed);
                    }
                    break;

                case Building.Type.Forester:
                    if (count == 0)
                    {
                        return(CheckResult.Needed);
                    }
                    break;

                // If we have at least one coal and iron, we can build a steelsmelter and a toolmaker to produce a scythe or pincer.
                // This can happen with a bit more than minimum supplies or if the mines produce something without a food source.
                // We will craft a scythe if we can't build a fisher. We will craft a pincer and/or hammer if we have no more knights.
                case Building.Type.ToolMaker:
                    if (count == 0 && player.GetCompletedBuildingCount(Building.Type.SteelSmelter) != 0)
                    {
                        return(CheckResult.Needed);
                    }
                    break;

                case Building.Type.SteelSmelter:
                    if (count == 0 &&
                        (game.GetResourceAmountInInventories(player, Resource.Type.Coal) != 0 || player.GetCompletedBuildingCount(Building.Type.CoalMine) != 0) &&
                        (game.GetResourceAmountInInventories(player, Resource.Type.IronOre) != 0 || player.GetCompletedBuildingCount(Building.Type.IronMine) != 0))
                    {
                        return(CheckResult.Needed);
                    }
                    break;

                case Building.Type.WeaponSmith:
                    if (count == 0 && player.GetCompletedBuildingCount(Building.Type.ToolMaker) != 0 &&
                        game.GetPossibleFreeKnightCount(player) < 4)
                    {
                        return(CheckResult.Needed);
                    }
                    break;
                }

                return(CheckResult.NotNeeded);
            }

            int numIncompleteBuildings        = game.GetPlayerBuildings(player).Count(building => !building.IsDone);
            int numPossileAdditionalBuildings = type == Building.Type.Hut ? ai.ExpandFocus / 2 + Math.Max(0, (int)player.LandArea / 50) : 0;

            if (numIncompleteBuildings > 2 + numPossileAdditionalBuildings + player.LandArea / 200 + ai.GameTime / (20 * Global.TICKS_PER_MIN) + Math.Max(ai.ExpandFocus - 1, ai.BuildingFocus))
            {
                return(CheckResult.NotNeeded);
            }

            // If we can't produce knights and don't have any left, we won't build
            // several buildings until we have a weaponsmith. Otherwise we might
            // run out of space for large buildings and therefore a weaponsmith.
            bool hasKnightRequirements = ai.HasRequirementsForKnights(game);

            switch (type)
            {
            case Building.Type.Lumberjack:
                if (TestBuilding(count, ai, game, player, 45 - ai.ConstructionMaterialFocus * 7, 55 - ai.ConstructionMaterialFocus * 10, 75))
                {
                    if (game.GetResourceAmountInInventories(player, Resource.Type.Plank) < 70 + ai.ConstructionMaterialFocus * ai.ConstructionMaterialFocus * 40 - count * 3)
                    {
                        return(NeedBuilding(ai, game, player, type));
                    }
                }
                break;

            case Building.Type.Forester:
            {
                int lumberjackCount = (int)player.GetTotalBuildingCount(Building.Type.Lumberjack);

                if (count < lumberjackCount + ai.ConstructionMaterialFocus && TestBuilding(count, ai, game, player, 30 - ai.ConstructionMaterialFocus * 7, 60 - ai.ConstructionMaterialFocus * 20, 50))
                {
                    return(NeedBuilding(ai, game, player, type));
                }
            }
            break;

            case Building.Type.Stonecutter:
                if (TestBuilding(count, ai, game, player, 110 - ai.ConstructionMaterialFocus * 32, 100 - ai.ConstructionMaterialFocus * 20, 75))
                {
                    if (game.GetResourceAmountInInventories(player, Resource.Type.Stone) < 50 + ai.ConstructionMaterialFocus * ai.ConstructionMaterialFocus * 30 - count * 5)
                    {
                        return(NeedBuilding(ai, game, player, type));
                    }
                }
                break;

            case Building.Type.Sawmill:
            {
                int lumberjackCount = (int)player.GetTotalBuildingCount(Building.Type.Lumberjack);

                if (count < lumberjackCount * 3 - ai.ConstructionMaterialFocus && TestBuilding(count, ai, game, player, 120 - ai.ConstructionMaterialFocus * 10, 400 - ai.ConstructionMaterialFocus * 15, 30))
                {
                    return(NeedBuilding(ai, game, player, type));
                }
            }
            break;

            case Building.Type.ToolMaker:
                if (count < 1 && ai.GameTime > 30 * Global.TICKS_PER_SEC + (2 - intelligence / 20) * Global.TICKS_PER_MIN)
                {
                    return(NeedBuilding(ai, game, player, type));
                }
                if (count < 2 && game.GetResourceAmountInInventories(player, Resource.Type.Plank) >= 100 && game.GetResourceAmountInInventories(player, Resource.Type.Stone) >= 20 &&
                    game.GetResourceAmountInInventories(player, Resource.Type.Steel) >= 75 && TestBuilding(1, ai, game, player, 180, 800, 5))
                {
                    return(NeedBuilding(ai, game, player, type));
                }
                break;

            case Building.Type.Hut:
            case Building.Type.Tower:
            case Building.Type.Fortress:
            {
                // TODO: large military buildings should be placed near important buildings or near to an enemy to start fights (depending on AI character)

                if (game.GetPossibleFreeKnightCount(player) == 0)
                {
                    return(CheckResult.NotNeeded);
                }

                var numHuts       = player.GetTotalBuildingCount(Building.Type.Hut);
                var numTowers     = player.GetTotalBuildingCount(Building.Type.Tower);
                var numFortresses = player.GetTotalBuildingCount(Building.Type.Fortress);

                var percHut      = ai.GetMilitaryBuildingPercentage(Building.Type.Hut);
                var percTower    = ai.GetMilitaryBuildingPercentage(Building.Type.Tower);
                var percFortress = ai.GetMilitaryBuildingPercentage(Building.Type.Fortress);

                uint numHutsPerTower    = 32u - (uint)Math.Ceiling(2.0 * (percTower + 50.0) / percHut);      // 10-30
                uint numHutsPerFortress = 48u - (uint)Math.Ceiling(4.0 * (percFortress + 20.0) / percHut);   // 16-46

                if (numHuts < numHutsPerTower + numTowers * numHutsPerTower)
                {
                    if (type != Building.Type.Hut)
                    {
                        return(CheckResult.NotNeeded);
                    }
                }
                else if (numHuts < numHutsPerFortress + numFortresses * numHutsPerFortress)
                {
                    if (type == Building.Type.Fortress)
                    {
                        return(CheckResult.NotNeeded);
                    }
                }

                if (!ai.CanBuildMilitaryBuilding(type))
                {
                    return(CheckResult.NotNeeded);
                }

                int focus = Misc.Max(ai.MilitaryFocus, (ai.DefendFocus + 1) / 2, ai.ExpandFocus) + (ai.MilitaryFocus + ai.DefendFocus + ai.ExpandFocus) / 4;

                if (focus == 0 && numHuts == 0)
                {
                    focus = 1;
                }

                float gameTimeFactor = ai.GameTime / (10.0f * Global.TICKS_PER_MIN);        // increases every 10 minutes
                gameTimeFactor = Math.Min(100.0f, gameTimeFactor * gameTimeFactor);         // 10 min -> 1, 20 min -> 4, 30 min -> 9, 40 min -> 16, ... 100 min -> 100
                long numPerLand = (focus * 50 + player.LandArea * 3 - 400) / (200 - Misc.Round(gameTimeFactor));
                long numPerTime = (focus + 1) * Misc.Round(gameTimeFactor / (12 - ai.Aggressivity * 2));

                if (CanBuildMilitary(ai, game, player) &&
                    count < focus + numPerLand + numPerTime &&
                    ai.GameTime > (90 - intelligence - focus * 15 - ai.Aggressivity * 5) * Global.TICKS_PER_SEC)
                {
                    return(NeedBuilding(ai, game, player, type));
                }

                break;
            }

            case Building.Type.CoalMine:
                if (count < 1 && ai.GameTime > (30 - Misc.Max(ai.GoldFocus, ai.SteelFocus, ai.MilitaryFocus) * 10 - intelligence / 7) * 5 * Global.TICKS_PER_SEC)
                {
                    return(NeedBuilding(ai, game, player, type));
                }
                else if (count > 0 && count < Math.Max(0, (ai.GameTime - 30 * Global.TICKS_PER_MIN) / ((80 - Misc.Max(ai.GoldFocus, ai.SteelFocus, ai.MilitaryFocus) * 10) * Global.TICKS_PER_MIN)))
                {
                    uint numIronMines    = player.GetCompletedBuildingCount(Building.Type.IronMine);
                    uint numGoldMines    = player.GetCompletedBuildingCount(Building.Type.GoldMine);
                    uint numWeaponSmiths = player.GetCompletedBuildingCount(Building.Type.WeaponSmith);

                    var maxNeededCoalMines = Math.Max(2, 1 + (numIronMines + ai.SteelFocus / 2) + (numGoldMines + ai.GoldFocus / 2) + (numWeaponSmiths + ai.MilitaryFocus / 2));

                    if (count < maxNeededCoalMines)
                    {
                        return(NeedBuilding(ai, game, player, type));
                    }
                }
                break;

            case Building.Type.IronMine:
                if (count < 1 && ai.GameTime > (33 - Math.Max(ai.SteelFocus, ai.MilitaryFocus) * 10 - intelligence / 8) * 5 * Global.TICKS_PER_SEC)
                {
                    return(NeedBuilding(ai, game, player, type));
                }
                else if (count > 0 && count < Math.Max(0, (ai.GameTime - 30 * Global.TICKS_PER_MIN) / ((100 - Misc.Max(ai.SteelFocus, ai.MilitaryFocus) * 10) * Global.TICKS_PER_MIN)))
                {
                    uint numCoalMines = player.GetCompletedBuildingCount(Building.Type.CoalMine);

                    var maxNeededIronMines = Math.Max(2, 1 + (numCoalMines + Misc.Max(ai.SteelFocus, ai.MilitaryFocus) / 2));

                    if (count < maxNeededIronMines)
                    {
                        return(NeedBuilding(ai, game, player, type));
                    }
                }
                break;

            case Building.Type.GoldMine:
                if (count < 1 && ai.GameTime > (45 - Math.Max(ai.GoldFocus, ai.MilitaryFocus - 1) * 7 - intelligence / 9) * 5 * Global.TICKS_PER_SEC)
                {
                    return(NeedBuilding(ai, game, player, type));
                }
                else if (count > 0 && count < Math.Max(0, (ai.GameTime - 30 * Global.TICKS_PER_MIN) / ((160 - Misc.Max(ai.GoldFocus, ai.MilitaryFocus - 1) * 10) * Global.TICKS_PER_MIN)))
                {
                    uint numCoalMines = player.GetCompletedBuildingCount(Building.Type.CoalMine);

                    var maxNeededGoldMines = Math.Max(2, 1 + (numCoalMines + Misc.Max(ai.GoldFocus, ai.MilitaryFocus) / 2));

                    if (count < maxNeededGoldMines)
                    {
                        return(NeedBuilding(ai, game, player, type));
                    }
                }
                break;

            case Building.Type.StoneMine:
                if (count < 1 && ai.GameTime > (120 - Math.Max(ai.BuildingFocus, ai.ConstructionMaterialFocus) * 20 - intelligence / 10) * 5 * Global.TICKS_PER_SEC)
                {
                    if (ai.ConstructionMaterialFocus == 2 || player.GetResourceCount(Resource.Type.Stone) < 45 - ai.ConstructionMaterialFocus * 15)
                    {
                        return(NeedBuilding(ai, game, player, type));
                    }
                }
                else if (count > 0 && count < Math.Max(0, (ai.GameTime - 40 * Global.TICKS_PER_MIN) / ((200 - ai.ConstructionMaterialFocus * 15) * Global.TICKS_PER_MIN)))
                {
                    uint numSawMills = player.GetCompletedBuildingCount(Building.Type.Sawmill);

                    var maxNeededStoneMines = Math.Max(2, 1 + (numSawMills + ai.ConstructionMaterialFocus / 2));

                    if (count < maxNeededStoneMines)
                    {
                        return(NeedBuilding(ai, game, player, type));
                    }
                }
                break;

            case Building.Type.Farm:
            case Building.Type.Mill:
            case Building.Type.Baker:
            case Building.Type.PigFarm:
            case Building.Type.Butcher:
            case Building.Type.Fisher:
                if (!hasKnightRequirements)
                {
                    return(CheckResult.NotNeeded);
                }
                if (ai.GameTime > (120 - Math.Max(ai.FoodFocus, ai.BuildingFocus) * 15) * Global.TICKS_PER_SEC && NeedFoodBuilding(ai, game, player, type))
                {
                    return(NeedBuilding(ai, game, player, type));
                }
                break;

            case Building.Type.SteelSmelter:
            {
                if (count != 0 && player.GetTotalBuildingCount(Building.Type.WeaponSmith) == 0)
                {
                    return(CheckResult.NotNeeded);
                }

                if (count < player.GetCompletedBuildingCount(Building.Type.IronMine) * Math.Max(2, ai.SteelFocus + 1) &&
                    game.GetResourceAmountInInventories(player, Resource.Type.Plank) >= 5 &&
                    game.GetResourceAmountInInventories(player, Resource.Type.Stone) >= 3)
                {
                    return(NeedBuilding(ai, game, player, type));
                }
            }
            break;

            case Building.Type.GoldSmelter:
            {
                if (!hasKnightRequirements)
                {
                    return(CheckResult.NotNeeded);
                }

                if (count < player.GetCompletedBuildingCount(Building.Type.GoldMine) * (ai.GoldFocus + 2) &&
                    game.GetResourceAmountInInventories(player, Resource.Type.Plank) >= 5 &&
                    game.GetResourceAmountInInventories(player, Resource.Type.Stone) >= 3 &&
                    TestBuilding(count, ai, game, player, 80 - ai.GoldFocus * 10, 50 - ai.GoldFocus * 5, 20))
                {
                    return(NeedBuilding(ai, game, player, type));
                }
                else if (count < 1 && game.GetResourceAmountInInventories(player, Resource.Type.GoldOre) >= 35 - ai.GoldFocus * 16)
                {
                    // Gold focus: 0 -> min 35 ore, 1 -> min 19 ore, 2 -> min 3 ore
                    if (ai.GameTime > (60 - ai.GoldFocus * 20) * Global.TICKS_PER_MIN)
                    {
                        return(NeedBuilding(ai, game, player, type));
                    }
                }
            }
            break;

            case Building.Type.WeaponSmith:
            {
                if (count == 0)
                {
                    if (player.GetCompletedBuildingCount(Building.Type.ToolMaker) > 0 && player.GetCompletedBuildingCount(Building.Type.SteelSmelter) > 0)
                    {
                        return(NeedBuilding(ai, game, player, type));
                    }
                    else if (game.GetResourceAmountInInventories(player, Resource.Type.Coal) >= 10 && game.GetResourceAmountInInventories(player, Resource.Type.Steel) >= 10 &&
                             ai.GameTime > (10 - Misc.Max(ai.MilitaryFocus, ai.ExpandFocus, ai.DefendFocus - 1, ai.Aggressivity - 1) - game.RandomInt() % 3) * Global.TICKS_PER_MIN)
                    {
                        return(NeedBuilding(ai, game, player, type));
                    }
                }

                if (count < Math.Min(player.GetCompletedBuildingCount(Building.Type.CoalMine) + 1, player.GetCompletedBuildingCount(Building.Type.SteelSmelter)))
                {
                    return(NeedBuilding(ai, game, player, type));
                }
            }
            break;

            case Building.Type.Stock:
                if (!hasKnightRequirements)
                {
                    return(CheckResult.NotNeeded);
                }

                if (count < (game.Map.Size + 1) / 2 + ai.BuildingFocus &&
                    count < ((int)player.LandArea + ai.BuildingFocus * 300) / 1200 && ai.GameTime > 60 - ai.BuildingFocus * 8 * Global.TICKS_PER_MIN &&
                    player.GetCompletedBuildingCount(Building.Type.WeaponSmith) > count &&
                    ai.Chance(50 + ai.BuildingFocus * 25))
                {
                    return(NeedBuilding(ai, game, player, type));
                }
                break;

            case Building.Type.Boatbuilder:
                if (count < 1 && ai.GameTime > 52 - ai.BuildingFocus * 2 * Global.TICKS_PER_MIN &&
                    game.GetResourceAmountInInventories(player, Resource.Type.Plank) >= 24 - ai.BuildingFocus * 4 &&
                    ai.Chance(1))
                {
                    return(NeedBuilding(ai, game, player, type));
                }
                break;
            }

            return(CheckResult.NotNeeded);
        }
Ejemplo n.º 24
0
        bool NeedFoodBuilding(AI ai, Game game, Player player, Building.Type type)
        {
            // TODO: Fishers can't be build in any case or on any map.
            // Therefore the ratio for food end buildings need adjustment in this case.
            // Otherwise no new food chains will be build.

            int numberOfMines = game.GetPlayerBuildings(player).Where(building =>
                                                                      building.BuildingType == Building.Type.CoalMine ||
                                                                      building.BuildingType == Building.Type.IronMine ||
                                                                      building.BuildingType == Building.Type.GoldMine ||
                                                                      building.BuildingType == Building.Type.StoneMine).Count();
            int  numberOfFishers        = (int)player.GetTotalBuildingCount(Building.Type.Fisher);
            int  numberOfFarms          = (int)player.GetTotalBuildingCount(Building.Type.Farm);
            int  numberOfCompletedFarms = (int)player.GetCompletedBuildingCount(Building.Type.Farm);
            int  numberOfMills          = (int)player.GetTotalBuildingCount(Building.Type.Mill);
            int  numberOfBakers         = (int)player.GetTotalBuildingCount(Building.Type.Baker);
            int  numberOfPigFarms       = (int)player.GetTotalBuildingCount(Building.Type.PigFarm);
            int  numberOfButchers       = (int)player.GetTotalBuildingCount(Building.Type.Butcher);
            bool hasPotentialFarmer     = player.GetSerfCount(Serf.Type.Farmer) != 0 ||
                                          game.GetResourceAmountInInventories(player, Resource.Type.Scythe) != 0;

            // If there are no mines and some game time has passed
            // the AI will at least build one of its favorite food source chain.
            if (numberOfMines == 0)
            {
                if (ai.GameTime >= (25 - ai.FoodFocus * 4 - (type == Building.Type.Fisher ? 5 : 0)) * Global.TICKS_PER_MIN)
                {
                    switch (type)
                    {
                    case Building.Type.Fisher:
                        if (numberOfFishers == 0 && (ai.GetFoodSourcePriority(0) == 2 || !hasPotentialFarmer))
                        {
                            return(true);
                        }
                        break;

                    case Building.Type.Farm:
                        if (numberOfFarms == 0 && ai.GetFoodSourcePriority(0) != 2 && hasPotentialFarmer)
                        {
                            return(true);
                        }
                        break;

                    case Building.Type.Mill:
                        if (numberOfCompletedFarms != 0 && numberOfMills < Math.Max(1, ai.FoodFocus) && ai.GetFoodSourcePriority(1) == 2 &&
                            game.GetResourceAmountInInventories(player, Resource.Type.Plank) > 3)
                        {
                            return(true);
                        }
                        break;

                    case Building.Type.Baker:
                        if (numberOfMills != 0 && numberOfBakers == 0 && ai.GetFoodSourcePriority(1) == 2)
                        {
                            return(true);
                        }
                        break;

                    case Building.Type.PigFarm:
                        if (numberOfCompletedFarms != 0 && numberOfPigFarms < 2 + ai.FoodFocus && ai.GetFoodSourcePriority(2) == 2 &&
                            game.GetResourceAmountInInventories(player, Resource.Type.Plank) > 4)
                        {
                            return(true);
                        }
                        break;

                    case Building.Type.Butcher:
                        if (numberOfPigFarms != 0 && numberOfButchers == 0 && ai.GetFoodSourcePriority(2) == 2)
                        {
                            return(true);
                        }
                        break;
                    }
                }

                return(false);
            }

            int numPossibleMines  = numberOfFishers + numberOfButchers * 3 + numberOfBakers * 2;
            int numMineDifference = ai.FoodFocus + numberOfMines - numPossibleMines;

            if (numMineDifference <= 0)
            {
                return(false);
            }
            else
            {
                int numFoodEndBuildings = numberOfFishers + numberOfBakers + numberOfButchers;

                switch (type)
                {
                case Building.Type.Fisher:
                    if (numFoodEndBuildings == 0)
                    {
                        return(ai.GetFoodSourcePriority(0) == 2);
                    }
                    return((float)numberOfFishers / numFoodEndBuildings < ai.GetFoodSourcePriorityInPercentage(0) / 100.0f);

                case Building.Type.Mill:
                    if (numberOfMills > 1 + numberOfBakers * 2)
                    {
                        return(false);
                    }
                    if (numberOfCompletedFarms == 0 && game.GetResourceAmountInInventories(player, Resource.Type.Wheat) < 10)
                    {
                        return(false);
                    }
                    if (numberOfMills < numberOfBakers * 2)
                    {
                        return(true);
                    }
                    if (numFoodEndBuildings == 0 && numberOfMills == 0)
                    {
                        return(ai.GetFoodSourcePriority(1) == 2);
                    }
                    return((float)numberOfBakers / numFoodEndBuildings < ai.GetFoodSourcePriorityInPercentage(1) / 100.0f);

                case Building.Type.Baker:
                    if (numberOfMills == 0)
                    {
                        return(false);
                    }
                    if (numFoodEndBuildings == 0)
                    {
                        return(ai.GetFoodSourcePriority(1) == 2);
                    }
                    return((float)numberOfBakers / numFoodEndBuildings < ai.GetFoodSourcePriorityInPercentage(1) / 100.0f);

                case Building.Type.PigFarm:
                    if (numberOfPigFarms > 2 + numberOfButchers * 6)
                    {
                        return(false);
                    }
                    if (numberOfCompletedFarms == 0 && game.GetResourceAmountInInventories(player, Resource.Type.Wheat) < 10)
                    {
                        return(false);
                    }
                    if (numberOfPigFarms < numberOfButchers * 6)
                    {
                        return(true);
                    }
                    if (numFoodEndBuildings == 0 && numberOfPigFarms == 0)
                    {
                        return(ai.GetFoodSourcePriority(2) == 2);
                    }
                    return((float)numberOfButchers / numFoodEndBuildings < ai.GetFoodSourcePriorityInPercentage(2) / 100.0f);

                case Building.Type.Butcher:
                    if (numberOfPigFarms == 0)
                    {
                        return(false);
                    }
                    if (numFoodEndBuildings == 0)
                    {
                        return(ai.GetFoodSourcePriority(2) == 2);
                    }
                    return((float)numberOfButchers / numFoodEndBuildings < ai.GetFoodSourcePriorityInPercentage(2) / 100.0f);

                case Building.Type.Farm:
                {
                    int numNeeded = numberOfMills * 2 + (numberOfPigFarms + 5) / 6;

                    if (numNeeded > numberOfFarms)
                    {
                        return(true);
                    }

                    if (numFoodEndBuildings == 0)
                    {
                        if (numberOfFarms == 0)
                        {
                            return(ai.GetFoodSourcePriority(0) != 2);
                        }

                        return(false);
                    }

                    /*if (ai.GetFoodSourcePriority(1) == 2)
                     *  return (float)numberOfButchers / numFoodEndBuildings < ai.GetFoodSourcePriorityInPercentage(2) / 100.0f;
                     * else if (ai.GetFoodSourcePriority(2) == 2)
                     *  return (float)numberOfBakers / numFoodEndBuildings < ai.GetFoodSourcePriorityInPercentage(1) / 100.0f;
                     * else
                     * {
                     *  return (float)numberOfBakers / numFoodEndBuildings < ai.GetFoodSourcePriorityInPercentage(1) / 100.0f ||
                     *      (float)numberOfButchers / numFoodEndBuildings < ai.GetFoodSourcePriorityInPercentage(2) / 100.0f;
                     * }*/

                    return(false);
                }
                }
            }

            return(false);
        }
Ejemplo n.º 25
0
 static int BuildingsInArea(Map map, uint basePosition, int range, Building.Type buildingType, Func <Map, uint, Map.FindData> searchFunc, int minDistance = 0)
 {
     return(map.FindInArea(basePosition, range, searchFunc, minDistance).Count(building => (building as Building).BuildingType == buildingType));
 }
Ejemplo n.º 26
0
 public AIStateBuildBuilding(Building.Type buildingType)
     : base(AI.State.BuildBuilding)
 {
     type = buildingType;
 }