diff --git a/docs/conf.py b/docs/conf.py index b3b44bff..acb56c98 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -70,7 +70,7 @@ exclude_patterns = [] # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'furo' +html_theme = 'sphinx_rtd_theme' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/docs/dev/hegemony.rst b/docs/dev/hegemony.rst index 01e47ea4..40a7e2f1 100644 --- a/docs/dev/hegemony.rst +++ b/docs/dev/hegemony.rst @@ -1,7 +1,7 @@ .. SPDX-License-Identifier: GFDL-1.3-or-later 国战实现相关碎碎念 -================= +================== 国战流程与身份版基本相同,就有一些有区别: @@ -14,14 +14,14 @@ 下面来一个个分析一下。胜利和奖惩已经在22写过了,不分析。 双将与同势力选将 ------------ +---------------- 双将好说,已经做完了。主要是同势力选将,可能需要单独写个处理函数吧。还有抽武将的时候也要避免出现没人同势力的情况啊。 简而言之就是UI加个同势力选项;同时,随机生成武将环节中如果可选人数小于X+1(X为游戏内势力数,一般为4),那么就抽X+1张,然后去掉多余的。 暗将与亮将 ----- +---------- 首先不要亮出武将,即别broadcast general,或者把general先设为暗将。 @@ -55,7 +55,7 @@ 然后就是UI了。这个得走cpp了谁让Lua服务端没有这种处理函数呢?(也根本不应该有,Lua和处理消息根本不在一个线程好吧)先不管这些,总之在暗将状态下,对于服务端notify到的触发型技能,给个预亮按钮。就换个按钮样式而已。主动和视为因为不影响烧条就照旧处理。就触发技弄成预亮键。视为技拼触发技的情况也弄成预亮hhh。 变回暗将 ------ +-------- 点名批评邹氏 @@ -64,7 +64,7 @@ changeHero成暗将然后notify获得即可。两人都暗了的话还要变势 明将就是先notify失去再changeHero。 调虎离山 ------ +-------- 将目标设为死人即可(删除) diff --git a/docs/diy/09-exppattern.rst b/docs/diy/09-exppattern.rst index ae2a3044..dde237e9 100644 --- a/docs/diy/09-exppattern.rst +++ b/docs/diy/09-exppattern.rst @@ -7,4 +7,44 @@ 你可能也已经注意到了,在不少Room中的askFor...函数中,出现了很多次pattern参数。这个pattern就是Exppattern,它用来辅助确定询问的卡牌必须满足哪些需求。 +由于用作参数的pattern基本都是string类型,所以这里主要围绕如何编写这种字符串来说。 +pattern的语法 +------------- + +一个完整的pattern是用多个 ``matcher`` 组成的,并用分号 ``;`` 相连接。 + +而每个单独的matcher的语法,则类似这样: + +.. code:: + + 牌名|点数|花色|区域|完整牌名|牌类型|牌id + +一个个来看看: + +- 牌名:能匹配的牌名,准确来说匹配的是 ``trueName`` 。比如slash也能匹配火杀。但反过来就不行了。 +- 点数:匹配的牌的点数。可以用波浪线表示范围:2~6等。 +- 花色:匹配的牌的花色,可以写heart, spade, club, diamond +- 区域:匹配的牌的区域,匹配hand(手牌区), equip(装备区),以及各种私人牌堆。 +- 完整牌名:类似牌名,但匹配的是 ``name`` 。 +- 牌类型:匹配牌的类型,可以写 basic, trick, equip +- 牌id:匹配牌的id + +在这每一项中,你可以用逗号 ``,`` 来分隔相应的项,让他能匹配多种情况。比如 ``slash,jink`` 就能同时匹配杀和闪。 + +你也可以使用 ``^`` 来否定某一个元素,这样会匹配除了他之外的卡牌。比如 ``.|.|.|.|.|.|^65`` 匹配所有id不为65的牌。 + +若想同时否定多个元素,则需要用括号,例如 ``^(3,5)`` 。 ``^3,^5`` 会被认为是匹配所有不是3或者所有不是5,这样一来就变成匹配所有了。 + +说到匹配所有,使用点号 ``.`` 即可让这一项匹配所有。默认情况下每一项都是匹配所有情况。 + +对pattern进行测试 +----------------- + +答案是使用dbg大法让游戏停下!然后可以用如下的代码测试一个pattern: + +.. code:: lua + + Exppattern:Parse(".|2~8"):match(card) + +至于card自己想办法获取吧,比如getCardById啥的。 diff --git a/docs/diy/10-eventstack.rst b/docs/diy/10-eventstack.rst new file mode 100644 index 00000000..f4cd41db --- /dev/null +++ b/docs/diy/10-eventstack.rst @@ -0,0 +1,124 @@ +.. SPDX-License-Identifier: GFDL-1.3-or-later + +解析:事件栈 +============ + +fk和神杀的一大区别就是拥有事件栈。下面对事件栈稍作解说并说明如何利用它让DIY更便捷。 + +何谓事件 +-------- + +相信各位对 *触发时机* 这个概念不会陌生。拿伤害举例吧,就涉及 *造成伤害时* 、 *受到伤害后* 等等时机。那么 *伤害* 本身呢?换句话说, ``room:damage`` 里面发生了啥? + +在神杀中,伤害就是直接执行一系列代码。Fk在这方面则是有区别的——它新建了一个伤害 *事件* ,然后执行这个事件(也就是正常的伤害流程)。 + +为什么要做一个事件机制呢?答案是为了更好的处理插结状况,以及实现老朱然(划掉 + +事件有以下几个特点: + +- 能携带额外信息: 这一点就让代码在插结的情况下也能正确运行 +- 能被随时中断而不影响游戏运行: 以胆为守! +- 即使被中断了也能清理现场: 后面会详细说说关于这个的注意事项 + +当然了,本文不会讨论事件机制的具体实现方法,而只会说明它在DIY能派上哪些用场。 + +初步观察事件栈 +-------------- + +Fk提供了一个方便的函数: ``GameLogic:dumpEventStack()`` ,它能输出当前的事件栈。你可以直接在代码中调用它,或者在用dbg大法调试代码时现场调用它。 + +总之来举个例子,我去洛神里面加一行给大伙看看效果好了: + +.. code:: lua + + on_use = function(self, event, target, player, data) + local room = player.room + room.logic:dumpEventStack() -- 打印此时事件栈 + room:obtainCard(player.id, data.card, false) + end, + +玩一下游戏,人机对我们使用了【杀】,我们掉血发动奸雄,此时可以看到这样的输出:(仅用作例子,实际上随着游戏的更新结果不一定相同) + +:: + + ===== Start of event stack dump ===== + + Stack level #7: GameEvent.SkillEffect + Stack level #6: GameEvent.Damage + Stack level #5: GameEvent.SkillEffect + Stack level #4: GameEvent.UseCard + Stack level #3: GameEvent.Phase + Stack level #2: GameEvent.Turn + Stack level #1: GameEvent.Round + + ===== End of event stack dump ===== + +来看看吧。栈顶层的就是当前的事件——SkillEffect,即技能生效事件。此时生效的技能是奸雄。然后往上一层就是伤害事件了,再往上是【杀】的生效事件,再往上是使用卡牌【杀】的事件,再往上是执行阶段事件(这里执行出牌阶段),再往上是执行回合,最底层的是执行轮次。 + +是不是很清晰的列出了所有插结情况呢?顺便一提,dumpEventStack还接收一个布尔型参数。如果你传一个true进去的话,能看到更加详细的输出,不过可能详细过头就是了。这种简略版输出是默认情况,刚好也便于说明。 + +如何调查事件栈 +-------------- + +Fk提供了一系列用来调查事件栈的函数。 + +首先是获取当前的游戏事件—— ``GameLogic:getCurrentEvent()`` 。这个函数会把事件栈栈顶的事件返回。 + +然后的东西就是根据事件来找比他更早的事件了,或者说找自己的父事件。 + +我们可以用 ``event.parent`` 获取这个游戏事件event的父事件。也就是刚好比他早一点的事件,在栈中处于它下层紧挨着的事件。比如前面的栈中,Damage事件的父事件是SkillEffect事件。 + +由于父事件也是事件,所以它也有parent属性,也就是说可以写出诸如 ``event.parent.parent...`` 的代码。当然了这样写不好看,也可能出bug,所以有一个方便的函数—— ``GameEvent:findParent(eventType)`` 。该函数像遍历链表一般的找到比这个事件更早的、类型符合参数指定的事件。比如 ``event:findParent(GameEvent.Turn)`` 就返回距离此事件最近的回合事件。 + +如何给事件附加数据 +------------------ + +事件虽是类的实例,但本质上是一张表。所以直接用 ``event.xxx = xxx`` 就能给他附加数据了。 + +获得数据也是一样的简单,用 ``event.xxx`` 就行了。 + +这样做的最大好处就是解决了插结问题。下面举个插结的例子以便大家能更加了解。 + +没有! + +如何终止事件 +------------ + +用 ``GameEvent:shutdown()`` 。这个函数能终止一切结算并结束这个事件。如果该事件不是栈顶的事件的话,那么会先逐一终止比他更晚发生的所有事件,然后再终止这个事件。 + +GameLogic里面也提供了方便的函数。 ``GameLogic:breakEvent()`` 可以终止当前事件。 ``GameLogic:breakTurn()`` 是个专为老朱然封装的函数,能终止一切结算并结束本回合。 + +还有个可能也是非常常用的:只要发生了任何错误,那么当前事件也会被终止。比如你不小心操作了本不该为nil的对象,或者直接手动调用error函数,或者发生assert failed等等报错后。这种情况下,事件终止更像是一种错误处理方式,而不是你真的想终止这个事件了。 + +.. note:: + + 在fk比较早期的时候,还没有事件机制一说。因此只要发生任何错误,都会整局游戏立刻停止(因为Lua报错导致自己停止运行了)。这是不是很糟糕呢?不小心写了个bug,结果整个游戏都卡住不动了。而有了事件机制后,bug只会影响当前事件而不至于威胁到整个游戏的进行。这也为拓展开发带来了更大的容错率啊。 + +关于事件的灾后清理 +------------------ + +在事件意外终止后,有一些事情也是要做的,并不是真正的直接终止结算走人了。比如在使用牌事件终止后,被使用的牌会从处理区进入弃牌堆,以及诸如此类的。 + +大家在制作DIY的时候应该会经常用到标记保存技能的相关数据。为了让事件即使被中断也能清理好这些标记,就要去熟悉这些事件终止时是如何执行清理的。 + +.. hint:: + + 这里提一下refresh only。所谓refresh only的触发方式,就是只会执行触发技的can_refresh和on_refresh,而不去管can_trigger之类的。结合refresh的定位,这是不是用来清理各种标记的绝好时机呢? + 下面的各种触发,如无特殊说明,都是refresh only的。 + +首先是阶段被终止后: + +- 清除所有玩家本阶段的卡牌/技能使用记录。 +- 清除所有玩家所有以-phase结尾的标记。 +- 触发EventPhaseEnd时机。 + +然后是回合被终止后: + +- 清除所有玩家本回合卡牌/技能使用记录以及-turn结尾的标记 +- 触发“结束阶段开始时” +- 触发“结束阶段结束时” +- 触发EventPhaseChanging:从结束阶段到NotActive +- 触发“NotActive开始时” +- 触发“回合结束时” + +以上就是常见的要注意的点,建议在编写用于清理标记的on_refresh时也考虑一下。 diff --git a/docs/diy/index.rst b/docs/diy/index.rst index 9b7d001e..9a0089ca 100644 --- a/docs/diy/index.rst +++ b/docs/diy/index.rst @@ -15,3 +15,4 @@ Diy文档 07-events.rst 08-debugging.rst 09-exppattern.rst + 10-eventstack.rst diff --git a/docs/requirements.txt b/docs/requirements.txt index e384c4d5..52e0f74b 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,2 @@ sphinx-lua -furo +sphinx-rtd-theme