예제 #1
0
        public override void OnUse(Room room, CardUseStruct use)
        {
            Player player = use.From;

            if (use.To.Count == 0)
            {
                use.To.Add(player);
            }

            object     data   = use;
            RoomThread thread = room.RoomThread;

            thread.Trigger(TriggerEvent.PreCardUsed, room, player, ref data);

            CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, player.Name)
            {
                CardString = RoomLogic.CardToString(room, use.Card)
            };

            room.MoveCardTo(use.Card, player, Place.PlaceTable, reason, true);
            Thread.Sleep(300);
            room.RoomThread.Trigger(TriggerEvent.CardUsedAnnounced, room, use.From, ref data);
            room.RoomThread.Trigger(TriggerEvent.CardTargetAnnounced, room, use.From, ref data);
            thread.Trigger(TriggerEvent.CardUsed, room, player, ref data);
            thread.Trigger(TriggerEvent.CardFinished, room, player, ref data);
        }
예제 #2
0
        public override void Use(Room room, CardUseStruct card_use)
        {
            List <Player> targets = card_use.To;
            string        str     = RoomLogic.CardToString(room, card_use.Card);

            if (targets.Count == 0 || RoomLogic.PlayerContainsTrick(room, targets[0], Name))
            {
                /*
                 * if (movable)
                 * {
                 *  OnNullified(room, card_use.From, card_use.Card);
                 *  if (room.GetCardOwner(card_use.Card.GetEffectiveId()) != card_use.From) return;
                 * }
                 */
                CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_USE, card_use.From.Name, null, card_use.Card.Skill, null)
                {
                    Card = card_use.Card
                };
                room.MoveCardTo(card_use.Card, null, Place.DiscardPile, reason, true);
                return;
            }

            if (room.GetCardIdsOnTable(room.GetSubCards(card_use.Card)).Count == 0)
            {
                return;
            }

            CardMoveReason reason2 = new CardMoveReason(MoveReason.S_REASON_USE, card_use.From.Name, targets[0].Name, card_use.Card.Skill, null)
            {
                Card = card_use.Card
            };

            room.MoveCardTo(card_use.Card, null, targets[0], Place.PlaceDelayedTrick, reason2, true);
        }
예제 #3
0
        public override void Use(Room room, CardUseStruct card_use)
        {
            Player player = card_use.From;
            Player target = card_use.To[0];

            if (target.Alive && !target.IsKongcheng() && RoomLogic.CanGetCard(room, player, target, "h"))
            {
                target.SetFlags("daoshu_target");
                string suit = room.AskForChoice(player, "daoshu", string.Join("+", suits));
                target.SetFlags("-daoshu_target");

                int id = room.AskForCardChosen(player, target, "h", "daoshu", false, HandlingMethod.MethodGet);
                room.ObtainCard(player, id);

                if (WrappedCard.GetSuitString(room.GetCard(id).Suit) == suit)
                {
                    room.Damage(new DamageStruct("daoshu", player, target));
                }
                else
                {
                    suit = WrappedCard.GetSuitString(room.GetCard(id).Suit);
                    player.SetFlags("daoshu");
                    List <int>     ids    = new List <int>();
                    CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_GIVE, player.Name, target.Name, "daoshu", string.Empty);
                    foreach (int card_id in player.GetCards("h"))
                    {
                        if (WrappedCard.GetSuitString(room.GetCard(card_id).Suit) != suit)
                        {
                            ids.Add(card_id);
                        }
                    }

                    if (ids.Count == 0)
                    {
                        room.ShowAllCards(player, null, "daoshu");
                    }
                    else if (ids.Count == 1)
                    {
                        room.ObtainCard(target, ref ids, reason, true);
                    }
                    else
                    {
                        List <int> to_give = room.AskForExchange(player, "daoshu", 1, 1, "@daoshu-give:" + target.Name, string.Empty, string.Format(".|^{0}|.|hand", suit), card_use.Card.SkillPosition);
                        if (to_give.Count == 1)
                        {
                            room.ObtainCard(target, ref to_give, reason, true);
                        }
                        else
                        {
                            List <int> give = new List <int> {
                                ids[0]
                            };
                            room.ObtainCard(target, ref give, reason, true);
                        }
                    }
                }
            }
        }
예제 #4
0
 public override bool Effect(TriggerEvent triggerEvent, Room room, Player zhurong, ref object data, Player ask_who, TriggerStruct info)
 {
     if (data is DamageStruct damage)
     {
         int            card_id = room.AskForCardChosen(zhurong, damage.To, "he", Name, false, HandlingMethod.MethodGet);
         CardMoveReason reason  = new CardMoveReason(MoveReason.S_REASON_EXTRACTION, zhurong.Name);
         room.ObtainCard(zhurong, room.GetCard(card_id), reason, room.GetCardPlace(card_id) != Place.PlaceHand);
     }
     return(false);
 }
예제 #5
0
        public virtual void Use(Room room, CardUseStruct card_use)
        {
            WrappedCard   card    = card_use.Card;
            List <Player> targets = card_use.To;

            for (int index = 0; index < targets.Count; index++)
            {
                Player           target = targets[index];
                CardEffectStruct effect = new CardEffectStruct
                {
                    Card        = card,
                    From        = card_use.From,
                    To          = target,
                    Multiple    = (targets.Count > 1),
                    Drank       = card_use.Drank,
                    ExDamage    = card_use.ExDamage,
                    BasicEffect = card_use.EffectCount.Count > index ? card_use.EffectCount[index] : new CardBasicEffect(target, 0, 0, 0)
                };

                List <Player> players = new List <Player>();
                for (int i = index; i < targets.Count; i++)
                {
                    if (card_use.EffectCount.Count <= i || !card_use.EffectCount[i].Nullified)
                    {
                        players.Add(targets[i]);
                    }
                }
                effect.StackPlayers = players;

                room.CardEffect(effect);
            }

            List <int> table_cardids = room.GetCardIdsOnTable(room.GetSubCards(card));

            if (table_cardids.Count > 0)
            {
                CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_USE, card_use.From.Name, null, card.Skill, null)
                {
                    Card = card
                };
                if (targets.Count == 1)
                {
                    reason.TargetId = targets[0].Name;
                }
                CardsMoveStruct move = new CardsMoveStruct(table_cardids, card_use.From, null, Place.PlaceTable, Place.DiscardPile, reason);
                room.MoveCardsAtomic(new List <CardsMoveStruct> {
                    move
                }, true);
            }
        }
