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); }
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)); }
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 } })); }
/// <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); }
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()); }
/// <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); }
public void cmdInitReplace(THHGame game, params Card[] cards) { game.answers.answer(id, new InitReplaceResponse() { cardsId = cards.Select(c => c.id).ToArray() }); }
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); }
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); }
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); }
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); }
public void cmdAttack(THHGame game, Card card, Card target) { game.answers.answer(id, new AttackResponse() { cardId = card.id, targetId = target.id }); }
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)); }
public override Task execute(THHGame game, Card card, Card target) { if (_onExecute != null) { return(_onExecute(game, card, target)); } return(Task.CompletedTask); }
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); }
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() }); }
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 })); }
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); }
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(); }
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)); } }
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]); } }
/// <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); }
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); } }
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()); }
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); }); }
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); } }
/// <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); }
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); }
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); }
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); }