Ejemplo n.º 1
0
        public override double computeUtility(Person voter, VoteOption option, List <ReasonMsg> msgs)
        {
            double u = option.getBaseUtility(voter);

            Person p = option.person;

            double newValue = title.getPrestige();

            double benefitToPerson = newValue;

            //We know how much they would be advantaged. We now need to know how much we like them to determine
            //if this is a good thing or not

            double benefitU = benefitToPerson * voter.getRelation(p).getLiking() * voter.map.param.utility_unlandedTitleMult;

            //Check if you should avoid voting for yourself
            bool wouldBeOutvoted = false;

            if (p == voter)
            {
                foreach (Person p2 in voter.society.people)
                {
                    if (p2.prestige > p.prestige * 2)
                    {
                        wouldBeOutvoted = true;
                    }
                }
            }
            if (wouldBeOutvoted)
            {
                benefitU *= voter.map.param.utility_wouldBeOutvotedMult;
                msgs.Add(new ReasonMsg("Benefit to (reduced by fears of being outvoted) " + p.getFullName(), benefitU));
                u += benefitU;
            }
            else
            {
                msgs.Add(new ReasonMsg("Benefit to " + p.getFullName(), benefitU));
                u += benefitU;
            }

            //We need to know if someone's going to lose out here
            //(Note this is irrelevant if they're the person who's being voted on)
            if (title.heldBy != null && title.heldBy != p)
            {
                double damageToOther = title.getPrestige();
                double localU        = -damageToOther *voter.getRelation(title.heldBy).getLiking() * voter.map.param.utility_unlandedTitleMult;

                if (wouldBeOutvoted)
                {
                    localU *= voter.map.param.utility_wouldBeOutvotedMult;
                }
                msgs.Add(new ReasonMsg("Harm to " + title.heldBy.getFullName(), localU));
                u += localU;
            }

            //Existing prestige of person being voted on
            double prestigeU = p.prestige * society.map.param.utility_prestigeMultForTitle;

            msgs.Add(new ReasonMsg("Prestige of " + p.getFullName(), prestigeU));
            u += prestigeU;

            return(u);
        }
Ejemplo n.º 2
0
        public override void cast(Map map, Hex hex)
        {
            base.cast(map, hex);


            ThreatItem item = hex.location.person().getGreatestThreat();

            if (item == null)
            {
                return;
            }

            string changes = "";

            foreach (Location loc in hex.location.getNeighbours())
            {
                if (loc.person() != null)
                {
                    Person other = loc.person();
                    foreach (ThreatItem t2 in other.threatEvaluations)
                    {
                        if (t2.isSame(item))
                        {
                            double delta = item.threat - t2.threat;
                            if (delta <= 0)
                            {
                                continue;
                            }
                            double liking = other.getRelation(hex.location.person()).getLiking();
                            if (liking <= 0)
                            {
                                continue;
                            }
                            liking /= 100;

                            double prev = t2.threat;
                            delta *= liking;
                            if (t2.threat + delta > 200)
                            {
                                delta = 200 - t2.threat;
                            }
                            t2.threat         += delta;
                            t2.temporaryDread += delta;

                            changes += other.getFullName() + " " + (int)(prev) + " -> " + (int)(t2.threat) + "; ";
                        }
                    }
                }
            }
            if (changes.Length > 0)
            {
                changes = changes.Substring(0, changes.Length - 2);//Strip the last separator
            }

            string msgs = "You spread " + hex.location.person().getFullName() + "'s fears of " + item.getTitle() + " to any neighbour who will listen. ";

            if (changes.Length > 0)
            {
                msgs += "\n" + changes;
            }
            else
            {
                msgs += "\nBut there are none.";
            }
            map.world.prefabStore.popImgMsg(
                msgs,
                map.world.wordStore.lookup("ABILITY_SPREAD_FEAR"));
        }
Ejemplo n.º 3
0
        public Color getColor(Hex hex)
        {
            if (mask == maskType.NATION)
            {
                if (hex.owner != null)
                {
                    float r     = hex.owner.color[0];
                    float g     = hex.owner.color[1];
                    float b     = hex.owner.color[2];
                    Color color = new Color(r, g, b, 0.8f);
                    return(color);
                }
                else
                {
                    return(new Color(0.5f, 0.5f, 0.5f, 0.5f));
                }
            }
            else if (mask == maskType.PROVINCE)
            {
                return(new Color(hex.province.cr, hex.province.cg, hex.province.cb, 0.5f));
            }
            else if (mask == maskType.INFORMATION)
            {
                if (hex.location != null && GraphicalMap.selectedHex != null && GraphicalMap.selectedHex.location != null && GraphicalMap.selectedHex.location.soc != null)
                {
                    SocialGroup group = GraphicalMap.selectedHex.location.soc;

                    float mult = (float)map.getInformationAvailability(hex.location, group);
                    mult = Mathf.Max(0, mult);
                    mult = Mathf.Min(1, mult);
                    float r = mult;
                    float g = mult;
                    float b = mult;

                    //Color color = new Color(r, g, b, 0.8f);
                    Color color = new Color(0, 0, 0, (1 - mult));
                    return(color);
                }
                else if (hex.location != null)
                {
                    return(new Color(0f, 0f, 0f, 1f));
                }
                else
                {
                    return(new Color(0f, 0f, 0f, 0.75f));
                }
            }
            else if (mask == maskType.THREAT)
            {
                if (hex.location != null && GraphicalMap.selectedHex != null && GraphicalMap.selectedHex.location != null && GraphicalMap.selectedHex.location.settlement != null && GraphicalMap.selectedHex.location.settlement.title != null && GraphicalMap.selectedHex.location.settlement.title.heldBy != null)
                {
                    SocialGroup group = GraphicalMap.selectedHex.location.soc;

                    Person p             = GraphicalMap.selectedHex.settlement.title.heldBy;
                    double highestThreat = 0;
                    foreach (ThreatItem item in p.threatEvaluations)
                    {
                        if (item.group != null && item.threat > highestThreat)
                        {
                            highestThreat = item.threat;
                        }
                    }
                    if (highestThreat != 0)
                    {
                        if (hex.location.soc == null)
                        {
                            return(Color.black);
                        }
                        double threat = 0;
                        foreach (ThreatItem item in p.threatEvaluations)
                        {
                            if (item.group == hex.location.soc)
                            {
                                threat = item.threat / highestThreat; break;
                            }
                        }
                        float mult = (float)threat;
                        mult = Mathf.Max(0, mult);
                        mult = Mathf.Min(1, mult);
                        float r = mult;
                        float g = mult;
                        float b = mult;

                        //Color color = new Color(r, g, b, 0.8f);
                        Color color = new Color(mult, 0, 0, 0.5f);
                        return(color);
                    }
                    else
                    {
                        return(Color.black);
                    }
                }
                else if (hex.location != null)
                {
                    return(new Color(0f, 0f, 0f, 1f));
                }
                else
                {
                    return(new Color(0f, 0f, 0f, 0.75f));
                }
            }

            else if (mask == maskType.LIKING_THEM)
            {
                Color c = new Color(0, 0, 0, 0.5f);
                try
                {
                    Person me     = GraphicalMap.selectedHex.location.settlement.title.heldBy;
                    Person them   = hex.location.settlement.title.heldBy;
                    float  liking = (float)them.getRelation(me).getLiking();
                    if (liking > 0)
                    {
                        if (liking > 100)
                        {
                            liking = 100;
                        }
                        liking /= 100;
                        c       = new Color(0, liking, 0, 0.5f);
                    }
                    else
                    {
                        liking *= -1;
                        if (liking > 100)
                        {
                            liking = 100;
                        }
                        liking /= 100;
                        c       = new Color(liking, 0, 0, 0.5f);
                    }
                }
                catch (NullReferenceException e)
                {
                }
                catch (ArgumentNullException e)
                {
                }
                return(c);
            }

            else if (mask == maskType.LIKING_ME)
            {
                Color c = new Color(0, 0, 0, 0.5f);
                try
                {
                    Person me     = GraphicalMap.selectedHex.location.settlement.title.heldBy;
                    Person them   = hex.location.settlement.title.heldBy;
                    float  liking = (float)me.getRelation(them).getLiking();
                    if (liking > 0)
                    {
                        if (liking > 100)
                        {
                            liking = 100;
                        }
                        liking /= 100;
                        c       = new Color(0, liking, 0, 0.5f);
                    }
                    else
                    {
                        liking *= -1;
                        if (liking > 100)
                        {
                            liking = 100;
                        }
                        liking /= 100;
                        c       = new Color(liking, 0, 0, 0.5f);
                    }
                }
                catch (NullReferenceException e)
                {
                }
                catch (ArgumentNullException e)
                {
                }
                return(c);
            }
            else if (mask == maskType.EVIDENCE)
            {
                try
                {
                    Person them = hex.settlement.title.heldBy;

                    return(new Color((float)them.evidence, 0, 0, 0.5f));
                }
                catch (Exception e)
                {
                    return(new Color(0, 0, 0, 0.5f));
                }
            }
            else if (mask == maskType.SUSPICION)
            {
                try
                {
                    Person me   = GraphicalMap.selectedHex.settlement.title.heldBy;
                    Person them = hex.settlement.title.heldBy;
                    RelObj rel  = me.getRelation(them);

                    return(new Color((float)rel.suspicion, 0, 0, 0.5f));
                }catch (Exception e)
                {
                    return(new Color(0, 0, 0, 0.5f));
                }
            }
            else if (mask == maskType.SUSPICION_FROM)
            {
                try
                {
                    Person them = GraphicalMap.selectedHex.settlement.title.heldBy;
                    Person me   = hex.settlement.title.heldBy;
                    RelObj rel  = me.getRelation(them);

                    return(new Color((float)rel.suspicion, 0, 0, 0.5f));
                }
                catch (Exception e)
                {
                    return(new Color(0, 0, 0, 0.5f));
                }
            }
            else if (mask == maskType.TESTING)
            {
                if (hex.location != null)
                {
                    if (hex.location.debugVal == map.turn)
                    {
                        return(new Color(1, 1, 1, 0.5f));
                    }
                    else
                    {
                        return(new Color(0, 0, 0, 0.5f));
                    }
                }

                return(new Color(0f, 0f, 0f, 0.75f));
            }
            else
            {
                return(new Color(0, 0, 0, 0));
            }
        }
Ejemplo n.º 4
0
        public string getBodyText()
        {
            if (mask == maskType.LIKING_ME)
            {
                try
                {
                    Hex    hex  = GraphicalMap.getHexUnderMouse(Input.mousePosition).hex;
                    Person me   = GraphicalMap.selectedHex.location.settlement.title.heldBy;
                    Person them = hex.location.settlement.title.heldBy;

                    if (me.state == Person.personState.enthralled)
                    {
                        return(me.getFullName() + " is enthralled, so does not have normal likings.");
                    }
                    string words = me.getFullName() + " liking for " + them.getFullName();
                    RelObj rel   = me.getRelation(them);
                    words += "\nAmount: " + ((int)rel.getLiking());

                    double sus = rel.getDislikingFromSuspicion(me);
                    if (sus != 0)
                    {
                        words += "\nFROM SUSPICION: " + sus;
                    }
                    List <RelEvent> sortedEvents = new List <RelEvent>();
                    sortedEvents.AddRange(rel.events);
                    sortedEvents.Sort();
                    int nPrinted = 0;
                    foreach (RelEvent ev in sortedEvents)
                    {
                        words    += "\n  -" + ev.reason + " : " + ((int)ev.amount);
                        nPrinted += 1;
                        if (nPrinted > 6)
                        {
                            break;
                        }
                    }
                    return(words);
                }
                catch (Exception e)
                {
                    return("");
                }
            }
            else if (mask == maskType.LIKING_THEM)
            {
                try
                {
                    Hex    hex  = GraphicalMap.getHexUnderMouse(Input.mousePosition).hex;
                    Person them = GraphicalMap.selectedHex.location.settlement.title.heldBy;
                    Person me   = hex.location.settlement.title.heldBy;

                    if (me.state == Person.personState.enthralled)
                    {
                        return(me.getFullName() + " is enthralled, so does not have normal likings.");
                    }

                    string words = me.getFullName() + " liking for " + them.getFullName();
                    RelObj rel   = me.getRelation(them);
                    words += "\nAmount: " + ((int)rel.getLiking());

                    double sus = rel.getDislikingFromSuspicion(me);
                    if (sus != 0)
                    {
                        words += "\nFROM SUSPICION: " + (int)sus;
                    }

                    List <RelEvent> sortedEvents = new List <RelEvent>();
                    sortedEvents.AddRange(rel.events);
                    sortedEvents.Sort();
                    int nPrinted = 0;
                    foreach (RelEvent ev in sortedEvents)
                    {
                        words    += "\n  -" + ev.reason + " : " + ((int)ev.amount);
                        nPrinted += 1;
                        if (nPrinted > 6)
                        {
                            break;
                        }
                    }
                    return(words);
                }
                catch (Exception e)
                {
                    return("");
                }
            }
            return("");
        }
