private void onRecvAction(object sender, EventArgs args, GenericAction callback)
        {
            if (args is OnAttackEventArgs)
            {
                var arg = args as OnAttackEventArgs;
                UberDebug.LogChannel(this, "Frontend", "ServantView收到攻击事件");
                callback += (a, b) => { UberDebug.LogChannel("Frontend", "ServantAttack动画播放完毕"); };

                var targetServant = cardVM.Board.Deck.GetCardByRID(arg.TargetRID);
                if (targetServant != null)
                {
                    ObjectPositionEventArgs target;
                    if (targetServant is CharacterInfoViewModel)
                    {
                        target = new SpecialCardPositionEventArgs(SpecialCardPositionEventArgs.CardType.MasterCard, !cardVM.Board.IsSelf);
                    }
                    else
                    {
                        target = new CardPositionEventArgs(cardVM.Board.ServantCount, cardVM.Index, !cardVM.Board.IsSelf);
                    }
                    PlayAnimation("ServantAttack", new ServantAttackEventArgs(
                                      new CardPositionEventArgs(cardVM.Board.ServantCount, cardVM.Index, cardVM.Board.IsSelf),
                                      target)
                                  , callback);
                }
                else
                {
                    throw new NullReferenceException($"没有找到rid为{arg.TargetRID}的卡");
                }
            }

            if (args is IndexChangeEventArgs && drawed)
            {
                var arg = args as IndexChangeEventArgs;
                PlayAnimation(this, new CardAnimationEventArgs()
                {
                    AnimationName = "RetinueMove",
                    EventArgs     = new CardPositionEventArgs(arg.Count > 0 ? arg.Count : cardVM.Board.ServantCount, arg.Index, cardVM.Board.IsSelf)
                }, callback);
            }

            if (args is RetinueSummonEventArgs)
            {
                callback += (a, b) => { drawed = true; };
                var arg = args as RetinueSummonEventArgs;
                PlayAnimation(this, new CardAnimationEventArgs()
                {
                    AnimationName = "RetinueSummon",
                    EventArgs     = new CardPositionEventArgs(cardVM.Board.ServantCount, cardVM.Index, cardVM.Board.IsSelf)
                }, callback);
            }

            if (args is CardAnimationEventArgs)
            {
                PlayAnimation(this, args, callback);
            }
        }
 public PositionWithRotation GetPOV(CardPositionEventArgs pos, bool global = false)
 {
     return(GetServantPosition(pos.GroupID, pos.GroupCount, pos.SelfSide, global));
 }