public override void castInner(Map map, Person person)
        {
            ThreatItem item = person.getGreatestThreat();

            if (item == null)
            {
                return;
            }

            double prevThreat = item.threat;
            double addDread   = item.threat * map.param.ability_instillDreadMult;
            bool   hitCap     = false;

            if (item.threat + addDread >= 200)
            {
                hitCap      = true;
                item.threat = 200 - item.threat;//Now at 200
            }
            else
            {
                item.temporaryDread += addDread;
                item.threat         += addDread;
            }

            string msgs = "You draw upon " + person.getFullName() + "'s fears, adding to their dread of " + item.getTitle() + ". Their threat estimate has gone from "
                          + (int)(prevThreat) + " to " + (int)(item.threat) + ".";

            if (hitCap)
            {
                msgs += "\n(It is now at its maximum value)";
            }
            map.world.prefabStore.popImgMsg(
                msgs,
                map.world.wordStore.lookup("ABILITY_INSTILL_DREAD"));
        }
예제 #2
0
 public override bool castable(Map map, Person person)
 {
     if (person.sanity >= map.param.ability_breakMindMaxSanity)
     {
         return(false);
     }
     if (person.getGreatestThreat() == null)
     {
         return(false);
     }
     if (person.getGreatestThreat().threat < map.param.person_fearLevel_terrified)
     {
         return(false);
     }
     return(true);
 }