예제 #6
0
        public override bool Effect(TriggerEvent triggerEvent, Room room, Player player, ref object data, Player ask_who, TriggerStruct info)
        {
            if (triggerEvent == TriggerEvent.TargetChosen)
            {
                room.AskForDiscard(player, Name, 1, 1, false, true, "@dragonphoenix-discard");
            }
            else if (data is DyingStruct dying && dying.Damage.From != null && dying.Damage.From.Alive && !player.IsKongcheng() && RoomLogic.CanGetCard(room, ask_who, player, "h"))
            {
                int            id     = room.AskForCardChosen(ask_who, player, "h", Name, false, FunctionCard.HandlingMethod.MethodGet);
                CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_EXTRACTION, ask_who.Name, Name, Name);
                room.ObtainCard(ask_who, room.GetCard(id), reason, false);
            }

            return(false);
        }
예제 #7
0
        public virtual void DoRecast(Room room, CardUseStruct use)
        {
            WrappedCard    card   = use.Card;
            CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_RECAST, use.From.Name)
            {
                SkillName = card.Skill
            };

            room.RecordSubCards(use.Card);
            room.MoveCardTo(card, null, Place.PlaceTable, reason, true);
            if (!string.IsNullOrEmpty(reason.SkillName))
            {
                room.BroadcastSkillInvoke(use.From, use.Card);
            }
            else
            {
                room.BroadcastSkillInvoke("@recast", use.From.IsMale() ? "male" : "female", -1);
            }

            if (!string.IsNullOrEmpty(card.Skill) && !card.Skill.StartsWith("-") && use.IsOwnerUse && RoomLogic.PlayerHasSkill(room, use.From, card.Skill))
            {
                room.NotifySkillInvoked(use.From, card.Skill);
            }

            LogMessage log = new LogMessage("#Card_Recast")
            {
                From     = use.From.Name,
                Card_str = RoomLogic.CardToString(room, card)
            };

            room.SendLog(log);

            List <int> table_cardids = room.GetCardIdsOnTable(room.GetSubCards(card));

            if (table_cardids.Count > 0)
            {
                CardsMoveStruct move = new CardsMoveStruct(table_cardids, use.From, null, Place.PlaceTable, Place.DiscardPile, reason);
                room.MoveCardsAtomic(new List <CardsMoveStruct>()
                {
                    move
                }, true);
                room.RemoveSubCards(use.Card);
            }

            room.DrawCards(use.From, 1, "recast");
        }
예제 #8
0
        public override TriggerStruct Cost(TriggerEvent triggerEvent, Room room, Player player, ref object data, Player lifeng, TriggerStruct info)
        {
            if (player.Alive && player.Phase == PlayerPhase.Finish && player.HandcardNum < player.Hp && lifeng.GetPile("commissariat").Count > 0)
            {
                List <int> ids = room.AskForExchange(lifeng, Name, 1, 0, "@shuliang:" + player.Name, "commissariat", string.Empty, info.SkillPosition);
                if (ids.Count > 0)
                {
                    CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_REMOVE_FROM_PILE, string.Empty, Name, Name);
                    room.ThrowCard(ref ids, reason, null);
                    room.DoAnimate(AnimateType.S_ANIMATE_INDICATE, lifeng.Name, player.Name);
                    room.BroadcastSkillInvoke(Name, lifeng, info.SkillPosition);
                    return(info);
                }
            }

            return(new TriggerStruct());
        }
예제 #9
0
        public override bool Effect(TriggerEvent triggerEvent, Room room, Player player, ref object data, Player ask_who, TriggerStruct info)
        {
            Player lord = null;

            foreach (Player p in room.GetAlivePlayers())
            {
                if (p.GetRoleEnum() == PlayerRole.Lord)
                {
                    lord = p;
                    break;
                }
            }
            List <int> give = room.AskForExchange(player, Name, 1, 0, "@huying:" + lord.Name, string.Empty, Slash.ClassName, info.SkillPosition);

            room.SendCompulsoryTriggerLog(player, Name, true);
            room.BroadcastSkillInvoke(Name, player, info.SkillPosition);
            room.DoAnimate(AnimateType.S_ANIMATE_INDICATE, player.Name, lord.Name);

            if (give.Count > 0)
            {
                room.ObtainCard(lord, ref give, new CardMoveReason(MoveReason.S_REASON_GIVE, player.Name, lord.Name, Name, string.Empty), true);
            }
            else
            {
                room.LoseHp(player);
                if (lord.Alive)
                {
                    foreach (int id in room.DrawPile)
                    {
                        WrappedCard card = room.GetCard(id);
                        if (card.Name.Contains(Slash.ClassName))
                        {
                            CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_GOTBACK, lord.Name, Name, string.Empty);
                            List <int>     ids    = new List <int> {
                                id
                            };
                            room.ObtainCard(lord, ref ids, reason, true);
                            break;
                        }
                    }
                }
            }

            return(false);
        }
예제 #10
0
        public override void Use(Room room, CardUseStruct card_use)
        {
            List <Player> targets        = card_use.To;
            string        str            = RoomLogic.CardToString(room, card_use.Card);
            List <string> nullified_list = room.ContainsTag("CardUseNullifiedList") ? (List <string>)room.GetTag("CardUseNullifiedList") : new List <string>();
            bool          all_nullified  = nullified_list.Contains("_ALL_TARGETS");

            if (all_nullified || targets.Count == 0)
            {
                if (movable)
                {
                    OnNullified(room, card_use.From, card_use.Card);
                    if (room.GetCardOwner(card_use.Card.GetEffectiveId()) != card_use.From)
                    {
                        return;
                    }
                }
                CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, card_use.From.Name, null, card_use.Card.Skill, null)
                {
                    CardString = str
                };
                room.MoveCardTo(card_use.Card, null, Place.DiscardPile, reason, true);
                return;
            }

            if (room.GetCardIdsOnTable(card_use.Card).Count == 0)
            {
                return;
            }

            CardMoveReason reason2 = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, card_use.From.Name, targets[0].Name, card_use.Card.Skill, null)
            {
                CardString = str
            };

            room.MoveCardTo(card_use.Card, null, targets[0], Place.PlaceDelayedTrick, reason2, true);
        }
예제 #11
0
        public override void OnUse(Room room, CardUseStruct use)
        {
            string str = RoomLogic.CardToString(room, use.Card);

            object     data   = use;
            RoomThread thread = room.RoomThread;

            thread.Trigger(TriggerEvent.PreCardUsed, room, use.From, ref data);

            CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, use.From.Name, use.To[0].Name, use.Card.Skill, null)
            {
                CardString = str,
                General    = RoomLogic.GetGeneralSkin(room, use.From, use.Card.Skill, use.Card.SkillPosition)
            };

            room.MoveCardTo(use.Card, use.From, Place.PlaceTable, reason, true);

            LogMessage log = new LogMessage
            {
                From     = use.From.Name,
                To       = new List <string>(),
                Type     = "#DelayedTrick",
                Card_str = str
            };

            foreach (Player to in use.To)
            {
                log.To.Add(to.Name);
            }
            room.SendLog(log);

            Thread.Sleep(300);
            room.RoomThread.Trigger(TriggerEvent.CardUsedAnnounced, room, use.From, ref data);
            room.RoomThread.Trigger(TriggerEvent.CardTargetAnnounced, room, use.From, ref data);
            thread.Trigger(TriggerEvent.CardUsed, room, use.From, ref data);
            thread.Trigger(TriggerEvent.CardFinished, room, use.From, ref data);
        }
예제 #12
0
        public override void OnNullified(Room room, Player target, WrappedCard card)
        {
            RoomThread thread = room.RoomThread;

            string card_str = RoomLogic.CardToString(room, card);
            bool   move     = false;
            Player p        = null;

            if (movable)
            {
                List <Player> players       = new List <Player>();
                List <Player> count_players = new List <Player>(room.Players);
                Player        starter       = target;
                int           index         = count_players.IndexOf(starter);
                for (int i = index + 1; i < count_players.Count; i++)
                {
                    if (count_players[i].Alive)
                    {
                        players.Add(count_players[i]);
                    }
                }

                for (int i = 0; i <= index; i++)
                {
                    if (count_players[i].Alive)
                    {
                        players.Add(count_players[i]);
                    }
                }

                foreach (Player player in players)
                {
                    if (RoomLogic.PlayerContainsTrick(room, player, Name))
                    {
                        continue;
                    }

                    Skill skill = RoomLogic.IsProhibited(room, null, player, card);
                    if (skill != null)
                    {
                        skill = Engine.GetMainSkill(skill.Name);
                        LogMessage log = new LogMessage
                        {
                            Type = "#SkillAvoid",
                            From = player.Name,
                            Arg  = skill.Name,
                            Arg2 = Name
                        };
                        room.SendLog(log);

                        room.BroadcastSkillInvoke(skill.Name, player);
                        continue;
                    }
                    if (player.HasFlag(card_str + "_delay_trick_cancel"))
                    {
                        continue;
                    }

                    CardUseStruct use  = new CardUseStruct(room.GetCard(card.GetEffectiveId()), null, player);
                    object        data = use;
                    thread.Trigger(TriggerEvent.TargetConfirming, room, player, ref data);
                    CardUseStruct new_use = (CardUseStruct)data;
                    if (new_use.To.Count == 0)
                    {
                        p = player;
                        player.SetFlags(card_str + "_delay_trick_cancel");
                        break;
                    }

                    CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_TRANSFER, string.Empty)
                    {
                        CardString = RoomLogic.CardToString(room, card)
                    };
                    room.MoveCardTo(card, null, player, Place.PlaceDelayedTrick, reason, true);
                    move = true;

                    foreach (Player p2 in room.GetAllPlayers())
                    {
                        thread.Trigger(TriggerEvent.TargetChosen, room, p2, ref data);
                    }
                    foreach (Player p2 in room.GetAllPlayers())
                    {
                        thread.Trigger(TriggerEvent.TargetConfirmed, room, p2, ref data);
                    }
                    break;
                }
            }

            if (p != null)
            {
                OnNullified(room, p, card);
            }
            else if (!move)
            {
                foreach (Player player in room.GetAllPlayers())
                {
                    if (player.HasFlag(RoomLogic.CardToString(room, card) + "_delay_trick_cancel"))
                    {
                        player.SetFlags(string.Format("-{0}{1}", card_str, "_delay_trick_cancel"));
                    }
                }

                CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_NATURAL_ENTER, string.Empty);
                room.MoveCardTo(card, null, Place.DiscardPile, reason, true);
            }
        }
예제 #13
0
        public override bool Effect(TriggerEvent triggerEvent, Room room, Player player, ref object data, Player target, TriggerStruct trigger_info)
        {
            if (room.SkipGameRule)
            {
                room.SkipGameRule = false;
                return(false);
            }

            // Handle global events
            if (player == null)
            {
                if (triggerEvent == TriggerEvent.GameStart)
                {
                    OnGameStart(room, ref data);
                }

                if (triggerEvent != TriggerEvent.BeforeCardsMove && triggerEvent != TriggerEvent.CardsMoveOneTime)
                {
                    return(false);
                }
            }

            switch (triggerEvent)
            {
            case TriggerEvent.TurnStart:
                OnTurnStart(room, player, ref data);
                break;

            case TriggerEvent.EventPhaseProceeding:
                OnPhaseProceed(room, player, ref data);
                break;

            case TriggerEvent.EventPhaseEnd:
                OnPhaseEnd(room, player, ref data);
                break;

            case TriggerEvent.EventPhaseChanging:
                OnPhaseChanging(room, player, ref data);
                break;

            case TriggerEvent.PreCardUsed:
                OnPreCardUsed(room, player, ref data);
                break;

            case TriggerEvent.CardUsed:
                OnCardUsed(room, player, ref data);
                break;

            case TriggerEvent.CardFinished:
                CardUseStruct use = (CardUseStruct)data;
                //room.ClearCardFlag(use.Card);
                use.Card.ClearFlags();                      //RoomCard会在其移动后自动清除flag
                room.RemoveSubCards(use.Card);

                //以askforcard形式使用的卡牌没有onUse的trigger,但有finish
                if (use.Reason != CardUseStruct.CardUseReason.CARD_USE_REASON_RESPONSE)
                {
                    room.RemoveUseOnFinish();
                }

                if (Engine.GetFunctionCard(use.Card.Name).IsNDTrick())
                {
                    room.RemoveHegNullification(use.Card);
                }

                foreach (Client p in room.Clients)
                {
                    room.DoNotify(p, CommandType.S_COMMAND_NULLIFICATION_ASKED, new List <string> {
                        "."
                    });
                }

                break;

            case TriggerEvent.EventAcquireSkill:
            case TriggerEvent.EventLoseSkill:
                InfoStruct info       = (InfoStruct)data;
                string     skill_name = info.Info;
                Skill      skill      = Engine.GetSkill(skill_name);
                bool       refilter   = skill is FilterSkill;

                if (!refilter && skill is TriggerSkill)
                {
                    TriggerSkill trigger = (TriggerSkill)skill;
                    ViewAsSkill  vsskill = trigger.ViewAsSkill;
                    if (vsskill != null && (vsskill is FilterSkill))
                    {
                        refilter = true;
                    }
                }

                if (refilter)
                {
                    room.FilterCards(player, player.GetCards("he"), triggerEvent == TriggerEvent.EventLoseSkill);
                }

                CheckBigKingdoms(room);
                break;

            case TriggerEvent.PostHpReduced:
                if (player.Hp > 0 || player.HasFlag("Global_Dying"))     // newest GameRule -- a player cannot enter dying when it is dying.
                {
                    break;
                }
                if (data is DamageStruct damage)
                {
                    room.EnterDying(player, damage);
                }
                else
                {
                    room.EnterDying(player, new DamageStruct());
                }

                break;

            case TriggerEvent.AskForPeaches:
                OnAskforPeach(room, player, ref data);
                break;

            case TriggerEvent.AskForPeachesDone:
            {
                if (player.Hp <= 0 && player.Alive)
                {
                    DyingStruct dying = (DyingStruct)data;
                    room.KillPlayer(player, dying.Damage);
                }

                break;
            }

            case TriggerEvent.ConfirmDamage:
            {
                break;
            }

            case TriggerEvent.DamageDone:
            {
                damage = (DamageStruct)data;
                if (damage.From != null && !damage.From.Alive)
                {
                    damage.From = null;
                }
                room.SendDamageLog(damage);

                if (damage.Nature != DamageNature.Normal && player.Chained && !damage.Chain && !damage.ChainStarter)
                {
                    damage.ChainStarter = true;
                }

                data = damage;

                bool reduce = !room.ApplyDamage(player, damage);

                if (reduce)
                {
                    room.RoomThread.Trigger(TriggerEvent.PostHpReduced, room, player, ref data);
                }

                break;
            }

            case TriggerEvent.DamageComplete:
            {
                damage = (DamageStruct)data;
                if (damage.Prevented)
                {
                    return(false);
                }

                /*
                 * if (damage.Nature != DamageNature.Normal && player.Chained)
                 * {
                 *  room.ChainedRemoveOnDamageDone(player, damage);
                 * }
                 */
                if (damage.Nature != DamageNature.Normal && !damage.Chain && damage.ChainStarter)              // iron chain effect
                {
                    List <Player> chained_players = new List <Player>();
                    if (!room.Current.Alive)
                    {
                        chained_players = room.GetOtherPlayers(room.Current);
                    }
                    else
                    {
                        chained_players = room.GetAllPlayers();
                    }
                    chained_players.Remove(damage.To);
                    foreach (Player chained_player in chained_players)
                    {
                        if (chained_player.Chained)
                        {
                            Thread.Sleep(500);
                            LogMessage log = new LogMessage
                            {
                                Type = "#IronChainDamage",
                                From = chained_player.Name
                            };
                            room.SendLog(log);

                            DamageStruct chain_damage = damage;
                            chain_damage.To             = chained_player;
                            chain_damage.Chain          = true;
                            chain_damage.Transfer       = false;
                            chain_damage.TransferReason = null;

                            room.Damage(chain_damage);
                        }
                    }
                }

                foreach (Player p in room.GetAllPlayers())
                {
                    if (p.HasFlag("Global_DFDebut"))
                    {
                        p.SetFlags("-Global_DFDebut");
                        room.RoomThread.Trigger(TriggerEvent.DFDebut, room, p);
                    }
                }
                break;
            }

            case TriggerEvent.CardEffect:
            {
                if (data is CardEffectStruct effect)
                {
                    if (Engine.GetFunctionCard(effect.Card.Name) is DelayedTrick)
                    {
                        CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_DELAYTRICK_EFFECT,
                                                                   effect.To.Name, effect.Card.Skill, effect.Card.Name)
                        {
                            Card = effect.Card
                        };

                        room.MoveCardTo(effect.Card, effect.To, Place.PlaceTable, reason, true);
                        Thread.Sleep(500);
                    }
                }
                break;
            }

            case TriggerEvent.CardEffected:
            {
                if (data is CardEffectStruct effect)
                {
                    FunctionCard fcard = Engine.GetFunctionCard(effect.Card.Name);
                    if (!(fcard is Slash) && effect.BasicEffect.Nullified)
                    {
                        LogMessage log = new LogMessage
                        {
                            Type = "#Cardnullified",
                            From = effect.To.Name,
                            Arg  = effect.Card.Name
                        };
                        room.SendLog(log);

                        return(true);
                    }
                    else if (fcard.TypeID == CardType.TypeTrick && room.IsCanceled(effect))
                    {
                        effect.To.SetFlags("Global_NonSkillnullify");
                        return(true);
                    }
                    object _effect = effect;
                    room.RoomThread.Trigger(TriggerEvent.CardEffectConfirmed, room, effect.To, ref _effect);

                    if (effect.To.Alive || fcard is Slash)
                    {
                        fcard.OnEffect(room, effect);
                    }
                }

                break;
            }

            case TriggerEvent.SlashEffected:
            {
                SlashEffectStruct effect = (SlashEffectStruct)data;
                if (effect.Nullified)
                {
                    LogMessage log = new LogMessage
                    {
                        Type = "#Cardnullified",
                        From = effect.To.Name,
                        Arg  = effect.Slash.Name
                    };
                    room.SendLog(log);

                    return(true);
                }

                if (effect.Jink_num > 0)
                {
                    room.RoomThread.Trigger(TriggerEvent.SlashProceed, room, effect.From, ref data);
                }
                else
                {
                    room.SlashResult(effect, null);
                }
                break;
            }

            case TriggerEvent.SlashProceed:
            {
                SlashEffectStruct effect  = (SlashEffectStruct)data;
                string            slasher = effect.From.Name;
                if (!effect.To.Alive)
                {
                    break;
                }
                if (effect.Jink_num == 1)
                {
                    CardResponseStruct resp = room.AskForCard(effect.To, Slash.ClassName, Jink.ClassName, string.Format("slash-jink:{0}::{1}", slasher, effect.Slash.Name),
                                                              data, HandlingMethod.MethodUse, null, effect.From, false, false);
                    room.SlashResult(effect, room.IsJinkEffected(effect.To, resp) ? resp.Card : null);
                }
                else
                {
                    WrappedCard jink = new WrappedCard(DummyCard.ClassName);
                    for (int i = effect.Jink_num; i > 0; i--)
                    {
                        string             prompt = string.Format("@multi-jink{0}:{1}::{2}:{3}", i == effect.Jink_num ? "-start" : string.Empty, slasher, i, effect.Slash.Name);
                        CardResponseStruct resp   = room.AskForCard(effect.To, Slash.ClassName, Jink.ClassName, prompt, data, HandlingMethod.MethodUse, null, effect.From, false, false);

                        if (!room.IsJinkEffected(effect.To, resp))
                        {
                            //delete jink;
                            room.SlashResult(effect, null);
                            return(false);
                        }
                        else
                        {
                            jink.AddSubCard(resp.Card);
                        }
                    }
                    room.SlashResult(effect, jink);
                }

                break;
            }

            case TriggerEvent.SlashHit:
            {
                SlashEffectStruct effect = (SlashEffectStruct)data;
                if (effect.Drank > 0)
                {
                    LogMessage log = new LogMessage
                    {
                        Type = "#AnalepticBuff",
                        From = effect.From.Name,
                        To   = new List <string> {
                            effect.To.Name
                        },
                        Arg  = (1 + effect.ExDamage).ToString(),
                        Arg2 = (1 + effect.ExDamage + effect.Drank).ToString()
                    };

                    room.SendLog(log);
                }
                DamageStruct slash_damage = new DamageStruct(effect.Slash, effect.From, effect.To, 1 + effect.ExDamage + effect.Drank, effect.Nature)
                {
                    Drank = effect.Drank > 0
                };
                room.Damage(slash_damage);
                break;
            }

            case TriggerEvent.BeforeGameOverJudge:
            {
                if (!player.General1Showed)
                {
                    room.ShowGeneral(player, true, false, false);
                }
                if (!player.General2Showed)
                {
                    room.ShowGeneral(player, false, false, false);
                }
                break;
            }

            case TriggerEvent.GameOverJudge:
            {
                string winner = GetWinner(room);
                if (!string.IsNullOrEmpty(winner))
                {
                    room.GameOver(winner);
                    return(true);
                }

                break;
            }

            case TriggerEvent.BuryVictim:
            {
                OnBuryVictim(room, player, ref data);
                break;
            }

            case TriggerEvent.StartJudge:
            {
                int         card_id      = room.GetNCards(1)[0];
                JudgeStruct judge_struct = (JudgeStruct)data;
                judge_struct.Card = room.GetCard(card_id);

                LogMessage log = new LogMessage
                {
                    Type     = "$InitialJudge",
                    From     = judge_struct.Who.Name,
                    Card_str = card_id.ToString()
                };
                room.SendLog(log);

                room.MoveCardTo(judge_struct.Card, null, judge_struct.Who, Place.PlaceJudge,
                                new CardMoveReason(MoveReason.S_REASON_JUDGE, judge_struct.Who.Name, null, null, judge_struct.Reason), true);

                Thread.Sleep(500);
                bool effected = judge_struct.Good == Engine.MatchExpPattern(room, judge_struct.Pattern, judge_struct.Who, judge_struct.Card);
                judge_struct.UpdateResult(effected);
                data = judge_struct;
                break;
            }

            case TriggerEvent.JudgeResult:
            {
                JudgeStruct judge = (JudgeStruct)data;
                LogMessage  log   = new LogMessage
                {
                    Type     = "$JudgeResult",
                    From     = player.Name,
                    Card_str = RoomLogic.CardToString(room, judge.Card)
                };
                room.SendLog(log);

                //Thread.Sleep(500);
                if (judge.PlayAnimation)
                {
                    room.SendJudgeResult(judge);
                    Thread.Sleep(800);
                }

                break;
            }

            case TriggerEvent.FinishJudge:
            {
                JudgeStruct judge = (JudgeStruct)data;

                if (room.GetCardPlace(judge.Card.Id) == Place.PlaceJudge)
                {
                    CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_JUDGEDONE, judge.Who.Name, null, judge.Reason);
                    room.MoveCardTo(judge.Card, judge.Who, null, Place.DiscardPile, reason, true);
                }

                break;
            }

            case TriggerEvent.ChoiceMade:
            {
                foreach (Player p in room.GetAlivePlayers())
                {
                    List <string> flags = new List <string>(p.Flags);
                    foreach (string flag in flags)
                    {
                        if (flag.StartsWith("Global_") && flag.EndsWith("Failed"))
                        {
                            p.SetFlags("-" + flag);
                        }
                    }
                }
                break;
            }

            case TriggerEvent.GeneralShown:
            {
                string winner = GetWinner(room);
                if (!string.IsNullOrEmpty(winner))
                {
                    room.GameOver(winner);         // if all hasShownGenreal, and they are all friend, game over.
                    return(true);
                }
                if (!room.ContainsTag("TheFirstToShowRewarded"))
                {
                    room.SetTag("TheFirstToShowRewarded", true);
                    room.SetPlayerMark(player, "@pioneer", 1);
                    room.AttachSkillToPlayer(player, "pioneer");
                }
                if (player.Alive && player.HasShownAllGenerals())
                {
                    if (player.GetMark("CompanionEffect") > 0)
                    {
                        room.RemovePlayerMark(player, "CompanionEffect");
                        room.DoSuperLightbox(player, string.Empty, "companion");
                        room.SetPlayerMark(player, "@companion", 1);
                        room.AttachSkillToPlayer(player, "companion");
                    }
                    if (player.GetMark("HalfMaxHpLeft") > 0)
                    {
                        room.RemovePlayerMark(player, "HalfMaxHpLeft");
                        room.SetPlayerMark(player, "@megatama", 1);
                        room.AttachSkillToPlayer(player, "megatama");
                    }
                }
                CheckBigKingdoms(room);
                break;
            }

            case TriggerEvent.BeforeCardsMove:
            {
                if (data is CardsMoveOneTimeStruct move)
                {
                    bool should_find_io = false;
                    if (move.To_place == Place.DiscardPile)
                    {
                        if (move.Reason.Reason != MoveReason.S_REASON_USE)
                        {
                            should_find_io = true;         // not use
                        }
                        else if (move.Card_ids.Count > 1)
                        {
                            should_find_io = true;         // use card isn't IO
                        }
                        else
                        {
                            WrappedCard card = room.GetCard(move.Card_ids[0]);
                            if (card.Name == Edict.ClassName && !card.HasFlag("edict_normal_use"))
                            {
                                should_find_io = true;         // use card isn't IO
                            }
                        }
                    }
                    if (should_find_io)
                    {
                        foreach (int id in move.Card_ids)
                        {
                            WrappedCard card = room.GetCard(id);
                            if (card.Name == Edict.ClassName)
                            {
                                room.MoveCardTo(card, null, Place.PlaceTable, true);
                                room.AddToPile(room.Players[0], "#edict", card, false);
                                LogMessage log = new LogMessage
                                {
                                    Type = "#RemoveEdict",
                                    Arg  = Edict.ClassName
                                };
                                room.SendLog(log);
                                room.SetTag("EdictInvoke", true);
                                room.SetTag("EdictCard", card);
                                int i = move.Card_ids.IndexOf(id);
                                move.From_places.RemoveAt(i);
                                move.Open.RemoveAt(i);
                                move.From_pile_names.RemoveAt(i);
                                move.Card_ids.Remove(id);
                                data = move;
                                break;
                            }
                        }
                    }
                }
                break;
            }

            case TriggerEvent.Death:
            {
                OnDeath(room, player, ref data);
                break;
            }

            case TriggerEvent.CardsMoveOneTime:
            {
                if (data is CardsMoveOneTimeStruct move)
                {
                    if (move.From != null && move.From_places.Contains(Place.PlaceEquip))
                    {
                        foreach (int id in move.Card_ids)
                        {
                            WrappedCard card = room.GetCard(id);
                            if (card.Name == JadeSeal.ClassName)
                            {
                                CheckBigKingdoms(room);
                                break;
                            }
                        }
                    }

                    if (move.To != null && move.To_place == Place.PlaceEquip)
                    {
                        foreach (int id in move.Card_ids)
                        {
                            WrappedCard card = room.GetCard(id);
                            if (card.Name == JadeSeal.ClassName)
                            {
                                CheckBigKingdoms(room);
                                break;
                            }
                        }
                    }
                }

                break;
            }

            default:
                break;
            }

            return(false);
        }
예제 #14
0
        public override void OnNullified(Room room, Player target, WrappedCard card)
        {
            RoomThread thread = room.RoomThread;

            string card_str = RoomLogic.CardToString(room, card);
            bool   move     = false;
            Player p        = null;

            if (movable)
            {
                List <Player> players       = new List <Player>();
                List <Player> count_players = new List <Player>(room.Players);
                Player        starter       = target;
                int           index         = count_players.IndexOf(starter);
                for (int i = index + 1; i < count_players.Count; i++)
                {
                    if (count_players[i].Alive)
                    {
                        players.Add(count_players[i]);
                    }
                }

                for (int i = 0; i <= index; i++)
                {
                    if (count_players[i].Alive)
                    {
                        players.Add(count_players[i]);
                    }
                }

                foreach (Player player in players)
                {
                    if (RoomLogic.PlayerContainsTrick(room, player, Name) || !player.JudgingAreaAvailable)
                    {
                        continue;
                    }

                    Skill skill = RoomLogic.IsProhibited(room, null, player, card);
                    if (skill != null)
                    {
                        skill = Engine.GetMainSkill(skill.Name);
                        LogMessage log = new LogMessage
                        {
                            Type = "#SkillAvoid",
                            From = player.Name,
                            Arg  = skill.Name,
                            Arg2 = Name
                        };
                        room.SendLog(log);
                        if (RoomLogic.PlayerHasShownSkill(room, player, skill))
                        {
                            room.NotifySkillInvoked(player, skill.Name);
                            GeneralSkin gsk        = RoomLogic.GetGeneralSkin(room, player, skill.Name);
                            string      genral     = gsk.General;
                            int         skin_id    = gsk.SkinId;
                            string      skill_name = skill.Name;
                            int         audio      = -1;
                            skill.GetEffectIndex(room, player, card, ref audio, ref skill_name, ref genral, ref skin_id);
                            if (audio >= -1)
                            {
                                room.BroadcastSkillInvoke(skill_name, "male", audio, genral, skin_id);
                            }
                        }
                        continue;
                    }
                    //if (player.HasFlag(card_str + "_delay_trick_cancel")) continue;

                    /*
                     * CardUseStruct use = new CardUseStruct(room.GetCard(card.GetEffectiveId()), null, player)
                     * {
                     *  EffectCount = new List<CardBasicEffect> { FillCardBasicEffct(room, player) }
                     * };
                     * object data = use;
                     * thread.Trigger(TriggerEvent.TargetConfirming, room, player, ref data);
                     * CardUseStruct new_use = (CardUseStruct)data;
                     * if (new_use.To.Count == 0)
                     * {
                     *  p = player;
                     *  player.SetFlags(card_str + "_delay_trick_cancel");
                     *  break;
                     * }
                     *
                     * thread.Trigger(TriggerEvent.TargetChosen, room, null, ref data);
                     * thread.Trigger(TriggerEvent.TargetConfirmed, room, player, ref data);
                     */
                    CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_TRANSFER, string.Empty)
                    {
                        Card = card
                    };
                    room.MoveCardTo(card, null, player, Place.PlaceDelayedTrick, reason, true);
                    move = true;

                    break;
                }
            }

            if (p != null)
            {
                OnNullified(room, p, card);
            }
            else if (!move)
            {
                //foreach (Player player in room.GetAllPlayers())
                //if (player.HasFlag(RoomLogic.CardToString(room, card) + "_delay_trick_cancel"))
                //player.SetFlags(string.Format("-{0}{1}", card_str, "_delay_trick_cancel"));

                CardMoveReason reason = new CardMoveReason(MoveReason.S_REASON_NATURAL_ENTER, string.Empty);
                room.MoveCardTo(card, null, Place.DiscardPile, reason, true);
            }
        }
예제 #15
0
        public override void Use(Room room, CardUseStruct card_use)
        {
            WrappedCard card = card_use.Card;

            if (card_use.To.Count == 0)
            {
                CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, card_use.From.Name, null, card.Skill, null)
                {
                    CardString = RoomLogic.CardToString(room, card_use.Card)
                };
                room.MoveCardTo(card, room.GetCardOwner(card.GetEffectiveId()), null, Place.DiscardPile, reason, true);
            }

            if (room.GetCardIdsOnTable(card).Count == 0)
            {
                return;
            }

            int    equipped_id = -1;
            Player target      = card_use.To[0];

            if (target.HasEquip((int)EquipLocation()))
            {
                equipped_id = target.GetEquip((int)EquipLocation());
            }

            List <CardsMoveStruct> exchangeMove = new List <CardsMoveStruct> {
            };
            CardsMoveStruct move1 = new CardsMoveStruct(card.GetEffectiveId(), target, Place.PlaceEquip,
                                                        new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, target.Name));

            move1.Reason.CardString = RoomLogic.CardToString(room, card_use.Card);
            exchangeMove.Add(move1);
            if (equipped_id != -1)
            {
                CardsMoveStruct move2 = new CardsMoveStruct(equipped_id, target, Place.PlaceTable,
                                                            new CardMoveReason(CardMoveReason.MoveReason.S_REASON_CHANGE_EQUIP, target.Name));
                exchangeMove.Add(move2);
            }
            room.MoveCardsAtomic(exchangeMove, true);

            LogMessage log = new LogMessage
            {
                From     = target.Name,
                Type     = "$Install",
                Card_str = card.GetEffectiveId().ToString()
            };

            room.SendLog(log);

            if (equipped_id != -1)
            {
                if (room.GetCardPlace(equipped_id) == Place.PlaceTable)
                {
                    CardsMoveStruct move3 = new CardsMoveStruct(equipped_id, null, Place.DiscardPile,
                                                                new CardMoveReason(CardMoveReason.MoveReason.S_REASON_CHANGE_EQUIP, target.Name));
                    room.MoveCardsAtomic(new List <CardsMoveStruct> {
                        move3
                    }, true);
                }
            }
        }
예제 #16
0
        public virtual void OnUse(Room room, CardUseStruct card_use)
        {
            Player player = card_use.From;

            room.SortByActionOrder(ref card_use);
            List <Player> targets = card_use.To;

            bool       hidden = (TypeID == CardType.TypeSkill && !WillThrow);
            LogMessage log    = new LogMessage("#UseCard")
            {
                From     = player.Name,
                To       = new List <string>(),
                Card_str = RoomLogic.CardToString(room, card_use.Card)
            };

            if (!TargetFixed(card_use.Card) || card_use.To.Count > 1 || !card_use.To.Contains(card_use.From))
            {
                log.SetTos(card_use.To);
            }


            List <int>             used_cards = new List <int>();
            List <CardsMoveStruct> moves      = new List <CardsMoveStruct>();

            used_cards.AddRange(card_use.Card.SubCards);

            RoomThread thread = room.RoomThread;
            object     data   = card_use;

            thread.Trigger(TriggerEvent.PreCardUsed, room, player, ref data);

            card_use = (CardUseStruct)data;

            if (TypeID != CardType.TypeSkill)
            {
                CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, player.Name, null, card_use.Card.Skill, null)
                {
                    CardString = RoomLogic.CardToString(room, card_use.Card),
                    General    = RoomLogic.GetGeneralSkin(room, player, card_use.Card.Skill, card_use.Card.SkillPosition)
                };
                if (card_use.To.Count == 1)
                {
                    reason.TargetId = card_use.To[0].Name;
                }

                foreach (int id in used_cards)
                {
                    CardsMoveStruct move = new CardsMoveStruct(id, null, Place.PlaceTable, reason);
                    moves.Add(move);
                }
                room.MoveCardsAtomic(moves, true);
                if (used_cards.Count == 0)
                {                                                                                 //show virtual card on table
                    CardsMoveStruct move = new CardsMoveStruct(-1, player, Place.PlaceTable, reason)
                    {
                        From_place       = Place.PlaceUnknown,
                        From             = player.Name,
                        Is_last_handcard = false,
                    };
                    room.NotifyUsingVirtualCard(RoomLogic.CardToString(room, card_use.Card), move);
                }

                room.SendLog(log);
                if (this is Collateral)
                { // put it here for I don't wanna repeat these codes in Card::onUse
                    Player victim = room.FindPlayer((string)card_use.To[0].GetTag("collateralVictim"), true);
                    if (victim != null)
                    {
                        log = new LogMessage("#CollateralSlash")
                        {
                            From = card_use.From.Name,
                            To   = new List <string> {
                                victim.Name
                            },
                        };
                        room.SendLog(log);
                        room.DoAnimate(AnimateType.S_ANIMATE_INDICATE, card_use.To[0].Name, victim.Name);
                    }
                }
            }
            else
            {
                CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_THROW, card_use.From.Name, null,
                                                           card_use.Card.Skill, null)
                {
                    CardString = RoomLogic.CardToString(room, card_use.Card),
                    General    = RoomLogic.GetGeneralSkin(room, player, card_use.Card.Skill, card_use.Card.SkillPosition)
                };

                FunctionCard card = Engine.GetFunctionCard(card_use.Card.Name);
                if (card is SkillCard && WillThrow)
                {
                    room.MoveCardTo(card_use.Card, card_use.From, null, Place.PlaceTable, reason, true);
                }
                room.SendLog(log);

                if (WillThrow)
                {
                    List <int> table_cardids = room.GetCardIdsOnTable(card_use.Card);
                    if (table_cardids.Count > 0)
                    {
                        CardsMoveStruct move = new CardsMoveStruct(table_cardids, player, null, Place.PlaceTable, Place.DiscardPile, reason);
                        room.MoveCardsAtomic(new List <CardsMoveStruct> {
                            move
                        }, true);
                    }
                }
            }
            room.RoomThread.Trigger(TriggerEvent.CardUsedAnnounced, room, player, ref data);
            room.RoomThread.Trigger(TriggerEvent.CardTargetAnnounced, room, player, ref data);

            room.RoomThread.Trigger(TriggerEvent.CardUsed, room, player, ref data);
            room.RoomThread.Trigger(TriggerEvent.CardFinished, room, player, ref data);
        }
