コード例 #1
0
        public async Task <bool> tryUse(THHGame game, Card card, int position, params Card[] targets)
        {
            if (!card.isUsable(game, this, out _))
            {
                return(false);
            }
            card.setUsed(true);
            await setGem(game, gem - card.getCost());

            await game.triggers.doEvent(new UseEventArg()
            {
                player = this, card = card, position = position, targets = targets
            }, async arg =>
            {
                THHPlayer player = arg.player;
                card             = arg.card;
                targets          = arg.targets;
                game.logger.log(arg.player + "使用" + arg.card + (targets.Length > 0 ? ",目标:" + string.Join <Card>(",", targets) : null));
                if (arg.card.define is ServantCardDefine || (card.define is GeneratedCardDefine && (card.define as GeneratedCardDefine).type == CardDefineType.SERVANT))
                {
                    //随从卡,将卡置入战场
                    await tryPutIntoField(game, arg.player.hand, arg.card, arg.position);
                    IEffect effect = arg.card.define.getEffectOn <ActiveEventArg>(game.triggers);
                    if (effect != null)
                    {
                        ActiveEventArg active = new ActiveEventArg(player, card, targets);
                        await game.triggers.doEvent(active, activeLogic);
                        async Task activeLogic(ActiveEventArg eventArg)
                        {
                            await effect.execute(game, player, card, new object[] { eventArg }, targets);
                        }
                    }
                    //IEffect effect = arg.card.define.getEffectOn<BattleCryEventArg>(game.triggers);
                    //if (effect != null)
                    //{
                    //    await game.triggers.doEvent(new BattleCryEventArg() { player = arg.player, card = arg.card, effect = effect, targets = arg.targets }, arg2 =>
                    //    {
                    //        return arg2.effect.execute(game, arg2.player, arg2.card, new object[] { arg2 }, arg2.targets);
                    //    });
                    //}
                }
                else if (card.define is SkillCardDefine)
                {
                    IEffect effect = arg.card.define.getEffectOn <ActiveEventArg>(game.triggers);
                    await effect.execute(game, arg.player, arg.card, new object[] { new ActiveEventArg(player, card, targets) }, arg.targets);
                }
                else if (card.define is SpellCardDefine || (card.define is GeneratedCardDefine && (card.define as GeneratedCardDefine).type == CardDefineType.SPELL))
                {
                    //法术卡,释放效果然后丢进墓地
                    player.hand.remove(game, card);
                    IEffect effect = arg.card.define.getEffectOn <ActiveEventArg>(game.triggers);
                    await effect.execute(game, player, card, new object[] { new ActiveEventArg(player, card, targets) }, targets);
                    player.grave.add(game, card);
                }
            });

            await game.updateDeath();

            return(true);
        }
コード例 #2
0
 public THHPlayer(THHGame game, int id, string name, MasterCardDefine master, IEnumerable <CardDefine> deck) : base(id, name)
 {
     this.master = game.createCard(master);
     addPile(new Pile(game, PileName.MASTER, 1));
     getPile(PileName.MASTER).add(game, this.master);
     skill = game.createCardById(master.skillID);
     addPile(new Pile(game, PileName.SKILL, 1));
     this[PileName.SKILL].add(game, skill);
     this.deck = new Pile(game, PileName.DECK);
     if (deck != null)
     {
         this.deck.add(game, deck.Select(d => game.createCard(d)).ToArray());
     }
     addPile(this.deck);
     init = new Pile(game, PileName.INIT, maxCount: 4);
     addPile(init);
     hand = new Pile(game, PileName.HAND, maxCount: 10);
     addPile(hand);
     field = new Pile(game, PileName.FIELD, maxCount: 7);
     addPile(field);
     grave = new Pile(game, PileName.GRAVE);
     addPile(grave);
     warp = new Pile(game, PileName.WARP);
     addPile(warp);
     addPile(new Pile(game, PileName.ITEM));
 }
