// MapEventSide.ApplySimulationDamageToSelectedTroop public static bool ApplySimulationDamageToSelectedTroop(MapEventSide side, CharacterObject strikedTroop, PartyBase strikedTroopParty, UniqueTroopDescriptor strikedTroopDescriptor, int selectedSimulationTroopIndex, List <UniqueTroopDescriptor> strikedTroopList, PartyAttackComposition attack, DamageTypes damageType, PartyBase strikerParty, MapEventState mapEventState, IBattleObserver battleObserver, out float damage) { bool IsFinishingStrike = mapEventState.ApplyDamageToPartyTroop(attack, strikedTroopParty, strikedTroop, out damage); if (IsFinishingStrike) { if (strikedTroop.IsHero) { battleObserver?.TroopNumberChanged(side.MissionSide, (IBattleCombatant)strikedTroopParty, (BasicCharacterObject)strikedTroop, -1, 0, 1, 0, 0, 0); } else { float survivalChance = Campaign.Current.Models.PartyHealingModel.GetSurvivalChance(strikedTroopParty, strikedTroop, damageType, strikerParty); if (MBRandom.RandomFloat < survivalChance) { side.OnTroopWounded(strikedTroopDescriptor); battleObserver?.TroopNumberChanged(side.MissionSide, (IBattleCombatant)strikedTroopParty, (BasicCharacterObject)strikedTroop, -1, 0, 1, 0, 0, 0); if (strikedTroopParty.MobileParty != null) { SkillLevelingManager.OnSurgeryApplied(strikedTroopParty.MobileParty, 1f); } } else { side.OnTroopKilled(strikedTroopDescriptor); battleObserver?.TroopNumberChanged(side.MissionSide, (IBattleCombatant)strikedTroopParty, (BasicCharacterObject)strikedTroop, -1, 1, 0, 0, 0, 0); if (strikedTroopParty.MobileParty != null) { SkillLevelingManager.OnSurgeryApplied(strikedTroopParty.MobileParty, 0.5f); } } } // side.RemoveSelectedTroopFromSimulationList(); RemoveSelectedTroopFromSimulationList(side, selectedSimulationTroopIndex, strikedTroopList); } return(IsFinishingStrike); }
public override void OnScoreHit(Agent affectedAgent, Agent affectorAgent, int affectorWeaponKind, bool isBlocked, float damage, float movementSpeedDamageModifier, float hitDistance, AgentAttackType attackType, float shotDifficulty, int weaponCurrentUsageIndex) { try { //Check to see if the affector is a hero if (affectedAgent == null || affectedAgent.Character == null || affectorAgent == null || affectorAgent.Character == null || !affectorAgent.IsHero) { return; } Hero affectorHero = ((CharacterObject)affectorAgent.Character).HeroObject; //If the hero is not the player or in the player's party, don't do anything if (affectorHero != null && (affectorHero == Hero.MainHero || affectorHero.PartyBelongedTo != null && affectorHero.PartyBelongedTo == Hero.MainHero.PartyBelongedTo)) { Hero captainHero = null; Hero commanderHero = null; //If the affector is the player's companion, set the commander and captain as the player. if (affectorHero != Hero.MainHero) { CharacterObject leaderCharacter = (CharacterObject)affectorAgent.Team.Leader.Character; if (leaderCharacter.HeroObject == Hero.MainHero) { captainHero = Hero.MainHero; commanderHero = Hero.MainHero; } } float hitPointRatio = (Math.Min(damage, affectedAgent.HealthLimit) / affectedAgent.HealthLimit) * 0.5f; bool isTeamKill = affectorAgent.Team == affectedAgent.Team; bool isFatal = affectedAgent.Health <= 0; SkillLevelingManager.OnCombatHit(affectorAgent.Character as CharacterObject, affectedAgent.Character as CharacterObject, captainHero, commanderHero, movementSpeedDamageModifier, shotDifficulty, affectorWeaponKind, hitPointRatio, false, affectorAgent.HasMount, isTeamKill, false, weaponCurrentUsageIndex, damage, isFatal); //MessageBox.Show($"Did this!\nAffector:{affectorAgent.Character.Name}\nAffected:{affectedAgent.Character.Name}"); } } catch (Exception ex) { MessageBox.Show($"An error occurred during Tournament experience logic:\n\n{ex.ToStringFull()}"); } }
public override void OnScoreHit(Agent affectedAgent, Agent affectorAgent, int affectorWeaponKind, bool isBlocked, float damage, float movementSpeedDamageModifier, float hitDistance, AgentAttackType attackType, float shotDifficulty, int weaponCurrentUsageIndex) { try { Hero affectorHero; if (!IsValidAffected(affectedAgent) || !IsValidAffector(affectorAgent, out affectorHero)) { return; } if (affectorHero != null) { Hero captainHero = null; Hero commanderHero = null; //If the affector is the player's companion, set the commander and captain as the player. if (affectorHero != Hero.MainHero) { CharacterObject leaderCharacter = (CharacterObject)affectorAgent.Team.Leader.Character; if (leaderCharacter.HeroObject == Hero.MainHero) { captainHero = Hero.MainHero; commanderHero = Hero.MainHero; } } float hitPointRatio = (Math.Min(damage, affectedAgent.HealthLimit) / affectedAgent.HealthLimit) * 0.5f; bool isTeamKill = affectorAgent.Team == affectedAgent.Team; bool isFatal = affectedAgent.Health <= 0; //MessageBox.Show($"Giving experience to {affectorAgent.Character.Name} in tournament.\nAffected:{affectedAgent.Character.Name}\nCaptain: {captainHero?.Name?.ToString()}"); SkillLevelingManager.OnCombatHit(affectorAgent.Character as CharacterObject, affectedAgent.Character as CharacterObject, captainHero, commanderHero, movementSpeedDamageModifier, shotDifficulty, affectorWeaponKind, hitPointRatio, false, affectorAgent.HasMount, isTeamKill, false, weaponCurrentUsageIndex, damage, isFatal); } } catch (Exception ex) { MessageBox.Show($"An error occurred during Tournament experience logic:\n\n{ex.ToStringFull()}"); } }
// TODO: track total cost, and only upgrade if player can afford X number of this upgrade to prevent spending all their money. public static void UpgradeParty(PartyBase party) { var memberRoster = party.MemberRoster; var troopUpgradeMetadataCollection = new List <TroopUpgradeMetadata>(); for (var memberIndex = 0; memberIndex < memberRoster.Count; ++memberIndex) { var elementCopyAtIndex = memberRoster.GetElementCopyAtIndex(memberIndex); if (!elementCopyAtIndex.HasHigherTierToUpgradeTo()) { continue; } var upgradeXpCostPerUnit = elementCopyAtIndex.Character.UpgradeXpCost; var totalUnitsReadyToUpgradeInElement = elementCopyAtIndex.NumberReadyToUpgrade; for (var upgradeTargetIndex = 0; upgradeTargetIndex < elementCopyAtIndex.Character.UpgradeTargets.Length; ++upgradeTargetIndex) { var totalUnitsToUpgradeInElement = totalUnitsReadyToUpgradeInElement; var upgradeTarget = elementCopyAtIndex.Character.UpgradeTargets[upgradeTargetIndex]; // the higher tier unit type to upgrade to var costToUpgradeToHigherTierPerUnit = elementCopyAtIndex.Character.UpgradeCost(party, upgradeTargetIndex); var totalCostToUpgradeToHigherTier = totalUnitsToUpgradeInElement * costToUpgradeToHigherTierPerUnit; if (party.LeaderHero != null && costToUpgradeToHigherTierPerUnit != 0 && totalCostToUpgradeToHigherTier > party.LeaderHero.Gold) { totalUnitsToUpgradeInElement = party.LeaderHero.Gold / costToUpgradeToHigherTierPerUnit; } var canUpgrade = true; if (elementCopyAtIndex.Character.UpgradeTargets[upgradeTargetIndex].UpgradeRequiresItemFromCategory != null) { canUpgrade = false; var totalItemsAvailableToSupplyTroopUpgrade = 0; foreach (var itemRosterElement in party.ItemRoster) { if (itemRosterElement.EquipmentElement.Item.ItemCategory == upgradeTarget.UpgradeRequiresItemFromCategory) { totalItemsAvailableToSupplyTroopUpgrade += itemRosterElement.Amount; canUpgrade = true; if (totalItemsAvailableToSupplyTroopUpgrade >= totalUnitsToUpgradeInElement) { break; } } } if (canUpgrade) { totalUnitsToUpgradeInElement = Math.Min(totalItemsAvailableToSupplyTroopUpgrade, totalUnitsToUpgradeInElement); } } if (party.Culture.IsBandit) { canUpgrade = elementCopyAtIndex.Character.UpgradeTargets[upgradeTargetIndex].Culture.IsBandit; } if (canUpgrade && totalUnitsToUpgradeInElement > 0) { troopUpgradeMetadataCollection.Add( new TroopUpgradeMetadata( memberIndex, elementCopyAtIndex.Character.UpgradeTargets[upgradeTargetIndex], totalUnitsToUpgradeInElement, costToUpgradeToHigherTierPerUnit ) ); } } if (troopUpgradeMetadataCollection.Any()) { var randomElement = troopUpgradeMetadataCollection.GetRandomElement(); var upgradedTierCharacterObject = randomElement.CharacterUpgradeTarget; var totalUnitsToUpgradeInElement = randomElement.TotalUnitsToUpgradeInElement; var costToUpgradeToHigherTierPerUnit = randomElement.CostToUpgradeToHigherTierPerUnit; var totalUpgradeXpCost = upgradeXpCostPerUnit * totalUnitsToUpgradeInElement; memberRoster.SetElementXp(memberIndex, memberRoster.GetElementXp(memberIndex) - totalUpgradeXpCost); memberRoster.AddToCounts(elementCopyAtIndex.Character, -totalUnitsToUpgradeInElement); memberRoster.AddToCounts(upgradedTierCharacterObject, totalUnitsToUpgradeInElement); if (upgradedTierCharacterObject.UpgradeRequiresItemFromCategory != null) { var newTotalUnitsToUpgradeInElement = totalUnitsToUpgradeInElement; foreach (var itemRosterElement in party.ItemRoster) { if (itemRosterElement.EquipmentElement.Item.ItemCategory == upgradedTierCharacterObject.UpgradeRequiresItemFromCategory) { var totalUnitsToUpgradeInElementDueToItemRequirements = Math.Min(newTotalUnitsToUpgradeInElement, itemRosterElement.Amount); party.ItemRoster.AddToCounts(itemRosterElement.EquipmentElement.Item, -totalUnitsToUpgradeInElementDueToItemRequirements); newTotalUnitsToUpgradeInElement -= totalUnitsToUpgradeInElementDueToItemRequirements; if (newTotalUnitsToUpgradeInElement == 0) { break; } } } } var totalCostToUpgradeUnitsInElement = costToUpgradeToHigherTierPerUnit * totalUnitsToUpgradeInElement; if (party.Owner.Gold < totalCostToUpgradeUnitsInElement) { totalUnitsToUpgradeInElement = party.Owner.Gold / costToUpgradeToHigherTierPerUnit; } if (totalUnitsToUpgradeInElement > 0) { if (party.Owner != null) { SkillLevelingManager.OnUpgradeTroops(party, upgradedTierCharacterObject, totalUnitsToUpgradeInElement); GiveGoldAction.ApplyBetweenCharacters(party.Owner, null, totalCostToUpgradeUnitsInElement, true); } else if (party.LeaderHero != null) { SkillLevelingManager.OnUpgradeTroops(party, upgradedTierCharacterObject, totalUnitsToUpgradeInElement); GiveGoldAction.ApplyBetweenCharacters(party.LeaderHero, null, totalCostToUpgradeUnitsInElement, true); } } } } }
public static void UpgradeReadyTroops(PartyBase party) { var memberRoster = party.MemberRoster; var troopUpgradeModel = Campaign.Current.Models.PartyTroopUpgradeModel; var cavalryRatioAtParty = party.MobileParty == null || party.MobileParty.IsGarrison || party.MobileParty.IsMilitia || party.MobileParty.IsVillager ? 1f : party.NumberOfMenWithHorse / (party.NumberOfAllMembers + 0.1f); for (var index1 = 0; index1 < memberRoster.Count; ++index1) { var elementCopyAtIndex = memberRoster.GetElementCopyAtIndex(index1); if (troopUpgradeModel.IsTroopUpgradeable(party, elementCopyAtIndex.Character)) { var characterObjects = new List <Tuple <CharacterObject, int, int> >(); var numberReadyToUpgrade = elementCopyAtIndex.NumberReadyToUpgrade; var upgradeXpCost = elementCopyAtIndex.Character.UpgradeXpCost; if (numberReadyToUpgrade > elementCopyAtIndex.Number - elementCopyAtIndex.WoundedNumber) { numberReadyToUpgrade = elementCopyAtIndex.Number - elementCopyAtIndex.WoundedNumber; } if (numberReadyToUpgrade > 0) { for (var index2 = 0; index2 < elementCopyAtIndex.Character.UpgradeTargets.Length; ++index2) { var upgradeTarget = elementCopyAtIndex.Character.UpgradeTargets[index2]; var upgradeGoldCost = elementCopyAtIndex.Character.UpgradeCost(party, index2); if (party.LeaderHero != null && upgradeGoldCost != 0 && numberReadyToUpgrade * upgradeGoldCost > party.LeaderHero.Gold) { numberReadyToUpgrade = party.LeaderHero.Gold / upgradeGoldCost; } if (party.Owner != null && elementCopyAtIndex.Character.UpgradeTargets[index2].UpgradeRequiresItemFromCategory != null) { var flag = false; var itemCount = 0; foreach (var itemRosterElement in party.ItemRoster) { if (itemRosterElement.EquipmentElement.Item.ItemCategory == upgradeTarget.UpgradeRequiresItemFromCategory) { itemCount += itemRosterElement.Amount; flag = true; if (itemCount >= numberReadyToUpgrade) { break; } } } if (flag) { numberReadyToUpgrade = Math.Min(itemCount, numberReadyToUpgrade); } } //if (party.Culture.IsBandit) // flag = elementCopyAtIndex.Character.UpgradeTargets[index2].Culture.IsBandit; //if (elementCopyAtIndex.Character.Occupation == Occupation.Bandit) // flag = troopUpgradeModel.CanPartyUpgradeTroopToTarget(party, elementCopyAtIndex.Character, elementCopyAtIndex.Character.UpgradeTargets[index2]); if (numberReadyToUpgrade > 0) { characterObjects.Add(new Tuple <CharacterObject, int, int>(elementCopyAtIndex.Character.UpgradeTargets[index2], numberReadyToUpgrade, upgradeGoldCost)); } } if (characterObjects.Count > 0) { var character = characterObjects.GetRandomElement(); if (party.IsMobile && party.LeaderHero != null && cavalryRatioAtParty < 0.360000014305115) { var num2 = 0f; foreach (var tuple2 in characterObjects) { num2 += CalculateUpgradeChance(tuple2.Item1, 1f, cavalryRatioAtParty); } var num3 = num2 * MBRandom.RandomFloat; foreach (var tuple2 in characterObjects) { num3 -= CalculateUpgradeChance(tuple2.Item1, 1f, cavalryRatioAtParty); if (num3 < 0.0) { character = tuple2; break; } } } var characterObject = character.Item1; var numberToUpgrade = character.Item2; var upgradeGoldCost = character.Item3; var totalXpCost = upgradeXpCost * numberToUpgrade; memberRoster.SetElementXp(index1, memberRoster.GetElementXp(index1) - totalXpCost); memberRoster.AddToCounts(elementCopyAtIndex.Character, -numberToUpgrade); memberRoster.AddToCounts(characterObject, numberToUpgrade); var gold = party.Owner?.Gold; var totalGoldCost = upgradeGoldCost * numberToUpgrade; if ((gold.GetValueOrDefault() < totalGoldCost) & gold.HasValue) { numberToUpgrade = party.Owner.Gold / upgradeGoldCost; } if (numberToUpgrade > 0) { if (party.Owner != null) { SkillLevelingManager.OnUpgradeTroops(party, characterObject, numberToUpgrade); GiveGoldAction.ApplyBetweenCharacters(party.Owner, null, upgradeGoldCost * numberToUpgrade, true); } else if (party.LeaderHero != null) { SkillLevelingManager.OnUpgradeTroops(party, characterObject, numberToUpgrade); GiveGoldAction.ApplyBetweenCharacters(party.LeaderHero, null, upgradeGoldCost * numberToUpgrade, true); } } } } } } }
internal static bool Prefix(ref bool __result, ref MapEventSide __instance, ref CharacterObject ____selectedSimulationTroop, ref UniqueTroopDescriptor ____selectedSimulationTroopDescriptor, int damage, DamageTypes damageType, out int troopState, PartyBase strikerParty) { if (strikerParty.MapEvent != null && SimulationModel.IsValidEventType(strikerParty.MapEvent.EventType)) { if (SimulationsPool.TryGetSimulationModel(strikerParty.MapEvent.Id, out var simulationModel)) { SimulationTroopState simulationTroopState = SimulationTroopState.Alive; __result = false; // try to find the attacked troop in our model. Id doesn't exist call vanilla method var troopId = ____selectedSimulationTroop.Id; var troop = simulationModel.Parties[(int)__instance.MissionSide].Troops.Find(t => t.CharacterObject.Id == troopId); if (troop == null) { troopState = (int)simulationTroopState; return(true); } var battleObserver = MapEventSideAccessTools.GetBattleObserver(__instance); var allocatedTroops = MapEventSideAccessTools.GetAllocatedTroops(__instance); // troop is a Hero logic if (____selectedSimulationTroop.IsHero) { __instance.AddHeroDamage(____selectedSimulationTroop.HeroObject, damage); if (____selectedSimulationTroop.HeroObject.IsWounded) { __result = true; simulationTroopState = SimulationTroopState.Wounded; if (battleObserver != null) { battleObserver.TroopNumberChanged(__instance.MissionSide, __instance.GetAllocatedTroopParty(____selectedSimulationTroopDescriptor), ____selectedSimulationTroop, -1, 0, 1, 0, 0, 0); } } } // regular logic else if (troop.ApplyDamage(damage)) { PartyBase party = allocatedTroops[____selectedSimulationTroopDescriptor].Party; float survivalChance = Campaign.Current.Models.PartyHealingModel.GetSurvivalChance(party, ____selectedSimulationTroop, damageType, strikerParty); if (MBRandom.RandomFloat < survivalChance) { __instance.OnTroopWounded(____selectedSimulationTroopDescriptor); simulationTroopState = SimulationTroopState.Wounded; if (battleObserver != null) { battleObserver.TroopNumberChanged(__instance.MissionSide, __instance.GetAllocatedTroopParty(____selectedSimulationTroopDescriptor), ____selectedSimulationTroop, -1, 0, 1, 0, 0, 0); } SkillLevelingManager.OnSurgeryApplied(party.MobileParty, 1f); } else { __instance.OnTroopKilled(____selectedSimulationTroopDescriptor); simulationTroopState = SimulationTroopState.Kille; if (battleObserver != null) { battleObserver.TroopNumberChanged(__instance.MissionSide, __instance.GetAllocatedTroopParty(____selectedSimulationTroopDescriptor), ____selectedSimulationTroop, -1, 1, 0, 0, 0, 0); } SkillLevelingManager.OnSurgeryApplied(party.MobileParty, 0.5f); } __result = true; } if (__result) { __instance.RemoveSelectedTroopFromSimulationList(); } troopState = (int)simulationTroopState; return(false); } } troopState = 1; return(true); }