public static bool IsAvailableToIncident(InterceptedIncident_HumanCrowd_RaidEnemy testIncident, out string failReason) { Map map = testIncident.parms.target as Map; failReason = "Not enought colonists"; return(map != null && map.mapPawns.FreeColonistsSpawnedCount > 0); }
public static bool IsAvailableToIncident(InterceptedIncident_HumanCrowd_RaidEnemy testIncident, out string failReason) { Map map = testIncident.parms.target as Map; failReason = "PES_RaidNeg_Sub_Rescue_NoPrisoner".Translate(); return(map != null && map.mapPawns.PrisonersOfColonySpawnedCount > 0 && map.mapPawns.PrisonersOfColonySpawned.Any((Pawn p) => { return !p.Dead && p.Faction == testIncident.SourceFaction; })); }
public static DiaNode RebuffNode() { TravelingIncidentCaravan caravan = DialogUtilities.tempCaravan; Pawn pawn = DialogUtilities.tempPawn; InterceptedIncident_HumanCrowd_RaidEnemy incident = caravan.incident as InterceptedIncident_HumanCrowd_RaidEnemy; if (incident == null) { return(null); } if (incident.raidGoalType == RaidGoalType.Smite) { return(null); } StringBuilder sb = new StringBuilder("PES_RaidNeg_Rebuff_Confirmation".Translate()); sb.AppendLine(); if (incident.raidGoalType == RaidGoalType.Rescue) { Log.Message(incident.raidGoalType.ToString()); sb.AppendLine("PES_RaidNeg_Rebuff_Confirmation_Rescue".Translate()); RaidingGoal_Rescue goal = incident.goal as RaidingGoal_Rescue; foreach (var p in goal.Prisoners) { sb.AppendLine(" " + p.Name.ToStringShort); } } sb.AppendLine(); sb.Append(@"<i>"); sb.Append("PES_RaidNeg_Rebuff_Explanation".Translate(pawn.Name.ToStringShort)); sb.Append(@"</i>"); DiaNode diaNode = new DiaNode(sb.ToString()); void rebuffAction() { RaidingGoalUtility.RebuffDemandAndSmiteThePlayer(caravan, pawn); } DiaOption option = new DiaOption("PES_SimpleConfirm".Translate()); option.action = rebuffAction; option.resolveTree = true; //if (pawn.story.WorkTagIsDisabled(WorkTags.Violent)) //Lt. Bob: 1.1 - Replaced with below if (pawn.WorkTagIsDisabled(WorkTags.Violent)) //Lt. Bob: 1.1 { option.Disable("PES_RaidNeg_Rebuff_Rescue_Fail".Translate()); } diaNode.options.Add(option); diaNode.options.Add(DialogUtilities.CurtOption("PES_Cancel", null, null, true)); return(diaNode); }
public override void ApplyToIncident(InterceptedIncident_HumanCrowd_RaidEnemy _incident) { base.ApplyToIncident(_incident); Map map = incident.parms.target as Map; List <Pawn> validColonists = new List <Pawn>(); foreach (var pawn in map.mapPawns.FreeColonistsSpawned) { if (!pawn.Dead) { validColonists.Add(pawn); } } if (validColonists.Count <= 0) { throw new Exception("Try to create enslave goal but there is no colonist!"); } this.Slaves = new List <Pawn>(); int maxNum = MaxColonistsByRaidPoints(incident.parms.points); maxNum = Math.Min(maxNum, Mathf.FloorToInt(map.mapPawns.FreeColonistsSpawnedCount * 0.5f)); if (maxNum < 1) { throw new Exception("Should not resolve enslave goal when there are only 1 colonist!"); } foreach (var pawn in validColonists.InRandomOrder()) { if (Slaves.Count >= maxNum) { break; } Slaves.Add(pawn); } if (PES_Settings.DebugModeOn) { string ss = "Want Colonists:"; foreach (var x in Slaves) { ss += "\n" + x.Name.ToStringShort; } Log.Message(ss); } }
public override void ApplyToIncident(InterceptedIncident_HumanCrowd_RaidEnemy _incident) { base.ApplyToIncident(_incident); Map map = incident.parms.target as Map; List <Pawn> validPrisoners = new List <Pawn>(); foreach (var pawn in map.mapPawns.PrisonersOfColonySpawned) { if (!pawn.Dead && pawn.Faction == incident.SourceFaction) { validPrisoners.Add(pawn); } } if (validPrisoners.Count <= 0) { throw new Exception("Try to create prisoner rescue goal but there is no prisoners!"); } this.Prisoners = new List <Pawn>(); int maxNum = MaxPrisonersByRaidPoints(incident.parms.points); foreach (var pawn in validPrisoners.InRandomOrder()) { if (Prisoners.Count >= maxNum) { break; } Prisoners.Add(pawn); } if (PES_Settings.DebugModeOn) { string ss = "Rescue Prisoners:"; foreach (var x in Prisoners) { ss += "\n" + x.Name.ToStringShort; } Log.Message(ss); } }
public static void CombatMoralResolver(InterceptedIncident_HumanCrowd_RaidEnemy incident) { Map map = incident.parms.target as Map; var colonists = map.mapPawns.FreeColonists; HediffDef hediffPos = PESDefOf.PES_CombatFervor; HediffDef hediffNeg = PESDefOf.PES_CombatTiredness; if (incident.CombatMoral == 0) { return; } foreach (var pawn in colonists) { if (incident.CombatMoral == 1) { if (pawn.health.hediffSet.HasHediff(hediffNeg)) { foreach (var hediff in pawn.health.hediffSet.hediffs) { if (hediff.def == hediffNeg) { pawn.health.RemoveHediff(hediff); break; } } } pawn.health.AddHediff(hediffPos, null, null, null); } else { if (!pawn.health.hediffSet.HasHediff(hediffPos)) { pawn.health.AddHediff(hediffNeg, null, null, null); } } } }
public static DiaNode DelayNode() { TravelingIncidentCaravan caravan = DialogUtilities.tempCaravan; Pawn pawn = DialogUtilities.tempPawn; InterceptedIncident_HumanCrowd_RaidEnemy incident = caravan.incident as InterceptedIncident_HumanCrowd_RaidEnemy; if (incident == null) { return(null); } if (incident.raidGoalType == RaidGoalType.Smite) { return(null); } DiaNode delaySuccessNode() { DiaNode diaNode = new DiaNode("PES_RaidNeg_Delay_Success".Translate(caravan.CaravanTitle)); diaNode.options.Add(DialogUtilities.CurtOption("PES_Reassuring", null, () => { caravan.StageForThreeHours(); DialogUtilities.NegotiatorLearnSocial(true); }, true)); return(diaNode); } DiaNode delayFailNode() { DiaNode diaNode = new DiaNode("PES_RaidNeg_Delay_Fail".Translate()); diaNode.options.Add(DialogUtilities.CurtOption("PES_DAMNIT", null, () => { caravan.ApplyDelayCoolDown(); DialogUtilities.NegotiatorLearnSocial(false); }, true)); return(diaNode); } DiaNode delaySmiteNode() { DiaNode diaNode = new DiaNode("PES_RaidNeg_Delay_Smite".Translate()); diaNode.options.Add(DialogUtilities.CurtOption("PES_DAMNIT", null, () => { caravan.Communicable = false; incident.goal = new RaidingGoal_Smite(); DialogUtilities.NegotiatorLearnSocial(false); }, true)); return(diaNode); } DiaNode delayNode = new DiaNode("PES_RaidNeg_Delay_Intro".Translate()); DiaOption option; //Persuasion float successOdds = Mathf.Clamp01(PES_Settings.BaseDelayPersuasionChance * pawn.NegotiatePowerFactor()); StringBuilder sb = new StringBuilder(string.Format("[{0}]: {1}\n", "PES_Persuade_noun".Translate(), "PES_RaidNeg_Delay_Persuasion".Translate())); sb.AppendLine(OddsIndicator(successOdds, "PES_RaidNeg_Delay_Success_Name")); option = new DiaOption(sb.ToString()); option.action = DialogUtilities.ResolveActionByOdds(successOdds, null, delaySuccessNode(), null, delayFailNode()); delayNode.options.Add(option); //Intimidation successOdds = Mathf.Clamp01(PES_Settings.BaseDelayIntimidationSuccessChance * pawn.NegotiatePowerFactor()); float smiteOdds = Mathf.Clamp01(PES_Settings.BaseDelayIntimidationSmiteChance * pawn.NegotiatePowerFactorNeg()); string intimidationText = ("PES_RaidNeg_Delay_Intimidation_" + incident.raidGoalType.ToString()).Translate(); sb = new StringBuilder(string.Format("[{0}]: {1}\n", "PES_intimidate_noun".Translate(), intimidationText)); sb.AppendLine(OddsIndicator(successOdds, "PES_RaidNeg_Delay_Success_Name", smiteOdds, "PES_RaidNeg_Delay_Smite_Name")); option = new DiaOption(sb.ToString()); option.action = DialogUtilities.ResolveActionByOdds(successOdds, null, delaySuccessNode(), smiteOdds, null, delaySmiteNode(), null, delayFailNode()); delayNode.options.Add(option); //Beguilement if (pawn.skills.GetSkill(SkillDefOf.Social).Level >= 15) { successOdds = Mathf.Clamp01(PES_Settings.BaseDelayBeguilementChance * pawn.NegotiatePowerFactor()); string beguilementText = ("PES_RaidNeg_Delay_Beguilement_" + incident.raidGoalType.ToString()).Translate(); sb = new StringBuilder(string.Format("[{0}]: {1}\n", "PES_beguile_noun".Translate(), beguilementText)); sb.AppendLine(OddsIndicator(successOdds, "PES_RaidNeg_Delay_Success_Name")); option = new DiaOption(sb.ToString()); option.action = DialogUtilities.ResolveActionByOdds(successOdds, null, delaySuccessNode(), null, delayFailNode()); delayNode.options.Add(option); } delayNode.options.Add(DialogUtilities.CurtOption("PES_Cancel", null, null, true)); return(delayNode); }
public static DiaNode RemedyDetail(Action successAction) { TravelingIncidentCaravan caravan = DialogUtilities.tempCaravan; Pawn pawn = DialogUtilities.tempPawn; InterceptedIncident_HumanCrowd_RaidEnemy incident = caravan.incident as InterceptedIncident_HumanCrowd_RaidEnemy; RaidingGoal goal = incident.goal; if (incident == null) { return(null); } if (incident.raidGoalType == RaidGoalType.Smite) { return(null); } DiaNode RemedySuccessNode() { DiaNode diaNode = new DiaNode("PES_RaidNeg_Sub_success".Translate()); diaNode.options.Add(DialogUtilities.CurtOption("PES_Reassuring", null, () => { successAction(); caravan.ApplyNegotiationCoolDown(); DialogUtilities.NegotiatorLearnSocial(true); }, true)); return(diaNode); } DiaNode RemedyFailNode() { DiaNode diaNode = new DiaNode("PES_RaidNeg_Sub_Fail".Translate()); diaNode.options.Add(DialogUtilities.CurtOption("PES_ASHAME", null, () => { caravan.ApplyNegotiationCoolDown(); DialogUtilities.NegotiatorLearnSocial(false); }, true)); return(diaNode); } DiaNode RemedySmiteNode() { DiaNode diaNode = new DiaNode("PES_raidNeg_NegDeeper_Bargain_Smite".Translate()); diaNode.options.Add(DialogUtilities.CurtOption("PES_DAMNIT", null, () => { caravan.Communicable = false; incident.goal = new RaidingGoal_Smite(); caravan.ApplyNegotiationCoolDown(); DialogUtilities.NegotiatorLearnSocial(false); }, true)); return(diaNode); } DiaNode remedyNode = new DiaNode("PES_RaidNeg_Sub_Intro".Translate()); DiaOption option; //Persuasion float successOdds = Mathf.Clamp01(PES_Settings.BaseRemedyPersuasionChance * pawn.NegotiatePowerFactor()); StringBuilder sb = new StringBuilder(string.Format("[{0}]: {1}\n", "PES_Persuade_noun".Translate(), goal.RemedyPersuasionStr)); sb.AppendLine(OddsIndicator(successOdds, "PES_raidNeg_NegDeeper_Bargain_Success_Name")); option = new DiaOption(sb.ToString()); option.action = DialogUtilities.ResolveActionByOdds(successOdds, null, RemedySuccessNode(), null, RemedyFailNode()); remedyNode.options.Add(option); //Intimidation successOdds = Mathf.Clamp01(PES_Settings.BaseRemedyIntimidationSuccessChance * pawn.NegotiatePowerFactor()); float smiteOdds = Mathf.Clamp01(PES_Settings.BaseRemedyIntimidationSmiteChance * pawn.NegotiatePowerFactorNeg()); sb = new StringBuilder(string.Format("[{0}]: {1}\n", "PES_intimidate_noun".Translate(), goal.RemedyIntimidationStr)); sb.AppendLine(OddsIndicator(successOdds, "PES_raidNeg_NegDeeper_Bargain_Success_Name", smiteOdds, "PES_RaidNeg_Negdeeper_Bargain_Smite_Name")); option = new DiaOption(sb.ToString()); option.action = DialogUtilities.ResolveActionByOdds(successOdds, null, RemedySuccessNode(), smiteOdds, null, RemedySmiteNode(), null, RemedyFailNode()); remedyNode.options.Add(option); //Beguilement if (pawn.skills.GetSkill(SkillDefOf.Social).Level >= 15) { successOdds = Mathf.Clamp01(PES_Settings.BaseRemedyBeguilementChance * pawn.NegotiatePowerFactor()); sb = new StringBuilder(string.Format("[{0}]: {1}\n", "PES_beguile_noun".Translate(), goal.RemedyBeguilementStr)); sb.AppendLine(OddsIndicator(successOdds, "PES_raidNeg_NegDeeper_Bargain_Success_Name")); option = new DiaOption(sb.ToString()); option.action = DialogUtilities.ResolveActionByOdds(successOdds, null, RemedySuccessNode(), null, RemedyFailNode()); remedyNode.options.Add(option); } remedyNode.options.Add(DialogUtilities.CurtOption("PES_Cancel", null, null, true)); return(remedyNode); }
public static DiaNode NegotiateDeepNode() { TravelingIncidentCaravan caravan = DialogUtilities.tempCaravan; Pawn pawn = DialogUtilities.tempPawn; InterceptedIncident_HumanCrowd_RaidEnemy incident = caravan.incident as InterceptedIncident_HumanCrowd_RaidEnemy; RaidingGoal goal = incident.goal; if (incident == null) { return(null); } if (incident.raidGoalType == RaidGoalType.Smite) { return(null); } DiaNode diaNode = new DiaNode("PES_RaidNeg_NegDeeper_Prolog".Translate()); DiaOption option; StringBuilder sb; string failReason; //surrender option = new DiaOption("PES_RaidNeg_NegDeeper_Surrender".Translate() + "\n"); if (!goal.IsAchievable(out failReason)) { option.disabled = true; option.disabledReason = failReason; } else { DiaNode surrenderConfirmation() { DiaNode cnode = new DiaNode("PES_RaidNeg_NegDeeper_Surrender_Comfirmation".Translate()); cnode.options.Add(DialogUtilities.CurtOption("PES_SimpleConfirm", null, () => { goal.Achieve(); }, true)); cnode.options.Add(DialogUtilities.CurtOption("PES_Cancel", null, null, true)); return(cnode); } option.link = surrenderConfirmation(); } diaNode.options.Add(option); //bargain option = new DiaOption("PES_RaidNeg_NegDeeper_Bargain".Translate() + "\n"); if (!goal.CanBargain(out failReason)) { option.disabled = true; option.disabledReason = failReason; } else if (caravan.negotiateCoolDownTick > 0) { option.Disable("PES_RaidNeg_NegCoolDown".Translate(GenDate.ToStringTicksToPeriod(caravan.negotiateCoolDownTick))); } else { DiaNode BargainNode() { DiaNode bNode = new DiaNode("PES_RaidNeg_NegDeeper_Bargain_Intro".Translate()); foreach (var x in goal.BargainChoices()) { bNode.options.Add(x); } bNode.options.Add(DialogUtilities.CurtOption("PES_Cancel", null, null, true)); return(bNode); } option.link = BargainNode(); } diaNode.options.Add(option); //Remedy option = new DiaOption("PES_RaidNeg_NegDeeper_Remedy".Translate()); if (caravan.negotiateCoolDownTick > 0) { option.Disable("PES_RaidNeg_NegCoolDown".Translate(GenDate.ToStringTicksToPeriod(caravan.negotiateCoolDownTick))); } else { DiaNode RemedyNode() { DiaNode rNode = new DiaNode("PES_RaidNeg_Sub_Intro".Translate()); DiaOption rOption; if (incident.raidGoalType != RaidGoalType.Rescue) { rOption = new DiaOption("PES_RaidNeg_Sub_Rescue".Translate()); if (!RaidingGoal_Rescue.IsAvailableToIncident(incident, out failReason)) { rOption.Disable(failReason); } rOption.link = RemedyDetail(() => { (new RaidingGoal_Rescue()).ApplyToIncident(incident); }); rNode.options.Add(rOption); } if (incident.raidGoalType != RaidGoalType.Extortion) { rOption = new DiaOption("PES_RaidNeg_Sub_Extortion".Translate()); rOption.link = RemedyDetail(() => { (new RaidingGoal_Extortion()).ApplyToIncident(incident); }); rNode.options.Add(rOption); rNode.options.Add(DialogUtilities.CurtOption("PES_Cancel", null, null, true)); } rNode.options.Add(DialogUtilities.CurtOption("PES_Cancel", null, null, true)); return(rNode); } option.link = RemedyNode(); } diaNode.options.Add(option); diaNode.options.Add(DialogUtilities.CurtOption("PES_Cancel", null, null, true)); return(diaNode); }
public static DiaNode PrologueNode() { TravelingIncidentCaravan caravan = DialogUtilities.tempCaravan; Pawn pawn = DialogUtilities.tempPawn; InterceptedIncident_HumanCrowd_RaidEnemy incident = caravan.incident as InterceptedIncident_HumanCrowd_RaidEnemy; RaidingGoal goal = incident.goal; if (incident == null) { return(null); } if (incident.raidGoalType == RaidGoalType.Smite) { return(null); } if (incident.SourceFaction == Faction.OfMechanoids) { return(DialogMaker_TryToContact.MechanoidAnswers()); } StringBuilder sb = new StringBuilder("PES_RaidNeg_Proglog".Translate(caravan.CaravanTitle, incident.SourceFaction)); sb.AppendLine(); sb.AppendLine(); bool polite = false; if (incident.raidGoalType == RaidGoalType.Rescue) { if (new FloatRange(0f, 1f).RandomInRange < 0.5f) { polite = true; } } if (incident.raidGoalType == RaidGoalType.Extortion) { if (new FloatRange(0f, 1f).RandomInRange < 0.2f) { polite = true; } } if (polite) { sb.Append("PES_RaidNeg_Attitude_Polite".Translate()); } else { sb.Append("PES_RaidNeg_Attitude_Rude".Translate()); } sb.AppendLine(goal.GoalExpStr); sb.AppendLine(); if (polite) { sb.AppendLine("PES_RaidNeg_DemandSurrender_Polite".Translate()); } else { sb.AppendLine("PES_RaidNeg_DemandSurrender_rude".Translate()); } DiaNode diaNode = new DiaNode(sb.ToString()); DiaOption option; string rebuffStr = "PES_RaidNeg_Rebuff_Head".Translate() + ("PES_RaidNeg_Rebuff_" + incident.raidGoalType.ToString()).Translate() + "\n"; option = new DiaOption(rebuffStr); option.link = RebuffNode(); diaNode.options.Add(option); option = new DiaOption("PES_RaidNeg_NegDeeper".Translate() + "\n"); option.link = NegotiateDeepNode(); diaNode.options.Add(option); option = new DiaOption("PES_RaidNeg_Delay".Translate() + "\n"); option.link = DelayNode(); if (caravan.stageRemainingTick > 0) { option.Disable("PES_RaidNeg_Delay_Staging".Translate(GenDate.ToStringTicksToPeriod(caravan.stageRemainingTick))); } else if (caravan.StagedBefore) { option.Disable("PES_RaidNeg_Delay_DoneBefore".Translate()); } else if (caravan.delayCoolDownTick > 0) { option.Disable("PES_RaidNeg_Delay_CoolDown".Translate(GenDate.ToStringTicksToPeriod(caravan.delayCoolDownTick))); } diaNode.options.Add(option); diaNode.options.Add(DialogUtilities.CurtOption("PES_Cancel", null, null, true)); return(diaNode); }
public static bool IsAvailableToIncident(InterceptedIncident_HumanCrowd_RaidEnemy testIncident, out string failReason) { failReason = "This should always be available"; return(true); }
public override void ApplyToIncident(InterceptedIncident_HumanCrowd_RaidEnemy _incident) { base.ApplyToIncident(_incident); needSilver = Mathf.RoundToInt(incident.parms.points); }
//public abstract float ActiveContactOdds { get; } public virtual void ApplyToIncident(InterceptedIncident_HumanCrowd_RaidEnemy _incident) { _incident.goal = this; this.incident = _incident; }
public static bool IsAvailableToIncident(InterceptedIncident_HumanCrowd_RaidEnemy testIncident, out string failReason) { failReason = "Not enought raid power"; return(testIncident.parms.points >= 1000); }
public static void ResolveRaidGoal(InterceptedIncident_HumanCrowd_RaidEnemy incident) { if (incident.SourceFaction == Faction.OfMechanoids) { new RaidingGoal_Extermination().ApplyToIncident(incident); if (PES_Settings.DebugModeOn) { Log.Message("Figure out raid goal: " + RaidGoalType.Extermination.ToString()); } return; } Map map = incident.parms.target as Map; Dictionary <RaidGoalType, float> weightDic = new Dictionary <RaidGoalType, float>() { [RaidGoalType.Conquer] = 1f, [RaidGoalType.Extortion] = 1f, [RaidGoalType.Enslave] = 1f, [RaidGoalType.Rescue] = 1f }; float ConquerWeight = 0f; if (incident.parms.points < 1000f) { ConquerWeight = 0f; } else if (incident.parms.points < 3000f) { ConquerWeight = 1f; } else { ConquerWeight = 2f; } weightDic[RaidGoalType.Conquer] = ConquerWeight; float EnslaveWeight = 0f; if (map.mapPawns.FreeColonistsSpawnedCount <= 1) { EnslaveWeight = 0f; } else { EnslaveWeight = Mathf.Clamp01(map.mapPawns.FreeColonistsSpawnedCount / 10f) * 0.8f; } weightDic[RaidGoalType.Enslave] = EnslaveWeight; float RescueWeight = 0f; if (map.mapPawns.PrisonersOfColonySpawnedCount < 1) { RescueWeight = 0f; } else { int factionPrisonerSum = map.mapPawns.PrisonersOfColonySpawned.Sum(p => !p.Dead && p.Faction == incident.SourceFaction ? 1 : 0); if (factionPrisonerSum == 0) { RescueWeight = 0f; } else if (factionPrisonerSum <= 3) { RescueWeight = 1f; } else { RescueWeight = 2f; } } weightDic[RaidGoalType.Rescue] = RescueWeight; RaidGoalType theChosenOne = weightDic.Keys.ToList().RandomElementByWeight(t => weightDic[t]); if (PES_Settings.DebugModeOn) { Log.Message("Figure out raid goal: " + theChosenOne.ToString()); } RaidingGoal goal = Activator.CreateInstance(RaidingGoal.GetRaidClassByEnum(theChosenOne)) as RaidingGoal; goal.ApplyToIncident(incident); }