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); }
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(); }
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); }
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); }
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; }
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; }
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; } }
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; } }