mirror of
https://github.com/evennia/evennia.git
synced 2026-03-17 05:16:31 +01:00
Add breadcrumbs. Format markdown files to char width 100
This commit is contained in:
parent
10c1831aad
commit
78970e92b3
142 changed files with 10357 additions and 3417 deletions
|
|
@ -1,11 +1,16 @@
|
|||
# Tutorial Aggressive NPCs
|
||||
|
||||
|
||||
This tutorial shows the implementation of an NPC object that responds to characters entering their location. In this example the NPC has the option to respond aggressively or not, but any actions could be triggered this way.
|
||||
This tutorial shows the implementation of an NPC object that responds to characters entering their
|
||||
location. In this example the NPC has the option to respond aggressively or not, but any actions
|
||||
could be triggered this way.
|
||||
|
||||
One could imagine using a [Script](Scripts) that is constantly checking for newcomers. This would be highly inefficient (most of the time its check would fail). Instead we handle this on-demand by using a couple of existing object hooks to inform the NPC that a Character has entered.
|
||||
One could imagine using a [Script](Scripts) that is constantly checking for newcomers. This would be
|
||||
highly inefficient (most of the time its check would fail). Instead we handle this on-demand by
|
||||
using a couple of existing object hooks to inform the NPC that a Character has entered.
|
||||
|
||||
It is assumed that you already know how to create custom room and character typeclasses, please see the [Basic Game tutorial](Tutorial-for-basic-MUSH-like-game) if you haven't already done this.
|
||||
It is assumed that you already know how to create custom room and character typeclasses, please see
|
||||
the [Basic Game tutorial](Tutorial-for-basic-MUSH-like-game) if you haven't already done this.
|
||||
|
||||
What we will need is the following:
|
||||
|
||||
|
|
@ -13,7 +18,8 @@ What we will need is the following:
|
|||
- A custom [Room](Objects#rooms) typeclass that can tell the NPC that someone entered.
|
||||
- We will also tweak our default `Character` typeclass a little.
|
||||
|
||||
To begin with, we need to create an NPC typeclass. Create a new file inside of your typeclasses folder and name it `npcs.py` and then add the following code:
|
||||
To begin with, we need to create an NPC typeclass. Create a new file inside of your typeclasses
|
||||
folder and name it `npcs.py` and then add the following code:
|
||||
|
||||
```python
|
||||
from typeclasses.characters import Character
|
||||
|
|
@ -33,7 +39,11 @@ class NPC(Character):
|
|||
self.execute_cmd(f"say Greetings, {character}!")
|
||||
```
|
||||
|
||||
We will define our custom `Character` typeclass below. As for the new `at_char_entered` method we've just defined, we'll ensure that it will be called by the room where the NPC is located, when a player enters that room. You'll notice that right now, the NPC merely speaks. You can expand this part as you like and trigger all sorts of effects here (like combat code, fleeing, bartering or quest-giving) as your game design dictates.
|
||||
We will define our custom `Character` typeclass below. As for the new `at_char_entered` method we've
|
||||
just defined, we'll ensure that it will be called by the room where the NPC is located, when a
|
||||
player enters that room. You'll notice that right now, the NPC merely speaks. You can expand this
|
||||
part as you like and trigger all sorts of effects here (like combat code, fleeing, bartering or
|
||||
quest-giving) as your game design dictates.
|
||||
|
||||
Now your `typeclasses.rooms` module needs to have the following added:
|
||||
|
||||
|
|
@ -55,13 +65,26 @@ from evennia import utils
|
|||
item.at_char_entered(obj)
|
||||
```
|
||||
|
||||
`inherits_from` must be given the full path of the class. If the object inherited a class from your `world.races` module, then you would check inheritance with `world.races.Human`, for example. There is no need to import these prior, as we are passing in the full path. As a matter of a fact, `inherits_from` does not properly work if you import the class and only pass in the name of the class.
|
||||
`inherits_from` must be given the full path of the class. If the object inherited a class from your
|
||||
`world.races` module, then you would check inheritance with `world.races.Human`, for example. There
|
||||
is no need to import these prior, as we are passing in the full path. As a matter of a fact,
|
||||
`inherits_from` does not properly work if you import the class and only pass in the name of the
|
||||
class.
|
||||
|
||||
> Note: [at_object_receive](https://github.com/evennia/evennia/blob/master/evennia/objects/objects.py#L1529) is a default hook of the `DefaultObject` typeclass (and its children). Here we are overriding this hook in our customized room typeclass to suit our needs.
|
||||
> Note:
|
||||
[at_object_receive](https://github.com/evennia/evennia/blob/master/evennia/objects/objects.py#L1529)
|
||||
is a default hook of the `DefaultObject` typeclass (and its children). Here we are overriding this
|
||||
hook in our customized room typeclass to suit our needs.
|
||||
|
||||
This room checks the typeclass of objects entering it (using `utils.inherits_from` and responds to `Characters`, ignoring other NPCs or objects. When triggered the room will look through its contents and inform any `NPCs inside by calling their `at_char_entered` method.
|
||||
This room checks the typeclass of objects entering it (using `utils.inherits_from` and responds to
|
||||
`Characters`, ignoring other NPCs or objects. When triggered the room will look through its
|
||||
contents and inform any `NPCs inside by calling their `at_char_entered` method.
|
||||
|
||||
You'll also see that we have added a 'look' into this code. This is because, by default, the `at_object_receive` is carried out *before* the character's `at_after_move` which, we will now overload. This means that a character entering would see the NPC perform its actions before the 'look' command. Deactivate the look command in the default `Character` class within the `typeclasses.characters` module:
|
||||
You'll also see that we have added a 'look' into this code. This is because, by default, the
|
||||
`at_object_receive` is carried out *before* the character's `at_after_move` which, we will now
|
||||
overload. This means that a character entering would see the NPC perform its actions before the
|
||||
'look' command. Deactivate the look command in the default `Character` class within the
|
||||
`typeclasses.characters` module:
|
||||
|
||||
```python
|
||||
# Add this hook in any blank area within your Character class.
|
||||
|
|
@ -80,15 +103,18 @@ reload
|
|||
create/drop Orc:npcs.NPC
|
||||
```
|
||||
|
||||
> Note: You could also give the path as `typeclasses.npcs.NPC`, but Evennia will look into the `typeclasses` folder automatically, so this is a little shorter.
|
||||
> Note: You could also give the path as `typeclasses.npcs.NPC`, but Evennia will look into the
|
||||
`typeclasses` folder automatically, so this is a little shorter.
|
||||
|
||||
When you enter the aggressive NPC's location, it will default to using its peaceful action (say your name is Anna):
|
||||
When you enter the aggressive NPC's location, it will default to using its peaceful action (say your
|
||||
name is Anna):
|
||||
|
||||
```
|
||||
Orc says, "Greetings, Anna!"
|
||||
```
|
||||
|
||||
Now we turn on the aggressive mode (we do it manually but it could also be triggered by some sort of AI code).
|
||||
Now we turn on the aggressive mode (we do it manually but it could also be triggered by some sort of
|
||||
AI code).
|
||||
|
||||
```
|
||||
set orc/is_aggressive = True
|
||||
|
|
@ -98,4 +124,4 @@ Now it will perform its aggressive action whenever a character enters.
|
|||
|
||||
```
|
||||
Orc says, "Graaah, die, Anna!"
|
||||
```
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue