/// <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; }
/// <summary> /// Prepares this unit to do pathfinding with the "AStarEdgeCalc()" heuristic method. /// Note that to reduce garbage, this heuristic may reuse global variables, /// which means only one Unit can have a heuristic at any time. /// </summary> private void PrepareAStarEdgeCalc(bool avoidEnemies) { _temp_enemies.Clear(); foreach (ulong enemyGroupID in MyGroup.EnemiesByID) { foreach (ulong enemyUnitID in TheMap.Groups.Get(enemyGroupID).UnitsByID) { _temp_enemies.Add(TheMap.GetUnit(enemyUnitID)); } } }
public Bed(Map theMap, ulong groupID, Vector2i pos) : base(theMap, groupID, pos) { //Keep track of when sleeping units die. SleepingUnitsByID.OnElementAdded += (ids, id) => { TheMap.GetUnit(id).OnKilled += Callback_SleeperKilled; }; SleepingUnitsByID.OnElementRemoved += (ids, id) => { TheMap.GetUnit(id).OnKilled -= Callback_SleeperKilled; }; }
public override IEnumerable TakeTurn() { //Gain stats for everybody in bed. foreach (ulong unitID in SleepingUnitsByID) { var pChar = (PlayerChar)TheMap.GetUnit(unitID); pChar.Energy.Value += Player_Char.Consts.EnergyIncreaseFromBedPerTurn(SleepingUnitsByID.Count, pChar.AdultMultiplier); pChar.Health.Value += Player_Char.Consts.HealthIncreaseFromBedPerTurn(SleepingUnitsByID.Count, pChar.AdultMultiplier); } //Count the number of male/female pairs. int nMales = 0, nFemales = 0; foreach (Unit unit in SleepingUnitsByID.Select(id => TheMap.GetUnit(id))) { PlayerChar pChar = (PlayerChar)unit; if (pChar.IsAdult) { switch (pChar.Personality.Gender.Value) { case Player_Char.Personality.Genders.Male: nMales += 1; break; case Player_Char.Personality.Genders.Female: nFemales += 1; break; default: throw new NotImplementedException(((PlayerChar)unit).Personality.Gender.ToString()); } } } int nPairs = Math.Min(nMales, nFemales); //For each pair, give them a chance to make a baby. for (int i = 0; i < nPairs; ++i) { if (UnityEngine.Random.value < Player_Char.Consts.ReproductionChance) { //Get the father and mother. ulong fatherID = SleepingUnitsByID.Where(id => { PlayerChar pc = (PlayerChar)TheMap.GetUnit(id); return(pc.Personality.Gender.Value == Player_Char.Personality.Genders.Male); }).ElementAt(i); ulong motherID = SleepingUnitsByID.Where(id => { PlayerChar pc = (PlayerChar)TheMap.GetUnit(id); return(pc.Personality.Gender.Value == Player_Char.Personality.Genders.Female); }).ElementAt(i); PlayerChar father = (PlayerChar)TheMap.GetUnit(fatherID), mother = (PlayerChar)TheMap.GetUnit(motherID); //Create the baby. var gender = (UnityEngine.Random.value > 0.5f ? Player_Char.Personality.Genders.Male : Player_Char.Personality.Genders.Female); int seed = UnityEngine.Random.Range(0, int.MaxValue); string name = Player_Char.Personality.GenerateName(gender, seed); PlayerChar baby = new PlayerChar(TheMap, father.MyGroupID, UnityEngine.Mathf.Lerp(Player_Char.Consts.MinStart_Food, Player_Char.Consts.MaxStart_Food, UnityEngine.Random.value), UnityEngine.Mathf.Lerp(Player_Char.Consts.MinStart_Energy, Player_Char.Consts.MaxStart_Energy, UnityEngine.Random.value), UnityEngine.Mathf.Lerp(Player_Char.Consts.MinStart_Strength, Player_Char.Consts.MaxStart_Strength, UnityEngine.Random.value), 0.0f, name, gender); TheMap.AddUnit(baby); baby.Pos.Value = Pos; if (OnMakeBaby != null) { OnMakeBaby(this, father, mother, baby); } } } yield break; }