> For the complete documentation index, see [llms.txt](https://miao-3.gitbook.io/betonquest-zhong-wen-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://miao-3.gitbook.io/betonquest-zhong-wen-wiki/jiao-cheng/ru-men/ji-chu-jiao-cheng/tiao-jian.md).

# 条件

现在你知道了如何使用目标给玩家任务了，现在是时候来学习条件了。这是任务中必不可少的一部分，因为它可以让你基于玩家的行动来创建不同的结果。你可以通过给任何一个对话、事件或目标附加条件来实现。例如，你可以有一个对话选项，只有当玩家的背包中有特定的物品时才可以使用。

本教程中，你将学习如何创建和使用条件！

{% hint style="danger" %}
要求

你必须已完成上一章“[安装指南](/betonquest-zhong-wen-wiki/jiao-cheng/ru-men.md)”内容

你必须已完成上一节“[对话](/betonquest-zhong-wen-wiki/jiao-cheng/ru-men/ji-chu-jiao-cheng/dui-hua.md)”内容

你必须已完成上一节“[事件](/betonquest-zhong-wen-wiki/jiao-cheng/ru-men/ji-chu-jiao-cheng/shi-jian.md)”内容

你必须已完成上一节“[目标](/betonquest-zhong-wen-wiki/jiao-cheng/ru-men/ji-chu-jiao-cheng/mu-biao.md)”内容
{% endhint %}

## 下载教程预设

<img src="https://twemoji.maxcdn.com/v/latest/svg/26a0.svg" alt="⚠" data-size="line"> <mark style="color:red;">**如果您已经使用了上一个教程步骤的配置，请不要执行此操作。**</mark> <img src="https://twemoji.maxcdn.com/v/latest/svg/26a0.svg" alt="⚠" data-size="line">

在聊天框中输入以下命令下载本节教程的预设内容：

```
/bq download BetonQuest/Quest-Tutorials main QuestPackages /Basics/Conditions/1-DirectoryStructure /tutorialQuest
```

您现在可以在此位置找到本教程所需的所有文件：

&#x20;"*你的服务器文件存放位置/plugins/BetonQuest/QuestPackages/tutorialQuest*"

## 1.为你的你一个条件创建文件夹结构&#x20;

在“*tutorialQuest*”`QuestPackage`中添加一个名为“*conditions.yml*”的新文件。现在，你的文件结构应该像是这样的：

:file\_folder:tutorialQuest

* &#x20;:open\_file\_folder:package.yml
* &#x20;:open\_file\_folder:events.yml
* &#x20;:open\_file\_folder:objectives.yml
* &#x20;:open\_file\_folder:**conditions.yml**
* &#x20;:file\_folder:conversations
  * &#x20;:open\_file\_folder:jack.yml
  * &#x20;:open\_file\_folder:blacksmith.yml

现在我们有了自己的文件结构，可以开始创建条件了！

## 2.定义你的第一个条件&#x20;

现在我们已经创建了他，打开 "conditions.yml" ，并将以下文本添加进去：

{% code title="conditions.yml" overflow="wrap" lineNumbers="true" %}

```
conditions: 
  isDay: "time 6-18"
```

{% endcode %}

* 第 1 行`conditions:` ：所有的条件都必须在这一部分中.

那么，现在我们能在这里看到什么呢？

* `isDay`是条件的名称，你可以随意起名。我们建议将他设置为与之相关的名字。

条件结构：

* `time`：结构中的第一个至永远都是条件类型&#x20;
* `6-18`：这是`time`条件的一个选项。它定义了时间间隔为 true，意思就是从早上 6 点到晚上 6 点都时间间隔为 true

现在我们已经创建了你的的第一个条件，检查服务器上的游戏时间是否设置了特定的时间。保存文件并继续下一步！

## 3.在游戏中检查条件&#x20;

你可以在游戏中检查条件是否为true或false。

每次测试时保存所有文件是非常重要的！保存后在服务器上输入`/bq reload`。

运行一条指令是检查条件最简单的方式：

&#x20;在服务器上输入`/bq condition NAME tutorialQuest.isDay`。这个命令会根据时间显示 “false” 或 “true” 的结果。如果是白天，那就是 true ; 如果是夜晚，那就是 false 。

{% hint style="info" %}
**小提示**

使用`/time set day`和`/time set night`命令可以更改世界时间。

你可以在游戏中用它来测试你的条件。
{% endhint %}

让我们来拆解分析一下：&#x20;

* `/bq conditions` 告诉BetonQuest，一些条件应该被检查是否为true或false&#x20;
* `NAME`一个玩家的名字&#x20;
* `tutorialQuest`任务包的名字。这是必要的，因为在不同的任务包中可能会存在相同事件的名字。&#x20;
* `isDay`检查条件的名字，不要忘记用一个点把任务包分开`tutorialQuest`**`.`**`isDay`。

<details>

<summary>这个示例不起作用吗？</summary>

通过运行以指令获取正确的配置。\
*这将覆盖您对示例所做的任何更改（包括 NPC ID）。*\
[基础教程](https://miao-3.gitbook.io/betonquest-zhong-wen-wiki/jiao-cheng/ru-men/ji-chu-jiao-cheng/pages/3gPGDyqwfkb9OR8DAmsm#1.-jiang-dui-hua-lian-jie-dao-npc-shang)中介绍了将 NPC 链接到对话。<img src="https://twemoji.maxcdn.com/v/latest/svg/26a0.svg" alt="⚠" data-size="line">

```
/bq download BetonQuest/Quest-Tutorials main QuestPackages /Basics/Conditions/2-FirstCondition /tutorialQuest overwrite
```

</details>

## 4.将条件合并到目标当中

条件可以被添加到目标中来限制玩家任务推进和完成目标的能力。目标只会在条件为“true”时，才会向前推进。既然这样，我们想让玩家只有在夜晚钓鱼时，目标才会推进。让我们来添加条件`isDay`到目标中吧：

{% code title="objectives.yml" lineNumbers="true" %}

```
objectives:
  fishingObj: "fish COD 3 hookLocation:100;63;100;world range:20 events:caughtAllFish conditions:!isDay"
```

{% endcode %}

我们可以在这里看到很多东西：

* `conditions:`这个选项适用于所有目标。你可以添加多个条件用逗号隔开（`conditions:con1,con2,con3`）
* 感叹号`!`在条件前表示反转。意思就是说，如果条件为“true”将会被视为“false”，反之亦然。如果使用了多个条件，则必须对每个条件设置该值（`conditions:!con1,! con2,!con3`）
* 需要注意的是，我们条件被设置为检查是否为白天（`6-18`），我们需要反转`isDay`的条件，因为我们希望在夜间才能推进任务。现在如果是夜晚（`23-2`），条件将变为true。

完成以上改动后，请保存、重载并测试它！

## 5.将条件合并到对话当中

&#x20;在对话中，条件可以被用来控制`player_options`。这是一个可以创建有着多个答案的复杂对话的强大的功能。 例如，当前的 NPC Jack 的对话可以无限重复，玩家可以获取更多的食物，这并不是我们想要的。

### 5.1.让Jack只给一次食物

为了解决这个问题，我们需要创建为对话创建一个替代路径。只有玩家获得食物时才会显示。为了实现它，我们将要创建一个事件来给予玩家一个"tag"（意为标签，下同），并且在对话中添加一个条件。

我们将以一个tag条件来开始：

<pre data-title="conditions.yml" data-line-numbers><code>conditions:
  isNight: "time 6-18"
  <a data-footnote-ref href="#user-content-fn-1">hasReceivedFood: "tag foodReceived"</a>
</code></pre>

{% hint style="success" %}
**什么是“tag”？**&#x20;

“tag”是一个标签，可以被添加到玩家上。这是一种存储玩家永久信息的简单方法。之后，你将在另一个教程中了解有关它们的更多信息。
{% endhint %}

如果玩家有着被定义的tag，则tag的条件就是"true"。让我们来拆解分析一下：

* `hasRecivedFood`条件的名字，你可以随意起名。我们建议将他设置为与之相关的名字。
* 条件结构：
  * `tag`：结构中的第一个值总是条件类型。
  * `foodReceived`：玩家必须所有的标签名称。

标签可以通过事件给予给玩家。下面让我们来创建一个事件，为玩家给予一个标签：

<pre data-title="events.yml" data-line-numbers><code>events:
  # 其他事件不再展示
<a data-footnote-ref href="#user-content-fn-1">  addFoodReceivedTag: "tag add foodReceived"</a>
</code></pre>

{% hint style="warning" %}
**提示**&#x20;

如果你不理解为什么我们在`events`部分中创建一个事件（说明你偷懒没按顺序看！）你应该回到事件教程中仔细阅读并理解它！
{% endhint %}

我们现在准备好了下一步：在对话中添加条件和事件。

在对话文件夹中打开你的`jack.yml`文件，添加给予玩家标签的事件，并且条件不会在特定的对话部分中重复。

<pre data-title="jack.yml" data-line-numbers><code>conversations:
  Jack:
    quester: "Jack"
    first: "<a data-footnote-ref href="#user-content-fn-2">alreadyReceivedFood</a>,firstGreeting" 

    NPC_options:
      <a data-footnote-ref href="#user-content-fn-3">firstGreeting: </a>
        text: "Hello and welcome to my town traveler! Nice to see you. Where are you from?"
        pointer: "whereYouFrom"
      # 其他 NPC_options 不再展示
      foodAnswer:
        text: "You're welcome! Take it... &#x26;7*gives food*"
        events: "giveFoodToPlayer,<a data-footnote-ref href="#user-content-fn-4">addFoodReceivedTag</a>" 
        pointer: "thankYou"
        conditions: "!hasReceivedFood"
      alreadyReceivedFood:
        text: "Hey %player%! I think I already gave you your welcome food..."
        conditions: "<a data-footnote-ref href="#user-content-fn-5">hasReceivedFood</a>"  
        pointer: "saySorry"
      # 其他 NPC_options 不再展示

    player_options:
      # Other player_options not shown
      saySorry:
        text: "You are right. Thanks again!"
        pointer: "townTour"
      # 其他 player_options 不再展示
</code></pre>

就像你看到的那样，我们也为它添加了新的选项。现在，NPC将会说：你已经收到食物了，不会再给你更多食物了！

{% hint style="info" %}
**关于测试的温馨提示：**

如果你想再次测试这个对话，你需要删除玩家的标签。你可以输入`/bq tag remove <player> <tag>`这个指令来删除玩家的标签。
{% endhint %}

<details>

<summary>这个示例不起作用吗？</summary>

通过运行以下命令获取正确的配置。\
*这将覆盖您对示例所做的任何更改（包括 NPC ID）。*\
[基础教程](https://miao-3.gitbook.io/betonquest-zhong-wen-wiki/jiao-cheng/ru-men/ji-chu-jiao-cheng/pages/3gPGDyqwfkb9OR8DAmsm#1.-jiang-dui-hua-lian-jie-dao-npc-shang)中介绍了将 NPC 链接到对话。<img src="https://twemoji.maxcdn.com/v/latest/svg/26a0.svg" alt="⚠" data-size="line">

```
/bq download BetonQuest/Quest-Tutorials main QuestPackages /Basics/Conditions/3-ConditionsInConversations /tutorialQuest overwrite
```

</details>

## 5.3.让铁匠至进行一次盔甲的交易

铁匠的对话也存在类似上方的问题。这没有办法来获得奖励，那么对话就会一遍又一遍地开始。让我们来修复这个问题!

### 5.3.1.准备对话

让我们来添加当玩家已经接受任务，但还不能完成它的对话吧：

{% code title="blacksmith.yml" lineNumbers="true" %}

```
conversations:
  Blacksmith:
    quester: "Blacksmith"
    first: "alreadyStarted,firstGreeting"
    NPC_options:
      firstGreeting:
        # 其他 player_options 不再展示
      alreadyStarted:
        text: "Come back to me if you caught all the fish!"
        conditions: "hasStartedFishing"
    player_options:
      # 其他 player_options 不再展示
      accept:
        text: "Sure! I could use a new armour."
        event: "startFishingObj,addStartedFishingTag"
        pointer: "goodLuck"
      # 其他 player_options 不再展示

```

{% endcode %}

像这样，我们需要&#x5728;*"conditions.yml"*&#x6587;件中添加条件。我们还需要添加一个条件来检查玩家的背包中是否有我们所需要数量的cod（鳕鱼）。我们可以通过添加一个`item`条件来做到。

{% code title="conditions.yml" lineNumbers="true" %}

```
conditions:
  isNight: "time 6-18"
  hasRecivedFood: "tag foodReceived"
  hasDoneTour: "tag tourDone"
  hasStartedFishing: "tag startedFishing"
  hasFishInInv: "item cod:3"
  hasDoneQuest: "tag questDone"
```

{% endcode %}

此外，我们还必须添加新的事件才行。这要从玩家的背包中删除3条鳕鱼，并且添加一个完成任务的标签。

{% code title="events.yml" lineNumbers="true" %}

```
events:
  # 其他事件不再展示
  addStartedFishingTag: "tag add startedFishing"
  addQuestDoneTag: "tag add questDone"
  takeFishFromPlayer: "take cod:3"  
```

{% endcode %}

现在让我们使用这些新的要素来完成对话。

需要我们注意的是，我们在对话中检查了`hasFishInInv`两次。这可以避免玩家在确定开始选项的时候通过丢弃物品来作弊。如果玩家这样做的话，对话就会简单地结束，并且不会给予任何物品。

<pre data-title="blacksmith.yml" data-line-numbers><code>conversations:
  Blacksmith:
    quester: "Blacksmith"
    first: "questDone,caughtAllFish,alreadyStarted,firstGreeting"
    NPC_options:
      firstGreeting:
        # 其他 player_options 不再展示
      caughtAllFish:
        text: "Oh let me see! Amazing.. Can I have them?"
        pointer: "agree"
        conditions: "hasFishInInv"
      giveFishToBlacksmith:
        text: "Thank you very much and here is the promised armour!"
        pointer: "seeYouSoon"
        events: "takeFishFromPlayer,addQuestDoneTag"
        <a data-footnote-ref href="#user-content-fn-6">conditions: "hasFishInInv" </a>
      goodbye:
        text: "It was nice to meet you! I hope we will see us soon again. Goodbye"
      questDone: 
        <a data-footnote-ref href="#user-content-fn-7">text: "Nice to see you again %player%!" </a>
        conditions: "hasDoneQuest"
    player_options:
       其他 player_options 不再展示
      deny:
        text: "I dont have time right now."
        pointer: "maybeLater"
      agree:
        text: "Of course! Take em."
        pointer: "giveFishToBlacksmith"
      seeYouSoon:
        text: "That was a pleasure! See you soon..."
        pointer: "goodbye"
</code></pre>

### 5.3.2 发放盔甲

现在添加一个事件来奖励你自己的的玩家。

{% hint style="warning" %}
提示：

你必须使用`give`事件来给予物品，一切物品均已在你的"*package.yml*" 文件中的`items`部分中被定义。
{% endhint %}

<details>

<summary>解决方案：</summary>

{% code title="package.yml" lineNumbers="true" %}

```
items:
  # Other items not shown
  ironHelmet: "IRON_HELMET"
  ironChestplate: "IRON_CHESTPLATE"
  ironLeggings: "IRON_LEGGINGS"
  ironBoots: "IRON_BOOTS"
```

{% endcode %}

{% code title="events.yml" lineNumbers="true" %}

```
events:
  # Other events not shown
  rewardPlayer: "give ironBoots,ironChestplate,ironLeggings,ironHelmet"
```

{% endcode %}

{% code title="blacksmith.yml" lineNumbers="true" %}

```
giveFishToBlacksmith:
  text: "Thank you very much and here is the promised armour!"
  pointer: "seeYouSoon"
  events: "takeFishFromPlayer,addQuestDoneTag,rewardPlayer"
  conditions: "hasFishInInv"
```

{% endcode %}

</details>

<details>

<summary>这个示例不起作用吗？</summary>

通过运行以指令获取正确的配置。\
*这将覆盖您对示例所做的任何更改（包括 NPC ID）。*\
[基础教程](https://miao-3.gitbook.io/betonquest-zhong-wen-wiki/jiao-cheng/ru-men/ji-chu-jiao-cheng/pages/3gPGDyqwfkb9OR8DAmsm#1.-jiang-dui-hua-lian-jie-dao-npc-shang)中介绍了将 NPC 链接到对话。<img src="https://twemoji.maxcdn.com/v/latest/svg/26a0.svg" alt="⚠" data-size="line">

```
/bq download BetonQuest/Quest-Tutorials main QuestPackages /Basics/Conditions/5-FullExample /tutorialQuest overwrite
```

</details>

## 6.事件中的条件

在这部分中，你讲学习如何在事件中使用条件。当你想阻止一个事件被触发，但由于玩家有些条件不符合时，这很容易。

我们将在"*conditions.yml*" 文件中，临时创建一个名为`receiveNotify`标签条件，像这样：

{% code title="conditions.yml" lineNumbers="true" %}

```
conditions:
  receiveNotify: "tag receiveNotify"
```

{% endcode %}

现在我们来创建一个事件来测试我们刚刚创建的条件。为了达到测试目的，我们将用一个`notify`（通知）事件：

{% code title="events.yml" lineNumbers="true" %}

```
events:
  notifyPlayer: "notify You completed the quest! io:Title sound:firework_rocket conditions:receiveNotify"
```

{% endcode %}

让我们来拆解分析一下：

* `notifyPlayer`：事件的名字
* `notifyxia`：事件类型，`notify`（通知）事件用于向玩家发送通知
* `You completed the quest!`：通知的消息内容
* `io:Title：`消息将以 Tittle（标题）的形式显示
* `sound:firework_rocket`：消息将伴随着一个烟花音效
* `conditions:receiveNotify`：事件将会在是否符合`receiveNotify`条件才会触发。这个参数适用所有事件。

你能看到通知事件使用了一个条件。这意味着只有玩家在拥有标签的情况下，才能够收到通知。记得保存、重载，并在游戏中测试它是否工作！

你可以简单地使用BetonQuest命令进行测试:

```
/bq event PLAYERNAME tutorialQuest.notifyPlayer
```

但是什么也没有，因为玩家没有`receiveNotify`标签。

现在运行以下指令，然后再次尝试上面的指令。

``/bq tag PLAYERNAME del tutorialQuest.receiveNotify`.``

当你需要测试你的任务并且重置玩家的进度时，这是非常有用的。&#x20;

依照你的喜好，你可以将这个事件添加到你的铁匠对话中。但请确保你在事件的指令中删除了条件。在该任务中，它没有任何用处，但在notify（通知）事件中，它展示了如何在事件中使用条件的一个很好的例子。

## 总结

现在，你已经了解了什么是条件，以及如何在目标、对话和事件中使用它们。

更多的条件可以在条件列表中找到。

[^1]: 新增部分

[^2]: 这个选项会从左到右检查所有对话的可能开始开始的指向。玩家符合第一个条件将会被使用。条件可以在`NPC_options`中找到。如果玩家不符合其中任意一个选项，那么对话将不会开始。

    在目前的情况下来看，如果玩家符合 `hasRecivedFood`条件，他们将开始`alreadyReceivedFood`选项。

[^3]: 如果没有其他选项符合条件，该选项将会被展示。这是因为该选项没有条件，并且在`first`列表中是最后一个选项。

[^4]: 如果玩家选择了`foodAnswer`这个选项。他将会给予玩家食物和`foodReceived`标签。

[^5]: 这个条件会确保如果玩家有`foodReceived`标签，玩家将只能看见`alreadyFoodReceived`这个选项

[^6]: 这个就是我们上面所说的避免玩家作弊的保护。如果玩家丢弃物品，对话就会结束。

[^7]: 当玩家已经完成任务时的对话
