Beispiel #1
0
        public PlayResult DoSpyMission__Turn(SpyMission mission, Location target)
        {
            if (!target.IsValid)
            {
                return(new PlayResult(PlayError.InvalidLocation));
            }
            PlayResult result = theEmpire.Play(Protocol.sSetSpyMission + ((int)mission << 4));

            if (!result.OK)
            {
                return(result);
            }
            else
            {
                result = MoveToNeighborOf__Turn(target);
                if (!result.OK || result.UnitRemoved || result.NewUnitOrCitySpotted)
                {
                    return(result);
                }
                else
                {
                    return(Step__Turn(target));
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Query progress of a specific settler job at this location
        /// </summary>
        /// <param name="job">the job</param>
        /// <param name="progress">the progress</param>
        /// <returns>result of operation</returns>
        public PlayResult GetJobProgress__Turn(Job job, out JobProgress progress)
        {
            fixed(int *jobProgressData = new int[Protocol.nJob * 3])
            {
                PlayResult result = theEmpire.Play(Protocol.sGetJobProgress, ID, jobProgressData);

                progress = new JobProgress(jobProgressData[(int)job * 3], jobProgressData[(int)job * 3 + 1], jobProgressData[(int)job * 3 + 2]);
                return(result);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Change production project to a buiding or wonder.
        /// </summary>
        /// <param name="building">the building to produce</param>
        /// <returns>result of operation</returns>
        public PlayResult SetBuildingInProduction__Turn(Building building)
        {
            PlayResult result = theEmpire.Play(Protocol.sSetCityProject, indexInSharedMemory, ((int)building & Protocol.cpIndex) | Protocol.cpImp);

            if (result.Effective)
            {
                InvalidateReport();
            }
            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// Do no longer exploit any tile except the tile of the city itself. Combined with OptimizeExploitedLocations, this can
        /// be used to set priorities for tile exploitation between cities with overlapping area. Typical sequence:
        /// (1) LowPriorityCity.StopExploitation
        /// (2) HighPriorityCity.OptimizeExploitedLocations
        /// (3) LowPriorityCity.OptimizeExploitedLocations
        /// Usually calling this should be followed by an OptimizeExploitedLocations for the same city within the same turn. Otherwise
        /// the city will remain in the non-exploiting state and start to decline.
        /// </summary>
        /// <returns>result of operation</returns>
        public PlayResult StopExploitation__Turn()
        {
            PlayResult result = theEmpire.Play(Protocol.sSetCityTiles, indexInSharedMemory, 1 << 13);

            if (result.Effective)
            {
                InvalidateReport();
            }
            return(result);
        }
Beispiel #5
0
        /// <summary>
        /// Attack a unit. Moves along shortest possible path considering all known information.
        /// Only does the part of the move that is possible within this turn.
        /// If move has to be continued next turn the return value has the Error property Incomplete.
        /// Hostile terrain is considered to find a compromise between damage and reaching the target fast.
        /// </summary>
        /// <param name="target">unit to attack</param>
        /// <returns>result of operation</returns>
        public PlayResult Attack__Turn(Location target)
        {
            if (!target.IsValid)
            {
                return(new PlayResult(PlayError.InvalidLocation));
            }
            PlayResult moved = MoveToNeighborOf__Turn(target);

            if (!moved.OK || moved.UnitRemoved || moved.NewUnitOrCitySpotted)
            {
                return(moved);
            }
            else
            {
                return(Step__Turn(target));
            }
        }
Beispiel #6
0
        /// <summary>
        /// rebuild an existing building
        /// </summary>
        /// <param name="building">the building to rebuild</param>
        /// <returns>result of operation</returns>
        public PlayResult RebuildBuilding__Turn(Building building)
        {
            PlayResult result = theEmpire.Play(Protocol.sRebuildCityImprovement, indexInSharedMemory, (int)building);

            if (result.Effective)
            {
                if (building == Building.Palace || building == Building.StockExchange || building == Building.SpacePort)
                {
                    theEmpire.InvalidateAllCityReports();
                }
                else
                {
                    InvalidateReport();
                }
            }
            return(result);
        }
Beispiel #7
0
        /// <summary>
        /// add unit to the city it's located in
        /// </summary>
        /// <returns>result of operation</returns>
        public PlayResult AddToCity__Turn()
        {
            City       city   = Location.OwnCity;
            PlayResult result = theEmpire.Play(Protocol.sAddToCity, indexInSharedMemory);

            if (result.OK)
            {
                if (Home != null)
                {
                    Home.InvalidateReport();
                }
                if (city != null)
                {
                    city.InvalidateReport();
                }
            }
            return(result);
        }
Beispiel #8
0
        /// <summary>
        /// set home of unit in city it's located in
        /// </summary>
        /// <returns>result of operation</returns>
        public PlayResult SetHomeHere__Turn()
        {
            City       oldHome = Home;
            PlayResult result  = theEmpire.Play(Protocol.sSetUnitHome, indexInSharedMemory);

            if (result.OK)
            {
                if (oldHome != null)
                {
                    oldHome.InvalidateReport();
                }
                if (Home != null)
                {
                    Home.InvalidateReport();
                }
            }
            return(result);
        }
Beispiel #9
0
        /// <summary>
        /// Change production project to a unit.
        /// </summary>
        /// <param name="model">model of the unit to produce</param>
        /// <param name="options">options</param>
        /// <returns>result of operation</returns>
        public PlayResult SetUnitInProduction__Turn(Model model, UnitProductionOptions options)
        {
            int optionArray = 0;

            if ((options & UnitProductionOptions.AsConscripts) != 0)
            {
                optionArray += Protocol.cpConscripts;
            }
            if ((options & UnitProductionOptions.AllowDisbandCity) != 0)
            {
                optionArray += Protocol.cpDisbandCity;
            }
            PlayResult result = theEmpire.Play(Protocol.sSetCityProject, indexInSharedMemory, model.IndexInSharedMemory | optionArray);

            if (result.Effective)
            {
                InvalidateReport();
            }
            return(result);
        }
Beispiel #10
0
        //bool MoveForecast__Turn(ToLoc; var RemainingMovement: integer)
        //{
        //    return true; // todo !!!
        //}

        //bool AttackForecast__Turn(ToLoc,AttackMovement; var RemainingHealth: integer)
        //{
        //    return true; // todo !!!
        //}

        //bool DefenseForecast__Turn(euix,ToLoc: integer; var RemainingHealth: integer)
        //{
        //    return true; // todo !!!
        //}

        /// <summary>
        /// Disband unit. If located in city producing a unit, utilize material.
        /// </summary>
        /// <returns>result of operation</returns>
        public PlayResult Disband__Turn()
        {
            City city = Location.OwnCity;

            List <City> citiesChanged = null;

            if (Load > 0)
            {
                citiesChanged = new List <City>();
                foreach (Unit unit in theEmpire.Units)
                {
                    if (unit.Transport == this && unit.Home != null && !citiesChanged.Contains(unit.Home))
                    {
                        citiesChanged.Add(unit.Home);
                    }
                }
            }

            PlayResult result = theEmpire.Play(Protocol.sRemoveUnit, indexInSharedMemory);

            if (result.OK)
            {
                theEmpire.UpdateLists(AEmpire.UpdateArea.Units);
                if (Home != null)
                {
                    Home.InvalidateReport();
                }
                if (city != null)
                {
                    city.InvalidateReport();                     // in case unit was utilized
                }
                if (citiesChanged != null)
                {
                    foreach (City city1 in citiesChanged)
                    {
                        city1.InvalidateReport();
                    }
                }
            }
            return(result);
        }
Beispiel #11
0
        /// <summary>
        /// Move unit to neighbor location.
        /// Causes loading to transport if:
        /// (1) unit is ground unit and target location is water and has transport present
        /// (2) unit is aircraft and target location has carrier present
        /// </summary>
        /// <param name="target">location to move to, must be neighbor of current location</param>
        /// <returns>result of operation</returns>
        public PlayResult Step__Turn(Location target)
        {
            if (!target.IsValid)
            {
                return(new PlayResult(PlayError.InvalidLocation));
            }
            RC targetRC = target - Location;

            if (targetRC.Distance > 3)
            {
                return(new PlayResult(PlayError.RulesViolation));
            }

            OtherLocation[] newObservations = null;
            if (model.HasExtendedObservationRange || target.ProvidesExtendedObservationRange)
            {
                newObservations = target.Distance5Area;
            }
            else
            {
                newObservations = target.Neighbors;
            }
            for (int i = 0; i < newObservations.Length; i++)
            {
                if (newObservations[i].Location.IsObserved)
                {
                    newObservations[i] = new OtherLocation(new Location(theEmpire, -1), new RC(0, 0));                     // not a new observation, make invalid
                }
            }
            bool foreignCityChangePossible = false;

            foreach (OtherLocation observation in newObservations)
            {
                if (observation.Location.IsValid)
                {
                    foreignCityChangePossible |= observation.Location.HasForeignCity;
                }
            }

            int         moveCommand   = Protocol.sMoveUnit + (((targetRC.a - targetRC.b) & 7) << 4) + (((targetRC.a + targetRC.b) & 7) << 7);
            List <City> citiesChanged = null;

            if (Load > 0)
            {
                if ((!target.HasForeignUnit && target.MayCauseUnrest != Location.MayCauseUnrest) || // crossing border changing unrest
                    theEmpire.TestPlay(moveCommand, indexInSharedMemory).UnitRemoved)               // transport will die
                {                                                                                   // reports of all home cities of transported units will become invalid
                    citiesChanged = new List <City>();
                    foreach (Unit unit in theEmpire.Units)
                    {
                        if (unit.Transport == this && unit.Home != null && !citiesChanged.Contains(unit.Home))
                        {
                            citiesChanged.Add(unit.Home);
                        }
                    }
                }
            }
            bool       targetHadForeignCityBefore = target.HasForeignCity;
            bool       causedUnrestBefore         = CausesUnrest;
            PlayResult result = theEmpire.Play(moveCommand, indexInSharedMemory);

            if (result.Effective)
            {
                AEmpire.UpdateArea updateArea = AEmpire.UpdateArea.Basic;

                foreach (OtherLocation observation in newObservations)
                {
                    if (observation.Location.IsValid)
                    {
                        foreignCityChangePossible |= observation.Location.HasForeignCity;
                    }
                }
                if (foreignCityChangePossible)
                {
                    updateArea |= AEmpire.UpdateArea.ForeignCities;
                }

                if (result.UnitRemoved)
                {
                    updateArea |= AEmpire.UpdateArea.Units;
                }
                if (targetHadForeignCityBefore && !target.HasForeignCity)
                {
                    updateArea |= AEmpire.UpdateArea.ForeignCities;                     // foreign city destroyed or captured
                    if (target.HasOwnCity)
                    {
                        updateArea |= AEmpire.UpdateArea.Cities;                         // captured, new own city
                    }
                }
                if (updateArea != AEmpire.UpdateArea.Basic)
                {
                    theEmpire.UpdateLists(updateArea);
                }
                if (Home != null && (!Exists || CausesUnrest != causedUnrestBefore))
                {
                    Home.InvalidateReport();
                }
                if (citiesChanged != null)
                {
                    foreach (City city in citiesChanged)
                    {
                        city.InvalidateReport();
                    }
                }

                if (theEmpire.HadEvent__Turn((EmpireEvent)Protocol.phStealTech))                 // capture with temple of zeus
                {
                    theEmpire.StealAdvance();
                }
            }
            return(result);
        }
Beispiel #12
0
        // internal
        PlayResult MoveTo(Location target, bool approach)
        {
            if (!target.IsValid)
            {
                return(new PlayResult(PlayError.InvalidLocation));
            }
            if (MustPauseForMountains)
            {
                return(new PlayResult(PlayError.Incomplete));
            }

            // pathfinding necessary
            TravelSprawl sprawl = null;

            if (approach)
            {
                sprawl = new TravelSprawl(theEmpire, this, target);
            }
            else
            {
                sprawl = new TravelSprawl(theEmpire, this);
            }
            foreach (Location reachedLocation in sprawl)
            {
                if (reachedLocation == target)
                {
                    break;
                }
            }
            if (!sprawl.WasIterated(target))
            {
                return(new PlayResult(PlayError.NoWay));
            }

            Location[] path = sprawl.Path(target);
            foreach (Location step in path)
            {
                if (sprawl.Distance(step).NewTurn)
                {
                    return(new PlayResult(PlayError.Incomplete));                    // has to be continued next turn
                }
                if (!IsTerrainResistant && Location.OneTurnHostileDamage == 0 && step.OneTurnHostileDamage > 0)
                {                 // recover before passing hostile terrain?
                    int damageToNextNonHostileLocation = sprawl.DamageToNextNonHostileLocation(Location, target);
                    if (damageToNextNonHostileLocation >= 100)
                    {
                        return(new PlayResult(PlayError.NoWay));
                    }
                    else if (Location.OneTurnHostileDamage == 0 && Health <= damageToNextNonHostileLocation)
                    {
                        return(new PlayResult(PlayError.RecoverFirst));
                    }
                }

                PlayResult result = Step__Turn(step);
                if (!result.OK || result.UnitRemoved || result.NewUnitOrCitySpotted)
                {
                    return(result);
                }
            }
            return(PlayResult.Success);
        }