public void flee(Map map)
        {
            double bestDist = 0;
            Location target = null;
            foreach (Location l2 in map.locations)
            {
                bool safe = true;
                if (l2.soc == null  || l2.soc.hostileTo(this)) {continue; }
                foreach (Unit u in l2.units)
                {
                    if (u.hostileTo(this)) { safe = false;break; }
                }
                if (!safe) { continue; }
                foreach (Location l3 in l2.getNeighbours())
                {
                    if (!safe) { break; }
                    foreach (Unit u in l3.units)
                    {
                        if (u.hostileTo(this)) { safe = false;break; }
                    }
                }
                if (!safe) { continue; }

                //Evaluated as safe. Flee option
                double dist = map.getDist(this.location, l2);
                if (dist < bestDist || target == null)
                {
                    target = l2;
                    bestDist = dist;
                }
            }
            task = new Task_GoToLocation(target);
        }
        public void turnTick()
        {
            if (map.locations[index] != this)
            {
                throw new Exception("Assertion failed: locations not consistent");
            }
            if (settlement != null)
            {
                settlement.turnTick();
            }

            foreach (Property p in properties)
            {
                p.proto.turnTick(p, this);
            }
            checkPropertiesEndOfTurn();

            foreach (Evidence e in evidence)
            {
                if (e.pointsTo != null && e.pointsTo.isEnthralled())
                {
                    map.hintSystem.popHint(HintSystem.hintType.EVIDENCE);
                }
            }

            if (soc != null && soc is Society)
            {
                foreach (Evidence e in evidence)
                {
                    if (e.assignedInvestigator != null)
                    {
                        if (map.units.Contains(e.assignedInvestigator) == false)
                        {
                            e.assignedInvestigator = null;
                        }                                                                                          //Dead
                        else if (e.assignedInvestigator.location != this && e.assignedInvestigator.task is Task_GoToClue == false)
                        {
                            e.assignedInvestigator = null;//Disrupted
                        }
                    }
                    e.rumourCounter += 1;
                    if (e.rumourCounter > 4)
                    {
                        e.rumourCounter = 0;
                        if (!e.reportedToSociety)//Evidence self-submits to the local society, to allow folks without investigators to have a chance
                        {
                            Society socSoc = (Society)soc;
                            socSoc.evidenceSubmitted.Add(e);
                            socSoc.lastEvidenceSubmission = map.turn;
                            e.turnSubmitted = map.turn;
                            e.locationFound = this;

                            //double deltaFear = World.staticMap.param.threat_evidencePresented;
                            if (socSoc.isDarkEmpire == false)
                            {
                                addAgentDreadAroundThisLocation();
                                //socSoc.dread_agents_evidenceFound += deltaFear;
                            }
                        }
                        e.reportedToSociety = true;
                        if (e.assignedInvestigator == null && e.pointsTo != null && e.pointsTo.person != null)
                        {
                            double minDist = 0;
                            Unit   bestU   = null;
                            foreach (Unit u in map.units)
                            {
                                if (
                                    u is Unit_Investigator &&
                                    u.person != null &&
                                    u.person.state != Person.personState.enthralledAgent &&
                                    u.person.getRelation(e.pointsTo.person).suspicion > 0 &&
                                    u.task is Task_Wander &&
                                    u.location.evidence.Count == 0)
                                {
                                    double dist = map.getDist(u.location, this);
                                    dist *= Eleven.random.NextDouble();
                                    if (dist < minDist || bestU == null)
                                    {
                                        bestU   = u;
                                        minDist = dist;
                                    }
                                }
                            }
                            if (bestU != null)
                            {
                                e.assignedInvestigator = bestU;
                                bestU.task             = new Task_GoToClue(this);
                                map.world.prefabStore.popMsgAgent(bestU, e.pointsTo, bestU.getName() + " has learnt of evidence in " + this.getName() + " and is travelling to investigate." +
                                                                  " They recognised the methods of " + e.pointsTo.getName() + ", whom they were already suspicious of.");
                            }
                        }
                    }
                }
            }

            bool needDeletion = false;

            foreach (Unit u in units)
            {
                if (u.location != this)
                {
                    throw new Exception("Unit at wrong location: " + u.getName() + " at " + this.getName());
                }
                if (map.units.Contains(u) == false)
                {
                    needDeletion = true;
                    //throw new Exception("Badly handled unit");
                }
            }

            //A horrific hack, because units were, for whatever reason, getting left behind in locations
            //They called "disband", removed themselves from the main unit list, and even checked to ensure they were gone. For whatever reason, either they were not or they were re-added later
            //Bad times, can't fix, sad times
            //
            //Might have been fixed a while ago, I realise. Feel free to try removing this and seeing what it does. Or changing it to an assert
            if (needDeletion)
            {
                List <Unit> rems = new List <Unit>();
                foreach (Unit u in units)
                {
                    if (map.units.Contains(u) == false)
                    {
                        rems.Add(u);
                    }
                }
                foreach (Unit u in rems)
                {
                    units.Remove(u);
                }
            }

            recomputeLinkDisabling();
        }
        public void turnTickAI_Medic(Map map)
        {
            if (task == null)
            {
                bool onDisease = false;
                foreach (Property pr in location.properties)
                {
                    if (pr.proto.isDisease)
                    {
                        onDisease = true;
                        break;
                    }
                }
                if (onDisease)
                {
                    task = new Task_TreatDisease();
                    return;
                }

                double   dist      = 0;
                Location plagueLoc = null;
                foreach (Location loc in map.locations)
                {
                    if (loc.soc == null || loc.soc.hostileTo(this))
                    {
                        continue;
                    }

                    bool hasDisease = false;
                    foreach (Property pr in loc.properties)
                    {
                        if (pr.proto.isDisease)
                        {
                            hasDisease = true;
                            break;
                        }
                    }
                    if (!hasDisease)
                    {
                        continue;
                    }
                    double d = map.getDist(loc.hex, location.hex);
                    if (plagueLoc == null)
                    {
                        plagueLoc = loc;
                        dist      = d;
                    }
                    else if (plagueLoc.soc != this.society && loc.soc == this.society)
                    {
                        plagueLoc = loc;
                        dist      = d;
                    }
                    else if (plagueLoc.soc == this.society && loc.soc != this.society)
                    {
                        //Don't switch to prefer a foreign location
                    }
                    else if (d < dist)
                    {
                        dist      = d;
                        plagueLoc = loc;
                    }
                }
                if (plagueLoc != null)
                {
                    task = new Task_GoToLocation(plagueLoc);
                }
            }
            if (task != null)
            {
                task.turnTick(this);
            }
        }