mirror of
https://github.com/evennia/evennia.git
synced 2026-03-28 02:36:32 +01:00
Complete reshuffling of contribs. Not moved tests
This commit is contained in:
parent
9efaea9e35
commit
9b92b595c4
27 changed files with 552 additions and 29 deletions
|
|
@ -7,7 +7,6 @@ Testing suite for contrib folder
|
|||
import time
|
||||
import datetime
|
||||
from anything import Anything
|
||||
from django.test import override_settings
|
||||
from evennia.commands.default.tests import CommandTest
|
||||
from evennia.utils.test_resources import EvenniaTest, mockdelay, mockdeferLater
|
||||
from mock import Mock, patch
|
||||
|
|
|
|||
35
evennia/contrib/tutorials/batchprocessor/README.md
Normal file
35
evennia/contrib/tutorials/batchprocessor/README.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# Batch processor examples
|
||||
|
||||
Contibution - Griatch 2012
|
||||
|
||||
The batch processor is used for generating in-game content from one or more
|
||||
static files. Files can be stored with version control and then 'applied'
|
||||
to the game to create content.
|
||||
|
||||
There are two batch processor types:
|
||||
|
||||
- Batch-cmd processor: A list of `#`-separated Evennia commands being executed
|
||||
in sequence, such as `create`, `dig`, `north` etc. When running a script
|
||||
of this type (filename ending with `.ev`), the caller of the script will be
|
||||
the one performing the script's actions.
|
||||
- Batch-code processor: A full Python script (filename ending with `.py` that
|
||||
executes Evennia api calls to build, such as `evennia.create_object` or
|
||||
`evennia.search_object` etc. It can be divided up into comment-separated
|
||||
chunks so one can execute only parts of the script at a time (in this way it's
|
||||
a little different than a normal Python file).
|
||||
|
||||
## Usage
|
||||
|
||||
To test the two example batch files, you need `Developer` or `superuser`
|
||||
permissions, be logged into the game and run of
|
||||
|
||||
> batchcommand/interactive tutorials.batchprocessor.example_batch_cmds
|
||||
> batchcode/interactive tutorials.batchprocessor.example_batch_code
|
||||
|
||||
The `/interactive` drops you in interactive mode so you can follow along what
|
||||
the scripts do. Skip it to build it all at once.
|
||||
|
||||
Both commands produce the same results - they create a red-button object,
|
||||
a table and a chair. If you run either with the `/debug` switch, the objects will
|
||||
be deleted afterwards (for quick tests of syntax that you don't want to spam new
|
||||
objects, for example).
|
||||
4
evennia/contrib/tutorials/batchprocessor/__init__.py
Normal file
4
evennia/contrib/tutorials/batchprocessor/__init__.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
"""
|
||||
Batch processing examples - Griatch 2012
|
||||
|
||||
"""
|
||||
16
evennia/contrib/tutorials/bodyfunctions/README.md
Normal file
16
evennia/contrib/tutorials/bodyfunctions/README.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Script example
|
||||
|
||||
Griatch - 2012
|
||||
|
||||
Example script for testing. This adds a simple timer that has your
|
||||
character make observations and notices at irregular intervals.
|
||||
|
||||
To test, use (in game)
|
||||
|
||||
> script me = contrib.tutorials.bodyfunctions.BodyFunctions
|
||||
|
||||
## Notes
|
||||
|
||||
Use `scripts me` to see the script running on you. Note that even though
|
||||
the timer ticks down to 0, you will _not_ see an echo every tick (it's
|
||||
random if an echo is given on a tick or not).
|
||||
6
evennia/contrib/tutorials/bodyfunctions/__init__.py
Normal file
6
evennia/contrib/tutorials/bodyfunctions/__init__.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"""
|
||||
Bodyfunctions example script - Griatch, 2012
|
||||
|
||||
"""
|
||||
|
||||
from .bodyfunctions import BodyFunctions # noqa
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
"""
|
||||
Script example
|
||||
|
||||
Griatch - 2012
|
||||
|
||||
Example script for testing. This adds a simple timer that has your
|
||||
character make observations and notices at irregular intervals.
|
||||
|
||||
To test, use
|
||||
@script me = tutorial_examples.bodyfunctions.BodyFunctions
|
||||
script me = tutorial_examples.bodyfunctions.BodyFunctions
|
||||
|
||||
The script will only send messages to the object it is stored on, so
|
||||
make sure to put it on yourself or you won't see any messages!
|
||||
|
|
@ -16,6 +20,7 @@ from evennia import DefaultScript
|
|||
class BodyFunctions(DefaultScript):
|
||||
"""
|
||||
This class defines the script itself
|
||||
|
||||
"""
|
||||
|
||||
def at_script_creation(self):
|
||||
34
evennia/contrib/tutorials/red_button/README.md
Normal file
34
evennia/contrib/tutorials/red_button/README.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Red Button example
|
||||
|
||||
Griatch - 2011
|
||||
|
||||
This is a more advanced example object with its own functionality (commands)
|
||||
on it.
|
||||
|
||||
Create the button with
|
||||
|
||||
create/drop button:tutorials.red_button.RedButton
|
||||
|
||||
Note that you must drop the button before you can see its messages! It's
|
||||
imperative that you press the red button. You know you want to.
|
||||
|
||||
Use `del button` to destroy/stop the button when you are done playing.
|
||||
|
||||
## Technical
|
||||
|
||||
The button's functionality is controlled by CmdSets that gets added and removed
|
||||
depending on the 'state' the button is in.
|
||||
|
||||
- Lid-closed state: In this state the button is covered by a glass cover and
|
||||
trying to 'push' it will fail. You can 'nudge', 'smash' or 'open' the lid.
|
||||
- Lid-open state: In this state the lid is open but will close again after a
|
||||
certain time. Using 'push' now will press the button and trigger the
|
||||
Blind-state.
|
||||
- Blind-state: In this mode you are blinded by a bright flash. This will affect
|
||||
your normal commands like 'look' and help until the blindness wears off after
|
||||
a certain time.
|
||||
|
||||
Timers are handled by persistent delays on the button. These are examples of
|
||||
`evennia.utils.utils.delay` calls that wait a certain time before calling a
|
||||
method - such as when closing the lid and un-blinding a character.
|
||||
|
||||
6
evennia/contrib/tutorials/red_button/__init__.py
Normal file
6
evennia/contrib/tutorials/red_button/__init__.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"""
|
||||
Tutorial Red Button Object - Griatch 2011
|
||||
|
||||
"""
|
||||
|
||||
from .red_button import RedButton # noqa
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
"""
|
||||
Red Button
|
||||
|
||||
Griatch - 2011
|
||||
|
||||
This is a more advanced example object. It combines functions from
|
||||
script.examples as well as commands.examples to make an interactive
|
||||
|
|
@ -6,14 +9,14 @@ button typeclass.
|
|||
|
||||
Create this button with
|
||||
|
||||
create/drop red_button.RedButton
|
||||
create/drop tutorials.red_button.RedButton
|
||||
|
||||
Note that you must drop the button before you can see its messages!
|
||||
|
||||
## Technical
|
||||
|
||||
The button's functionality is controlled by CmdSets that gets added and removed
|
||||
depending on the 'state' the button is in.
|
||||
depending on the 'state' the button is in.
|
||||
|
||||
- Lid-closed state: In this state the button is covered by a glass cover and trying
|
||||
to 'push' it will fail. You can 'nudge', 'smash' or 'open' the lid.
|
||||
21
evennia/contrib/tutorials/talking_npc/README.md
Normal file
21
evennia/contrib/tutorials/talking_npc/README.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Talkative NPC example
|
||||
|
||||
Contribution - Griatch 2011, grungies1138, 2016
|
||||
|
||||
This is a static NPC object capable of holding a simple menu-driven
|
||||
conversation. It's just meant as an example.
|
||||
|
||||
## Installation
|
||||
|
||||
Create the NPC by creating an object of typeclass `contrib.tutorials.talking_npc.TalkingNPC`,
|
||||
For example:
|
||||
|
||||
create/drop John : contrib.tutorials.talking_npc.TalkingNPC
|
||||
|
||||
Use `talk` in the same room as the NPC to start a conversation.
|
||||
|
||||
If there are many talkative npcs in the same room you will get to choose which
|
||||
one's talk command to call (Evennia handles this automatically).
|
||||
|
||||
This use of EvMenu is very simplistic; See EvMenu for a lot more complex
|
||||
possibilities.
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
# Evennia Tutorial World
|
||||
|
||||
Griatch 2011, 2015
|
||||
|
|
@ -10,30 +9,33 @@ herein are designed to show off features of the engine, not to be a
|
|||
very challenging (nor long) gaming experience. As such it's of course
|
||||
only skimming the surface of what is possible.
|
||||
|
||||
The tutorial world also includes a game tutor menu example, exemplifying
|
||||
Evmenu.
|
||||
|
||||
## Install
|
||||
## Installation
|
||||
|
||||
Log in as superuser (#1), then run
|
||||
|
||||
@batchcommand tutorial_world.build
|
||||
batchcommand tutorials.tutorial_world.build
|
||||
|
||||
Wait a little while for building to complete and don't run the command
|
||||
again. This should build the world and connect it to Limbo.
|
||||
again even if it's slow. This builds the world and connect it to Limbo
|
||||
and creates a new exit `tutorial`.
|
||||
|
||||
If you are a superuser (User `#1`), use the `@quell` command to play
|
||||
the tutorial as intended.
|
||||
If you are a superuser (User `#1`), use the `quell` command to play
|
||||
the tutorial as intended.
|
||||
|
||||
|
||||
## Comments
|
||||
|
||||
The tutorial world is intended for your playing around with the engine.
|
||||
It will help you learn how to accomplish some more advanced effects
|
||||
and might give some good ideas along the way.
|
||||
The tutorial world is intended to be explored and analyzed. It will help you
|
||||
learn how to accomplish some more advanced effects and might give some good
|
||||
ideas along the way.
|
||||
|
||||
It's suggested you play it through (as a normal user, NOT as
|
||||
Superuser!) and explore it a bit, then come back here and start
|
||||
looking into the (heavily documented) build/source code to find out
|
||||
how things tick - that's the "tutorial" in Tutorial world after all.
|
||||
It's suggested you play it through (as a normal user, NOT as Superuser!) and
|
||||
explore it a bit, then come back here and start looking into the (heavily
|
||||
documented) build/source code to find out how things tick - that's the
|
||||
"tutorial" in Tutorial world after all.
|
||||
|
||||
Please report bugs in the tutorial to the Evennia issue tracker.
|
||||
|
||||
|
|
@ -50,6 +52,7 @@ tutorial game**
|
|||
|
||||
|
||||
|
||||
|
||||
## Tutorial World Room map
|
||||
|
||||
?
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
This package holds the demo game of Evennia.
|
||||
Tutorial world - Griatch, 2011, 2015
|
||||
|
||||
"""
|
||||
|
||||
|
||||
from . import mob, objects, rooms
|
||||
from . import mob, objects, rooms # noqa
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
# To load this file, place yourself in Limbo (room #2) and load the
|
||||
# file as user #1 with
|
||||
#
|
||||
# @batchcommand contrib.tutorial_world.build
|
||||
# batchcommand contrib.tutorials.tutorial_world.build
|
||||
#
|
||||
# If you give the /interactive switch you can step through the
|
||||
# build process command for command.
|
||||
|
|
@ -285,7 +285,7 @@ start
|
|||
#
|
||||
@set sign/tutorial_info =
|
||||
This is a readable object, of the Typeclass
|
||||
evennia.contrib.tutorial_world.objects.TutorialReadable. The sign has a cmdset
|
||||
evennia.contrib.tutorials.tutorial_world.objects.TutorialReadable. The sign has a cmdset
|
||||
defined on itself, containing only one command, namely 'read'. This
|
||||
command is what allows you to 'read sign'. Doing so returns the
|
||||
contents of the Attribute 'readable_sign', containing the information
|
||||
|
|
@ -488,7 +488,7 @@ north
|
|||
#
|
||||
bridge
|
||||
#
|
||||
# Set up properties on bridge room (see contrib.tutorial_world.rooms.BridgeRoom)
|
||||
# Set up properties on bridge room (see contrib.tutorials.tutorial_world.rooms.BridgeRoom)
|
||||
#
|
||||
# connect west edge to cliff
|
||||
#
|
||||
|
|
@ -1363,7 +1363,7 @@ The prize you have been looking for!
|
|||
what can be done with Evennia. The tutorial focuses more on showing
|
||||
various techniques than to supply any sort of novel storytelling or
|
||||
gaming challenge. The full README and source code for the tutorial
|
||||
world can be found under |wcontrib/tutorial_world|g.
|
||||
world can be found under |wcontrib/tutorials/tutorial_world|g.
|
||||
|
||||
|
||||
If you went through the tutorial quest once, it can be interesting to
|
||||
|
|
|
|||
157
evennia/contrib/utils/fieldfill/README.md
Normal file
157
evennia/contrib/utils/fieldfill/README.md
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
# Easy fillable form
|
||||
|
||||
Contrib - Tim Ashley Jenkins 2018
|
||||
|
||||
This module contains a function that calls an easily customizable EvMenu - this
|
||||
menu presents the player with a fillable form, with fields that can be filled
|
||||
out in any order. Each field's value can be verified, with the function
|
||||
allowing easy checks for text and integer input, minimum and maximum values /
|
||||
character lengths, or can even be verified by a custom function. Once the form
|
||||
is submitted, the form's data is submitted as a dictionary to any callable of
|
||||
your choice.
|
||||
|
||||
The function that initializes the fillable form menu is fairly simple, and
|
||||
includes the caller, the template for the form, and the callback(caller, result)
|
||||
to which the form data will be sent to upon submission.
|
||||
|
||||
init_fill_field(formtemplate, caller, formcallback)
|
||||
|
||||
Form templates are defined as a list of dictionaries - each dictionary
|
||||
represents a field in the form, and contains the data for the field's name and
|
||||
behavior. For example, this basic form template will allow a player to fill out
|
||||
a brief character profile:
|
||||
|
||||
PROFILE_TEMPLATE = [
|
||||
{"fieldname":"Name", "fieldtype":"text"},
|
||||
{"fieldname":"Age", "fieldtype":"number"},
|
||||
{"fieldname":"History", "fieldtype":"text"},
|
||||
]
|
||||
|
||||
This will present the player with an EvMenu showing this basic form:
|
||||
|
||||
```
|
||||
Name:
|
||||
Age:
|
||||
History:
|
||||
```
|
||||
|
||||
While in this menu, the player can assign a new value to any field with the
|
||||
syntax <field> = <new value>, like so:
|
||||
|
||||
```
|
||||
> name = Ashley
|
||||
Field 'Name' set to: Ashley
|
||||
```
|
||||
|
||||
Typing 'look' by itself will show the form and its current values.
|
||||
|
||||
```
|
||||
> look
|
||||
|
||||
Name: Ashley
|
||||
Age:
|
||||
History:
|
||||
```
|
||||
|
||||
Number fields require an integer input, and will reject any text that can't
|
||||
be converted into an integer.
|
||||
|
||||
```
|
||||
> age = youthful
|
||||
Field 'Age' requires a number.
|
||||
> age = 31
|
||||
Field 'Age' set to: 31
|
||||
```
|
||||
|
||||
Form data is presented as an EvTable, so text of any length will wrap cleanly.
|
||||
|
||||
```
|
||||
> history = EVERY MORNING I WAKE UP AND OPEN PALM SLAM[...]
|
||||
Field 'History' set to: EVERY MORNING I WAKE UP AND[...]
|
||||
> look
|
||||
|
||||
Name: Ashley
|
||||
Age: 31
|
||||
History: EVERY MORNING I WAKE UP AND OPEN PALM SLAM A VHS INTO THE SLOT.
|
||||
IT'S CHRONICLES OF RIDDICK AND RIGHT THEN AND THERE I START DOING
|
||||
THE MOVES ALONGSIDE WITH THE MAIN CHARACTER, RIDDICK. I DO EVERY
|
||||
MOVE AND I DO EVERY MOVE HARD.
|
||||
```
|
||||
|
||||
When the player types 'submit' (or your specified submit command), the menu
|
||||
quits and the form's data is passed to your specified function as a dictionary,
|
||||
like so:
|
||||
|
||||
formdata = {"Name":"Ashley", "Age":31, "History":"EVERY MORNING I[...]"}
|
||||
|
||||
You can do whatever you like with this data in your function - forms can be used
|
||||
to set data on a character, to help builders create objects, or for players to
|
||||
craft items or perform other complicated actions with many variables involved.
|
||||
|
||||
The data that your form will accept can also be specified in your form template -
|
||||
let's say, for example, that you won't accept ages under 18 or over 100. You can
|
||||
do this by specifying "min" and "max" values in your field's dictionary:
|
||||
|
||||
```
|
||||
PROFILE_TEMPLATE = [
|
||||
{"fieldname":"Name", "fieldtype":"text"},
|
||||
{"fieldname":"Age", "fieldtype":"number", "min":18, "max":100},
|
||||
{"fieldname":"History", "fieldtype":"text"}
|
||||
]
|
||||
```
|
||||
|
||||
Now if the player tries to enter a value out of range, the form will not acept the
|
||||
given value.
|
||||
|
||||
```
|
||||
> age = 10
|
||||
Field 'Age' reqiures a minimum value of 18.
|
||||
> age = 900
|
||||
Field 'Age' has a maximum value of 100.
|
||||
```
|
||||
|
||||
Setting 'min' and 'max' for a text field will instead act as a minimum or
|
||||
maximum character length for the player's input.
|
||||
|
||||
There are lots of ways to present the form to the player - fields can have default
|
||||
values or show a custom message in place of a blank value, and player input can be
|
||||
verified by a custom function, allowing for a great deal of flexibility. There
|
||||
is also an option for 'bool' fields, which accept only a True / False input and
|
||||
can be customized to represent the choice to the player however you like (E.G.
|
||||
Yes/No, On/Off, Enabled/Disabled, etc.)
|
||||
|
||||
This module contains a simple example form that demonstrates all of the included
|
||||
functionality - a command that allows a player to compose a message to another
|
||||
online character and have it send after a custom delay. You can test it by
|
||||
importing this module in your game's `default_cmdsets.py` module and adding
|
||||
CmdTestMenu to your default character's command set.
|
||||
|
||||
## FIELD TEMPLATE KEYS:
|
||||
|
||||
### Required:
|
||||
|
||||
```
|
||||
fieldname (str): Name of the field, as presented to the player.
|
||||
fieldtype (str): Type of value required: 'text', 'number', or 'bool'.
|
||||
```
|
||||
|
||||
### Optional:
|
||||
|
||||
- max (int): Maximum character length (if text) or value (if number).
|
||||
- min (int): Minimum charater length (if text) or value (if number).
|
||||
- truestr (str): String for a 'True' value in a bool field.
|
||||
(E.G. 'On', 'Enabled', 'Yes')
|
||||
- falsestr (str): String for a 'False' value in a bool field.
|
||||
(E.G. 'Off', 'Disabled', 'No')
|
||||
- default (str): Initial value (blank if not given).
|
||||
- blankmsg (str): Message to show in place of value when field is blank.
|
||||
- cantclear (bool): Field can't be cleared if True.
|
||||
- required (bool): If True, form cannot be submitted while field is blank.
|
||||
- verifyfunc (callable): Name of a callable used to verify input - takes
|
||||
(caller, value) as arguments. If the function returns True,
|
||||
the player's input is considered valid - if it returns False,
|
||||
the input is rejected. Any other value returned will act as
|
||||
the field's new value, replacing the player's input. This
|
||||
allows for values that aren't strings or integers (such as
|
||||
object dbrefs). For boolean fields, return '0' or '1' to set
|
||||
the field to False or True.
|
||||
7
evennia/contrib/utils/fieldfill/__init__.py
Normal file
7
evennia/contrib/utils/fieldfill/__init__.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
"""
|
||||
FieldFill contrib - Tim Ashley Jenkins 2018
|
||||
|
||||
"""
|
||||
|
||||
from .fieldfill import FieldEvMenu # noqa
|
||||
from .fieldfill import CmdTestMenu # noqa
|
||||
|
|
@ -12,8 +12,8 @@ is submitted, the form's data is submitted as a dictionary to any callable of
|
|||
your choice.
|
||||
|
||||
The function that initializes the fillable form menu is fairly simple, and
|
||||
includes the caller, the template for the form, and the callback(caller, result) to which the form
|
||||
data will be sent to upon submission.
|
||||
includes the caller, the template for the form, and the callback(caller, result)
|
||||
to which the form data will be sent to upon submission.
|
||||
|
||||
init_fill_field(formtemplate, caller, formcallback)
|
||||
|
||||
52
evennia/contrib/utils/random_string_generator/README.md
Normal file
52
evennia/contrib/utils/random_string_generator/README.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Pseudo-random generator and registry
|
||||
|
||||
Contribution - Vincent Le Goff 2017
|
||||
|
||||
This contrib can be used to generate pseudo-random strings of information
|
||||
with specific criteria. You could, for instance, use it to generate
|
||||
phone numbers, license plate numbers, validation codes, non-sensivite
|
||||
passwords and so on. The strings generated by the generator will be
|
||||
stored and won't be available again in order to avoid repetition.
|
||||
Here's a very simple example:
|
||||
|
||||
```python
|
||||
|
||||
from evennia.contrib.random_string_generator import RandomStringGenerator
|
||||
|
||||
# Create a generator for phone numbers
|
||||
phone_generator = RandomStringGenerator("phone number", r"555-[0-9]{3}-[0-9]{4}")
|
||||
|
||||
# Generate a phone number (555-XXX-XXXX with X as numbers)
|
||||
number = phone_generator.get()
|
||||
|
||||
# `number` will contain something like: "555-981-2207"
|
||||
# If you call `phone_generator.get`, it won't give the same anymore.phone_generator.all()
|
||||
# Will return a list of all currently-used phone numbers
|
||||
phone_generator.remove("555-981-2207")
|
||||
|
||||
# The number can be generated again
|
||||
```
|
||||
|
||||
## Importing
|
||||
|
||||
1. Import the `RandomStringGenerator` class from the contrib.
|
||||
2. Create an instance of this class taking two arguments:
|
||||
- The name of the gemerator (like "phone number", "license plate"...).
|
||||
- The regular expression representing the expected results.
|
||||
3. Use the generator's `all`, `get` and `remove` methods as shown above.
|
||||
|
||||
To understand how to read and create regular expressions, you can refer to
|
||||
[the documentation on the re module](https://docs.python.org/2/library/re.html).
|
||||
Some examples of regular expressions you could use:
|
||||
|
||||
- `r"555-\d{3}-\d{4}"`: 555, a dash, 3 digits, another dash, 4 digits.
|
||||
- `r"[0-9]{3}[A-Z][0-9]{3}"`: 3 digits, a capital letter, 3 digits.
|
||||
- `r"[A-Za-z0-9]{8,15}"`: between 8 and 15 letters and digits.
|
||||
- ...
|
||||
|
||||
Behind the scenes, a script is created to store the generated information
|
||||
for a single generator. The `RandomStringGenerator` object will also
|
||||
read the regular expression you give to it to see what information is
|
||||
required (letters, digits, a more restricted class, simple characters...)...
|
||||
More complex regular expressions (with branches for instance) might not be
|
||||
available.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
"""
|
||||
Pseudo-random generator - vlgeoff 2017
|
||||
|
||||
"""
|
||||
|
||||
from .random_string_generator import RandomStringGenerator # noqa
|
||||
|
|
@ -98,7 +98,7 @@ class RandomStringGeneratorScript(DefaultScript):
|
|||
self.db.generated = {}
|
||||
|
||||
|
||||
class RandomStringGenerator(object):
|
||||
class RandomStringGenerator:
|
||||
|
||||
"""
|
||||
A generator class to generate pseudo-random strings with a rule.
|
||||
|
|
@ -156,7 +156,7 @@ class RandomStringGenerator(object):
|
|||
self._find_elements(regex)
|
||||
|
||||
def __repr__(self):
|
||||
return "<evennia.contrib.random_string_generator.RandomStringGenerator for {}>".format(
|
||||
return "<evennia.contrib.tutorials.random_string_generator.RandomStringGenerator for {}>".format(
|
||||
self.name
|
||||
)
|
||||
|
||||
|
|
@ -168,7 +168,8 @@ class RandomStringGenerator(object):
|
|||
try:
|
||||
script = ScriptDB.objects.get(db_key="generator_script")
|
||||
except ScriptDB.DoesNotExist:
|
||||
script = create_script("contrib.random_string_generator.RandomStringGeneratorScript")
|
||||
script = create_script(
|
||||
"contrib.tutorials.random_string_generator.RandomStringGeneratorScript")
|
||||
|
||||
type(self).script = script
|
||||
return script
|
||||
161
evennia/contrib/utils/tree_select/README.md
Normal file
161
evennia/contrib/utils/tree_select/README.md
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
# Easy menu selection tree
|
||||
|
||||
Contrib - Tim Ashley Jenkins 2017
|
||||
|
||||
This module allows you to create and initialize an entire branching EvMenu
|
||||
instance with nothing but a multi-line string passed to one function.
|
||||
|
||||
EvMenu is incredibly powerful and flexible, but using it for simple menus
|
||||
can often be fairly cumbersome - a simple menu that can branch into five
|
||||
categories would require six nodes, each with options represented as a list
|
||||
of dictionaries.
|
||||
|
||||
This module provides a function, `init_tree_selection`, which acts as a frontend
|
||||
for EvMenu, dynamically sourcing the options from a multi-line string you
|
||||
provide. For example, if you define a string as such:
|
||||
|
||||
TEST_MENU = '''Foo
|
||||
Bar
|
||||
Baz
|
||||
Qux'''
|
||||
|
||||
And then use `TEST_MENU` as the 'treestr' source when you call
|
||||
`init_tree_selection` on a player:
|
||||
|
||||
init_tree_selection(TEST_MENU, caller, callback)
|
||||
|
||||
The player will be presented with an EvMenu, like so:
|
||||
|
||||
___________________________
|
||||
|
||||
Make your selection:
|
||||
___________________________
|
||||
|
||||
Foo
|
||||
Bar
|
||||
Baz
|
||||
Qux
|
||||
|
||||
Making a selection will pass the selection's key to the specified callback as a
|
||||
string along with the caller, as well as the index of the selection (the line
|
||||
number on the source string) along with the source string for the tree itself.
|
||||
|
||||
In addition to specifying selections on the menu, you can also specify
|
||||
categories. Categories are indicated by putting options below it preceded with
|
||||
a '-' character. If a selection is a category, then choosing it will bring up a
|
||||
new menu node, prompting the player to select between those options, or to go
|
||||
back to the previous menu. In addition, categories are marked by default with a
|
||||
'[+]' at the end of their key. Both this marker and the option to go back can be
|
||||
disabled.
|
||||
|
||||
Categories can be nested in other categories as well - just go another '-'
|
||||
deeper. You can do this as many times as you like. There's no hard limit to the
|
||||
number of categories you can go down.
|
||||
|
||||
For example, let's add some more options to our menu, turning 'Bar' into a
|
||||
category.
|
||||
|
||||
TEST_MENU = '''Foo
|
||||
Bar
|
||||
-You've got to know
|
||||
--When to hold em
|
||||
--When to fold em
|
||||
--When to walk away
|
||||
Baz
|
||||
Qux'''
|
||||
|
||||
Now when we call the menu, we can see that 'Bar' has become a category instead of a
|
||||
selectable option.
|
||||
|
||||
_______________________________
|
||||
|
||||
Make your selection:
|
||||
_______________________________
|
||||
|
||||
Foo
|
||||
Bar [+]
|
||||
Baz
|
||||
Qux
|
||||
|
||||
Note the [+] next to 'Bar'. If we select 'Bar', it'll show us the option listed
|
||||
under it.
|
||||
|
||||
________________________________________________________________
|
||||
|
||||
Bar
|
||||
________________________________________________________________
|
||||
|
||||
You've got to know [+]
|
||||
<< Go Back: Return to the previous menu.
|
||||
|
||||
Just the one option, which is a category itself, and the option to go back,
|
||||
which will take us back to the previous menu. Let's select 'You've got to know'.
|
||||
|
||||
________________________________________________________________
|
||||
|
||||
You've got to know
|
||||
________________________________________________________________
|
||||
|
||||
When to hold em
|
||||
When to fold em
|
||||
When to walk away
|
||||
<< Go Back: Return to the previous menu.
|
||||
|
||||
Now we see the three options listed under it, too. We can select one of them or
|
||||
use 'Go Back' to return to the 'Bar' menu we were just at before. It's very
|
||||
simple to make a branching tree of selections!
|
||||
|
||||
One last thing - you can set the descriptions for the various options simply by
|
||||
adding a ':' character followed by the description to the option's line. For
|
||||
example, let's add a description to 'Baz' in our menu:
|
||||
|
||||
TEST_MENU = '''Foo
|
||||
Bar
|
||||
-You've got to know
|
||||
--When to hold em
|
||||
--When to fold em
|
||||
--When to walk away
|
||||
Baz: Look at this one: the best option.
|
||||
Qux'''
|
||||
|
||||
Now we see that the Baz option has a description attached that's separate from its key:
|
||||
|
||||
_______________________________________________________________
|
||||
|
||||
Make your selection:
|
||||
_______________________________________________________________
|
||||
|
||||
Foo
|
||||
Bar [+]
|
||||
Baz: Look at this one: the best option.
|
||||
Qux
|
||||
|
||||
Once the player makes a selection - let's say, 'Foo' - the menu will terminate
|
||||
and call your specified callback with the selection, like so:
|
||||
|
||||
callback(caller, TEST_MENU, 0, "Foo")
|
||||
|
||||
The index of the selection is given along with a string containing the
|
||||
selection's key. That way, if you have two selections in the menu with the same
|
||||
key, you can still differentiate between them.
|
||||
|
||||
And that's all there is to it! For simple branching-tree selections, using this
|
||||
system is much easier than manually creating EvMenu nodes. It also makes
|
||||
generating menus with dynamic options much easier - since the source of the menu
|
||||
tree is just a string, you could easily generate that string procedurally before
|
||||
passing it to the `init_tree_selection` function. For example, if a player casts
|
||||
a spell or does an attack without specifying a target, instead of giving them an
|
||||
error, you could present them with a list of valid targets to select by
|
||||
generating a multi-line string of targets and passing it to
|
||||
`init_tree_selection`, with the callable performing the maneuver once a
|
||||
selection is made.
|
||||
|
||||
This selection system only works for simple branching trees - doing anything
|
||||
really complicated like jumping between categories or prompting for arbitrary
|
||||
input would still require a full EvMenu implementation. For simple selections,
|
||||
however, I'm sure you will find using this function to be much easier!
|
||||
|
||||
Included in this module is a sample menu and function which will let a player
|
||||
change the color of their name - feel free to mess with it to get a feel for how
|
||||
this system works by importing this module in your game's `default_cmdsets.py`
|
||||
module and adding `CmdNameColor` to your default character's command set.
|
||||
6
evennia/contrib/utils/tree_select/__init__.py
Normal file
6
evennia/contrib/utils/tree_select/__init__.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"""
|
||||
Menu selection tree - Tim Ashley Jenkins 2017
|
||||
|
||||
"""
|
||||
|
||||
from .tree_select import init_tree_selection # noqa
|
||||
|
|
@ -155,6 +155,7 @@ Included in this module is a sample menu and function which will let a player ch
|
|||
of their name - feel free to mess with it to get a feel for how this system works by importing
|
||||
this module in your game's default_cmdsets.py module and adding CmdNameColor to your default
|
||||
character's command set.
|
||||
|
||||
"""
|
||||
|
||||
from evennia.utils import evmenu
|
||||
Loading…
Add table
Add a link
Reference in a new issue