コード例 #3
0
ファイル: THHCard.cs プロジェクト: minsuika/TouhouHeartstone
 public static Task die(this Card card, THHGame game, DeathEventArg.Info info)
 {
     return(die(new Card[] { card }, game, new Dictionary <Card, DeathEventArg.Info>()
     {
         { card, info }
     }));
 }
コード例 #4
0
ファイル: THHCard.cs プロジェクト: minsuika/TouhouHeartstone
 /// <summary>
 /// 这个角色能否对目标进行攻击?
 /// </summary>
 /// <param name="card"></param>
 /// <param name="game"></param>
 /// <param name="player"></param>
 /// <param name="target"></param>
 /// <returns></returns>
 public static bool isAttackable(this Card card, THHGame game, THHPlayer player, Card target, out string tip)
 {
     if (target == player.master || player.field.Contains(target))
     {
         tip = "你不能攻击友方角色";
         return(false);
     }
     if (target.getCurrentLife() <= 0)
     {
         tip = "目标随从已经死亡";
         return(false);
     }
     if (game.getOpponent(player).field.Any(c => c.isTaunt()) && !target.isTaunt())
     {
         tip = "你必须先攻击具有嘲讽的随从";
         return(false);
     }
     if (card.isRush() && !card.isReady() && game.players.Any(p => p.master == target) && !card.isCharge())
     {
         tip = "具有突袭的随从在没有准备好的情况下不能攻击敌方英雄";//除非你具有冲锋
         return(false);
     }
     if (target.isStealth())
     {
         tip = "无法攻击潜行的目标";
         return(false);
     }
     tip = null;
     return(true);
 }
コード例 #5
0
ファイル: THHCard.cs プロジェクト: minsuika/TouhouHeartstone
        public static Card[] getAvaliableTargets(this Card card, THHGame game)
        {
            IActiveEffect effect = card.define.getEffectOn <THHPlayer.ActiveEventArg>(game.triggers) as IActiveEffect;

            if (effect == null)
            {
                return(null);
            }
            List <Card> targetList = new List <Card>();

            foreach (THHPlayer player in game.players)
            {
                if (effect.checkTarget(game, null, card, new object[] { player.master }))
                {
                    targetList.Add(player.master);
                }
                foreach (Card servant in player.field)
                {
                    if (effect.checkTarget(game, null, card, new object[] { servant }))
                    {
                        targetList.Add(servant);
                    }
                }
            }
            return(targetList.ToArray());
        }
コード例 #6
0
 /// <summary>
 /// 这个角色能否进行攻击?
 /// </summary>
 /// <param name="card"></param>
 /// <returns></returns>
 public static bool canAttack(this Card card, THHGame game)
 {
     if (card.pile.name != PileName.FIELD)//你只能在战场上进行攻击。是不是必须得活着,这是个哲学问题。
     {
         return(false);
     }
     if (card.getAttack(game) <= 0)//没有攻击力
     {
         return(false);
     }
     if (!card.isReady(game) &&//还没准备好
         !card.isCharge(game) &&//且没有冲锋
         !(card.isRush(game) && game.getOpponent(card.getOwner()).field.Any(c => card.isAttackable(game, card.getOwner(), c, out _)))   //且并非有突袭且有可以攻击的敌方随从
         )
     {
         return(false);
     }
     if (card.getAttackTimes(game) >= card.getMaxAttackTimes())//已经攻击过了
     {
         return(false);
     }
     if (card.isFreeze(game))
     {
         return(false);
     }
     if (card.getKeywords(game).Contains(Keyword.CANTATTACK))
     {
         return(false);
     }
     return(true);
 }
コード例 #7
0
 public void cmdInitReplace(THHGame game, params Card[] cards)
 {
     game.answers.answer(id, new InitReplaceResponse()
     {
         cardsId = cards.Select(c => c.id).ToArray()
     });
 }
