Expand tutorial on equipmenthandler

This commit is contained in:
Griatch 2022-08-30 23:03:39 +02:00
parent 9c45feaf10
commit 805fbd5edb
423 changed files with 689 additions and 3613 deletions

View file

@ -14,7 +14,7 @@ you only the beginning or some part of it, it covers much of the things needed t
Evennia is developed using Python. Even if you are more of a designer than a coder, it is wise to
learn how to read and understand basic Python code. If you are new to Python, or need a refresher,
take a look at our [Python introduction](../Howtos/Beginner-Tutorial/Part1/Python-basic-introduction.md).
take a look at our [Python introduction](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Python-basic-introduction.md).
## Explore Evennia interactively
@ -91,7 +91,7 @@ using such a checker can be a good start to weed out the simple problems.
## Plan before you code
Before you start coding away at your dream game, take a look at our [Game Planning](../Howtos/Beginner-Tutorial/Part2/Game-Planning.md)
Before you start coding away at your dream game, take a look at our [Game Planning](../Howtos/Beginner-Tutorial/Part2/Beginner-Tutorial-Game-Planning.md)
page. It might hopefully help you avoid some common pitfalls and time sinks.
## Code in your game folder, not in the evennia/ repository

View file

@ -26,7 +26,7 @@ on. The tutorial world included with Evennia showcases a dark room that replaces
commands with its own versions because the Character cannot see.
If you want a quick start into defining your first commands and using them with command sets, you
can head over to the [Adding Command Tutorial](../Howtos/Beginner-Tutorial/Part1/Adding-Commands.md) which steps through things
can head over to the [Adding Command Tutorial](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.md) which steps through things
without the explanations.
## Defining Command Sets
@ -112,7 +112,7 @@ back even if all other cmdsets fail or are removed. It is always persistent and
by `cmdset.delete()`. To remove a default cmdset you must explicitly call `cmdset.remove_default()`.
Command sets are often added to an object in its `at_object_creation` method. For more examples of
adding commands, read the [Step by step tutorial](../Howtos/Beginner-Tutorial/Part1/Adding-Commands.md). Generally you can
adding commands, read the [Step by step tutorial](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.md). Generally you can
customize which command sets are added to your objects by using `self.cmdset.add()` or
`self.cmdset.add_default()`.

View file

@ -6,4 +6,4 @@
See also:
- [Default Commands](./Default-Commands.md)
- [Adding Command Tutorial](../Howtos/Beginner-Tutorial/Part1/Adding-Commands.md)
- [Adding Command Tutorial](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.md)

View file

@ -29,7 +29,7 @@ object in various ways. Consider a "Tree" object with a cmdset defining the comm
This page goes into full detail about how to use Commands. To fully use them you must also read the
page detailing [Command Sets](./Command-Sets.md). There is also a step-by-step
[Adding Command Tutorial](../Howtos/Beginner-Tutorial/Part1/Adding-Commands.md) that will get you started quickly without the
[Adding Command Tutorial](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.md) that will get you started quickly without the
extra explanations.
## Defining Commands

View file

