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 void clicked(Map map) { this.ability.turnLastCast = map.turn; soc.voteCooldown = 0; soc.voteSession = new VoteSession(); soc.voteSession.issue = issue; soc.voteSession.assignVoters(); soc.voteSession.timeRemaining = map.param.society_votingDuration; map.world.prefabStore.popImgMsg("Voting session called. You may now cast your vote on the issue of: " + issue.ToString(), map.world.wordStore.lookup("SOC_VOTE_SESSION_CALLED")); map.overmind.hasTakenAction = true; }
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 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; } }