public override double computeUtility(Person voter, VoteOption option, List <ReasonMsg> msgs) { double u = option.getBaseUtility(voter); Person p = option.person; double newValue = title.getPrestige(); double benefitToPerson = newValue; //We know how much they would be advantaged. We now need to know how much we like them to determine //if this is a good thing or not double benefitU = benefitToPerson * voter.getRelation(p).getLiking() * voter.map.param.utility_unlandedTitleMult; //Check if you should avoid voting for yourself bool wouldBeOutvoted = false; if (p == voter) { foreach (Person p2 in voter.society.people) { if (p2.prestige > p.prestige * 2) { wouldBeOutvoted = true; } } } if (wouldBeOutvoted) { benefitU *= voter.map.param.utility_wouldBeOutvotedMult; msgs.Add(new ReasonMsg("Benefit to (reduced by fears of being outvoted) " + p.getFullName(), benefitU)); u += benefitU; } else { msgs.Add(new ReasonMsg("Benefit to " + p.getFullName(), benefitU)); u += benefitU; } //We need to know if someone's going to lose out here //(Note this is irrelevant if they're the person who's being voted on) if (title.heldBy != null && title.heldBy != p) { double damageToOther = title.getPrestige(); double localU = -damageToOther *voter.getRelation(title.heldBy).getLiking() * voter.map.param.utility_unlandedTitleMult; if (wouldBeOutvoted) { localU *= voter.map.param.utility_wouldBeOutvotedMult; } msgs.Add(new ReasonMsg("Harm to " + title.heldBy.getFullName(), localU)); u += localU; } //Existing prestige of person being voted on double prestigeU = p.prestige * society.map.param.utility_prestigeMultForTitle; msgs.Add(new ReasonMsg("Prestige of " + p.getFullName(), prestigeU)); u += prestigeU; return(u); }
public override void cast(Map map, Hex hex) { base.cast(map, hex); ThreatItem item = hex.location.person().getGreatestThreat(); if (item == null) { return; } string changes = ""; foreach (Location loc in hex.location.getNeighbours()) { if (loc.person() != null) { Person other = loc.person(); foreach (ThreatItem t2 in other.threatEvaluations) { if (t2.isSame(item)) { double delta = item.threat - t2.threat; if (delta <= 0) { continue; } double liking = other.getRelation(hex.location.person()).getLiking(); if (liking <= 0) { continue; } liking /= 100; double prev = t2.threat; delta *= liking; if (t2.threat + delta > 200) { delta = 200 - t2.threat; } t2.threat += delta; t2.temporaryDread += delta; changes += other.getFullName() + " " + (int)(prev) + " -> " + (int)(t2.threat) + "; "; } } } } if (changes.Length > 0) { changes = changes.Substring(0, changes.Length - 2);//Strip the last separator } string msgs = "You spread " + hex.location.person().getFullName() + "'s fears of " + item.getTitle() + " to any neighbour who will listen. "; if (changes.Length > 0) { msgs += "\n" + changes; } else { msgs += "\nBut there are none."; } map.world.prefabStore.popImgMsg( msgs, map.world.wordStore.lookup("ABILITY_SPREAD_FEAR")); }
public Color getColor(Hex hex) { if (mask == maskType.NATION) { if (hex.owner != null) { float r = hex.owner.color[0]; float g = hex.owner.color[1]; float b = hex.owner.color[2]; Color color = new Color(r, g, b, 0.8f); return(color); } else { return(new Color(0.5f, 0.5f, 0.5f, 0.5f)); } } else if (mask == maskType.PROVINCE) { return(new Color(hex.province.cr, hex.province.cg, hex.province.cb, 0.5f)); } else if (mask == maskType.INFORMATION) { if (hex.location != null && GraphicalMap.selectedHex != null && GraphicalMap.selectedHex.location != null && GraphicalMap.selectedHex.location.soc != null) { SocialGroup group = GraphicalMap.selectedHex.location.soc; float mult = (float)map.getInformationAvailability(hex.location, group); mult = Mathf.Max(0, mult); mult = Mathf.Min(1, mult); float r = mult; float g = mult; float b = mult; //Color color = new Color(r, g, b, 0.8f); Color color = new Color(0, 0, 0, (1 - mult)); return(color); } else if (hex.location != null) { return(new Color(0f, 0f, 0f, 1f)); } else { return(new Color(0f, 0f, 0f, 0.75f)); } } else if (mask == maskType.THREAT) { if (hex.location != null && GraphicalMap.selectedHex != null && GraphicalMap.selectedHex.location != null && GraphicalMap.selectedHex.location.settlement != null && GraphicalMap.selectedHex.location.settlement.title != null && GraphicalMap.selectedHex.location.settlement.title.heldBy != null) { SocialGroup group = GraphicalMap.selectedHex.location.soc; Person p = GraphicalMap.selectedHex.settlement.title.heldBy; double highestThreat = 0; foreach (ThreatItem item in p.threatEvaluations) { if (item.group != null && item.threat > highestThreat) { highestThreat = item.threat; } } if (highestThreat != 0) { if (hex.location.soc == null) { return(Color.black); } double threat = 0; foreach (ThreatItem item in p.threatEvaluations) { if (item.group == hex.location.soc) { threat = item.threat / highestThreat; break; } } float mult = (float)threat; mult = Mathf.Max(0, mult); mult = Mathf.Min(1, mult); float r = mult; float g = mult; float b = mult; //Color color = new Color(r, g, b, 0.8f); Color color = new Color(mult, 0, 0, 0.5f); return(color); } else { return(Color.black); } } else if (hex.location != null) { return(new Color(0f, 0f, 0f, 1f)); } else { return(new Color(0f, 0f, 0f, 0.75f)); } } else if (mask == maskType.LIKING_THEM) { Color c = new Color(0, 0, 0, 0.5f); try { Person me = GraphicalMap.selectedHex.location.settlement.title.heldBy; Person them = hex.location.settlement.title.heldBy; float liking = (float)them.getRelation(me).getLiking(); if (liking > 0) { if (liking > 100) { liking = 100; } liking /= 100; c = new Color(0, liking, 0, 0.5f); } else { liking *= -1; if (liking > 100) { liking = 100; } liking /= 100; c = new Color(liking, 0, 0, 0.5f); } } catch (NullReferenceException e) { } catch (ArgumentNullException e) { } return(c); } else if (mask == maskType.LIKING_ME) { Color c = new Color(0, 0, 0, 0.5f); try { Person me = GraphicalMap.selectedHex.location.settlement.title.heldBy; Person them = hex.location.settlement.title.heldBy; float liking = (float)me.getRelation(them).getLiking(); if (liking > 0) { if (liking > 100) { liking = 100; } liking /= 100; c = new Color(0, liking, 0, 0.5f); } else { liking *= -1; if (liking > 100) { liking = 100; } liking /= 100; c = new Color(liking, 0, 0, 0.5f); } } catch (NullReferenceException e) { } catch (ArgumentNullException e) { } return(c); } else if (mask == maskType.EVIDENCE) { try { Person them = hex.settlement.title.heldBy; return(new Color((float)them.evidence, 0, 0, 0.5f)); } catch (Exception e) { return(new Color(0, 0, 0, 0.5f)); } } else if (mask == maskType.SUSPICION) { try { Person me = GraphicalMap.selectedHex.settlement.title.heldBy; Person them = hex.settlement.title.heldBy; RelObj rel = me.getRelation(them); return(new Color((float)rel.suspicion, 0, 0, 0.5f)); }catch (Exception e) { return(new Color(0, 0, 0, 0.5f)); } } else if (mask == maskType.SUSPICION_FROM) { try { Person them = GraphicalMap.selectedHex.settlement.title.heldBy; Person me = hex.settlement.title.heldBy; RelObj rel = me.getRelation(them); return(new Color((float)rel.suspicion, 0, 0, 0.5f)); } catch (Exception e) { return(new Color(0, 0, 0, 0.5f)); } } else if (mask == maskType.TESTING) { if (hex.location != null) { if (hex.location.debugVal == map.turn) { return(new Color(1, 1, 1, 0.5f)); } else { return(new Color(0, 0, 0, 0.5f)); } } return(new Color(0f, 0f, 0f, 0.75f)); } else { return(new Color(0, 0, 0, 0)); } }
public string getBodyText() { if (mask == maskType.LIKING_ME) { try { Hex hex = GraphicalMap.getHexUnderMouse(Input.mousePosition).hex; Person me = GraphicalMap.selectedHex.location.settlement.title.heldBy; Person them = hex.location.settlement.title.heldBy; if (me.state == Person.personState.enthralled) { return(me.getFullName() + " is enthralled, so does not have normal likings."); } string words = me.getFullName() + " liking for " + them.getFullName(); RelObj rel = me.getRelation(them); words += "\nAmount: " + ((int)rel.getLiking()); double sus = rel.getDislikingFromSuspicion(me); if (sus != 0) { words += "\nFROM SUSPICION: " + sus; } List <RelEvent> sortedEvents = new List <RelEvent>(); sortedEvents.AddRange(rel.events); sortedEvents.Sort(); int nPrinted = 0; foreach (RelEvent ev in sortedEvents) { words += "\n -" + ev.reason + " : " + ((int)ev.amount); nPrinted += 1; if (nPrinted > 6) { break; } } return(words); } catch (Exception e) { return(""); } } else if (mask == maskType.LIKING_THEM) { try { Hex hex = GraphicalMap.getHexUnderMouse(Input.mousePosition).hex; Person them = GraphicalMap.selectedHex.location.settlement.title.heldBy; Person me = hex.location.settlement.title.heldBy; if (me.state == Person.personState.enthralled) { return(me.getFullName() + " is enthralled, so does not have normal likings."); } string words = me.getFullName() + " liking for " + them.getFullName(); RelObj rel = me.getRelation(them); words += "\nAmount: " + ((int)rel.getLiking()); double sus = rel.getDislikingFromSuspicion(me); if (sus != 0) { words += "\nFROM SUSPICION: " + (int)sus; } List <RelEvent> sortedEvents = new List <RelEvent>(); sortedEvents.AddRange(rel.events); sortedEvents.Sort(); int nPrinted = 0; foreach (RelEvent ev in sortedEvents) { words += "\n -" + ev.reason + " : " + ((int)ev.amount); nPrinted += 1; if (nPrinted > 6) { break; } } return(words); } catch (Exception e) { return(""); } } return(""); }
public string getBodyText() { if (mask == maskType.LIKING_ME) { try { Hex hex = GraphicalMap.getHexUnderMouse(Input.mousePosition).hex; Person me = null; if (GraphicalMap.selectedSelectable is Unit) { if (((Unit)GraphicalMap.selectedSelectable).person != null) { me = ((Unit)GraphicalMap.selectedSelectable).person; } } else { me = GraphicalMap.selectedHex.location.settlement.title.heldBy; } Person them = hex.location.settlement.title.heldBy; if (me.state == Person.personState.enthralled) { return(me.getFullName() + " is enthralled, so does not have normal likings."); } string words = me.getFullName() + " liking for " + them.getFullName(); RelObj rel = me.getRelation(them); words += "\nAmount: " + ((int)rel.getLiking()); double sus = rel.getDislikingFromSuspicion(); if (sus != 0) { words += "\nFROM SUSPICION: " + (int)sus; } List <ReasonMsg> msgs = new List <ReasonMsg>(); RelObj.getLikingModifiers(me, them.index, msgs); foreach (ReasonMsg msg in msgs) { words += "\n\n -" + msg.msg + " " + ((int)msg.value); } List <RelEvent> sortedEvents = new List <RelEvent>(); sortedEvents.AddRange(rel.events); sortedEvents.Sort(); int nPrinted = 0; foreach (RelEvent ev in sortedEvents) { words += "\n\n -" + ev.reason + " : " + ((int)ev.amount); nPrinted += 1; if (nPrinted > 6) { break; } } return(words); } catch (Exception e) { return(""); } } else if (mask == maskType.LIKING_THEM) { try { Hex hex = GraphicalMap.getHexUnderMouse(Input.mousePosition).hex; Person them = null; if (GraphicalMap.selectedSelectable is Unit) { if (((Unit)GraphicalMap.selectedSelectable).person != null) { them = ((Unit)GraphicalMap.selectedSelectable).person; } } else { them = GraphicalMap.selectedHex.location.settlement.title.heldBy; } Person me = hex.location.settlement.title.heldBy; if (me.state == Person.personState.enthralled) { return(me.getFullName() + " is enthralled, so does not have normal likings."); } string words = me.getFullName() + " liking for " + them.getFullName(); RelObj rel = me.getRelation(them); words += "\nAmount: " + ((int)rel.getLiking()); double sus = rel.getDislikingFromSuspicion(); if (sus != 0) { words += "\nFROM SUSPICION: " + (int)sus; } List <ReasonMsg> msgs = new List <ReasonMsg>(); RelObj.getLikingModifiers(me, them.index, msgs); foreach (ReasonMsg msg in msgs) { words += "\n\n -" + msg.msg + " " + ((int)msg.value); } List <RelEvent> sortedEvents = new List <RelEvent>(); sortedEvents.AddRange(rel.events); sortedEvents.Sort(); int nPrinted = 0; foreach (RelEvent ev in sortedEvents) { words += "\n\n -" + ev.reason + " : " + ((int)ev.amount); nPrinted += 1; if (nPrinted > 6) { break; } } return(words); } catch (Exception e) { return(""); } } else if (mask == maskType.VOTE_EFFECT) { if (GraphicalMap.selectedHex != null && GraphicalMap.selectedHex.location != null && GraphicalMap.selectedHex.location.person() != null) { Person voter = GraphicalMap.selectedHex.location.person(); Society soc = (Society)voter.society; if (soc.voteSession == null) { return("No voting currently happening in " + voter.getFullName() + "'s society"); } VoteOption opt = soc.voteSession.issue.options[0]; foreach (VoteOption o2 in soc.voteSession.issue.options) { if (o2.votesFor.Contains(voter)) { opt = o2; break; } } return("The change in liking towards " + voter.getFullName() + " if they vote for their currently preferred option (" + opt.info(soc.voteSession.issue) + ")."); } } return(""); }
public static void refresh(Person pf) { focus = pf; int tn = activeSociety.people.Count - 1; int i = 0; foreach (GraphicalSlot s in loadedSlots) { if (s.inner == focus) { s.targetPosition = Vector3.zero; s.subtitle.text = ""; s.lowerRightText.text = ""; } else { int n, ring; if (i < 12) { n = (tn < 12) ? tn : 12; ring = 0; } else { n = (tn - 12 < 52) ? tn - 12 : 52; ring = 1; } RelObj rel = focus.getRelation(s.inner); float liking = (float)rel.getLiking() / 100; if (i == 0) { Debug.Log(rel.suspicion.ToString()); } float radius = (1.75f * ring + 3.0f); float x = Mathf.Cos(6.28f / n * i + ring * 0.1f) * radius; float y = Mathf.Sin(6.28f / n * i + ring * 0.1f) * radius; s.targetPosition = new Vector3(x, y, 0.0f); if (liking < 0) { s.targetColor = Color.Lerp(s.neutralColor, s.badColor, -liking); } else { s.targetColor = Color.Lerp(s.neutralColor, s.goodColor, liking); } s.targetColor.a = 0.5f; //s.targetColor.a = 0.1f + ((float)rel.suspicion / 100); s.subtitle.text = "Relationship with " + focus.firstName; s.lowerRightText.text = "Liked by: " + focus.getRelation(s.inner).getLiking().ToString("N0") + "%"; s.lowerRightText.text += ", Likes: " + s.inner.getRelation(focus).getLiking().ToString("N0") + "%"; s.lowerRightText.text += "\nSuspected by: " + focus.getRelation(s.inner).suspicion.ToString("N0") + "%"; s.lowerRightText.text += ", Suspects: " + s.inner.getRelation(focus).suspicion.ToString("N0") + "%"; i += 1; } } }
public override void turnTick(Unit unit) { //Enthralled can't just eat clues if (unit.isEnthralled()) { unit.task = null; return; } if (unit.location.evidence.Count > 0) { Evidence massiveEvidence = null; foreach (Evidence ev in unit.location.evidence) { if (ev.instaDiscover) { massiveEvidence = ev; break; } } if (massiveEvidence != null) { discoverMassiveEvidence(massiveEvidence, unit); return; } dur += 1; if (dur >= unit.location.map.param.unit_investigateTime) { Evidence ev = unit.location.evidence[0]; if (ev.pointsTo != null) { if (unit.person != null && ev.pointsTo.person != null) { unit.person.getRelation(ev.pointsTo.person).suspicion = System.Math.Min(1, unit.person.getRelation(ev.pointsTo.person).suspicion + ev.weight); } else { //Can't use suspicion system, go straight to murder //Makes sense since they're probably non-human terrors unit.hostility.Add(ev.pointsTo); } unit.location.map.addMessage(unit.getName() + " has found evidence from " + ev.pointsTo.getName(), MsgEvent.LEVEL_ORANGE, false, unit.location.hex); } else if (ev.pointsToPerson != null) { if (unit.person != null && ev.pointsToPerson != null) { unit.person.getRelation(ev.pointsToPerson).suspicion = System.Math.Min(1, unit.person.getRelation(ev.pointsToPerson).suspicion + ev.weight); } unit.location.map.addMessage(unit.getName() + " has found evidence from " + ev.pointsToPerson.getFullName(), MsgEvent.LEVEL_ORANGE, false, unit.location.hex); } if (unit is Unit_Investigator) { Unit_Investigator inv = (Unit_Investigator)unit; inv.evidenceCarried.Add(ev); ev.discoveredBy = inv; } ev.locationFound = unit.location; unit.location.evidence.Remove(ev); unit.task = null; unit.location.map.overmind.panicFromCluesDiscovered += unit.location.map.param.panic_fromClueFound; if (unit.location.map.overmind.panicFromCluesDiscovered > 1) { unit.location.map.overmind.panicFromCluesDiscovered = 1; } //If we're already at maximum suspicion we can now begin pursuing them if (unit is Unit_Investigator) { Unit_Investigator inv = (Unit_Investigator)unit; if (inv.state == Unit_Investigator.unitState.investigator) { if (ev.pointsTo != null && ev.pointsTo.person != null && inv.person.getRelation(ev.pointsTo.person).suspicion >= 1) { Task_HuntEnthralled_InvState task = new Task_HuntEnthralled_InvState(inv, ev.pointsTo); inv.task = task; unit.location.map.world.prefabStore.popMsgAgent(inv, ev.pointsTo, inv.getName() + " has found evidence left by " + ev.pointsTo.getName() + ", and because they are an investigator who is 100% suspicious of " + ev.pointsTo.getName() + ", is able to use these clues to determine the location of " + ev.pointsTo.getName() + ", and will begin to chase them for " + task.turnsLeft + " turns."); } } } if (unit.task == null) { if (unit.location.person() != null) { Person noble = unit.location.person(); foreach (RelObj rel in unit.person.relations.Values) { ////Goes negative if they suspect more than we do, reaches 1.0 if we suspect 1.0 and they suspect 0.0 // if ((rel.suspicion - noble.getRelation(rel.them).suspicion) > Eleven.random.NextDouble()) if ((rel.suspicion > noble.getRelation(rel.them).suspicion * 1.1)) { unit.task = new Task_ShareSuspicions(); return; } } } } } } else { //Evidence gone. Probably eaten by someone else. Return to idle to retask next turn unit.task = null; } }
public Color getColor(Hex hex) { if (mask == maskType.NONE) { if (GraphicalMap.selectedSelectable != null && GraphicalMap.selectedSelectable is Unit) { if (hex.owner != null && hex.owner.hostileTo((Unit)GraphicalMap.selectedSelectable)) { return(new Color(0.5f, 0.0f, 0f, 0.5f)); } } return(Color.clear); } else if (mask == maskType.NATION) { if (hex.owner != null) { float r = hex.owner.color.r; float g = hex.owner.color.g; float b = hex.owner.color.b; Color color = new Color(r, g, b, 0.8f); return(color); } else { return(new Color(0.5f, 0.5f, 0.5f, 0.5f)); } } else if (mask == maskType.PROVINCE) { return(new Color(hex.province.cr, hex.province.cg, hex.province.cb, 0.5f)); } else if (mask == maskType.VOTE_EFFECT) { if (GraphicalMap.selectedHex != null && GraphicalMap.selectedHex.location != null && GraphicalMap.selectedHex.location.person() != null && hex.location != null && hex.location.soc != null) { if (GraphicalMap.selectedHex == hex) { return(new Color(1f, 1f, 1f, 0.5f)); } Person voter = GraphicalMap.selectedHex.location.person(); if (hex.location.soc == voter.society) { if (hex.location.person() != null && hex.location.soc is Society) { Society soc = (Society)hex.location.soc; if (soc.voteSession == null) { return(new Color(0f, 0f, 0f, 0.75f)); } VoteOption opt = null; foreach (VoteOption o2 in soc.voteSession.issue.options) { if (o2.votesFor.Contains(voter)) { opt = o2; break; } } if (opt == null) { soc.voteSession.assignVoters(); } foreach (VoteOption o2 in soc.voteSession.issue.options) { if (o2.votesFor.Contains(voter)) { opt = o2; break; } } if (soc.voteSession != null) { float delta = (float)soc.voteSession.issue.getLikingDelta(hex.location.person(), opt, soc.voteSession.issue); delta /= 25; if (delta > 1) { delta = 1f; } if (delta < -1) { delta = -1f; } if (delta >= 0) { return(new Color(0f, delta, 0f, 0.75f)); } else { return(new Color(-delta, 0f, 0f, 0.75f)); } } } } } return(new Color(0f, 0f, 0f, 0.75f)); } else if (mask == maskType.THREAT) { if (hex.location != null && GraphicalMap.selectedHex != null && GraphicalMap.selectedHex.location != null && GraphicalMap.selectedHex.location.settlement != null && GraphicalMap.selectedHex.location.settlement.title != null && GraphicalMap.selectedHex.location.settlement.title.heldBy != null) { SocialGroup group = GraphicalMap.selectedHex.location.soc; Person p = GraphicalMap.selectedHex.settlement.title.heldBy; double highestThreat = 0; foreach (ThreatItem item in p.threatEvaluations) { if (item.group != null && item.threat > highestThreat) { highestThreat = item.threat; } } if (highestThreat != 0) { if (hex.location.soc == null) { return(Color.black); } double threat = 0; foreach (ThreatItem item in p.threatEvaluations) { if (item.group == hex.location.soc) { threat = item.threat / highestThreat; break; } } float mult = (float)threat; mult = Mathf.Max(0, mult); mult = Mathf.Min(1, mult); //Color color = new Color(r, g, b, 0.8f); Color color = new Color(mult, 0, 0, 0.5f); return(color); } else { return(Color.black); } } else if (hex.location != null) { return(new Color(0f, 0f, 0f, 1f)); } else { return(new Color(0f, 0f, 0f, 0.75f)); } } else if (mask == maskType.LIKING_THEM) { Color c = new Color(0, 0, 0, 0.5f); try { Person me = null; if (GraphicalMap.selectedSelectable is Unit) { if (((Unit)GraphicalMap.selectedSelectable).person != null) { me = ((Unit)GraphicalMap.selectedSelectable).person; } } else { me = GraphicalMap.selectedHex.location.settlement.title.heldBy; } Person them = hex.location.settlement.title.heldBy; float liking = (float)them.getRelation(me).getLiking(); if (liking > 0) { if (liking > 100) { liking = 100; } liking /= 100; c = new Color(0, liking, 0, 0.5f); } else { liking *= -1; if (liking > 100) { liking = 100; } liking /= 100; c = new Color(liking, 0, 0, 0.5f); } } catch (NullReferenceException e) { } catch (ArgumentNullException e) { } return(c); } else if (mask == maskType.LIKING_ME) { Color c = new Color(0, 0, 0, 0.5f); try { Person me = null; if (GraphicalMap.selectedSelectable is Unit) { if (((Unit)GraphicalMap.selectedSelectable).person != null) { me = ((Unit)GraphicalMap.selectedSelectable).person; } } else { me = GraphicalMap.selectedHex.location.settlement.title.heldBy; } Person them = hex.location.settlement.title.heldBy; float liking = (float)me.getRelation(them).getLiking(); if (liking > 0) { if (liking > 100) { liking = 100; } liking /= 100; c = new Color(0, liking, 0, 0.5f); } else { liking *= -1; if (liking > 100) { liking = 100; } liking /= 100; c = new Color(liking, 0, 0, 0.5f); } } catch (NullReferenceException e) { } catch (ArgumentNullException e) { } return(c); } else if (mask == maskType.AWARENESS) { try { Person them = hex.settlement.title.heldBy; return(new Color((float)them.awareness, 0, 0, 0.9f)); } catch (Exception e) { return(new Color(0, 0, 0, 0.9f)); } } else if (mask == maskType.INFILTRATION) { try { float inf = (float)hex.settlement.infiltration; return(new Color(inf, inf, inf, 0.9f)); } catch (Exception e) { return(new Color(0, 0, 0, 0.9f)); } } else if (mask == maskType.SUSPICION) { try { Person me = GraphicalMap.selectedHex.settlement.title.heldBy; Person them = hex.settlement.title.heldBy; RelObj rel = me.getRelation(them); return(new Color((float)rel.suspicion, 0, 0, 0.5f)); }catch (Exception e) { return(new Color(0, 0, 0, 0.5f)); } } else if (mask == maskType.SUSPICION_FROM) { try { Person them = GraphicalMap.selectedHex.settlement.title.heldBy; Person me = hex.settlement.title.heldBy; RelObj rel = me.getRelation(them); return(new Color((float)rel.suspicion, 0, 0, 0.5f)); } catch (Exception e) { return(new Color(0, 0, 0, 0.5f)); } } else if (mask == maskType.TESTING) { if (hex.location != null) { if (hex.location.debugVal == map.turn) { return(new Color(1, 1, 1, 0.5f)); } else { return(new Color(0, 0, 0, 0.5f)); } } return(new Color(0f, 0f, 0f, 0.75f)); } else { return(new Color(0, 0, 0, 0)); } }
public void takeLocationFromOther(SocialGroup att, SocialGroup def, Location taken) { World.log(att.getName() + " takes " + taken.getName() + " from " + def.getName()); int priority = MsgEvent.LEVEL_YELLOW; bool benefit = !def.hasEnthralled(); if (att.hasEnthralled()) { priority = MsgEvent.LEVEL_GREEN; } else if (def.hasEnthralled()) { priority = MsgEvent.LEVEL_RED; } else { priority = MsgEvent.LEVEL_YELLOW; } turnMessages.Add(new MsgEvent(att.getName() + " takes " + taken.getName() + " from " + def.getName(), priority, benefit)); if (taken.settlement != null) { if (taken.settlement.isHuman == false) { taken.settlement = null;//Burn it down } else if (taken.settlement.title != null && taken.settlement.title.heldBy != null) { Person lord = taken.settlement.title.heldBy; if (att is Society) { Society socAtt = (Society)att; lord.prestige *= param.combat_prestigeLossFromConquest; if (socAtt.getSovreign() != null) { lord.getRelation(socAtt.getSovreign()).addLiking(param.person_likingFromBeingInvaded, "Their nation invaded mine", turn); } foreach (Title t in lord.titles) { t.heldBy = null; } lord.titles.Clear(); movePerson(lord, socAtt); } else { lord.die("Killed by " + att.getName() + " when " + taken.getName() + " fell"); } } } taken.soc = att; att.takeLocationFromOther(def, taken); bool hasRemainingTerritory = false; foreach (Location loc in locations) { if (loc.soc == def) { hasRemainingTerritory = true; break; } } if (!hasRemainingTerritory) { World.log("Last territory taken"); addMessage(def.getName() + " has lost its last holdings to " + att.getName()); /* * if (att is Society && def is Society) * { * Society sAtt = (Society)att; * Society sDef = (Society)def; * List<Person> toMove = new List<Person>(); * foreach (Person p in sDef.people) * { * if (p.title_land == null) * { * toMove.Add(p); * } * } * foreach (Person p in toMove) * { * movePerson(p, sAtt); * addMessage(p.getFullName() + " is now part of the court of " + att.getName(), MsgEvent.LEVEL_GRAY, false); * } * } */ } }
public override double computeUtility(Person voter, VoteOption option, List <ReasonMsg> msgs) { double u = option.getBaseUtility(voter); Person p = option.person; double existingValue = 0; if (p.title_land != null) { existingValue = p.title_land.settlement.getPrestige(); } double newValue = title.settlement.getPrestige(); double benefitToPerson = newValue - existingValue; //We know how much they would be advantaged. We now need to know how much we like them to determine //if this is a good thing or not double localU = benefitToPerson * voter.getRelation(p).getLiking() * voter.map.param.utility_landedTitleMult; msgs.Add(new ReasonMsg("Benefit to " + p.getFullName(), localU)); u += localU; if (title.heldBy == null) { localU = voter.map.param.utility_landedTitleAssignBaseline; msgs.Add(new ReasonMsg("Need to assign the title", localU)); u += localU; } if (option.person != voter.society.getSovereign() && voter != option.person) { Person wouldBeSuperior = title.settlement.location.getSuperiorInSociety(voter.society); Person currentSuperior = option.person.getDirectSuperiorIfAny(); if (currentSuperior == voter && wouldBeSuperior != voter) { //Follower would be leaving double desirabilityAsFollower = 0; foreach (Trait t in option.person.traits) { desirabilityAsFollower += t.desirabilityAsFollower(); } if (wouldBeSuperior == voter) { localU = -desirabilityAsFollower; msgs.Add(new ReasonMsg("Desirability as follower", localU)); u += localU; } } else if (currentSuperior != voter && wouldBeSuperior == voter) { //Follower would be arriving double desirabilityAsFollower = 0; foreach (Trait t in option.person.traits) { desirabilityAsFollower += t.desirabilityAsFollower(); } if (wouldBeSuperior == voter) { localU = desirabilityAsFollower; msgs.Add(new ReasonMsg("Desirability as follower", localU)); u += localU; } } } //We need to know if someone's going to lose out here //(Note this is irrelevant if they're the person who's being voted on) if (title.heldBy != null && title.heldBy != p) { double damageToOther = title.settlement.getPrestige(); localU = -damageToOther *voter.getRelation(title.heldBy).getLiking() * voter.map.param.utility_landedTitleMult; msgs.Add(new ReasonMsg(title.heldBy.getFullName() + " would lose title", localU)); u += localU; } return(u); }
public override double computeUtility(Person p, VoteOption option, List <ReasonMsg> msgs) { double u = option.getBaseUtility(p); double advtangeToMe = 0; double advantageToAllies = 0; double advantageToEnemeies = 0; foreach (Person affected in society.people) { if (affected.title_land != null) { double delta = 1; if (affected.title_land.settlement.econTraits().Contains(option.econ_to)) { delta *= society.map.param.econ_multFromBuff; } if (affected.title_land.settlement.econTraits().Contains(option.econ_from)) { delta /= society.map.param.econ_multFromBuff; } delta = 1 - delta; //Run off the base prestige, so all change is regarded the same, regardless of existing changes if (affected == p) { advtangeToMe = delta * p.getRelation(affected).getLiking() * affected.title_land.settlement.basePrestige * society.map.param.utility_econEffect; } else { if (p.getRelation(affected).getLiking() > 0) { advantageToAllies += delta * p.getRelation(affected).getLiking() * affected.title_land.settlement.basePrestige * society.map.param.utility_econEffectOther; } else { advantageToEnemeies += delta * p.getRelation(affected).getLiking() * affected.title_land.settlement.basePrestige * society.map.param.utility_econEffectOther; } } } } //If we're actually affected by this, don't care more about the wellbeing of others than of yourself if (Math.Abs(advtangeToMe) > 1) { if (Math.Abs(advantageToAllies) > Math.Abs(advtangeToMe) / 3) { if (advantageToAllies > 0) { advantageToAllies = Math.Abs(advtangeToMe) / 3; } if (advantageToAllies < 0) { advantageToAllies = -Math.Abs(advtangeToMe) / 3; } } if (Math.Abs(advantageToEnemeies) > Math.Abs(advtangeToMe) / 3) { if (advantageToEnemeies > 0) { advantageToEnemeies = Math.Abs(advtangeToMe) / 3; } if (advantageToEnemeies < 0) { advantageToEnemeies = -Math.Abs(advtangeToMe) / 3; } } } msgs.Add(new ReasonMsg("Advantage to me", advtangeToMe)); u += advtangeToMe; msgs.Add(new ReasonMsg("Advantage to allies", advantageToAllies)); u += advantageToAllies; msgs.Add(new ReasonMsg("Advantage to enemies", advantageToEnemeies)); u += advantageToEnemeies; //World.log("Econ advantages " + advtangeToMe + " " + advantageToAllies + " " + advantageToEnemeies); return(u); }
public override double computeUtility(Person p, VoteOption option, List <ReasonMsg> msgs) { double u = option.getBaseUtility(p); double concernLevel = p.threat_agents.threat; //curr 0 to 200 concernLevel += (100 * p.awareness) + (100 * p.map.worldPanic); //0 to 400 concernLevel /= 4; concernLevel = Math.Min(concernLevel, (p.map.worldPanic * 100) + 20); concernLevel *= (1 - p.shadow); if (p.state == Person.personState.enthralled || p.state == Person.personState.broken) { concernLevel = 0; } //Define the range at which this manner of response is appropriate double responseLevelMin = 0; double responseLevelMax = 0; if (option.index == DEFEND_PROVINCE) { responseLevelMin = 10; responseLevelMax = 40; int evidenceFound = 0; foreach (Evidence ev in foundEvidence) { if (ev.locationFound.province.index == option.province) { evidenceFound += 1; } } double localU = World.staticMap.param.utility_defendEvidenceProvince * evidenceFound * (1 - p.shadow); msgs.Add(new ReasonMsg("Amount of evidence found in " + society.map.provinces[option.province].name + " province", localU)); u += localU; localU = 0; foreach (Person person in society.people) { if (person.getLocation() != null && person.getLocation().province.index == option.province) { localU += p.getRelation(person.index).getLiking() * World.staticMap.param.utility_agentDefendProvinceLikingMult; } } string add = ""; msgs.Add(new ReasonMsg("Liking for nobles in province" + add, localU)); u += localU; if (p.getLocation().province.index != option.province) { localU = p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat; if (localU != 0) { msgs.Add(new ReasonMsg("Does not help me personally", localU)); u += localU; } } else { localU = -1 * p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat; if (localU != 0) { msgs.Add(new ReasonMsg("Helps me personally", localU)); u += localU; } } } if (option.index == NATIONWIDE_SECURITY) { responseLevelMin = 10; responseLevelMax = 40; double localU = World.staticMap.param.utility_evidenceResonseBaseline * (concernLevel / 100); msgs.Add(new ReasonMsg("Base Desirability", localU)); u += localU; localU = p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat / 2; if (localU != 0) { msgs.Add(new ReasonMsg("Doesn't maximise my provinces' defences", localU)); u += localU; } } if (option.index == NO_RESPONSE) { responseLevelMin = 0; responseLevelMax = 10; if (p.getGreatestThreat() != null && p.getGreatestThreat() != p.threat_agents) { double localU = World.staticMap.param.utility_greatestThreatDelta * 0.5; msgs.Add(new ReasonMsg("Not our greatest threat", localU)); u += localU; } else { double localU = -World.staticMap.param.utility_greatestThreatDelta; msgs.Add(new ReasonMsg("Dark Agents are our greatest threat", localU)); u += localU; } } if (option.index == EXPELL_ALL_FOREIGN_AGENTS) { responseLevelMin = 75; responseLevelMax = 100; double n = 0; foreach (Unit unit in society.map.units) { if (unit.society == society) { continue; } if (society.enemies.Contains(unit) == false) { n += 1; } } if (n > 0) { msgs.Add(new ReasonMsg("So many potential enemies!", concernLevel)); u += concernLevel; } } if (option.index == LOCKDOWN_PROVINCE) { responseLevelMin = 40; responseLevelMax = 100; int evidenceFound = 0; foreach (Evidence ev in foundEvidence) { if (ev.locationFound.province.index == option.province) { evidenceFound += 1; } } double localU = World.staticMap.param.utility_defendEvidenceProvince * evidenceFound * (1 - p.shadow); msgs.Add(new ReasonMsg("Amount of evidence found in " + society.map.provinces[option.province].name + " province", localU)); u += localU; localU = 0; foreach (Person person in society.people) { if (person.getLocation() != null && person.getLocation().province.index == option.province) { localU += p.getRelation(person.index).getLiking() * World.staticMap.param.utility_agentDefendProvinceLikingMult; } } string add = "" + (int)(localU); msgs.Add(new ReasonMsg("Liking for nobles in province" + add, localU)); u += localU; if (p.getLocation().province.index != option.province) { localU = p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat; if (localU != 0) { msgs.Add(new ReasonMsg("Does not help me personally", localU)); u += localU; } } else { localU = -1 * p.getSelfInterest() * p.threat_agents.threat * World.staticMap.param.utility_selfInterestFromThreat; if (localU != 0) { msgs.Add(new ReasonMsg("Helps me personally", localU)); u += localU; } } } if (option.index == AGENT_TO_INVESTIGATOR) { responseLevelMin = 0; responseLevelMax = 100; Unit_Investigator inv = (Unit_Investigator)option.unit; double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.investigator); localU *= p.map.param.utility_swapAgentRolesMult; msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU)); u += localU; bool hasSuspicions = false; foreach (RelObj rel in inv.person.relations.Values) { if (inv.location.map.persons[rel.them] == null) { continue; } if (rel.suspicion > 0 && inv.location.map.persons[rel.them].unit != null && inv.location.map.units.Contains(inv.location.map.persons[rel.them].unit)) { hasSuspicions = true; } } if (hasSuspicions) { localU = 12; msgs.Add(new ReasonMsg("Has a suspect", localU)); u += localU; } } if (option.index == AGENT_TO_BASIC) { responseLevelMin = 0; responseLevelMax = 100; double localU = Unit_Investigator.getSwitchUtility(p, (Unit_Investigator)option.unit, Unit_Investigator.unitState.basic); localU *= p.map.param.utility_swapAgentRolesMult; msgs.Add(new ReasonMsg("Balance of agent skills vs balance of threats", localU)); u += localU; } if (concernLevel > responseLevelMax) { double delta = responseLevelMax - concernLevel; delta *= society.map.param.utility_extremeismScaling; double localU = delta; msgs.Add(new ReasonMsg("Too weak response for current concern level (" + (int)(concernLevel) + "%)", localU)); u += localU; } if (concernLevel < responseLevelMin) { double delta = concernLevel - responseLevelMin; delta *= society.map.param.utility_extremeismScaling; double localU = delta; msgs.Add(new ReasonMsg("Too extreme for current concern level (" + (int)(concernLevel) + "%)", localU)); u += localU; } return(u); }
public override void turnTick(Unit unit) { if (unit.location.evidence.Count > 0) { unit.task = new Task_Investigate(); return; } List <Location> neighbours = unit.location.getNeighbours(); int c = 0; Location chosen = null; foreach (Location loc in neighbours) { if (loc.evidence.Count > 0) { chosen = loc; break; } if (visitBuffer.Contains(loc) == false) { c += 1; if (Eleven.random.Next(c) == 0) { chosen = loc; } } } if (chosen != null) { visitBuffer.AddLast(chosen); } else { int q = Eleven.random.Next(neighbours.Count); chosen = neighbours[q]; } unit.location.map.adjacentMoveTo(unit, chosen); if (visitBuffer.Count > bufferSize) { visitBuffer.RemoveFirst(); } //Start investigating the evidence you just moved to if (unit.location.evidence.Count > 0) { unit.task = new Task_Investigate(); return; } //See if you want to warn this new person about anything if (unit.location.person() != null) { Person noble = unit.location.person(); foreach (RelObj rel in unit.person.relations.Values) { //Goes negative if they suspect more than we do, reaches 1.0 if we suspect 1.0 and they suspect 0.0 if ((rel.suspicion - noble.getRelation(rel.them).suspicion) > Eleven.random.NextDouble()) { unit.task = new Task_ShareSuspicions(); return; } } } wanderTimer += 1; if (wanderTimer > wanderDur) { if (unit.parentLocation != null) { unit.task = new Task_GoToLocation(unit.parentLocation); } else { //Done wandering, go home to ensure you don't wander too far for too long unit.task = new Task_GoToSocialGroup(unit.society); } } }