コード例 #8
0
        public async Task <bool> createToken(THHGame game, CardDefine define, int position)
        {
            if (game == null)
            {
                throw new ArgumentNullException(nameof(game));
            }
            if (define == null)
            {
                throw new ArgumentNullException(nameof(define));
            }
            if (field.count >= field.maxCount)
            {
                return(false);
            }
            await game.triggers.doEvent(new CreateTokenEventArg()
            {
                player = this, define = define, position = position
            }, async arg =>
            {
                THHPlayer player = arg.player;
                define           = arg.define;
                position         = arg.position;
                if (field.count >= field.maxCount)
                {
                    return;
                }
                game.logger.log(player + "召唤" + define.GetType().Name + "位于" + position);
                arg.card = game.createCard(define);
                await tryPutIntoField(game, null, arg.card, position);
            });

            return(true);
        }
コード例 #9
0
        public static async Task <bool> tryAttack(this Card card, THHGame game, Card target)
        {
            if (!card.canAttack())
            {
                return(false);
            }
            await game.triggers.doEvent(new AttackEventArg()
            {
                card = card, target = target
            }, async arg =>
            {
                game.logger.log(arg.card + "攻击" + arg.target);
                arg.card.setAttackTimes(arg.card.getAttackTimes() + 1);
                if (arg.card.getAttack() > 0)
                {
                    await arg.target.damage(game, arg.card.getAttack());
                }
                if (arg.target.getAttack() > 0)
                {
                    await arg.card.damage(game, arg.target.getAttack());
                }
            });

            await game.updateDeath();

            return(true);
        }
コード例 #10
0
ファイル: THHEffect.cs プロジェクト: hbn2020/TouhouHeartstone
        public virtual void onEnable(THHGame game, Card card, Buff buff)
        {
            string triggerName;

            if (buff == null)
            {
                triggerName = "DeathTrigger<" + id + ">";
            }
            else
            {
                triggerName = "DeathTrigger<" + id + ">(" + buff + ")";
            }
            Trigger <THHCard.DeathEventArg> trigger = card.getProp <Trigger <THHCard.DeathEventArg> >(game, triggerName);

            if (trigger != null)
            {
                return;
            }
            game.logger.log("Effect", card + "注册亡语" + triggerName);
            trigger = new Trigger <THHCard.DeathEventArg>(arg =>
            {
                if (!arg.infoDic.ContainsKey(card))
                {
                    return(Task.CompletedTask);
                }
                if (onExecute != null)
                {
                    return(onExecute(game, card, arg.infoDic[card].position));
                }
                return(Task.CompletedTask);
            });
            card.setProp(triggerName, trigger);
            game.triggers.registerAfter(trigger);
        }
