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

BetonQuest:修订间差异

来自Minecraft插件百科
跳转到导航 跳转到搜索
(增加分类)
无编辑摘要
 
(未显示5个用户的16个中间版本)
第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的对话,玩家可以进入不同的路线,获得不同的任务奖励。
== 特点 ==
== 特点 ==
*你的冒险不止一条路可以走
*你的冒险不止一条路可以走
*强大的事件系统:可以在任何地方发生你想的事情
*强大的事件系统:事件可以发生在任何地方
*强大的条件系统:你可以限制任何事情的(不)发生
*强大的条件系统:你可以限制任何事情的(不)发生
*拥有队伍系统,这带来了团队任务
*组队系统允许创建团队任务
*与NPC的对话的多样性
*与NPC的对话的多样性
*所有的日志记录在一本书中
*任务日志记录在一本书中
*独立的任务物品背包
*独立的任务物品背包
*可以对物品操作,甚至是书中的文本
*可以对物品操作,甚至是书中的文本
第26行: 第24行:
*完善的荣誉系统
*完善的荣誉系统
*位置监听:当玩家进入指定区域会触发事件
*位置监听:当玩家进入指定区域会触发事件
*每日任务和可重复任务
*日常任务与重复奖励
*任务可以分配到不同的包(方便管理)
*任务可以分配到不同的背包(方便管理)
*支持Citizens2
*支持Citizens2
*MythicMobs, Skript, WorldGuard和Vault的混合(意思就是全部支持)
*MythicMobs, Skript, WorldGuard和Vault的混合(意思就是全部支持)
第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]找到它.
#不过这不是前置插件,您也可以用方块来做NPC不过那样会减少真实感
#下载BetonQuest插件,将.jar放在您的插件文件夹中并启动服务器.BetonQuest将会生成配置文件.
#如果您想使用MySQL进行储存数据,打开config.yml,填写您的数据库信息.如果不想,留空就好了,插件会使用SQLite来代替.
#如果您不想使用自动更新,在禁用它之前,请重新启动服务器或重新加载插件.
#当您认为完成之后,您可以重新加载插件(/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 – 给予一本日志
第62行: 第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
*/backpack: b, bb, bbackpack, betonbackpack, betonquestbackpack
*'''/backpack:'''b, bb, bbackpack, betonbackpack, betonquestbackpack
*/q: bq, bquest, bquests, betonquest, betonquests, quest, quests
*'''/q:''' bq, bquest, bquests, betonquest, betonquests, quest, quests
**objective: o, objectives
**'''objective:''' o, objectives
**tag: t, tags
**'''tag:''' t, tags
**point: p, points
**'''point:''' p, points
**event: e, events
**'''event:''' e, events
**condition: c, conditions
**'''condition:''' c, conditions
**journal: j, journals
**'''journal:''' j, journals
**item: i, items
**'''item:''' i, items
**create: package
**'''create:''' package
*/questlang: ql
*'''/questlang:''' ql
 
=== 详情 ===
=== 详情 ===
*/q reload重载所有配置,但是不是所有东西都会被保存。当数据库保存时,不可以修改玩家数据。数据库也是一样,你需要重启/重载服务器才可以保存数据库<br>
*/q reload重载所有配置,但是不是所有东西都会被保存。当数据库保存时,不可以修改玩家数据。数据库也是一样,你需要重启/重载服务器才可以保存数据库<br>
第90行: 第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
第95行: 第126行:
*betonquest.backpack –允许使用/backpack 指令(默认为玩家)
*betonquest.backpack –允许使用/backpack 指令(默认为玩家)
*betonquest.conversation -允许与NPC对话(默认为玩家)betonquest.language -允许改变的语言(默认为玩家)
*betonquest.conversation -允许与NPC对话(默认为玩家)betonquest.language -允许改变的语言(默认为玩家)
== 创建对话 ==
对话是rpg系统的基础,这是开始或者完成任务的主要方法,也可以制造更多身临其境的游戏体验。你制作的每一个对话文件都放在在"conversations" 目录下。(更多相关信息请看"default"文件夹里面的 BetonQuest目录)对话文件文件必须以.yml为后缀,比如 innkeeper. yml


让我们来脑补一下。然后我们可以尝试去弄清楚如何完成它。在玩家的眼里面看上去是这样的:玩家右击npc(让我们把npc称作小芳玩家称作小五)小芳说出她的初始文本,然后小五可以从中选择,假设有三个选项。小五在聊天栏输入 1(或者2,3),然后小芳继续对话。小五再一次拥有选项去选择之类的。如果小五输入其他例如字母或者较大的数字。小芳会做出她无法理解他的回应。
== 使用教程 ==
安装插件之后你首先想到的应该是怎么使用它。如果你想使用GUI,将''default_conversation_IO''修改为''chest'',之后保存文件并且在服务器上使用''/q reload''命令。
登录并在随意位置放一个彩色粘土。在它上面放一个头(例如僵尸的头)并且在粘土块的一侧放一个牌子。填写如下内容
'''[NPC]
Innkeeper'''
右键这个NPC,将会出现对话。如果没有,检查你是否成功地制作了NPC。Innkeeper会让你砍一些树,你可以看到日志有了新的记录,不要放置原木然后摧毁, BetonQuest会检测方块的数量,你只能去砍树。如果你是创造模式,给自己16个原木。之后,你可以返回NPC那里得到奖励


每一个对话必须设定npc名字(一些对话不可以绑定任何npc,所以指定它非常重要,即使还没有这个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: 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[特定反转_位置])
 
=== 标签基础 ===
现在,你学会了怎么用事件与条件。之后,我会告诉你什么是标签(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。
现在你应该了解了这个方便的系统。你可以当玩家第一次与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''。这是''innkeepe''r的对话文件,就是那个让你砍树的人。参考它来完成你的第一个对话吧。创建一个新文件,命名为''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_mine''r事件(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个,这样会更加高效。


注意1:配置文件使用yaml格式。如果你不知道什么是yaml,cnm不会百度么(can u f**k the Google?)?最主要的规则是当你进入更深层的阶层树时你要用两个空格代替标签。如果你想使用单引号(必须半角),你需要确保还有另一个单引号且它们分别处于文本开头及结尾 (例如上面的未知配置项)。当写为ture或者false时它依旧需要用'围起来。如果你想用&来做一行的开头,那么你需要在开头结尾加上单引号。
注意2:上文的对话只是一个栗子。它并不是有效的,因为它缺少了很多其他的设置。
== 支持插件 ==
== 支持插件 ==
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事件。
第141行: 第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