游戏流程相关
=============

房主按下开始游戏按钮后，系统会创建一个最根本的事件——游戏事件。
然后大家就开始确定好座位、选择武将、开始游戏等等。

游戏开始之前
--------------

这里指的是第一轮开始之前。仔细观察会发现，最开始的那阵子游戏显示为“第0轮”，
这时还没有任何轮次发生过。
此时可以触发“游戏准备时”，此时机无承担者，无data数据
fk.GamePrepared   @游戏准备时


1. 所有玩家随机排列座位。
2. 发放身份牌，其中主公的身份公开。
3. 主公选择武将并展示，然后所有其他玩家同时选择武将。
4. 所有玩家展示自己的武将。
5. 将一号位（主公）设为当前行动者。
6. 准备好牌堆。
7. 根据玩家的选将，每个玩家对应的角色获得武将牌上的技能。
8. 触发“游戏开始前”
9. 分发初始手牌
10. 进入无限循环，每次循环的内容是执行一个轮次事件

第9999轮时，游戏平局。

分发初始手牌
---------------

::

  从当前行动者开始，对每名角色:
    以该角色为承担者，触发“分发初始手牌前”
    fk.DrawInitialCards     @摸初始牌时
    该角色摸4张牌（不触发任何时机，摸牌数可能被修改）

  所有玩家选择是否使用手气卡，手气卡的作用是重新获得新的初始手牌

  从当前行动者开始，对每名角色:
    以该角色为承担者，触发“分发初始手牌后”
    fk.AfterDrawInitialCards = 14   @在摸初始牌后（在手气卡后）
    两个时机的data是DrawInitialData，继承DrawInitialDataSpec类型。


需要注意的是，初始手牌的摸牌不触发移动牌相关时机（移牌前、移牌后）。
这也是先说明移动牌事件的原因。

轮次事件
---------------

分发完初始手牌后，游戏便开始无限的执行轮次事件。

轮次事件，顾名思义就是一轮游戏，即从一号位开始所有角色各执行一个额定回合的
行为。所有角色按逆时针顺序执行回合。当下个行动者的座位号比当前行动者的座位号
相等或者更小的情况下，轮次事件结束。

具体结算方式如下：

::

  若这是第一轮，则:
  以当前行动者为承担者，触发“游戏开始时”
  fk.GameStart   @游戏开始时

  以当前行动者为承担者，触发“轮次开始时”
  fk.RoundStart   @轮次开始时


  无限循环:
    当前行动者进行一个回合
    将当前行动者设为下家
    若当前行动者的座位不大于自己上家的座位:
      结束此循环

  以当前行动者的上家为承担者，触发“轮次结束时”，“轮次结束后”
  fk.RoundEnd    @轮次结束时
  fk.AfterRoundEnd   @轮次结束后

  触发“游戏开始时”，还有相关的轮次时机时，data都是RoundData，继承RoundDataSpec类型的数据

在上述的循环中，所有角色都确保能执行一个回合。当出现座位号变小的情况时，
说明此时已经执行完一轮了，这时轮次事件结束。

回合事件
-------------

回合事件包含了前置判断、主效果和清理效果。三种效果的结算逻辑如下：

::
  回合准备：

  （此为前置判断）
  若该角色处于休整状态，则将其休整轮数-1，若完成休整则复活该角色
  若该角色已阵亡，则判断未通过

  以该角色为承担者，触发“回合准备时”（这个时机返回true会导致判断未通过，跳过本回合）
  fk.PreTurnStart   @回合准备时

  若该角色的武将牌背面向上，则将武将牌翻面至正面向上，然后判断未通过

  以该角色为承担者，触发“回合开始前”（这个时机返回true会导致判断未通过，跳过本回合）
  fk.BeforeTurnStart   @回合开始前


  判断顺利通过。

::

  （此为主效果，需通过前置判断方可执行）
  以该角色为承担者，触发“回合开始时”
  fk.TurnStart     @回合开始时
  回合事件的data均为TurnData，继承TurnDataSpec

  令所有阶段为[准备阶段，判定阶段，摸牌阶段，出牌阶段，弃牌阶段，结束阶段]
  对所有阶段中的每个阶段，依次执行:
    将该角色的阶段设为该阶段
    若阶段未被跳过，则:
      以该角色为承担者，触发“阶段切换时”（可能导致阶段被跳过）
      （若在触发本时机技能的on_use函数中设置data.skipped为true则导致本时机被跳过）
      fk.EventPhaseChanging    @阶段切换时

    若阶段被跳过，data.skipped为true，则:
      以该角色为承担者，触发“阶段跳过时”
      （若在触发本时机技能的on_use函数中设置data.skipped为true则执行本时机函数）
      fk.EventPhaseSkipping     @阶段跳过时

      若触发“阶段跳过时”后，以该角色为承担者，触发“阶段跳过后”。
      （若在触发本时机技能的on_use函数中设置data.skipped为true则执行本时机函数）

      fk.EventPhaseSkipped    @阶段跳过后

     阶段的data均为PhaseData，继承PhaseDataSpec 

    若阶段未被跳过，data.skipped不为true，则:
      该角色执行阶段事件
    否则跳过本阶段
 
  阶段都执行完了，将该角色的阶段设为“回合外”

::

  （此为清理效果）
  以该角色为承担者，触发“回合结束时”
  fk.TurnEnd     @回合结束时
  data为TurnData，继承TurnDataSpec
  
  以该角色为承担者，触发“回合改变时”
  fk.EventTurnChanging   @回合改变时
  data={
    from   ServerPlayer  @当前回合角色, 
    to   ServerPlayer  @当前回合角色的下家，
    skipRoundPlus  boolean  @是否跳过轮数
  }

阶段事件
-----------

::

  （主效果）
  以该角色为承担者，触发“阶段开始时”（可能导致事件结束）
  （若在触发本时机技能的on_use函数中return true则导致本阶段终止）  
  fk.EventPhaseStart   @阶段开始时

  以该角色为承担者，触发“阶段进行时”
  fk.EventPhaseProceeding   @阶段进行时
  两个时机的data均为PhaseData，继承PhaseDataSpec

  根据角色当前阶段的不同，执行不同的结算:
    若是判定阶段，则:
      对判定区内所有牌按后进来先判定的顺序依次进行:
        将此牌移动到处理区
        执行此牌的效果（一般会令角色进行判定）
        执行此牌的后续效果（置入弃牌堆或者置入下家判定区，或者别的）
    若是摸牌阶段，则:
      以该角色为承担者，触发“摸牌阶段摸牌时”（可能改变摸牌数量）
      fk.DrawNCards   @摸牌阶段摸牌时

      该角色摸2张牌
      以该角色为承担者，触发“摸牌阶段摸牌后”
      fk.AfterDrawNCards   @摸牌阶段摸牌后
    两个时机的data均为DrawNCardsData，继承DrawNCardsDataSpec 
    若是出牌阶段，则:
      可使用任意张牌和技能，直到阶段结束（主动结束或者被动结束）
    若是弃牌阶段，则:
      该角色将手牌弃置至手牌上限，不能弃置不计入手牌上限的

::

  （清理效果）
  以该角色为承担者，触发“阶段结束时”
  fk.EventPhaseEnd   @阶段结束时

  data均为PhaseData，继承PhaseDataSpec


游戏结束
----------

在游戏结束时触发的时机

::
    无触发者
    fk.GameFinished   @游戏结束时

    data数据为winner， winner string @ 获胜的身份，空字符串表示平局

::