private TroopDamage SendAttackDamage(Troop troop, bool counter) { this.RecentlyFighting = 3; troop.RecentlyFighting = 3; TroopDamage damage = new TroopDamage(); damage.SourceTroop = this; damage.DestinationTroop = troop; damage.Counter = counter; damage.AntiAttack = GameObject.Chance(troop.ChanceOfBlockAttack); damage.AntiArrowAttack = this.ArrowOffence && (troop.IsAntiArrowAttack || GameObject.Chance(troop.ChanceOfBlockArrowAttack)); damage.AntiCounterAttack = !counter && this.IsAntiCounterAttack; damage.Critical = (!counter && !troop.OutburstPreventCriticalStrike) && (GameObject.Chance(this.ChanceOfMustCriticalStrike) || GameObject.Chance(this.CriticalStrikeChance - troop.AntiCriticalStrikeChance)); damage.OnFire = GameObject.Chance((this.ChanceOfOnFire > this.BaseChanceOfOnFire) ? this.ChanceOfOnFire : this.BaseChanceOfOnFire); damage.Chaos = GameObject.Chance(this.ChanceOfChaosAttack); if (this.Status == TroopStatus.埋伏) { this.Status = TroopStatus.一般; damage.Waylay = true; if (!damage.Critical) { this.PreAction = TroopPreAction.伏击; } } if (troop.Defence <= 0) { damage.Damage = troop.Quantity; return damage; } int defence = troop.Defence; if ((this.BaseDefenceConsidered > 0) && (this.DefenceConsidered > 0)) { int num2 = (this.BaseDefenceConsidered < this.DefenceConsidered) ? this.BaseDefenceConsidered : this.DefenceConsidered; if (defence > num2) { defence = num2; } } else if (this.BaseDefenceConsidered > 0) { if (defence > this.BaseDefenceConsidered) { defence = this.BaseDefenceConsidered; } } else if (this.DefenceConsidered > 0) { if (defence > this.DefenceConsidered) { defence = this.DefenceConsidered; } } else if (GameObject.Chance(this.ChanceOfFixDefenceAttack) && (defence > 100)) { defence = 100; } damage.SourceOffence = this.Offence; if ((!troop.StuntAvoidSurround && !counter) && (this.StuntMustSurround || !GameObject.Chance(troop.AvoidSurroundedChance))) { TroopList surroundAttackingTroop = this.GetSurroundAttackingTroop(troop); if (surroundAttackingTroop.Count >= 3) { int num3 = 0; damage.Surround = true; damage.DestinationMoraleChange -= GlobalVariables.SurroundFactor * ((surroundAttackingTroop.Count - 3) + 1); troop.Effect = TroopEffect.被包围; foreach (Troop troop2 in surroundAttackingTroop) { if (troop2 != this) { damage.SurroudingList.Add(troop2); troop2.Surrounding = true; damage.SourceOffence += StaticMethods.GetRandomValue(troop2.Offence, GlobalVariables.SurroundFactor * 4 / 5); num3 += StaticMethods.GetRandomValue(troop2.ChaosAfterSurroundAttackChance, GlobalVariables.SurroundFactor * 2 / 5); } } damage.Chaos = GameObject.Chance(this.ChaosAfterSurroundAttackChance + num3); } } //int num4 = (int) (((damage.SourceOffence * 500) * Parameters.TroopDamageRate) / ((float) defence)); int num4 = (int)(Math.Pow(damage.SourceOffence / (float)defence, 0.62) * 1.16 * 500 * Parameters.TroopDamageRate); switch (troop.Army.Kind.Type) { case MilitaryType.步兵: num4 = (int)(num4 * this.OffenceRateOnSubdueBubing); break; case MilitaryType.弩兵: num4 = (int)(num4 * this.OffenceRateOnSubdueNubing); break; case MilitaryType.骑兵: num4 = (int)((num4 * this.OffenceRateOnSubdueQibing) * ((this.RateOfQibingDamage > this.BaseRateOfQibingDamage) ? this.RateOfQibingDamage : this.BaseRateOfQibingDamage)); break; case MilitaryType.水军: num4 = (int)(num4 * this.OffenceRateOnSubdueShuijun); break; case MilitaryType.器械: num4 = (int)(num4 * this.OffenceRateOnSubdueQixie); break; } if (this.MoraleDownOfAttack > 0) { damage.DestinationMoraleChange -= this.MoraleDownOfAttack; } if (damage.OnFire) { int num5 = (int)((troop.Army.Kind.MinScale * Parameters.FireDamageScale) * base.Scenario.GetTerrainDetailByPositionNoCheck(troop.Position).FireDamageRate); num5 = (int)(num5 * this.FireDamageRate); if (troop.RateOfFireProtection > 0f) { num5 = (int)(num5 * troop.RateOfFireProtection); } damage.FireDamage = num5; } damage.InjuredDamage = (int)(this.reduceInjuredOnAttack * damage.DestinationTroop.Army.Kind.MinScale); damage.TirednessIncrease = this.TirednessIncreaseOnAttack; damage.StealFood = Math.Min(damage.DestinationTroop.Food, this.StealFood); if (damage.Critical) //控制单挑发生相关 { this.PreAction = TroopPreAction.暴击; num4 = (int)((num4 * 1.5f) * troop.RateOfCriticalDamageReceived); if (!(damage.Chaos || !GameObject.Chance(this.ChaosAfterCriticalStrikeChance))) { damage.Chaos = true; } if (this.MoraleDecrementOfCriticalStrike > 0) { damage.DestinationMoraleChange -= this.MoraleDecrementOfCriticalStrike; } Challenge challenge = new Challenge(); challenge.ChallgenEvent(this, troop, damage, base.Scenario); //单挑事件 damage.InjuredDamage += (int)(this.reduceInjuredOnCritical * damage.DestinationTroop.Army.Kind.MinScale); damage.TirednessIncrease += this.TirednessIncreaseOnCritical; } if (damage.Waylay) { damage.DestinationMoraleChange -= 10; if (troop.NeverBeIntoChaosWhileWaylay) { damage.Chaos = false; } else if (!this.Army.Kind.AirOffence) { damage.Chaos = this.InevitableChaosOnWaylay || GameObject.Chance(30); } } if (damage.Counter) { num4 = (int)(num4 * 0.5f); } if (!(counter || (this.AttackDecrementOfCombativity <= 0))) { damage.DestinationCombativityChange -= this.AttackDecrementOfCombativity; } if (counter && (this.CounterAttackDecrementOfCombativity > 0)) { damage.CounterCombativityDown += this.CounterAttackDecrementOfCombativity; } if (!troop.HasCombatTitle) { if (this.CombativityDecrementOnPower > 0) { damage.DestinationCombativityChange -= this.CombativityDecrementOnPower; } if (this.MoraleDecrementOnPrestige > 0) { damage.DestinationMoraleChange -= this.MoraleDecrementOnPrestige; } } if (GameObject.Chance(this.ChanceOfTrippleDamage)) { num4 *= 3; } else if (GameObject.Chance(this.ChanceOfDoubleDamage)) { num4 *= 2; } if (GameObject.Chance(troop.ChanceOfHalfDamage)) { num4 /= 2; } damage.Damage = num4; damage.StealTroop = Math.Min(damage.DestinationTroop.Quantity, (int)(damage.Damage * this.StealTroop)); damage.StealInjured = Math.Min(damage.DestinationTroop.InjuryQuantity, (int)(damage.Damage * this.StealInjured)); damage.OfficerInjury = 0; if ((damage.Critical || troop.Quantity <= damage.Damage) && damage.Damage > 0 && GlobalVariables.OfficerDieInBattleRate > 0) { float dieChance = GlobalVariables.OfficerDieInBattleRate / 10000.0f; if (troop.Quantity <= damage.Damage) { dieChance *= 2; } if (damage.Surround) { dieChance *= 1.5f; } if (damage.Waylay) { dieChance *= 3; } dieChance *= (damage.SourceTroop.Leader.Strength + damage.SourceTroop.Leader.Braveness * 10 - damage.DestinationTroop.Leader.Strength - damage.DestinationTroop.Leader.Braveness * 10 + 100) / 100.0f; double rand = GameObject.Random(100000) / 100000.0; damage.OfficerInjury = (float) (dieChance / rand); if (damage.OfficerInjury < 0.1) { damage.OfficerInjury = 0; } } ExtensionInterface.call("TroopSendTroopDamage", new Object[] { this.Scenario, this, damage, troop, counter }); return damage; }
private void HandleTroopDamage(TroopDamage damage) { GameObjects.Animations.TileAnimation animation; if (damage.Surround) { damage.DestinationTroop.Effect = TroopEffect.无; foreach (Troop troop in damage.SurroudingList) { troop.Surrounding = false; } } int num = (((((2 + (damage.AntiArrowAttack ? 1 : 0)) + (damage.Critical ? 1 : 0)) + (damage.Chaos ? 1 : 0)) + (damage.OnFire ? 1 : 0)) + (damage.Waylay ? 1 : 0)) + (damage.SourceTroop.CombatMethodApplied ? 1 : 0); damage.SourceTroop.IncreaseAttackExperience(num * 2); damage.DestinationTroop.IncreaseBeAttackedExperience(num * 2); damage.SourceTroop.Leader.TroopDamageDealt += damage.Damage; damage.DestinationTroop.Leader.TroopBeDamageDealt += damage.Damage; if (damage.AntiAttack) { animation = base.Scenario.GeneratorOfTileAnimation.AddTileAnimation(TileAnimationKind.抵挡, damage.DestinationTroop.Position, false); if (animation != null) { damage.DestinationTroop.TryToPlaySound(damage.DestinationTroop.Position, this.getSoundPath(animation.LinkedAnimation), false); } if (this.OnAntiAttack != null) { this.OnAntiAttack(damage.SourceTroop, damage.DestinationTroop); } } else if (damage.AntiArrowAttack) { animation = base.Scenario.GeneratorOfTileAnimation.AddTileAnimation(TileAnimationKind.抵挡, damage.DestinationTroop.Position, false); if (animation != null) { damage.DestinationTroop.TryToPlaySound(damage.DestinationTroop.Position, this.getSoundPath(animation.LinkedAnimation), false); } if (this.OnAntiArrowAttack != null) { this.OnAntiArrowAttack(damage.SourceTroop, damage.DestinationTroop); } } else { if (damage.ChallengeHappened) //处理单挑结果 { /* this.CurrentSourceChallengePerson = damage.ChallengeSourcePerson; this.CurrentDestinationChallengePerson = damage.ChallengeDestinationPerson; if (this.OnPersonChallenge != null) { this.OnPersonChallenge(damage.ChallengeResult, damage.SourceTroop, this.CurrentSourceChallengePerson, damage.DestinationTroop, this.CurrentDestinationChallengePerson); } */ Challenge challeng = new Challenge(); challeng.HandleChallengeResult(damage, damage.ChallengeResult, damage.SourceTroop, damage.ChallengeSourcePerson, damage.DestinationTroop, damage.ChallengeDestinationPerson, base.Scenario); } if (damage.OfficerInjury > 0 && !damage.DestinationTroop.ImmunityOfDieInBattle) { int c = GameObject.Random(damage.DestinationTroop.Persons.Count); Person toInjure = damage.DestinationTroop.Persons[c] as Person; toInjure.InjureRate -= damage.OfficerInjury; if (toInjure.InjureRate < 0.05) { if (damage.DestinationTroop == damage.DestinationTroop.StartingArchitecture.RobberTroop) { damage.DestinationTroop.Persons.Remove(damage.DestinationTroop.Leader); damage.DestinationTroop.Leader.LocationTroop = null; } else { if (!toInjure.ImmunityOfDieInBattle) { toInjure.KilledInBattle(damage.SourceTroop); } } } } if (damage.OnFire && base.Scenario.IsFireVaild(damage.DestinationTroop.Position, false, MilitaryType.步兵)) { base.Scenario.SetPositionOnFire(damage.DestinationTroop.Position); } if ((damage.SourceTroop.StuntDayDecrementOfAttack > 0) && (damage.DestinationTroop.StuntDayLeft > 0)) { damage.DestinationTroop.StuntDayLeft -= damage.SourceTroop.StuntDayDecrementOfAttack; if (damage.DestinationTroop.StuntDayLeft < 1) { damage.DestinationTroop.StuntDayLeft = 1; } } if (!damage.SourceTroop.Destroyed && !damage.DestinationTroop.Destroyed) { if (!damage.SourceTroop.MoraleNoChanceAfterAttacked) { damage.SourceTroop.ChangeMorale(damage.SourceMoraleChange); CheckTroopRout(damage.SourceTroop); } if (!damage.SourceTroop.CombativityNoChanceAfterAttacked) { damage.SourceTroop.ChangeCombativity(damage.SourceCombativityChange); } ///////////////////////////////////////////////////////////////////// damage.DestinationTroop.DecreaseQuantity(damage.Damage); if (damage.OnFire) { damage.DestinationTroop.DecreaseQuantity(damage.FireDamage); } damage.DestinationTroop.IncreaseInjuryQuantity(damage.Injury); if (!damage.DestinationTroop.CombativityNoChanceAfterAttacked) { damage.DestinationTroop.ChangeCombativity(damage.DestinationCombativityChange); } if (!damage.DestinationTroop.MoraleNoChanceAfterAttacked) { damage.DestinationTroop.ChangeMorale(damage.DestinationMoraleChange); } damage.DestinationTroop.DecreaseInjuryQuantity(damage.InjuredDamage); ////////////////////////////////////////////////////////////////////////////////// damage.SourceTroop.IncreaseQuantity(damage.StealTroop); //damage.DestinationTroop.DecreaseQuantity(damage.StealTroop); damage.SourceTroop.InjuryQuantity += damage.StealInjured; //damage.DestinationTroop.DecreaseInjuryQuantity(damage.StealInjured); /////////////////////////////////////////////////////////////////////////////////// damage.DestinationTroop.Army.Tiredness += damage.TirednessIncrease; damage.DestinationTroop.Food -= damage.StealFood; damage.SourceTroop.IncreaseFood(damage.StealFood); foreach (Person p in damage.DestinationTroop.Persons) { p.Tiredness += damage.TirednessIncrease; } if (!damage.SourceTroop.Destroyed) { CheckTroopRout(damage.SourceTroop, damage.DestinationTroop); } else { CheckTroopRout(damage.DestinationTroop); } if (!damage.DestinationTroop.Destroyed) { if ((damage.DestinationTroop.BelongedFaction != null) && (damage.DestinationTroop.BelongedFaction.RateOfCombativityRecoveryAfterAttacked > 0f)) { damage.DestinationTroop.IncreaseCombativity(StaticMethods.GetRandomValue((int)((damage.DestinationTroop.Leader.Braveness * 100) * damage.DestinationTroop.BelongedFaction.RateOfCombativityRecoveryAfterAttacked), 100)); } if (damage.BeCountered && !damage.SourceTroop.Destroyed) { damage.SourceTroop.DecreaseQuantity(damage.CounterDamage); damage.SourceTroop.IncreaseInjuryQuantity(damage.CounterInjury); if (!damage.SourceTroop.CombativityNoChanceAfterAttacked) { damage.SourceTroop.DecreaseCombativity(damage.CounterCombativityDown); } CheckTroopRout(damage.DestinationTroop, damage.SourceTroop); } //原来的单挑结果处理位置。因为必须在部队毁灭前处理人物,所以把代码上移。 if (!damage.SourceTroop.Destroyed) { if (damage.Waylay) { damage.DestinationTroop.OperationDone = true; damage.DestinationTroop.MovabilityLeft = -1; if (this.OnReceiveWaylay != null) { this.OnReceiveWaylay(damage.SourceTroop, damage.DestinationTroop); } } if (damage.Critical && (!damage.Waylay && (this.OnReceiveCriticalStrike != null))) { this.OnReceiveCriticalStrike(damage.SourceTroop, damage.DestinationTroop); } if (damage.Chaos) { damage.DestinationTroop.SetChaos(damage.SourceTroop.GenerateAttackChaosDay(2)); } } } } } }