예제 #17
0
        public override void OnEffect(Room room, CardEffectStruct effect)
        {
            WrappedCard card = effect.Card;

            if (room.GetCardIdsOnTable(card).Count == 0)
            {
                return;
            }

            LogMessage log = new LogMessage
            {
                From = effect.To.Name,
                Type = "#DelayedTrick",
                Arg  = card.Name
            };

            room.SendLog(log);

            JudgeStruct judge_struct = new JudgeStruct
            {
                Pattern        = judge.Pattern,
                Good           = judge.Good,
                Negative       = judge.Negative,
                Reason         = judge.Reason,
                PlayAnimation  = judge.PlayAnimation,
                Time_consuming = judge.Time_consuming,
                Who            = effect.To
            };

            room.Judge(ref judge_struct);
            if (judge_struct.IsEffected())
            {
                TakeEffect(room, effect.To, card);
                List <int> table_cardids = room.GetCardIdsOnTable(card);
                if (table_cardids.Count > 0)
                {
                    //DummyCard dummy(table_cardids);
                    CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_NATURAL_ENTER, null);
                    //room->moveCardTo(&dummy, NULL, Player::DiscardPile, reason, true);
                    CardsMoveStruct move = new CardsMoveStruct(table_cardids, null, Place.DiscardPile, reason);
                    room.MoveCardsAtomic(new List <CardsMoveStruct> {
                        move
                    }, true);
                }
            }
            else if (movable)
            {
                OnNullified(room, effect.To, card);
            }
            else
            {
                List <int> table_cardids = room.GetCardIdsOnTable(card);
                if (table_cardids.Count > 0)
                {
                    CardMoveReason  reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_NATURAL_ENTER, null);
                    CardsMoveStruct move   = new CardsMoveStruct(table_cardids, null, Place.DiscardPile, reason);
                    room.MoveCardsAtomic(new List <CardsMoveStruct> {
                        move
                    }, true);
                }
            }
        }
예제 #18
0
        public virtual void Use(Room room, CardUseStruct card_use)
        {
            WrappedCard   card           = card_use.Card;
            List <Player> targets        = card_use.To;
            List <string> nullified_list = room.GetTag("CardUseNullifiedList") != null ? (List <string>)room.GetTag("CardUseNullifiedList") : new List <string>();
            bool          all_nullified  = nullified_list.Contains("_ALL_TARGETS");

            foreach (Player target in targets)
            {
                CardEffectStruct effect = new CardEffectStruct
                {
                    Card      = card,
                    From      = card_use.From,
                    To        = target,
                    Multiple  = (targets.Count > 1),
                    Nullified = (all_nullified || nullified_list.Contains(target.Name)),
                    Drank     = card_use.Drank,
                };
                if (card_use.EffectCount != null)
                {
                    foreach (EffctCount count in new List <EffctCount>(card_use.EffectCount))
                    {
                        if ((count.From == card_use.From && count.To == target && count.Index == targets.IndexOf(target)) ||
                            (count.To == card_use.From && count.From == target) && count.Index == targets.IndexOf(target))
                        {
                            card_use.EffectCount.Remove(count);
                            if (effect.EffectCount != null)
                            {
                                effect.EffectCount.Add(count);
                            }
                            else
                            {
                                effect.EffectCount = new List <EffctCount> {
                                    count
                                }
                            };
                            break;
                        }
                    }
                }

                List <Player> players = new List <Player>();
                for (int i = targets.IndexOf(target); i < targets.Count; i++)
                {
                    if (!nullified_list.Contains(targets[i].Name) && !all_nullified)
                    {
                        players.Add(targets[i]);
                    }
                }
                room.SetTag("targets" + RoomLogic.CardToString(room, card), players);
                effect.StackPlayers = players;

                room.CardEffect(effect);
            }

            List <int> table_cardids = room.GetCardIdsOnTable(card);

            if (table_cardids.Count > 0)
            {
                CardMoveReason reason = new CardMoveReason(CardMoveReason.MoveReason.S_REASON_USE, card_use.From.Name, null, card.Skill, null)
                {
                    CardString = RoomLogic.CardToString(room, card)
                };
                if (targets.Count == 1)
                {
                    reason.TargetId = targets[0].Name;
                }
                CardsMoveStruct move = new CardsMoveStruct(table_cardids, card_use.From, null, Place.PlaceTable, Place.DiscardPile, reason);
                room.MoveCardsAtomic(new List <CardsMoveStruct> {
                    move
                }, true);
            }
        }