private static void CalculateInfluenceChangePostfix(Clan clan, ref ExplainedNumber __result) { if (!Settings.Instance !.EnableInfluenceBalancing) { return; } /// Corruption if (Settings.Instance !.EnableCorruption) { float corruption = clan.GetCorruption(); if (corruption >= 0.01f) { __result.Add(-corruption, _TCorruption); } } /// Influence Decay if (Settings.Instance !.EnableInfluenceDecay && clan.Influence > Settings.Instance !.InfluenceDecayThreshold) { float decayFactor = Settings.Instance !.InfluenceDecayPercentage / 100f; int decay = (int)(decayFactor * (clan.Influence - Settings.Instance !.InfluenceDecayThreshold)); if (decay > 0) { __result.Add(-decay, _TInfluenceDecay); } } /// Minimum Influence Gain (Maximum Influence Loss) __result.LimitMin(-Settings.Instance !.MaximumInfluenceLoss); }
private static void Postfix(MobileParty party, ref ExplainedNumber result) { if (party.ItemRoster.FoodVariety > 10) { result.Add(party.ItemRoster.FoodVariety - 4f, GameTexts.FindText("str_food_bonus_morale", (string)null)); } }
static bool Prefix(PartyBase party, float influenceValueOfBattle, float contributionShare, StatExplainer explanation, ref float __result) { bool patched = false; try { var battleInfluenceMultiplier = 1f; if (Settings.Instance.BattleRewardApplyToAI || party.LeaderHero != null && party.LeaderHero == Hero.MainHero) { battleInfluenceMultiplier = Settings.Instance.BattleInfluenceMultiplier; } var stat = new ExplainedNumber(party.MapFaction.IsKingdomFaction ? (influenceValueOfBattle * contributionShare * battleInfluenceMultiplier) : 0f, explanation, null); __result = stat.ResultNumber; patched = true; } catch (Exception ex) { MessageBox.Show($"An error occurred during DefaultBattleRewardModelInfluencePatch. Reverting to original behavior... \n\nException:\n{ex.Message}\n\n{ex.InnerException?.Message}\n\n{ex.InnerException?.Message}"); } return(!patched); }
private void ImperialChange(SettlementInfo settlementInfo, ref ExplainedNumber explainedNumber) { if (!RevolutionsSettings.Instance.RevoltsImperialLoyaltyMechanic) { return; } if (settlementInfo.IsOfImperialCulture) { if (settlementInfo.IsCurrentFactionOfImperialCulture) { explainedNumber.Add(3, new TextObject(GameTexts.RevoltsLoyaltyCalculationImperialLoyalty)); } else { explainedNumber.Add(-1, new TextObject(GameTexts.RevoltsLoyaltyCalculationForeignRule)); } } else { if (settlementInfo.IsCurrentFactionOfImperialCulture) { explainedNumber.Add(-1, new TextObject(GameTexts.RevoltsLoyaltyCalculationImperialAversion)); } if (settlementInfo.LoyalFaction.StringId != settlementInfo.CurrentFactionId) { explainedNumber.Add(1, new TextObject(GameTexts.RevoltsLoyaltyCalculationForeignRule)); } } }
private static void Postfix(ref float __result, Town fortification, StatExplainer explanation) { var perk = ActivePatch._perk; var hero = fortification.Settlement?.OwnerClan?.Leader; if (hero == null || !hero.GetPerkValue(perk) || fortification.Settlement.Parties.Count(x => x.LeaderHero == fortification.Settlement.OwnerClan.Leader) <= 0) { return; } var explainedNumber = new ExplainedNumber(__result, explanation); if (explanation.Lines.Count > 0) { explanation.Lines.RemoveAt(explanation.Lines.Count - 1); } var extra = explanation.Lines.Where(line => line.Number > 0).Sum(line => line.Number); if (extra < float.Epsilon) { return; } explainedNumber.Add(extra * perk.PrimaryBonus - extra, perk.Name); __result = explainedNumber.ResultNumber; }
public override float CalculateTownFoodStocksChange(Town town, StatExplainer explanation = null) { float baseVal = base.CalculateTownFoodStocksChange(town, explanation); if (Settings.Instance.SettlementFoodBonusEnabled) { try { ExplainedNumber en = new ExplainedNumber(baseVal, explanation); explanation?.Lines.Remove(explanation.Lines.Last()); if (town.IsCastle) { en.Add(Settings.Instance.CastleFoodBonus, new TextObject("Military rations")); } else if (town.IsTown) { en.Add(Settings.Instance.TownFoodBonus, new TextObject("Citizen food drive")); } return(en.ResultNumber); } catch (Exception ex) { MessageBox.Show($"An error occurred in TweakedSettlementFoodModel: {ex.ToStringFull()}"); return(baseVal); } } else { return(baseVal); } }
private static void Postfix(ref int __result, MobileParty party, StatExplainer explanation) { var perk = ActivePatch._perk; if (!(party.LeaderHero?.GetPerkValue(perk) ?? false)) { return; } var extra = party.LeaderHero.Clan.Settlements.Count() * perk.PrimaryBonus; if (extra < float.Epsilon) { return; } var explainedNumber = new ExplainedNumber(__result, explanation); var baseLine = explanation?.Lines.Find(x => x.Name == "Base"); if (baseLine != null) { explanation.Lines.Remove(baseLine); } explainedNumber.Add(party.LeaderHero.Clan.Settlements.Count() * perk.PrimaryBonus, perk.Name); __result = (int)explainedNumber.ResultNumber; }
public override void CalculateClanIncome( Clan clan, ref ExplainedNumber goldChange, bool applyWithdrawals = false) { goldChange.Add(666, new TextObject("hardcoded 666")); }
private static int CalculateGarrisonChangeInternal( Settlement settlement, StatExplainer explanation = null) { ExplainedNumber result = new ExplainedNumber(0.0f, explanation, (TextObject)null); if (settlement.IsTown || settlement.IsCastle) { double loyalty = (double)settlement.Town.Loyalty; if (settlement.IsStarving) { float foodChange = settlement.Town.FoodChange; int num = !settlement.Town.Owner.IsStarving || (double)foodChange >= -19.0 ? 0 : (int)(((double)foodChange + 10.0) * SubModule.Settings.garrisonFoodConsumpetionMultiplier / 10.0); result.Add((float)num, LightSettlementGarrisonModel._foodShortageText); } if (settlement.Town.GarrisonParty != null && ((double)settlement.Town.GarrisonParty.Party.NumberOfHealthyMembers + (double)result.ResultNumber) / (double)settlement.Town.GarrisonParty.Party.PartySizeLimit > (double)settlement.Town.GarrisonParty.PaymentRatio) { int num = 0; do { ++num; }while (((double)settlement.Town.GarrisonParty.Party.NumberOfHealthyMembers + (double)result.ResultNumber - (double)num) / (double)settlement.Town.GarrisonParty.Party.PartySizeLimit >= (double)settlement.Town.GarrisonParty.PaymentRatio && (double)settlement.Town.GarrisonParty.Party.NumberOfHealthyMembers + (double)result.ResultNumber - (double)num > 0.0 && num < 20); result.Add((float)-num, LightSettlementGarrisonModel._paymentIsLess); } } LightSettlementGarrisonModel.GetSettlementGarrisonChangeDueToIssues(settlement, ref result); return((int)result.ResultNumber); }
private static void Postfix( DefaultPartySpeedCalculatingModel __instance, ref MobileParty mobileParty, ref float baseSpeed, ref StatExplainer explanation, ref float __result) { TerrainType faceTerrainType = Campaign.Current.MapSceneWrapper.GetFaceTerrainType(mobileParty.CurrentNavigationFace); if (faceTerrainType == TerrainType.Forest && mobileParty.Leader != null && mobileParty.Leader.GetFeatValue(DefaultFeats.Cultural.BattanianForestAgility)) { var explainedNumber = new ExplainedNumber(baseSpeed, explanation, null); var movingAtForestEffectField = AccessTools.Field(typeof(DefaultPartySpeedCalculatingModel), "MovingAtForestEffect"); var movingAtForestEffect = (float)movingAtForestEffectField.GetValue(__instance); var battanianAgilityBonus = DefaultFeats.Cultural.BattanianForestAgility.EffectBonus * Math.Abs(movingAtForestEffect); explainedNumber.AddFactor(battanianAgilityBonus, DefaultFeats.Cultural.BattanianForestAgility.Name); __result = explainedNumber.ResultNumber; } }
private static void Postfix(ref int __result, MobileParty party, StatExplainer explanation) { var perk = ActivePatch._perk; var hero = party.LeaderHero; if (hero == null || hero.Clan?.Kingdom?.RulingClan?.Leader != hero) { return; } if (!hero.GetPerkValue(perk)) { return; } var kingdomClans = hero.Clan?.Kingdom?.Clans; if (kingdomClans == null) { return; } var extra = (int)Math.Max(0, (kingdomClans.Count() - 1) * perk.PrimaryBonus); if (extra <= 0) { return; } var explainedNumber = new ExplainedNumber(__result, explanation); explainedNumber.Add(extra, perk.Name); __result = (int)explainedNumber.ResultNumber; }
private static void Postfix(ref float __result, Village village, StatExplainer explanation) { var perk = ActivePatch._perk; if (!(village.Bound?.OwnerClan?.Leader?.GetPerkValue(perk) ?? false)) { return; } var explainedNumber = new ExplainedNumber(__result, explanation); if (!(__result > -0.0001f) || !(__result < 0.0001f) && explanation.Lines.Count > 0) { explanation.Lines.RemoveAt(explanation.Lines.Count - 1); } var extra = explanation.Lines.Where(line => line.Number > 0).Sum(line => line.Number); if (extra < float.Epsilon) { return; } explainedNumber.Add(extra * perk.PrimaryBonus - extra, perk.Name); __result = explainedNumber.ResultNumber; }
public static void CalculateInfluenceChangePatch(ref ExplainedNumber __result, Clan clan, bool includeDescriptions = false) { if (Settings.Instance.EnableInfluenceBalancing) { var influenceChange = __result; if (Settings.Instance.EnableCorruption) { float corruption = clan.GetCorruption(); if (corruption > 0) { influenceChange.Add(-corruption, new TextObject("{=dUCOV7km}Corruption (too many fiefs)")); } } if (Settings.Instance.EnableInfluenceDecay) { int influenceDecayFactor = clan.Influence > Settings.Instance.InfluenceDecayThreshold ? (int)-((clan.Influence - Settings.Instance.InfluenceDecayThreshold) * (Settings.Instance.InfluenceDecayPercentage / 100)) : 0; if (influenceDecayFactor < 0) { influenceChange.Add(influenceDecayFactor, new TextObject("{=koTNaZUX}Influence Decay (too much influence)")); } } float maximumInfluenceLoss = Settings.Instance.MaximumInfluenceLoss; if (influenceChange.ResultNumber < -maximumInfluenceLoss) { influenceChange.Add(-maximumInfluenceLoss, new TextObject("{=uZc8Hg01}Maximum Influence Loss")); } __result = influenceChange; } }
private static void Postfix(MobileParty mobileParty, ref ExplainedNumber __result) { if (PartyMilitiaMap.ContainsKey(mobileParty)) { __result.AddFactor(SpeedModifier, new TextObject("Bandit Militia")); } }
public override float CalculateLoyaltyChange(Town town, StatExplainer explanation = null) { ExplainedNumber explainedNumber = new ExplainedNumber(0.0f, explanation, (TextObject)null); SettlementInfo info = RevolutionBehaviour.GetSettlementInformation(town.Settlement); if (!town.IsTown) { return(explainedNumber.ResultNumber + base.CalculateLoyaltyChange(town, explanation)); } if (info.Settlement.MapFaction.Leader == Hero.MainHero) { explainedNumber.Add(_basePlayerLoyalty, GameTexts.FindText("str_loyalty_bannerlord")); if (ModOptions.OptionsData.PlayerAffectedByOverextension && ModOptions.OptionsData.OverextensionMechanics) { Overextension(info, ref explainedNumber); } } else { BaseLoyalty(info, ref explainedNumber); if (ModOptions.OptionsData.OverextensionMechanics) { Overextension(info, ref explainedNumber); } } return(explainedNumber.ResultNumber + base.CalculateLoyaltyChange(town, explanation)); }
private static int CalculateGarrisonChangeInternal(Settlement settlement, StatExplainer explanation = null) { ExplainedNumber explainedNumber = new ExplainedNumber(0f, explanation, null); if (settlement.IsTown || settlement.IsCastle) { float loyalty = settlement.Town.Loyalty; if (settlement.IsStarving) { float foodChange = settlement.Town.FoodChange; int num = (settlement.Town.Owner.IsStarving && foodChange < -19f) ? ((int)((foodChange + 10f) / 10f)) : 0; explainedNumber.Add((float)num, WangSettlementGarrisonModel._foodShortageText, null); } if (settlement.Town.GarrisonParty != null && ((float)settlement.Town.GarrisonParty.Party.NumberOfHealthyMembers + explainedNumber.ResultNumber) / (float)settlement.Town.GarrisonParty.Party.PartySizeLimit > settlement.Town.GarrisonParty.PaymentRatio) { int num2 = 0; do { num2++; }while (((float)settlement.Town.GarrisonParty.Party.NumberOfHealthyMembers + explainedNumber.ResultNumber - (float)num2) / (float)settlement.Town.GarrisonParty.Party.PartySizeLimit >= settlement.Town.GarrisonParty.PaymentRatio && (float)settlement.Town.GarrisonParty.Party.NumberOfHealthyMembers + explainedNumber.ResultNumber - (float)num2 > 0f && num2 < 20); explainedNumber.Add((float)(-(float)num2), WangSettlementGarrisonModel._paymentIsLess, null); } } WangSettlementGarrisonModel.GetSettlementGarrisonChangeDueToIssues(settlement, ref explainedNumber); return((int)explainedNumber.ResultNumber); }
private int GetEstimatedRelationValue() { ExplainedNumber explainedNumber = new ExplainedNumber((float)GetBaseRelationValueOfCurrentGoldCost(), new StatExplainer(), null); Campaign.Current.Models.DiplomacyModel.GetRelationIncreaseFactor(Hero.MainHero, _clan.Leader, ref explainedNumber); return(MBMath.Floor(explainedNumber.ResultNumber)); }
public static void Postfix( Clan clan, ref ExplainedNumber goldChange, bool applyWithdrawals = false) { goldChange.Add(EntrepreneurModel.TotalPlayerRevenue, new TextObject("Revenue from acres")); }
public static void Postfix(ref float __result, MobileParty party, StatExplainer explainer) { //For now only do hero if (party.LeaderHero == Hero.MainHero) { if (party.Scout != null) { var sk = party.Scout.GetSkillValue(DefaultSkills.Scouting); if (sk > 0) { var mod = 1.0f - ((float)sk / 300.0f); if (mod < 0.1f) { mod = 0.1f; } mod = MBRandom.RandomFloatRanged(mod, 1.0f); var orig = __result; var deduction = (orig - ((__result * mod))) * -1f;; ExplainedNumber en = new ExplainedNumber(__result, explainer); explainer?.Lines.Remove(explainer.Lines.Last()); var textObject = new TextObject("{FIRST_NAME} scouted for food.", null); textObject.SetTextVariable("FIRST_NAME", party.Scout.FirstName); //textObject.SetTextVariable("REDUCTION_AMOUNT", (orig-__result).ToString()); en.Add(deduction, textObject); __result = en.ResultNumber; } } } }
static bool Prefix(ref float __result, Hero hero) { if (hero == Hero.MainHero || hero.Spouse == Hero.MainHero || hero.Clan.Leader == Hero.MainHero) { float num = 0.0f; if (hero.Spouse != null && hero.Age >= (double)SettingClass.Instance.MinPregnantAge && hero.Age <= (double)SettingClass.Instance.MaxPregnantAge && SettingClass.Instance.DailyPregnancyChanceOfTheMC - 0.0f >= 0.09f) { ExplainedNumber bonuses = new ExplainedNumber(1f, new StringBuilder("The chance of hero being pregnant")); PerkHelper.AddPerkBonusForCharacter(DefaultPerks.Medicine.PerfectHealth, hero.Clan.Leader.CharacterObject, ref bonuses); num = (float)bonuses.ResultNumber * 0.001f + SettingClass.Instance.DailyPregnancyChanceOfTheMC; if (num >= 1.0f) { num = 1.0f; } } __result = num; return(false); } return(true); }
static void CalculateLearningLimitPostfix(ref ExplainedNumber __result) { float newLearningLimit = __result.ResultNumber * LEARNING_RATE_LIMIT_MULTIPLIER - __result.ResultNumber; __result.AddFactor(newLearningLimit); __result.LimitMax(500); }
public void PatchSpeedDueToFriendiness(ref MobileParty mobileParty, ref ExplainedNumber bonuses, ref Settlement closest_settlement) { if (closest_settlement.MapFaction == null) { // Training field. return; } if (mobileParty.MapFaction == null) { InformationManager.DisplayMessage(new InformationMessage("mobile party faction is null")); return; } if (mobileParty.MapFaction.IsAtWarWith(closest_settlement.MapFaction)) { bonuses.Add(-0.5f, new TextObject("Unfriendly Territory")); PatchSpeedDueToCulture(ref mobileParty, ref bonuses, ref closest_settlement); } if (mobileParty.MapFaction.StringId == closest_settlement.MapFaction.StringId) { bonuses.Add(0.5f, new TextObject("Friendly Territory")); PatchSpeedDueToCulture(ref mobileParty, ref bonuses, ref closest_settlement); } }
public override float CalculateProsperityChange(Town fortification, StatExplainer explanation = null) { var result = base.CalculateProsperityChange(fortification, explanation); if (fortification.Owner.IsStarving || result < 0) { return(result); } var prosperity = fortification.Owner.Settlement.Prosperity; ExplainedNumber explainedNumber = new ExplainedNumber(0f, explanation, null); float foodChange = Campaign.Current.Models.SettlementFoodModel.CalculateTownFoodStocksChange(fortification, null); if (foodChange < -1 && Math.Abs(fortification.FoodStocks / foodChange) < 20 && prosperity < 1000 && result > 1) { explainedNumber.Add(-result, _surplusFoodText); } else if (SettlementSetting.Instance.boostProsperityGrowth > 0) { var factor = SettlementSetting.Instance.boostProsperityGrowth * result > 1 ? result : 1; explainedNumber.Add((float)factor, _surplusFoodText); } var r = result + explainedNumber.ResultNumber; if (prosperity > 11000 && r > 1f) { explainedNumber.Add((int)Math.Sqrt(r) - r, _surplusFoodText); } return(result + explainedNumber.ResultNumber); }
public void PatchSpeedDueToCulture(ref MobileParty mobileParty, ref ExplainedNumber bonuses, ref Settlement closest_settlement) { if (closest_settlement.Culture == null) { // Training field. return; } if (mobileParty.LeaderHero == null) { return; } if (mobileParty.LeaderHero.Culture == null) { InformationManager.DisplayMessage(new InformationMessage("mobile party faction is null")); return; } if (closest_settlement.Culture == mobileParty.Leader.Culture) { bonuses.Add(0.5f, new TextObject("Friendly Culture")); } else { bonuses.Add(-0.5f, new TextObject("Unfriendly Culture")); } }
static bool Prefix(PartyBase party, float renownValueOfBattle, float contributionShare, StatExplainer explanation, ref float __result) { bool patched = false; try { if (party.LeaderHero != null && party.LeaderHero == Hero.MainHero) { ExplainedNumber stat; stat = new ExplainedNumber((renownValueOfBattle * contributionShare) * Settings.Instance.BattleRenownMultiplier, explanation); if (party.IsMobile) { if (party.MobileParty.HasPerk(DefaultPerks.TwoHanded.Notorious)) { PerkHelper.AddPerkBonusForParty(DefaultPerks.TwoHanded.Notorious, party.MobileParty, ref stat); } if (party.MobileParty.HasPerk(DefaultPerks.Charm.ShowYourScars)) { PerkHelper.AddPerkBonusForParty(DefaultPerks.Charm.ShowYourScars, party.MobileParty, ref stat); } } __result = stat.ResultNumber; patched = true; } } catch (Exception ex) { MessageBox.Show($"An error occurred during DefaultBattleRewardModelPatch. Reverting to original behaviour...\n\nException:\n{ex.Message}\n\n{ex.InnerException?.Message}\n\n{ex.InnerException?.InnerException?.Message}"); } return(!patched); }
public static int GetModifiedRelation(this Hero hero, Hero otherHero) { ExplainedNumber relationBetweenHeroes = new ExplainedNumber(CharacterRelationManager.GetHeroRelation(hero, otherHero), null, null); deGetPersonalityEffects(Campaign.Current.Models.DiplomacyModel is DefaultDiplomacyModel defaultDiplomacyModel ? defaultDiplomacyModel : new DefaultDiplomacyModel(), ref relationBetweenHeroes, hero, otherHero); return(MBMath.Round(MBMath.ClampFloat(relationBetweenHeroes.ResultNumber + (RelativesHelper.BloodRelatives(hero, otherHero) ? 30f : 0f), -100f, 100f))); }
static bool Prefix(PartyBase party, float renownValueOfBattle, float contributionShare, StatExplainer explanation, ref float __result) { bool patched = false; try { var battleRenownMultiplier = 1f; if (Settings.Instance.BattleRewardApplyToAI || party.LeaderHero != null && party.LeaderHero == Hero.MainHero) { battleRenownMultiplier = Settings.Instance.BattleRenownMultiplier; } var stat = new ExplainedNumber((renownValueOfBattle * contributionShare) * battleRenownMultiplier, explanation); //TODO:: Implement this the same as native in next game update //if (party.IsMobile && party.MobileParty.HasPerk(DefaultPerks.Charm.ShowYourScars)) //{ // PerkHelper.AddPerkBonusForParty(DefaultPerks.Charm.ShowYourScars, party.MobileParty, ref stat); //} if (party.IsMobile && party.Leader != null && party.Leader.HeroObject != null && party.LeaderHero.GetPerkValue(DefaultPerks.Charm.ShowYourScars)) { PerkHelper.AddPerkBonusForParty(DefaultPerks.Charm.ShowYourScars, party.MobileParty, true, ref stat); } __result = stat.ResultNumber; patched = true; } catch (Exception ex) { MessageBox.Show($"An error occurred during DefaultBattleRewardModelRenownPatch. Reverting to original behaviour...\n\nException:\n{ex.Message}\n\n{ex.InnerException?.Message}\n\n{ex.InnerException?.InnerException?.Message}"); } return(!patched); }
public override float GetEffectivePartyMorale(MobileParty mobileParty, StatExplainer explanation = null) { ExplainedNumber explainedNumber; if (mobileParty.IsMainParty) { explainedNumber = new ExplainedNumber(30f, explanation, (TextObject)null); // Changed from 50f to 30f } else { explainedNumber = new ExplainedNumber(50f, explanation, (TextObject)null); } explainedNumber.Add(mobileParty.RecentEventsMorale, this._recentEventsText); this.GetMoraleEffectsFromSkill(mobileParty, ref explainedNumber); if (mobileParty.Party.IsStarving) { explainedNumber.Add((float)this.GetStarvationMoralePenalty(mobileParty), this._starvationMoraleText); } if ((double)mobileParty.HasUnpaidWages > 0.0) { explainedNumber.Add(mobileParty.HasUnpaidWages * (float)this.GetNoWageMoralePenalty(mobileParty), this._noWageMoraleText); } this.CalculateFoodVarietyMoraleBonus(mobileParty, ref explainedNumber); this.GetPartySizeMoraleEffect(mobileParty, ref explainedNumber); return(explainedNumber.ResultNumber); }
public override float CalculateMilitiaChange(Settlement settlement, StatExplainer explanation = null) { float baseVal = base.CalculateMilitiaChange(settlement, explanation); ExplainedNumber en = new ExplainedNumber(0f, explanation); en.Add(baseVal); try { if (Settings.Instance.SettlementMilitiaBonusEnabled) { if (settlement.IsCastle) { en.Add(Settings.Instance.CastleMilitiaBonus, new TextObject("Recruitment drive")); } if (settlement.IsTown) { en.Add(Settings.Instance.TownMilitiaBonus, new TextObject("Citizen militia")); } } } catch (Exception ex) { MessageBox.Show($"An error occurred in TweakedSettlementMilitiaModule:\n\n{ex.ToStringFull()}"); } return(en.ResultNumber); }
private static void Postfix(Clan clan, ref ExplainedNumber goldChange, bool applyWithdrawals = false) { foreach (var pair in SlaveEstateBehavior.SlaveEstates) { int wage = 0; SlaveEstate slaveEstate = pair.Value; Village village = pair.Key; if (slaveEstate.Guards == null) { slaveEstate.Guards = TroopRoster.CreateDummyTroopRoster(); } else { foreach (TroopRosterElement troop in slaveEstate.Guards) { wage += troop.Number * troop.Character.TroopWage; } } if (wage > 0) { goldChange.Add(-1 * wage, new TextObject("Wage of slave estate guards at " + village.Name.ToString())); } } }