public override void Run(GameEvent gameEvent, GameEventArgs eventArgs)
{
List<Card> computeBackup;
ICard c;
if (eventArgs.Skill != null)
{
CompositeCard card;
CardTransformSkill s = (CardTransformSkill)eventArgs.Skill;
if (eventArgs.Card is CompositeCard)
{
//仅在 Sha.UseDummyShaTo 里,eventArgs.Card才会被赋值且为CompositeCard
//表示 该DummySha的Verifier里被skill所转化
//参看 Sha.UseDummyShaTo
card = eventArgs.Card as CompositeCard;
s.NotifyAction(eventArgs.Source, eventArgs.Targets, card);
}
else if (!s.Transform(eventArgs.Cards, null, out card, eventArgs.Targets))
{
throw new TriggerResultException(TriggerResult.Retry);
}
c = card;
}
else
{
Trace.Assert(eventArgs.Cards.Count == 1);
c = eventArgs.Cards[0];
}
c.Type.TagAndNotify(eventArgs.Source, eventArgs.Targets, c);
// if it's delayed tool or equipment, we can't move it to compute area. call handlers directly
if (CardCategoryManager.IsCardCategory(c.Type.Category, CardCategory.DelayedTool)
|| CardCategoryManager.IsCardCategory(c.Type.Category, CardCategory.Equipment))
{
//使用延时锦囊和装备是应该触发PlayerUsedCard的。
//延时锦囊也应该触发CardUsageTargetConfirming和CardUsageTargetConfirmed
//因为在国战中,有成为目标后“取消之”这一个概念。
GameEventArgs newArg = new GameEventArgs();
newArg.Source = eventArgs.Source;
newArg.UiTargets = eventArgs.Targets;
newArg.Targets = c.Type.ActualTargets(newArg.Source, eventArgs.Targets, c);
newArg.Card = c;
newArg.ReadonlyCard = new ReadOnlyCard(c);
newArg.InResponseTo = eventArgs.InResponseTo;
Game.CurrentGame.Emit(GameEvent.PlayerUsedCard, newArg);
if (c.Type.IsCardCategory(CardCategory.DelayedTool))
{
Game.CurrentGame.Emit(GameEvent.CardUsageTargetConfirming, newArg);
Game.CurrentGame.Emit(GameEvent.CardUsageTargetConfirmed, newArg);
}
c.Type.Process(new GameEventArgs() { Source = eventArgs.Source, Targets = eventArgs.Targets, Card = c });
return;
}
var rdonlyCard = new ReadOnlyCard(c);
computeBackup = new List<Card>(Game.CurrentGame.Decks[DeckType.Compute]);
Game.CurrentGame.Decks[DeckType.Compute].Clear();
CardsMovement m = new CardsMovement();
Player isDoingAFavor = eventArgs.Source;
if (c is CompositeCard)
{
m.Cards = new List<Card>(((CompositeCard)c).Subcards);
if (c.Owner != null && c.Owner != eventArgs.Source)
{
Trace.TraceInformation("Acting on behalf of others");
isDoingAFavor = c.Owner;
}
}
else
{
m.Cards = new List<Card>(eventArgs.Cards);
}
m.To = new DeckPlace(null, DeckType.Compute);
m.Helper = new MovementHelper();
foreach (var checkFavor in m.Cards)
{
if (checkFavor.Owner != null && checkFavor.Owner != eventArgs.Source)
{
Trace.TraceInformation("Acting on behalf of others");
isDoingAFavor = checkFavor.Owner;
}
}
bool runTrigger = !c.Type.IsReforging(eventArgs.Source, eventArgs.Skill, m.Cards, eventArgs.Targets);
Game.CurrentGame.MoveCards(m, false, GameDelays.PlayerAction);
if (isDoingAFavor != eventArgs.Source)
{
Game.CurrentGame.PlayerPlayedCard(isDoingAFavor, new List<Player>() { eventArgs.Source }, c);
Game.CurrentGame.PlayerLostCard(isDoingAFavor, eventArgs.Cards != null ? eventArgs.Cards : ((CompositeCard)c).Subcards);
}
else
{
Game.CurrentGame.PlayerLostCard(eventArgs.Source, eventArgs.Cards);
}
Player savedSource = eventArgs.Source;
GameEventArgs arg = new GameEventArgs();
arg.Source = eventArgs.Source;
arg.UiTargets = eventArgs.Targets;
arg.Targets = c.Type.ActualTargets(arg.Source, eventArgs.Targets, c);
arg.Card = c;
arg.ReadonlyCard = rdonlyCard;
arg.InResponseTo = eventArgs.InResponseTo;
//we inherit card attributes if some readonly card is passed down from the caller (解烦)
if (eventArgs.ReadonlyCard != null)
{
arg.ReadonlyCard.Attributes.Clear();
foreach (var pair in eventArgs.ReadonlyCard.Attributes)
{
arg.ReadonlyCard.Attributes.Add(pair.Key, pair.Value);
}
}
Game.CurrentGame.SortByOrderOfComputation(Game.CurrentGame.CurrentPlayer, arg.Targets);
if (runTrigger)
{
try
{
Game.CurrentGame.Emit(GameEvent.PlayerUsedCard, arg);
Game.CurrentGame.Emit(GameEvent.CardUsageTargetConfirming, arg);
Game.CurrentGame.Emit(GameEvent.CardUsageTargetConfirmed, arg);
}
catch (TriggerResultException)
{
throw new NotImplementedException();
}
}
c.Type.Process(arg);
if (runTrigger)
{
try
{
Game.CurrentGame.Emit(GameEvent.CardUsageDone, arg);
}
catch (TriggerResultException)
{
throw new NotImplementedException();
}
}
if (Game.CurrentGame.Decks[DeckType.Compute].Count > 0)
{
m.Cards = new List<Card>(Game.CurrentGame.Decks[DeckType.Compute]);
m.To = new DeckPlace(null, DeckType.Discard);
m.Helper = new MovementHelper();
Game.CurrentGame.PlayerAboutToDiscardCard(savedSource, m.Cards, DiscardReason.Use);
Game.CurrentGame.MoveCards(m, false, GameDelays.None);
Game.CurrentGame.PlayerDiscardedCard(savedSource, m.Cards, DiscardReason.Use);
}
Trace.Assert(Game.CurrentGame.Decks[DeckType.Compute].Count == 0);
Game.CurrentGame.Decks[DeckType.Compute].AddRange(computeBackup);
}