/// <summary> /// A Unity coroutine that runs the turn of every unit in this group. /// Default behavior: For every unit, takes its turn. Adds a separation of /// "UnityLogic.Options.UnitTurnInterval" seconds between each turn. /// </summary> public virtual IEnumerable TakeTurn() { //Keep careful track of the units we're going to update. HashSet <Unit> unitsToUpdate = new HashSet <Unit>(UnitsByID.Select(id => TheMap.GetUnit(id))); Action <LockedSet <ulong>, ulong> onUnitAdded = (units, unitID) => unitsToUpdate.Add(TheMap.GetUnit(unitID)); Action <LockedSet <ulong>, ulong> onUnitRemoved = (units, unitID) => unitsToUpdate.Remove(TheMap.GetUnit(unitID)); UnitsByID.OnElementAdded += onUnitAdded; UnitsByID.OnElementRemoved += onUnitRemoved; while (unitsToUpdate.Count > 0) { Unit unit = unitsToUpdate.First(); unitsToUpdate.Remove(unit); //Take the unit's turn. foreach (object o in unit.TakeTurn()) { yield return(o); } //Wait for the next turn. yield return(UnityLogic.Options.UnitTurnIntervalFlag); } UnitsByID.OnElementRemoved -= onUnitAdded; UnitsByID.OnElementRemoved -= onUnitRemoved; }
public virtual void ReadData(MyData.Reader reader) { ID = reader.UInt64("id"); TurnPriority.Value = reader.Int("turnPriority"); UnitsByID.Clear(); reader.Collection("units", (MyData.Reader r, ref ulong outID, string name) => { outID = r.UInt64(name); }, (size) => UnitsByID); AlliesByID.Clear(); reader.Collection("allies", (MyData.Reader r, ref ulong outID, string name) => { outID = r.UInt64(name); }, (size) => AlliesByID); EnemiesByID.Clear(); reader.Collection("enemies", (MyData.Reader r, ref ulong outID, string name) => { outID = r.UInt64(name); }, (size) => EnemiesByID); }