Ejemplo n.º 5
0
        public string getBodyText()
        {
            if (mask == maskType.LIKING_ME)
            {
                try
                {
                    Hex    hex = GraphicalMap.getHexUnderMouse(Input.mousePosition).hex;
                    Person me  = null;
                    if (GraphicalMap.selectedSelectable is Unit)
                    {
                        if (((Unit)GraphicalMap.selectedSelectable).person != null)
                        {
                            me = ((Unit)GraphicalMap.selectedSelectable).person;
                        }
                    }
                    else
                    {
                        me = GraphicalMap.selectedHex.location.settlement.title.heldBy;
                    }
                    Person them = hex.location.settlement.title.heldBy;

                    if (me.state == Person.personState.enthralled)
                    {
                        return(me.getFullName() + " is enthralled, so does not have normal likings.");
                    }
                    string words = me.getFullName() + " liking for " + them.getFullName();
                    RelObj rel   = me.getRelation(them);
                    words += "\nAmount: " + ((int)rel.getLiking());

                    double sus = rel.getDislikingFromSuspicion();
                    if (sus != 0)
                    {
                        words += "\nFROM SUSPICION: " + (int)sus;
                    }

                    List <ReasonMsg> msgs = new List <ReasonMsg>();
                    RelObj.getLikingModifiers(me, them.index, msgs);
                    foreach (ReasonMsg msg in msgs)
                    {
                        words += "\n\n  -" + msg.msg + " " + ((int)msg.value);
                    }

                    List <RelEvent> sortedEvents = new List <RelEvent>();
                    sortedEvents.AddRange(rel.events);
                    sortedEvents.Sort();
                    int nPrinted = 0;
                    foreach (RelEvent ev in sortedEvents)
                    {
                        words    += "\n\n  -" + ev.reason + " : " + ((int)ev.amount);
                        nPrinted += 1;
                        if (nPrinted > 6)
                        {
                            break;
                        }
                    }
                    return(words);
                }
                catch (Exception e)
                {
                    return("");
                }
            }
            else if (mask == maskType.LIKING_THEM)
            {
                try
                {
                    Hex    hex  = GraphicalMap.getHexUnderMouse(Input.mousePosition).hex;
                    Person them = null;
                    if (GraphicalMap.selectedSelectable is Unit)
                    {
                        if (((Unit)GraphicalMap.selectedSelectable).person != null)
                        {
                            them = ((Unit)GraphicalMap.selectedSelectable).person;
                        }
                    }
                    else
                    {
                        them = GraphicalMap.selectedHex.location.settlement.title.heldBy;
                    }
                    Person me = hex.location.settlement.title.heldBy;

                    if (me.state == Person.personState.enthralled)
                    {
                        return(me.getFullName() + " is enthralled, so does not have normal likings.");
                    }

                    string words = me.getFullName() + " liking for " + them.getFullName();
                    RelObj rel   = me.getRelation(them);
                    words += "\nAmount: " + ((int)rel.getLiking());

                    double sus = rel.getDislikingFromSuspicion();
                    if (sus != 0)
                    {
                        words += "\nFROM SUSPICION: " + (int)sus;
                    }

                    List <ReasonMsg> msgs = new List <ReasonMsg>();
                    RelObj.getLikingModifiers(me, them.index, msgs);
                    foreach (ReasonMsg msg in msgs)
                    {
                        words += "\n\n  -" + msg.msg + " " + ((int)msg.value);
                    }

                    List <RelEvent> sortedEvents = new List <RelEvent>();
                    sortedEvents.AddRange(rel.events);
                    sortedEvents.Sort();
                    int nPrinted = 0;
                    foreach (RelEvent ev in sortedEvents)
                    {
                        words    += "\n\n  -" + ev.reason + " : " + ((int)ev.amount);
                        nPrinted += 1;
                        if (nPrinted > 6)
                        {
                            break;
                        }
                    }
                    return(words);
                }
                catch (Exception e)
                {
                    return("");
                }
            }
            else if (mask == maskType.VOTE_EFFECT)
            {
                if (GraphicalMap.selectedHex != null && GraphicalMap.selectedHex.location != null && GraphicalMap.selectedHex.location.person() != null)
                {
                    Person  voter = GraphicalMap.selectedHex.location.person();
                    Society soc   = (Society)voter.society;
                    if (soc.voteSession == null)
                    {
                        return("No voting currently happening in " + voter.getFullName() + "'s society");
                    }
                    VoteOption opt = soc.voteSession.issue.options[0];
                    foreach (VoteOption o2 in soc.voteSession.issue.options)
                    {
                        if (o2.votesFor.Contains(voter))
                        {
                            opt = o2;
                            break;
                        }
                    }
                    return("The change in liking towards " + voter.getFullName() + " if they vote for their currently preferred option (" + opt.info(soc.voteSession.issue) + ").");
                }
            }
            return("");
        }
