public void DoDamage(Player source, Player dest, Player originalTarget, int magnitude, DamageElement elemental, ICard card, ReadOnlyCard readonlyCard)
{
if (dest.IsDead) return;
var damageArgs = new DamageEventArgs() { Source = source, OriginalTarget = originalTarget, Targets = new List<Player>(), Magnitude = magnitude, Element = elemental };
HealthChangedEventArgs healthChangedArgs;
int ironShackledDamage = 0;
DamageElement ironShackledDamageElement = DamageElement.None;
if (readonlyCard == null)
{
readonlyCard = new ReadOnlyCard(new Card() { Place = new DeckPlace(null, null) });
}
damageArgs.ReadonlyCard = readonlyCard;
if (card is CompositeCard)
{
if ((card as CompositeCard).Subcards != null)
{
damageArgs.Cards = new List<Card>((card as CompositeCard).Subcards);
}
}
else if (card is Card)
{
damageArgs.Cards = new List<Card>() { card as Card };
}
else
{
damageArgs.Cards = new List<Card>();
}
damageArgs.Targets.Add(dest);
damageArgs.Card = card;
try
{
//伤害来源与基数、属性的确定发生在伤害结算前,连环,以及转移的伤害不会重新确定来源与基数,所以不会多次触发【裸衣】,以及【酒】
while (damageArgs.ReadonlyCard[SourceAndElementIsConfirmed] == 0)
{
Emit(GameEvent.DamageSourceConfirmed, damageArgs);
Emit(GameEvent.DamageElementConfirmed, damageArgs);
damageArgs.ReadonlyCard[SourceAndElementIsConfirmed] = 1;
break;
}
Emit(GameEvent.BeforeDamageComputing, damageArgs);
Emit(GameEvent.DamageComputingStarted, damageArgs);
Emit(GameEvent.DamageCaused, damageArgs);
Emit(GameEvent.DamageInflicted, damageArgs);
if (damageArgs.Magnitude == 0)
{
Trace.TraceInformation("Damage is 0, aborting");
return;
}
if (damageArgs.Targets[0].IsIronShackled && damageArgs.Element != DamageElement.None)
{
ironShackledDamage = damageArgs.Magnitude;
Trace.TraceInformation("IronShackled damage {0}", ironShackledDamage);
ironShackledDamageElement = damageArgs.Element;
damageArgs.Targets[0].IsIronShackled = false;
// if this is TieSuo damage already, prevent itself from spreading...
if (readonlyCard[IsIronShackleDamage] == 1) ironShackledDamage = 0;
}
healthChangedArgs = new HealthChangedEventArgs(damageArgs);
Emit(GameEvent.BeforeHealthChanged, healthChangedArgs);
damageArgs.Magnitude = -healthChangedArgs.Delta;
}
catch (TriggerResultException e)
{
if (e.Status == TriggerResult.End)
{
//伤害结算完毕事件应该总是被触发
//受到伤害的角色如果存活能发动的技能/会执行的技能效果:【酒诗②】、执行【天香】摸牌的效果。
Emit(GameEvent.DamageComputingFinished, damageArgs);
Trace.TraceInformation("Damage Aborted");
return;
}
Trace.Assert(false);
return;
}
Trace.Assert(damageArgs.Targets.Count == 1);
damageArgs.Targets[0].Health -= damageArgs.Magnitude;
Trace.TraceInformation("Player {0} Lose {1} hp, @ {2} hp", damageArgs.Targets[0].Id, damageArgs.Magnitude, damageArgs.Targets[0].Health);
NotificationProxy.NotifyDamage(damageArgs.Source, damageArgs.Targets[0], damageArgs.Magnitude, damageArgs.Element);
GameDelays.Delay(GameDelays.Damage);
try
{
Emit(GameEvent.AfterHealthChanged, healthChangedArgs);
}
catch (TriggerResultException)
{
}
Emit(GameEvent.AfterDamageCaused, damageArgs);
Emit(GameEvent.AfterDamageInflicted, damageArgs);
Emit(GameEvent.DamageComputingFinished, damageArgs);
if (ironShackledDamage != 0)
{
List<Player> toProcess = new List<Player>(AlivePlayers);
SortByOrderOfComputation(CurrentPlayer, toProcess);
foreach (Player p in toProcess)
{
if (p.IsIronShackled)
{
readonlyCard[IsIronShackleDamage] = 1;
DoDamage(damageArgs.Source, p, originalTarget, ironShackledDamage, ironShackledDamageElement, card, readonlyCard);
}
}
}
}