static void Postfix(ref AgingCampaignBehavior __instance, Hero current) { if (!current.IsTemplate && current.IsAlive) { if ((int)current.BirthDay.ElapsedDaysUntilNow == (int)CampaignTime.Years((float)Campaign.Current.Models.AgeModel.HeroComesOfAge).ToDays) { if (current.HeroState != Hero.CharacterStates.Active) { CampaignEventDispatcher dispatcher = GameComponent.CampaignEventDispatcher(); if (null != dispatcher) { ReflectUtils.ReflectMethodAndInvoke("OnHeroComesOfAge", dispatcher, new Object[] { current }); } } } else if ((int)current.BirthDay.ElapsedDaysUntilNow == (int)CampaignTime.Years((float)Campaign.Current.Models.AgeModel.BecomeTeenagerAge).ToDays) { // CampaignEventDispatcher.Instance.OnHeroReachesTeenAge(current); } else if ((int)current.BirthDay.ElapsedDaysUntilNow == (int)CampaignTime.Years((float)Campaign.Current.Models.AgeModel.BecomeChildAge).ToDays) { // CampaignEventDispatcher.Instance.OnHeroGrowsOutOfInfancy(current); } } }
private static bool GetRandomBirthDayForAge(float age, ref CampaignTime __result) { var now = CampaignTime.Now; float birthYear = now.GetYear - age; float randDayOfYear = MBRandom.RandomFloatRanged(1, Main.TimeParam.DayPerYear); if (randDayOfYear > now.GetDayOfYear) { --birthYear; } __result = CampaignTime.Years(birthYear) + CampaignTime.Days(randDayOfYear); return(false); }
// Mercifully, this does something. Although there might be an issue with birthdays causing edited heroes to age up // more often than not, so this needs to be rewritten. // Needs to differentiate if the game is under setup or in progress, but that is something for another update. public static void ResetBirthDayForAge(CharacterObject characterObject, float targetAge, bool randomize = false) { if (characterObject.IsHero == false) { return; } Hero hero = characterObject.HeroObject; if (DCCSettings.Instance == null || DCCSettings.Instance.OverrideAge) { return; } hero.BirthDay = randomize ? HeroHelper.GetRandomBirthDayForAge(targetAge) : CampaignTime.Years((float)(CampaignTime.Now.ToYears - targetAge)); }
private void SetStoryVisibleTimeoutIfNeeded(QuestBase quest) { if (!IsFirstStoryPhase() || !quest.IsSpecialQuest || !quest.IsOngoing) { return; } // set visible timeout to be when vanilla would have (silently) timed // out the quest, minus a day to make very sure the quest doesn't // somehow trigger vanilla's silent timeout too early. CampaignTime newDueTime = FirstPhase.Instance.FirstPhaseStartTime + CampaignTime.Years(FirstPhaseTimeLimitInYears) - CampaignTime.Days(1); if (quest.QuestDueTime != newDueTime) { quest.ChangeQuestDueTime(newDueTime); ShowNotification(new TextObject("{=QuestTimeRemainingUpdated}Quest time remaining was updated."), "event:/ui/notification/quest_update"); } }
public static void FastGrowth(Hero child) { if (!MoreSpouseSetting.Instance.SettingData.ChildrenFastGrowthEnable) { return; } if (null == child) { return; } if (child.Age < MoreSpouseSetting.Instance.SettingData.ChildrenFastGrowtStopGrowUpAge) { int lastAge = (int)child.Age; int circle = MoreSpouseSetting.Instance.SettingData.ChildrenFastGrowthCycleInDays; int days = (int)CampaignTime.Now.ToDays; if (days % circle == 0) { CampaignTime newBirthDay = CampaignTime.Years((float)CampaignTime.Now.ToYears - (float)(lastAge + 1)); child.SetBirthDay(newBirthDay); if (Hero.MainHero.Children.Contains(child)) { InformationManager.DisplayMessage(new InformationMessage(child.Name.ToString() + " AGE =" + child.Age)); } } int comeOfAgeDays = (int)CampaignTime.Years((float)Campaign.Current.Models.AgeModel.HeroComesOfAge).ToDays; days = (int)child.BirthDay.ElapsedDaysUntilNow; if (days == comeOfAgeDays) { if (child == Hero.MainHero || Hero.MainHero.Children.Contains(child) || (null != Hero.MainHero.Father && Hero.MainHero.Father.Children.Contains(child))) { TextObject textObject = GameTexts.FindText("suems_children_grow_up_to_hero_age", null); StringHelpers.SetCharacterProperties("SUE_HERO", child.CharacterObject, null, textObject); InformationManager.AddQuickInformation(textObject, 0, null, "event:/ui/notification/quest_finished"); } } } }
public void Import(Hero character, bool updateAppearance) { string filename = GetSaveName(character); bool isPlayer = Helper.CharacterHasTraitDeveloper(character); int? year = null, season = null, day = null, hour = null; long? remaining = null; int? mercy = null, valor = null, honor = null, generosity = null, calculating = null; string culture = null; foreach (var keyValuePair in Helper.ReadFile(filename)) { var key = keyValuePair.Key; var value = keyValuePair.Value; // Parse try { // Birthday if (key.Equals("Year")) { year = Convert.ToInt32(value); } else if (key.Equals("Season")) { season = Convert.ToInt32(value); } else if (key.Equals("Day")) { day = Convert.ToInt32(value); } else if (key.Equals("Hour")) { hour = Convert.ToInt32(value); } else if (key.Equals("RemainingTicks")) { remaining = Convert.ToInt64(value); } // Culture else if (key.Equals("Culture")) { culture = value; } // Traits // if the character is the player (who has a trait developer), read the XP else if (isPlayer) { if (key.Equals("MercyXP")) { mercy = Convert.ToInt32(value); } else if (key.Equals("ValorXP")) { valor = Convert.ToInt32(value); } else if (key.Equals("HonorXP")) { honor = Convert.ToInt32(value); } else if (key.Equals("GenerosityXP")) { generosity = Convert.ToInt32(value); } else if (key.Equals("CalculatingXP")) { calculating = Convert.ToInt32(value); } } else { // The character doesn't not have a trait developer (non-player). Directly read the traits. if (key.Equals("Mercy")) { mercy = Convert.ToInt32(value); } else if (key.Equals("Valor")) { valor = Convert.ToInt32(value); } else if (key.Equals("Honor")) { honor = Convert.ToInt32(value); } else if (key.Equals("Generosity")) { generosity = Convert.ToInt32(value); } else if (key.Equals("Calculating")) { calculating = Convert.ToInt32(value); } } } catch { Helper.ShowAndLog($"Failed to parse {key} for {character}"); return; } } bool readBirthdaySuccess = false; bool readCultureSuccess = false; bool readTraitsSuccess = false; // Read Birthday if (year.HasValue && season.HasValue && day.HasValue && hour.HasValue && remaining.HasValue) { var b = CampaignTime.Years(year.Value) + CampaignTime.Seasons(season.Value) + CampaignTime.Days(day.Value) + CampaignTime.Hours(hour.Value); long newTicks = b.GetTicks(); newTicks += remaining.Value; var newBirthDay = Helper.CreateCampaignTime(newTicks); character.BirthDay = newBirthDay; // Update character model if (updateAppearance) { var dps = character.BodyProperties.DynamicProperties; dps.Age = character.Age; typeof(BodyProperties) .GetField("_dynamicBodyProperties", BindingFlags.Instance | BindingFlags.NonPublic) .SetValue(character.BodyProperties, dps); } readBirthdaySuccess = true; } // Read Culture if (culture != null) { CultureCode c; if (Enum.TryParse(culture, true, out c) == false) { c = CultureCode.Invalid; } if (c != CultureCode.Invalid) { var heroOfThisCulture = Hero.FindFirst((h) => h.Culture.GetCultureCode() == c); if (heroOfThisCulture != null) { character.CharacterObject.Culture = heroOfThisCulture.CharacterObject.Culture; if (character.Clan.Leader == character) { character.Clan.Culture = character.CharacterObject.Culture; // Clan culture changes too } readCultureSuccess = true; } else { //Helper.ShowAndLog($"{character.Name}'s culture not imported: Can't set to culture \"{c.ToString()}\"!"); } } else { //Helper.ShowAndLog($"{character.Name}'s culture not imported: Invalid culture \"{culture}\"!"); } } else { //Helper.ShowAndLog($"{character.Name}'s culture not imported: culture value is empty!"); } // Read Traits if (mercy.HasValue && valor.HasValue && honor.HasValue && generosity.HasValue && calculating.HasValue) { if (isPlayer) { var ptd = Campaign.Current.PlayerTraitDeveloper; var deltaMercy = mercy.Value - ptd.GetPropertyValue(DefaultTraits.Mercy); var deltaValor = valor.Value - ptd.GetPropertyValue(DefaultTraits.Valor); var deltaHonor = honor.Value - ptd.GetPropertyValue(DefaultTraits.Honor); var deltaGenerosity = generosity.Value - ptd.GetPropertyValue(DefaultTraits.Generosity); var deltaCalculating = calculating.Value - ptd.GetPropertyValue(DefaultTraits.Calculating); if (deltaMercy != 0) { ptd.AddTraitXp(DefaultTraits.Mercy, deltaMercy); } if (deltaValor != 0) { ptd.AddTraitXp(DefaultTraits.Valor, deltaValor); } if (deltaHonor != 0) { ptd.AddTraitXp(DefaultTraits.Honor, deltaHonor); } if (deltaGenerosity != 0) { ptd.AddTraitXp(DefaultTraits.Generosity, deltaGenerosity); } if (deltaCalculating != 0) { ptd.AddTraitXp(DefaultTraits.Calculating, deltaCalculating); } } else { // It will clamp to min max value in SetTraitLevel() character.SetTraitLevel(DefaultTraits.Mercy, mercy.Value); character.SetTraitLevel(DefaultTraits.Valor, valor.Value); character.SetTraitLevel(DefaultTraits.Honor, honor.Value); character.SetTraitLevel(DefaultTraits.Generosity, generosity.Value); character.SetTraitLevel(DefaultTraits.Calculating, calculating.Value); } readTraitsSuccess = true; } string msg = $"Imported {character.Name}'s "; if (readBirthdaySuccess && readCultureSuccess && readTraitsSuccess) { msg += "birthday, culture and traits."; } else if (readBirthdaySuccess && readCultureSuccess && !readTraitsSuccess) { msg += "birthday and culture."; } else if (readBirthdaySuccess && !readCultureSuccess && readTraitsSuccess) { msg += "birthday and traits."; } else if (!readBirthdaySuccess && readCultureSuccess && readTraitsSuccess) { msg += "culture and traits."; } else if (readBirthdaySuccess && !readCultureSuccess && !readTraitsSuccess) { msg += "birthday."; } else if (!readBirthdaySuccess && readCultureSuccess && !readTraitsSuccess) { msg += "culture."; } else if (!readBirthdaySuccess && !readCultureSuccess && readTraitsSuccess) { msg += "traits."; } else { msg = null; } if (msg != null) { Helper.ShowAndLog(msg + $" Appearance {(updateAppearance ? string.Empty : "not")} updated.", new Color(0, 1, 0)); } }
public void Export(Hero character) { StringBuilder sb = new StringBuilder(); sb.AppendLine("//Lines started with // are comments."); sb.AppendLine(string.Empty); sb.AppendLine("//Readme:"); sb.AppendLine("//Season ranges from 0 to 3. Spring is 0 and Autumn is 2, for example."); sb.AppendLine("//Day starts with 0. So if your birthday is Summer 11, Day should be 10."); sb.AppendLine("//Use the field \"FormattedBirthday\" to check what your birthday is, after export."); sb.AppendLine("//If you want to modify RemainingTicks, remember there are 10000 ticks per game second."); sb.AppendLine("//Traits range from -2 to 2."); sb.AppendLine(Environment.NewLine); sb.AppendLine($"//{character.Name}'s birthday:"); sb.AppendLine($"Year={character.BirthDay.GetYear}"); sb.AppendLine($"Season={character.BirthDay.GetSeasonOfYear}"); sb.AppendLine($"Day={character.BirthDay.GetDayOfSeason}"); sb.AppendLine($"Hour={character.BirthDay.GetHourOfDay}"); // Get remaining ticks so we don't lose any milliseconds. var b = CampaignTime.Years(character.BirthDay.GetYear) + CampaignTime.Seasons(character.BirthDay.GetSeasonOfYear) + CampaignTime.Days(character.BirthDay.GetDayOfSeason) + CampaignTime.Hours(character.BirthDay.GetHourOfDay); sb.AppendLine($"RemainingTicks={(character.BirthDay - b).GetTicks()}"); sb.AppendLine(Environment.NewLine); // Culture sb.AppendLine("//Culture:"); sb.AppendLine($"Culture={character.Culture.GetName()}"); sb.AppendLine(Environment.NewLine); // Is this character the player? bool isPlayer = Helper.CharacterHasTraitDeveloper(character); // Traits string traitPromptStr = isPlayer ? " (Read only. Modify Trait XP to change traits)" : string.Empty; sb.AppendLine($"//Traits{traitPromptStr}:"); var traits = character.GetHeroTraits(); sb.AppendLine($"Mercy={traits.Mercy}"); sb.AppendLine($"Valor={traits.Valor}"); sb.AppendLine($"Honor={traits.Honor}"); sb.AppendLine($"Generosity={traits.Generosity}"); sb.AppendLine($"Calculating={traits.Calculating}"); sb.AppendLine(Environment.NewLine); // Trait XP if (isPlayer) { sb.AppendLine("//Trait XP:"); sb.AppendLine($"MercyXP={Campaign.Current.PlayerTraitDeveloper.GetPropertyValue(DefaultTraits.Mercy)}"); sb.AppendLine($"ValorXP={Campaign.Current.PlayerTraitDeveloper.GetPropertyValue(DefaultTraits.Valor)}"); sb.AppendLine($"HonorXP={Campaign.Current.PlayerTraitDeveloper.GetPropertyValue(DefaultTraits.Honor)}"); sb.AppendLine($"GenerosityXP={Campaign.Current.PlayerTraitDeveloper.GetPropertyValue(DefaultTraits.Generosity)}"); sb.AppendLine($"CalculatingXP={Campaign.Current.PlayerTraitDeveloper.GetPropertyValue(DefaultTraits.Calculating)}"); sb.AppendLine(Environment.NewLine); } // Output. sb.AppendLine("//Don't modify this field as it will not be read."); sb.AppendLine($"FormattedBirthday={character.BirthDay.ToString()}"); for (int i = DefaultTraits.Mercy.MinValue; i <= DefaultTraits.Mercy.MaxValue; ++i) { sb.AppendLine($"MercyXPRequired{i}={Campaign.Current.Models.CharacterDevelopmentModel.GetTraitXpRequiredForTraitLevel(DefaultTraits.Mercy, i)}"); } for (int i = DefaultTraits.Valor.MinValue; i <= DefaultTraits.Valor.MaxValue; ++i) { sb.AppendLine($"ValorXPRequired{i}={Campaign.Current.Models.CharacterDevelopmentModel.GetTraitXpRequiredForTraitLevel(DefaultTraits.Valor, i)}"); } for (int i = DefaultTraits.Honor.MinValue; i <= DefaultTraits.Honor.MaxValue; ++i) { sb.AppendLine($"HonorXPRequired{i}={Campaign.Current.Models.CharacterDevelopmentModel.GetTraitXpRequiredForTraitLevel(DefaultTraits.Honor, i)}"); } for (int i = DefaultTraits.Generosity.MinValue; i <= DefaultTraits.Generosity.MaxValue; ++i) { sb.AppendLine($"GenerosityXPRequired{i}={Campaign.Current.Models.CharacterDevelopmentModel.GetTraitXpRequiredForTraitLevel(DefaultTraits.Generosity, i)}"); } for (int i = DefaultTraits.Calculating.MinValue; i <= DefaultTraits.Calculating.MaxValue; ++i) { sb.AppendLine($"CalculatingXPRequired{i}={Campaign.Current.Models.CharacterDevelopmentModel.GetTraitXpRequiredForTraitLevel(DefaultTraits.Calculating, i)}"); } File.WriteAllText(this.GetSaveName(character), sb.ToString()); Helper.ShowAndLog($"Exported {character.Name}'s birthday, culture and traits."); }
public static Hero?SpawnNoble(Clan clan, int ageMin, int ageMax = -1, bool isFemale = false) { var templateSeq = Hero.All.Where(h => h.IsNoble && h.CharacterObject.Occupation == Occupation.Lord && (isFemale && h.IsFemale || !isFemale && !h.IsFemale)); var template = templateSeq.Where(h => h.Culture == clan.Culture).GetRandomElement() ?? templateSeq.GetRandomElement(); if (template is null) { return(null); } ageMax = ageMax <= ageMin ? -1 : ageMax; int age = ageMax < 0 ? ageMin : MBRandom.RandomInt(ageMin, ageMax); var hero = HeroCreator.CreateSpecialHero(template.CharacterObject, bornSettlement: clan.HomeSettlement, faction: clan, supporterOfClan: clan, age: age); // Our own, exact age assignment: // FIXME: Will need update in e1.5.5 hero.BirthDay = CampaignTime.Now - CampaignTime.Years(age); hero.CharacterObject.Age = hero.Age; // Get it into the BasicCharacterObject.Age property as well // Attributes for (var attr = CharacterAttributesEnum.First; attr < CharacterAttributesEnum.End; ++attr) { hero.SetAttributeValue(attr, MBRandom.RandomInt(6, 7)); } // Skills: levels & focus point minimums foreach (var skillObj in Game.Current.SkillList) { var curSkill = hero.GetSkillValue(skillObj); var curFocus = hero.HeroDeveloper.GetFocus(skillObj); int minSkill = MBRandom.RandomInt(75, 110); int minFocus = minSkill > 95 ? 4 : MBRandom.RandomInt(2, 3); if (curSkill < minSkill) { hero.HeroDeveloper.ChangeSkillLevel(skillObj, minSkill - curSkill, false); } if (curFocus < minFocus) { hero.HeroDeveloper.AddFocus(skillObj, minFocus - curFocus, false); } } // TODO: // - morph StaticBodyParameters a bit, in a way that doesn't result in ogres // - equip them with a culture-appropriate horse and horse harness // - ensure they have some decent equipment (maybe pick a template soldier from each culture) hero.Name = hero.FirstName; hero.IsNoble = true; hero.ChangeState(Hero.CharacterStates.Active); CampaignEventDispatcher.Instance.OnHeroCreated(hero, false); return(hero); }
//GetGeneralSupportScore internal - per decision type private float GetGeneralSupportScore(Clan clan, MakePeaceKingdomDecision makePeaceDecision, DecisionOutcome possibleOutcome) { int valueForClan = new PeaceBarterable(makePeaceDecision.Kingdom, makePeaceDecision.FactionToMakePeaceWith, CampaignTime.Years(1f)).GetValueForFaction(clan) - Campaign.Current.Models.DiplomacyModel.GetValueOfDailyTribute(makePeaceDecision.DailyTributeToBePaid); float situationalFactorValue = 0; if (Settings.Instance.PeaceSupportCalculationMethod.SelectedValue.EnumValue.HasFlag(PeaceAndWarConsideration.SituationalFactor)) { situationalFactorValue = ApplySituationalFactor(makePeaceDecision, ref valueForClan); } return(FieldAccessHelper.ShouldPeaceBeDeclaredByRef(possibleOutcome) ? valueForClan * Campaign.Current.Models.DiplomacyModel.DenarsToInfluence() + situationalFactorValue : -valueForClan *Campaign.Current.Models.DiplomacyModel.DenarsToInfluence() - situationalFactorValue); }
private static void barter_for_peace_consequence_delegate(DialogueParams param) // looks like a lot, I just stole most of this from tw >_> { BarterManager instance = BarterManager.Instance; Hero mainHero = Hero.MainHero; Hero oneToOneConversationHero = Hero.OneToOneConversationHero; PartyBase mainParty = PartyBase.MainParty; MobileParty conversationParty = MobileParty.ConversationParty; PartyBase otherParty = (conversationParty != null) ? conversationParty.Party : null; Hero beneficiaryOfOtherHero = null; BarterManager.BarterContextInitializer initContext = new BarterManager.BarterContextInitializer(BarterManager.Instance.InitializeMakePeaceBarterContext); int persuasionCostReduction = 0; bool isAIBarter = false; Barterable[] array = new Barterable[1]; int num = 0; Hero originalOwner = conversationParty.MapFaction.Leader; Hero mainHero2 = Hero.MainHero; MobileParty conversationParty2 = MobileParty.ConversationParty; array[num] = new PeaceBarterable(originalOwner, conversationParty.MapFaction, mainHero.MapFaction, CampaignTime.Years(1f)); instance.StartBarterOffer(mainHero, oneToOneConversationHero, mainParty, otherParty, beneficiaryOfOtherHero, initContext, persuasionCostReduction, isAIBarter, array); }
public static void DetermineSupport(MakePeaceKingdomDecision __instance, ref float __result, Clan clan, DecisionOutcome possibleOutcome) { var test1 = new PeaceBarterable(__instance.Kingdom, __instance.FactionToMakePeaceWith, CampaignTime.Years(1f)).GetValueForFaction(clan); //InformationManager.DisplayMessage(new InformationMessage(__instance.FactionToMakePeaceWith.Name.ToString() + ":" + test1.ToString())); var shouldPeaceBeDeclared = (bool)possibleOutcome.GetType().GetField("ShouldPeaceBeDeclared", BindingFlags.Instance | BindingFlags.Public).GetValue(possibleOutcome); if (DiplomacySetting.Instance.EnableMakePeaceStrategyPlus) { var atWars = (from x in clan.Kingdom.Stances where x.IsAtWar && x.Faction1.IsKingdomFaction && x.Faction2.IsKingdomFaction select x).ToArray <StanceLink>(); //var plus = 2 * atWars.Length * (float)(new PeaceBarterable(__instance.Kingdom, __instance.FactionToMakePeaceWith, CampaignTime.Years(1f)).GetValueForFaction(clan)) * Campaign.Current.Models.DiplomacyModel.DenarsToInfluence(); var plus = 1f; var settlementsOccupyed = DiplomacySetting.GetFactionSettlementOccupyedByFaction(clan.MapFaction, __instance.FactionToMakePeaceWith).Sum(a => a.IsCastle ? 2 : 3); plus *= settlementsOccupyed == 0 ? 0f : (float)Math.Sqrt(settlementsOccupyed); StanceLink stanceWith = clan.MapFaction.GetStanceWith(__instance.FactionToMakePeaceWith); var toDays = stanceWith.WarStartDate.ElapsedDaysUntilNow; //兼容旧档 if (toDays > 2000) { Traverse.Create(stanceWith).Property("WarStartDate").SetValue(CampaignTime.Now); toDays = stanceWith.WarStartDate.ElapsedDaysUntilNow; } var daysFactor = Math.Min(9, toDays < 20 ? 1 : toDays / 20f); var factor = Math.Max(0, daysFactor - plus); var clanMercy = clan.Leader.GetTraitLevel(DefaultTraits.Mercy) * 20; if (shouldPeaceBeDeclared) { __result += Math.Abs(__result) / 10 * (factor) + clanMercy; } else { // __result -= Math.Abs(__result) / 10 * (resultFactor) - clanMercy; } } if (__instance.ProposerClan == Clan.PlayerClan && DiplomacySetting.Instance.RelationEffectOfMakePeaceDecision > 0 && __result >= 0) { var relation = CharacterRelationManager.GetHeroRelation(Hero.MainHero, clan.Leader); relation = relation > 0 ? relation : 0; if (shouldPeaceBeDeclared) { __result += Math.Abs(__result) * DiplomacySetting.Instance.RelationEffectOfMakePeaceDecision * relation / 100f; } else { __result -= Math.Abs(__result) * DiplomacySetting.Instance.RelationEffectOfMakePeaceDecision / 10 * relation / 100f; } } }