mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
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 "Documentation built (single version)."
|
||||
@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.
|
||||
mv-index:
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ than, the doc-strings of each component in the [API](../Evennia-API).
|
|||
- [MonitorHandler](./MonitorHandler)
|
||||
- [TickerHandler](./TickerHandler)
|
||||
- [Lock system](./Locks)
|
||||
- [FuncParser](FuncParser)
|
||||
- [FuncParser](./FuncParser)
|
||||
|
||||
## Server and network
|
||||
|
||||
|
|
|
|||
|
|
@ -14,31 +14,31 @@ a server reload/reboot).
|
|||
|
||||
## 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`
|
||||
(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:
|
||||
|
||||
```python
|
||||
# mygame/typeclasses/objects.py
|
||||
```python
|
||||
# mygame/typeclasses/objects.py
|
||||
|
||||
from evennia import DefaultObject
|
||||
from evennia.utils import lazy_property
|
||||
from evennia.contrib.traits import TraitHandler
|
||||
from evennia import DefaultObject
|
||||
from evennia.utils import lazy_property
|
||||
from evennia.contrib.traits import TraitHandler
|
||||
|
||||
# ...
|
||||
# ...
|
||||
|
||||
class Object(DefaultObject):
|
||||
...
|
||||
@lazy_property
|
||||
def traits(self):
|
||||
# this adds the handler as .traits
|
||||
return TraitHandler(self)
|
||||
class Object(DefaultObject):
|
||||
...
|
||||
@lazy_property
|
||||
def traits(self):
|
||||
# this adds the handler as .traits
|
||||
return TraitHandler(self)
|
||||
|
||||
```
|
||||
|
||||
After a reload you can now try adding some example traits:
|
||||
```
|
||||
|
||||
## Using traits
|
||||
|
||||
|
|
@ -48,6 +48,7 @@ in Evennia).
|
|||
|
||||
```python
|
||||
# this is an example using the "static" trait, described below
|
||||
|
||||
>>> obj.traits.add("hunting", "Hunting Skill", trait_type="static", base=4)
|
||||
>>> obj.traits.hunting.value
|
||||
4
|
||||
|
|
@ -130,17 +131,19 @@ that varies slowly or not at all, and which may be modified in-place.
|
|||
```
|
||||
|
||||
### Counter
|
||||
::
|
||||
|
||||
min/unset base base+mod max/unset
|
||||
|--------------|--------|---------X--------X------------|
|
||||
current value
|
||||
= current
|
||||
+ mod
|
||||
|--------------|--------|---------X--------X------------|
|
||||
current value
|
||||
= current
|
||||
+ mod
|
||||
|
||||
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,
|
||||
which will both be added to the base and to current (forming .value).
|
||||
The min/max of the range are optional, a boundary set to None will remove it.
|
||||
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, which will both be added to the base and to current (forming
|
||||
`.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
|
||||
>>> 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:
|
||||
|
||||
`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
|
||||
interval. Here is an example for skill values between 0 and 10:
|
||||
::
|
||||
|
||||
{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
|
||||
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`
|
||||
|
|
@ -190,11 +198,11 @@ value.
|
|||
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
|
||||
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`
|
||||
per-second, and the .value will still be restrained by min/max boundaries, if
|
||||
those are set.
|
||||
recover after a certain time. The rate is given as change of the current
|
||||
`.value` per-second, and this will still be restrained by min/max boundaries,
|
||||
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
|
||||
a previous value.
|
||||
|
||||
|
|
@ -220,35 +228,41 @@ a previous value.
|
|||
>>> obj.traits.hunting.rate = 0 # disable auto-change
|
||||
|
||||
```
|
||||
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
|
||||
integer, you must run run int() on the result yourself.
|
||||
Note that if `.rate` is a non-integer, the resulting `.value` (at least until it
|
||||
reaches a boundary or rate-target) will also come out a float (so you can get a
|
||||
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.
|
||||
|
||||
```python
|
||||
>>> obj.traits.hunting.percentage()
|
||||
>>> obj.traits.hunting.percent()
|
||||
"71.0%"
|
||||
>>> obj.traits.hunting.percent(formatting=None)
|
||||
71.0
|
||||
|
||||
```
|
||||
|
||||
### Gauge
|
||||
|
||||
This emulates a [fuel-] gauge that empties from a base+mod value.
|
||||
::
|
||||
|
||||
min/0 max=base+mod
|
||||
|-----------------------X---------------------------|
|
||||
value
|
||||
= current
|
||||
|
||||
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
|
||||
only applies to the max value of the gauge and not the current value. The
|
||||
minimum bound defaults to 0. This trait is useful for showing resources that
|
||||
can deplete, like health, stamina and the like.
|
||||
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
|
||||
`.mod` modifier only applies to the max value of the gauge and not the current
|
||||
value. The minimum bound defaults to 0 if not set explicitly.
|
||||
|
||||
This trait is useful for showing commonly depletable resources like health,
|
||||
stamina and the like.
|
||||
|
||||
```python
|
||||
>>> 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
|
||||
have `rate` and `ratetarget` to auto-update the value. The rate is particularly useful
|
||||
for gauges, for everything from poison slowly draining your health, to resting gradually
|
||||
increasing it. You can also use the `.percentage()` function to show the current value
|
||||
as a percentage.
|
||||
The Gauge trait is subclass of the Counter, so you have access to the same
|
||||
methods and properties where they make sense. So gauges can also have a
|
||||
`.descs` dict to describe the intervals in text, and can use `.percent()` to
|
||||
get how filled it is as a percentage etc.
|
||||
|
||||
The `.rate` is particularly relevant for gauges - useful for everything
|
||||
from poison slowly draining your health, to resting gradually increasing it.
|
||||
|
||||
### Trait
|
||||
|
||||
A single value of any type.
|
||||
|
||||
This is the 'base' Trait, meant to inherit from if you want to make your own
|
||||
trait-types (see below). Its .value can be 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.
|
||||
This is the 'base' Trait, meant to inherit from if you want to invent
|
||||
trait-types from scratch (most of the time you'll probably inherit from some of
|
||||
the more advanced trait-type classes though). A `Trait`s `.value` can be
|
||||
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
|
||||
|
|
@ -291,38 +309,45 @@ acts just like a glorified Attribute.
|
|||
|
||||
## Expanding with your own Traits
|
||||
|
||||
A Trait is a class inhering from `evennia.contrib.traits.Trait` (or
|
||||
from one of the existing Trait classes).
|
||||
A Trait is a class inhering from `evennia.contrib.traits.Trait` (or from one of
|
||||
the existing Trait classes).
|
||||
|
||||
```python
|
||||
# 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"
|
||||
default_keys = {
|
||||
"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
|
||||
itself, with a default value of 0. This has all the
|
||||
functionality of a Trait - for example, if you do del on the `rage` property, it will be
|
||||
set back to its default (0). If you wanted to customize what it does, you
|
||||
just add `rage` property get/setters/deleters on the class.
|
||||
itself, with a default value of 0. This has all the functionality of a Trait -
|
||||
for example, if you do del on the `rage` property, it will be set back to its
|
||||
default (0). Above we also added some helper methods.
|
||||
|
||||
To add your custom RageTrait to Evennia, add the following to your settings file
|
||||
(assuming your class is in mygame/world/traits.py):
|
||||
::
|
||||
|
||||
TRAIT_CLASS_PATHS = ["world.traits.RageTrait"]
|
||||
|
||||
Reload the server and you should now be able to use your trait:
|
||||
|
||||
```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
|
||||
30
|
||||
|
||||
|
|
|
|||
|
|
@ -1710,36 +1710,39 @@ def ask_yes_no(caller, prompt, yes_action, no_action, default=None,
|
|||
|
||||
Args:
|
||||
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]
|
||||
depending on the setting of `default`. If `allow_abort`, then the
|
||||
`A(bort)` will also be available.
|
||||
marker `{options}` which will be filled with 'Y/N', '[Y]/N' or
|
||||
'Y/[N]' depending on the setting of `default`. If `allow_abort` is set,
|
||||
then the 'A(bort)' option will also be available.
|
||||
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.
|
||||
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.
|
||||
default (str optional): One of "N", "Y", "A" or None for no default.
|
||||
If "A" is given, `allow_abort` is assumed set. The user can choose
|
||||
the default option just by pressing return.
|
||||
allow_abort (bool, optional): If set, the Q(uit) option is available,
|
||||
which is neither yes or no.
|
||||
default (str optional): This is what the user will get if they just press the
|
||||
return key without giving any input. One of 'N', 'Y', 'A' or 'None'
|
||||
for no default. If 'A' is given, `allow_abort` is auto-set.
|
||||
allow_abort (bool, optional): If set, the 'A(bort)' option is available
|
||||
(a third option meaning neither yes or no but just exits the prompt).
|
||||
session (Session, optional): This allows to specify the
|
||||
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
|
||||
then updated by the command and is available (for example in
|
||||
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:
|
||||
RuntimeError: If default and allow_abort clashes.
|
||||
RuntimeError, FooError: If default and allow_abort clashes.
|
||||
|
||||
Example:
|
||||
::
|
||||
|
||||
ask_yes_no(caller, "Are you happy {suffix}?",
|
||||
"you answered yes", "you answered no")
|
||||
ask_yes_no(caller, "Are you sad {suffix}?",
|
||||
_callable_yes, _callable_no, allow_abort=True)
|
||||
# just returning strings
|
||||
ask_yes_no(caller, "Are you happy {options}?",
|
||||
"you answered yes", "you answered no")
|
||||
# trigger callables
|
||||
ask_yes_no(caller, "Are you sad {options}?",
|
||||
_callable_yes, _callable_no, allow_abort=True)
|
||||
|
||||
"""
|
||||
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)
|
||||
no_action = _callable_no_txt
|
||||
|
||||
# prepare the prompt with suffix
|
||||
suffix = "Y/N"
|
||||
# prepare the prompt with options
|
||||
options = "Y/N"
|
||||
abort_txt = "/Abort" if allow_abort else ""
|
||||
if default:
|
||||
default = default.lower()
|
||||
if default == "y":
|
||||
suffix = "[Y]/N"
|
||||
options = "[Y]/N"
|
||||
elif default == "n":
|
||||
suffix = "Y/[N]"
|
||||
options = "Y/[N]"
|
||||
elif default == "a":
|
||||
allow_abort = True
|
||||
abort_txt = "/[A]bort"
|
||||
suffix += abort_txt
|
||||
prompt = prompt.format(suffix=suffix)
|
||||
options += abort_txt
|
||||
prompt = prompt.format(options=options)
|
||||
|
||||
caller.ndb._yes_no_question = _Prompt()
|
||||
caller.ndb._yes_no_question.session = session
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue