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)); } } }
/// <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); } }
/// <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); }
/// <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); }
/// <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)); } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
//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); }
/// <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); }
// 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); }