Esempio n. 1
0
        public double getLikingDelta(Person p, VoteOption option, VoteIssue issue)
        {
            if (issue.options.Count < 2)
            {
                return(0);
            }


            //Special case voting
            if (issue is VoteIssue_AssignTitle)
            {
                bool votedForSelf = false;
                foreach (VoteOption opt in issue.options)
                {
                    if (opt.person == p && opt.votesFor.Contains(p))
                    {
                        //I voted for myself
                        votedForSelf = true;
                    }
                }
                if (votedForSelf)
                {
                    if (option.person != p)
                    {
                        //Didn't vote for me! Loathesome!
                        return(p.map.param.person_dislikeFromNotBeingVotedFor);
                    }
                }
            }

            double utility  = computeUtility(p, option, new List <ReasonMsg>());
            double deltaRel = utility;

            if (deltaRel > 0)
            {
                deltaRel *= p.map.param.person_votingRelChangePerUtilityPositive;
            }
            else
            {
                deltaRel *= p.map.param.person_votingRelChangePerUtilityNegative;
            }
            if (deltaRel > p.map.param.person_maxLikingGainFromVoteAccordance)
            {
                deltaRel = p.map.param.person_maxLikingGainFromVoteAccordance;
            }
            if (deltaRel < p.map.param.person_maxLikingLossFromVoteDiscord)
            {
                deltaRel = p.map.param.person_maxLikingLossFromVoteDiscord;
            }

            if (deltaRel < 0)
            {
                //You can't hate someone for voting the same way you did, that's just nuts.
                if (option.votesFor.Contains(p))
                {
                    deltaRel = 0;
                }
            }
            return(deltaRel);
        }
Esempio n. 2
0
        public void changeLikingForVotes(VoteOption option, VoteIssue issue)
        {
            if (issue.options.Count < 2)
            {
                return;
            }                                       //No reason to hate someone for voting for the only permitted option

            //Everyone affected/concerned about the vote now changes their opinion of all the voters for the winning option
            //depending on how much they care and how much they were affected
            foreach (Person p in society.people)
            {
                double deltaRel = getLikingDelta(p, option, issue);
                if (issue.proposer == p && (option.votesFor.Contains(p) == false))
                {
                    foreach (Person voter in option.votesFor)
                    {
                        p.getRelation(voter).addLiking(society.map.param.society_dislikeFromFailedProposal, "Did not vote on my proposed measure " + this.ToString(),
                                                       society.map.turn, RelObj.STACK_NONE);
                    }
                }
                foreach (Person voter in option.votesFor)
                {
                    p.getRelation(voter).addLiking(deltaRel, "Vote on issue " + this.ToString(), society.map.turn, RelObj.STACK_REPLACE);
                }
            }
        }
 public void setTo(Ab_Soc_ProposeVote ability,Society soc,VoteIssue issue)
 {
     this.soc = soc;
     this.issue = issue;
     this.ability = ability;
     title.text = issue.ToString();
     //body.text = issue.getLargeDesc();
 }
Esempio n. 4
0
        public PopupXBoxThreat getVoteReasonBox(VoteIssue vi, VoteOption vo, Person p)
        {
            GameObject      obj      = Instantiate(xBoxThreat) as GameObject;
            PopupXBoxThreat specific = obj.GetComponent <PopupXBoxThreat>();

            specific.setTo(vi, vo, p);
            specific.body = "The available vote options and the reasons behind each choice.";

            return(specific);
        }
Esempio n. 5
0
        public PopupXScroll getScrollSetVotes(Person p, VoteIssue vi)
        {
            PopupXScroll specific = getInnerXScrollSet();

            foreach (VoteOption vo in vi.options)
            {
                PopupXBoxThreat box = getVoteReasonBox(vi, vo, p);
                box.gameObject.transform.SetParent(specific.gameObject.transform);
                specific.scrollables.Add(box);
            }

            return(specific);
        }
Esempio n. 6
0
 public void logVote(VoteIssue issue)
 {
     if (World.logging)
     {
         string line = "  " + issue.ToString() + " for soc " + issue.society.getName();
         log.takeLine(line);
         foreach (VoteOption opt in issue.options)
         {
             line  = "     " + opt.fixedLenInfo();
             line += " U " + Eleven.toFixedLen(issue.computeUtility(this, opt, new List <ReasonMsg>()), 12);
             log.takeLine(line);
         }
     }
 }
        public void setTo(VoteIssue vi, VoteOption vo, Person p)
        {
            titleText.text = "For " + vo.info(vi);

            List <ReasonMsg> rs    = new List <ReasonMsg>();
            double           total = vi.computeUtility(p, vo, rs);

            string t = "";

            foreach (ReasonMsg r in rs)
            {
                t += "Influenced (" + r.value.ToString("N0") + ") by\n" + r.msg + "\n\n";
            }

            t            += "\nTotal Desirability: " + total.ToString("N0");
            mainText.text = t;
        }