@ -49,7 +49,7 @@ connect to the demo via your telnet client you can do so at `demo.evennia.com`,
Once you installed Evennia yourself it comes with its own tutorial - this shows off some of the
possibilities _and_ gives you a small single-player quest to play. The tutorial takes only one
single in-game command to install as explained [here](Howtos/Beginner-Tutorial/Part1/Tutorial-World.md).
single in-game command to install as explained [here](Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Tutorial-World.md).
## What you need to know to work with Evennia
@ -72,7 +72,7 @@ online](https://github.com/evennia/evennia). We also have a comprehensive [onlin
manual](https://evennia.com/docs) with lots of examples. But while Python is
considered a very easy programming language to get into, you do have a learning curve to climb if
you are new to programming. Evennia's [Starting-tutorial](Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Part1-Intro.md) has a [basic introduction
to Python](Howtos/Beginner-Tutorial/Part1/Python-basic-introduction.md) but you should probably also sit down
to Python](Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Python-basic-introduction.md) but you should probably also sit down
with a full Python beginner's tutorial at some point (there are plenty of them on
the web if you look around). See also our [link
page](./Links.md) for some reading suggestions. To efficiently code your dream game in
@ -124,7 +124,7 @@ chat](https://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE
on IRC. This allows you to chat directly with other developers new and old as well as with the devs
of Evennia itself. This chat is logged (you can find links on https://www.evennia.com) and can also
be searched from the same place for discussion topics you are interested in.
2. Read the [Game Planning](Howtos/Beginner-Tutorial/Part2/Game-Planning.md) wiki page. It gives some ideas for your work flow and the
2. Read the [Game Planning](Howtos/Beginner-Tutorial/Part2/Beginner-Tutorial-Game-Planning.md) wiki page. It gives some ideas for your work flow and the
state of mind you should aim for - including cutting down the scope of your game for its first
release.
3. Do the [Tutorial for basic MUSH-like game](Howtos/Tutorial-for-basic-MUSH-like-game.md) carefully from

View file

@ -100,7 +100,7 @@ There is usually no need to know the details of Django's database handling in or
it will handle most of the complexity for you under the hood using what we call
[typeclasses](./Glossary.md#typeclass). But should you need the power of Django you can always get it.
Most commonly people want to use "raw" Django when doing more advanced/custom database queries than
offered by Evennia's [default search functions](Howtos/Beginner-Tutorial/Part1/Searching-Things.md). One will then need
offered by Evennia's [default search functions](Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Searching-Things.md). One will then need
to read about Django's _querysets_. Querysets are Python method calls on a special form that lets
you build complex queries. They get converted into optimized SQL queries under the hood, suitable
for your current database. [Here is our tutorial/explanation of Django queries](Tutorial-Searching-

View file

@ -753,7 +753,7 @@ class CmdStand2(Command):
```
This forced us to to use the full power of the `caller.search` method. If we wanted to search for something
more complex we would likely need to break out a [Django query](Beginner-Tutorial/Part1/Django-queries.md) to do it. The key here is that
more complex we would likely need to break out a [Django query](Beginner-Tutorial/Part1/Beginner-Tutorial-Django-queries.md) to do it. The key here is that
we know that the object we are looking for is a `Sittable` and that it must have an Attribute named `sitter`
which should be set to us, the one sitting on/in the thing. Once we have that we just call `.do_stand` on it
and let the Typeclass handle the rest.

View file

@ -54,7 +54,7 @@ A new folder `myarx` should appear next to the ones you already had. You could r
something else if you want.
`cd` into `myarx`. If you wonder about the structure of the game dir, you can
[read more about it here](Beginner-Tutorial/Part1/Gamedir-Overview.md).
[read more about it here](Beginner-Tutorial/Part1/Beginner-Tutorial-Gamedir-Overview.md).
### Clean up settings

View file

@ -181,7 +181,7 @@ class CmdEcho(Command):
First we added a docstring. This is always a good thing to do in general, but for a Command class, it will also
automatically become the in-game help entry! Next we add the `func` method. It has one active line where it
makes use of some of those variables we found the Command offers to us. If you did the
[basic Python tutorial](./Python-basic-introduction.md), you will recognize `.msg` - this will send a message
[basic Python tutorial](./Beginner-Tutorial-Python-basic-introduction.md), you will recognize `.msg` - this will send a message
to the object it is attached to us - in this case `self.caller`, that is, us. We grab `self.args` and includes
that in the message.

View file

@ -149,7 +149,7 @@ the raw description of your current room (including color codes), so that you ca
set its description to something else.
You create new Commands (or modify existing ones) in Python outside the game. We will get to that
later, in the [Commands tutorial](./Adding-Commands.md).
later, in the [Commands tutorial](./Beginner-Tutorial-Adding-Commands.md).
## Get a Personality

View file

@ -200,7 +200,7 @@ people change and re-structure this in various ways to better fit their ideas.
- [batch_cmds.ev](github:evennia/game_template/world/batch_cmds.ev) - This is an `.ev` file, which is essentially
just a list of Evennia commands to execute in sequence. This one is empty and ready to expand on. The
[Tutorial World](./Tutorial-World.md) was built with such a batch-file.
[Tutorial World](./Beginner-Tutorial-Tutorial-World.md) was built with such a batch-file.
- [prototypes.py](github:evennia/game_template/world/prototypes.py) - A [prototype](../../../Components/Prototypes.md) is a way
to easily vary objects without changing their base typeclass. For example, one could use prototypes to
tell that Two goblins, while both of the class 'Goblin' (so they follow the same code logic), should have different

View file

@ -251,7 +251,7 @@ You are specifying exactly which typeclass you want to use to build the Giantess
desc = You see nothing special.
-------------------------------------------------------------------------------
We used the `examine` command briefly in the [lesson about building in-game](./Building-Quickstart.md). Now these lines
We used the `examine` command briefly in the [lesson about building in-game](./Beginner-Tutorial-Building-Quickstart.md). Now these lines
may be more useful to us:
- **Name/key** - The name of this thing. The value `(#14)` is probably different for you. This is the
unique 'primary key' or _dbref_ for this entity in the database.
@ -357,7 +357,7 @@ You got a lot longer output this time. You have a lot more going on than a simpl
- **Session id(s)**: This identifies the _Session_ (that is, the individual connection to a player's game client).
- **Account** shows, well the `Account` object associated with this Character and Session.
- **Stored/Merged Cmdsets** and **Commands available** is related to which _Commands_ are stored on you. We will
get to them in the [next lesson](./Adding-Commands.md). For now it's enough to know these consitute all the
get to them in the [next lesson](./Beginner-Tutorial-Adding-Commands.md). For now it's enough to know these consitute all the
commands available to you at a given moment.
- **Non-Persistent attributes** are Attributes that are only stored temporarily and will go away on next reload.

View file

@ -143,8 +143,8 @@ change (no code changed, only stuff in the database).
## Adding a Command to an object
The commands of a cmdset attached to an object with `obj.cmdset.add()` will by default be made available to that object
but _also to those in the same location as that object_. If you did the [Building introduction](./Building-Quickstart.md)
you've seen an example of this with the "Red Button" object. The [Tutorial world](./Tutorial-World.md)
but _also to those in the same location as that object_. If you did the [Building introduction](./Beginner-Tutorial-Building-Quickstart.md)
you've seen an example of this with the "Red Button" object. The [Tutorial world](./Beginner-Tutorial-Tutorial-World.md)
also has many examples of objects with commands on them.
To show how this could work, let's put our 'hit' Command on our simple `sword` object from the previous section.

View file

@ -30,18 +30,18 @@ these concepts in the context of Evennia before.
:maxdepth: 1
:numbered:
Building-Quickstart
Tutorial-World
Python-basic-introduction
Gamedir-Overview
Python-classes-and-objects
Evennia-Library-Overview
Learning-Typeclasses
Adding-Commands
More-on-Commands
Creating-Things
Searching-Things
Django-queries
Beginner-Tutorial-Building-Quickstart
Beginner-Tutorial-Tutorial-World
Beginner-Tutorial-Python-basic-introduction
Beginner-Tutorial-Gamedir-Overview
Beginner-Tutorial-Python-classes-and-objects
Beginner-Tutorial-Evennia-Library-Overview
Beginner-Tutorial-Learning-Typeclasses
Beginner-Tutorial-Adding-Commands
Beginner-Tutorial-More-on-Commands
Beginner-Tutorial-Creating-Things
Beginner-Tutorial-Searching-Things
Beginner-Tutorial-Django-queries
```
@ -50,17 +50,17 @@ Django-queries
```{toctree}
:maxdepth: 2
Building-Quickstart
Tutorial-World
Python-basic-introduction
Gamedir-Overview
Python-classes-and-objects
Evennia-Library-Overview
Learning-Typeclasses
Adding-Commands
More-on-Commands
Creating-Things
Searching-Things
Django-queries
Beginner-Tutorial-Building-Quickstart
Beginner-Tutorial-Tutorial-World
Beginner-Tutorial-Python-basic-introduction
Beginner-Tutorial-Gamedir-Overview
Beginner-Tutorial-Python-classes-and-objects
Beginner-Tutorial-Evennia-Library-Overview
Beginner-Tutorial-Learning-Typeclasses
Beginner-Tutorial-Adding-Commands
Beginner-Tutorial-More-on-Commands
Beginner-Tutorial-Creating-Things
Beginner-Tutorial-Searching-Things
Beginner-Tutorial-Django-queries
```

View file

@ -93,7 +93,7 @@ The form `from ... import ... as ...` renames the import.
> Avoid renaming unless it's to avoid a name-collistion like above - you want to make things as
> easy to read as possible, and renaming adds another layer of potential confusion.
In [the basic intro to Python](./Python-basic-introduction.md) we learned how to open the in-game
In [the basic intro to Python](./Beginner-Tutorial-Python-basic-introduction.md) we learned how to open the in-game
multi-line interpreter.
> py
@ -153,7 +153,7 @@ Next we have a `class` named `Object`, which _inherits_ from `DefaultObject`. Th
actually do anything on its own, its only code (except the docstring) is `pass` which means,
well, to pass and don't do anything.
We will get back to this module in the [next lesson](./Learning-Typeclasses.md). First we need to do a
We will get back to this module in the [next lesson](./Beginner-Tutorial-Learning-Typeclasses.md). First we need to do a
little detour to understand what a 'class', an 'object' or 'instance' is. These are fundamental
things to understand before you can use Evennia efficiently.
```{sidebar} OOP

View file

@ -29,16 +29,16 @@ and "what to think about" when creating a multiplayer online text game.
```{toctree}
:maxdepth: 1
Planning-Where-Do-I-Begin.md
Game-Planning.md
Planning-The-Tutorial-Game.md
Beginner-Tutorial-Planning-Where-Do-I-Begin.md
Beginner-Tutorial-Game-Planning.md
Beginner-Tutorial-Planning-The-Tutorial-Game.md
```
## Table of Contents
```{toctree}
Planning-Where-Do-I-Begin.md
Game-Planning.md
Planning-The-Tutorial-Game.md
Beginner-Tutorial-Planning-Where-Do-I-Begin.md
Beginner-Tutorial-Game-Planning.md
Beginner-Tutorial-Planning-The-Tutorial-Game.md
```

View file

@ -32,7 +32,7 @@ Here's an overview of the topside camp for inspiration (quickly thrown together
![Last Step Camp](../../../_static/images/starting_tutorial/Dungeon_Merchant_Camp.jpg)
For the rest of this lesson we'll answer and reason around the specific questions posed in the previous [Game Planning](./Game-Planning.md) lesson.
For the rest of this lesson we'll answer and reason around the specific questions posed in the previous [Game Planning](./Beginner-Tutorial-Game-Planning.md) lesson.
## Administration

View file

@ -276,6 +276,34 @@ class EvAdventureRollEngine:
# ...
```
## Connecting the Character with Evennia
You can easily make yourself an `EvAdventureCharacter` in-game by using the
`type` command:
type self = evadventure.characters.EvAdventureCharacter
You can now do `examine self` to check your type updated.
If you want _all_ new Characters to be of this type you need to tell Evennia about it. Evennia
uses a global setting `BASE_CHARACTER_TYPECLASS` to know which typeclass to use when creating
Characters (when logging in, for example). This defaults to `typeclasses.characters.Character` (that is,
the `Character` class in `mygame/typeclasses/characters.py`).
There are thus two ways to weave your new Character class into Evennia:
1. Change `mygame/server/conf/settings.py` and add `BASE_CHARACTER_CLASS = "evadventure.characters.EvAdventureCharacter"`.
2. Or, change `typeclasses.characters.Character` to inherit from `EvAdventureCharacter`.
You must always reload the server for changes like this to take effect.
```{important}
In this tutorial we are making all changes in a folder `mygame/evadventure/`. This means we can isolate
our code but means we need to do some extra steps to tie the character (and other objects) into Evennia.
For your own game it would be just fine to start editing `mygame/typeclasses/characters.py` directly
instead.
```
## Unit Testing
@ -329,6 +357,34 @@ For running the tests you do:
evennia test --settings settings.py .evadventure.tests.test_character
## About races and classes
_Knave_ doesn't have any D&D-style _classes_ (like Thief, Fighter etc). It also does not bother with
_races_ (like dwarves, elves etc). This makes the tutorial shorter, but you may ask yourself how you'd
add these functions.
In the framework we have sketched out for _Knave_, it would be simple - you'd add your race/class as
an Attribute on your Character:
```python
# mygame/evadventure/characters.py
from evennia import DefaultCharacter, AttributeProperty
# ...
class EvAdventureCharacter(LivingMixin, DefaultCharacter):
# ...
charclass = AttributeProperty("Fighter")
charrace = AttributeProperty("Human")
```
We use `charclass` rather than `class` here, because `class` is a reserved Python keyword. Naming
`race` as `charrace` thus matches in style.
## Summary

View file

@ -32,14 +32,13 @@ The BACKPACK is special - it contains any number of items (up to the maximum slo
> Create a new module `mygame/evadventure/equipment.py`.
In default Evennia, everything you pick up will end up "inside" your character object (that is, have
you as its `.location`). This is called your _inventory_ and has no limit. We will keep 'moving items into us'
when we pick them up, but we will add more functionality using an _Equipment handler_.
```{sidebar}
If you want to understand more about behind how Evennia uses handlers, there is a
[dedicated tutorial](../../Tutorial-Persistent-Handler.md) talking about the principle.
```
In default Evennia, everything you pick up will end up "inside" your character object (that is, have
you as its `.location`). This is called your _inventory_ and has no limit. We will keep 'moving items into us'
when we pick them up, but we will add more functionality using an _Equipment handler_.
A handler is (for our purposes) an object that sits "on" another entity, containing functionality
for doing one specific thing (managing equipment, in our case).
@ -101,13 +100,14 @@ class EvAdventureCharacter(LivingMixin, DefaultCharacter):
return EquipmentHandler(self)
```
After reloading the server, the equipment-handler will now be accessible on the character as
After reloading the server, the equipment-handler will now be accessible on character-instances as
character.equipment
The `@lazy_property` works such that it will not load the handler until it is first accessed. When that
happens, we start up the handler and feed it `self` (the Character itself). This is what enters `__init__`
as `.obj` in the `EquipmentHandler` code above.
The `@lazy_property` works such that it will not load the handler until someone actually tries to
fetch it with `character.equipment`. When that
happens, we start up the handler and feed it `self` (the `Character` instance itself). This is what
enters `__init__` as `.obj` in the `EquipmentHandler` code above.
So we now have a handler on the character, and the handler has a back-reference to the character it sits
on.
@ -125,9 +125,36 @@ have one item except `WieldLocation.BACKPACK`, which is a list.
## Connecting the EquipmentHandler
We already made `EquipmentHandler` available on the Character as `.equipment`. Now we want it to come into
play automatically whenever we pick up or drop something. To do this we need to override two hooks
on the Character class:
Whenever an object leaves from one location to the next, Evennia will call a set of _hooks_ (methods) on the
object that moves, on the source-location and on its destination. This is the same for all moving things -
whether it's a character moving between rooms or an item being dropping from your hand to the ground.
We need to tie our new `EquipmentHandler` into this system. By reading the doc page on [Objects](../../../Components/Objects.md),
or looking at the [DefaultObject.move_to](evennia.objects.objects.DefaultObject.move_to) docstring, we'll
find out what hooks Evennia will call. Here `self` is the object being moved from
`source_location` to `destination`:
1. `self.at_pre_move(destination)` (abort if return False)
2. `source_location.at_pre_object_leave(self, destination)` (abort if return False)
3. `destination.at_pre_object_receive(self, source_location)` (abort if return False)
4. `source_location.at_object_leave(self, destination)`
5. `self.announce_move_from(destination)`
6. (move happens here)
7. `self.announce_move_to(source_location)`
8. `destination.at_object_receive(self, source_location)`
9. `self.at_post_move(source_location)`
All of these hooks can be overridden to customize movement behavior. In this case we are interested in
controlling how items 'enter' and 'leave' our character - being 'inside' the character is the same as
them 'carrying' it. We have three good hook-candidates to use for this.
- `.at_pre_object_receive` - used to check if you can actually pick something up, or if your equipment-store is full.
- `.at_object_receive` - used to add the item to the equipmenthandler
- `.at_object_leave` - used to remove the item from the equipmenthandler
You could also picture using `.at_pre_object_leave` to restrict dropping (cursed?) items, but
we will skip that for this tutorial.
```python
# mygame/evadventure/character.py
@ -143,7 +170,6 @@ class EvAdventureCharacter(LivingMixin, DefaultCharacter):
if they pick up something). If it returns False, move is aborted.
"""
# we haven't written this yet!
return self.equipment.validate_slot_usage(moved_object)
def at_object_receive(self, moved_object, source_location, **kwargs):
@ -151,7 +177,7 @@ class EvAdventureCharacter(LivingMixin, DefaultCharacter):
Called by Evennia when an object arrives 'in' the character.
"""
self.equipment.add(moved_object)
self.equipment.add(moved_object)
def at_object_leave(self, moved_object, destination, **kwargs):
"""
@ -161,6 +187,413 @@ class EvAdventureCharacter(LivingMixin, DefaultCharacter):
self.equipment.remove(moved_object)
```
Above we have assumed the `EquipmentHandler` (`.equipment`) has methods `.validate_slot_usage`,
`.add` and `.remove`. But we haven't actually added them yet - we just put some reasonable names! Before
we can use this, we need to go actually adding those methods.
## Expanding the Equipmenthandler
## `.validate_slot_usage`
Let's start with implementing the first method we came up with above, `validate_slot_usage`:
```python
# mygame/evadventure/equipment.py
from .enums import WieldLocation, Ability
class EquipmentError(TypeError):
"""All types of equipment-errors"""
pass
class EquipmentHandler:
# ...
@property
def max_slots(self):
"""Max amount of slots, based on CON defense (CON + 10)"""
return getattr(self.obj, Ability.CON.value, 1) + 10
def count_slots(self):
"""Count current slot usage"""
slots = self.slots
wield_usage = sum(
getattr(slotobj, "size", 0) or 0
for slot, slotobj in slots.items()
if slot is not WieldLocation.BACKPACK
)
backpack_usage = sum(
getattr(slotobj, "size", 0) or 0 for slotobj in slots[WieldLocation.BACKPACK]
)
return wield_usage + backpack_usage
def validate_slot_usage(self, obj):
"""
Check if obj can fit in equipment, based on its size.
"""
if not inherits_from(obj, EvAdventureObject):
# in case we mix with non-evadventure objects
raise EquipmentError(f"{obj.key} is not something that can be equipped.")
size = obj.size
max_slots = self.max_slots
current_slot_usage = self.count_slots()
return current_slot_usage + size <= max_slots:
```
```{sidebar}
The `@property` decorator turns a method into a property so you don't need to 'call' it.
That is, you can access `.max_slots` instead of `.max_slots()`. In this case, it's just a
little less to type.
```
We add two helpers - the `max_slots` _property_ and `count_slots`, a method that calculate the current
slots being in use. Let's figure out how they work.
### `.max_slots`
For `max_slots`, remember that `.obj` on the handler is a back-reference to the `EvAdventureCharacter` we
put this handler on. `getattr` is a Python method for retrieving a named property on an object.
The `Enum` `Ability.CON.value` is the string `Constitution` (check out the
[first Utility and Enums tutorial](./Beginner-Tutorial-Utilities.md) if you don't recall).
So to be clear,
```python
getattr(self.obj, Ability.CON.value) + 10
```
is the same as writing
```python
getattr(your_character, "Constitution") + 10
```
which is the same as doing something like this:
```python
your_character.Constitution + 10
```
In our code we write `getattr(self.obj, Ability.CON.value, 1)` - that extra `1` means that if there
should happen to _not_ be a property "Constitution" on `self.obj`, we should not error out but just
return 1.
### `.count_slots`
In this helper we use two Python tools - the `sum()` function and a
[list comprehension](https://www.w3schools.com/python/python_lists_comprehension.asp). The former
simply adds the values of any iterable together. The latter is a more efficient way to create a list:
new_list = [item for item in some_iterable if condition]
all_above_5 = [num for num in range(10) if num > 5] # [6, 7, 8, 9]
all_below_5 = [num for num in range(10) if num < 5] # [0, 1, 2, 3, 4]
To make it easier to understand, try reading the last line above as "for every number in the range 0-9,
pick all with a value below 5 and make a list of them". You can also embed such comprehensions
directly in a function call like `sum()` without using `[]` around it.
In `count_slots` we have this code:
```python
wield_usage = sum(
getattr(slotobj, "size", 0)
for slot, slotobj in slots.items()
if slot is not WieldLocation.BACKPACK
)
```
We should be able to follow all except `slots.items()`. Since `slots` is a `dict`, we can use `.items()`
to get a sequence of `(key, value)` pairs. We store these in `slot` and `slotobj`. So the above can
be understood as "for every `slot` and `slotobj`-pair in `slots`, check which slot location it is.
If it is _not_ in the backpack, get its size and add it to the list. Sum over all these
sizes".
A less compact but maybe more readonable way to write this would be:
```python
backpack_item_sizes = []
for slot, slotobj in slots.items():
if slot is not WieldLocation.BACKPACK:
size = getattr(slotobj, "size", 0)
backpack_item_sizes.append(size)
wield_usage = sum(backpack_item_sizes)
```
The same is done for the items actually in the BACKPACK slot. The total sizes are added
together.
### Validating slots
With these helpers in place, `validate_slot_usage` now becomes simple. We use `max_slots` to see how much we can carry.
We then get how many slots we are already using (with `count_slots`) and see if our new `obj`'s size
would be too much for us.
## `.add` and `.remove`
We will make it so `.add` puts something in the `BACKPACK` location and `remove` drops it, wherever
it is (even if it was in your hands).
```python
# mygame/evadventure/equipment.py
from .enums import WieldLocation, Ability
# ...
class EquipmentHandler:
# ...
def add(self, obj):
"""
Put something in the backpack.
"""
self.validate_slot_usage(obj)
self.slots[WieldLocation.BACKPACK].append(obj)
self._save()
def remove(self, slot):
"""
Remove contents of a particular slot, for
example `equipment.remove(WieldLocation.SHIELD_HAND)`
"""
slots = self.slots
ret = []
if slot is WieldLocation.BACKPACK:
# empty entire backpack!
ret.extend(slots[slot])
slots[slot] = []
else:
ret.append(slots[slot])
slots[slot] = None
if ret:
self._save()
return ret
```
Both of these should be straight forward to follow. In `.add`, we make use of `validate_slot_usage` to
double-check we can actually fit the thing, then we add the item to the backpack.
In `.delete`, we allow emptying by `WieldLocation` - we figure out what slot it is and return
the item within (if any). If we gave `BACKPACK` as the slot, we empty the backpack and
return all items.
Whenever we change the equipment loadout we must make sure to `._save()` the result, or it will
be lost after a server reload.
## Moving things around
With the help of `.remove()` and `.add()` we can get things in and out of the `BACKPACK` equipment
location. We also need to grab stuff from the backpack and wield or wear it. We add a `.move` method
on the `EquipmentHandler` to do this:
```python
# mygame/evadventure/equipment.py
from .enums import WieldLocation, Ability
# ...
class EquipmentHandler:
# ...
def move(self, obj):
"""Move object from backpack to its intended `inventory_use_slot`."""
# make sure to remove from equipment/backpack first, to avoid double-adding
self.remove(obj)
slots = self.slots
use_slot = getattr(obj, "inventory_use_slot", WieldLocation.BACKPACK)
to_backpack = []
if use_slot is WieldLocation.TWO_HANDS:
# two-handed weapons can't co-exist with weapon/shield-hand used items
to_backpack = [slots[WieldLocation.WEAPON_HAND], slots[WieldLocation.SHIELD_HAND]]
slots[WieldLocation.WEAPON_HAND] = slots[WieldLocation.SHIELD_HAND] = None
slots[use_slot] = obj
elif use_slot in (WieldLocation.WEAPON_HAND, WieldLocation.SHIELD_HAND):
# can't keep a two-handed weapon if adding a one-handed weapon or shield
to_backpack = [slots[WieldLocation.TWO_HANDS]]
slots[WieldLocation.TWO_HANDS] = None
slots[use_slot] = obj
elif use_slot is WieldLocation.BACKPACK:
# it belongs in backpack, so goes back to it
to_backpack = [obj]
else:
# for others (body, head), just replace whatever's there
replaced = [obj]
slots[use_slot] = obj
for to_backpack_obj in to_backpack:
# put stuff in backpack
slots[use_slot].append(to_backpack_obj)
# store new state
self._save()
```
Here we remember that every `EvAdventureObject` has an `inventory_use_slot` property that tells us where
it goes. So we just need to move the object to that slot, replacing whatever is in that place
from before. Anything we replace goes back to the backpack.
## Get everything
In order to visualize our inventory, we need some method to get everything we are carrying.
```python
# mygame/evadventure/equipment.py
from .enums import WieldLocation, Ability
# ...
class EquipmentHandler:
# ...
def all(self):
"""
Get all objects in inventory, regardless of location.
"""
slots = self.slots
lst = [
(slots[WieldLocation.WEAPON_HAND], WieldLocation.WEAPON_HAND),
(slots[WieldLocation.SHIELD_HAND], WieldLocation.SHIELD_HAND),
(slots[WieldLocation.TWO_HANDS], WieldLocation.TWO_HANDS),
(slots[WieldLocation.BODY], WieldLocation.BODY),
(slots[WieldLocation.HEAD], WieldLocation.HEAD),
] + [(item, WieldLocation.BACKPACK) for item in slots[WieldLocation.BACKPACK]]
return lst
```
Here we get all the equipment locations and add their contents together into a list of tuples
`[(item, WieldLocation), ...]`. This is convenient for display.
## Weapon and armor
It's convenient to have the `EquipmentHandler` easily tell you what weapon is currently wielded
and what _armor_ level all worn equipment provides. Otherwise you'd need to figure out what item is
in which wield-slot and to add up armor slots manually every time you need to know.
```python
# mygame/evadventure/equipment.py
from .objects import WeaponEmptyHand
from .enums import WieldLocation, Ability
# ...
class EquipmentHandler:
# ...
@property
def armor(self):
slots = self.slots
return sum(
(
# armor is listed using its defense, so we remove 10 from it
# (11 is base no-armor value in Knave)
getattr(slots[WieldLocation.BODY], "armor", 1),
# shields and helmets are listed by their bonus to armor
getattr(slots[WieldLocation.SHIELD_HAND], "armor", 0),
getattr(slots[WieldLocation.HEAD], "armor", 0),
)
)
@property
def weapon(self):
# first checks two-handed wield, then one-handed; the two
# should never appear simultaneously anyhow (checked in `move` method).
slots = self.slots
weapon = slots[WieldLocation.TWO_HANDS]
if not weapon:
weapon = slots[WieldLocation.WEAPON_HAND]
if not weapon:
weapon = WeaponEmptyHand()
return weapon
```
In the `.armor()` method we get the item (if any) out of each relevant wield-slot (body, shield, head),
and grab their `armor` Attribute. We then `sum()` them all up.
In `.weapon()`, we simply check which of the possible weapon slots (weapon-hand or two-hands) have
something in them. If not we fall back to the 'fake' weapon `WeaponEmptyHand` which is just a 'dummy'
object that represents your bare hands with damage and all.
(created in [The Object tutorial](./Beginner-Tutorial-Objects.md#your-bare-hands) earlier).
## Extra credits
This covers the basic functionality of the equipment handler. There are other useful methods that
can be added:
- Given an item, figure out which equipment slot it is currently in
- Make a string representing the current loadout
- Get everything in the backpack (only)
- Get all wieldable items (weapons, shields) from backpack
- Get all usable items (items with a use-location of `BACKPACK`) from the backpack
Experiment with adding those. A full example is found in
[evennia/contrib/tutorials/evadventure/equipment.py](evennia.contrib.tutorials.evadventure.equipment).
## Unit Testing
> Create a new module `mygame/evadventure/tests/test_equipment.py`.
```{sidebar}
See [evennia/contrib/tutorials/evadventure/tests/test_equipment.py](evennia.contrib.tutorials.evadventure.tests.test_equipment)
for a finished testing example.
```
To test the `EquipmentHandler`, easiest is create an `EvAdventureCharacter` (this should by now
have `EquipmentHandler` available on itself as `.equipment`) and a few test objects; then test
passing these into the handler's methods.
```python
# mygame/evadventure/tests/test_equipment.py
from evennia.utils import create
from evennia.utils.test_resources import BaseEvenniaTest
from ..objects import EvAdventureRoom
from ..enums import WieldLocation
class TestEquipment(BaseEvenniaTest):
def setUp(self):
self.character = create.create_object(EvAdventureCharacter, key='testchar')
self.helmet = create.create_object(EvAdventureHelmet, key="helmet")
self.weapon = create.create_object(EvAdventureWeapon, key="weapon")
def test_add_remove):
self.character.equipment.add(self.helmet)
self.assertEqual(
self.character.equipment.slots[WieldLocation.BACKPACK],
[self.helmet]
)
self.character.equipment.remove(self.helmet)
self.assertEqual(self.character.equipment.slots[WieldLocation.BACKPACK], [])
# ...
```
## Summary
_Handlers_ are useful for grouping functionality together. Now that we spent our time making the
`EquipmentHandler`, we shouldn't need to worry about item-slots anymore - the handler 'handles' all
the details for us. As long as we call its methods, the details can be forgotten about.
We also learned to use _hooks_ to tie _Knave_'s custom equipment handling into Evennia.
With `Characters`, `Objects` and now `Equipment` in place, we should be able to move on to character
generation - where players get to make their own character!

View file

@ -325,10 +325,36 @@ class EvAdventureHelmet(EvAdventureArmor):
inventory_use_slot = WieldLocation.HEAD
```
## Your Bare hands
This is a 'dummy' object that is not stored in the database. We will use this in the upcoming
[Equipment tutorial lesson](./Beginner-Tutorial-Equipment.md) to represent when you have 'nothing'
in your hands. This way we don't need to add any special case for this.
```python
class WeaponEmptyHand:
obj_type = ObjType.WEAPON
key = "Empty Fists"
inventory_use_slot = WieldLocation.WEAPON_HAND
attack_type = Ability.STR
defense_type = Ability.ARMOR
damage_roll = "1d4"
quality = 100000 # let's assume fists are always available ...
def __repr__(self):
return "<WeaponEmptyHand>"
```
## Testing and Extra credits
Remember the `get_obj_stats` function from the [Utility Tutorial](./Beginner-Tutorial-Utilities.md) earlier?
We had to use dummy-values since we didn't yet know how we would store properties on Objects in the game.
Well, we just figured out all we need! You can go back and update `get_obj_stats` to properly read the data
from the object it receives.
When you change this function you must also update the related unit test - so your existing test becomes a
nice way to test your new Objects as well! Add more tests showing the output of feeding different object-types
to `get_obj_stats`.
Try it out yourself. If you need help, a finished utility example is found in [evennia/contrib/tutorials/evadventure/utils.py](get_obj_stats).

View file

@ -216,6 +216,12 @@ So we just set them to dummy values. We'll need to get back to this when we have
## Testing
```{important}
It's useful for any game dev to know how to effectively test their code. So we'll try to include a
*Testing* section at the end of each of the implementation lessons to follow. Writing tests for your code
is optional but highly recommended; it can feel a little cumbersome at first, but you'll thank yourself later.
```
> create a new module `mygame/evadventure/tests/test_utils.py`
How do you know if you made a typo in the code above? You could _manually_ test it by reloading your
@ -228,7 +234,7 @@ doing that test when you change this code later.
```{sidebar}
In [evennia/contrib/evadventure/tests/test_utils.py](evennia.contrib.evadventure.tests.test_utils)
is the final test module. To dive deeper into unit testing in Evennia, see the
is an example of the testing module. To dive deeper into unit testing in Evennia, see the
[Unit testing](../../../Coding/Unit-Testing.md) documentation.
```

View file

@ -28,7 +28,7 @@ Character [Command Set](../Components/Command-Sets.md)?
**A:** Go to `mygame/commands/default_cmdsets.py`. Find the `CharacterCmdSet` class. It has one
method named `at_cmdset_creation`. At the end of that method, add the following line:
`self.remove(default_cmds.CmdGet())`. See the [Adding Commands Tutorial](Beginner-Tutorial/Part1/Adding-Commands.md)
`self.remove(default_cmds.CmdGet())`. See the [Adding Commands Tutorial](Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.md)
for more info.
## Preventing character from moving based on a condition
@ -156,7 +156,7 @@ class CmdWerewolf(Command):
def func(self):
# ...
```
Add this to the [default cmdset as usual](Beginner-Tutorial/Part1/Adding-Commands.md). The `is_full_moon` [lock
Add this to the [default cmdset as usual](Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.md). The `is_full_moon` [lock
function](../Components/Locks.md#lock-functions) does not yet exist. We must create that:
```python

View file

@ -27,7 +27,7 @@ told us that we couldn't go there.
## Adding default error commands
The way to do this is to give Evennia an _alternative_ Command to use when no Exit-Command is found
in the room. See [Adding Commands](Beginner-Tutorial/Part1/Adding-Commands.md) for more info about the
in the room. See [Adding Commands](Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.md) for more info about the
process of adding new Commands to Evennia.
In this example all we'll do is echo an error message.

View file

@ -211,7 +211,7 @@ for-roleplaying-sessions) that can be of interest.
An important aspect of making things more familiar for *Players* is adding new and tweaking existing
commands. How this is done is covered by the [Tutorial on adding new commands](Adding-Command-
Tutorial). You may also find it useful to shop through the `evennia/contrib/` folder. The
[Tutorial world](Beginner-Tutorial/Part1/Tutorial-World.md) is a small single-player quest you can try (its not very MUSH-
[Tutorial world](Beginner-Tutorial/Part1/Beginner-Tutorial-Tutorial-World.md) is a small single-player quest you can try (its not very MUSH-
like but it does show many Evennia concepts in action). Beyond that there are [many more tutorials](./Howtos-Overview.md)
to try out. If you feel you want a more visual overview you can also look at
[Evennia in pictures](https://evennia.blogspot.se/2016/05/evennia-in-pictures.html).

View file

@ -686,7 +686,7 @@ implemented.
## Rooms
Evennia comes with rooms out of the box, so no extra work needed. A GM will automatically have all
needed building commands available. A fuller go-through is found in the [Building tutorial](Beginner-Tutorial/Part1/Building-Quickstart.md).
needed building commands available. A fuller go-through is found in the [Building tutorial](Beginner-Tutorial/Part1/Beginner-Tutorial-Building-Quickstart.md).
Here are some useful highlights:
* `@dig roomname;alias = exit_there;alias, exit_back;alias` - this is the basic command for digging

View file

@ -2,7 +2,7 @@
This tutorial will elaborate on the many ways one can parse command arguments. The first step after
[adding a command](Beginner-Tutorial/Part1/Adding-Commands.md) usually is to parse its arguments. There are lots of
[adding a command](Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.md) usually is to parse its arguments. There are lots of
ways to do it, but some are indeed better than others and this tutorial will try to present them.
If you're a Python beginner, this tutorial might help you a lot. If you're already familiar with
@ -652,7 +652,7 @@ about... what is this `"book"`?
To get an object from a string, we perform an Evennia search. Evennia provides a `search` method on
all typeclassed objects (you will most likely use the one on characters or accounts). This method
supports a very wide array of arguments and has [its own tutorial](Beginner-Tutorial/Part1/Searching-Things.md).
supports a very wide array of arguments and has [its own tutorial](Beginner-Tutorial/Part1/Beginner-Tutorial-Searching-Things.md).
Some examples of useful cases follow:
### Local searches

View file

@ -84,7 +84,7 @@ In this section we will try to create an actual "map" object that an account can
at.
Evennia offers a range of [default commands](../Components/Default-Commands.md) for
[creating objects and rooms in-game](Beginner-Tutorial/Part1/Building-Quickstart.md). While readily accessible, these commands are made to do very
[creating objects and rooms in-game](Beginner-Tutorial/Part1/Beginner-Tutorial-Building-Quickstart.md). While readily accessible, these commands are made to do very
specific, restricted things and will thus not offer as much flexibility to experiment (for an
advanced exception see [the FuncParser](../Components/FuncParser.md)). Additionally, entering long
descriptions and properties over and over in the game client can become tedious; especially when

View file

@ -507,7 +507,7 @@ class CmdAttack(Command):
```
The `attack` command will not go into the combat cmdset but rather into the default cmdset. See e.g.
the [Adding Command Tutorial](Beginner-Tutorial/Part1/Adding-Commands.md) if you are unsure about how to do this.
the [Adding Command Tutorial](Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.md) if you are unsure about how to do this.
## Expanding the example

View file

@ -660,6 +660,6 @@ The simple "Power" game mechanic should be easily expandable to something more f
useful, same is true for the combat score principle. The `+attack` could be made to target a
specific player (or npc) and automatically compare their relevant attributes to determine a result.
To continue from here, you can take a look at the [Tutorial World](Beginner-Tutorial/Part1/Tutorial-World.md). For
To continue from here, you can take a look at the [Tutorial World](Beginner-Tutorial/Part1/Beginner-Tutorial-Tutorial-World.md). For
more specific ideas, see the [other tutorials and hints](./Howtos-Overview.md) as well
as the [Evennia Component overview](../Components/Components-Overview.md).

View file

@ -30,7 +30,7 @@ pip install python-twitter
Evennia doesn't have a `tweet` command out of the box so you need to write your own little
[Command](../Components/Commands.md) in order to tweet. If you are unsure about how commands work and how to add
them, it can be an idea to go through the [Adding a Command Tutorial](../Howtos/Beginner-Tutorial/Part1/Adding-Commands.md)
them, it can be an idea to go through the [Adding a Command Tutorial](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.md)
before continuing.
You can create the command in a separate command module (something like `mygame/commands/tweet.py`)

View file

@ -111,7 +111,7 @@ beforehand to make sure you don't pick a game name that is already taken - be ni
You are good to go!
Evennia comes with a small [Tutorial World](../Howtos/Beginner-Tutorial/Part1/Tutorial-World.md) to experiment and learn from. After logging
Evennia comes with a small [Tutorial World](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Tutorial-World.md) to experiment and learn from. After logging
in, you can create it by running
batchcommand tutorial_world.build

View file

@ -1,7 +0,0 @@
evennia
=======
.. toctree::
:maxdepth: 6
evennia

View file

@ -1,7 +0,0 @@
evennia.accounts.accounts module
================================
.. automodule:: evennia.accounts.accounts
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.accounts.bots module
============================
.. automodule:: evennia.accounts.bots
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.accounts.manager module
===============================
.. automodule:: evennia.accounts.manager
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.accounts.models module
==============================
.. automodule:: evennia.accounts.models
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,17 +0,0 @@
evennia.accounts package
========================
.. automodule:: evennia.accounts
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.accounts.accounts
evennia.accounts.bots
evennia.accounts.manager
evennia.accounts.models

View file

@ -1,7 +0,0 @@
evennia.commands.cmdhandler module
==================================
.. automodule:: evennia.commands.cmdhandler
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.cmdparser module
=================================
.. automodule:: evennia.commands.cmdparser
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.cmdset module
==============================
.. automodule:: evennia.commands.cmdset
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.cmdsethandler module
=====================================
.. automodule:: evennia.commands.cmdsethandler
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.command module
===============================
.. automodule:: evennia.commands.command
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.account module
=======================================
.. automodule:: evennia.commands.default.account
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.admin module
=====================================
.. automodule:: evennia.commands.default.admin
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.batchprocess module
============================================
.. automodule:: evennia.commands.default.batchprocess
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.building module
========================================
.. automodule:: evennia.commands.default.building
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.cmdset\_account module
===============================================
.. automodule:: evennia.commands.default.cmdset_account
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.cmdset\_character module
=================================================
.. automodule:: evennia.commands.default.cmdset_character
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.cmdset\_session module
===============================================
.. automodule:: evennia.commands.default.cmdset_session
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.cmdset\_unloggedin module
==================================================
.. automodule:: evennia.commands.default.cmdset_unloggedin
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.comms module
=====================================
.. automodule:: evennia.commands.default.comms
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.general module
=======================================
.. automodule:: evennia.commands.default.general
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.help module
====================================
.. automodule:: evennia.commands.default.help
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.muxcommand module
==========================================
.. automodule:: evennia.commands.default.muxcommand
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,29 +0,0 @@
evennia.commands.default package
================================
.. automodule:: evennia.commands.default
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.commands.default.account
evennia.commands.default.admin
evennia.commands.default.batchprocess
evennia.commands.default.building
evennia.commands.default.cmdset_account
evennia.commands.default.cmdset_character
evennia.commands.default.cmdset_session
evennia.commands.default.cmdset_unloggedin
evennia.commands.default.comms
evennia.commands.default.general
evennia.commands.default.help
evennia.commands.default.muxcommand
evennia.commands.default.syscommands
evennia.commands.default.system
evennia.commands.default.tests
evennia.commands.default.unloggedin

View file

@ -1,7 +0,0 @@
evennia.commands.default.syscommands module
===========================================
.. automodule:: evennia.commands.default.syscommands
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.system module
======================================
.. automodule:: evennia.commands.default.system
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.tests module
=====================================
.. automodule:: evennia.commands.default.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.commands.default.unloggedin module
==========================================
.. automodule:: evennia.commands.default.unloggedin
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,24 +0,0 @@
evennia.commands package
========================
.. automodule:: evennia.commands
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.commands.cmdhandler
evennia.commands.cmdparser
evennia.commands.cmdset
evennia.commands.cmdsethandler
evennia.commands.command
.. toctree::
:maxdepth: 6
evennia.commands.default

View file

@ -1,7 +0,0 @@
evennia.comms.comms module
==========================
.. automodule:: evennia.comms.comms
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.comms.managers module
=============================
.. automodule:: evennia.comms.managers
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.comms.models module
===========================
.. automodule:: evennia.comms.models
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,16 +0,0 @@
evennia.comms package
=====================
.. automodule:: evennia.comms
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.comms.comms
evennia.comms.managers
evennia.comms.models

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.awsstorage.aws\_s3\_cdn module
============================================================
.. automodule:: evennia.contrib.base_systems.awsstorage.aws_s3_cdn
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,15 +0,0 @@
evennia.contrib.base\_systems.awsstorage package
================================================
.. automodule:: evennia.contrib.base_systems.awsstorage
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.contrib.base_systems.awsstorage.aws_s3_cdn
evennia.contrib.base_systems.awsstorage.tests

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.awsstorage.tests module
=====================================================
.. automodule:: evennia.contrib.base_systems.awsstorage.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.building\_menu.building\_menu module
==================================================================
.. automodule:: evennia.contrib.base_systems.building_menu.building_menu
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,15 +0,0 @@
evennia.contrib.base\_systems.building\_menu package
====================================================
.. automodule:: evennia.contrib.base_systems.building_menu
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.contrib.base_systems.building_menu.building_menu
evennia.contrib.base_systems.building_menu.tests

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.building\_menu.tests module
=========================================================
.. automodule:: evennia.contrib.base_systems.building_menu.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.color\_markups.color\_markups module
==================================================================
.. automodule:: evennia.contrib.base_systems.color_markups.color_markups
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,15 +0,0 @@
evennia.contrib.base\_systems.color\_markups package
====================================================
.. automodule:: evennia.contrib.base_systems.color_markups
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.contrib.base_systems.color_markups.color_markups
evennia.contrib.base_systems.color_markups.tests

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.color\_markups.tests module
=========================================================
.. automodule:: evennia.contrib.base_systems.color_markups.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.components.component module
=========================================================
.. automodule:: evennia.contrib.base_systems.components.component
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.components.dbfield module
=======================================================
.. automodule:: evennia.contrib.base_systems.components.dbfield
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.components.holder module
======================================================
.. automodule:: evennia.contrib.base_systems.components.holder
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,18 +0,0 @@
evennia.contrib.base\_systems.components package
================================================
.. automodule:: evennia.contrib.base_systems.components
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.contrib.base_systems.components.component
evennia.contrib.base_systems.components.dbfield
evennia.contrib.base_systems.components.holder
evennia.contrib.base_systems.components.signals
evennia.contrib.base_systems.components.tests

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.components.signals module
=======================================================
.. automodule:: evennia.contrib.base_systems.components.signals
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.components.tests module
=====================================================
.. automodule:: evennia.contrib.base_systems.components.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.custom\_gametime.custom\_gametime module
======================================================================
.. automodule:: evennia.contrib.base_systems.custom_gametime.custom_gametime
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,15 +0,0 @@
evennia.contrib.base\_systems.custom\_gametime package
======================================================
.. automodule:: evennia.contrib.base_systems.custom_gametime
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.contrib.base_systems.custom_gametime.custom_gametime
evennia.contrib.base_systems.custom_gametime.tests

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.custom\_gametime.tests module
===========================================================
.. automodule:: evennia.contrib.base_systems.custom_gametime.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.email\_login.connection\_screens module
=====================================================================
.. automodule:: evennia.contrib.base_systems.email_login.connection_screens
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.email\_login.email\_login module
==============================================================
.. automodule:: evennia.contrib.base_systems.email_login.email_login
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,16 +0,0 @@
evennia.contrib.base\_systems.email\_login package
==================================================
.. automodule:: evennia.contrib.base_systems.email_login
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.contrib.base_systems.email_login.connection_screens
evennia.contrib.base_systems.email_login.email_login
evennia.contrib.base_systems.email_login.tests

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.email\_login.tests module
=======================================================
.. automodule:: evennia.contrib.base_systems.email_login.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.ingame\_python.callbackhandler module
===================================================================
.. automodule:: evennia.contrib.base_systems.ingame_python.callbackhandler
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.ingame\_python.commands module
============================================================
.. automodule:: evennia.contrib.base_systems.ingame_python.commands
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.ingame\_python.eventfuncs module
==============================================================
.. automodule:: evennia.contrib.base_systems.ingame_python.eventfuncs
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,20 +0,0 @@
evennia.contrib.base\_systems.ingame\_python package
====================================================
.. automodule:: evennia.contrib.base_systems.ingame_python
:members:
:undoc-members:
:show-inheritance:
.. toctree::
:maxdepth: 6
evennia.contrib.base_systems.ingame_python.callbackhandler
evennia.contrib.base_systems.ingame_python.commands
evennia.contrib.base_systems.ingame_python.eventfuncs
evennia.contrib.base_systems.ingame_python.scripts
evennia.contrib.base_systems.ingame_python.tests
evennia.contrib.base_systems.ingame_python.typeclasses
evennia.contrib.base_systems.ingame_python.utils

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.ingame\_python.scripts module
===========================================================
.. automodule:: evennia.contrib.base_systems.ingame_python.scripts
:members:
:undoc-members:
:show-inheritance:

View file

@ -1,7 +0,0 @@
evennia.contrib.base\_systems.ingame\_python.tests module
=========================================================
.. automodule:: evennia.contrib.base_systems.ingame_python.tests
:members:
:undoc-members:
:show-inheritance:

Some files were not shown because too many files have changed in this diff Show more