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; } }