Esempio n. 8
0
        public void SetInfo(VoteIssue i, VoteOption v, Person p)
        {
            foreground.sprite  = votesIcon;
            foreground.enabled = false;
            midground.enabled  = false;
            background.enabled = false;

            name.text = "";
            info.text = "";

            name2.text = "For " + v.info(i, true);
            info2.text = v.votingWeight.ToString("N0") + " influence across " + v.votesFor.Count + " votes";

            if (p != null)
            {
                // FIXME: use the list of reasons somewhere
                double utility = i.computeUtility(p, v, new List <ReasonMsg>());
                info2.text += "\n" + p.getFullName() + " values at " + utility.ToString("N0");
            }
        }
        public string info(VoteIssue issue, bool shrt = false)
        {
            string reply = "";

            if (econ_from != null)
            {
                if (shrt)
                {
                    return(econ_from.name + " -> " + econ_to.name);
                }
                else
                {
                    return("Move economic priority away from " + econ_from.name + " to benefit " + econ_to.name);
                }
            }
            if (issue is VoteIssue_MilitaryStance)
            {
                if (shrt)
                {
                    return new string[] { "Defensive", "Offensive", "Introspective" }
                }
        private VoteIssue checkForCrises()
        {
            if (map.simplified)
            {
                return(null);
            }

            if (society.crisisWitchHunt)
            {
                VoteIssue_WitchHunt issue = new VoteIssue_WitchHunt(society, this);

                VoteOption opt;

                foreach (Person p in society.people)
                {
                    opt        = new VoteOption();
                    opt.person = p;
                    issue.options.Add(opt);
                }

                return(issue);
            }

            VoteIssue replyIssue = null;
            int       c          = 0;

            if (society.lastEvidenceSubmission > society.lastEvidenceResponse && (society.isDarkEmpire == false))
            {
                List <Evidence> unprocessedEvidence = new List <Evidence>();
                foreach (Evidence ev in society.evidenceSubmitted)
                {
                    if (society.handledEvidence.Contains(ev))
                    {
                        continue;
                    }
                    unprocessedEvidence.Add(ev);
                }


                VoteIssue_Crisis_EvidenceDiscovered issue = new VoteIssue_Crisis_EvidenceDiscovered(society, this, unprocessedEvidence);

                //Every province (even those unaffected) can have its security increased (egotism influenced)
                HashSet <Province> provinces        = new HashSet <Province>();
                HashSet <Province> securedProvinces = new HashSet <Province>();
                bool hasRaisedSecurity = false;
                foreach (Location loc in map.locations)
                {
                    if (loc.soc == this.society)
                    {
                        provinces.Add(loc.province);

                        foreach (Property pr in loc.properties)
                        {
                            if (pr.proto is Pr_MajorSecurityBoost || pr.proto is Pr_MinorSecurityBoost || pr.proto is Pr_Lockdown)
                            {
                                hasRaisedSecurity = true;
                                securedProvinces.Add(loc.province);
                            }
                        }
                    }
                }
                VoteOption opt;

                opt       = new VoteOption();
                opt.index = VoteIssue_Crisis_EvidenceDiscovered.NO_RESPONSE;
                issue.options.Add(opt);

                bool existEnemies = false;
                foreach (Unit u in map.units)
                {
                    if (society.enemies.Contains(u) == false && u.society != society)
                    {
                        existEnemies = true;
                    }
                }
                if (existEnemies)
                {
                    opt       = new VoteOption();
                    opt.index = VoteIssue_Crisis_EvidenceDiscovered.EXPELL_ALL_FOREIGN_AGENTS;
                    issue.options.Add(opt);
                }

                if (!hasRaisedSecurity)
                {
                    opt       = new VoteOption();
                    opt.index = VoteIssue_Crisis_EvidenceDiscovered.NATIONWIDE_SECURITY;
                    issue.options.Add(opt);
                }

                foreach (Province prv in provinces)
                {
                    if (securedProvinces.Contains(prv) == false)
                    {
                        opt          = new VoteOption();
                        opt.province = prv.index;
                        opt.index    = VoteIssue_Crisis_EvidenceDiscovered.DEFEND_PROVINCE;
                        issue.options.Add(opt);

                        opt          = new VoteOption();
                        opt.province = prv.index;
                        opt.index    = VoteIssue_Crisis_EvidenceDiscovered.LOCKDOWN_PROVINCE;
                        issue.options.Add(opt);
                    }
                }
                foreach (Unit unit in map.units)
                {
                    if (unit is Unit_Investigator && unit.society == society)
                    {
                        Unit_Investigator inv = (Unit_Investigator)unit;
                        if (inv.canPromote() == false)
                        {
                            continue;
                        }
                        if (inv.state == Unit_Investigator.unitState.investigator || inv.state == Unit_Investigator.unitState.paladin)
                        {
                            //Already in offensive anti-agent state, no need to intefere
                        }
                        else if (inv.state == Unit_Investigator.unitState.basic) //Could upgrade to investigator if they've got a target
                        {
                            opt           = new VoteOption();
                            opt.unit      = unit;
                            opt.agentRole = Unit_Investigator.unitState.investigator;
                            opt.index     = VoteIssue_Crisis_EvidenceDiscovered.AGENT_TO_INVESTIGATOR;
                            issue.options.Add(opt);
                        }
                        else
                        {
                            opt           = new VoteOption();
                            opt.unit      = unit;
                            opt.agentRole = Unit_Investigator.unitState.basic;
                            opt.index     = VoteIssue_Crisis_EvidenceDiscovered.AGENT_TO_BASIC;
                            issue.options.Add(opt);
                        }
                    }
                }



                //bool hostilityPossible = false;
                //foreach (Evidence ev in unprocessedEvidence)
                //{
                //    World.log("Evidence. Discovered by " + ev.discoveredBy.getName() + " points to " + ev.pointsTo.getName() + " discSoc " + ev.discoveredBy.society.getName() + " us " + society.getName());
                //    if (ev.discoveredBy != null && ev.pointsTo != null && ev.discoveredBy.society == society)
                //    {
                //        if (ev.discoveredBy.hostileTo(ev.pointsTo)) { continue; }
                //        hostilityPossible = true;
                //    }
                //}

                //Decide if this is the crisis you're gonna deal with right now
                c += 1;
                if (Eleven.random.Next(c) == 0)
                {
                    replyIssue = issue;
                }
            }


            bool nobleCrisis = society.crisisNobles;

            if (
                this.awareness >= map.param.awarenessCanCallNobleCrisis &&
                map.turn - society.lastNobleCrisis >= map.param.awarenessMinNobleCrisisPeriod &&
                map.worldPanic >= map.param.panic_canCallNobleCrisis &&
                (this.society.isDarkEmpire == false) &&
                this.state != personState.broken &&
                this.state != personState.enthralled)
            {
                foreach (Person p in society.people)
                {
                    if (p == this)
                    {
                        continue;
                    }
                    if (this.getRelation(p.index).suspicion > 0.5)
                    {
                        nobleCrisis = true;
                    }
                }
            }
            if (nobleCrisis)
            {
                World.log("Noble crisis initiated");
                List <Evidence> unprocessedEvidence = new List <Evidence>();
                foreach (Evidence ev in society.evidenceSubmitted)
                {
                    if (society.handledEvidence.Contains(ev))
                    {
                        continue;
                    }
                    unprocessedEvidence.Add(ev);
                }


                VoteIssue_Crisis_EnshadowedNobles issue = new VoteIssue_Crisis_EnshadowedNobles(society, this, unprocessedEvidence);

                VoteOption opt;

                opt       = new VoteOption();
                opt.index = VoteIssue_Crisis_EnshadowedNobles.NO_RESPONSE;
                issue.options.Add(opt);

                opt       = new VoteOption();
                opt.index = VoteIssue_Crisis_EnshadowedNobles.WITCH_HUNT;
                issue.options.Add(opt);

                foreach (Unit unit in map.units)
                {
                    if (unit is Unit_Investigator && unit.society == society)
                    {
                        Unit_Investigator inv = (Unit_Investigator)unit;
                        if (inv.canPromote() == false)
                        {
                            continue;
                        }
                        if (inv.state == Unit_Investigator.unitState.investigator || inv.state == Unit_Investigator.unitState.paladin)
                        {
                            //Already in offensive anti-agent state, no need to intefere
                        }
                        else if (inv.state == Unit_Investigator.unitState.basic)//Could upgrade to investigator if they've got a target
                        {
                            opt           = new VoteOption();
                            opt.unit      = unit;
                            opt.agentRole = Unit_Investigator.unitState.investigator;
                            opt.index     = VoteIssue_Crisis_EnshadowedNobles.AGENT_TO_INQUISITOR;
                            issue.options.Add(opt);
                        }
                        else
                        {
                            opt           = new VoteOption();
                            opt.unit      = unit;
                            opt.agentRole = Unit_Investigator.unitState.basic;
                            opt.index     = VoteIssue_Crisis_EnshadowedNobles.AGENT_TO_BASIC;
                            issue.options.Add(opt);
                        }
                    }
                }

                c += 1;
                if (Eleven.random.Next(c) == 0)
                {
                    replyIssue = issue;
                }
            }
            if (society.crisisWarShort != null)
            {
                VoteIssue_Crisis_WarThreatens issue = new VoteIssue_Crisis_WarThreatens(society, this, society.crisisWarShort, society.crisisWarLong);
                VoteOption opt;

                opt       = new VoteOption();
                opt.index = VoteIssue_Crisis_WarThreatens.NO_RESPONSE;
                issue.options.Add(opt);

                foreach (Unit unit in map.units)
                {
                    if (unit is Unit_Investigator && unit.society == society)
                    {
                        Unit_Investigator inv = (Unit_Investigator)unit;
                        if (inv.canPromote() == false)
                        {
                            continue;
                        }
                        if (inv.state == Unit_Investigator.unitState.knight || inv.state == Unit_Investigator.unitState.paladin)
                        {
                            //Already doing something useful, ignore these
                        }
                        else if (inv.state == Unit_Investigator.unitState.basic)//Could upgrade to knight
                        {
                            opt           = new VoteOption();
                            opt.unit      = unit;
                            opt.agentRole = Unit_Investigator.unitState.knight;
                            opt.index     = VoteIssue_Crisis_WarThreatens.AGENT_TO_KNIGHT;
                            issue.options.Add(opt);
                        }
                        else
                        {
                            opt           = new VoteOption();
                            opt.unit      = unit;
                            opt.agentRole = Unit_Investigator.unitState.basic;
                            opt.index     = VoteIssue_Crisis_WarThreatens.AGENT_TO_BASIC;
                            issue.options.Add(opt);
                        }
                    }
                }


                //Decide if this is the crisis you're gonna deal with right now
                if (issue.options.Count > 1)
                {
                    c += 1;
                    if (Eleven.random.Next(c) == 0)
                    {
                        replyIssue = issue;
                    }
                }
            }

            if (society.crisisPlague != null)
            {
                VoteIssue_Crisis_Plague issue = new VoteIssue_Crisis_Plague(society, this, society.crisisPlague, society.crisisPlagueLong);
                VoteOption opt;

                opt       = new VoteOption();
                opt.index = VoteIssue_Crisis_Plague.NO_RESPONSE;
                issue.options.Add(opt);

                opt       = new VoteOption();
                opt.index = VoteIssue_Crisis_Plague.QUARANTINE;
                issue.options.Add(opt);

                opt       = new VoteOption();
                opt.index = VoteIssue_Crisis_Plague.TREATMENT;
                issue.options.Add(opt);

                foreach (Unit unit in map.units)
                {
                    if (unit is Unit_Investigator && unit.society == society)
                    {
                        Unit_Investigator inv = (Unit_Investigator)unit;
                        if (inv.canPromote() == false)
                        {
                            continue;
                        }
                        if (inv.state == Unit_Investigator.unitState.medic || inv.state == Unit_Investigator.unitState.paladin)
                        {
                            //Already doing something useful, ignore these
                        }
                        else if (inv.state == Unit_Investigator.unitState.basic)//Could upgrade to medic
                        {
                            opt           = new VoteOption();
                            opt.unit      = unit;
                            opt.agentRole = Unit_Investigator.unitState.medic;
                            opt.index     = VoteIssue_Crisis_Plague.AGENT_TO_MEDIC;
                            issue.options.Add(opt);
                        }
                        else
                        {
                            opt           = new VoteOption();
                            opt.unit      = unit;
                            opt.agentRole = Unit_Investigator.unitState.basic;
                            opt.index     = VoteIssue_Crisis_Plague.AGENT_TO_BASIC;
                            issue.options.Add(opt);
                        }
                    }
                }


                //Decide if this is the crisis you're gonna deal with right now
                if (issue.options.Count > 1)
                {
                    c += 1;
                    if (Eleven.random.Next(c) == 0)
                    {
                        replyIssue = issue;
                    }
                }
            }
            return(replyIssue);
        }
        public override void cast(Map map, Hex hex)
        {
            //base.cast(map, hex);

            Society soc = map.overmind.enthralled.society;

            Person    proposer = map.overmind.enthralled;
            VoteIssue issue    = null;

            List <VoteIssue> potentialIssues = new List <VoteIssue>();

            if (soc.posture == Society.militaryPosture.offensive && soc.offensiveTarget != null && (soc.isAtWar() == false))
            {
                issue = new VoteIssue_DeclareWar(soc, soc.offensiveTarget, proposer);
                potentialIssues.Add(issue);
                VoteOption option_0 = new VoteOption();
                option_0.index = 0;
                issue.options.Add(option_0);
                VoteOption option_1 = new VoteOption();
                option_1.index = 1;
                issue.options.Add(option_1);
            }


            if (proposer.title_land != null)
            {
                potentialIssues.AddRange(econIssues(map, proposer, soc));
            }

            //Remove unlanded nobles
            List <Person> removables = new List <Person>();

            foreach (Person p in soc.people)
            {
                if (p.title_land == null)
                {
                    removables.Add(p);
                }
            }
            if (removables.Count != 0)
            {
                issue = new VoteIssue_DismissFromCourt(soc, proposer);
                foreach (Person p in removables)
                {
                    VoteOption option = new VoteOption();
                    option.person = p;
                    issue.options.Add(option);
                }
                potentialIssues.Add(issue);
            }

            issue = new VoteIssue_MilitaryStance(soc, proposer);
            potentialIssues.Add(issue);
            for (int i = 0; i < 3; i++)
            {
                VoteOption opt = new VoteOption();
                opt.index = i;
                issue.options.Add(opt);
            }

            //Check to see if you want to alter offensive military targetting
            issue = new VoteIssue_SetOffensiveTarget(soc, proposer);
            foreach (SocialGroup neighbour in map.getExtendedNeighbours(soc))
            {
                VoteOption option = new VoteOption();
                option.group = neighbour;
                issue.options.Add(option);
            }
            potentialIssues.Add(issue);

            //Check to see if you want to alter defensive military targetting
            issue = new VoteIssue_SetDefensiveTarget(soc, proposer);
            foreach (ThreatItem item in proposer.threatEvaluations)
            {
                if (item.group == null)
                {
                    continue;
                }
                VoteOption option = new VoteOption();
                option.group = item.group;
                issue.options.Add(option);
            }

            //Check if you want to vassalise yourself
            if (soc.offensiveTarget != null && soc.posture == Society.militaryPosture.defensive && (soc.isAtWar() == false))
            {
                foreach (SocialGroup sg in soc.getNeighbours())
                {
                    if (sg is Society == false)
                    {
                        continue;
                    }
                    if (sg == soc)
                    {
                        continue;
                    }
                    Society other = (Society)sg;
                    if (other.defensiveTarget == soc.defensiveTarget)
                    {
                        issue = new VoteIssue_Vassalise(soc, other, proposer);
                        VoteOption option_0 = new VoteOption();
                        option_0.index = 0;
                        issue.options.Add(option_0);

                        VoteOption option_1 = new VoteOption();
                        option_1.index = 1;
                        issue.options.Add(option_1);

                        potentialIssues.Add(issue);
                    }
                }
            }


            //Check if you want to execute someone
            if (soc.posture == Society.militaryPosture.introverted)
            {
                foreach (Person p in soc.people)
                {
                    if (p == proposer)
                    {
                        continue;
                    }
                    issue = new VoteIssue_JudgeSuspect(soc, p, proposer);
                    VoteOption option_0 = new VoteOption();
                    option_0.index = 0;
                    issue.options.Add(option_0);

                    VoteOption option_1 = new VoteOption();
                    option_1.index = 1;
                    issue.options.Add(option_1);

                    potentialIssues.Add(issue);
                }
            }

            foreach (Title t in soc.titles)
            {
                if (t.turnLastAssigned - map.turn > map.param.society_minTimeBetweenTitleReassignments)
                {
                    issue = new VoteIssue_AssignTitle(soc, proposer, t);
                    potentialIssues.Add(issue);
                    //Everyone is eligible
                    foreach (Person p in soc.people)
                    {
                        VoteOption opt = new VoteOption();
                        opt.person = p;
                        issue.options.Add(opt);
                    }
                }
            }
            foreach (Location loc in map.locations)
            {
                if (loc.soc == soc && loc.settlement != null && loc.settlement.title != null)
                {
                    issue = new VoteIssue_AssignLandedTitle(soc, proposer, loc.settlement.title);
                    potentialIssues.Add(issue);
                    //Everyone is eligible
                    foreach (Person p in soc.people)
                    {
                        VoteOption opt = new VoteOption();
                        opt.person = p;
                        issue.options.Add(opt);
                    }
                }
            }

            map.world.ui.addBlocker(map.world.prefabStore.getScrollSet(this, soc, potentialIssues).gameObject);
            map.overmind.hasTakenAction = false;
        }
Esempio n. 12
0
        private PopupBoxVoteIssue getVoteIssueBox(Ab_Soc_ProposeVote ab, Society soc, VoteIssue issue)
        {
            GameObject        obj = Instantiate(popScrollVoteIssue) as GameObject;
            PopupBoxVoteIssue msg = obj.GetComponent <PopupBoxVoteIssue>();

            msg.setTo(ab, soc, issue);
            return(msg);
        }
        public VoteIssue proposeVotingIssue()
        {
            //Note we start at 1 utility. This means no guaranteed negative/near-zero utility options will be proposed
            double    bestU     = 1;
            VoteIssue bestIssue = null;

            bool existFreeTitles = false;


            foreach (Location loc in map.locations)
            {
                if (loc.soc == society && loc.settlement != null && loc.settlement.title != null && loc.settlement.title.heldBy == null)
                {
                    existFreeTitles = true;
                }
            }

            VoteIssue issue;


            if (true)
            { //ANWSAVE
              //Unlanded titles can be distributed
              //Assignment of sovreign takes priority over any other voting, in the minds of the lords and ladies
                foreach (Title t in society.titles)
                {
                    if (t.heldBy != null && (map.turn - t.turnLastAssigned < map.param.society_minTimeBetweenTitleReassignments))
                    {
                        continue;
                    }
                    issue = new VoteIssue_AssignTitle(society, this, t);

                    //Everyone is eligible
                    foreach (Person p in society.people)
                    {
                        VoteOption opt = new VoteOption();
                        opt.person = p;
                        issue.options.Add(opt);
                    }
                    foreach (VoteOption opt in issue.options)
                    {
                        //Random factor to prevent them all rushing a singular voting choice
                        double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                        if (localU > bestU || (t == society.sovreign && t.heldBy == null))//Note we force them to vote on a sovereign if there is none
                        {
                            bestU     = localU;
                            bestIssue = issue;
                        }
                    }
                }

                //Assignment of sovreign takes priority over any other voting, in the minds of the lords and ladies
                if (society.getSovreign() != null)
                {
                    foreach (Location loc in map.locations)
                    {
                        //If there are unhanded out titles, only consider those. Else, check all.
                        //Maybe they could be rearranged (handed out or simply swapped) in a way which could benefit you
                        //if (loc.soc == society && loc.settlement != null && loc.settlement.title != null && ((!existFreeTitles) || (loc.settlement.title.heldBy == null)))

                        //We're now stopping them suggesting this on places with existing nobles, as that lead to undue amounts of swapping
                        if (loc.soc == society && loc.settlement != null && loc.settlement.title != null && (loc.settlement.title.heldBy == null))
                        {
                            //if (map.turn - loc.turnLastAssigned  < Params.society_minTimeBetweenLocReassignments) { continue; }
                            issue = new VoteIssue_AssignLandedTitle(society, this, loc.settlement.title);
                            if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType())
                            {
                                break;
                            }                                                                                      //Already seen this proposal, most likely. Make another or skip
                                                                                                                   //Everyone is eligible
                            foreach (Person p in society.people)
                            {
                                if (p.title_land != null)
                                {
                                    continue;
                                }                                  //Again, to prevent constant shuffling
                                VoteOption opt = new VoteOption();
                                opt.person = p;
                                issue.options.Add(opt);
                            }

                            foreach (VoteOption opt in issue.options)
                            {
                                //Random factor to prevent them all rushing a singular voting choice
                                double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                                if (localU > bestU)
                                {
                                    bestU     = localU;
                                    bestIssue = issue;
                                }
                            }
                        }
                    }

                    if (!existFreeTitles)
                    {
                        //Check to see if you want to economically rebalance the economy
                        if (this.title_land != null)
                        {
                            HashSet <EconTrait> mine = new HashSet <EconTrait>();
                            HashSet <EconTrait> all  = new HashSet <EconTrait>();


                            foreach (EconTrait trait in title_land.settlement.econTraits())
                            {
                                mine.Add(trait);
                            }
                            foreach (Location loc in map.locations)
                            {
                                if (loc.soc == society && loc.settlement != null)
                                {
                                    foreach (EconTrait trait in loc.settlement.econTraits())
                                    {
                                        all.Add(trait);
                                    }
                                }
                            }

                            foreach (EconTrait econ_from in all)
                            {
                                if (mine.Contains(econ_from))
                                {
                                    continue;
                                }                                      //Don't take from yourself
                                foreach (EconTrait econ_to in mine)
                                {
                                    issue = new VoteIssue_EconomicRebalancing(society, this, econ_from, econ_to);
                                    //Allow them to spam econ votes
                                    //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip

                                    bool present = false;
                                    foreach (EconEffect effect in society.econEffects)
                                    {
                                        if (effect.from == econ_from && effect.to == econ_to)
                                        {
                                            present = true;
                                        }
                                        if (effect.to == econ_from && effect.from == econ_to)
                                        {
                                            present = true;
                                        }
                                    }
                                    if (present)
                                    {
                                        continue;
                                    }

                                    //We have our two options (one way or the other)
                                    VoteOption opt1 = new VoteOption();
                                    opt1.econ_from = econ_from;
                                    opt1.econ_to   = econ_to;
                                    issue.options.Add(opt1);
                                    VoteOption opt2 = new VoteOption();
                                    opt2.econ_from = econ_to;
                                    opt2.econ_to   = econ_from;
                                    issue.options.Add(opt2);

                                    foreach (VoteOption opt in issue.options)
                                    {
                                        //Random factor to prevent them all rushing a singular voting choice
                                        double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                                        if (localU > bestU)
                                        {
                                            bestU     = localU;
                                            bestIssue = issue;
                                        }
                                    }
                                }
                            }
                        }

                        //Check to see if you want to alter offensive military targetting
                        issue = new VoteIssue_SetOffensiveTarget(society, this);
                        foreach (SocialGroup neighbour in map.getExtendedNeighbours(society))
                        {
                            VoteOption option = new VoteOption();
                            option.group = neighbour;
                            issue.options.Add(option);
                        }
                        foreach (VoteOption opt in issue.options)
                        {
                            //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip

                            //Random factor to prevent them all rushing a singular voting choice
                            double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                            if (localU > bestU)
                            {
                                bestU     = localU;
                                bestIssue = issue;
                            }
                        }


                        //Check to see if you want to alter defensive military targetting
                        issue = new VoteIssue_SetDefensiveTarget(society, this);
                        foreach (ThreatItem item in threatEvaluations)
                        {
                            if (item.group == null)
                            {
                                continue;
                            }
                            VoteOption option = new VoteOption();
                            option.group = item.group;
                            issue.options.Add(option);
                        }
                        foreach (VoteOption opt in issue.options)
                        {
                            //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip

                            //Random factor to prevent them all rushing a singular voting choice
                            double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                            if (localU > bestU)
                            {
                                bestU     = localU;
                                bestIssue = issue;
                            }
                        }


                        //Change military posture, to either improve defence, fix internal problems, or attack an enemy
                        issue = new VoteIssue_MilitaryStance(society, this);
                        for (int i = 0; i < 3; i++)
                        {
                            VoteOption opt = new VoteOption();
                            opt.index = i;
                            issue.options.Add(opt);
                        }
                        foreach (VoteOption opt in issue.options)
                        {
                            //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip

                            //Random factor to prevent them all rushing a singular voting choice
                            double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                            if (localU > bestU)
                            {
                                bestU     = localU;
                                bestIssue = issue;
                            }
                        }


                        //Check to see if you want to declare war
                        //You need to be in offensive posture to be allowed to do so
                        if (society.offensiveTarget != null && society.posture == Society.militaryPosture.offensive && society.getRel(society.offensiveTarget).state != DipRel.dipState.war)
                        {
                            issue = new VoteIssue_DeclareWar(society, society.offensiveTarget, this);
                            VoteOption option_0 = new VoteOption();
                            option_0.index = 0;
                            issue.options.Add(option_0);

                            VoteOption option_1 = new VoteOption();
                            option_1.index = 1;
                            issue.options.Add(option_1);

                            //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip
                            //Random factor to prevent them all rushing a singular voting choice
                            double localU = issue.computeUtility(this, option_1, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                            if (localU > bestU)
                            {
                                bestU     = localU;
                                bestIssue = issue;
                            }
                        }

                        //Check to see if you want to defensively vassalise yourself
                        //You need to be in defensive posture to be allowed to do so
                        if (society.offensiveTarget != null && society.posture == Society.militaryPosture.defensive && (society.isAtWar() == false))
                        {
                            foreach (SocialGroup sg in society.getNeighbours())
                            {
                                if (sg is Society == false)
                                {
                                    continue;
                                }
                                if (sg == this.society)
                                {
                                    continue;
                                }
                                Society other = (Society)sg;
                                if (other.defensiveTarget == this.society.defensiveTarget)
                                {
                                    issue = new VoteIssue_Vassalise(society, other, this);
                                    VoteOption option_0 = new VoteOption();
                                    option_0.index = 0;
                                    issue.options.Add(option_0);

                                    VoteOption option_1 = new VoteOption();
                                    option_1.index = 1;
                                    issue.options.Add(option_1);

                                    //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip
                                    //Random factor to prevent them all rushing a singular voting choice
                                    double localU = issue.computeUtility(this, option_1, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                                    if (localU > bestU)
                                    {
                                        bestU     = localU;
                                        bestIssue = issue;
                                    }
                                }
                            }
                        }

                        //Check if you want to execute someone
                        if (society.posture == Society.militaryPosture.introverted)
                        {
                            foreach (Person p in society.people)
                            {
                                if (p == this)
                                {
                                    continue;
                                }
                                issue = new VoteIssue_JudgeSuspect(society, p, this);
                                VoteOption option_0 = new VoteOption();
                                option_0.index = 0;
                                issue.options.Add(option_0);

                                VoteOption option_1 = new VoteOption();
                                option_1.index = 1;
                                issue.options.Add(option_1);

                                //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip
                                //Random factor to prevent them all rushing a singular voting choice
                                double localU = issue.computeUtility(this, option_1, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                                if (localU > bestU)
                                {
                                    bestU     = localU;
                                    bestIssue = issue;
                                }
                            }
                        }
                    }//ANWSave
                }
            }

            lastProposedIssue = bestIssue;
            return(bestIssue);
        }
        public void processVoting()
        {
            if (voteSession == null)
            {
                if (voteCooldown > 0)
                {
                    voteCooldown -= 1; return;
                }

                Person proposer = null;
                foreach (Person p in people)
                {
                    if (p.state == Person.personState.enthralled)
                    {
                        continue;
                    }
                    if (proposer == null)
                    {
                        proposer = p;
                    }
                    else
                    {
                        int myDelta    = map.turn - p.lastVoteProposalTurn;
                        int theirDelta = map.turn - proposer.lastVoteProposalTurn;
                        if (myDelta > theirDelta)
                        {
                            proposer = p;
                        }
                    }
                }
                if (proposer != null)
                {
                    proposer.lastVoteProposalTurn = map.turn;
                    VoteIssue issue = proposer.proposeVotingIssue();
                    if (issue == null)
                    {
                        return;
                    }

                    bool   positive = true;
                    int    priority = (this.hasEnthralled()) ? 1 : 3;
                    string msg      = this.getName() + " now voting on " + issue.ToString();

                    World.staticMap.addMessage(msg, priority, positive);

                    //Otherwise, on with voting for this new thing
                    voteSession               = new VoteSession();
                    voteSession.issue         = issue;
                    voteSession.timeRemaining = map.param.society_votingDuration;
                    if (World.logging && logbox != null)
                    {
                        logbox.takeLine("Starting voting on " + voteSession.issue.ToString());
                    }

                    if (this.hasEnthralled())
                    {
                        voteSession.assignVoters();
                        VoteOption optionChoice = null;
                        foreach (VoteOption opt in voteSession.issue.options)
                        {
                            if (opt.votesFor.Contains(proposer))
                            {
                                optionChoice = opt;
                                break;
                            }
                        }
                        string str = proposer.getFullName() + " has proposed a measure to be voted on by the nobles of "
                                     + this.getName() + ".\nThey are voting " +
                                     optionChoice.info(issue);

                        map.world.prefabStore.popImgMsg(str, "Voting issue: " + issue.getLargeDesc());
                    }
                }
            }
            else
            {
                if (voteSession.issue.stillValid(map) == false)
                {
                    voteSession = null;
                    World.log("Vote session no longer valid");
                    return;
                }
                if (voteSession.timeRemaining > 0)
                {
                    voteSession.timeRemaining -= 1; return;
                }

                voteSession.assignVoters();

                double     topVote = 0;
                VoteOption winner  = null;
                foreach (VoteOption option in voteSession.issue.options)
                {
                    if (option.votingWeight > topVote || winner == null)
                    {
                        winner  = option;
                        topVote = option.votingWeight;
                    }

                    voteSession.issue.changeLikingForVotes(option, voteSession.issue);
                }

                if (World.logging && logbox != null)
                {
                    logbox.takeLine("End voting on " + voteSession.issue.ToString());
                }
                if (World.logging && logbox != null)
                {
                    logbox.takeLine("    Winning option: " + winner.info());
                }

                if (this.hasEnthralled())
                {
                    string str = "Chosen outcome: " + winner.info(voteSession.issue);
                    str += "\nVotes for: ";
                    foreach (Person p in winner.votesFor)
                    {
                        str += p.getFullName() + ", ";
                    }
                    str = str.Substring(0, str.Length - 2);

                    map.world.prefabStore.popImgMsg(str, "Voting concluded. Issue: " + voteSession.issue.getLargeDesc());
                }

                voteSession.issue.implement(winner);
                if (voteSession.issue is VoteIssue_AssignLandedTitle == false)
                {
                    billsSinceLastSettlementAssignment += 1;
                }
                else
                {
                    billsSinceLastSettlementAssignment = 0;
                }
                voteSession = null;
            }
        }
Esempio n. 15
0
        public VoteIssue proposeVotingIssue()
        {
            double    bestU           = 25;
            VoteIssue bestIssue       = null;
            bool      forcedBest      = false;
            bool      existFreeTitles = false;

            if (World.logging)
            {
                log.takeLine("Proposing vote on turn " + map.turn);
            }


            foreach (Location loc in map.locations)
            {
                if (loc.soc == society && loc.settlement != null && loc.settlement.title != null && loc.settlement.title.heldBy == null)
                {
                    existFreeTitles = true;
                }
            }


            VoteIssue issue;

            //Unlanded titles can be distributed
            //Assignment of sovreign takes priority over any other voting, in the minds of the lords and ladies
            foreach (Title t in society.titles)
            {
                //Can assign an unassigned title, or hold routine elections
                bool canHold = t.heldBy == null || (map.turn - t.turnLastAssigned >= map.param.society_minTimeBetweenTitleReassignments);
                //You can hold emergency elections in the event of upcoming civil war
                if (society.data_societalStability < 0 && t == society.sovreign)
                {
                    canHold = true;
                }

                if (!canHold)
                {
                    continue;
                }

                issue = new VoteIssue_AssignTitle(society, this, t);

                if (t is Title_Sovreign)
                {
                    if (society.titles.Count == 1)
                    {
                        //Everyone is eligible
                        foreach (Person p in society.people)
                        {
                            VoteOption opt = new VoteOption();
                            opt.person = p;
                            issue.options.Add(opt);
                        }
                    }
                    else
                    {
                        //Only provincial rulers are elligible
                        foreach (Person p in society.people)
                        {
                            if (p.titles.Count > 0)
                            {
                                VoteOption opt = new VoteOption();
                                opt.person = p;
                                issue.options.Add(opt);
                            }
                        }
                    }
                }
                else if (t is Title_ProvinceRuler)
                {
                    Title_ProvinceRuler t2 = (Title_ProvinceRuler)t;
                    //Nobles holding land in region are eligible
                    foreach (Person p in society.people)
                    {
                        if (p == society.getSovreign())
                        {
                            continue;
                        }
                        if (p.title_land != null && p.title_land.settlement.location.province == t2.province)
                        {
                            VoteOption opt = new VoteOption();
                            opt.person = p;
                            issue.options.Add(opt);
                        }
                    }
                }
                if (issue.options.Count == 0)
                {
                    continue;
                }
                foreach (VoteOption opt in issue.options)
                {
                    //Random factor to prevent them all rushing a singular voting choice
                    double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                    if (localU > bestU || (t == society.sovreign && t.heldBy == null))//Note we force them to vote on a sovereign if there is none
                    {
                        bestU      = localU;
                        bestIssue  = issue;
                        forcedBest = true;
                    }
                }
                logVote(issue);
            }

            if (society.getSovreign() != null)
            {
                int      oldestAssignment = 100000000;
                Location bestAssignable   = null;

                /*
                 * if (society.billsSinceLastSettlementAssignment > map.param.society_billsBetweenLandAssignments)
                 * {
                 *  foreach (Location loc in map.locations)
                 *  {
                 *      if (loc.soc == this.society && loc.settlement != null && loc.settlement.title != null)
                 *      {
                 *          if (loc.settlement.lastAssigned < oldestAssignment)
                 *          {
                 *              oldestAssignment = loc.settlement.lastAssigned;
                 *              bestAssignable = loc;
                 *          }
                 *      }
                 *  }
                 * }
                 */

                foreach (Location loc in map.locations)
                {
                    //If there are unhanded out titles, only consider those. Else, check all.
                    //Maybe they could be rearranged (handed out or simply swapped) in a way which could benefit you
                    //if (loc.soc == society && loc.settlement != null && loc.settlement.title != null && ((!existFreeTitles) || (loc.settlement.title.heldBy == null)))

                    //We're now stopping them suggesting this on places with existing nobles, as that lead to undue amounts of swapping
                    //  *now ammended to allow a single swap every N bills, AND it must be the last swapped one
                    if (loc.soc == society && loc.settlement != null && loc.settlement.title != null && (loc.settlement.title.heldBy == null || loc == bestAssignable))
                    {
                        //if (map.turn - loc.turnLastAssigned  < Params.society_minTimeBetweenLocReassignments) { continue; }
                        issue = new VoteIssue_AssignLandedTitle(society, this, loc.settlement.title);
                        // if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip
                        //Everyone is eligible
                        foreach (Person p in society.people)
                        {
                            if (p.title_land != loc.settlement.title && p.title_land != null)
                            {
                                continue;
                            }                                                                              //Again, to prevent constant shuffling
                            VoteOption opt = new VoteOption();
                            opt.person = p;
                            issue.options.Add(opt);
                        }

                        foreach (VoteOption opt in issue.options)
                        {
                            //Random factor to prevent them all rushing a singular voting choice
                            double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                            if (localU > bestU)
                            {
                                bestU      = localU;
                                bestIssue  = issue;
                                forcedBest = true;
                            }
                        }
                        logVote(issue);
                    }
                }

                if (society.needsToDecreasePopulation)
                {
                    issue = new VoteIssue_DismissFromCourt(society, this);
                    foreach (Person p in society.people)
                    {
                        if (p.title_land == null)
                        {
                            VoteOption opt = new VoteOption();
                            opt.person = p;
                            issue.options.Add(opt);
                        }
                    }
                    foreach (VoteOption opt in issue.options)
                    {
                        //Random factor to prevent them all rushing a singular voting choice
                        double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                        if (localU > bestU)
                        {
                            bestU      = localU;
                            bestIssue  = issue;
                            forcedBest = true;
                        }
                    }
                }

                if (!forcedBest)
                {
                    //Check to see if you want to economically rebalance the economy
                    if (this.title_land != null)
                    {
                        HashSet <EconTrait> mine = new HashSet <EconTrait>();
                        HashSet <EconTrait> all  = new HashSet <EconTrait>();


                        foreach (EconTrait trait in title_land.settlement.econTraits())
                        {
                            mine.Add(trait);
                        }
                        foreach (Location loc in map.locations)
                        {
                            if (loc.soc == society && loc.settlement != null)
                            {
                                foreach (EconTrait trait in loc.settlement.econTraits())
                                {
                                    all.Add(trait);
                                }
                            }
                        }

                        foreach (EconTrait econ_from in all)
                        {
                            if (mine.Contains(econ_from))
                            {
                                continue;
                            }                                          //Don't take from yourself
                            foreach (EconTrait econ_to in mine)
                            {
                                issue = new VoteIssue_EconomicRebalancing(society, this, econ_from, econ_to);
                                //Allow them to spam econ votes
                                //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip

                                bool present = false;
                                foreach (EconEffect effect in society.econEffects)
                                {
                                    if (effect.from == econ_from && effect.to == econ_to)
                                    {
                                        present = true;
                                    }
                                    if (effect.to == econ_from && effect.from == econ_to)
                                    {
                                        present = true;
                                    }
                                }
                                if (present)
                                {
                                    continue;
                                }

                                //We have our two options (one way or the other)
                                VoteOption opt1 = new VoteOption();
                                opt1.econ_from = econ_from;
                                opt1.econ_to   = econ_to;
                                issue.options.Add(opt1);
                                VoteOption opt2 = new VoteOption();
                                opt2.econ_from = econ_to;
                                opt2.econ_to   = econ_from;
                                issue.options.Add(opt2);

                                foreach (VoteOption opt in issue.options)
                                {
                                    //Random factor to prevent them all rushing a singular voting choice
                                    double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble() * map.param.society_votingEconHiddenBiasMult;
                                    if (localU > bestU)
                                    {
                                        bestU     = localU;
                                        bestIssue = issue;
                                    }
                                }

                                logVote(issue);
                            }
                        }
                    }

                    //Check to see if you want to alter offensive military targetting
                    if (map.turn - society.lastOffensiveTargetSetting > 8)
                    {
                        issue = new VoteIssue_SetOffensiveTarget(society, this);
                        foreach (SocialGroup neighbour in map.getExtendedNeighbours(society))
                        {
                            VoteOption option = new VoteOption();
                            option.group = neighbour;
                            issue.options.Add(option);
                        }
                        double     localBest = 0;
                        VoteOption voteOpt   = null;
                        foreach (VoteOption opt in issue.options)
                        {
                            //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip

                            //Random factor to prevent them all rushing a singular voting choice
                            double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                            if (localU > localBest)
                            {
                                localBest = localU;
                                voteOpt   = opt;
                            }
                        }
                        if (voteOpt != null && voteOpt.group != society.offensiveTarget && localBest > bestU)
                        {
                            bestU     = localBest;
                            bestIssue = issue;
                        }
                        logVote(issue);
                    }

                    {
                        //Check to see if you want to alter defensive military targetting
                        issue = new VoteIssue_SetDefensiveTarget(society, this);
                        foreach (ThreatItem item in threatEvaluations)
                        {
                            if (item.group == null)
                            {
                                continue;
                            }
                            VoteOption option = new VoteOption();
                            option.group = item.group;
                            issue.options.Add(option);
                        }
                        double     localBest = 0;
                        VoteOption voteOpt   = null;
                        foreach (VoteOption opt in issue.options)
                        {
                            //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip

                            //Random factor to prevent them all rushing a singular voting choice
                            double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                            if (localU > localBest)
                            {
                                localBest = localU;
                                voteOpt   = opt;
                            }
                        }
                        if (voteOpt != null && voteOpt.group != society.defensiveTarget && localBest > bestU)
                        {
                            bestU     = localBest;
                            bestIssue = issue;
                        }
                        logVote(issue);
                    }

                    {
                        //Change military posture, to either improve defence, fix internal problems, or attack an enemy
                        issue = new VoteIssue_MilitaryStance(society, this);
                        for (int i = 0; i < 3; i++)
                        {
                            VoteOption opt = new VoteOption();
                            opt.index = i;
                            issue.options.Add(opt);
                        }
                        double     localBest = 0;
                        VoteOption voteOpt   = null;
                        foreach (VoteOption opt in issue.options)
                        {
                            //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip

                            //Random factor to prevent them all rushing a singular voting choice
                            double localU = issue.computeUtility(this, opt, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                            if (localU > localBest)
                            {
                                localBest = localU;
                                voteOpt   = opt;
                            }
                        }
                        int ourIndex = 0;
                        if (society.posture == Society.militaryPosture.defensive)
                        {
                            ourIndex = 0;
                        }
                        if (society.posture == Society.militaryPosture.offensive)
                        {
                            ourIndex = 1;
                        }
                        if (society.posture == Society.militaryPosture.introverted)
                        {
                            ourIndex = 2;
                        }
                        if (voteOpt != null && voteOpt.index != ourIndex && localBest > bestU)
                        {
                            bestU     = localBest;
                            bestIssue = issue;
                        }
                        logVote(issue);
                    }

                    //Check to see if you want to declare war
                    //You need to be in offensive posture to be allowed to do so
                    if (society.offensiveTarget != null && society.posture == Society.militaryPosture.offensive && society.getRel(society.offensiveTarget).state != DipRel.dipState.war)
                    {
                        issue = new VoteIssue_DeclareWar(society, society.offensiveTarget, this);
                        VoteOption option_0 = new VoteOption();
                        option_0.index = 0;
                        issue.options.Add(option_0);

                        VoteOption option_1 = new VoteOption();
                        option_1.index = 1;
                        issue.options.Add(option_1);

                        //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip
                        //Random factor to prevent them all rushing a singular voting choice
                        double uWar   = issue.computeUtility(this, option_1, new List <ReasonMsg>());
                        double uPeace = issue.computeUtility(this, option_0, new List <ReasonMsg>());
                        double localU = (uWar - uPeace) * Eleven.random.NextDouble();
                        if (localU > bestU)
                        {
                            bestU     = localU;
                            bestIssue = issue;
                        }
                        logVote(issue);
                    }

                    //Check to see if you want to defensively vassalise yourself
                    //You need to be in defensive posture to be allowed to do so
                    if (society.offensiveTarget != null && society.posture == Society.militaryPosture.defensive && (society.isAtWar() == false))
                    {
                        foreach (SocialGroup sg in society.getNeighbours())
                        {
                            if (sg is Society == false)
                            {
                                continue;
                            }
                            if (sg == this.society)
                            {
                                continue;
                            }
                            Society other = (Society)sg;
                            if (other.defensiveTarget == this.society.defensiveTarget)
                            {
                                issue = new VoteIssue_Vassalise(society, other, this);
                                VoteOption option_0 = new VoteOption();
                                option_0.index = 0;
                                issue.options.Add(option_0);

                                VoteOption option_1 = new VoteOption();
                                option_1.index = 1;
                                issue.options.Add(option_1);

                                //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip
                                //Random factor to prevent them all rushing a singular voting choice
                                double localU = issue.computeUtility(this, option_1, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                                if (localU > bestU)
                                {
                                    bestU     = localU;
                                    bestIssue = issue;
                                }
                                logVote(issue);
                            }
                        }
                    }
                    if (map.param.useAwareness == 1 && map.worldPanic >= map.param.panic_canAlly && this.awareness >= map.param.awareness_canProposeLightAlliance)
                    {
                        issue = new VoteIssue_LightAlliance(society, null, this);
                        VoteOption option_0 = new VoteOption();
                        option_0.group = null;
                        issue.options.Add(option_0);

                        foreach (SocialGroup sg in society.getNeighbours())
                        {
                            if (sg is Society == false)
                            {
                                continue;
                            }
                            if (sg == this.society)
                            {
                                continue;
                            }
                            Society other = (Society)sg;
                            if (other.isDarkEmpire)
                            {
                                continue;
                            }

                            VoteOption option_1 = new VoteOption();
                            option_1.group = sg;
                            issue.options.Add(option_1);

                            //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip
                            //Random factor to prevent them all rushing a singular voting choice
                            double localU = issue.computeUtility(this, option_1, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                            if (localU > bestU)
                            {
                                bestU     = localU;
                                bestIssue = issue;
                            }
                            logVote(issue);
                        }
                    }

                    //Check if you want to execute someone
                    if (society.posture == Society.militaryPosture.introverted)
                    {
                        foreach (Person p in society.people)
                        {
                            if (p == this)
                            {
                                continue;
                            }
                            issue = new VoteIssue_JudgeSuspect(society, p, this);
                            VoteOption option_0 = new VoteOption();
                            option_0.index = 0;
                            issue.options.Add(option_0);

                            VoteOption option_1 = new VoteOption();
                            option_1.index = 1;
                            issue.options.Add(option_1);

                            //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip
                            //Random factor to prevent them all rushing a singular voting choice
                            double localU = issue.computeUtility(this, option_1, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                            if (localU > bestU)
                            {
                                bestU     = localU;
                                bestIssue = issue;
                            }
                            logVote(issue);
                        }
                    }
                    foreach (Unit u in map.units)
                    {
                        if (u.person == null)
                        {
                            continue;
                        }
                        if (getRelation(u.person).getLiking() >= 0)
                        {
                            continue;
                        }
                        if (society.enemies.Contains(unit))
                        {
                            continue;
                        }
                        issue = new VoteIssue_CondemnAgent(society, u, this);
                        VoteOption option_0 = new VoteOption();
                        option_0.index = 0;
                        issue.options.Add(option_0);

                        VoteOption option_1 = new VoteOption();
                        option_1.index = 1;
                        issue.options.Add(option_1);

                        //if (lastProposedIssue != null && lastProposedIssue.GetType() == issue.GetType()) { break; }//Already seen this proposal, most likely. Make another or skip
                        //Random factor to prevent them all rushing a singular voting choice
                        double localU = issue.computeUtility(this, option_1, new List <ReasonMsg>()) * Eleven.random.NextDouble();
                        if (localU > bestU)
                        {
                            bestU     = localU;
                            bestIssue = issue;
                        }
                        logVote(issue);
                    }
                }
            }

            if (bestIssue != null)
            {
                if (World.logging)
                {
                    log.takeLine("CHOSE: " + bestIssue.ToString());
                }
            }
            //lastProposedIssue = bestIssue;
            return(bestIssue);
        }
        public void processVoting()
        {
            if (voteSession == null)
            {
                if (voteCooldown > 0)
                {
                    voteCooldown -= 1; return;
                }

                Person proposer = null;
                foreach (Person p in people)
                {
                    if (p.state == Person.personState.enthralled)
                    {
                        continue;
                    }
                    if (proposer == null)
                    {
                        proposer = p;
                    }
                    else
                    {
                        int myDelta    = map.turn - p.lastVoteProposalTurn;
                        int theirDelta = map.turn - proposer.lastVoteProposalTurn;
                        if (myDelta > theirDelta)
                        {
                            proposer = p;
                        }
                    }
                }
                if (proposer != null)
                {
                    proposer.lastVoteProposalTurn = map.turn;
                    VoteIssue issue = proposer.proposeVotingIssue();
                    if (issue == null)
                    {
                        return;
                    }

                    bool   positive = true;
                    int    priority = (this.hasEnthralled()) ? 1 : 3;
                    string msg      = this.getName() + " now voting on " + issue.ToString();

                    World.staticMap.addMessage(msg, priority, positive);

                    //Otherwise, on with voting for this new thing
                    voteSession               = new VoteSession();
                    voteSession.issue         = issue;
                    voteSession.timeRemaining = map.param.society_votingDuration;
                }
            }
            else
            {
                if (voteSession.issue.stillValid(map) == false)
                {
                    voteSession = null;
                    World.log("Vote session no longer valid");
                    return;
                }
                if (voteSession.timeRemaining > 0)
                {
                    voteSession.timeRemaining -= 1; return;
                }

                voteSession.assignVoters();

                double     topVote = 0;
                VoteOption winner  = null;
                foreach (VoteOption option in voteSession.issue.options)
                {
                    if (option.votingWeight > topVote || winner == null)
                    {
                        winner  = option;
                        topVote = option.votingWeight;
                    }

                    voteSession.issue.changeLikingForVotes(option);
                }

                voteSession.issue.implement(winner);
                voteSession = null;
            }
        }