public void recomputeInformationAvailability(SocialGroup sg) { int CUTOFF = 128; HashSet <Location> closed = new HashSet <Location>(); List <Location> working = new List <Location>(); List <double> distances = new List <double>(); foreach (Location a in locations) { if (a.soc == sg) { closed.Add(a); working.Add(a); double dist = 1; distances.Add(dist); a.information.set(sg, dist); } } int steps = 0; while (working.Count > 0) { steps += 1; if (steps >= CUTOFF) { break; } List <Location> next = new List <Location>(); List <double> nextDistances = new List <double>(); for (int i = 0; i < working.Count; i++) { Location l = working[i]; double dist = distances[i]; dist *= l.getInformationAvailability(); dist = Math.Max(param.minInformationAvailability, dist); l.information.set(sg, dist); foreach (Location n in l.getNeighbours()) { if (closed.Contains(n)) { continue; } closed.Add(n); nextDistances.Add(dist); next.Add(n); } } working = next; distances = nextDistances; } }
public List <SocialGroup> getExtendedNeighbours(SocialGroup sg) { int CUTOFF = 128; List <SocialGroup> reply = new List <SocialGroup>(); HashSet <Location> closed = new HashSet <Location>(); List <Location> working = new List <Location>(); foreach (Location a in locations) { if (a.soc == sg) { closed.Add(a); working.Add(a); } } int steps = 0; while (working.Count > 0) { steps += 1; if (steps >= CUTOFF) { break; } List <Location> next = new List <Location>(); List <double> nextDistances = new List <double>(); for (int i = 0; i < working.Count; i++) { Location l = working[i]; if (l.soc != null && l.soc != sg) { if (reply.Contains(l.soc) == false) { reply.Add(l.soc); } } else { foreach (Location n in l.getNeighbours()) { if (closed.Contains(n)) { continue; } closed.Add(n); next.Add(n); } } } working = next; } return(reply); }
public void recomputeInformationAvailability(SocialGroup sg) { int CUTOFF = 128; HashSet <Location> closed = new HashSet <Location>(); List <Location> working = new List <Location>(); List <int> distances = new List <int>(); foreach (Location a in locations) { if (a.soc == sg) { closed.Add(a); working.Add(a); int dist = 0; distances.Add(dist); a.distanceToTarget[sg] = 0; } } int steps = 0; while (working.Count > 0) { steps += 1; if (steps >= CUTOFF) { break; } List <Location> next = new List <Location>(); List <int> nextDistances = new List <int>(); for (int i = 0; i < working.Count; i++) { Location l = working[i]; int dist = distances[i]; l.distanceToTarget[sg] = dist; dist += 1; foreach (Location n in l.getNeighbours()) { if (closed.Contains(n)) { continue; } closed.Add(n); nextDistances.Add(dist); next.Add(n); } } working = next; distances = nextDistances; } }
public List <Location> getNeighbours(Location loc) { //List<Location> reply = new List<Location>(); //foreach (Link l in loc.links) //{ // reply.Add(l.other(loc)); //} //return reply; return(loc.getNeighbours()); }
public override void turnTick(Property p, Location location) { base.turnTick(p, location); bool underQuarantine = false; foreach (Property p2 in location.properties) { if (p2.proto is Pr_Quarantine) { underQuarantine = true; break; } } if (location.settlement != null && location.settlement is SettlementHuman) { SettlementHuman set = (SettlementHuman)location.settlement; set.population -= 1; if (set.population <= 0) { location.map.addMessage(set.location.getName() + " has been eradicated by the Red Death", MsgEvent.LEVEL_RED, true, location.hex); if (set.title != null && set.title.heldBy != null) { set.title.heldBy.die("Died of the Red Death", true); } set.fallIntoRuin(); } } foreach (Location l2 in location.getNeighbours()) { if (l2.settlement != null && l2.settlement.isHuman && l2.soc != null && l2.soc is Society) { bool canApply = true; foreach (Property p2 in l2.properties) { if (p2.proto is Pr_RedDeath || p2.proto is Pr_RedDeathImmunity) { canApply = false; break; } } double pSpread = World.staticMap.param.unit_rd_redDeathPlaguePSpread; if (underQuarantine) { pSpread /= 2; } if (canApply && Eleven.random.NextDouble() < pSpread) { Property.addProperty(World.staticMap, l2, "Red Death"); Society soc = (Society)l2.soc; if (location.map.turn - soc.lastPlagueCrisis > location.map.param.society_crisis_plagueCrisisCooldown) { soc.crisisPlague = "The Red Death Plague"; soc.crisisPlagueLong = "The Red Death plague is spreading in our lands, we must deal with this new crisis. " + "We can either quarantine the disased settlements, treat infected patients, or we could deploy our agents as disease curing specialists."; soc.lastPlagueCrisis = location.map.turn; } } } } }
public override void turnTick(Unit unit) { if (unit.location.settlement != null) { unit.task = null; return; } dur += 1; if (dur >= unit.location.map.param.unit_establishNewSettlementTime || (!unit.location.map.burnInComplete)) { unit.task = null; Location loc = unit.location; int c = 0; Society receiver = null; foreach (Location l2 in loc.getNeighbours()) { if (l2.soc != null && l2.soc is Society) { c += 1; if (Eleven.random.Next(c) == 0) { receiver = (Society)l2.soc; } } } if (receiver == null) { //foreach (SocialGroup sg in loc.map.socialGroups) //{ // if (sg is Society) // { // c += 1; // if (Eleven.random.Next(c) == 0) // { // receiver = (Society)sg; // } // } //} //Start a fully new colony. //Maybe in time this could have a cool name, like "Merchant republic" and be a free port city or something receiver = new Society(unit.location.map, loc); receiver.setName(loc.shortName); loc.soc = receiver; unit.location.map.socialGroups.Add(receiver); } if (receiver != null) { if (loc.isMajor) { loc.settlement = new Set_City(loc); } else { int q = 0; double[] weights = new double[] { 2, 1, 2 }; double roll = 0; for (int i = 0; i < weights.Length; i++) { roll += weights[i]; } roll *= Eleven.random.NextDouble(); for (int i = 0; i < weights.Length; i++) { roll -= weights[i]; if (roll <= 0) { q = i; break; } } if (q == 0) { loc.settlement = new Set_Abbey(loc); } else if (q == 1) { loc.settlement = new Set_University(loc); } else { loc.settlement = new Set_Fort(loc); } } loc.soc = receiver; SettlementHuman set = (SettlementHuman)loc.settlement; set.population = 1;//Start at the start loc.map.addMessage(loc.soc.getName() + " expands, add new settlement: " + loc.getName(), MsgEvent.LEVEL_RED, false, loc.hex); } } }
public void AI_WeakReleased(Map map) { if (this.movesTaken != 0) { return; } if (this.task is Task_GoToLocation) { return; } //Already moving or fleeing if (this is Unit_Vampire vamp) { if (vamp.blood < vamp.maxBlood * 0.3 && location.person() != null) { //Drink vamp.blood = vamp.maxBlood; double amount = map.param.unit_minorEvidence; Evidence e2 = new Evidence(map.turn); e2.pointsTo = vamp; e2.weight = amount; vamp.location.evidence.Add(e2); return; } } bool shouldFlee = false; if (this.location.soc != null && this.location.soc.hostileTo(this)) { shouldFlee = true; } if (!shouldFlee) { foreach (Unit u in location.units) { if (u.hostileTo(this)) { shouldFlee = true; break; } } } if (!shouldFlee) { foreach (Location l2 in location.getNeighbours()) { if (shouldFlee) { break; } foreach (Unit u in l2.units) { if (u.hostileTo(this)) { shouldFlee = true; break; } } } } if (shouldFlee) { flee(map); } if (this.task != null) { return; } this.movesTaken += 1; if (this.location.person() != null) { if (this.location.settlement.infiltration < World.staticMap.param.ability_unit_spreadShadowInfiltrationReq) { bool lockedDown = false; foreach (Property p in location.properties) { if (p.proto is Pr_Lockdown) { lockedDown = true; break; } } if (location.settlement.security >= 5) { lockedDown = true; } if (!lockedDown) { this.task = new Task_Infiltrate_Weak(); return; } } else if (this.location.person().shadow < 1) { this.task = new Task_SpreadShadow_Weak(); return; } } //We're not starting a new task, so this location is bad. Onwards to greener pastures Location target = null; double bestDist = -1; int c = 0; Location safeHarbor = null; foreach (Location loc in map.locations) { if (loc == this.location) { continue; } if (loc.soc == null) { continue; } if (loc.soc.hostileTo(this)) { continue; } if (loc.person() != null && loc.soc is Society && loc.person().shadow < 1) { bool good = true; foreach (Unit u in loc.units) { if (u.hostileTo(this)) { good = false; break; } } if (loc.settlement.security >= 5) { good = false; } if (good) { foreach (Property pr in loc.properties) { if (pr.proto is Pr_Lockdown) { good = false; break; } if (pr.proto is Pr_MajorSecurityBoost) { good = false; break; } } } if (good) { double dist = Math.Abs(loc.hex.x - this.location.hex.x) + Math.Abs(loc.hex.y - this.location.hex.y); //dist *= Eleven.random.NextDouble(); double score = (loc.person().prestige + 5) / (dist + 1); if (loc.map.overmind.lightbringerLocations.Contains(loc)) { score *= 25; } //score *= Eleven.random.NextDouble() * Eleven.random.NextDouble(); //if (dist < bestDist || bestDist == -1) //{ // bestDist = dist; // target = loc; //} if (score > bestDist || bestDist == -1) { bestDist = score; target = loc; } } } if (loc.soc is Society) { c += 1; if (Eleven.random.Next(c) == 0) { safeHarbor = loc; } } } if (target != null) { task = new Task_GoToLocation(target); } else { //We're unable to find anywhere to infiltrate. Probably banned from everywhere else. Do we have safe harbor? Can we change our name? if (location.soc is Society && location.soc.hostileTo(this) == false) { //In a safe harbor, swap out now task = new Task_ChangeIdentity(); } else if (safeHarbor != null) { task = new Task_GoToLocation(safeHarbor); } else { die(map, "Was no further use");; } } }