Some docstring cleanup
This commit is contained in:
parent
170db66d2c
commit
8ab169f70b
4 changed files with 118 additions and 82 deletions
|
|
@ -120,6 +120,14 @@ local:
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Documentation built (single version)."
|
@echo "Documentation built (single version)."
|
||||||
@echo "To see result, open evennia/docs/build/html/index.html in a browser."
|
@echo "To see result, open evennia/docs/build/html/index.html in a browser."
|
||||||
|
|
||||||
|
# build only that which updated since last run (no clean or index-creation)
|
||||||
|
localupdate:
|
||||||
|
make _check-env
|
||||||
|
make _html-build
|
||||||
|
@echo ""
|
||||||
|
@echo "Documentation built (single version, only updates, no auto-index)."
|
||||||
|
@echo "To see result, open evennia/docs/build/html/index.html in a browser."
|
||||||
|
|
||||||
# note that this should be done for each relevant multiversion branch.
|
# note that this should be done for each relevant multiversion branch.
|
||||||
mv-index:
|
mv-index:
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ than, the doc-strings of each component in the [API](../Evennia-API).
|
||||||
- [MonitorHandler](./MonitorHandler)
|
- [MonitorHandler](./MonitorHandler)
|
||||||
- [TickerHandler](./TickerHandler)
|
- [TickerHandler](./TickerHandler)
|
||||||
- [Lock system](./Locks)
|
- [Lock system](./Locks)
|
||||||
- [FuncParser](FuncParser)
|
- [FuncParser](./FuncParser)
|
||||||
|
|
||||||
## Server and network
|
## Server and network
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,31 +14,31 @@ a server reload/reboot).
|
||||||
|
|
||||||
## Adding Traits to a typeclass
|
## Adding Traits to a typeclass
|
||||||
|
|
||||||
To access and manipulate traits on an object, its Typeclass needs to have a
|
To access and manipulate traits on an entity, its Typeclass needs to have a
|
||||||
`TraitHandler` assigned it. Usually, the handler is made available as `.traits`
|
`TraitHandler` assigned it. Usually, the handler is made available as `.traits`
|
||||||
(in the same way as `.tags` or `.attributes`).
|
(in the same way as `.tags` or `.attributes`). It's recommended to do this
|
||||||
|
using Evennia's `lazy_property` (which basically just means it's not
|
||||||
|
initialized until it's actually accessed).
|
||||||
|
|
||||||
Here's an example for adding the TraitHandler to the base Object class:
|
Here's an example for adding the TraitHandler to the base Object class:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# mygame/typeclasses/objects.py
|
# mygame/typeclasses/objects.py
|
||||||
|
|
||||||
from evennia import DefaultObject
|
from evennia import DefaultObject
|
||||||
from evennia.utils import lazy_property
|
from evennia.utils import lazy_property
|
||||||
from evennia.contrib.traits import TraitHandler
|
from evennia.contrib.traits import TraitHandler
|
||||||
|
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
class Object(DefaultObject):
|
class Object(DefaultObject):
|
||||||
...
|
...
|
||||||
@lazy_property
|
@lazy_property
|
||||||
def traits(self):
|
def traits(self):
|
||||||
# this adds the handler as .traits
|
# this adds the handler as .traits
|
||||||
return TraitHandler(self)
|
return TraitHandler(self)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
After a reload you can now try adding some example traits:
|
|
||||||
|
|
||||||
## Using traits
|
## Using traits
|
||||||
|
|
||||||
|
|
@ -48,6 +48,7 @@ in Evennia).
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# this is an example using the "static" trait, described below
|
# this is an example using the "static" trait, described below
|
||||||
|
|
||||||
>>> obj.traits.add("hunting", "Hunting Skill", trait_type="static", base=4)
|
>>> obj.traits.add("hunting", "Hunting Skill", trait_type="static", base=4)
|
||||||
>>> obj.traits.hunting.value
|
>>> obj.traits.hunting.value
|
||||||
4
|
4
|
||||||
|
|
@ -130,17 +131,19 @@ that varies slowly or not at all, and which may be modified in-place.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Counter
|
### Counter
|
||||||
|
::
|
||||||
|
|
||||||
min/unset base base+mod max/unset
|
min/unset base base+mod max/unset
|
||||||
|--------------|--------|---------X--------X------------|
|
|--------------|--------|---------X--------X------------|
|
||||||
current value
|
current value
|
||||||
= current
|
= current
|
||||||
+ mod
|
+ mod
|
||||||
|
|
||||||
A counter describes a value that can move from a base. The `current` property
|
A counter describes a value that can move from a base. The `.current` property
|
||||||
is the thing usually modified. It starts at the `base`. One can also add a modifier,
|
is the thing usually modified. It starts at the `.base`. One can also add a
|
||||||
which will both be added to the base and to current (forming .value).
|
modifier, which will both be added to the base and to current (forming
|
||||||
The min/max of the range are optional, a boundary set to None will remove it.
|
`.value`). The min/max of the range are optional, a boundary set to None will
|
||||||
|
remove it. A suggested use for a Counter Trait would be to track skill values.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
>>> obj.traits.add("hunting", "Hunting Skill", trait_type="counter",
|
>>> obj.traits.add("hunting", "Hunting Skill", trait_type="counter",
|
||||||
|
|
@ -160,10 +163,15 @@ The min/max of the range are optional, a boundary set to None will remove it.
|
||||||
|
|
||||||
Counters have some extra properties:
|
Counters have some extra properties:
|
||||||
|
|
||||||
`descs` is a dict {upper_bound:text_description}. This allows for easily
|
#### .descs
|
||||||
|
|
||||||
|
The `descs` property is a dict {upper_bound:text_description}. This allows for easily
|
||||||
storing a more human-friendly description of the current value in the
|
storing a more human-friendly description of the current value in the
|
||||||
interval. Here is an example for skill values between 0 and 10:
|
interval. Here is an example for skill values between 0 and 10:
|
||||||
|
::
|
||||||
|
|
||||||
{0: "unskilled", 1: "neophyte", 5: "trained", 7: "expert", 9: "master"}
|
{0: "unskilled", 1: "neophyte", 5: "trained", 7: "expert", 9: "master"}
|
||||||
|
|
||||||
The keys must be supplied from smallest to largest. Any values below the lowest and above the
|
The keys must be supplied from smallest to largest. Any values below the lowest and above the
|
||||||
highest description will be considered to be included in the closest description slot.
|
highest description will be considered to be included in the closest description slot.
|
||||||
By calling `.desc()` on the Counter, will you get the text matching the current `value`
|
By calling `.desc()` on the Counter, will you get the text matching the current `value`
|
||||||
|
|
@ -190,11 +198,11 @@ value.
|
||||||
The `rate` property defaults to 0. If set to a value different from 0, it
|
The `rate` property defaults to 0. If set to a value different from 0, it
|
||||||
allows the trait to change value dynamically. This could be used for example
|
allows the trait to change value dynamically. This could be used for example
|
||||||
for an attribute that was temporarily lowered but will gradually (or abruptly)
|
for an attribute that was temporarily lowered but will gradually (or abruptly)
|
||||||
recover after a certain time. The rate is given as change of the `current`
|
recover after a certain time. The rate is given as change of the current
|
||||||
per-second, and the .value will still be restrained by min/max boundaries, if
|
`.value` per-second, and this will still be restrained by min/max boundaries,
|
||||||
those are set.
|
if those are set.
|
||||||
|
|
||||||
It is also possible to set a ".ratetarget", for the auto-change to stop at
|
It is also possible to set a `.ratetarget`, for the auto-change to stop at
|
||||||
(rather than at the min/max boundaries). This allows the value to return to
|
(rather than at the min/max boundaries). This allows the value to return to
|
||||||
a previous value.
|
a previous value.
|
||||||
|
|
||||||
|
|
@ -220,35 +228,41 @@ a previous value.
|
||||||
>>> obj.traits.hunting.rate = 0 # disable auto-change
|
>>> obj.traits.hunting.rate = 0 # disable auto-change
|
||||||
|
|
||||||
```
|
```
|
||||||
Note that if rate is a non-integer, the resulting .value (at least until it
|
Note that if `.rate` is a non-integer, the resulting `.value` (at least until it
|
||||||
reaches the boundary) will likely also come out a float. If you expect an
|
reaches a boundary or rate-target) will also come out a float (so you can get a
|
||||||
integer, you must run run int() on the result yourself.
|
very exact value at the current time). If you expect an integer, you must run
|
||||||
|
`int()` (or something like `round()`) on the result yourself.
|
||||||
|
|
||||||
#### .percentage()
|
#### .percent()
|
||||||
|
|
||||||
If both min and max are defined, the `.percentage()` method of the trait will
|
If both min and max are defined, the `.percent()` method of the trait will
|
||||||
return the value as a percentage.
|
return the value as a percentage.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
>>> obj.traits.hunting.percentage()
|
>>> obj.traits.hunting.percent()
|
||||||
"71.0%"
|
"71.0%"
|
||||||
|
>>> obj.traits.hunting.percent(formatting=None)
|
||||||
|
71.0
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Gauge
|
### Gauge
|
||||||
|
|
||||||
This emulates a [fuel-] gauge that empties from a base+mod value.
|
This emulates a [fuel-] gauge that empties from a base+mod value.
|
||||||
|
::
|
||||||
|
|
||||||
min/0 max=base+mod
|
min/0 max=base+mod
|
||||||
|-----------------------X---------------------------|
|
|-----------------------X---------------------------|
|
||||||
value
|
value
|
||||||
= current
|
= current
|
||||||
|
|
||||||
The 'current' value will start from a full gauge. The .max property is
|
The `.current` value will start from a full gauge. The .max property is
|
||||||
read-only and is set by .base + .mod. So contrary to a Counter, the modifier
|
read-only and is set by `.base` + `.mod`. So contrary to a `Counter`, the
|
||||||
only applies to the max value of the gauge and not the current value. The
|
`.mod` modifier only applies to the max value of the gauge and not the current
|
||||||
minimum bound defaults to 0. This trait is useful for showing resources that
|
value. The minimum bound defaults to 0 if not set explicitly.
|
||||||
can deplete, like health, stamina and the like.
|
|
||||||
|
This trait is useful for showing commonly depletable resources like health,
|
||||||
|
stamina and the like.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
>>> obj.traits.add("hp", "Health", trait_type="gauge", base=100)
|
>>> obj.traits.add("hp", "Health", trait_type="gauge", base=100)
|
||||||
|
|
@ -263,20 +277,24 @@ can deplete, like health, stamina and the like.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Same as Counters, Gauges can also have `descs` to describe the interval and can also
|
The Gauge trait is subclass of the Counter, so you have access to the same
|
||||||
have `rate` and `ratetarget` to auto-update the value. The rate is particularly useful
|
methods and properties where they make sense. So gauges can also have a
|
||||||
for gauges, for everything from poison slowly draining your health, to resting gradually
|
`.descs` dict to describe the intervals in text, and can use `.percent()` to
|
||||||
increasing it. You can also use the `.percentage()` function to show the current value
|
get how filled it is as a percentage etc.
|
||||||
as a percentage.
|
|
||||||
|
The `.rate` is particularly relevant for gauges - useful for everything
|
||||||
|
from poison slowly draining your health, to resting gradually increasing it.
|
||||||
|
|
||||||
### Trait
|
### Trait
|
||||||
|
|
||||||
A single value of any type.
|
A single value of any type.
|
||||||
|
|
||||||
This is the 'base' Trait, meant to inherit from if you want to make your own
|
This is the 'base' Trait, meant to inherit from if you want to invent
|
||||||
trait-types (see below). Its .value can be anything (that can be stored in an Attribute)
|
trait-types from scratch (most of the time you'll probably inherit from some of
|
||||||
and if it's a integer/float you can do arithmetic with it, but otherwise it
|
the more advanced trait-type classes though). A `Trait`s `.value` can be
|
||||||
acts just like a glorified Attribute.
|
anything (that can be stored in an Attribute) and if it's a integer/float you
|
||||||
|
can do arithmetic with it, but otherwise it acts just like a glorified
|
||||||
|
Attribute.
|
||||||
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
@ -291,38 +309,45 @@ acts just like a glorified Attribute.
|
||||||
|
|
||||||
## Expanding with your own Traits
|
## Expanding with your own Traits
|
||||||
|
|
||||||
A Trait is a class inhering from `evennia.contrib.traits.Trait` (or
|
A Trait is a class inhering from `evennia.contrib.traits.Trait` (or from one of
|
||||||
from one of the existing Trait classes).
|
the existing Trait classes).
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# in a file, say, 'mygame/world/traits.py'
|
# in a file, say, 'mygame/world/traits.py'
|
||||||
|
|
||||||
from evennia.contrib.traits import Trait
|
from evennia.contrib.traits import StaticTrait
|
||||||
|
|
||||||
class RageTrait(Trait):
|
class RageTrait(StaticTrait):
|
||||||
|
|
||||||
trait_type = "rage"
|
trait_type = "rage"
|
||||||
default_keys = {
|
default_keys = {
|
||||||
"rage": 0
|
"rage": 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def berserk(self):
|
||||||
|
self.mod = 100
|
||||||
|
|
||||||
|
def sedate(self):
|
||||||
|
self.mod = 0
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Above is an example custom-trait-class "rage" that stores a property "rage" on
|
Above is an example custom-trait-class "rage" that stores a property "rage" on
|
||||||
itself, with a default value of 0. This has all the
|
itself, with a default value of 0. This has all the functionality of a Trait -
|
||||||
functionality of a Trait - for example, if you do del on the `rage` property, it will be
|
for example, if you do del on the `rage` property, it will be set back to its
|
||||||
set back to its default (0). If you wanted to customize what it does, you
|
default (0). Above we also added some helper methods.
|
||||||
just add `rage` property get/setters/deleters on the class.
|
|
||||||
|
|
||||||
To add your custom RageTrait to Evennia, add the following to your settings file
|
To add your custom RageTrait to Evennia, add the following to your settings file
|
||||||
(assuming your class is in mygame/world/traits.py):
|
(assuming your class is in mygame/world/traits.py):
|
||||||
|
::
|
||||||
|
|
||||||
TRAIT_CLASS_PATHS = ["world.traits.RageTrait"]
|
TRAIT_CLASS_PATHS = ["world.traits.RageTrait"]
|
||||||
|
|
||||||
Reload the server and you should now be able to use your trait:
|
Reload the server and you should now be able to use your trait:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
>>> obj.traits.add("mood", "A dark mood", rage=30)
|
>>> obj.traits.add("mood", "A dark mood", rage=30, trait_type='rage')
|
||||||
>>> obj.traits.mood.rage
|
>>> obj.traits.mood.rage
|
||||||
30
|
30
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1710,36 +1710,39 @@ def ask_yes_no(caller, prompt, yes_action, no_action, default=None,
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
prompt (str): The yes/no question to ask. This takes an optional formatting
|
prompt (str): The yes/no question to ask. This takes an optional formatting
|
||||||
marker `{suffix}` which will be filled with 'Y/N', [Y]/N or Y/[N]
|
marker `{options}` which will be filled with 'Y/N', '[Y]/N' or
|
||||||
depending on the setting of `default`. If `allow_abort`, then the
|
'Y/[N]' depending on the setting of `default`. If `allow_abort` is set,
|
||||||
`A(bort)` will also be available.
|
then the 'A(bort)' option will also be available.
|
||||||
yes_action (callable or str): If a callable, this will be called
|
yes_action (callable or str): If a callable, this will be called
|
||||||
with `(caller, *args, **kwargs) when the yes-choice is made.
|
with `(caller, *args, **kwargs)` when the Yes-choice is made.
|
||||||
If a string, this string will be echoed back to the caller.
|
If a string, this string will be echoed back to the caller.
|
||||||
no_action (callable or str): If a callable, this will be called
|
no_action (callable or str): If a callable, this will be called
|
||||||
with `(caller, *args, **kwargs)` when the no-choice is made.
|
with `(caller, *args, **kwargs)` when the No-choice is made.
|
||||||
If a string, this string will be echoed back to the caller.
|
If a string, this string will be echoed back to the caller.
|
||||||
default (str optional): One of "N", "Y", "A" or None for no default.
|
default (str optional): This is what the user will get if they just press the
|
||||||
If "A" is given, `allow_abort` is assumed set. The user can choose
|
return key without giving any input. One of 'N', 'Y', 'A' or 'None'
|
||||||
the default option just by pressing return.
|
for no default. If 'A' is given, `allow_abort` is auto-set.
|
||||||
allow_abort (bool, optional): If set, the Q(uit) option is available,
|
allow_abort (bool, optional): If set, the 'A(bort)' option is available
|
||||||
which is neither yes or no.
|
(a third option meaning neither yes or no but just exits the prompt).
|
||||||
session (Session, optional): This allows to specify the
|
session (Session, optional): This allows to specify the
|
||||||
session to send the prompt to. It's usually only needed if `caller`
|
session to send the prompt to. It's usually only needed if `caller`
|
||||||
is an Account in multisession modes greater than 2. The session is
|
is an Account in multisession modes greater than 2. The session is
|
||||||
then updated by the command and is available (for example in
|
then updated by the command and is available (for example in
|
||||||
callbacks) through `caller.ndb._yes_no_question.session`.
|
callbacks) through `caller.ndb._yes_no_question.session`.
|
||||||
*args, **kwargs: These are passed into the callables, if any.
|
*args, **kwargs: These are passed into the callables.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
RuntimeError: If default and allow_abort clashes.
|
RuntimeError, FooError: If default and allow_abort clashes.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
::
|
||||||
|
|
||||||
ask_yes_no(caller, "Are you happy {suffix}?",
|
# just returning strings
|
||||||
"you answered yes", "you answered no")
|
ask_yes_no(caller, "Are you happy {options}?",
|
||||||
ask_yes_no(caller, "Are you sad {suffix}?",
|
"you answered yes", "you answered no")
|
||||||
_callable_yes, _callable_no, allow_abort=True)
|
# trigger callables
|
||||||
|
ask_yes_no(caller, "Are you sad {options}?",
|
||||||
|
_callable_yes, _callable_no, allow_abort=True)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def _callable_yes_txt(caller, *args, **kwargs):
|
def _callable_yes_txt(caller, *args, **kwargs):
|
||||||
|
|
@ -1760,20 +1763,20 @@ def ask_yes_no(caller, prompt, yes_action, no_action, default=None,
|
||||||
kwargs['no_txt'] = str(no_action)
|
kwargs['no_txt'] = str(no_action)
|
||||||
no_action = _callable_no_txt
|
no_action = _callable_no_txt
|
||||||
|
|
||||||
# prepare the prompt with suffix
|
# prepare the prompt with options
|
||||||
suffix = "Y/N"
|
options = "Y/N"
|
||||||
abort_txt = "/Abort" if allow_abort else ""
|
abort_txt = "/Abort" if allow_abort else ""
|
||||||
if default:
|
if default:
|
||||||
default = default.lower()
|
default = default.lower()
|
||||||
if default == "y":
|
if default == "y":
|
||||||
suffix = "[Y]/N"
|
options = "[Y]/N"
|
||||||
elif default == "n":
|
elif default == "n":
|
||||||
suffix = "Y/[N]"
|
options = "Y/[N]"
|
||||||
elif default == "a":
|
elif default == "a":
|
||||||
allow_abort = True
|
allow_abort = True
|
||||||
abort_txt = "/[A]bort"
|
abort_txt = "/[A]bort"
|
||||||
suffix += abort_txt
|
options += abort_txt
|
||||||
prompt = prompt.format(suffix=suffix)
|
prompt = prompt.format(options=options)
|
||||||
|
|
||||||
caller.ndb._yes_no_question = _Prompt()
|
caller.ndb._yes_no_question = _Prompt()
|
||||||
caller.ndb._yes_no_question.session = session
|
caller.ndb._yes_no_question.session = session
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue