• 欢迎来到Minecraft插件百科!
  • 对百科编辑一脸懵逼?帮助:快速入门带您快速熟悉百科编辑!
  • 因近日遭受攻击,百科现已限制编辑,有意编辑请加入插件百科企鹅群:223812289

BetonQuest:修订间差异

来自Minecraft插件百科
跳转到导航 跳转到搜索
无编辑摘要
 
(未显示3个用户的8个中间版本)
第1行: 第1行:
{{待完善}}
{{Bukkit Plugin Infobox
{{Bukkit Plugin Infobox
|插件名=BetonQuest
|插件名=BetonQuest
|图标=[[文件:BetonQuestLOGO.png]]
|版本=v1.7.3
|版本=v1.7.3
|前置插件=无
|前置插件=无
第6行: 第8行:
|網址=http://dev.bukkit.org/bukkit-plugins/betonquest/
|網址=http://dev.bukkit.org/bukkit-plugins/betonquest/
}}
}}
<center>[[文件:BetonQuestLOGO.png]]</center>
'''BetonQuest'''是一个好用的任务插件。它不像传统的插件将任务与对话绑定,而是网状多选结构(即类似Gal的剧情系统)。
 


你的任务不一定要像普通单线任务"击杀, 带来物品, 获得奖励"一样,你可以创建多条任务线,通过与NPC的对话,玩家可以进入不同的任务线,获得不同的任务奖励。


{{待完善}}
[[Category:娱乐]] [[Category:角色]]
BetonQuest是一个好用的任务插件。它不像传统的插件将任务与对话绑定,而是网状多选结构(即类似Gal的剧情系统)。<br>
你的任务不一定要像普通单线任务"击杀, 带来物品, 获得奖励"一样,你可以创建多条任务线,通过与NPC的对话,玩家可以进入不同的任务线,获得不同的任务奖励。
== 特点 ==
== 特点 ==
*你的冒险不止一条路可以走
*你的冒险不止一条路可以走
第36行: 第34行:
*可备份的配置及数据
*可备份的配置及数据
*自动升级
*自动升级
== 概览 ==
== 概览 ==
这插件到底怎样运作?我将以一个简单的伐木任务为例来描述。请注意“事件”、“条件”和“目标”之间的区别。<br>
这插件到底怎样运作?我将以一个简单的伐木任务为例来描述。请注意“事件”、“条件”和“目标”之间的区别。<br>
第44行: 第43行:
这些对话可以像在Baldur's Gate或是Skyrim一样有多种路线,任务可以有多种方式来结束,也可以有很多不同的影响玩家声誉的结局,就靠你来决定了。<br>
这些对话可以像在Baldur's Gate或是Skyrim一样有多种路线,任务可以有多种方式来结束,也可以有很多不同的影响玩家声誉的结局,就靠你来决定了。<br>
这个插件也包含了一个在书中的日志。你玩过Morrowind吗? 它们差不多一样,我们只是保留了你查看日志的顺序,所以你不必翻好几百页。现在完成任务并不需要显示像“你收集了所有的矿石,现在回到矿工那儿!”这样的信息。反之,它可以更新玩家的日志,加入像这样的新的记录:“我收集了所有的矿石,我需要回到矿工那儿去拿奖励!”。这样会显得真实得多。
这个插件也包含了一个在书中的日志。你玩过Morrowind吗? 它们差不多一样,我们只是保留了你查看日志的顺序,所以你不必翻好几百页。现在完成任务并不需要显示像“你收集了所有的矿石,现在回到矿工那儿!”这样的信息。反之,它可以更新玩家的日志,加入像这样的新的记录:“我收集了所有的矿石,我需要回到矿工那儿去拿奖励!”。这样会显得真实得多。
== 安装 ==
== 安装 ==
#首先您可以安装Citizens插件,你可以在[http://dev.bukkit.org/bukkit-plugins/citizens/ Bukkit]找到它.
#首先您可以安装Citizens插件,你可以在[http://dev.bukkit.org/bukkit-plugins/citizens/ Bukkit]找到它.
第51行: 第51行:
#如果您不想使用自动更新,在禁用它之前,请重新启动服务器或重新加载插件.
#如果您不想使用自动更新,在禁用它之前,请重新启动服务器或重新加载插件.
#当您认为完成之后,您可以重新加载插件(/q reload).现在让我们来学习BetonQuests插件的基础知识吧.
#当您认为完成之后,您可以重新加载插件(/q reload).现在让我们来学习BetonQuests插件的基础知识吧.
== 配置 ==
'''#请勿修改Version选项,他可能会导致你的配置文件被覆盖。'''
在config.yml中有几个选项,我将尽可能的叙述那些在使用这个插件前,你可能需要修改的选项。其余的选项都是在本文档中相应的小节叙述的。
<br />'''MySQL''':如果你使用MySQL当作数据库,请填写其内容,留空将使用SQLite作为数据库。
<br />'''update''':这部分控制着更新系统,
<br />'''enable''':选项默认设置为true,他控制着整个更新系统是否工作。
<br />'''download_bugfixes''':控制着BetonQuest如果自动更新,是否下载最新的已经修复BUG的版本。 (比如1.7.3 -> 1.7.4 或 1.8.1 -> 1.8.3),这些版本并不改变插件工作的方式,只是修复了BUG的版本,推荐将这项设置为True。
<br />'''notify_new_release''':这个选项负责在启动的时候检测是否有新的版本,若有就通知(比如1.7.6 - > 1.8),因为这些更新可能引入新特性或改变工作方式,所以他们不会自动下载。当你准备好更新的时候,你可以使用/q update指令。
<br />如果你使用一个开发版本,这里将会有三个选项:'''notify_dev_build''',它和'''notify_new_release'''是一样的,但是他会检测是否有开发版本可以替换。在这里没有特定的版本检查,如果发现dev的数量较高,这个就会出现。你下载开发版本应当承担你的责任(原文:You download development builds on your own responsibility.)
<br />'''Language''':设置插件的语言: 目前有7种语言:英语(en),德国(de),法国(fr),西班牙(es),中国(cn)、荷兰(nl)和波兰(pl)。
<br />'''sounds''':这个选项定义了在不同的场合播放的声音。'''start'''和'''end'''节点定义了当对话开始和结束的时候所播放的声音。'''journal''' 节点定义了当任务笔记更新时所播放的声音。'''update'''节点定义了指当日志文件更新时,所播放提醒玩家的声音。'''full'''节点定义了当玩家使用/j command,但是背包已经满了的情况下播放。所有的可能的声音名称可以
[https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Sound.html 在这]找到。
<br />'''combat_delay''':这个节点定义了一个战斗延迟系统(以秒为单位),定义了玩家必须在战斗结束多长时间后才可以开始对话。
<br />'''notify_pullback''':这个选项定义了玩家在对话中试图离开是否禁止。
<br />'''default_package''':这里写了一个默认包的名称,当你使用/q command 的时候默认是对应这个包。
<br />'''cmd_blacklist''':这是一个列表,代表了在会话中不能使用的命令,注意这里仅可以输入一个词。
<br />'''hook''':这里控制了是否与其他插件互动,你可以在这里关掉。
<br />'''remove_items_after_respawn'''如果你不设置gamerule的keepInventory(死亡掉落),请保持这个选项的启用,它可以防止死后其他玩家复制任务的物品,玩家死亡之后,他的任务物品的掉落物将会被删除,并且放到他的背包里。但是有些插件可能试图恢复玩家背包内的所有物品(例如WorldGuard开启keep-inventory)
== 指令 ==
== 指令 ==
  /j – 给予一本日志
  /j – 给予一本日志
第69行: 第90行:
  /q vector <packname.variable> <newvariable>: 计算第一个位置变量到你的位置并且储存到第二个参数中
  /q vector <packname.variable> <newvariable>: 计算第一个位置变量到你的位置并且储存到第二个参数中
  /questlang <lang> - 改变玩家的语言(如果由控制台使用就可以改变全局语言)
  /questlang <lang> - 改变玩家的语言(如果由控制台使用就可以改变全局语言)
=== 缩写 ===
=== 缩写 ===
*'''/j:''' bj, journal, bjournal, betonjournal, betonquestjournal
*'''/j:''' bj, journal, bjournal, betonjournal, betonquestjournal
第98行: 第120行:
*使用'/q create beton' 你可以创建一个名为'beton'的任务,它将会与默认任务相同。<br>
*使用'/q create beton' 你可以创建一个名为'beton'的任务,它将会与默认任务相同。<br>
*/q vector 命令可以让你创建一个由第一个位置变量到你的位置的矢量。结果会储存到"vectors.{第二参数}"
*/q vector 命令可以让你创建一个由第一个位置变量到你的位置的矢量。结果会储存到"vectors.{第二参数}"
== 权限 ==
== 权限 ==
*betonquest.admin – 允许使用管理员命令(/q ...)且可以创建NPC
*betonquest.admin – 允许使用管理员命令(/q ...)且可以创建NPC
第103行: 第126行:
*betonquest.backpack –允许使用/backpack 指令(默认为玩家)
*betonquest.backpack –允许使用/backpack 指令(默认为玩家)
*betonquest.conversation -允许与NPC对话(默认为玩家)betonquest.language -允许改变的语言(默认为玩家)
*betonquest.conversation -允许与NPC对话(默认为玩家)betonquest.language -允许改变的语言(默认为玩家)
=== 使用教程 ===
 
== 使用教程 ==
安装插件之后你首先想到的应该是怎么使用它。如果你想使用GUI,将''default_conversation_IO''修改为''chest'',之后保存文件并且在服务器上使用''/q reload''命令。
安装插件之后你首先想到的应该是怎么使用它。如果你想使用GUI,将''default_conversation_IO''修改为''chest'',之后保存文件并且在服务器上使用''/q reload''命令。
登录并在随意位置放一个彩色粘土。在它上面放一个头(例如僵尸的头)并且在粘土块的一侧放一个牌子。填写如下内容
登录并在随意位置放一个彩色粘土。在它上面放一个头(例如僵尸的头)并且在粘土块的一侧放一个牌子。填写如下内容
第109行: 第133行:
Innkeeper'''
Innkeeper'''
右键这个NPC,将会出现对话。如果没有,检查你是否成功地制作了NPC。Innkeeper会让你砍一些树,你可以看到日志有了新的记录,不要放置原木然后摧毁, BetonQuest会检测方块的数量,你只能去砍树。如果你是创造模式,给自己16个原木。之后,你可以返回NPC那里得到奖励
右键这个NPC,将会出现对话。如果没有,检查你是否成功地制作了NPC。Innkeeper会让你砍一些树,你可以看到日志有了新的记录,不要放置原木然后摧毁, BetonQuest会检测方块的数量,你只能去砍树。如果你是创造模式,给自己16个原木。之后,你可以返回NPC那里得到奖励
==== 使用事件和条件 ====
 
=== 使用事件和条件 ===
现在你会了非常基础的东西。我们不能做出来一个完整的对话,因为它们使用了很多事件与条件,所以我们要了解它们。去阅读词汇参考或者继续阅读教程
现在你会了非常基础的东西。我们不能做出来一个完整的对话,因为它们使用了很多事件与条件,所以我们要了解它们。去阅读词汇参考或者继续阅读教程
===== 事件 =====
 
==== 事件 ====
让我们从默认包中打开''events.yml''。添加新的一行:''foo: message Hello world!''这是一个事件的指令字符。BetonQuest使用它来确定事件的类型和它要做的事情。''foo''是事件的名字,''message''是一个类型,并且Hello world!告诉message需要显示什么。在这种情况下,如果你运行''foo''事件,它会显示Hello owrld!信息。保存这个文件,使用''/q reload''命令然后使用''/q e foo''运行事件(q是quest缩写,e是event缩写,<名称>是你的Minecraft名字,没有括号,foo是我们创建的事件名称)。它会显示一个Hello world!信息
让我们从默认包中打开''events.yml''。添加新的一行:''foo: message Hello world!''这是一个事件的指令字符。BetonQuest使用它来确定事件的类型和它要做的事情。''foo''是事件的名字,''message''是一个类型,并且Hello world!告诉message需要显示什么。在这种情况下,如果你运行''foo''事件,它会显示Hello owrld!信息。保存这个文件,使用''/q reload''命令然后使用''/q e foo''运行事件(q是quest缩写,e是event缩写,<名称>是你的Minecraft名字,没有括号,foo是我们创建的事件名称)。它会显示一个Hello world!信息
创建另一个更复杂的事件。比如传送,它需要一个参数,''location''(位置)。在''events.yml''中添加一行:''bar: location 100;200;300;world(<事件名称>:location:x;y;z;<世界名称>)''。保存文件,重新加载插件,然后运行事件。
创建另一个更复杂的事件。比如传送,它需要一个参数,''location''(位置)。在''events.yml''中添加一行:''bar: location 100;200;300;world(<事件名称>:location:x;y;z;<世界名称>)''。保存文件,重新加载插件,然后运行事件。
祝贺你,你刚刚创建了你的第一个事件。继续做一些其他事件类型的实验。你可以在事件列表中找到它们。你完成了开始学习的条件。
祝贺你,你刚刚创建了你的第一个事件。继续做一些其他事件类型的实验。你可以在事件列表中找到它们。你完成了开始学习的条件。
===== 条件 =====
 
==== 条件 ====
打开conditions.yml并添加新的一行:''foo: location 100;200;300;world;5''很明显,命名方式与事件相同,但它们没有任何联系。条件名称和事件名称是无关的,因此你可以给它们相同的名称。现在让我们看看指令字符。你可以认为地点是一种条件,它会检查玩家是否在附近。注意,最后一个参数是一个整数,5。这是检查的范围。完成了吗?做完了就保存文件并重新加载插件吧。
打开conditions.yml并添加新的一行:''foo: location 100;200;300;world;5''很明显,命名方式与事件相同,但它们没有任何联系。条件名称和事件名称是无关的,因此你可以给它们相同的名称。现在让我们看看指令字符。你可以认为地点是一种条件,它会检查玩家是否在附近。注意,最后一个参数是一个整数,5。这是检查的范围。完成了吗?做完了就保存文件并重新加载插件吧。
现在,走到你在条件所定义的位置,使用''/q c foo''(C是''condition''的缩写)。它应该会显示“''checking condition blah blah blah: true''”。我们把焦点放在最后的那个词,''true''。这意味着你满足条件:你站的位置在5格之内。现在移动2格,再次使用命令,你仍应符合条件。现在尝试走4格,它应该会显示false。你现在已经在5格之外。明白了吗?太好了!
现在,走到你在条件所定义的位置,使用''/q c foo''(C是''condition''的缩写)。它应该会显示“''checking condition blah blah blah: true''”。我们把焦点放在最后的那个词,''true''。这意味着你满足条件:你站的位置在5格之内。现在移动2格,再次使用命令,你仍应符合条件。现在尝试走4格,它应该会显示false。你现在已经在5格之外。明白了吗?太好了!
现在,我告诉了你最简单地使用这些条件。再次打开''events.yml''文件,并在foo字符末尾添加条件:''foo argument''。顺便说一下,最好重命名foo事件为baz,这样名字不会混淆。现在你应该有这样的一行:''message Hello world!  conditions: foo''baz事件只会在foo条件为true时运行。重载插件,走到5格之外,尝试运行''baz''事件。漂亮,什么都没有发生。这是因为你不符合''foo''条件。走进范围再次尝试运行事件。它应该显示hello world!消息。
现在,我告诉了你最简单地使用这些条件。再次打开''events.yml''文件,并在foo字符末尾添加条件:''foo argument''。顺便说一下,最好重命名foo事件为baz,这样名字不会混淆。现在你应该有这样的一行:''message Hello world!  conditions: foo''baz事件只会在foo条件为true时运行。重载插件,走到5格之外,尝试运行''baz''事件。漂亮,什么都没有发生。这是因为你不符合''foo''条件。走进范围再次尝试运行事件。它应该显示hello world!消息。
为我们完成了这样一个条件庆祝吧(ahaaaa lolllllll 2333333),那么问题来了,如果你想在玩家不在范围内时显示消息,该怎么做呢?(我不告诉你[doge])别担心,你不用''specifyinverted_location''条件或其他的什么(那么问题来了,那串英文是什么意思呢?)。你可以简单地否定条件,否定使条件以完全相反的方式运作,在这种情况下,条件只会在玩家在范围外时成立。打开''events.yml''并在''foo''条件前加一个感叹号(半角 ! ),现在应该是这样:''baz: message Hello world! conditions:!foo'',这表示“当''foo''不成立时显示Hello world!”保存文件,重新加载插件,运行事件然后乱跑一会儿,看看它是如何工作的。(对了,那串英文是反转_位置的意思啦,非要翻译就是相位反转_位面!xddddd[特定反转_位置])
为我们完成了这样一个条件庆祝吧(ahaaaa lolllllll 2333333),那么问题来了,如果你想在玩家不在范围内时显示消息,该怎么做呢?(我不告诉你[doge])别担心,你不用''specifyinverted_location''条件或其他的什么(那么问题来了,那串英文是什么意思呢?)。你可以简单地否定条件,否定使条件以完全相反的方式运作,在这种情况下,条件只会在玩家在范围外时成立。打开''events.yml''并在''foo''条件前加一个感叹号(半角 ! ),现在应该是这样:''baz: message Hello world! conditions:!foo'',这表示“当''foo''不成立时显示Hello world!”保存文件,重新加载插件,运行事件然后乱跑一会儿,看看它是如何工作的。(对了,那串英文是反转_位置的意思啦,非要翻译就是相位反转_位面!xddddd[特定反转_位置])
==== 标签基础 ====
 
=== 标签基础 ===
现在,你学会了怎么用事件与条件。之后,我会告诉你什么是标签(tag)。创建两个个新的事件''add_beton_tag: tag add beton''和''del_beton_tag: tag del beton''。取事件名称时,要注意与内容相关,否则很容易混淆,很不方便。假设你有100个事件,foo24,bar65等等。你也许会迅速的被闪瞎。所以, ''add_beton_tag''  标签给玩家添加了''beton''标签,''del_beton_tag'' 移除了它。保存文件,重载插件并且运行事件。什么都没发生还是成功了呢?使用''/q t''命令(t是tags的缩写。)它会显示标签列表。现在我们注意一下''default.beton'',当然,''default''是包名,并且''beton''是标签名,并且在''add_beton_tag''事件中定义了。现在运行''del_beton_tag''事件,猜猜会发生什么?''default.beton''标签消失了!综上可知,添加删除标签的方法。
现在,你学会了怎么用事件与条件。之后,我会告诉你什么是标签(tag)。创建两个个新的事件''add_beton_tag: tag add beton''和''del_beton_tag: tag del beton''。取事件名称时,要注意与内容相关,否则很容易混淆,很不方便。假设你有100个事件,foo24,bar65等等。你也许会迅速的被闪瞎。所以, ''add_beton_tag''  标签给玩家添加了''beton''标签,''del_beton_tag'' 移除了它。保存文件,重载插件并且运行事件。什么都没发生还是成功了呢?使用''/q t''命令(t是tags的缩写。)它会显示标签列表。现在我们注意一下''default.beton'',当然,''default''是包名,并且''beton''是标签名,并且在''add_beton_tag''事件中定义了。现在运行''del_beton_tag''事件,猜猜会发生什么?''default.beton''标签消失了!综上可知,添加删除标签的方法。
没有什么是可以犯错的,标签是BetonQuest中最有用的东西之一。它们需要通过tag条件来使用。打开''conditions.yml''并且添加''has_beton_tag: tag beton''。你可以认为''tag''是一种条件(和''tag''事件相同,但它们不是一样的,一个是事件,另一个是条件)''beton''是标签的名字。你没有指定''default.beton'',但你可以这样做。保存,重载插件并且检查条件。它会显示true。
没有什么是可以犯错的,标签是BetonQuest中最有用的东西之一。它们需要通过tag条件来使用。打开''conditions.yml''并且添加''has_beton_tag: tag beton''。你可以认为''tag''是一种条件(和''tag''事件相同,但它们不是一样的,一个是事件,另一个是条件)''beton''是标签的名字。你没有指定''default.beton'',但你可以这样做。保存,重载插件并且检查条件。它会显示true。
现在你应该了解了这个方便的系统。你可以当玩家第一次与NPC交流时
现在你应该了解了这个方便的系统。你可以当玩家第一次与NPC交流时
添加一个标签,并且当NPC获取到这个标签他会说一些不同的话,比如“欢迎回来”。
添加一个标签,并且当NPC获取到这个标签他会说一些不同的话,比如“欢迎回来”。
==== 创建目标 ====
 
=== 创建目标 ===
是时候写一些目标了!打开''objectives.yml''并且添加一行''kill_creepers: mobkill creeper 3 events:bar conditions:has_beton_tag''。让我们分析一下它。''kill_creepers''是目标的条件, ''mobkill''是任务类型。为了完成任务,玩家需要杀一些怪物,''creeper''是一种怪物,所以我们知道这些怪物必须是苦力怕。3是数量,它意味着玩家必须杀3个苦力怕。''event:bar''意味着任务完成后激发bar事件。''conditions:has_beton_tag''告诉我们只有玩家拥有beton标签时任务才可以完成。保存,重载并且使用''/q o add kill_creepers''命令(o是目标,add告诉插件添加一个目标)。
是时候写一些目标了!打开''objectives.yml''并且添加一行''kill_creepers: mobkill creeper 3 events:bar conditions:has_beton_tag''。让我们分析一下它。''kill_creepers''是目标的条件, ''mobkill''是任务类型。为了完成任务,玩家需要杀一些怪物,''creeper''是一种怪物,所以我们知道这些怪物必须是苦力怕。3是数量,它意味着玩家必须杀3个苦力怕。''event:bar''意味着任务完成后激发bar事件。''conditions:has_beton_tag''告诉我们只有玩家拥有beton标签时任务才可以完成。保存,重载并且使用''/q o add kill_creepers''命令(o是目标,add告诉插件添加一个目标)。
你现在可以用''/q o''命令来检查目标是否创建成功,它会显示所有活动的目标。它应该显示''default.kill_creepers''。之后,删除beton标签然后杀几个苦力怕。当你杀了三个之后你发现什么都没发生。这是因为has_beton_tag条件不工作了,所以目标不会计数。现在再添加标签并且杀苦力怕。当第三个死了之后你会传送到bar事件定义的位置。
你现在可以用''/q o''命令来检查目标是否创建成功,它会显示所有活动的目标。它应该显示''default.kill_creepers''。之后,删除beton标签然后杀几个苦力怕。当你杀了三个之后你发现什么都没发生。这是因为has_beton_tag条件不工作了,所以目标不会计数。现在再添加标签并且杀苦力怕。当第三个死了之后你会传送到bar事件定义的位置。
恭喜你!你学会了怎么用目标!你需要多做实验,因为任务中经常会使用它。仔细看看创建对话,你就完成了基础!
恭喜你!你学会了怎么用目标!你需要多做实验,因为任务中经常会使用它。仔细看看创建对话,你就完成了基础!
==== 创建对话 ====
 