Ejemplo n.º 6
0
        public static void refresh(Person pf)
        {
            focus = pf;

            int tn = activeSociety.people.Count - 1;
            int i  = 0;

            foreach (GraphicalSlot s in loadedSlots)
            {
                if (s.inner == focus)
                {
                    s.targetPosition = Vector3.zero;

                    s.subtitle.text       = "";
                    s.lowerRightText.text = "";
                }
                else
                {
                    int n, ring;
                    if (i < 12)
                    {
                        n    = (tn < 12) ? tn : 12;
                        ring = 0;
                    }
                    else
                    {
                        n    = (tn - 12 < 52) ? tn - 12 : 52;
                        ring = 1;
                    }

                    RelObj rel    = focus.getRelation(s.inner);
                    float  liking = (float)rel.getLiking() / 100;
                    if (i == 0)
                    {
                        Debug.Log(rel.suspicion.ToString());
                    }

                    float radius = (1.75f * ring + 3.0f);
                    float x      = Mathf.Cos(6.28f / n * i + ring * 0.1f) * radius;
                    float y      = Mathf.Sin(6.28f / n * i + ring * 0.1f) * radius;

                    s.targetPosition = new Vector3(x, y, 0.0f);
                    if (liking < 0)
                    {
                        s.targetColor = Color.Lerp(s.neutralColor, s.badColor, -liking);
                    }
                    else
                    {
                        s.targetColor = Color.Lerp(s.neutralColor, s.goodColor, liking);
                    }
                    s.targetColor.a = 0.5f;
                    //s.targetColor.a = 0.1f + ((float)rel.suspicion / 100);

                    s.subtitle.text        = "Relationship with " + focus.firstName;
                    s.lowerRightText.text  = "Liked by: " + focus.getRelation(s.inner).getLiking().ToString("N0") + "%";
                    s.lowerRightText.text += ", Likes: " + s.inner.getRelation(focus).getLiking().ToString("N0") + "%";
                    s.lowerRightText.text += "\nSuspected by: " + focus.getRelation(s.inner).suspicion.ToString("N0") + "%";
                    s.lowerRightText.text += ", Suspects: " + s.inner.getRelation(focus).suspicion.ToString("N0") + "%";

                    i += 1;
                }
            }
        }
        public override void turnTick(Unit unit)
        {
            //Enthralled can't just eat clues
            if (unit.isEnthralled())
            {
                unit.task = null;
                return;
            }

            if (unit.location.evidence.Count > 0)
            {
                Evidence massiveEvidence = null;
                foreach (Evidence ev in unit.location.evidence)
                {
                    if (ev.instaDiscover)
                    {
                        massiveEvidence = ev; break;
                    }
                }
                if (massiveEvidence != null)
                {
                    discoverMassiveEvidence(massiveEvidence, unit);
                    return;
                }

                dur += 1;
                if (dur >= unit.location.map.param.unit_investigateTime)
                {
                    Evidence ev = unit.location.evidence[0];
                    if (ev.pointsTo != null)
                    {
                        if (unit.person != null && ev.pointsTo.person != null)
                        {
                            unit.person.getRelation(ev.pointsTo.person).suspicion = System.Math.Min(1, unit.person.getRelation(ev.pointsTo.person).suspicion + ev.weight);
                        }
                        else
                        {
                            //Can't use suspicion system, go straight to murder
                            //Makes sense since they're probably non-human terrors
                            unit.hostility.Add(ev.pointsTo);
                        }

                        unit.location.map.addMessage(unit.getName() + " has found evidence from " + ev.pointsTo.getName(), MsgEvent.LEVEL_ORANGE, false, unit.location.hex);
                    }
                    else if (ev.pointsToPerson != null)
                    {
                        if (unit.person != null && ev.pointsToPerson != null)
                        {
                            unit.person.getRelation(ev.pointsToPerson).suspicion = System.Math.Min(1, unit.person.getRelation(ev.pointsToPerson).suspicion + ev.weight);
                        }

                        unit.location.map.addMessage(unit.getName() + " has found evidence from " + ev.pointsToPerson.getFullName(), MsgEvent.LEVEL_ORANGE, false, unit.location.hex);
                    }


                    if (unit is Unit_Investigator)
                    {
                        Unit_Investigator inv = (Unit_Investigator)unit;
                        inv.evidenceCarried.Add(ev);
                        ev.discoveredBy = inv;
                    }
                    ev.locationFound = unit.location;
                    unit.location.evidence.Remove(ev);
                    unit.task = null;

                    unit.location.map.overmind.panicFromCluesDiscovered += unit.location.map.param.panic_fromClueFound;
                    if (unit.location.map.overmind.panicFromCluesDiscovered > 1)
                    {
                        unit.location.map.overmind.panicFromCluesDiscovered = 1;
                    }


                    //If we're already at maximum suspicion we can now begin pursuing them
                    if (unit is Unit_Investigator)
                    {
                        Unit_Investigator inv = (Unit_Investigator)unit;
                        if (inv.state == Unit_Investigator.unitState.investigator)
                        {
                            if (ev.pointsTo != null && ev.pointsTo.person != null && inv.person.getRelation(ev.pointsTo.person).suspicion >= 1)
                            {
                                Task_HuntEnthralled_InvState task = new Task_HuntEnthralled_InvState(inv, ev.pointsTo);
                                inv.task = task;
                                unit.location.map.world.prefabStore.popMsgAgent(inv, ev.pointsTo,
                                                                                inv.getName() + " has found evidence left by " + ev.pointsTo.getName() + ", and because they are an investigator who is 100% suspicious of " + ev.pointsTo.getName()
                                                                                + ", is able to use these clues to determine the location of " + ev.pointsTo.getName() + ", and will begin to chase them for " + task.turnsLeft + " turns.");
                            }
                        }
                    }

                    if (unit.task == null)
                    {
                        if (unit.location.person() != null)
                        {
                            Person noble = unit.location.person();
                            foreach (RelObj rel in unit.person.relations.Values)
                            {
                                ////Goes negative if they suspect more than we do, reaches 1.0 if we suspect 1.0 and they suspect 0.0
                                // if ((rel.suspicion - noble.getRelation(rel.them).suspicion) > Eleven.random.NextDouble())
                                if ((rel.suspicion > noble.getRelation(rel.them).suspicion * 1.1))
                                {
                                    unit.task = new Task_ShareSuspicions();
                                    return;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                //Evidence gone. Probably eaten by someone else. Return to idle to retask next turn
                unit.task = null;
            }
        }
Ejemplo n.º 8
0
        public Color getColor(Hex hex)
        {
            if (mask == maskType.NONE)
            {
                if (GraphicalMap.selectedSelectable != null && GraphicalMap.selectedSelectable is Unit)
                {
                    if (hex.owner != null && hex.owner.hostileTo((Unit)GraphicalMap.selectedSelectable))
                    {
                        return(new Color(0.5f, 0.0f, 0f, 0.5f));
                    }
                }
                return(Color.clear);
            }
            else if (mask == maskType.NATION)
            {
                if (hex.owner != null)
                {
                    float r     = hex.owner.color.r;
                    float g     = hex.owner.color.g;
                    float b     = hex.owner.color.b;
                    Color color = new Color(r, g, b, 0.8f);
                    return(color);
                }
                else
                {
                    return(new Color(0.5f, 0.5f, 0.5f, 0.5f));
                }
            }
            else if (mask == maskType.PROVINCE)
            {
                return(new Color(hex.province.cr, hex.province.cg, hex.province.cb, 0.5f));
            }
            else if (mask == maskType.VOTE_EFFECT)
            {
                if (GraphicalMap.selectedHex != null && GraphicalMap.selectedHex.location != null && GraphicalMap.selectedHex.location.person() != null && hex.location != null && hex.location.soc != null)
                {
                    if (GraphicalMap.selectedHex == hex)
                    {
                        return(new Color(1f, 1f, 1f, 0.5f));
                    }
                    Person voter = GraphicalMap.selectedHex.location.person();
                    if (hex.location.soc == voter.society)
                    {
                        if (hex.location.person() != null && hex.location.soc is Society)
                        {
                            Society soc = (Society)hex.location.soc;
                            if (soc.voteSession == null)
                            {
                                return(new Color(0f, 0f, 0f, 0.75f));
                            }
                            VoteOption opt = null;
                            foreach (VoteOption o2 in soc.voteSession.issue.options)
                            {
                                if (o2.votesFor.Contains(voter))
                                {
                                    opt = o2;
                                    break;
                                }
                            }
                            if (opt == null)
                            {
                                soc.voteSession.assignVoters();
                            }
                            foreach (VoteOption o2 in soc.voteSession.issue.options)
                            {
                                if (o2.votesFor.Contains(voter))
                                {
                                    opt = o2;
                                    break;
                                }
                            }
                            if (soc.voteSession != null)
                            {
                                float delta = (float)soc.voteSession.issue.getLikingDelta(hex.location.person(), opt, soc.voteSession.issue);
                                delta /= 25;
                                if (delta > 1)
                                {
                                    delta = 1f;
                                }
                                if (delta < -1)
                                {
                                    delta = -1f;
                                }
                                if (delta >= 0)
                                {
                                    return(new Color(0f, delta, 0f, 0.75f));
                                }
                                else
                                {
                                    return(new Color(-delta, 0f, 0f, 0.75f));
                                }
                            }
                        }
                    }
                }
                return(new Color(0f, 0f, 0f, 0.75f));
            }
            else if (mask == maskType.THREAT)
            {
                if (hex.location != null && GraphicalMap.selectedHex != null && GraphicalMap.selectedHex.location != null && GraphicalMap.selectedHex.location.settlement != null && GraphicalMap.selectedHex.location.settlement.title != null && GraphicalMap.selectedHex.location.settlement.title.heldBy != null)
                {
                    SocialGroup group = GraphicalMap.selectedHex.location.soc;

                    Person p             = GraphicalMap.selectedHex.settlement.title.heldBy;
                    double highestThreat = 0;
                    foreach (ThreatItem item in p.threatEvaluations)
                    {
                        if (item.group != null && item.threat > highestThreat)
                        {
                            highestThreat = item.threat;
                        }
                    }
                    if (highestThreat != 0)
                    {
                        if (hex.location.soc == null)
                        {
                            return(Color.black);
                        }
                        double threat = 0;
                        foreach (ThreatItem item in p.threatEvaluations)
                        {
                            if (item.group == hex.location.soc)
                            {
                                threat = item.threat / highestThreat; break;
                            }
                        }
                        float mult = (float)threat;
                        mult = Mathf.Max(0, mult);
                        mult = Mathf.Min(1, mult);

                        //Color color = new Color(r, g, b, 0.8f);
                        Color color = new Color(mult, 0, 0, 0.5f);
                        return(color);
                    }
                    else
                    {
                        return(Color.black);
                    }
                }
                else if (hex.location != null)
                {
                    return(new Color(0f, 0f, 0f, 1f));
                }
                else
                {
                    return(new Color(0f, 0f, 0f, 0.75f));
                }
            }

            else if (mask == maskType.LIKING_THEM)
            {
                Color c = new Color(0, 0, 0, 0.5f);
                try
                {
                    Person me = null;
                    if (GraphicalMap.selectedSelectable is Unit)
                    {
                        if (((Unit)GraphicalMap.selectedSelectable).person != null)
                        {
                            me = ((Unit)GraphicalMap.selectedSelectable).person;
                        }
                    }
                    else
                    {
                        me = GraphicalMap.selectedHex.location.settlement.title.heldBy;
                    }

                    Person them   = hex.location.settlement.title.heldBy;
                    float  liking = (float)them.getRelation(me).getLiking();
                    if (liking > 0)
                    {
                        if (liking > 100)
                        {
                            liking = 100;
                        }
                        liking /= 100;
                        c       = new Color(0, liking, 0, 0.5f);
                    }
                    else
                    {
                        liking *= -1;
                        if (liking > 100)
                        {
                            liking = 100;
                        }
                        liking /= 100;
                        c       = new Color(liking, 0, 0, 0.5f);
                    }
                }
                catch (NullReferenceException e)
                {
                }
                catch (ArgumentNullException e)
                {
                }
                return(c);
            }

            else if (mask == maskType.LIKING_ME)
            {
                Color c = new Color(0, 0, 0, 0.5f);
                try
                {
                    Person me = null;
                    if (GraphicalMap.selectedSelectable is Unit)
                    {
                        if (((Unit)GraphicalMap.selectedSelectable).person != null)
                        {
                            me = ((Unit)GraphicalMap.selectedSelectable).person;
                        }
                    }
                    else
                    {
                        me = GraphicalMap.selectedHex.location.settlement.title.heldBy;
                    }
                    Person them   = hex.location.settlement.title.heldBy;
                    float  liking = (float)me.getRelation(them).getLiking();
                    if (liking > 0)
                    {
                        if (liking > 100)
                        {
                            liking = 100;
                        }
                        liking /= 100;
                        c       = new Color(0, liking, 0, 0.5f);
                    }
                    else
                    {
                        liking *= -1;
                        if (liking > 100)
                        {
                            liking = 100;
                        }
                        liking /= 100;
                        c       = new Color(liking, 0, 0, 0.5f);
                    }
                }
                catch (NullReferenceException e)
                {
                }
                catch (ArgumentNullException e)
                {
                }
                return(c);
            }
            else if (mask == maskType.AWARENESS)
            {
                try
                {
                    Person them = hex.settlement.title.heldBy;

                    return(new Color((float)them.awareness, 0, 0, 0.9f));
                }
                catch (Exception e)
                {
                    return(new Color(0, 0, 0, 0.9f));
                }
            }
            else if (mask == maskType.INFILTRATION)
            {
                try
                {
                    float inf = (float)hex.settlement.infiltration;

                    return(new Color(inf, inf, inf, 0.9f));
                }
                catch (Exception e)
                {
                    return(new Color(0, 0, 0, 0.9f));
                }
            }
            else if (mask == maskType.SUSPICION)
            {
                try
                {
                    Person me   = GraphicalMap.selectedHex.settlement.title.heldBy;
                    Person them = hex.settlement.title.heldBy;
                    RelObj rel  = me.getRelation(them);

                    return(new Color((float)rel.suspicion, 0, 0, 0.5f));
                }catch (Exception e)
                {
                    return(new Color(0, 0, 0, 0.5f));
                }
            }
            else if (mask == maskType.SUSPICION_FROM)
            {
                try
                {
                    Person them = GraphicalMap.selectedHex.settlement.title.heldBy;
                    Person me   = hex.settlement.title.heldBy;
                    RelObj rel  = me.getRelation(them);

                    return(new Color((float)rel.suspicion, 0, 0, 0.5f));
                }
                catch (Exception e)
                {
                    return(new Color(0, 0, 0, 0.5f));
                }
            }
            else if (mask == maskType.TESTING)
            {
                if (hex.location != null)
                {
                    if (hex.location.debugVal == map.turn)
                    {
                        return(new Color(1, 1, 1, 0.5f));
                    }
                    else
                    {
                        return(new Color(0, 0, 0, 0.5f));
                    }
                }

                return(new Color(0f, 0f, 0f, 0.75f));
            }
            else
            {
                return(new Color(0, 0, 0, 0));
            }
        }
        public void takeLocationFromOther(SocialGroup att, SocialGroup def, Location taken)
        {
            World.log(att.getName() + " takes " + taken.getName() + " from " + def.getName());
            int  priority = MsgEvent.LEVEL_YELLOW;
            bool benefit  = !def.hasEnthralled();

            if (att.hasEnthralled())
            {
                priority = MsgEvent.LEVEL_GREEN;
            }
            else if (def.hasEnthralled())
            {
                priority = MsgEvent.LEVEL_RED;
            }
            else
            {
                priority = MsgEvent.LEVEL_YELLOW;
            }


            turnMessages.Add(new MsgEvent(att.getName() + " takes " + taken.getName() + " from " + def.getName(), priority, benefit));

            if (taken.settlement != null)
            {
                if (taken.settlement.isHuman == false)
                {
                    taken.settlement = null;//Burn it down
                }
                else if (taken.settlement.title != null && taken.settlement.title.heldBy != null)
                {
                    Person lord = taken.settlement.title.heldBy;
                    if (att is Society)
                    {
                        Society socAtt = (Society)att;
                        lord.prestige *= param.combat_prestigeLossFromConquest;
                        if (socAtt.getSovreign() != null)
                        {
                            lord.getRelation(socAtt.getSovreign()).addLiking(param.person_likingFromBeingInvaded, "Their nation invaded mine", turn);
                        }
                        foreach (Title t in lord.titles)
                        {
                            t.heldBy = null;
                        }
                        lord.titles.Clear();


                        movePerson(lord, socAtt);
                    }
                    else
                    {
                        lord.die("Killed by " + att.getName() + " when " + taken.getName() + " fell");
                    }
                }
            }

            taken.soc = att;
            att.takeLocationFromOther(def, taken);

            bool hasRemainingTerritory = false;

            foreach (Location loc in locations)
            {
                if (loc.soc == def)
                {
                    hasRemainingTerritory = true;
                    break;
                }
            }
            if (!hasRemainingTerritory)
            {
                World.log("Last territory taken");
                addMessage(def.getName() + " has lost its last holdings to " + att.getName());

                /*
                 * if (att is Society && def is Society)
                 * {
                 *  Society sAtt = (Society)att;
                 *  Society sDef = (Society)def;
                 *  List<Person> toMove = new List<Person>();
                 *  foreach (Person p in sDef.people)
                 *  {
                 *      if (p.title_land == null)
                 *      {
                 *          toMove.Add(p);
                 *      }
                 *  }
                 *  foreach (Person p in toMove)
                 *  {
                 *      movePerson(p, sAtt);
                 *      addMessage(p.getFullName() + " is now part of the court of " + att.getName(), MsgEvent.LEVEL_GRAY, false);
                 *  }
                 * }
                 */
            }
        }
        public override double computeUtility(Person voter, VoteOption option, List <ReasonMsg> msgs)
        {
            double u = option.getBaseUtility(voter);

            Person p             = option.person;
            double existingValue = 0;

            if (p.title_land != null)
            {
                existingValue = p.title_land.settlement.getPrestige();
            }

            double newValue = title.settlement.getPrestige();

            double benefitToPerson = newValue - existingValue;

            //We know how much they would be advantaged. We now need to know how much we like them to determine
            //if this is a good thing or not

            double localU = benefitToPerson * voter.getRelation(p).getLiking() * voter.map.param.utility_landedTitleMult;

            msgs.Add(new ReasonMsg("Benefit to " + p.getFullName(), localU));
            u += localU;

            if (title.heldBy == null)
            {
                localU = voter.map.param.utility_landedTitleAssignBaseline;
                msgs.Add(new ReasonMsg("Need to assign the title", localU));
                u += localU;
            }

            if (option.person != voter.society.getSovereign() && voter != option.person)
            {
                Person wouldBeSuperior = title.settlement.location.getSuperiorInSociety(voter.society);
                Person currentSuperior = option.person.getDirectSuperiorIfAny();
                if (currentSuperior == voter && wouldBeSuperior != voter)
                {
                    //Follower would be leaving
                    double desirabilityAsFollower = 0;
                    foreach (Trait t in option.person.traits)
                    {
                        desirabilityAsFollower += t.desirabilityAsFollower();
                    }
                    if (wouldBeSuperior == voter)
                    {
                        localU = -desirabilityAsFollower;
                        msgs.Add(new ReasonMsg("Desirability as follower", localU));
                        u += localU;
                    }
                }
                else if (currentSuperior != voter && wouldBeSuperior == voter)
                {
                    //Follower would be arriving
                    double desirabilityAsFollower = 0;
                    foreach (Trait t in option.person.traits)
                    {
                        desirabilityAsFollower += t.desirabilityAsFollower();
                    }
                    if (wouldBeSuperior == voter)
                    {
                        localU = desirabilityAsFollower;
                        msgs.Add(new ReasonMsg("Desirability as follower", localU));
                        u += localU;
                    }
                }
            }

            //We need to know if someone's going to lose out here
            //(Note this is irrelevant if they're the person who's being voted on)
            if (title.heldBy != null && title.heldBy != p)
            {
                double damageToOther = title.settlement.getPrestige();
                localU = -damageToOther *voter.getRelation(title.heldBy).getLiking() * voter.map.param.utility_landedTitleMult;

                msgs.Add(new ReasonMsg(title.heldBy.getFullName() + " would lose title", localU));
                u += localU;
            }


            return(u);
        }
        public override double computeUtility(Person p, VoteOption option, List <ReasonMsg> msgs)
        {
            double u = option.getBaseUtility(p);

            double advtangeToMe        = 0;
            double advantageToAllies   = 0;
            double advantageToEnemeies = 0;

            foreach (Person affected in society.people)
            {
                if (affected.title_land != null)
                {
                    double delta = 1;
                    if (affected.title_land.settlement.econTraits().Contains(option.econ_to))
                    {
                        delta *= society.map.param.econ_multFromBuff;
                    }
                    if (affected.title_land.settlement.econTraits().Contains(option.econ_from))
                    {
                        delta /= society.map.param.econ_multFromBuff;
                    }

                    delta = 1 - delta;
                    //Run off the base prestige, so all change is regarded the same, regardless of existing changes
                    if (affected == p)
                    {
                        advtangeToMe = delta * p.getRelation(affected).getLiking() * affected.title_land.settlement.basePrestige * society.map.param.utility_econEffect;
                    }
                    else
                    {
                        if (p.getRelation(affected).getLiking() > 0)
                        {
                            advantageToAllies += delta * p.getRelation(affected).getLiking() * affected.title_land.settlement.basePrestige * society.map.param.utility_econEffectOther;
                        }
                        else
                        {
                            advantageToEnemeies += delta * p.getRelation(affected).getLiking() * affected.title_land.settlement.basePrestige * society.map.param.utility_econEffectOther;
                        }
                    }
                }
            }

            //If we're actually affected by this, don't care more about the wellbeing of others than of yourself
            if (Math.Abs(advtangeToMe) > 1)
            {
                if (Math.Abs(advantageToAllies) > Math.Abs(advtangeToMe) / 3)
                {
                    if (advantageToAllies > 0)
                    {
                        advantageToAllies = Math.Abs(advtangeToMe) / 3;
                    }
                    if (advantageToAllies < 0)
                    {
                        advantageToAllies = -Math.Abs(advtangeToMe) / 3;
                    }
                }
                if (Math.Abs(advantageToEnemeies) > Math.Abs(advtangeToMe) / 3)
                {
                    if (advantageToEnemeies > 0)
                    {
                        advantageToEnemeies = Math.Abs(advtangeToMe) / 3;
                    }
                    if (advantageToEnemeies < 0)
                    {
                        advantageToEnemeies = -Math.Abs(advtangeToMe) / 3;
                    }
                }
            }

            msgs.Add(new ReasonMsg("Advantage to me", advtangeToMe));
            u += advtangeToMe;
            msgs.Add(new ReasonMsg("Advantage to allies", advantageToAllies));
            u += advantageToAllies;
            msgs.Add(new ReasonMsg("Advantage to enemies", advantageToEnemeies));
            u += advantageToEnemeies;

            //World.log("Econ advantages " + advtangeToMe + " " + advantageToAllies + " " + advantageToEnemeies);

            return(u);
        }
        public override double computeUtility(Person p, VoteOption option, List <ReasonMsg> msgs)
        {
            double u = option.getBaseUtility(p);

            double concernLevel = p.threat_agents.threat;                   //curr 0 to 200

            concernLevel += (100 * p.awareness) + (100 * p.map.worldPanic); //0 to 400
            concernLevel /= 4;
            concernLevel  = Math.Min(concernLevel, (p.map.worldPanic * 100) + 20);

            concernLevel *= (1 - p.shadow);
            if (p.state == Person.personState.enthralled || p.state == Person.personState.broken)
            {
                concernLevel = 0;
            }

            //Define the range at which this manner of response is appropriate
            double responseLevelMin = 0;
            double responseLevelMax = 0;

            if (option.index == DEFEND_PROVINCE)
            {
                responseLevelMin = 10;
                responseLevelMax = 40;

                int evidenceFound = 0;
                foreach (Evidence ev in foundEvidence)
                {
                    if (ev.locationFound.province.index == option.province)
                    {
                        evidenceFound += 1;
                    }
                }

                double localU = World.staticMap.param.utility_defendEvidenceProvince * evidenceFound * (1 - p.shadow);
                msgs.Add(new ReasonMsg("Amount of evidence found in " + society.map.provinces[option.province].name + " province", localU));
                u += localU;

                localU = 0;
                foreach (Person person in society.people)
                {
                    if (person.getLocation() != null && person.getLocation().province.index == option.province)
                    {
                        localU += p.getRelation(person.index).getLiking() * World.staticMap.param.utility_agentDefendProvinceLikingMult;
                    }
                }
                string add = "";
                msgs.Add(new ReasonMsg("Liking for nobles in province" + add, localU));
                u += localU;

                if (p.getLocation().province.index != option.province)
                {
                    localU = p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat;
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Does not help me personally", localU));
                        u += localU;
                    }
                }
                else
                {
                    localU = -1 * p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat;
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Helps me personally", localU));
                        u += localU;
                    }
                }
            }
            if (option.index == NATIONWIDE_SECURITY)
            {
                responseLevelMin = 10;
                responseLevelMax = 40;

                double localU = World.staticMap.param.utility_evidenceResonseBaseline * (concernLevel / 100);
                msgs.Add(new ReasonMsg("Base Desirability", localU));
                u += localU;

                localU = p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat / 2;
                if (localU != 0)
                {
                    msgs.Add(new ReasonMsg("Doesn't maximise my provinces' defences", localU));
                    u += localU;
                }
            }
            if (option.index == NO_RESPONSE)
            {
                responseLevelMin = 0;
                responseLevelMax = 10;

                if (p.getGreatestThreat() != null && p.getGreatestThreat() != p.threat_agents)
                {
                    double localU = World.staticMap.param.utility_greatestThreatDelta * 0.5;
                    msgs.Add(new ReasonMsg("Not our greatest threat", localU));
                    u += localU;
                }
                else
                {
                    double localU = -World.staticMap.param.utility_greatestThreatDelta;
                    msgs.Add(new ReasonMsg("Dark Agents are our greatest threat", localU));
                    u += localU;
                }
            }

            if (option.index == EXPELL_ALL_FOREIGN_AGENTS)
            {
                responseLevelMin = 75;
                responseLevelMax = 100;

                double n = 0;
                foreach (Unit unit in society.map.units)
                {
                    if (unit.society == society)
                    {
                        continue;
                    }
                    if (society.enemies.Contains(unit) == false)
                    {
                        n += 1;
                    }
                }
                if (n > 0)
                {
                    msgs.Add(new ReasonMsg("So many potential enemies!", concernLevel));
                    u += concernLevel;
                }
            }
            if (option.index == LOCKDOWN_PROVINCE)
            {
                responseLevelMin = 40;
                responseLevelMax = 100;

                int evidenceFound = 0;
                foreach (Evidence ev in foundEvidence)
                {
                    if (ev.locationFound.province.index == option.province)
                    {
                        evidenceFound += 1;
                    }
                }

                double localU = World.staticMap.param.utility_defendEvidenceProvince * evidenceFound * (1 - p.shadow);
                msgs.Add(new ReasonMsg("Amount of evidence found in " + society.map.provinces[option.province].name + " province", localU));
                u += localU;

                localU = 0;
                foreach (Person person in society.people)
                {
                    if (person.getLocation() != null && person.getLocation().province.index == option.province)
                    {
                        localU += p.getRelation(person.index).getLiking() * World.staticMap.param.utility_agentDefendProvinceLikingMult;
                    }
                }
                string add = "" + (int)(localU);
                msgs.Add(new ReasonMsg("Liking for nobles in province" + add, localU));
                u += localU;

                if (p.getLocation().province.index != option.province)
                {
                    localU = p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat;
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Does not help me personally", localU));
                        u += localU;
                    }
                }
                else
                {
                    localU = -1 * p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat;
                    if (localU != 0)
                    {
                        msgs.Add(new ReasonMsg("Helps me personally", localU));
                        u += localU;
                    }
                }
            }
            if (option.index == AGENT_TO_INVESTIGATOR)
            {
                responseLevelMin = 0;
                responseLevelMax = 100;
                Unit_Investigator inv = (Unit_Investigator)option.unit;

                double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.investigator);
                localU *= p.map.param.utility_swapAgentRolesMult;
                msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU));
                u += localU;
                bool hasSuspicions = false;
                foreach (RelObj rel in inv.person.relations.Values)
                {
                    if (inv.location.map.persons[rel.them] == null)
                    {
                        continue;
                    }
                    if (rel.suspicion > 0 && inv.location.map.persons[rel.them].unit != null && inv.location.map.units.Contains(inv.location.map.persons[rel.them].unit))
                    {
                        hasSuspicions = true;
                    }
                }
                if (hasSuspicions)
                {
                    localU = 12;
                    msgs.Add(new ReasonMsg("Has a suspect", localU));
                    u += localU;
                }
            }
            if (option.index == AGENT_TO_BASIC)
            {
                responseLevelMin = 0;
                responseLevelMax = 100;

                double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.basic);
                localU *= p.map.param.utility_swapAgentRolesMult;
                msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU));
                u += localU;
            }

            if (concernLevel > responseLevelMax)
            {
                double delta = responseLevelMax - concernLevel;
                delta *= society.map.param.utility_extremeismScaling;
                double localU = delta;
                msgs.Add(new ReasonMsg("Too weak response for current concern level (" + (int)(concernLevel) + "%)", localU));
                u += localU;
            }
            if (concernLevel < responseLevelMin)
            {
                double delta = concernLevel - responseLevelMin;
                delta *= society.map.param.utility_extremeismScaling;
                double localU = delta;
                msgs.Add(new ReasonMsg("Too extreme for current concern level (" + (int)(concernLevel) + "%)", localU));
                u += localU;
            }
            return(u);
        }
        public override void turnTick(Unit unit)
        {
            if (unit.location.evidence.Count > 0)
            {
                unit.task = new Task_Investigate();
                return;
            }
            List <Location> neighbours = unit.location.getNeighbours();

            int      c      = 0;
            Location chosen = null;

            foreach (Location loc in neighbours)
            {
                if (loc.evidence.Count > 0)
                {
                    chosen = loc;
                    break;
                }
                if (visitBuffer.Contains(loc) == false)
                {
                    c += 1;
                    if (Eleven.random.Next(c) == 0)
                    {
                        chosen = loc;
                    }
                }
            }
            if (chosen != null)
            {
                visitBuffer.AddLast(chosen);
            }
            else
            {
                int q = Eleven.random.Next(neighbours.Count);
                chosen = neighbours[q];
            }
            unit.location.map.adjacentMoveTo(unit, chosen);
            if (visitBuffer.Count > bufferSize)
            {
                visitBuffer.RemoveFirst();
            }

            //Start investigating the evidence you just moved to
            if (unit.location.evidence.Count > 0)
            {
                unit.task = new Task_Investigate();
                return;
            }

            //See if you want to warn this new person about anything
            if (unit.location.person() != null)
            {
                Person noble = unit.location.person();
                foreach (RelObj rel in unit.person.relations.Values)
                {
                    //Goes negative if they suspect more than we do, reaches 1.0 if we suspect 1.0 and they suspect 0.0
                    if ((rel.suspicion - noble.getRelation(rel.them).suspicion) > Eleven.random.NextDouble())
                    {
                        unit.task = new Task_ShareSuspicions();
                        return;
                    }
                }
            }

            wanderTimer += 1;
            if (wanderTimer > wanderDur)
            {
                if (unit.parentLocation != null)
                {
                    unit.task = new Task_GoToLocation(unit.parentLocation);
                }
                else
                {
                    //Done wandering, go home to ensure you don't wander too far for too long
                    unit.task = new Task_GoToSocialGroup(unit.society);
                }
            }
        }