标记与banner的使用
=====================

这位是FreeKill项目的通用概念，用于为角色、房间附加各种信息。
不过本文将针对三国杀中mark的行为，对此进行叙说。

用好标记功能，可以实现非常非常多的功能，说本游戏靠标记撑起来也不为过。

概念与基本的读写
------------------

标记（Mark）如同三国杀中角色的标记概念，但和技能描述中保存一个数值不同，
在FreeKill中还可以保存字符串、布尔、列表乃至几乎任何值
（严格来说，所有可以被编码为cbor的值，放入不合条件的值的话会产生报错）。

banner（横幅？不知道为什么会如此命名）则是对标记的拓展，可以理解为这是附着在房间上的、
本局游戏的全局标记。

标记和Banner的读取：

.. code:: lua

   player:getMark(key)
   room:getBanner(key)

由于历史原因（致敬太阳神三国杀导致的），当读取mark时，如果不存在该mark（即为nil）的话，
``getMark`` 会返回0而不是nil。而getBanner在这种情况下会返回nil。

当读取时，player可以是客户端或服务端。room可以是服务端Room或者客户端Client。

标记和banner的修改：

.. code:: lua

   room:setPlayerMark(player, key, value)
   room:setBanner(key, value)

修改标记或Banner只能在服务端执行。一样的，由于历史原因，把角色的标记设为0的话会导致标记实际上被设为nil。

标记或Banner的显示
------------------------

在三国杀中，标记和Banner在UI上的显示与交互逻辑是完全一致的，所以以下只讨论mark。

受太阳神三国杀影响，标记会根据 ``key`` 中是否有一些奇奇怪怪的前缀来决定如何显示。
一个大前提是，如果key是以 ``@`` 字符开头的，那么它是一个UI上可见的标记，否则就是隐藏标记。
``@`` 这个字符看起来也有点像一个圆圆的标记啊。

在太阳神三国杀中标记必须是一张图片（至少2015版如此）。新月杀中标记则默认是文字标记了，
因为我真的受够了每加一类标记全都要做一张图的感觉。以下是对各种前缀的汇总：

- 只有一个 ``@``：普通标记。标记的值可以是数字、字符串、列表。若为字符串，则会被翻译。
  若为字符串列表，则会被翻译之后再通过空格连接起来。若为其他的类型。。自己试试吧，好像默认走toString了。
  我的建议是给这类普通标记就使用这里提到的普通类型。
- ``@@``：简单标记。以这个前缀开头的标记什么都不显示，只显示标记名。
  常见于铁骑之类只需要标记一下状态的技能。
- ``@$``：卡牌标记。标记的值可以是数字列表（卡牌id列表）或字符串列表（牌名列表）。
  它在界面上显示数量（即列表长度），用户点击该标记后弹出一个框，显示具体卡牌。
- ``@&``：武将牌标记。标记的值是字符串列表（武将name列表）。行为类似卡牌标记。
- ``@!``：图片标记，适合怀念神杀之人或者单纯想要图片标记时。有点麻烦，一般不建议用。
  顺便图片素材的路径在 ``<package_root>/image/mark`` 下，图片文件的文件名也要带前缀。
- ``@!!``：带描述的图片标记，有悬浮窗提示标记功能。请参考已有例子吧。
- ``@[xxx]``：QML标记。不知道为什么会这样取名，实际上就是可以自定义标记值显示格式，
  以及点击后弹出何种对话框的标记。适用于比较复杂的场景，具体创建和使用的方法后文叙述。

banner的相关前缀同上。

卡牌的标记
----------------------

在三国杀中由于实践上的需要，卡牌也可以附加标记，所谓cardMark。

.. todo::

   懒得写了，待补

QML标记
------------------------

.. todo::

   懒得写了，待补

有特殊功能的标记
----------------------

结合实践经验，开发者们为相当常用的功能定义了一些特殊标记，一共有两种：

- 预定义好的特殊标记
- 名字中带有特定后缀的标记

下面罗列一下游戏中预定义的后缀类型，至于实际使用例遍地都是～

自动清理类
~~~~~~~~~~~~

下面几个后缀适用于角色标记、卡牌标记、Banner。

- ``-phase``：阶段结束时清理此标记
- ``-turn``：回合结束时清理此标记
- ``-round``：轮次结束时清理此标记

下面几个后缀适用于卡牌标记

- ``-inhand``：卡牌离开手牌区时清理

.. todo::

   懒得写了，待补