コード例 #11
0
 public Task draw(THHGame game, Card card)
 {
     if (!deck.Contains(card))
     {
         return(Task.CompletedTask);
     }
     if (hand.count >= hand.maxCount)
     {
         return(game.triggers.doEvent(new BurnEventArg()
         {
             player = this, card = card
         }, arg =>
         {
             card = arg.card;
             arg.player.deck.moveTo(game, card, arg.player.grave, arg.player.grave.count);
             game.logger.log(arg.player + "的手牌已经满了," + card + "被送入墓地");
             return Task.CompletedTask;
         }));
     }
     else
     {
         return(game.triggers.doEvent(new DrawEventArg()
         {
             player = this, card = card
         }, async arg =>
         {
             THHPlayer player = arg.player;
             card = arg.card;
             if (card.define is SpellCardDefine spell && card.getProp <bool>(game, Keyword.AUTOCAST))
             {
                 await player.deck.moveTo(game, card, player.warp);
                 await card.activeEffect(game, player, new Card[0]);
                 await player.warp.moveTo(game, card, player.grave);
             }
コード例 #12
0
 public void cmdAttack(THHGame game, Card card, Card target)
 {
     game.answers.answer(id, new AttackResponse()
     {
         cardId   = card.id,
         targetId = target.id
     });
 }
コード例 #13
0
 public static Task <DamageEventArg> damage(this Card card, THHGame game, Card source, int value)
 {
     if (card == null)
     {
         return(Task.FromResult(default(DamageEventArg)));
     }
     return(damage(new Card[] { card }, game, source, value));
 }
コード例 #14
0
ファイル: THHEffect.cs プロジェクト: hbn2020/TouhouHeartstone
 public override Task execute(THHGame game, Card card, Card target)
 {
     if (_onExecute != null)
     {
         return(_onExecute(game, card, target));
     }
     return(Task.CompletedTask);
 }
コード例 #15
0
 public static bool isUsable(this Card card, THHGame game, THHPlayer player, out string info)
 {
     if (game.currentPlayer != player)//不是你的回合
     {
         info = "这不是你的回合";
         return(false);
     }
     if (card.define is ServantCardDefine servant)
     {
         if (player.gem < card.getCost())//费用不够
         {
             info = "你没有足够的法力值";
             return(false);
         }
         if (player.field.count >= player.field.maxCount)
         {
             info = "你无法将更多的随从置入战场";
             return(false);
         }
     }
     else if (card.define is SpellCardDefine spell)
     {
         if (player.gem < card.getCost())
         {
             info = "你没有足够的法力值";
             return(false);
         }
     }
     else if (card.define is SkillCardDefine skill)
     {
         if (card.isUsed())//已经用过了
         {
             info = "你已经使用过技能了";
             return(false);
         }
         if (player.gem < card.getCost())//费用不够
         {
             info = "你没有足够的法力值";
             return(false);
         }
         if (card.define.getEffectOn <THHPlayer.ActiveEventArg>(game.triggers) is IEffect effect && !effect.checkCondition(game, null, card, new object[]
         {
             new THHPlayer.ActiveEventArg(player, card, new object[0])
         }))
         {
             info = "技能不可用";
             return(false);
         }
     }
     else
     {
         info = "这是一张未知的卡牌";
         return(false);//不知道是什么卡
     }
     info = null;
     return(true);
 }
コード例 #16
0
 public void cmdUse(THHGame game, Card card, int position, params Card[] targets)
 {
     game.answers.answer(id, new UseResponse()
     {
         cardId    = card.id,
         position  = position,
         targetsId = targets.Select(c => c.id).ToArray()
     });
 }
コード例 #17
0
        public static bool isValidTarget(this Card card, THHGame game, Card target)
        {
            IEffect effect = card.define.getEffectOn <THHPlayer.ActiveEventArg>(game.triggers);

            if (effect == null)
            {
                return(false);
            }
            return(effect.checkTarget(game, null, card, new object[] { target }));
        }
コード例 #18
0
ファイル: THHEffect.cs プロジェクト: hbn2020/TouhouHeartstone
 public virtual bool checkTargets(THHGame game, Card card, object[] targets)
 {
     if (targets != null &&
         targets.Length > 0 &&
         targets[0] is Card target &&
         checkTarget(game, card, target))
     {
         return(true);
     }
     return(false);
 }
コード例 #19
0
ファイル: THHEffect.cs プロジェクト: hbn2020/TouhouHeartstone
 public override void onDisable(THHGame game, Card card, Buff buff)
 {
     if (onCardEnterHandTrigger != null)
     {
         game.triggers.removeAfter(onCardEnterHandTrigger);
         onCardEnterHandTrigger = null;
     }
     foreach (var pair in buffDic)
     {
         pair.Key.removeBuff(game, pair.Value);
     }
     buffDic.Clear();
 }
コード例 #20
0
ファイル: THHCard.cs プロジェクト: hbn2020/TouhouHeartstone
        public static Task backToHand(this Card card, THHGame game)
        {
            if (card.getOwner().hand.isFull)
            {
                game.logger.log(card.getOwner() + "的手牌已满,无法将" + card + "置入手牌");

                return(card.die(game));
            }
            else
            {
                game.logger.log("将" + card + "置入" + card.getOwner() + "的手牌");
                return(card.getOwner().field.moveTo(game, card, card.getOwner().hand));
            }
        }
コード例 #21
0
ファイル: THHCard.cs プロジェクト: hbn2020/TouhouHeartstone
        public static async Task silence(this IEnumerable <Card> cards, THHGame game)
        {
            foreach (var card in cards)
            {
                card.setProp(nameof(silence), true);
                await card.removeBuff(game, card.getBuffs());

                foreach (var effect in card.define.effects.OfType <IPassiveEffect>())
                {
                    effect.onDisable(game, card, null);
                }
                card.setKeywords(game, new string[0]);
            }
        }
コード例 #22
0
 /// <summary>
 /// 这个角色能否对目标进行攻击?
 /// </summary>
 /// <param name="card"></param>
 /// <param name="game"></param>
 /// <param name="player"></param>
 /// <param name="target"></param>
 /// <returns></returns>
 public static bool isAttackable(this Card card, THHGame game, THHPlayer player, Card target, out string tip)
 {
     if (target == player.master || player.field.Contains(target))
     {
         tip = "你不能攻击友方角色";
         return(false);
     }
     if (game.getOpponent(player).field.Any(c => c.isTaunt()) && !target.isTaunt())
     {
         tip = "你必须先攻击具有嘲讽的随从";
         return(false);
     }
     tip = null;
     return(true);
 }
コード例 #23
0
ファイル: THHCard.cs プロジェクト: hbn2020/TouhouHeartstone
        public static async Task activeEffect(this Card card, THHGame game, THHPlayer player, Card[] targets)
        {
            ITriggerEffect triggerEffect = card.define.getEffectOn <THHPlayer.ActiveEventArg>(game.triggers);

            if (triggerEffect != null)
            {
                await triggerEffect.execute(game, card, new object[] { new THHPlayer.ActiveEventArg(player, card, targets) }, targets);
            }
            IActiveEffect activeEffect = card.define.getActiveEffect();

            if (activeEffect != null)
            {
                await activeEffect.execute(game, card, new object[] { new THHPlayer.ActiveEventArg(player, card, targets) }, targets);
            }
        }
コード例 #24
0
ファイル: PileName.cs プロジェクト: ufii4/TouhouHeartstone
        public static Pile[] getPiles(this PileFlag flag, THHGame game, Player player)
        {
            List <Pile> pileList = new List <Pile>();

            if (flag.HasFlag(PileFlag.self))
            {
                addPileToList(player, flag, pileList);
            }
            if (flag.HasFlag(PileFlag.oppo))
            {
                player = game.getOpponent(player);
                addPileToList(player, flag, pileList);
            }
            return(pileList.ToArray());
        }
コード例 #25
0
 public static async Task damage(this IEnumerable <Card> cards, THHGame game, int value)
 {
     await game.triggers.doEvent(new DamageEventArg()
     {
         cards = cards.ToArray(), value = value
     }, arg =>
     {
         foreach (Card card in arg.cards)
         {
             card.setCurrentLife(card.getCurrentLife() - arg.value);
             game.logger.log(card + "受到" + arg.value + "点伤害,生命值=>" + card.getCurrentLife());
         }
         return(Task.CompletedTask);
     });
 }
コード例 #26
0
        internal async Task initReplace(THHGame game, params Card[] cards)
        {
            await game.triggers.doEvent(new InitReplaceEventArg()
            {
                player = this, cards = cards
            }, onInitReplace);

            Task onInitReplace(InitReplaceEventArg arg)
            {
                arg.replacedCards = arg.player.init.replaceByRandom(game, arg.cards, arg.player.deck);
                game.logger.log(arg.player + "替换卡牌:" + string.Join(",", arg.cards.Select(c => c.ToString())) + "=>"
                                + string.Join(",", arg.replacedCards.Select(c => c.ToString())));
                return(Task.CompletedTask);
            }
        }
コード例 #27
0
ファイル: THHEffect.cs プロジェクト: hbn2020/TouhouHeartstone
 /// <summary>
 /// 默认实现,存在可以作为目标的卡片。
 /// </summary>
 /// <param name="game"></param>
 /// <param name="card"></param>
 ///
 /// <returns></returns>
 public override bool checkCondition(THHGame game, Card card)
 {
     foreach (var player in game.players)
     {
         foreach (var pileName in ranges)
         {
             foreach (var target in player[pileName])
             {
                 if (checkTarget(game, card, target))
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
コード例 #28
0
 public THHPlayer(THHGame game, int id, string name, MasterCardDefine master, IEnumerable <CardDefine> deck) : base(id, name)
 {
     this.master = game.createCard(master);
     addPile(new Pile(game, "Master", new Card[] { this.master }, 1));
     skill = game.createCardById(master.skillID);
     addPile(new Pile(game, "Skill", new Card[] { skill }, 1));
     this.deck = new Pile(game, "Deck", deck.Select(d => game.createCard(d)).ToArray());
     addPile(this.deck);
     init = new Pile(game, "Init", maxCount: 4);
     addPile(init);
     hand = new Pile(game, "Hand", maxCount: 10);
     addPile(hand);
     field = new Pile(game, "Field", maxCount: 7);
     addPile(field);
     grave = new Pile(game, "Grave");
     addPile(grave);
 }
コード例 #29
0
ファイル: THHCard.cs プロジェクト: hbn2020/TouhouHeartstone
 public static bool isNeedTarget(this Card card, THHGame game, out Card[] targets)
 {
     if (card.define.getActiveEffect() is ITargetEffect targetEffect)
     {
         List <Card> targetList = new List <Card>();
         foreach (THHPlayer player in game.players)
         {
             if (targetEffect.checkTargets(game, null, card, new object[] { player.master }))
             {
                 targetList.Add(player.master);
             }
             foreach (Card servant in player.field)
             {
                 if (targetEffect.checkTargets(game, null, card, new object[] { servant }))
                 {
                     targetList.Add(servant);
                 }
             }
         }
         targets = targetList.ToArray();
         return(true);
     }
     if (card.define.getEffectOn <THHPlayer.ActiveEventArg>(game.triggers) is ITriggerEffect triggerEffect)
     {
         List <Card> targetList = new List <Card>();
         foreach (THHPlayer player in game.players)
         {
             if (triggerEffect.checkTargets(game, null, card, new object[] { player.master }))
             {
                 targetList.Add(player.master);
             }
             foreach (Card servant in player.field)
             {
                 if (triggerEffect.checkTargets(game, null, card, new object[] { servant }))
                 {
                     targetList.Add(servant);
                 }
             }
         }
         targets = targetList.ToArray();
         return(true);
     }
     targets = null;
     return(false);
 }
コード例 #30
0
ファイル: THHEffect.cs プロジェクト: hbn2020/TouhouHeartstone
        public virtual void onDisable(THHGame game, Card card, Buff buff)
        {
            string triggerName;

            if (buff == null)
            {
                triggerName = "DeathTrigger<" + id + ">";
            }
            else
            {
                triggerName = "DeathTrigger<" + id + ">(" + buff + ")";
            }
            Trigger <THHCard.DeathEventArg> trigger = card.getProp <Trigger <THHCard.DeathEventArg> >(game, triggerName);

            game.logger.log("Effect", card + "注销亡语" + triggerName);
            game.triggers.removeAfter(trigger);
            card.setProp <Trigger <THHCard.DamageEventArg> >(triggerName, null);
        }