Beispiel #1
0
        public override WrappedCard AskForSinglePeach(Player dying, DyingStruct dying_struct)
        {
            FunctionCard f_peach = Peach.Instance;
            FunctionCard f_ana   = Analeptic.Instance;

            if (self != dying & IsFriend(dying) && (CanSave(dying, 1 - dying.Hp) || dying.GetRoleEnum() == Player.PlayerRole.Lord))
            {
                if (dying.GetRoleEnum() != Player.PlayerRole.Lord && dying.IsNude() && !MaySave(dying) && !HasSkill(MasochismSkill))
                {
                    return(null);
                }

                List <WrappedCard> peaches = GetCards(Peach.ClassName, self);
                foreach (WrappedCard card in peaches)
                {
                    if (f_peach.IsAvailable(room, self, card) && Engine.IsProhibited(room, self, dying, card) == null)
                    {
                        return(card);
                    }
                }
            }
            else if (self == dying)
            {
                List <WrappedCard> peaches = new List <WrappedCard>();
                foreach (WrappedCard card in GetCards(Peach.ClassName, self))
                {
                    if (f_peach.IsAvailable(room, self, card) && Engine.IsProhibited(room, self, dying, card) == null)
                    {
                        peaches.Add(card);
                    }
                }
                foreach (WrappedCard card in GetCards(Analeptic.ClassName, self))
                {
                    if (f_ana.IsAvailable(room, self, card) && Engine.IsProhibited(room, self, dying, card) == null)
                    {
                        peaches.Add(card);
                    }
                }

                double      best   = -1000;
                WrappedCard result = null;
                foreach (WrappedCard card in peaches)
                {
                    double value = GetUseValue(card, self);
                    if (card.Name == Peach.ClassName)
                    {
                        value -= 2;
                    }
                    if (value > best)
                    {
                        best   = value;
                        result = card;
                    }
                }

                return(result);
            }

            return(null);
        }
Beispiel #2
0
        public static List <string> GuhuoCards(Room room, Player player)
        {
            List <string> guhuos = GetGuhuoCards(room, "btd");
            List <string> result = new List <string>();

            foreach (string name in guhuos)
            {
                FunctionCard fcard = Engine.GetFunctionCard(name);
                if (fcard is Slash && name != Slash.ClassName)
                {
                    continue;
                }
                if (fcard is Nullification && name != Nullification.ClassName)
                {
                    continue;
                }
                if (player.ContainsTag(string.Format("shefu_{0}", name)))
                {
                    continue;
                }

                result.Add(name);
            }

            return(result);
        }
Beispiel #3
0
        protected virtual void OnPhaseChanging(Room room, Player player, ref object data)
        {
            PhaseChangeStruct change = (PhaseChangeStruct)data;

            if (change.To == PlayerPhase.NotActive)
            {
                player.SetFlags(".");
                RoomLogic.ClearPlayerCardLimitation(player, true);
                foreach (Player p in room.GetAllPlayers())
                {
                    if (p.GetMark("drank") > 0)
                    {
                        LogMessage log = new LogMessage
                        {
                            Type = "#UnsetDrankEndOfTurn",
                            From = p.Name
                        };
                        room.SendLog(log);

                        room.SetPlayerMark(p, "drank", 0);
                    }
                }
                if (room.ContainsTag("EdictInvoke") && (bool)room.GetTag("EdictInvoke"))
                {
                    room.SetTag("EdictInvoke", false);
                    LogMessage log = new LogMessage
                    {
                        Type = "#EdictEffect",
                        From = player.Name,
                        Arg  = Edict.ClassName
                    };
                    room.SendLog(log);
                    WrappedCard io = (WrappedCard)room.GetTag("EdictCard");
                    if (io != null)
                    {
                        FunctionCard fcard = Engine.GetFunctionCard(io.Name);
                        foreach (Player p in room.GetAllPlayers())
                        {
                            if (!p.HasShownOneGeneral() && Engine.IsProhibited(room, null, p, io) == null) // from is null!
                            {
                                room.CardEffect(io, null, p);
                            }
                        }
                    }
                }
            }
            else if (change.To == PlayerPhase.Play)
            {
                player.AddHistory(".");
            }
            else if (change.To == PlayerPhase.Start)
            {
                if (!player.General1Showed && Engine.GetGeneral(player.ActualGeneral1, room.Setting.GameMode).IsLord())
                {
                    room.ShowGeneral(player);
                }
            }
        }
Beispiel #4
0
        public override ScoreStruct GetDamageScore(TrustedAI ai, DamageStruct damage)
        {
            ScoreStruct score = new ScoreStruct
            {
                Score = 0
            };

            if (damage.To != null && ai.HasSkill(Name, damage.To) && damage.Card != null)
            {
                score.Score = 1.2;
                FunctionCard fcard = Engine.GetFunctionCard(damage.Card.Name);
                if (!(fcard is SkillCard))
                {
                    foreach (int id in damage.Card.SubCards)
                    {
                        double value = Math.Max(ai.GetUseValue(id, damage.To, Player.Place.PlaceHand), ai.GetKeepValue(id, damage.To, Player.Place.PlaceHand));
                        score.Score += value * 0.45;
                    }

                    if (ai.WillSkipPlayPhase(damage.To))
                    {
                        score.Score /= 3;
                    }

                    if (damage.Damage >= damage.To.Hp)
                    {
                        score.Score /= 2;
                    }

                    if (damage.From != null && damage.From == damage.To && score.Score > 0)
                    {
                        score.Score /= 4;
                    }
                }

                if (damage.Damage > 1)
                {
                    score.Score /= 1.5;
                }
                if (ai.WillSkipPlayPhase(damage.To))
                {
                    score.Score /= 1.5;
                }

                if (ai.IsEnemy(damage.To))
                {
                    score.Score = -score.Score;
                }
                else
                {
                    score.Score -= 1.5;
                }
            }

            return(score);
        }
Beispiel #5
0
        public static List <string> GetGuhuoCards(Room room, string type)
        {
            List <string> all   = new List <string>();
            List <int>    cards = room.RoomCards;

            if (type.Contains("b"))
            {
                foreach (int id in cards)
                {
                    FunctionCard card = Engine.GetFunctionCard(Engine.GetRealCard(id).Name);
                    if (card is BasicCard && !all.Contains(card.Name))
                    {
                        all.Add(card.Name);
                    }
                }
            }

            if (type.Contains("t"))
            {
                foreach (int id in cards)
                {
                    FunctionCard card = Engine.GetFunctionCard(Engine.GetRealCard(id).Name);
                    if (card?.IsNDTrick() == true && !all.Contains(card.Name))
                    {
                        all.Add(card.Name);
                    }
                }
            }

            if (type.Contains("d"))
            {
                foreach (int id in cards)
                {
                    FunctionCard card = Engine.GetFunctionCard(Engine.GetRealCard(id).Name);
                    if (card?.IsNDTrick() == false && card is TrickCard && !all.Contains(card.Name))
                    {
                        all.Add(card.Name);
                    }
                }
            }

            return(all);
        }
 public override void DamageEffect(TrustedAI ai, ref DamageStruct damage, DamageStruct.DamageStep step)
 {
     if (damage.From != null && damage.Card != null && damage.From.HasWeapon(Name) && damage.Card.Name.Contains(Slash.ClassName) && !damage.Transfer && !damage.Chain)
     {
         Room       room = ai.Room;
         List <int> ids  = ai.GetKnownCards(damage.From);
         foreach (int id in ids)
         {
             if (damage.Card.SubCards.Contains(id))
             {
                 continue;
             }
             WrappedCard  card  = room.GetCard(id);
             FunctionCard fcard = Engine.GetFunctionCard(card.Name);
             if (fcard is Slash || fcard is Weapon)
             {
                 damage.Damage++;
                 break;
             }
         }
     }
 }
Beispiel #7
0
        public override double CardValue(TrustedAI ai, Player player, WrappedCard card, bool isUse, Player.Place place)
        {
            if (ai.HasSkill(Name) && ai.IsSituationClear())
            {
                FunctionCard fcard = Engine.GetFunctionCard(card.Name);
                if (fcard is DefensiveHorse || fcard is SpecialEquip)
                {
                    return(-2);
                }
            }

            if (!isUse && ai.IsCard(card.GetEffectiveId(), Slash.ClassName, player))
            {
                Player jiangwei = ai.FindPlayerBySkill(Name);
                if (jiangwei != null && !ai.IsFriend(jiangwei, player) && RoomLogic.CanSlash(ai.Room, player, jiangwei))
                {
                    return(2);
                }
            }

            return(0);
        }
        public override List <int> OnExchange(TrustedAI ai, Player player, string pattern, int min, int max, string pile)
        {
            Room room = ai.Room;

            if (room.GetTag(Name) is DamageStruct damage)
            {
                ScoreStruct score = ai.GetDamageScore(damage);
                damage.Damage++;
                ScoreStruct _score = ai.GetDamageScore(damage);
                if (_score.Score - score.Score > 3)
                {
                    List <int> ids = new List <int>();
                    foreach (int id in player.GetCards("h"))
                    {
                        if (!RoomLogic.CanDiscard(room, player, player, id))
                        {
                            continue;
                        }
                        WrappedCard  card  = room.GetCard(id);
                        FunctionCard fcard = Engine.GetFunctionCard(card.Name);
                        if (fcard is Slash || fcard is Weapon)
                        {
                            ids.Add(id);
                        }
                    }

                    if (ids.Count > 0)
                    {
                        ai.SortByUseValue(ref ids, false);
                        return(new List <int> {
                            ids[0]
                        });
                    }
                }
            }

            return(new List <int>());
        }
Beispiel #9
0
        public override List <WrappedCard> GetGuhuoCards(Room room, List <WrappedCard> cards, Player player)
        {
            List <WrappedCard> result = new List <WrappedCard>();

            foreach (string name in GuhuoCards(room, player))
            {
                FunctionCard fcard = Engine.GetFunctionCard(name);
                if (fcard is Slash && name != Slash.ClassName)
                {
                    continue;
                }
                if (player.ContainsTag(string.Format("shefu_{0}", name)))
                {
                    continue;
                }

                WrappedCard card = new WrappedCard(name);
                card.AddSubCards(cards);
                result.Add(card);
            }

            return(result);
        }
Beispiel #10
0
        public override double UseValueAdjust(TrustedAI ai, Player player, List <Player> targets, WrappedCard card)
        {
            Room room = ai.Room;

            if (ai.HasSkill("nuzhan", player) && targets.Count > 0)
            {
                WrappedCard  wrapped = room.GetCard(card.GetEffectiveId());
                FunctionCard fcard   = Engine.GetFunctionCard(wrapped.Name);
                if (fcard is TrickCard)
                {
                    return(2);
                }
                if (fcard is EquipCard)
                {
                    return(1.5);
                }
            }
            else if (targets.Count > 0)
            {
                return(0);
            }

            return(-1);
        }
Beispiel #11
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);
        }
Beispiel #12
0
        protected virtual void OnCardUsed(Room room, Player player, ref object data)
        {
            if (data is CardUseStruct card_use)
            {
                RoomThread thread = room.RoomThread;

                FunctionCard fcard = Engine.GetFunctionCard(card_use.Card.Name);
                WrappedCard  card  = card_use.Card;
                if (fcard.HasPreact)
                {
                    fcard.DoPreAction(room, player, card);
                    data = card_use;
                }

                room.AddUseList(card_use);
                card_use.EffectCount = new List <CardBasicEffect>();
                foreach (Player p in card_use.To)
                {
                    card_use.EffectCount.Add(fcard.FillCardBasicEffct(room, p));
                }
                data = card_use;

                if (card_use.From != null)
                {
                    thread.Trigger(TriggerEvent.TargetChoosing, room, card_use.From, ref data);
                    CardUseStruct new_use = (CardUseStruct)data;
                }

                card_use = (CardUseStruct)data;
                if (card_use.From != null && card_use.To.Count > 0)
                {
                    foreach (CardBasicEffect effect in card_use.EffectCount)
                    {
                        effect.Triggered = false;
                    }

                    while (card_use.EffectCount.Count > 0)
                    {
                        bool check = true;
                        int  count = card_use.EffectCount.Count;
                        for (int i = 0; i < count; i++)
                        {
                            CardBasicEffect effect = card_use.EffectCount[i];
                            if (!effect.Triggered)
                            {
                                check = false;
                                thread.Trigger(TriggerEvent.TargetConfirming, room, effect.To, ref data);
                                effect.Triggered = true;
                                break;
                            }
                        }

                        if (check)
                        {
                            break;
                        }

                        card_use = (CardUseStruct)data;
                    }
                }

                card_use = (CardUseStruct)data;

                if (card_use.From != null && card_use.To.Count > 0)
                {
                    thread.Trigger(TriggerEvent.TargetChosen, room, card_use.From, ref data);
                    for (int i = 0; i < card_use.EffectCount.Count; i++)
                    {
                        CardBasicEffect effect = card_use.EffectCount[i];
                        effect.Triggered = false;
                        thread.Trigger(TriggerEvent.TargetConfirmed, room, effect.To, ref data);
                        effect.Triggered = true;
                    }
                }

                card_use = (CardUseStruct)data;
                fcard.Use(room, card_use);
            }
        }
Beispiel #13
0
        protected virtual void OnPhaseProceed(Room room, Player player, ref object data)
        {
            switch (player.Phase)
            {
            case PlayerPhase.Judge:
            {
                List <int> tricks = new List <int>(player.JudgingArea);
                while (tricks.Count > 0 && player.Alive)
                {
                    WrappedCard trick = room.GetCard(tricks[tricks.Count - 1]);
                    tricks.RemoveAt(tricks.Count - 1);
                    bool on_effect = room.CardEffect(trick, null, player);
                    if (!on_effect)
                    {
                        FunctionCard card = Engine.GetFunctionCard(trick.Name);
                        card.OnNullified(room, player, trick);
                    }
                }
                break;
            }

            case PlayerPhase.Draw:
            {
                int num = (int)data;
                if (num > 0)
                {
                    room.DrawCards(player, num, "gamerule");
                }
                room.RoomThread.Trigger(TriggerEvent.AfterDrawNCards, room, player, ref data);

                break;
            }

            case PlayerPhase.Play:
            {
                bool add_index = true;
                while (player.Alive && string.IsNullOrEmpty(room.PreWinner))
                {
                    room.Activate(player, out CardUseStruct card_use, add_index);
                    if (card_use.Card != null)
                    {
                        add_index = room.UseCard(card_use);
                    }
                    else
                    {
                        break;
                    }
                }
                break;
            }

            case PlayerPhase.Discard:
            {
                List <int> handcards = new List <int>();
                foreach (int id in player.GetCards("h"))
                {
                    if (!Engine.IgnoreHandCard(room, player, id))
                    {
                        handcards.Add(id);
                    }
                }

                int discard_num = handcards.Count - RoomLogic.GetMaxCards(room, player);
                if (discard_num > 0)
                {
                    room.AskForDiscard(player, handcards, "gamerule", discard_num, discard_num);
                }

                break;
            }

            default:
                break;
            }
        }
Beispiel #14
0
        protected virtual void OnCardUsed(Room room, Player player, ref object data)
        {
            if (data is CardUseStruct card_use)
            {
                RoomThread thread = room.RoomThread;

                FunctionCard fcard = Engine.GetFunctionCard(card_use.Card.Name);
                WrappedCard  card  = card_use.Card;
                if (fcard.HasPreact)
                {
                    fcard.DoPreAction(room, player, card);
                    data = card_use;
                }

                List <Player>        targets  = card_use.To;
                List <CardUseStruct> use_list = room.ContainsTag("card_proceeing") ?
                                                (List <CardUseStruct>)room.GetTag("card_proceeing") : new List <CardUseStruct>(); //for serval purpose, such as AI
                use_list.Add(card_use);
                room.SetTag("card_proceeing", use_list);

                if (card_use.From != null)
                {
                    thread.Trigger(TriggerEvent.TargetChoosing, room, card_use.From, ref data);
                    CardUseStruct new_use = (CardUseStruct)data;
                    targets = new_use.To;
                }

                if (card_use.From != null && targets.Count > 0)
                {
                    List <Player> targets_copy = new List <Player>(targets);
                    foreach (Player to in targets_copy)
                    {
                        if (targets.Contains(to))
                        {
                            thread.Trigger(TriggerEvent.TargetConfirming, room, to, ref data);
                            CardUseStruct new_use = (CardUseStruct)data;
                            targets = new_use.To;
                            if (targets.Count == 0)
                            {
                                break;
                            }
                        }
                    }
                }

                card_use = (CardUseStruct)data;
                if (card_use.From != null && card_use.To.Count > 0)
                {
                    thread.Trigger(TriggerEvent.TargetChosen, room, card_use.From, ref data);
                    foreach (Player p in card_use.To)
                    {
                        thread.Trigger(TriggerEvent.TargetConfirmed, room, p, ref data);
                    }
                }
                card_use = (CardUseStruct)data;
                if (card_use.NullifiedList != null)
                {
                    room.SetTag("CardUseNullifiedList", card_use.NullifiedList);
                }
                fcard.Use(room, card_use);
            }
        }
Beispiel #15
0
        public override void Event(TriggerEvent triggerEvent, Player player, object data)
        {
            if (!self.Alive)
            {
                return;
            }

            base.Event(triggerEvent, player, data);

            if (triggerEvent == TriggerEvent.EventPhaseStart || triggerEvent == TriggerEvent.BuryVictim)
            {
                UpdatePlayers();
            }

            if (triggerEvent == TriggerEvent.CardsMoveOneTime && data is CardsMoveOneTimeStruct move)
            {
                bool   open      = false;
                bool   pile_open = false;
                Player from      = move.From;
                Player to        = move.To;

                foreach (Player p in room.GetAlivePlayers())
                {
                    if (p.HasFlag("Global_GongxinOperator") && (p == self || self.IsSameCamp(p)))
                    {
                        open = true;
                        break;
                    }
                }

                if ((from != null && (from == self || self.IsSameCamp(from))) || (to != null && (to == self || self.IsSameCamp(to)) && move.To_place != Player.Place.PlaceSpecial))
                {
                    open = true;
                }

                if (!open && to != null && !string.IsNullOrEmpty(move.To_pile_name) && !move.To_pile_name.StartsWith("#") && move.To != null)
                {
                    if (move.To.GetPileOpener(move.To_pile_name).Count == room.GetAllPlayers(true).Count)
                    {
                        pile_open = true;
                    }
                    else
                    {
                        foreach (string name in move.To.GetPileOpener(move.To_pile_name))
                        {
                            Player who = room.FindPlayer(name, true);
                            if (who != null && (who == self || self.IsSameCamp(who)))
                            {
                                open = true;
                                break;
                            }
                        }
                    }
                }

                if (to != null && move.To_place == Player.Place.PlaceHand)
                {
                    foreach (int id in move.Card_ids)
                    {
                        int         index = move.Card_ids.IndexOf(id);
                        WrappedCard card  = room.GetCard(id);
                        if (card.HasFlag("visible") || pile_open ||
                            move.From_places[index] == Player.Place.PlaceEquip || move.From_places[index] == Player.Place.PlaceDelayedTrick ||
                            move.From_places[index] == Player.Place.DiscardPile || move.From_places[index] == Player.Place.PlaceTable)
                        {
                            public_handcards[to].Add(id);
                            private_handcards[to].Add(id);
                            ClearCardLack(to, id);
                        }
                        else if (open)
                        {
                            private_handcards[to].Add(id);
                            ClearCardLack(to, id);
                        }
                        else
                        {
                            ClearCardLack(to);
                        }
                    }
                }

                if (to != null && move.To_place == Player.Place.PlaceSpecial && move.To_pile_name == "wooden_ox")
                {
                    foreach (int id in move.Card_ids)
                    {
                        if (open)
                        {
                            wooden_cards[to].Add(id);
                        }
                    }
                }

                if (from != null && move.From_places.Contains(Player.Place.PlaceHand))
                {
                    foreach (int id in move.Card_ids)
                    {
                        if (room.GetCard(id).HasFlag("visible") || pile_open || move.To_place == Player.Place.PlaceEquip ||
                            move.To_place == Player.Place.PlaceDelayedTrick || move.To_place == Player.Place.DiscardPile ||
                            move.To_place == Player.Place.PlaceTable)
                        {
                            public_handcards[from].RemoveAll(t => t == id);
                            private_handcards[from].RemoveAll(t => t == id);
                        }
                        else
                        {
                            public_handcards[from].Clear();
                            if (open)
                            {
                                private_handcards[from].RemoveAll(t => t == id);
                            }
                            else
                            {
                                private_handcards[from].Clear();
                            }
                        }
                    }
                }

                if (from != null && move.From_places.Contains(Player.Place.PlaceSpecial) && move.From_pile_names.Contains("wooden_ox"))
                {
                    foreach (int id in move.Card_ids)
                    {
                        int index = move.Card_ids.IndexOf(id);
                        if (open && move.From_pile_names[index] == "wooden_ox" && move.From_places[index] == Player.Place.PlaceSpecial)
                        {
                            wooden_cards[move.From].RemoveAll(t => t == id);
                        }
                    }
                }

                foreach (int id in move.Card_ids)
                {
                    int         index = move.Card_ids.IndexOf(id);
                    WrappedCard card  = room.GetCard(id);
                    if (move.From_places[index] == Player.Place.DrawPile)
                    {
                        if (move.To != null && move.To_place == Player.Place.PlaceHand && card.HasFlag("visible2" + self.Name))
                        {
                            private_handcards[move.To].Add(id);
                        }

                        if (guanxing.Key != null && guanxing.Value.Contains(id))
                        {
                            if (guanxing.Value[0] != id)
                            {
                                List <int> top_cards = new List <int>(guanxing.Value);
                                for (int y = top_cards.IndexOf(id); y < top_cards.Count; y++)
                                {
                                    guanxing.Value.RemoveAt(y);
                                }
                            }
                            else
                            {
                                guanxing.Value.RemoveAll(t => t == id);
                            }
                            if (guanxing.Value.Count == 0)
                            {
                                guanxing = new KeyValuePair <Player, List <int> >();
                            }
                        }
                    }
                }
            }

            if (triggerEvent == TriggerEvent.CardTargetAnnounced && data is CardUseStruct use)
            {
                FunctionCard fcard      = Engine.GetFunctionCard(use.Card.Name);
                string       class_name = fcard.Name;
                if (fcard is Slash)
                {
                    class_name = Slash.ClassName;
                }
                UseCard e = Engine.GetCardUsage(class_name);
                if (e != null)
                {
                    e.OnEvent(this, triggerEvent, player, data);
                }
            }

            if (triggerEvent == TriggerEvent.ChoiceMade && data is string str)
            {
                List <string> choices = new List <string>(str.Split(':'));
                foreach (SkillEvent e in skill_events.Values)
                {
                    if (e.Key.Contains(choices[0]))
                    {
                        e.OnEvent(this, triggerEvent, player, data);
                    }
                }

                foreach (UseCard e in Engine.GetCardUsages())
                {
                    if (e.Key.Contains(choices[0]))
                    {
                        e.OnEvent(this, triggerEvent, player, data);
                    }
                }

                if (choices[0] == "viewCards")
                {
                    List <int> ids = player.GetCards("h");
                    if (choices[choices.Count - 1] == "all")
                    {
                        public_handcards[player]  = ids;
                        private_handcards[player] = ids;
                    }
                    else if (choices[choices.Count - 1] == self.Name)
                    {
                        private_handcards[player] = ids;
                    }
                }
                else if (choices[0] == "showCards")
                {
                    List <int> ids = JsonUntity.StringList2IntList(new List <string>(choices[2].Split('+')));
                    if (choices[choices.Count - 1] == "all")
                    {
                        foreach (int id in ids)
                        {
                            if (!public_handcards[player].Contains(id))
                            {
                                public_handcards[player].Add(id);
                            }
                            if (!private_handcards[player].Contains(id))
                            {
                                private_handcards[player].Add(id);
                            }
                        }
                    }
                    else if (choices[choices.Count - 1] == self.Name)
                    {
                        foreach (int id in ids)
                        {
                            if (!private_handcards[player].Contains(id))
                            {
                                private_handcards[player].Add(id);
                            }
                        }
                    }
                }
                else if (choices[0] == "cardShow")
                {
                    int id = int.Parse(choices[choices.Count - 1].Substring(1, choices[choices.Count - 1].Length - 2));
                    if (!public_handcards[player].Contains(id))
                    {
                        public_handcards[player].Add(id);
                    }
                    if (!private_handcards[player].Contains(id))
                    {
                        private_handcards[player].Add(id);
                    }
                }
                else if (choices[0] == "ViewTopCards" || choices[0] == "ViewBottomCards")
                {
                    bool       open     = choices[choices.Count - 1] == "open";
                    List <int> drawpile = new List <int>(room.DrawPile);
                    List <int> moves    = JsonUntity.StringList2IntList(new List <string>(choices[2].Split('+')));
                    if (choices[0] == "ViewTopCards")
                    {
                        guanxing = new KeyValuePair <Player, List <int> >();
                        if (open)
                        {
                            for (int index = 0; index < moves.Count; index++)
                            {
                                int id = moves[index];
                                room.SetCardFlag(id, "visible");
                            }
                        }
                        else
                        {
                            foreach (int id in moves)
                            {
                                if (player == self || player.IsSameCamp(self))
                                {
                                    room.SetCardFlag(id, "visible2" + self.Name);
                                }
                            }

                            guanxing = new KeyValuePair <Player, List <int> >(player, moves);
                        }
                    }
                    else
                    {
                        if (open)
                        {
                            for (int index = 0; index < moves.Count; index++)
                            {
                                int id = moves[index];
                                room.SetCardFlag(id, "visible");
                            }
                        }
                        else
                        {
                            foreach (int id in moves)
                            {
                                room.SetCardFlag(id, "visible2" + choices[1]);
                            }
                        }
                    }
                }
            }
        }