=== 创建对话 ===
现在你理解了BetonQuest的事件、条件、目标,是时候创建一发对话了!在默认包里有一个''conversations''文件夹。里面只有一个文件,''innkeeper.yml''。这是''innkeepe''r的对话文件,就是那个让你砍树的人。参考它来完成你的第一个对话吧。创建一个新文件,命名为''miner.yml''。输入(为了学的更快,不要复制!)以下内容
现在你理解了BetonQuest的事件、条件、目标,是时候创建一发对话了!在默认包里有一个''conversations''文件夹。里面只有一个文件,''innkeeper.yml''。这是''innkeepe''r的对话文件,就是那个让你砍树的人。参考它来完成你的第一个对话吧。创建一个新文件,命名为''miner.yml''。输入(为了学的更快,不要复制!)以下内容
'''quester: Miner
'''quester: Miner
第190行: 第220行:
== 条件、事件、目标 ==
== 条件、事件、目标 ==
Condition(条件), event(事件), objectives(目标)被定义为“指令字符”。它可以匹配包含condition/event/objective的文字。感谢这些字符知道它们需要做什么。如果你想使用这些指令字符,请看下面的参考。它描述了这些指令字符的作用和用法。所有的指令字符都在特定的文件中定义,例如所有条件都在condition.yml.中配置。定义语法:''name: 'the instruction string containing the data'''。单引号大多情况可以省略(建议不省略)。以下,我会更详细地描述使用方法
Condition(条件), event(事件), objectives(目标)被定义为“指令字符”。它可以匹配包含condition/event/objective的文字。感谢这些字符知道它们需要做什么。如果你想使用这些指令字符,请看下面的参考。它描述了这些指令字符的作用和用法。所有的指令字符都在特定的文件中定义,例如所有条件都在condition.yml.中配置。定义语法:''name: 'the instruction string containing the data'''。单引号大多情况可以省略(建议不省略)。以下,我会更详细地描述使用方法
=== 条件 ===
=== 条件 ===
条件是创建高级任务必不可少的工具。它们可以让你控制玩家在对话中可以选择哪些选项,NPC如何回应这些选项或者任务目标完成。所有可能的条件参考如下。
条件是创建高级任务必不可少的工具。它们可以让你控制玩家在对话中可以选择哪些选项,NPC如何回应这些选项或者任务目标完成。所有可能的条件参考如下。
第195行: 第226行:
现在你拥有了一个条件
现在你拥有了一个条件
使用它来检查玩家是否正在做这个任务并且阻止他再做一次。当然,这个标签将会在任务开始之后添加,通过事件
使用它来检查玩家是否正在做这个任务并且阻止他再做一次。当然,这个标签将会在任务开始之后添加,通过事件
=== 事件 ===
=== 事件 ===
在某些时候你想让一些事情发生。刷新日志,设置标签,给予奖励,这些需要事件来完成。你需要像条件一样通过指令字符和指定名字定义它。你可以在事件参考中找到所有的给事件用的指令字符。在指令字符后面你可以添加条件:使用逗号分隔条件一类的东西,例如:''angry,!quest_started''。这将会让事件在条件达成时触发。
在某些时候你想让一些事情发生。刷新日志,设置标签,给予奖励,这些需要事件来完成。你需要像条件一样通过指令字符和指定名字定义它。你可以在事件参考中找到所有的给事件用的指令字符。在指令字符后面你可以添加条件:使用逗号分隔条件一类的东西,例如:''angry,!quest_started''。这将会让事件在条件达成时触发。
=== 目标 ===
=== 目标 ===
当你在创建任务的时候,任务目标是最主要的。你可以用一个指令字符“objective”来创建一个任务目标。这些可以在objectives.yml文件中定义,在说明文字的后面,你可以为目标添加条件或者事件。条件即限制任务的完成条件(比如需要城镇的入口防卫,在给定的任务地点击杀僵尸),事件会在任务完成时触发(比如给予奖励,或者设置一个标签,当从NPC上获得奖励时标签会激活),你可以在说明位置后面按照这样的格式去定义:“''conditions:条件1,条件2 events:事件1,事件2''”,用逗号去分割,而不是用空格。
当你在创建任务的时候,任务目标是最主要的。你可以用一个指令字符“objective”来创建一个任务目标。这些可以在objectives.yml文件中定义,在说明文字的后面,你可以为目标添加条件或者事件。条件即限制任务的完成条件(比如需要城镇的入口防卫,在给定的任务地点击杀僵尸),事件会在任务完成时触发(比如给予奖励,或者设置一个标签,当从NPC上获得奖励时标签会激活),你可以在说明位置后面按照这样的格式去定义:“''conditions:条件1,条件2 events:事件1,事件2''”,用逗号去分割,而不是用空格。
第204行: 第237行:
== 支持插件 ==
== 支持插件 ==
BetonQuest可以支持其他的插件,使用它们的功能。目前有三个插件: Citizens, Vault and MythicMobs.
BetonQuest可以支持其他的插件,使用它们的功能。目前有三个插件: Citizens, Vault and MythicMobs.
=== Citizens ===
=== Citizens ===
如果你有这个插件就可以创建NPC 来对话。我非常建议安装这个插件,NPC可以让对话更真实。Citizens也可以让你的NPC击杀的目标。
如果你有这个插件就可以创建NPC 来对话。我非常建议安装这个插件,NPC可以让对话更真实。Citizens也可以让你的NPC击杀的目标。
==== NPC击杀目标 ''npckill'' ====
==== NPC击杀目标 ''npckill'' ====
NPC击杀目标需要玩家击杀指定ID的NPC。你也可以设置杀多少次NPC。目标名称后面必须是NPC的ID。你可以用''amount:'' 设置数字。<br>
NPC击杀目标需要玩家击杀指定ID的NPC。你也可以设置杀多少次NPC。目标名称后面必须是NPC的ID。你可以用''amount:'' 设置数字。
 
'''例子:''' ''npckill 16 amount:3 events:reward label:citizens''
'''例子:''' ''npckill 16 amount:3 events:reward label:citizens''
==== NPC互动目标 ====
==== NPC互动目标 ====
玩家必须与指定ID的NPC交互。它也可以关闭动作,这样对话就不会触发了。第一个参数是数字(NPC的ID)第二个是设置项 ''cancel''.<br>
玩家必须与指定ID的NPC交互。它也可以关闭动作,这样对话就不会触发了。第一个参数是数字(NPC的ID)第二个是设置项 ''cancel''.
 
'''例子:''' ''npcinteract 3 cancel conditions:sneak events:steal label:stealing''
'''例子:''' ''npcinteract 3 cancel conditions:sneak events:steal label:stealing''
=== Vault ===
=== Vault ===
安装Vault你可以有权限事件和金钱条件/事件。
安装Vault你可以有权限事件和金钱条件/事件。
==== 权限事件 ''permission'' ====
==== 权限事件 ''permission'' ====
删除或者增加一个组的权限。第一个参数是''add''或者''remove'',这很好理解。第二个是 ''perm''或者''group'',这个也不难弄清楚。下一个就是你要添加或者删除的字符串。最后你需要指定一个世界。如果世界为空的话,这个修改就会变成全局的。<br>
删除或者增加一个组的权限。第一个参数是''add''或者''remove'',这很好理解。第二个是 ''perm''或者''group'',这个也不难弄清楚。下一个就是你要添加或者删除的字符串。最后你需要指定一个世界。如果世界为空的话,这个修改就会变成全局的。
 
'''例子:''' ''permission remove group bandit world_nether''
'''例子:''' ''permission remove group bandit world_nether''
==== 金钱事件 ''money'' ====
==== 金钱事件 ''money'' ====
从玩家的帐户存取款,只有一个参数,就是数量,它可以是负数。<br>
从玩家的帐户存取款,只有一个参数,就是数量,它可以是负数。
 
'''例子:''' ''money -100''
'''例子:''' ''money -100''
==== 金钱条件 ''money'' ====
==== 金钱条件 ''money'' ====
检查玩家的金钱是否足够,也只有一个参数,即需要达到的数值,不能为负<br>
检查玩家的金钱是否足够,也只有一个参数,即需要达到的数值,不能为负
 
'''例子:''' ''money 500''
'''例子:''' ''money 500''
=== MythicMobs ===
=== MythicMobs ===
你可以设置MythicMobs怪物击杀目标和MythicMobs生成怪物的事件。
你可以设置MythicMobs怪物击杀目标和MythicMobs生成怪物的事件。
==== MythicMobs怪物击杀目标 ''mmobkill'' ====
==== MythicMobs怪物击杀目标 ''mmobkill'' ====
完成这个目标需要击杀指定数量的指定怪物。第一个参数必须是怪物的内部名称(在MythicMobs的配置中有)。你可以添加''amount:''来指定击杀的数量<br>
完成这个目标需要击杀指定数量的指定怪物。第一个参数必须是怪物的内部名称(在MythicMobs的配置中有)。你可以添加''amount:''来指定击杀的数量
 
'''例子:''' ''mmobkill SkeletalKnight amount:2 events:reward label:mythicmobs''
'''例子:''' ''mmobkill SkeletalKnight amount:2 events:reward label:mythicmobs''
==== MythicMobs怪物生存事件 ''mspawnmob'' ====
==== MythicMobs怪物生存事件 ''mspawnmob'' ====
在指定的地方生成指定数量的怪。第一个参数应该是位置,格式是''100;200;300;world''。第二个是MythicMobs的内部名字(在MythicMobs的配置中有)后面跟一个冒号和等级。第三个是数量(必填)<br>
在指定的地方生成指定数量的怪。第一个参数应该是位置,格式是''100;200;300;world''。第二个是MythicMobs的内部名字(在MythicMobs的配置中有)后面跟一个冒号和等级。第三个是数量(必填)
 
'''例子:''' ''mspawnmob 100;200;300;world SkeletalKnight:1 5''
'''例子:''' ''mspawnmob 100;200;300;world SkeletalKnight:1 5''
=== Skript ===
=== Skript ===
BetonQuest也可以与Skript联动。为了避免混淆,我会使用插件的名称(Skript的一些事件BetonQuestnt也有。Skript可以让你通过脚本使用BetonQuest的事件,并且也可以用BetonQuest执行脚本。
BetonQuest也可以与Skript联动。为了避免混淆,我会使用插件的名称(Skript的一些事件BetonQuestnt也有。Skript可以让你通过脚本使用BetonQuest的事件,并且也可以用BetonQuest执行脚本。
==== Skript事件通过 BetonQuest ''skript'' 事件触发 ====
==== Skript事件通过 BetonQuest ''skript'' 事件触发 ====
这里描述了Skript事件和BetonQuest事件。
这里描述了Skript事件和BetonQuest事件。
第239行: 第291行:
'''例子:''' 脚本: ''on betonquest event "concrete" ''
'''例子:''' 脚本: ''on betonquest event "concrete" ''
events.yml:''fire_concrete_script: skript concrete''
events.yml:''fire_concrete_script: skript concrete''
==== Skript条件 ====
==== Skript条件 ====
你可以用 ''player meets [betonquest] condition "id"'' 语句检查BetonQuest 的条件。Betonquest是配置项,并且 ''id'' 是条件名称,在conditions.yml中定义。
你可以用 ''player meets [betonquest] condition "id"'' 语句检查BetonQuest 的条件。Betonquest是配置项,并且 ''id'' 是条件名称,在conditions.yml中定义。
'''例子:'''脚本: ''player meets condition "has_ore"''
'''例子:'''脚本: ''player meets condition "has_ore"''
conditions.yml: ''has_ore: item iron_ore:5''
conditions.yml: ''has_ore: item iron_ore:5''
==== Skript事件 ====
==== Skript事件 ====
你可以用脚本触发BetonQuest事件。Skript的语句是''fire [betonquest] event "id" for player''。
你可以用脚本触发BetonQuest事件。Skript的语句是''fire [betonquest] event "id" for player''。
'''例子:'''脚本: ''fire event "give_emeralds" for player''
'''例子:'''脚本: ''fire event "give_emeralds" for player''
events.yml:''give_emeralds: give emerald:5''
events.yml:''give_emeralds: give emerald:5''
=== WorldGuard ===
=== WorldGuard ===
==== WorldGuard区域目标 ''region'' ====
==== WorldGuard区域目标 ''region'' ====
完成这个目标需要进入指定区域,唯一的参数是区域名称。
完成这个目标需要进入指定区域,唯一的参数是区域名称。
'''例子:''' ''region beton events:kill label:trap''
'''例子:''' ''region beton events:kill label:trap''
==== WorldGuard区域条件 ''region'' ====
==== WorldGuard区域条件 ''region'' ====
条件会在玩家处于指定区域时成立,唯一的参数是区域名
条件会在玩家处于指定区域时成立,唯一的参数是区域名
'''例子:''' ''region beton''
'''例子:''' ''region beton''
[[分类:优秀条目申请]] [[分类:角色]] [[分类:娱乐]]
 
[[Category:娱乐]][[Category:角色]]

2021年6月3日 (四) 05:16的最新版本

本条目已有一定量的内容,但仍需完善

欢迎参与本条目的完善工作

你可以从以下几个方面入手

  • 参阅格式化手册,并对该页面进行相应格式排版工作;
  • 日常检查是否内容有更新版本并更新该页面;
  • 修复该页面中已出现/潜在的问题
BetonQuest
外文名BetonQuest
插件类型Spigot / CraftBukkit
最新版本v1.7.3
兼容服务端1.7.2-1.8.3
前置插件
源地址http://dev.bukkit.org/bukkit-plugins/BetonQuest

BetonQuest是一个好用的任务插件。它不像传统的插件将任务与对话绑定,而是网状多选结构(即类似Gal的剧情系统)。

你的任务不一定要像普通单线任务"击杀, 带来物品, 获得奖励"一样,你可以创建多条任务线,通过与NPC的对话,玩家可以进入不同的任务线,获得不同的任务奖励。

特点

  • 你的冒险不止一条路可以走
  • 强大的事件系统:事件可以发生在任何地方
  • 强大的条件系统:你可以限制任何事情的(不)发生
  • 组队系统允许创建团队任务
  • 与NPC的对话的多样性
  • 任务日志记录在一本书中
  • 独立的任务物品背包
  • 可以对物品操作,甚至是书中的文本
  • 可以给玩家增加标签(tag)来储存信息
  • 完善的荣誉系统
  • 位置监听:当玩家进入指定区域会触发事件
  • 日常任务与重复奖励
  • 任务可以分配到不同的背包(方便管理)
  • 支持Citizens2
  • MythicMobs, Skript, WorldGuard和Vault的混合(意思就是全部支持)
  • 多语言支持并且非常容易翻译
  • 玩家可以选择自己的语种
  • 可以使用API创建你自己的事件、条件、目标(Developer)
  • 支持SQLite&MySQL数据库
  • 可备份的配置及数据
  • 自动升级

概览

这插件到底怎样运作?我将以一个简单的伐木任务为例来描述。请注意“事件”、“条件”和“目标”之间的区别。
首先,你需要创建一个和NPC的对话。玩家可在对话内的多个选项中进行选择,NPC会根据选项做出不同的反应(例如NPC会在玩家要求工作时告诉他去砍些树) 。同时,在某些地方会有“事件”被触发,增加一个获得木头的“目标”。它将会把该玩家标记为开始任务的人。从现在开始,NPC会在对话中使用不同的选项,例如他会让玩家快点干活。这些选项将会基于“条件”被选择。
当玩家完成“目标”时(例如通过摧毁木头),“事件”将会触发,将这个玩家标为采集木头的人。当玩家返回NPC处并与其对话时,NPC将以“条件”来核对玩家是否真的拥有那块木头。如果是的话,他将触发给予奖励的“事件”。
我们没有创建任何“任务”对象,只是创建了一个能触发“事件”并与“条件”进行核对的对话。“目标”当然也不是“任务”,它只能在玩家得到木头时标记该玩家,不能单独存在。另一方面,该对话可以在之后开始其他任务(例如挖一些矿石),所以“目标”也不是“任务”
不要为举的例子感到失望,这些只是简化后的过程,所以我可以更简单的解释这个系统,其实用BetonQuest可以做到更多
这些对话可以像在Baldur's Gate或是Skyrim一样有多种路线,任务可以有多种方式来结束,也可以有很多不同的影响玩家声誉的结局,就靠你来决定了。
这个插件也包含了一个在书中的日志。你玩过Morrowind吗? 它们差不多一样,我们只是保留了你查看日志的顺序,所以你不必翻好几百页。现在完成任务并不需要显示像“你收集了所有的矿石,现在回到矿工那儿!”这样的信息。反之,它可以更新玩家的日志,加入像这样的新的记录:“我收集了所有的矿石,我需要回到矿工那儿去拿奖励!”。这样会显得真实得多。

安装

  1. 首先您可以安装Citizens插件,你可以在Bukkit找到它.
  2. 不过这不是前置插件,您也可以用方块来做NPC不过那样会减少真实感
  3. 下载BetonQuest插件,将.jar放在您的插件文件夹中并启动服务器.BetonQuest将会生成配置文件.
  4. 如果您想使用MySQL进行储存数据,打开config.yml,填写您的数据库信息.如果不想,留空就好了,插件会使用SQLite来代替.
  5. 如果您不想使用自动更新,在禁用它之前,请重新启动服务器或重新加载插件.
  6. 当您认为完成之后,您可以重新加载插件(/q reload).现在让我们来学习BetonQuests插件的基础知识吧.

配置

#请勿修改Version选项,他可能会导致你的配置文件被覆盖。

在config.yml中有几个选项,我将尽可能的叙述那些在使用这个插件前,你可能需要修改的选项。其余的选项都是在本文档中相应的小节叙述的。
MySQL:如果你使用MySQL当作数据库,请填写其内容,留空将使用SQLite作为数据库。
update:这部分控制着更新系统,
enable:选项默认设置为true,他控制着整个更新系统是否工作。
download_bugfixes:控制着BetonQuest如果自动更新,是否下载最新的已经修复BUG的版本。 (比如1.7.3 -> 1.7.4 或 1.8.1 -> 1.8.3),这些版本并不改变插件工作的方式,只是修复了BUG的版本,推荐将这项设置为True。
notify_new_release:这个选项负责在启动的时候检测是否有新的版本,若有就通知(比如1.7.6 - > 1.8),因为这些更新可能引入新特性或改变工作方式,所以他们不会自动下载。当你准备好更新的时候,你可以使用/q update指令。
如果你使用一个开发版本,这里将会有三个选项:notify_dev_build,它和notify_new_release是一样的,但是他会检测是否有开发版本可以替换。在这里没有特定的版本检查,如果发现dev的数量较高,这个就会出现。你下载开发版本应当承担你的责任(原文:You download development builds on your own responsibility.)
Language:设置插件的语言: 目前有7种语言:英语(en),德国(de),法国(fr),西班牙(es),中国(cn)、荷兰(nl)和波兰(pl)。
sounds:这个选项定义了在不同的场合播放的声音。startend节点定义了当对话开始和结束的时候所播放的声音。journal 节点定义了当任务笔记更新时所播放的声音。update节点定义了指当日志文件更新时,所播放提醒玩家的声音。full节点定义了当玩家使用/j command,但是背包已经满了的情况下播放。所有的可能的声音名称可以 在这找到。
combat_delay:这个节点定义了一个战斗延迟系统(以秒为单位),定义了玩家必须在战斗结束多长时间后才可以开始对话。
notify_pullback:这个选项定义了玩家在对话中试图离开是否禁止。
default_package:这里写了一个默认包的名称,当你使用/q command 的时候默认是对应这个包。
cmd_blacklist:这是一个列表,代表了在会话中不能使用的命令,注意这里仅可以输入一个词。
hook:这里控制了是否与其他插件互动,你可以在这里关掉。
remove_items_after_respawn如果你不设置gamerule的keepInventory(死亡掉落),请保持这个选项的启用,它可以防止死后其他玩家复制任务的物品,玩家死亡之后,他的任务物品的掉落物将会被删除,并且放到他的背包里。但是有些插件可能试图恢复玩家背包内的所有物品(例如WorldGuard开启keep-inventory)

指令

/j – 给予一本日志
/backpack – 打开背包
/q – 列出所有可用的管理员指令
/q reload – 重载插件
/q objectives <playerName> [list/add/del] [instruction] –列出/修改玩家目标
/q tags <playerName> [list/add/del] [tag] – 列出/修改玩家的标签
/q points <playerName> [list/add/del] [category] [amount] – 列出/修改玩家在所有阵营的点数
/q journal <playerName> [list/add/del] [package.pointer] [date] - lists
/q event <playerName> <package.eventID> - 为玩家激活一个事件
/q condition <playerName> <package.conditionID> - 显示玩家是否经历过指定的环境
/q item <package.itemID> - 创建一个基于你手中物品的物品
/q config <set/add/read> <path> [value] – 操作配置项
/q purge <playerName> - 删除玩家数据
/q backup – 创建配置文件和数据库的备份
/q create <package>: 创建一个新的包并包含默认任务
/q vector <packname.variable> <newvariable>: 计算第一个位置变量到你的位置并且储存到第二个参数中
/questlang <lang> - 改变玩家的语言(如果由控制台使用就可以改变全局语言)

缩写

  • /j: bj, journal, bjournal, betonjournal, betonquestjournal
  • /backpack:b, bb, bbackpack, betonbackpack, betonquestbackpack
  • /q: bq, bquest, bquests, betonquest, betonquests, quest, quests
    • objective: o, objectives
    • tag: t, tags
    • point: p, points
    • event: e, events
    • condition: c, conditions
    • journal: j, journals
    • item: i, items
    • create: package
  • /questlang: ql

详情

  • /q reload重载所有配置,但是不是所有东西都会被保存。当数据库保存时,不可以修改玩家数据。数据库也是一样,你需要重启/重载服务器才可以保存数据库
  • 标签相关的命令可以让你快速的编辑它 ,'/q tags Beton' 将会列出Beton这个玩家的标签。'/q tags Beton add test'将会添加"test"标签给玩家,并且 '/q tags Beton del test' 会移除它
  • 点数相关的命令可以操纵点数。向一个类别添加点数应该用'/q points Beton add reputation 20' (给"reputation"添加20点)。你也可以使用负数来减去。 删除全部点数使用'/q points Beton del reputation'.
  • 日志相关命令与上面两项相同。添加或删除使用 /q journal Beton add default.wood_started (or del),并且你也可以在结尾加上时间来指定时间,格式为:23.04.2014_16:52。注意要用_来代替空格!名字前必须带上包名,因为命令不属于任何包
  • 目标相关命令可以显示玩家的目标。它也可以直接对不表进行操作。记住要在事件/条件前加上包名!如果你想添加一个在events.yml中有定义的目标,只需要使用事件的相关命令
  • 使在线玩家激活事件可以使用'/q event Beton default.give_emeralds'这将会为玩家Beton从”default”包激活 "give_emeralds"。也有条件相关的指令来操作,例如'/q condition Beton default.has_food'。事件与条件必须在它们的文件中定义,这个命令不支持原版指令。你可以不写包名,之后插件会自动读取default_package它可以在config.yml设置
  • 如果需要创建一个"Nettlebane"任务物品,只需要把它拿在手里之后输入'/q item default.nettlebane'. 你手中的物品就会复制到items.yml 并且以你指定的名称保存(这里是"nettlebane"). 你也可以不输入包名.
  • 你可以在. set 项中自定义命令的参数。.add 可以让你快捷的添加字符到存在的值上. (需要注意的地方: 插件不会识别空格,你可以用“_”这个字符来代替空格。例如objective location,是一段存在的字符串,并且你想给它附加 100;200;300;world;10这个值,你的命令应该是/q config add default.events.loc_obj _100;200;300;world;10). read 可以显示配置的值。

这里的路径就是值的地址。你可以用“.”来表示分支,例如config.language,可以设置语言键的值,同理"bye"这个玩家的配置项路径应该是 default.conversations.innkeeper.player_options.bye.text

  • 你可以使用'/q purge Beton'清除指定玩家的数据. 目前无法使用命令清除整个数据库,但你可以修改数据库的前缀

如果你想要备份你的设置以及数据,需要你的服务器是空的(需要获取所有数据库的数据>所有玩家离线)之后运行'/q backup'这条命令,你将会获得一个包含所有数据的zip压缩文件。

  • 使用'/q create beton' 你可以创建一个名为'beton'的任务,它将会与默认任务相同。
  • /q vector 命令可以让你创建一个由第一个位置变量到你的位置的矢量。结果会储存到"vectors.{第二参数}"

权限

  • betonquest.admin – 允许使用管理员命令(/q ...)且可以创建NPC
  • betonquest.journal – 允许使用/ J指令(默认为玩家)
  • betonquest.backpack –允许使用/backpack 指令(默认为玩家)
  • betonquest.conversation -允许与NPC对话(默认为玩家)betonquest.language -允许改变的语言(默认为玩家)

使用教程

安装插件之后你首先想到的应该是怎么使用它。如果你想使用GUI,将default_conversation_IO修改为chest,之后保存文件并且在服务器上使用/q reload命令。 登录并在随意位置放一个彩色粘土。在它上面放一个头(例如僵尸的头)并且在粘土块的一侧放一个牌子。填写如下内容 [NPC] Innkeeper 右键这个NPC,将会出现对话。如果没有,检查你是否成功地制作了NPC。Innkeeper会让你砍一些树,你可以看到日志有了新的记录,不要放置原木然后摧毁, BetonQuest会检测方块的数量,你只能去砍树。如果你是创造模式,给自己16个原木。之后,你可以返回NPC那里得到奖励

使用事件和条件

现在你会了非常基础的东西。我们不能做出来一个完整的对话,因为它们使用了很多事件与条件,所以我们要了解它们。去阅读词汇参考或者继续阅读教程

事件

让我们从默认包中打开events.yml。添加新的一行:foo: message Hello world!这是一个事件的指令字符。BetonQuest使用它来确定事件的类型和它要做的事情。foo是事件的名字,message是一个类型,并且Hello world!告诉message需要显示什么。在这种情况下,如果你运行foo事件,它会显示Hello owrld!信息。保存这个文件,使用/q reload命令然后使用/q e foo运行事件(q是quest缩写,e是event缩写,<名称>是你的Minecraft名字,没有括号,foo是我们创建的事件名称)。它会显示一个Hello world!信息 创建另一个更复杂的事件。比如传送,它需要一个参数,location(位置)。在events.yml中添加一行:bar: location 100;200;300;world(<事件名称>:location:x;y;z;<世界名称>)。保存文件,重新加载插件,然后运行事件。 祝贺你,你刚刚创建了你的第一个事件。继续做一些其他事件类型的实验。你可以在事件列表中找到它们。你完成了开始学习的条件。

条件

打开conditions.yml并添加新的一行:foo: location 100;200;300;world;5很明显,命名方式与事件相同,但它们没有任何联系。条件名称和事件名称是无关的,因此你可以给它们相同的名称。现在让我们看看指令字符。你可以认为地点是一种条件,它会检查玩家是否在附近。注意,最后一个参数是一个整数,5。这是检查的范围。完成了吗?做完了就保存文件并重新加载插件吧。 现在,走到你在条件所定义的位置,使用/q c foo(C是condition的缩写)。它应该会显示“checking condition blah blah blah: true”。我们把焦点放在最后的那个词,true。这意味着你满足条件:你站的位置在5格之内。现在移动2格,再次使用命令,你仍应符合条件。现在尝试走4格,它应该会显示false。你现在已经在5格之外。明白了吗?太好了! 现在,我告诉了你最简单地使用这些条件。再次打开events.yml文件,并在foo字符末尾添加条件:foo argument。顺便说一下,最好重命名foo事件为baz,这样名字不会混淆。现在你应该有这样的一行:message Hello world! conditions: foobaz事件只会在foo条件为true时运行。重载插件,走到5格之外,尝试运行baz事件。漂亮,什么都没有发生。这是因为你不符合foo条件。走进范围再次尝试运行事件。它应该显示hello world!消息。 为我们完成了这样一个条件庆祝吧(ahaaaa lolllllll 2333333),那么问题来了,如果你想在玩家不在范围内时显示消息,该怎么做呢?(我不告诉你[doge])别担心,你不用specifyinverted_location条件或其他的什么(那么问题来了,那串英文是什么意思呢?)。你可以简单地否定条件,否定使条件以完全相反的方式运作,在这种情况下,条件只会在玩家在范围外时成立。打开events.yml并在foo条件前加一个感叹号(半角 ! ),现在应该是这样:baz: message Hello world! conditions:!foo,这表示“当foo不成立时显示Hello world!”保存文件,重新加载插件,运行事件然后乱跑一会儿,看看它是如何工作的。(对了,那串英文是反转_位置的意思啦,非要翻译就是相位反转_位面!xddddd[特定反转_位置])

标签基础

现在,你学会了怎么用事件与条件。之后,我会告诉你什么是标签(tag)。创建两个个新的事件add_beton_tag: tag add betondel_beton_tag: tag del beton。取事件名称时,要注意与内容相关,否则很容易混淆,很不方便。假设你有100个事件,foo24,bar65等等。你也许会迅速的被闪瞎。所以, add_beton_tag 标签给玩家添加了beton标签,del_beton_tag 移除了它。保存文件,重载插件并且运行事件。什么都没发生还是成功了呢?使用/q t命令(t是tags的缩写。)它会显示标签列表。现在我们注意一下default.beton,当然,default是包名,并且beton是标签名,并且在add_beton_tag事件中定义了。现在运行del_beton_tag事件,猜猜会发生什么?default.beton标签消失了!综上可知,添加删除标签的方法。 没有什么是可以犯错的,标签是BetonQuest中最有用的东西之一。它们需要通过tag条件来使用。打开conditions.yml并且添加has_beton_tag: tag beton。你可以认为tag是一种条件(和tag事件相同,但它们不是一样的,一个是事件,另一个是条件)beton是标签的名字。你没有指定default.beton,但你可以这样做。保存,重载插件并且检查条件。它会显示true。 现在你应该了解了这个方便的系统。你可以当玩家第一次与NPC交流时 添加一个标签,并且当NPC获取到这个标签他会说一些不同的话,比如“欢迎回来”。

创建目标

是时候写一些目标了!打开objectives.yml并且添加一行kill_creepers: mobkill creeper 3 events:bar conditions:has_beton_tag。让我们分析一下它。kill_creepers是目标的条件, mobkill是任务类型。为了完成任务,玩家需要杀一些怪物,creeper是一种怪物,所以我们知道这些怪物必须是苦力怕。3是数量,它意味着玩家必须杀3个苦力怕。event:bar意味着任务完成后激发bar事件。conditions:has_beton_tag告诉我们只有玩家拥有beton标签时任务才可以完成。保存,重载并且使用/q o add kill_creepers命令(o是目标,add告诉插件添加一个目标)。 你现在可以用/q o命令来检查目标是否创建成功,它会显示所有活动的目标。它应该显示default.kill_creepers。之后,删除beton标签然后杀几个苦力怕。当你杀了三个之后你发现什么都没发生。这是因为has_beton_tag条件不工作了,所以目标不会计数。现在再添加标签并且杀苦力怕。当第三个死了之后你会传送到bar事件定义的位置。 恭喜你!你学会了怎么用目标!你需要多做实验,因为任务中经常会使用它。仔细看看创建对话,你就完成了基础!

创建对话

现在你理解了BetonQuest的事件、条件、目标,是时候创建一发对话了!在默认包里有一个conversations文件夹。里面只有一个文件,innkeeper.yml。这是innkeeper的对话文件,就是那个让你砍树的人。参考它来完成你的第一个对话吧。创建一个新文件,命名为miner.yml。输入(为了学的更快,不要复制!)以下内容 quester: Miner first: greeting NPC_options:

 greeting:
   text: Hi there, traveler!

这是最基本的对话, Mine在开始谈话时将会说 Hi there,traveler!,之后,这个对话就会结束,因为这里没有玩家可以选择的选项。 现在你需要给一个NPC添加对话选项。你需要在 main.yml 文件中添加。现在打开它。就像你看到的,inkeeper.yml 对话对应的是文件中的innkeeper字段。这是你需要打在木牌上其中的一项,记住了吗0w0?现在,添加另外一行在 innkeeper字段底下:Miner: miner.yml,保存这个文件然后重启你的服务器。这将会连接我们的名叫“Miner(矿工)”的NPC的最新对话。在你的服务器内创建一个新的NPC,给他一个带有“Miner(矿工)”名字的木牌并且点击他的头部。 现在给NPC添加对话选项,你需要在 main.yml 文件中添加。打开它。就像你看到的,inkeeper.yml 对话对应的是文件中的innkeeper字段。这是你需要打在木牌上其中的一项,添加另外一行在 innkeeper字段底下:Miner:miner.yml,保存这个文件然后重启你的服务器。这将会让我们的 “Miner” NPC说话。在你的服务器内创建一个新的NPC,给他命名为“Miner”并点击他。 猜猜会发生什么?对话就会显示一遍,从开始到结尾。这个名为“Miner(矿工)”的NPC就会说Hi there,traveler! (你好啊,旅行者!)就像你设置的那样。现在看到设置对话的文件然后编辑它(再一次编辑,手动输入,不要复制粘贴!),所以这个选项看起来是这样的: 这个名为“Miner”的NPC会说Hi there,traveler!,就像你设置的那样。现在再编辑设置对话的文件(再一次编辑,手动输入,不要复制粘贴!), NPC_options:

 greeting:
   text: Hi there, traveler!
   pointers: hello, bye

player_options:

 hello:
   text: Hello!
 bye:
   text: I need to go, sorry.

保存这个文件,重启服务器,再次开启对话,你就会看到有两个选项可以供你选择:Hello!(你好!)和I need to go,sorry.(对不起,我要走了。)。选择它们其中的任何一个就会结束这个对话,因为这些选项没有任何内容。现在创建一个新的选项,例如weather(天气)和Nice weather.(好天气。)然后使hello的选项指向它。当你保存并且重启之后, Miner就会说Nice weather.(好天气。)当你告诉他Hello!(你好!)时,我想你会知道他会说什么! 现在,不管什么时候与Miner对话,他都会说一样的东西。如果你第二次和他对话,他应该已经知道你的名字,我们可以使用标签(tag)来完成它。定义一个meet_miner事件(event)和has_met_miner条件(condition)。当你与Miner对话时,他会检查has_met_miner条件。如果没有,他将会为你执行meet_miner事件,你下一次与他对话时,has_met_miner就会成立,他就可以知道你的名字了 现在,更改first_greeting这个选项。添加meet_miner事件并且在事件中添加has_met_miner条件(请使用!来否定这个条件,因为这个选项只会在玩家没有见过Miner的时候显示)。你需要用 来包含条件(分词符号),因为YAML中字符串不能以感叹号开头,写成下面这样: first: first_greeting NPC_options:

 first_greeting:
   text: Hi there, traveler!
   condition: '!has_met_miner'
   event: meet_miner
   pointers: hello, bye

如果玩家的has_met_miner不成立,first_greeting这个选项会被使用, meet_miner事件被激活,就会显示hello和bye选项。如果玩家已经见过Miner,has_met_miner条件不成立会发生什么?NPC将会尝试使用在first中定义的选项。让我们加入吧! NPC_options:

 regular_greeting:
   text: Hi %player%!
   pointers: hello, bye

这个选项没有任何事件,如果first_greeting不成立,NPC就会显示这个选项。 “%player%”是一个变量,它将会显示你的名字。这里有比这个更好的选择,会在 参考 这个章节中说明。保存并且重启,然后开始对话。如果你正确的做了所有的事情,Miner就会把你当做“旅行者”欢迎你,第二次跟他讲话,他就会带着你的Minecraft昵称欢迎你~ 这应该是你现在配置文件的样子,你可以检查一下配置错误: first: first_greeting,regular_greeting NPC_options:

 first_greeting:
   text: Hi there, traveler!
   condition: '!has_met_miner'
   event: meet_miner
   pointers: hello, bye 
 regular_greeting:
   text: Hi %player%!
   pointers: hello, bye
 weather:
   text: Nice weather.

player_options:

 hello:
   text: Hello!
   pointer: weather
 bye:
   text: I need to go, sorry.

现在你应该尝试制作自己的对话,你可以看着theinnkeeper.yml文件来帮助你创建对话。试着理解对话是怎样一步一步地工作的。你应该试着教程来完成创建Miner来完成这个任务:他找你要一些铁矿石并放在熔炉里冶炼,下一回他就会穿着盔甲! 你需要阅读 参考 章节,查看如何处理任务中的项目以及如何将条目添加到日记中。如果你想使用Citizens的NPC代替粘土,你需要阅读这一章。要了解更多关于事件、条件、目标、对话和变量,阅读下一章。

条件、事件、目标

Condition(条件), event(事件), objectives(目标)被定义为“指令字符”。它可以匹配包含condition/event/objective的文字。感谢这些字符知道它们需要做什么。如果你想使用这些指令字符,请看下面的参考。它描述了这些指令字符的作用和用法。所有的指令字符都在特定的文件中定义,例如所有条件都在condition.yml.中配置。定义语法:name: 'the instruction string containing the data'。单引号大多情况可以省略(建议不省略)。以下,我会更详细地描述使用方法

条件

条件是创建高级任务必不可少的工具。它们可以让你控制玩家在对话中可以选择哪些选项,NPC如何回应这些选项或者任务目标完成。所有可能的条件参考如下。 让我们看看玩家有没有一个beton_start标签(tags(标签)是一个可以在事件中添加给玩家的,之后我们就可以检查♂它了)你需要写一个像: tag beton_start这样指令字符。这是定义我们需要寻找什么。第一个单词是条件类型。它说明了这个条件需要检查一个标签。第二个是beton_test。它定义了哪个标签是我们想要寻找的。注意,你不能在一个条件中定义多个标签。为了做到它你需要多个条件。现在如果你在对话选项中使用了条件,它将会在玩家拥有这个标签时候出现。但是如果你想在玩家没有这个标签时候显示呢?为了达到这个目的你要在条件前面加一个!来达到目的。注意它是在对话设置里添加而不是条件配置。 现在你拥有了一个条件 使用它来检查玩家是否正在做这个任务并且阻止他再做一次。当然,这个标签将会在任务开始之后添加,通过事件

事件

在某些时候你想让一些事情发生。刷新日志,设置标签,给予奖励,这些需要事件来完成。你需要像条件一样通过指令字符和指定名字定义它。你可以在事件参考中找到所有的给事件用的指令字符。在指令字符后面你可以添加条件:使用逗号分隔条件一类的东西,例如:angry,!quest_started。这将会让事件在条件达成时触发。

目标

当你在创建任务的时候,任务目标是最主要的。你可以用一个指令字符“objective”来创建一个任务目标。这些可以在objectives.yml文件中定义,在说明文字的后面,你可以为目标添加条件或者事件。条件即限制任务的完成条件(比如需要城镇的入口防卫,在给定的任务地点击杀僵尸),事件会在任务完成时触发(比如给予奖励,或者设置一个标签,当从NPC上获得奖励时标签会激活),你可以在说明位置后面按照这样的格式去定义:“conditions:条件1,条件2 events:事件1,事件2”,用逗号去分割,而不是用空格。

目标任务在启动的时候载入,但是除非玩家去激活它们,否则不会消耗资源。这意味着,如果你定义了100个目标任务,有20个玩家一起执行其中一个,另外20个玩家执行另一个,其他的任务没有人去执行,那么仅仅有2个目标任务是激活的,不是100个,也不是40个,这样会更加高效。

支持插件

BetonQuest可以支持其他的插件,使用它们的功能。目前有三个插件: Citizens, Vault and MythicMobs.

Citizens

如果你有这个插件就可以创建NPC 来对话。我非常建议安装这个插件,NPC可以让对话更真实。Citizens也可以让你的NPC击杀的目标。

NPC击杀目标 npckill

NPC击杀目标需要玩家击杀指定ID的NPC。你也可以设置杀多少次NPC。目标名称后面必须是NPC的ID。你可以用amount: 设置数字。

例子: npckill 16 amount:3 events:reward label:citizens

NPC互动目标

玩家必须与指定ID的NPC交互。它也可以关闭动作,这样对话就不会触发了。第一个参数是数字(NPC的ID)第二个是设置项 cancel.

例子: npcinteract 3 cancel conditions:sneak events:steal label:stealing

Vault

安装Vault你可以有权限事件和金钱条件/事件。

权限事件 permission

删除或者增加一个组的权限。第一个参数是add或者remove,这很好理解。第二个是 perm或者group,这个也不难弄清楚。下一个就是你要添加或者删除的字符串。最后你需要指定一个世界。如果世界为空的话,这个修改就会变成全局的。

例子: permission remove group bandit world_nether

金钱事件 money

从玩家的帐户存取款,只有一个参数,就是数量,它可以是负数。

例子: money -100

金钱条件 money

检查玩家的金钱是否足够,也只有一个参数,即需要达到的数值,不能为负

例子: money 500

MythicMobs

你可以设置MythicMobs怪物击杀目标和MythicMobs生成怪物的事件。

MythicMobs怪物击杀目标 mmobkill

完成这个目标需要击杀指定数量的指定怪物。第一个参数必须是怪物的内部名称(在MythicMobs的配置中有)。你可以添加amount:来指定击杀的数量

例子: mmobkill SkeletalKnight amount:2 events:reward label:mythicmobs

MythicMobs怪物生存事件 mspawnmob

在指定的地方生成指定数量的怪。第一个参数应该是位置,格式是100;200;300;world。第二个是MythicMobs的内部名字(在MythicMobs的配置中有)后面跟一个冒号和等级。第三个是数量(必填)

例子: mspawnmob 100;200;300;world SkeletalKnight:1 5

Skript

BetonQuest也可以与Skript联动。为了避免混淆,我会使用插件的名称(Skript的一些事件BetonQuestnt也有。Skript可以让你通过脚本使用BetonQuest的事件,并且也可以用BetonQuest执行脚本。

Skript事件通过 BetonQuest skript 事件触发

这里描述了Skript事件和BetonQuest事件。

  1. Skript 事件 - on [betonquest] event "id" – 这一行可以触发 betonquest 中设定好的代码,并且 id 只能是字符串,且必须与你指定BetonQuest的事件相同。
  2. BetonQuest事件- skript – 这个事件会触发Skript的事件。指令只有一个参数,是事件的ID。必须和Skript中定义的事件相同。

例子: 脚本: on betonquest event "concrete" events.yml:fire_concrete_script: skript concrete

Skript条件

你可以用 player meets [betonquest] condition "id" 语句检查BetonQuest 的条件。Betonquest是配置项,并且 id 是条件名称,在conditions.yml中定义。 例子:脚本: player meets condition "has_ore" conditions.yml: has_ore: item iron_ore:5

Skript事件

你可以用脚本触发BetonQuest事件。Skript的语句是fire [betonquest] event "id" for player例子:脚本: fire event "give_emeralds" for player events.yml:give_emeralds: give emerald:5

WorldGuard

WorldGuard区域目标 region

完成这个目标需要进入指定区域,唯一的参数是区域名称。 例子: region beton events:kill label:trap

WorldGuard区域条件 region

条件会在玩家处于指定区域时成立,唯一的参数是区域名 例子: region beton