예제 #3
0
        public override double computeUtility(Person p, VoteOption option, List <ReasonMsg> msgs)
        {
            double u = option.getBaseUtility(p);

            double concernLevel = p.threat_enshadowedNobles.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 == NO_RESPONSE)
            {
                responseLevelMin = 0;
                responseLevelMax = 10;

                if (p.getGreatestThreat() != null && p.getGreatestThreat() != p.threat_enshadowedNobles)
                {
                    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("Enshadowed nobles are our greatest threat", localU));
                    u += localU;
                }
            }

            if (option.index == WITCH_HUNT)
            {
                responseLevelMin = 80;
                responseLevelMax = 100;

                double localU = -World.staticMap.param.utility_killSuspectRelucatance;
                msgs.Add(new ReasonMsg("Base Reluctance to Execute Noble", localU));
                u += localU;


                bool isWarlike   = false;
                bool isHonorable = false;
                bool isPacifist  = false;
                foreach (Trait t in p.traits)
                {
                    if (t is Trait_Political_Warlike)
                    {
                        isWarlike = true; break;
                    }
                    if (t is Trait_Political_Honorable)
                    {
                        isHonorable = true; break;
                    }
                    if (t is Trait_Political_Pacifist)
                    {
                        isPacifist = true; break;
                    }
                }
                if (isHonorable)
                {
                    localU = p.map.param.utility_honorableHatesWitchHunt;
                    msgs.Add(new ReasonMsg("Honorable Politician opposes executions without trials", localU));
                    u += localU;
                }
                if (isWarlike)
                {
                    localU = p.map.param.utility_warlikeLikesWitchHunt;
                    msgs.Add(new ReasonMsg("Warlike Politician supports violence", localU));
                    u += localU;
                }
                if (isPacifist)
                {
                    localU = -p.map.param.utility_warlikeLikesWitchHunt;
                    msgs.Add(new ReasonMsg("Pacifist Politician supports violence", localU));
                    u += localU;
                }

                double maxSuspicion = 0;
                foreach (Person p2 in p.society.people)
                {
                    maxSuspicion = Math.Max(maxSuspicion, p.getRelation(p2.index).suspicion);
                }
                localU = maxSuspicion;
                if (localU != 0)
                {
                    msgs.Add(new ReasonMsg("Suspicion towards other nobles", localU));
                    u += localU;
                }
            }

            if (option.index == AGENT_TO_INQUISITOR)
            {
                responseLevelMin = 0;
                responseLevelMax = 100;
                Unit_Investigator inv = (Unit_Investigator)option.unit;

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

                bool isCorrupt = false;
                foreach (Trait t in p.traits)
                {
                    if (t is Trait_Political_Corrupt)
                    {
                        isCorrupt = true; break;
                    }
                }
                if (isCorrupt)
                {
                    localU = p.map.param.utility_corruptHatesInquisitor;
                    msgs.Add(new ReasonMsg("Inquisitor may expose my political corruption", 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 bool castable(Map map, Person person)
 {
     return(person.getGreatestThreat() != null && person.getGreatestThreat().threat >= person.map.param.person_fearLevel_terrified);
 }
        public override void castInner(Map map, Person person)
        {
            ThreatItem item = person.getGreatestThreat();

            if (item == null)
            {
                return;
            }

            Society soc = person.society;
            Person  sov = soc.getSovreign();

            if (sov == null)
            {
                return;
            }
            int    nAffected = 0;
            double totalV    = 0;
            double sovFear   = 0;

            foreach (ThreatItem ti in sov.threatEvaluations)
            {
                if (item.isSame(ti))
                {
                    sovFear = ti.threat;
                    break;
                }
            }
            foreach (Person p in soc.people)
            {
                double myFear = 0;
                foreach (ThreatItem ti in p.threatEvaluations)
                {
                    if (item.isSame(ti))
                    {
                        myFear = ti.threat;
                        break;
                    }
                }

                double deltaFear = myFear - sovFear;
                if (deltaFear <= 0)
                {
                    continue;
                }

                double deltaLiking = deltaFear * map.param.ability_denounceLeaderLikingMult;
                deltaLiking = Math.Min(deltaLiking, map.param.ability_denounceLeaderMax);

                p.getRelation(sov).addLiking(-deltaLiking, "Doesn't take threat of " + item.getTitle() + " seriously", map.turn);

                nAffected += 1;
                totalV    += deltaFear;
            }

            double avrg = 0;

            if (nAffected > 0)
            {
                avrg = totalV / nAffected;
            }
            map.world.prefabStore.popImgMsg(
                "You rally the people against " + sov.getFullName() + ", denouncing them as unable to defend the people against the threat of " + item.getTitle() + ".\n" +
                nAffected + " nobles agree, with an average liking change of of " + (int)(-avrg),
                map.world.wordStore.lookup("ABILITY_DENOUNCE_LEADER"));
        }
예제 #6
0
        public override double computeUtility(Person voter, VoteOption option, List <ReasonMsg> msgs)
        {
            double     u = option.getBaseUtility(voter);
            ThreatItem greatestThreat = voter.getGreatestThreat();


            double ourStr = 1 + (voter.society.currentMilitary + (voter.society.maxMilitary / 2));
            double offStr = 1;
            double defStr = 1;

            if (voter.society.offensiveTarget != null)
            {
                offStr = voter.society.offensiveTarget.currentMilitary + (voter.society.offensiveTarget.maxMilitary / 2);
            }
            if (voter.society.defensiveTarget != null)
            {
                defStr = voter.society.defensiveTarget.currentMilitary + (voter.society.defensiveTarget.maxMilitary / 2);
            }

            double defUtility        = 0;
            double defGreatestThreat = 0;

            if (voter.society.defensiveTarget != null)
            {
                //Negative if we are stronger than the one we fear
                defUtility += (defStr - ourStr) / (ourStr + defStr) * voter.map.param.utility_militaryTargetRelStrengthDefensive;

                if (defUtility < -50)
                {
                    defUtility = -50;
                }

                if (greatestThreat != null)
                {
                    if (greatestThreat.group != null && greatestThreat.group.currentMilitary > voter.society.currentMilitary)
                    {
                        defGreatestThreat = World.staticMap.param.utility_greatestThreatDelta;
                        defUtility       += defGreatestThreat;
                        if (option.index == 0)
                        {
                            msgs.Add(new ReasonMsg("Our greatest threat (" + greatestThreat.group.getName() + ") is stronger than us, we must defend", defGreatestThreat));
                        }
                    }
                }
            }
            double offUtility            = 0;
            double offUtilityStr         = 0;
            double offUtilityPersonality = 0;
            double offUtilityTerritory   = 0;
            double offUtilityInstab      = 0;
            double offGreatestThreat     = 0;

            if (voter.society.offensiveTarget != null)
            {
                //Negative if the offensive target is stronger
                offUtilityStr += (ourStr - offStr) / (ourStr + offStr) * voter.map.param.utility_militaryTargetRelStrengthOffensive;
                if (voter.society.offensiveTarget is Society)
                {
                    offUtilityStr = Math.Min(offUtilityStr, voter.map.param.utility_militaryTargetRelStrengthOffensive);//Capped to prevent insanity snowballing
                }
                offUtilityPersonality += voter.getMilitarism() * voter.map.param.utility_militarism;

                //We want to expand into territory we already partially own
                bool hasOurTerritory = false;
                foreach (Location loc in voter.society.offensiveTarget.lastTurnLocs)
                {
                    if (loc.province == voter.getLocation().province)
                    {
                        hasOurTerritory = true;
                        break;
                    }
                }
                if (hasOurTerritory)
                {
                    offUtilityTerritory += society.map.param.utility_militaryTargetCompleteProvince * society.data_societalStability;
                }

                if (offUtilityStr > 0 && society.offensiveTarget is Society)
                {
                    //Counters expansion desire. Value always negative or zero
                    //u = off*stability
                    //u = off + (off*(stability-1))  (Because we are removing 1 from stability mult)
                    //If stab == 0 it's off - off
                    //If stab < 0 it's less than off
                    offUtilityInstab = offUtilityInstab * (society.data_societalStability - 1);
                }

                if (greatestThreat != null)
                {
                    if (greatestThreat.group != null && greatestThreat.group.currentMilitary < voter.society.currentMilitary)
                    {
                        offGreatestThreat += World.staticMap.param.utility_greatestThreatDelta;
                        if (option.index == 1)
                        {
                            msgs.Add(new ReasonMsg("Our greatest threat (" + greatestThreat.group.getName() + ") is weaker than us, we must attack", offGreatestThreat));
                        }
                    }
                }
                offUtility += offGreatestThreat;
                offUtility += offUtilityStr;
                offUtility += offUtilityPersonality;
                offUtility += offUtilityTerritory;
                offUtility += offUtilityInstab;
            }
            double introUtility          = 0;
            double introUtilityStability = 0;

            if (society.data_societalStability < 0.66)
            {
                introUtilityStability = -(society.data_societalStability - 1);  //0 if stability is 1, increasing to 1 if civil war is imminent, to 2 if every single person is a traitor
            }
            double introGreatestThreat = 0;

            if (greatestThreat != null)
            {
                if (greatestThreat.form == ThreatItem.formTypes.AGENTS || greatestThreat.form == ThreatItem.formTypes.ENSHADOWED_NOBLES)
                {
                    introGreatestThreat = World.staticMap.param.utility_greatestThreatDelta;
                    introUtility       += introGreatestThreat;
                    if (option.index == 2)
                    {
                        msgs.Add(new ReasonMsg("Our greatest threat (" + greatestThreat.getTitle() + ") requires internal security", introGreatestThreat));
                    }
                }
            }
            introUtilityStability *= voter.map.param.utility_introversionFromInstability;
            double introFromInnerThreat = voter.threat_enshadowedNobles.threat * voter.map.param.utility_introversionFromSuspicion;

            introUtility += introUtilityStability;
            introUtility += introFromInnerThreat;
            introUtility += 10;

            //Option 0 is DEFENSIVE
            //Option 1 is OFFENSIVE
            //Option 2 is INTROSPECTIVE
            if (voter.society.posture == Society.militaryPosture.defensive && option.index != 0)
            {
                u -= defUtility;
                msgs.Add(new ReasonMsg("Switching away from defensive", -defUtility));
            }
            if (voter.society.posture == Society.militaryPosture.offensive && option.index != 1)
            {
                u -= offUtility;
                msgs.Add(new ReasonMsg("Switching away from offensive", -offUtility));
            }
            if (voter.society.posture == Society.militaryPosture.introverted && option.index != 2)
            {
                u -= introUtility;
                msgs.Add(new ReasonMsg("Switching away from introversion", -introUtility));
            }

            if (option.index == 0)
            {
                if (society.posture != Society.militaryPosture.defensive)
                {
                    u += defUtility;
                    msgs.Add(new ReasonMsg("Our relative strength against defensive target", defUtility));
                    if (voter.society.isDarkEmpire)
                    {
                        int value = (int)(-100 * voter.shadow);
                        u += value;
                        msgs.Add(new ReasonMsg("We must expand the Dark Empire", value));
                    }
                }
                else
                {
                    u += defUtility;
                    msgs.Add(new ReasonMsg("Our relative strength against defensive target", defUtility));
                    if (voter.society.isDarkEmpire)
                    {
                        int value = (int)(-100 * voter.shadow);
                        u += value;
                        msgs.Add(new ReasonMsg("We must expand the Dark Empire", value));
                    }
                    msgs.Add(new ReasonMsg("No need to change: It is our current stance", -u));
                    u = 0;
                }
            }
            if (option.index == 1)
            {
                if (society.posture != Society.militaryPosture.offensive)
                {
                    u += offUtility;
                    msgs.Add(new ReasonMsg("Our relative strength against offensive target", offUtilityStr));
                    msgs.Add(new ReasonMsg("Risk of instability from expansion", offUtilityInstab));
                    msgs.Add(new ReasonMsg("Militarism personality", offUtilityPersonality));
                    msgs.Add(new ReasonMsg("Desire for territory", offUtilityTerritory));
                    if (voter.society.isDarkEmpire)
                    {
                        int value = (int)(100 * voter.shadow);
                        u += value;
                        msgs.Add(new ReasonMsg("We must expand the Dark Empire", value));
                    }
                }
                else
                {
                    u += offUtility;
                    msgs.Add(new ReasonMsg("Our relative strength against offensive target", offUtilityStr));
                    msgs.Add(new ReasonMsg("Risk of instability from expansion", offUtilityInstab));
                    msgs.Add(new ReasonMsg("Militarism personality", offUtilityPersonality));
                    msgs.Add(new ReasonMsg("Desire for territory", offUtilityTerritory));
                    if (voter.society.isDarkEmpire)
                    {
                        int value = (int)(100 * voter.shadow);
                        u += value;
                        msgs.Add(new ReasonMsg("We must expand the Dark Empire", value));
                    }
                    msgs.Add(new ReasonMsg("No need to change: It is our current stance", -u));
                    u = 0;
                }
            }
            if (option.index == 2)
            {
                msgs.Add(new ReasonMsg("Default position", 10));
                if (society.posture != Society.militaryPosture.introverted)
                {
                    u += introUtility;
                    msgs.Add(new ReasonMsg("Instability internally", introUtilityStability));
                    msgs.Add(new ReasonMsg("Suspicion of nobles' darkness", introFromInnerThreat));
                    if (voter.society.isDarkEmpire)
                    {
                        int value = (int)(-100 * voter.shadow);
                        u += value;
                        msgs.Add(new ReasonMsg("We must expand the Dark Empire", value));
                    }
                }
                else
                {
                    u += introUtility;
                    msgs.Add(new ReasonMsg("Instability internally", introUtilityStability));
                    msgs.Add(new ReasonMsg("Suspicion of nobles' darkness", introFromInnerThreat));
                    if (voter.society.isDarkEmpire)
                    {
                        int value = (int)(-100 * voter.shadow);
                        u += value;
                        msgs.Add(new ReasonMsg("We must expand the Dark Empire", value));
                    }
                    msgs.Add(new ReasonMsg("No need to change: It is our current stance", -u));
                    u = 0;
                }
            }


            return(u);
        }
        public void showPersonInfo(Person p)
        {
            uiPerson.setTo(p);

            //I'm sure there was a reason why this info assignment done in two separate classes
            //And I'm sure the reason is 'I was too lazy to do a full migration and left it till later'
            //As I am doing now

            prestigeText.text = "Prestige: " + (int)(p.prestige) + "\nPrestige Moving towards: " + (int)(p.getTargetPrestige(null));
            personShadowAndEvidenceVals.text = (int)(p.shadow * 100) + "%\n" + (int)(p.evidence * 100) + "%";


            personAwarenss.text = (int)(p.awareness * 100) + "%";
            if (p.action == null)
            {
                actionText.text = "Not Taking Action";
                actionDesc.text = "Characters can take actions if they become aware and world panic is sufficiently high.";
                actionDesc.text = "\n\nThis character is not taking an action.";
            }
            else
            {
                actionText.text = p.action.getShort();
                actionDesc.text = "Characters can take actions if they become aware and world panic is sufficiently high.";
                actionDesc.text = "\n\n" + p.action.getLong();
            }

            string bodyText = "";
            //if (p.getDirectSuperiorIfAny() != null)
            //{
            //    bodyText += "\nDirect Superior: " + p.getDirectSuperiorIfAny().getFullName();
            //}
            //else
            //{
            //    bodyText += "\nDirect Superior: None";
            //}
            //bodyText += "\n";
            //bodyText += "\n";
            ThreatItem threat = p.getGreatestThreat();

            if (threat != null)
            {
                bodyText += "\nBelieved Greatest Threat: " + threat.getTitle();
                bodyText += "\nFear of threat: " + (int)threat.threat;
                if (threat.threat > World.staticMap.param.person_fearLevel_terrified)
                {
                    bodyText += "\n[Terrified]";
                }
                else if (threat.threat > World.staticMap.param.person_fearLevel_afraid)
                {
                    bodyText += "\n[Afraid]";
                }
                else
                {
                    bodyText += "\n[Moderate Concern]";
                }
            }
            else
            {
                bodyText += "\nNot feeling threatened.";
            }

            personBody.text = bodyText;


            insanityText.text  = "Sanity state: " + p.madness.name;
            insanityText.text += "\nSanity: " + ((int)p.sanity) + " Maximum: " + p.maxSanity;

            insanityDescText.text = p.madness.desc + "\n\n" +
                                    "Characters have a sanity score. If this value drops to zero, they become insane, and begin to act in an erratic and dangerous manner. "
                                    + "Characters will dislike insane characters to a moderate degree, and insane characters will occasionally lash out, further reducing their relationships."
                                    + "\nYou can cause reduce sanity using certain abilities.";

            personAwarenssDesc.text = "A person's awareness is how much they have realised about the threat their world faces.\nIt allows them to take actions against the darkenss directly." +
                                      "\nSome nobles gain awareness each time you expend power, they can also gain awareness by gaining suspicion as they seen evidence, and can be warned by their fellow nobles, especially neighbours."
                                      + "\nAwareness gain can be increased by being in a place of learning, or increased or decreased by traits."
                                      + "\n\nThis noble has an awareness rate of " + (int)(100 * p.getAwarenessMult()) + "%";

            prestigeDescText.text = "";
            List <string> prestigeReasons = new List <string>();

            p.getTargetPrestige(prestigeReasons);
            foreach (string s in prestigeReasons)
            {
                prestigeDescText.text += "*" + s + "\n";
            }

            for (int i = 0; i < traits.Length; i++)
            {
                traits[i].SetActive(false);
                traitDescBoxes[i].SetActive(false);
            }
            for (int i = 0; i < p.traits.Count; i++)
            {
                traits[i].SetActive(true);
                traitNames[i].text = p.traits[i].name;
                traitDescs[i].text = p.traits[i].desc;
            }
        }
        public void showPersonInfo(Person p)
        {
            profileBack.enabled   = true;
            profileMid.enabled    = true;
            profileFore.enabled   = true;
            profileBorder.enabled = true;
            //Done to unfuck the distortion of images which periodically occurs
            profileBack.sprite   = null;
            profileMid.sprite    = null;
            profileFore.sprite   = null;
            profileBorder.sprite = null;
            profileBack.sprite   = p.getImageBack();
            profileMid.sprite    = p.getImageMid();
            profileFore.sprite   = p.getImageFore();
            if (p.society.getSovreign() == p)
            {
                profileBorder.sprite = p.map.world.textureStore.slotKing;
            }
            else if (p.titles.Count > 0)
            {
                profileBorder.sprite = p.map.world.textureStore.slotDuke;
            }
            else
            {
                profileBorder.sprite = p.map.world.textureStore.slotCount;
            }

            personTitle.text = p.getFullName();
            TitleLanded title = p.title_land;

            if (title == null)
            {
                locText.text = "No Landed Title";
            }
            else
            {
                locText.text = "of " + title.settlement.name;
            }
            string bodyText = "";

            if (p.getDirectSuperiorIfAny() != null)
            {
                bodyText += "\nDirect Superior: " + p.getDirectSuperiorIfAny().getFullName();
            }
            else
            {
                bodyText += "\nDirect Superior: None";
            }
            prestigeText.text = "Prestige: " + (int)(p.prestige) + "\nPrestige Moving towards: " + (int)(p.getTargetPrestige(null));
            bodyText         += "\nShadow: " + (int)(p.shadow * 100) + "%";
            bodyText         += "\nEvidence: " + (int)(p.evidence * 100) + "%";
            bodyText         += "\nMilitarism: " + (int)(p.politics_militarism * 100) + "%";
            bodyText         += " (" + p.getMilitarismInfo() + ")";

            bodyText += "\n";

            personAwarenss.text = (int)(p.awareness * 100) + "%";
            if (p.action == null)
            {
                actionText.text = "Not Taking Action";
                actionDesc.text = "Characters can take actions if they become aware and world panic is sufficiently high.";
                actionDesc.text = "\n\nThis character is not taking an action.";
            }
            else
            {
                actionText.text = p.action.getShort();
                actionDesc.text = "Characters can take actions if they become aware and world panic is sufficiently high.";
                actionDesc.text = "\n\n" + p.action.getLong();
            }

            Society     soc  = getSociety(GraphicalMap.selectedHex);
            VoteSession vote = (soc != null) ? soc.voteSession : null;

            if (vote != null)
            {
                bodyText += "\nVoting on: " + vote.issue.ToString();

                VoteOption vo = p.getVote(vote);
                bodyText += "\n\tto " + vo.info(vote.issue);
            }
            else
            {
                bodyText += "\nNot voting.";
            }

            bodyText += "\n";

            ThreatItem threat = p.getGreatestThreat();

            if (threat != null)
            {
                bodyText += "\nBelieved Greatest Threat: " + threat.getTitle();
                bodyText += "\nFear of threat: " + (int)threat.threat;
                if (threat.threat > World.staticMap.param.person_fearLevel_terrified)
                {
                    bodyText += "\n[Terrified]";
                }
                else if (threat.threat > World.staticMap.param.person_fearLevel_afraid)
                {
                    bodyText += "\n[Afraid]";
                }
                else
                {
                    bodyText += "\n[Moderate Concern]";
                }
            }
            else
            {
                bodyText += "\nNot feeling threatened.";
            }

            personBody.text = bodyText;


            insanityText.text  = "Sanity state: " + p.madness.name;
            insanityText.text += "\nSanity: " + ((int)p.sanity) + " Maximum: " + p.maxSanity;

            insanityDescText.text = p.madness.desc + "\n\n" +
                                    "Characters have a sanity score. If this value drops to zero, they become insane, and begin to act in an erratic and dangerous manner. "
                                    + "Characters will dislike insane characters to a moderate degree, and insane characters will occasionally lash out, further reducing their relationships."
                                    + "\nYou can cause reduce sanity using certain abilities.";

            personAwarenssDesc.text = "A person's awareness is how much they have realised about the threat their world faces.\nIt allows them to take actions against the darkenss directly." +
                                      "\nSome nobles gain awareness each time you expend power, they can also gain awareness by gaining suspicion as they seen evidence, and can be warned by their fellow nobles, especially neighbours."
                                      + "\nAwareness gain can be increased by being in a place of learning, or increased or decreased by traits."
                                      + "\n\nThis noble has an awareness rate of " + (int)(100 * p.getAwarenessMult()) + "%";

            prestigeDescText.text = "";
            List <string> prestigeReasons = new List <string>();

            p.getTargetPrestige(prestigeReasons);
            foreach (string s in prestigeReasons)
            {
                prestigeDescText.text += "*" + s + "\n";
            }

            for (int i = 0; i < traits.Length; i++)
            {
                traits[i].SetActive(false);
                traitDescBoxes[i].SetActive(false);
            }
            for (int i = 0; i < p.traits.Count; i++)
            {
                traits[i].SetActive(true);
                traitNames[i].text = p.traits[i].name;
                traitDescs[i].text = p.traits[i].desc;
            }
        }
        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 void showPersonInfo(Person p)
        {
            profileBack.enabled = true;
            profileMid.enabled  = true;
            profileFore.enabled = true;
            //Done to unfuck the distortion of images which periodically occurs
            profileBack.sprite = null;
            profileMid.sprite  = null;
            profileFore.sprite = null;
            profileBack.sprite = p.getImageBack();
            profileMid.sprite  = p.getImageMid();
            profileFore.sprite = p.getImageFore();
            personTitle.text   = p.getFullName();
            TitleLanded title = p.title_land;

            if (title == null)
            {
                locText.text = "No Landed Title";
            }
            else
            {
                locText.text = "of " + title.settlement.name;
            }
            string bodyText = "Prestige: " + (int)(p.prestige);

            bodyText += "\nPrestige Moving towards: " + (int)(p.targetPrestige);
            bodyText += "\nShadow: " + (int)(p.shadow * 100) + "%";
            bodyText += "\nEvidence: " + (int)(p.evidence * 100) + "%";
            bodyText += "\nMilitarism: " + (int)(p.politics_militarism * 100) + "%";
            bodyText += " (" + p.getMilitarismInfo() + ")";

            bodyText += "\n";

            Society     soc  = getSociety(GraphicalMap.selectedHex);
            VoteSession vote = (soc != null) ? soc.voteSession : null;

            if (vote != null)
            {
                bodyText += "\nVoting on: " + vote.issue.ToString();

                VoteOption vo = p.getVote(vote);
                bodyText += "\n\tto " + vo.info(vote.issue);
            }
            else
            {
                bodyText += "\nNot voting.";
            }

            bodyText += "\n";

            ThreatItem threat = p.getGreatestThreat();

            if (threat != null)
            {
                bodyText += "\nBelieved Greatest Threat: " + threat.getTitle();
            }
            else
            {
                bodyText += "\nNot feeling threatened.";
            }

            personBody.text = bodyText;
        }