diff --git a/docs/0.9.5/api/evennia.commands.default.building.html b/docs/0.9.5/api/evennia.commands.default.building.html
index 2a84edbbb1..0417f7eeb1 100644
--- a/docs/0.9.5/api/evennia.commands.default.building.html
+++ b/docs/0.9.5/api/evennia.commands.default.building.html
@@ -496,7 +496,7 @@ You can specify the /force switch to bypass this confirmation.
diff --git a/docs/0.9.5/api/evennia.commands.default.system.html b/docs/0.9.5/api/evennia.commands.default.system.html
index 868e9d6ed4..9ab9d84d9a 100644
--- a/docs/0.9.5/api/evennia.commands.default.system.html
+++ b/docs/0.9.5/api/evennia.commands.default.system.html
@@ -296,7 +296,7 @@ required since whole classes of scripts often have the same name.
diff --git a/docs/0.9.5/api/evennia.contrib.chargen.html b/docs/0.9.5/api/evennia.contrib.chargen.html
index d12901c845..e7f84087a5 100644
--- a/docs/0.9.5/api/evennia.contrib.chargen.html
+++ b/docs/0.9.5/api/evennia.contrib.chargen.html
@@ -79,7 +79,7 @@ at them with this command.
diff --git a/docs/0.9.5/api/evennia.contrib.dice.html b/docs/0.9.5/api/evennia.contrib.dice.html
index 31f97ae1cb..6dc941e2e3 100644
--- a/docs/0.9.5/api/evennia.contrib.dice.html
+++ b/docs/0.9.5/api/evennia.contrib.dice.html
@@ -151,7 +151,7 @@ everyone but the person rolling.
diff --git a/docs/0.9.5/api/evennia.contrib.email_login.html b/docs/0.9.5/api/evennia.contrib.email_login.html
index 8962dac44c..ed47397df5 100644
--- a/docs/0.9.5/api/evennia.contrib.email_login.html
+++ b/docs/0.9.5/api/evennia.contrib.email_login.html
@@ -76,7 +76,7 @@ the module given by settings.CONNECTION_SCREEN_MODULE.
diff --git a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_basic.html b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_basic.html
index 4383f10009..c337ec3963 100644
--- a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_basic.html
+++ b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_basic.html
@@ -562,7 +562,7 @@ if there are still any actions you can take.
diff --git a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_equip.html b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_equip.html
index a9e6929a11..76ba8cab38 100644
--- a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_equip.html
+++ b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_equip.html
@@ -679,7 +679,7 @@ if there are still any actions you can take.
diff --git a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_items.html b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_items.html
index c58f087ca3..5a993996d6 100644
--- a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_items.html
+++ b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_items.html
@@ -713,7 +713,7 @@ if there are still any actions you can take.
diff --git a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_magic.html b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_magic.html
index 45e59490ce..9d00e31190 100644
--- a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_magic.html
+++ b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_magic.html
@@ -585,7 +585,7 @@ if there are still any actions you can take.
diff --git a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_range.html b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_range.html
index 91da9c133f..bbd3dfc46f 100644
--- a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_range.html
+++ b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_range.html
@@ -997,7 +997,7 @@ if there are still any actions you can take.
diff --git a/docs/0.9.5/api/evennia.contrib.tutorial_examples.cmdset_red_button.html b/docs/0.9.5/api/evennia.contrib.tutorial_examples.cmdset_red_button.html
index 583166be95..1c73dfe6f6 100644
--- a/docs/0.9.5/api/evennia.contrib.tutorial_examples.cmdset_red_button.html
+++ b/docs/0.9.5/api/evennia.contrib.tutorial_examples.cmdset_red_button.html
@@ -107,7 +107,7 @@ push the lid of the button away.
diff --git a/docs/0.9.5/api/evennia.contrib.tutorial_world.objects.html b/docs/0.9.5/api/evennia.contrib.tutorial_world.objects.html
index 015d847cab..a1e187b3c6 100644
--- a/docs/0.9.5/api/evennia.contrib.tutorial_world.objects.html
+++ b/docs/0.9.5/api/evennia.contrib.tutorial_world.objects.html
@@ -353,7 +353,7 @@ of the object. We overload it with our own version.
diff --git a/docs/0.9.5/api/evennia.utils.evmore.html b/docs/0.9.5/api/evennia.utils.evmore.html
index d1df618373..5f37d78dfc 100644
--- a/docs/0.9.5/api/evennia.utils.evmore.html
+++ b/docs/0.9.5/api/evennia.utils.evmore.html
@@ -77,7 +77,7 @@ the caller.msg() construct every time the page is updated.
diff --git a/docs/1.0-dev/.buildinfo b/docs/1.0-dev/.buildinfo
index 982993b9a2..04c6fbb1a6 100644
--- a/docs/1.0-dev/.buildinfo
+++ b/docs/1.0-dev/.buildinfo
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: 8c9f4b59db1258692e62f50298da9a3e
+config: b2fb4b3cadc18ca336a414b8eb2c297f
tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/docs/1.0-dev/.vale/write-good/README.html b/docs/1.0-dev/.vale/write-good/README.html
index f8196ffa72..2c1e703245 100644
--- a/docs/1.0-dev/.vale/write-good/README.html
+++ b/docs/1.0-dev/.vale/write-good/README.html
@@ -34,43 +34,8 @@
Travis CI is an online service for checking, validating and potentially
-deploying code automatically. It can check that every commit is building successfully after every
-commit to its Github repository.
-
If your game is open source on Github you may use Travis for free.
-See [the Travis docs](https://docs.travis-ci.com/user/getting- started/) for how to get started.
-
After logging in you will get to point Travis to your repository on github. One further thing you
-need to set up yourself is a Travis config file named .travis.yml (note the initial period .).
-This should be created in the root of your game directory. The idea with this file is that it
-describes what Travis needs to import and build in order to create an instance of Evennia from
-scratch and then run validation tests on it. Here is an example:
This will tell travis how to download Evennia, install it, set up a database and then run
-your own test suite (inside the game dir). Use evenniatestevennia if you also want to
-run the Evennia full test suite.
-
You need to add this file to git (gitadd.travis.yml) and then commit your changes before Travis
-will be able to see it.
-
For properly testing your game you of course also need to write unittests.
-The Unit testing doc page gives some ideas on how to set those up for Evennia.
-You should be able to refer to that for making tests fitting your game.
Travis CI is an online service for checking, validating and potentially
+deploying code automatically. It can check that every commit is building successfully after every
+commit to its Github repository.
+
If your game is open source on Github you may use Travis for free.
+See [the Travis docs](https://docs.travis-ci.com/user/getting- started/) for how to get started.
+
After logging in you will get to point Travis to your repository on github. One further thing you
+need to set up yourself is a Travis config file named .travis.yml (note the initial period .).
+This should be created in the root of your game directory. The idea with this file is that it
+describes what Travis needs to import and build in order to create an instance of Evennia from
+scratch and then run validation tests on it. Here is an example:
This will tell travis how to download Evennia, install it, set up a database and then run
+your own test suite (inside the game dir). Use evenniatestevennia if you also want to
+run the Evennia full test suite.
+
You need to add this file to git (gitadd.travis.yml) and then commit your changes before Travis
+will be able to see it.
+
For properly testing your game you of course also need to write unittests.
+The Unit testing doc page gives some ideas on how to set those up for Evennia.
+You should be able to refer to that for making tests fitting your game.
One of the advantages of Evennia over traditional MU* development systems is that Evennia can
-integrate into enterprise-level integration environments and source control.
Continuous Integration (CI) is a development
-practice that requires developers to integrate code into a shared repository.
-Each check-in is then verified by an automated build, allowing teams to detect problems early. This
-can be set up to safely deploy data to a production server only after tests have passed, for example.
-
For Evennia, continuous integration allows an automated build process to:
-
-
Pull down a latest build from Source Control.
-
Run migrations on the backing SQL database.
-
Automate additional unique tasks for that project.
One of the advantages of Evennia over traditional MU* development systems is that Evennia can
+integrate into enterprise-level integration environments and source control.
Continuous Integration (CI) is a development
+practice that requires developers to integrate code into a shared repository.
+Each check-in is then verified by an automated build, allowing teams to detect problems early. This
+can be set up to safely deploy data to a production server only after tests have passed, for example.
+
For Evennia, continuous integration allows an automated build process to:
+
+
Pull down a latest build from Source Control.
+
Run migrations on the backing SQL database.
+
Automate additional unique tasks for that project.
Evennia consists of two processes, known as Portal and Server. They can be controlled from
-inside the game or from the command line as described here.
-
If you are new to the concept, the main purpose of separating the two is to have accounts connect to
-the Portal but keep the MUD running on the Server. This way one can restart/reload the game (the
-Server part) without Accounts getting disconnected.
The Server and Portal are glued together via an AMP (Asynchronous Messaging Protocol) connection.
-This allows the two programs to communicate seamlessly.
Evennia consists of two processes, known as Portal and Server. They can be controlled from
+inside the game or from the command line as described here.
+
If you are new to the concept, the main purpose of separating the two is to have accounts connect to
+the Portal but keep the MUD running on the Server. This way one can restart/reload the game (the
+Server part) without Accounts getting disconnected.
The Server and Portal are glued together via an AMP (Asynchronous Messaging Protocol) connection.
+This allows the two programs to communicate seamlessly.
Evennia supports clickable links for clients that supports it. This marks certain text so it can be
-clicked by a mouse and either trigger a given Evennia command, or open a URL in an external web
-browser. To support clickable links, Evennia requires the webclient or an third-party telnet client
-with MXP support (Note: Evennia only supports clickable links, no other MXP features).
-
-
|lc to start the link, by defining the command to execute.
-
|lu to start the link, by defining the URL to open.
-
|lt to continue with the text to show to the user (the link text).
-
|le to end the link text and the link definition.
-
-
All elements must appear in exactly this order to make a valid link. For example,
-
"If you go |lcnorth|ltto the north|le you will find a cottage."
-
-
-
This will display as “If you go to the north you will find a cottage.” where clicking the link
-will execute the command north. If the client does not support clickable links, only the link text
-will be shown.
Evennia supports clickable links for clients that supports it. This marks certain text so it can be
+clicked by a mouse and either trigger a given Evennia command, or open a URL in an external web
+browser. To support clickable links, Evennia requires the webclient or an third-party telnet client
+with MXP support (Note: Evennia only supports clickable links, no other MXP features).
+
+
|lc to start the link, by defining the command to execute.
+
|lu to start the link, by defining the URL to open.
+
|lt to continue with the text to show to the user (the link text).
+
|le to end the link text and the link definition.
+
+
All elements must appear in exactly this order to make a valid link. For example,
+
"If you go |lcnorth|ltto the north|le you will find a cottage."
+
+
+
This will display as “If you go to the north you will find a cottage.” where clicking the link
+will execute the command north. If the client does not support clickable links, only the link text
+will be shown.
Evennia supports guest logins out of the box. A guest login is an anonymous, low-access account
-and can be useful if you want users to have a chance to try out your game without committing to
-creating a real account.
-
Guest accounts are turned off by default. To activate, add this to your game/settings.py file:
-
GUEST_ENABLED = True
-
-
-
Henceforth users can use connectguest (in the default command set) to login with a guest account.
-You may need to change your Connection Screen to inform them of this
-possibility. Guest accounts work differently from normal accounts - they are automatically deleted
-whenever the user logs off or the server resets (but not during a reload). They are literally re-
-usable throw-away accounts.
-
You can add a few more variables to your settings.py file to customize your guests:
-
-
BASE_GUEST_TYPECLASS - the python-path to the default typeclass for guests.
-Defaults to "typeclasses.accounts.Guest".
-
PERMISSION_GUEST_DEFAULT - permission level for guest accounts. Defaults to "Guests",
-which is the lowest permission level in the hierarchy.
-
GUEST_START_LOCATION - the #dbref to the starting location newly logged-in guests should
-appear at. Defaults to "#2 (Limbo).
-
GUEST_HOME - guest home locations. Defaults to Limbo as well.
-
GUEST_LIST - this is a list holding the possible guest names to use when entering the game. The
-length of this list also sets how many guests may log in at the same time. By default this is a list
-of nine names from "Guest1" to "Guest9".
Evennia supports guest logins out of the box. A guest login is an anonymous, low-access account
+and can be useful if you want users to have a chance to try out your game without committing to
+creating a real account.
+
Guest accounts are turned off by default. To activate, add this to your game/settings.py file:
+
GUEST_ENABLED = True
+
+
+
Henceforth users can use connectguest (in the default command set) to login with a guest account.
+You may need to change your Connection Screen to inform them of this
+possibility. Guest accounts work differently from normal accounts - they are automatically deleted
+whenever the user logs off or the server resets (but not during a reload). They are literally re-
+usable throw-away accounts.
+
You can add a few more variables to your settings.py file to customize your guests:
+
+
BASE_GUEST_TYPECLASS - the python-path to the default typeclass for guests.
+Defaults to "typeclasses.accounts.Guest".
+
PERMISSION_GUEST_DEFAULT - permission level for guest accounts. Defaults to "Guests",
+which is the lowest permission level in the hierarchy.
+
GUEST_START_LOCATION - the #dbref to the starting location newly logged-in guests should
+appear at. Defaults to "#2 (Limbo).
+
GUEST_HOME - guest home locations. Defaults to Limbo as well.
+
GUEST_LIST - this is a list holding the possible guest names to use when entering the game. The
+length of this list also sets how many guests may log in at the same time. By default this is a list
+of nine names from "Guest1" to "Guest9".
Evennia understands various extra information embedded in text:
-
-
Colors - Using |r, |n etc can be used to mark parts of text with a color. The color will
-become ANSI/XTerm256 color tags for Telnet connections and CSS information for the webclient.
-
Clickable links - This allows you to provide a text the user can click to execute an
-in-game command. This is on the form |lccommand|lttext|le.
-
FuncParser callables - These are full-fledged function calls on the form $funcname(args,kwargs)
-that lead to calls to Python functions. The parser can be run with different available callables in different
-circumstances. The parser is run on all outgoing messages if settings.FUNCPARSER_PARSE_OUTGOING_MESSAGES_ENABLED=True
-(disabled by default).
Evennia understands various extra information embedded in text:
+
+
Colors - Using |r, |n etc can be used to mark parts of text with a color. The color will
+become ANSI/XTerm256 color tags for Telnet connections and CSS information for the webclient.
+
Clickable links - This allows you to provide a text the user can click to execute an
+in-game command. This is on the form |lccommand|lttext|le.
+
FuncParser callables - These are full-fledged function calls on the form $funcname(args,kwargs)
+that lead to calls to Python functions. The parser can be run with different available callables in different
+circumstances. The parser is run on all outgoing messages if settings.FUNCPARSER_PARSE_OUTGOING_MESSAGES_ENABLED=True
+(disabled by default).
Use scriptsme 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).
-
-
This document page is generated from evennia/contrib/tutorials/bodyfunctions/README.md. Changes to this
-file will be overwritten, so edit that file rather than this one.
Use scriptsme 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).
+
+
This document page is generated from evennia/contrib/tutorials/bodyfunctions/README.md. Changes to this
+file will be overwritten, so edit that file rather than this one.
This is a variant of the login system that asks for an email-address
-instead of a username to login. Note that it does not verify the email,
-it just uses it as the identifier rather than a username.
-
This used to be the default Evennia login before replacing it with a
-more standard username + password system (having to supply an email
-for some reason caused a lot of confusion when people wanted to expand
-on it. The email is not strictly needed internally, nor is any
-confirmation email sent out anyway).
If you want to modify the way the connection screen looks, point
-CONNECTION_SCREEN_MODULE to your own module. Use the default as a
-guide (see also Evennia docs).
-
-
This document page is generated from evennia/contrib/base_systems/email_login/README.md. Changes to this
-file will be overwritten, so edit that file rather than this one.
This is a variant of the login system that asks for an email-address
+instead of a username to login. Note that it does not verify the email,
+it just uses it as the identifier rather than a username.
+
This used to be the default Evennia login before replacing it with a
+more standard username + password system (having to supply an email
+for some reason caused a lot of confusion when people wanted to expand
+on it. The email is not strictly needed internally, nor is any
+confirmation email sent out anyway).
If you want to modify the way the connection screen looks, point
+CONNECTION_SCREEN_MODULE to your own module. Use the default as a
+guide (see also Evennia docs).
+
+
This document page is generated from evennia/contrib/base_systems/email_login/README.md. Changes to this
+file will be overwritten, so edit that file rather than this one.
A complete example MUD using Evennia. This is the final result of what is
-implemented if you follow the Getting-Started tutorial. It’s recommended
-that you follow the tutorial step by step and write your own code. But if
-you prefer you can also pick apart or use this as a starting point for your
-own game.
Uses a MUD-version of the Knave old-school
-fantasy ruleset by Ben Milton (classless and overall compatible with early
-edition D&D), released under the Creative Commons Attribution (all uses,
-including commercial are allowed
-as long as attribution is given).
-
Character creation using an editable character sheet
-
Weapons, effects, healing and resting
-
Two alternative combat systems (turn-based and twitch based)
-
Magic (three spells)
-
NPC/mobs with simple AI.
-
Simple Quest system.
-
Small game world.
-
Coded using best Evennia practices, with unit tests.
This document page is generated from evennia/contrib/tutorials/evadventure/README.md. Changes to this
-file will be overwritten, so edit that file rather than this one.
NOTE - this tutorial is WIP and NOT complete! It was put on hold to focus on
+releasing Evennia 1.0. You will still learn things from it, but don’t expect
+perfection.
+
+
A complete example MUD using Evennia. This is the final result of what is
+implemented if you follow the Getting-Started tutorial. It’s recommended
+that you follow the tutorial step by step and write your own code. But if
+you prefer you can also pick apart or use this as a starting point for your
+own game.
Uses a MUD-version of the Knave old-school
+fantasy ruleset by Ben Milton (classless and overall compatible with early
+edition D&D), released under the Creative Commons Attribution (all uses,
+including commercial are allowed
+as long as attribution is given).
+
Character creation using an editable character sheet
+
Weapons, effects, healing and resting
+
Two alternative combat systems (turn-based and twitch based)
+
Magic (three spells)
+
NPC/mobs with simple AI.
+
Simple Quest system.
+
Small game world.
+
Coded using best Evennia practices, with unit tests.
This document page is generated from evennia/contrib/tutorials/evadventure/README.md. Changes to this
+file will be overwritten, so edit that file rather than this one.
A module to integrate a stripped-down version of git within the game, allowing developers to view their git status, change branches, and pull updated code of both their local mygame repo and Evennia core. After a successful pull or checkout, the git command will reload the game: Manual restarts may be required to to apply certain changes that would impact persistent scripts etc.
+
Once the contrib is set up, integrating remote changes is as simple as entering the following into your game:
+
gitpull
+
+
+
The repositories you want to work with, be it only your local mygame repo, only Evennia core, or both, must be git directories for the command to function. If you are only interested in using this to get upstream Evennia changes, only the Evennia repository needs to be a git repository. Get started with version control here.
This package requires the dependency “gitpython”, a python library used to interact with git repositories. To install, it’s easiest to install Evennia’s extra requirements:
+
+
Activate your virtualenv
+
cd to the root of the Evennia repository. There should be an requirements_extra.txt file here.
This utility will only work if the directory you wish to work with is a git directory. If they are not, you will be prompted to initiate your directory as a git repository using the following commands in your terminal:
+
gitinit
+gitremoteaddorigin'link to your repository'
+
+
+
By default, the git commands are only available to those with Developer permissions and higher. You can change this by overriding the command and setting its locks from “cmd:pperm(Developer)” to the lock of your choice.
+
The supported commands are:
+
+
git status: An overview of your git repository, which files have been changed locally, and the commit you’re on.
+
git branch: What branches are available for you to check out.
+
git checkout ‘branch’: Checkout a branch.
+
git pull: Pull the latest code from your current branch.
+
All of these commands are also available with ‘evennia’, to serve the same functionality related to your Evennia directory. So:
The utility uses the existing GAME_DIR and EVENNIA_DIR settings from settings.py. You should not need to alter these if you have a standard directory setup, they ought to exist without any setup required from you.
+
+
This document page is generated from evennia/contrib/utils/git_integration/README.md. Changes to this
+file will be overwritten, so edit that file rather than this one.
+
+
+
\ No newline at end of file
diff --git a/docs/1.0-dev/Contribs/Contrib-Health-Bar.html b/docs/1.0-dev/Contribs/Contrib-Health-Bar.html
index 5d8f559529..1a840300f1 100644
--- a/docs/1.0-dev/Contribs/Contrib-Health-Bar.html
+++ b/docs/1.0-dev/Contribs/Contrib-Health-Bar.html
@@ -43,7 +43,62 @@
Contribution by Vincent-lg 2016. Reworked for modern EvMenu by Griatch, 2019.
-
This changes the Evennia login to ask for the account name and password as a series
-of questions instead of requiring you to enter both at once. It uses Evennia’s
-menu system EvMenu under the hood.
If you want to modify the way the connection screen looks, point
-CONNECTION_SCREEN_MODULE to your own module. Use the default as a
-guide (see also Evennia docs).
-
-
This document page is generated from evennia/contrib/base_systems/menu_login/README.md. Changes to this
-file will be overwritten, so edit that file rather than this one.
Contribution by Vincent-lg 2016. Reworked for modern EvMenu by Griatch, 2019.
+
This changes the Evennia login to ask for the account name and password as a series
+of questions instead of requiring you to enter both at once. It uses Evennia’s
+menu system EvMenu under the hood.
If you want to modify the way the connection screen looks, point
+CONNECTION_SCREEN_MODULE to your own module. Use the default as a
+guide (see also Evennia docs).
+
+
This document page is generated from evennia/contrib/base_systems/menu_login/README.md. Changes to this
+file will be overwritten, so edit that file rather than this one.
This document page is generated from evennia/contrib/tutorials/mirror/README.md. Changes to this
-file will be overwritten, so edit that file rather than this one.
This document page is generated from evennia/contrib/tutorials/mirror/README.md. Changes to this
+file will be overwritten, so edit that file rather than this one.
A “multidescer” is a concept from the MUSH world. It allows for
-creating, managing and switching between multiple character
-descriptions and is a way for quickly managing your look (such as when
-changing clothes) in more free-form roleplaying systems. This will also
-work well together with the rpsystem contrib.
-
This multidescer will not
-require any changes to the Character class, rather it will use the multidescs
-Attribute (a list) and create it if it does not exist.
Edit mygame/commands/default_cmdsets.py and add
-fromevennia.contrib.game_systems.multidescerimportCmdMultiDesc to the top.
-
Next, look up the at_cmdset_create method of the CharacterCmdSet
-class and add a line self.add(CmdMultiDesc()) to the end
-of it.
-
Reload the server and you should have the +desc command available (it
-will replace the default desc command).
-
-
This document page is generated from evennia/contrib/game_systems/multidescer/README.md. Changes to this
-file will be overwritten, so edit that file rather than this one.
A “multidescer” is a concept from the MUSH world. It allows for
+creating, managing and switching between multiple character
+descriptions and is a way for quickly managing your look (such as when
+changing clothes) in more free-form roleplaying systems. This will also
+work well together with the rpsystem contrib.
+
This multidescer will not
+require any changes to the Character class, rather it will use the multidescs
+Attribute (a list) and create it if it does not exist.
Edit mygame/commands/default_cmdsets.py and add
+fromevennia.contrib.game_systems.multidescerimportCmdMultiDesc to the top.
+
Next, look up the at_cmdset_create method of the CharacterCmdSet
+class and add a line self.add(CmdMultiDesc()) to the end
+of it.
+
Reload the server and you should have the +desc command available (it
+will replace the default desc command).
+
+
This document page is generated from evennia/contrib/game_systems/multidescer/README.md. Changes to this
+file will be overwritten, so edit that file rather than this one.
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.
-
-
This document page is generated from evennia/contrib/tutorials/talking_npc/README.md. Changes to this
-file will be overwritten, so edit that file rather than this one.
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.
+
+
This document page is generated from evennia/contrib/tutorials/talking_npc/README.md. Changes to this
+file will be overwritten, so edit that file rather than this one.
This will install all optional requirements of Evennia.
-
Import and add the evennia.contrib.commands.XYZGridCmdSet to the
+
Import and add the evennia.contrib.grid.xyzgrid.commands.XYZGridCmdSet to the
CharacterCmdset cmdset in mygame/commands.default_cmds.py. Reload
the server. This makes the map, goto/path and the modified teleport and
open commands available in-game.
This will add the new ability to enter evenniaxyzgrid<option> on the
@@ -1482,99 +1570,10 @@ file will be overwritten, so edit that file rather than this one.
A complete example MUD using Evennia. This is the final result of what is
-implemented if you follow the Getting-Started tutorial. It’s recommended
-that you follow the tutorial step by step and write your own code. But if
-you prefer you can also pick apart or use this as a starting point for your
-own game.
+
+
Warning
+
NOTE - this tutorial is WIP and NOT complete! It was put on hold to focus on
+releasing Evennia 1.0. You will still learn things from it, but don’t expect
+perfection.
A module to integrate a stripped-down version of git within the game, allowing developers to view their git status, change branches, and pull updated code of both their local mygame repo and Evennia core. After a successful pull or checkout, the git command will reload the game: Manual restarts may be required to to apply certain changes that would impact persistent scripts etc.
Evennia is licensed under the very friendly BSD
-(3-clause) license. You can find the license as
-LICENSE.txt in the Evennia
-repository’s root.
-
Q: When creating a game using Evennia, what does the license permit me to do with it?
-
A: It’s your own game world to do with as you please! Keep it to yourself or re-distribute it
-under another license of your choice - or sell it and become filthy rich for all we care.
-
Q: I have modified the Evennia library itself, what does the license say about that?
-
A: Our license allows you to do whatever you want with your modified Evennia, including
-re-distributing or selling it, as long as you include our license and copyright info found in
-LICENSE.txt along with your distribution.
-
… Of course, if you fix bugs or add some new snazzy feature we softly nudge you to make those
-changes available so they can be added to the core Evennia package for everyone’s benefit. The
-license doesn’t require you to do it, but that doesn’t mean we won’t still greatly appreciate it
-if you do!
-
Q: Can I re-distribute the Evennia server package along with my custom game implementation?
-
A: Sure. As long as the text in LICENSE.txt is included.
-
Q: What about Contributions?
-
The contributions in evennia/evennia/contrib are considered to be released under the same license
-as Evennia itself, unless the individual contributor has specifically defined otherwise.
Evennia is licensed under the very friendly BSD
+(3-clause) license. You can find the license as
+LICENSE.txt in the Evennia
+repository’s root.
+
Q: When creating a game using Evennia, what does the license permit me to do with it?
+
A: It’s your own game world to do with as you please! Keep it to yourself or re-distribute it
+under another license of your choice - or sell it and become filthy rich for all we care.
+
Q: I have modified the Evennia library itself, what does the license say about that?
+
A: Our license allows you to do whatever you want with your modified Evennia, including
+re-distributing or selling it, as long as you include our license and copyright info found in
+LICENSE.txt along with your distribution.
+
… Of course, if you fix bugs or add some new snazzy feature we softly nudge you to make those
+changes available so they can be added to the core Evennia package for everyone’s benefit. The
+license doesn’t require you to do it, but that doesn’t mean we won’t still greatly appreciate it
+if you do!
+
Q: Can I re-distribute the Evennia server package along with my custom game implementation?
+
A: Sure. As long as the text in LICENSE.txt is included.
+
Q: What about Contributions?
+
The contributions in evennia/evennia/contrib are considered to be released under the same license
+as Evennia itself, unless the individual contributor has specifically defined otherwise.
The first ime you run evenniastart (just after having created the database), you will be asked
-to interactively insert the superuser username, email and password. If you are deploying Evennia
-as part of an automatic build script, you don’t want to enter this information manually.
-
You can have the superuser be created automatically by passing environment variables to your
-build script:
-
-
EVENNIA_SUPERUSER_USERNAME
-
EVENNIA_SUPERUSER_PASSWORD
-
EVENNIA_SUPERUSER_EMAIL is optional. If not given, empty string is used.
-
-
These envvars will only be used on the very first server start and then ignored. For example:
The first ime you run evenniastart (just after having created the database), you will be asked
+to interactively insert the superuser username, email and password. If you are deploying Evennia
+as part of an automatic build script, you don’t want to enter this information manually.
+
You can have the superuser be created automatically by passing environment variables to your
+build script:
+
+
EVENNIA_SUPERUSER_USERNAME
+
EVENNIA_SUPERUSER_PASSWORD
+
EVENNIA_SUPERUSER_EMAIL is optional. If not given, empty string is used.
+
+
These envvars will only be used on the very first server start and then ignored. For example:
@@ -648,7 +695,7 @@ to change into myga
"column_names_color":("Table column header text.","Color","w"),"help_category_color":("Help category names.","Color","n"),"help_entry_color":("Help entry names.","Color","n"),
- "timezone":("Timezone for dates. @tz for a list.","Timezone","UTC"),
+ "timezone":("Timezone for dates.","Timezone","UTC"),}# Modules holding Option classes, responsible for serializing the option and# calling validator functions on it. Same-named functions in modules added
@@ -1270,57 +1317,10 @@ to change into myga
-
@@ -253,7 +287,7 @@
Keyword Args: typeclass (str): The typeclass to use for the account.
- is_superuser (bool): Wether or not this account is to be a superuser
+ is_superuser (bool): Whether or not this account is to be a superuser locks (str): Lockstring. permission (list): List of permission strings. tags (list): List of Tags on form `(key, category[, data])`
@@ -342,44 +376,10 @@
pass
Source code for evennia.commands.default.cmdset_unloggedin
-"""
-This module describes the unlogged state of the default game.
-The setting STATE_UNLOGGED should be set to the python path
-of the state instance in this module.
-"""
-fromevennia.commands.cmdsetimportCmdSet
-fromevennia.commands.defaultimportunloggedin
-
-
-
[docs]classUnloggedinCmdSet(CmdSet):
- """
- Sets up the unlogged cmdset.
- """
-
- key="DefaultUnloggedin"
- priority=0
-
-
Source code for evennia.commands.default.cmdset_unloggedin
+"""
+This module describes the unlogged state of the default game.
+The setting STATE_UNLOGGED should be set to the python path
+of the state instance in this module.
+"""
+fromevennia.commands.cmdsetimportCmdSet
+fromevennia.commands.defaultimportunloggedin
+
+
+
[docs]classUnloggedinCmdSet(CmdSet):
+ """
+ Sets up the unlogged cmdset.
+ """
+
+ key="DefaultUnloggedin"
+ priority=0
+
+
Source code for evennia.contrib.base_systems.components
-"""
-Components - ChrisLR 2022
-
-This is a basic Component System.
-It allows you to use components on typeclasses using a simple syntax.
-This helps writing isolated code and reusing it over multiple objects.
-
-See the docs for more information.
-"""
-
-fromevennia.contrib.base_systems.components.componentimportComponent
-fromevennia.contrib.base_systems.components.dbfieldimportDBField,NDBField,TagField
-fromevennia.contrib.base_systems.components.holderimportComponentHolderMixin,ComponentProperty
-
-
-
[docs]defget_component_class(component_name):
- subclasses=Component.__subclasses__()
- component_class=next((scforscinsubclassesifsc.name==component_name),None)
- ifcomponent_classisNone:
- message=(
- f"Component named {component_name} has not been found. "
- f"Make sure it has been imported before being used."
- )
- raiseException(message)
-
- returncomponent_class
Source code for evennia.contrib.base_systems.components
+"""
+Components - ChrisLR 2022
+
+This is a basic Component System.
+It allows you to use components on typeclasses using a simple syntax.
+This helps writing isolated code and reusing it over multiple objects.
+
+See the docs for more information.
+"""
+
+fromevennia.contrib.base_systems.components.componentimportComponent
+fromevennia.contrib.base_systems.components.dbfieldimportDBField,NDBField,TagField
+fromevennia.contrib.base_systems.components.holderimportComponentHolderMixin,ComponentProperty
+
+
+
[docs]defget_component_class(component_name):
+ subclasses=Component.__subclasses__()
+ component_class=next((scforscinsubclassesifsc.name==component_name),None)
+ ifcomponent_classisNone:
+ message=(
+ f"Component named {component_name} has not been found. "
+ f"Make sure it has been imported before being used."
+ )
+ raiseException(message)
+
+ returncomponent_class
@@ -45,6 +79,7 @@
Tests for the XYZgrid system."""
+fromunittestimportmockfromrandomimportrandintfromparameterizedimportparameterized
@@ -1457,46 +1492,87 @@
self.assertTrue(room2a.db.desc.startswith("This is the entrance to"))self.assertEqual(room2b.key,"North-west corner of the atrium")self.assertTrue(room2b.db.desc.startswith("Sunlight sifts down"))
@@ -49,9 +83,10 @@
"""
+fromdjango.confimportsettingsfromdjango.db.modelsimportQ
-fromevennia.objects.objectsimportDefaultRoom,DefaultExitfromevennia.objects.managerimportObjectManager
+fromevennia.objects.objectsimportDefaultExit,DefaultRoom# name of all tag categories. Note that the Z-coordinate is# the `map_name` of the XYZgrid
@@ -65,6 +100,8 @@
GET_XYZGRID=None
+CLIENT_DEFAULT_WIDTH=settings.CLIENT_DEFAULT_WIDTH
+
[docs]classXYZManager(ObjectManager):"""
@@ -271,7 +308,7 @@
f"{key}={val}"forkey,valinkwargs.items())raiseself.model.DoesNotExist(
- f"{self.model.__name__} "f"matching query {inp} does not exist."
+ f"{self.model.__name__} matching query {inp} does not exist.")
[docs]deftest_cmddice(self,mocked_randint):
- self.call(
- dice.CmdDice(),"3d6 + 4","You roll 3d6 + 4.| Roll(s): 5, 5 and 5. Total result is 19."
- )
- self.call(dice.CmdDice(),"100000d1000","The maximum roll allowed is 10000d10000.")
- self.call(dice.CmdDice(),"/secret 3d6 + 4","You roll 3d6 + 4 (secret, not echoed).")
[docs]deftest_cmddice(self,mocked_randint):
+ self.call(
+ dice.CmdDice(),"3d6 + 4","You roll 3d6 + 4.| Roll(s): 5, 5 and 5. Total result is 19."
+ )
+ self.call(dice.CmdDice(),"100000d1000","The maximum roll allowed is 10000d10000.")
+ self.call(dice.CmdDice(),"/secret 3d6 + 4","You roll 3d6 + 4 (secret, not echoed).")
[docs]deftest_talkingnpc(self):
- npc=create_object(talking_npc.TalkingNPC,key="npctalker",location=self.room1)
- self.call(talking_npc.CmdTalk(),"","(You walk up and talk to Char.)")
- npc.delete()
[docs]deftest_talkingnpc(self):
+ npc=create_object(talking_npc.TalkingNPC,key="npctalker",location=self.room1)
+ self.call(talking_npc.CmdTalk(),"","(You walk up and talk to Char.)")
+ npc.delete()
[docs]classGitCommand(MuxCommand):
+ """
+ The shared functionality between git/git evennia
+ """
+
+
[docs]defparse(self):
+ """
+ Parse the arguments, set default arg to 'status' and check for existence of currently targeted repo
+ """
+ super().parse()
+
+ ifself.args:
+ split_args=self.args.strip().split(" ",1)
+ self.action=split_args[0]
+ iflen(split_args)>1:
+ self.args=''.join(split_args[1:])
+ else:
+ self.args=''
+ else:
+ self.action="status"
+ self.args=""
+
+ self.err_msgs=["|rInvalid Git Repository|n:",
+ "The {repo_type} repository is not recognized as a git directory.",
+ "In order to initialize it as a git directory, you will need to access your terminal and run the following commands from within your directory:",
+ " git init",
+ " git remote add origin {remote_link}"]
+
+ try:
+ self.repo=git.Repo(self.directory,search_parent_directories=True)
+ exceptgit.exc.InvalidGitRepositoryError:
+ err_msg='\n'.join(self.err_msgs).format(repo_type=self.repo_type,remote_link=self.remote_link)
+ self.caller.msg(err_msg)
+ raiseInterruptCommand
+
+ self.commit=self.repo.head.commit
+
+ try:
+ self.branch=self.repo.active_branch.name
+ exceptTypeErrorastype_err:
+ self.caller.msg(type_err)
+ raiseInterruptCommand
+
+
[docs]defshort_sha(self,repo,hexsha):
+ """
+ Utility: Get the short SHA of a commit.
+ """
+ short_sha=repo.git.rev_parse(hexsha,short=True)
+ returnshort_sha
+
+
[docs]defget_status(self):
+ """
+ Retrieves the status of the active git repository, displaying unstaged changes/untracked files.
+ """
+ time_of_commit=datetime.datetime.fromtimestamp(self.commit.committed_date)
+ status_msg='\n'.join([f"Branch: |w{self.branch}|n ({self.repo.git.rev_parse(self.commit.hexsha,short=True)}) ({time_of_commit})",
+ f"By {self.commit.author.email}: {self.commit.message}"])
+
+ changedFiles={item.a_pathforiteminself.repo.index.diff(None)}
+ ifchangedFiles:
+ status_msg+=f"Unstaged/uncommitted changes:|/ |g{'|/ '.join(changedFiles)}|n|/"
+ iflen(self.repo.untracked_files)>0:
+ status_msg+=f"Untracked files:|/ |x{'|/ '.join(self.repo.untracked_files)}|n"
+ returnstatus_msg
+
+
[docs]defget_branches(self):
+ """
+ Display current and available branches.
+ """
+ remote_refs=self.repo.remote().refs
+ branch_msg=f"Current branch: |w{self.branch}|n. Branches available: {list_to_string(remote_refs)}"
+ returnbranch_msg
+
+
[docs]defcheckout(self):
+ """
+ Check out a specific branch.
+ """
+ remote_refs=self.repo.remote().refs
+ to_branch=self.args.strip().removeprefix('origin/')# Slightly hacky, but git tacks on the origin/
+
+ ifto_branchnotinremote_refs:
+ self.caller.msg(f"Branch '{to_branch}' not available.")
+ returnFalse
+ elifto_branch==self.branch:
+ self.caller.msg(f"Already on |w{to_branch}|n. Maybe you want <git pull>?")
+ returnFalse
+ else:
+ try:
+ self.repo.git.checkout(to_branch)
+ exceptgit.exc.GitCommandErroraserr:
+ self.caller.msg("Couldn't checkout {} ({})".format(to_branch,err.stderr.strip()))
+ returnFalse
+ self.msg(f"Checked out |w{to_branch}|n successfully. Server restart initiated.")
+ returnTrue
+
+
[docs]defpull(self):
+ """
+ Attempt to pull new code.
+ """
+ old_commit=self.commit
+ try:
+ self.repo.remotes.origin.pull()
+ exceptgit.exc.GitCommandErroraserr:
+ self.caller.msg("Couldn't pull {} ({})".format(self.branch,err.stderr.strip()))
+ returnFalse
+ ifold_commit==self.repo.head.commit:
+ self.caller.msg("No new code to pull, no need to reset.\n")
+ returnFalse
+ else:
+ self.caller.msg(f"You have pulled new code. Server restart initiated.|/Head now at {self.repo.git.rev_parse(self.repo.head.commit.hexsha,short=True)}.|/Author: {self.repo.head.commit.author.name} ({self.repo.head.commit.author.email})|/{self.repo.head.commit.message.strip()}")
+ returnTrue
+
+
[docs]deffunc(self):
+ """
+ Provide basic Git functionality within the game.
+ """
+ caller=self.caller
+
+ ifself.action=="status":
+ caller.msg(self.get_status())
+ elifself.action=="branch"or(self.action=="checkout"andnotself.args):
+ caller.msg(self.get_branches())
+ elifself.action=="checkout":
+ ifself.checkout():
+ SESSIONS.portal_restart_server()
+ elifself.action=="pull":
+ ifself.pull():
+ SESSIONS.portal_restart_server()
+ else:
+ caller.msg("You can only git status, git branch, git checkout, or git pull.")
+ return
+
+
[docs]classCmdGitEvennia(GitCommand):
+ """
+ Pull the latest code from the evennia core or checkout a different branch.
+
+ Usage:
+ git evennia status - View an overview of the evennia repository status.
+ git evennia branch - View available branches in evennia.
+ git evennia checkout <branch> - Checkout a different branch in evennia.
+ git evennia pull - Pull the latest evennia code.
+
+ For updating your local mygame repository, the same commands are available with 'git'.
+
+ If there are any conflicts encountered, the command will abort. The command will reload your game after pulling new code automatically, but for some changes involving persistent scripts etc, you may need to manually restart.
+ """
+
+ key="git evennia"
+ locks="cmd:pperm(Developer)"
+ help_category="System"
+ directory=settings.EVENNIA_DIR
+ repo_type="Evennia"
+ remote_link="https://github.com/evennia/evennia.git"
+
+
+
[docs]classCmdGit(GitCommand):
+ """
+ Pull the latest code from your repository or checkout a different branch.
+
+ Usage:
+ git status - View an overview of your git repository.
+ git branch - View available branches.
+ git checkout main - Checkout the main branch of your code.
+ git pull - Pull the latest code from your current branch.
+
+ For updating evennia code, the same commands are available with 'git evennia'.
+
+ If there are any conflicts encountered, the command will abort. The command will reload your game after pulling new code automatically, but for changes involving persistent scripts etc, you may need to manually restart.
+ """
+
+ key="git"
+ locks="cmd:pperm(Developer)"
+ help_category="System"
+ directory=settings.GAME_DIR
+ repo_type="game"
+ remote_link="[your remote link]"
[docs]deftest_git_checkout(self):
+ # Checkout no branch
+ self.test_cmd_git.checkout()
+ self.char1.msg.assert_called_with("Branch 'nonexistent_branch' not available.")
+
+
[docs]deftest_git_pull(self):
+ self.test_cmd_git.pull()
+ self.char1.msg.assert_called_with(f"You have pulled new code. Server restart initiated.|/Head now at {self.repo.git.rev_parse(self.repo.head.commit.hexsha,short=True)}.|/Author: {self.repo.head.commit.author.name} ({self.repo.head.commit.author.email})|/{self.repo.head.commit.message.strip()}")
+
+
+
\ No newline at end of file
diff --git a/docs/1.0-dev/_modules/evennia/contrib/utils/name_generator/namegen.html b/docs/1.0-dev/_modules/evennia/contrib/utils/name_generator/namegen.html
index 3d47d367af..ffd76e65b3 100644
--- a/docs/1.0-dev/_modules/evennia/contrib/utils/name_generator/namegen.html
+++ b/docs/1.0-dev/_modules/evennia/contrib/utils/name_generator/namegen.html
@@ -35,7 +35,41 @@
[docs]deftest_generate(self):
- """Generate and fail when exhausted."""
- generated=[]
- foriinrange(4):
- generated.append(SIMPLE_GENERATOR.get())
-
- generated.sort()
- self.assertEqual(generated,["00","01","10","11"])
-
- # At this point, we have generated 4 strings.
- # We can't generate one more
- withself.assertRaises(random_string_generator.ExhaustedGenerator):
- SIMPLE_GENERATOR.get()
[docs]deftest_generate(self):
+ """Generate and fail when exhausted."""
+ generated=[]
+ foriinrange(4):
+ generated.append(SIMPLE_GENERATOR.get())
+
+ generated.sort()
+ self.assertEqual(generated,["00","01","10","11"])
+
+ # At this point, we have generated 4 strings.
+ # We can't generate one more
+ withself.assertRaises(random_string_generator.ExhaustedGenerator):
+ SIMPLE_GENERATOR.get()
@@ -3174,47 +3208,30 @@
read for an error string instead. """
- traversing_object.msg(_("You cannot go there."))
+ traversing_object.msg(_("You cannot go there."))
+
+
[docs]defget_return_exit(self,return_all=False):
+ """
+ Get the exits that pair with this one in its destination room
+ (i.e. returns to its location)
+
+ Args:
+ return_all (bool): Whether to return available results as a
+ list or single matching exit.
+
+ Returns:
+ queryset or exit (Exit): The matching exit(s).
+ """
+ query=ObjectDB.objects.filter(db_location=self.destination,db_destination=self.location)
+ ifreturn_all:
+ returnquery
+ returnquery.first()
@@ -174,7 +208,7 @@
# attrs must be on form [(key, value, category, lockstr)]ifnotis_iter(attr):logger.log_error(
- "Prototype's 'attr' field must "f"be a list of tuples: {prototype}"
+ f"Prototype's 'attr' field must be a list of tuples: {prototype}")elifattr:nattr=len(attr)
@@ -279,8 +313,7 @@
forprotinprototype_list:ifnotisinstance(prot,dict):logger.log_err(
- f"Prototype read from {mod}.PROTOTYPE_LIST "
- f"is not a dict (skipping): {prot}"
+ f"Prototype read from {mod}.PROTOTYPE_LIST is not a dict (skipping): {prot}")continueelif"prototype_key"notinprot:
@@ -865,7 +898,7 @@
ifstrictandnot(typeclassorprototype_parent):ifis_prototype_base:_flags["errors"].append(
- _("Prototype {protkey} requires `typeclass` ""or 'prototype_parent'.").format(
+ _("Prototype {protkey} requires `typeclass` or 'prototype_parent'.").format(protkey=protkey))
@@ -908,8 +941,7 @@
ifnotprotparent:_flags["errors"].append(_(
- "Prototype {protkey}'s `prototype_parent` (named '{parent}') "
- "was not found."
+ "Prototype {protkey}'s `prototype_parent` (named '{parent}') was not found.").format(protkey=protkey,parent=protstring))
@@ -1001,7 +1033,7 @@
ifnotisinstance(value,str):returnvalue
- result=FUNC_PARSER.parse(value,raise_errors=True,return_str=False,caller=caller,**kwargs)
+ result=FUNC_PARSER.parse_to_any(value,raise_errors=True,caller=caller,**kwargs)returnresult
@@ -47,12 +81,13 @@
"""importshlex
-fromdjango.db.modelsimportF,Q,Count,ExpressionWrapper,FloatField
+
+fromdjango.db.modelsimportCount,ExpressionWrapper,F,FloatField,Qfromdjango.db.models.functionsimportCast
-fromevennia.utilsimportidmapper
-fromevennia.utils.utilsimportmake_iter,variable_from_modulefromevennia.typeclasses.attributesimportAttributefromevennia.typeclasses.tagsimportTag
+fromevennia.utilsimportidmapper
+fromevennia.utils.utilsimportclass_from_module,make_iter,variable_from_module__all__=("TypedObjectManager",)_GA=object.__getattribute__
@@ -238,6 +273,8 @@
query.append(("db_key",key))ifcategory:query.append(("db_category",category))
+ else:
+ query.append(("db_category",None))return_Tag.objects.filter(**dict(query))else:# search only among tags stored on on this model
@@ -579,15 +616,14 @@
[docs]deftypeclass_search(self,typeclass,include_children=False,include_parents=False):"""
- Searches through all objects returning those which has a
- certain typeclass. If location is set, limit search to objects
- in that location.
+ Searches through all objects returning those which are of the
+ specified typeclass. Args: typeclass (str or class): A typeclass class or a python path to a typeclass. include_children (bool, optional): Return objects with given typeclass *and* all children inheriting from this
- typeclass. Mutuall exclusive to `include_parents`.
+ typeclass. Mutually exclusive to `include_parents`. include_parents (bool, optional): Return objects with given typeclass *and* all parents to this typeclass. Mutually exclusive to `include_children`.
@@ -595,35 +631,28 @@
Returns: objects (list): The objects found with the given typeclasses.
+ Raises:
+ ImportError: If the provided `typeclass` is not a valid typeclass or the
+ path to an existing typeclass.
+
"""
-
- ifcallable(typeclass):
- cls=typeclass.__class__
- typeclass="%s.%s"%(cls.__module__,cls.__name__)
- elifnotisinstance(typeclass,str)andhasattr(typeclass,"path"):
- typeclass=typeclass.path
-
- # query objects of exact typeclass
- query=Q(db_typeclass_path__exact=typeclass)
+ ifnotcallable(typeclass):
+ typeclass=class_from_module(typeclass)ifinclude_children:
- # build requests for child typeclass objects
- clsmodule,clsname=typeclass.rsplit(".",1)
- cls=variable_from_module(clsmodule,clsname)
- subclasses=cls.__subclasses__()
- ifsubclasses:
- forchildin(childforchildinsubclassesifhasattr(child,"path")):
- query=query|Q(db_typeclass_path__exact=child.path)
- elifinclude_parents:
- # build requests for parent typeclass objects
- clsmodule,clsname=typeclass.rsplit(".",1)
- cls=variable_from_module(clsmodule,clsname)
- parents=cls.__mro__
+ query=typeclass.objects.all_family()
+ else:
+ query=typeclass.objects.all()
+
+ ifinclude_parents:
+ parents=typeclass.__mro__ifparents:
+ parent_queries=[]forparentin(parentforparentinparentsifhasattr(parent,"path")):
- query=query|Q(db_typeclass_path__exact=parent.path)
- # actually query the database
- returnsuper().filter(query)
[docs]classContainer:
@@ -242,16 +277,27 @@
initialized. """
+ ifself.loaded_data:
+ # we don't always load this, it collides with doc generation
+ global_BASE_SCRIPT_TYPECLASS
+ ifnot_BASE_SCRIPT_TYPECLASS:
+ _BASE_SCRIPT_TYPECLASS=class_from_module(settings.BASE_SCRIPT_TYPECLASS)
+
ifself.typeclass_storageisNone:self.typeclass_storage={}
- forkey,datainself.loaded_data.items():
+ forkey,datainlist(self.loaded_data.items()):try:typeclass=data.get("typeclass",settings.BASE_SCRIPT_TYPECLASS)
- self.typeclass_storage[key]=class_from_module(typeclass)
+ script_typeclass=class_from_module(typeclass)
+ assertissubclass(script_typeclass,_BASE_SCRIPT_TYPECLASS)
+ self.typeclass_storage[key]=script_typeclassexceptException:logger.log_trace(
- f"GlobalScriptContainer could not start import global script {key}."
- )
+ f"GlobalScriptContainer could not start import global script {key}. "
+ "It will be removed (skipped)."
+ )
+ # Let's remove this key/value. We want to let other scripts load.
+ self.loaded_data.pop(key)
@@ -396,7 +430,6 @@
ifcurr_func:# we are starting a nested funcdef
- return_str=Trueiflen(callstack)>_MAX_NESTING:# stack full - ignore this functionifraise_errors:
@@ -629,7 +662,9 @@
returnfullstr
[docs]defparse_to_any(
+ self,string,raise_errors=False,escape=False,strip=False,**reserved_kwargs
+ ):""" This parses a string and if the string only contains a "$func(...)", the return will be the return value of that function, even if it's not
@@ -641,6 +676,10 @@
raise_errors (bool, optional): If unset, leave a failing (or unrecognized) inline function as unparsed in the string. If set, raise an ParsingError.
+ escape (bool, optional): If set, escape all found functions so they
+ are not executed by later parsing.
+ strip (bool, optional): If set, strip any inline funcs from string
+ as if they were not there. **reserved_kwargs: If given, these are guaranteed to _always_ pass as part of each parsed callable's **kwargs. These override same-named default options given in `__init__` as well as any
@@ -677,9 +716,9 @@
"""returnself.parse(string,
- raise_errors=False,
- escape=False,
- strip=False,
+ raise_errors=raise_errors,
+ escape=escape,
+ strip=strip,return_str=False,**reserved_kwargs,)
@@ -835,7 +874,7 @@
num,*significant=argssignificant=significant[0]ifsignificantelse0try:
- round(num,significant)
+ returnround(num,significant)exceptException:ifkwargs.get("raise_errors"):raise
@@ -903,20 +942,33 @@
Args: listing (list): A list of items to randomly choose between. This will be converted from a string to a real list.
+ *args: If multiple args are given, will pick one randomly from them. Returns: any: The randomly chosen element. Example:
- - `$choice([key, flower, house])`
+ - `$choice(key, flower, house)` - `$choice([1, 2, 3, 4])` """ifnotargs:return""
- args,_=safe_convert_to_types(("py",{}),*args,**kwargs)
+
+ nargs=len(args)
+ ifnargs==1:
+ # this needs to be a list/tuple for this to make sense
+ args,_=safe_convert_to_types(("py",{}),args[0],**kwargs)
+ args=make_iter(args[0])ifargselseNone
+ else:
+ # separate arg per entry
+ converters=["py"for_inrange(nargs)]
+ args,_=safe_convert_to_types((converters,{}),*args,**kwargs)
+
+ ifnotargs:
+ return""try:
- returnrandom.choice(args[0])
+ returnrandom.choice(args)exceptException:ifkwargs.get("raise_errors"):raise
@@ -1130,7 +1182,9 @@
security. If called without session, the call is aborted. Args:
- query (str): The key or dbref to search for.
+ query (str): The key or dbref to search for. This can consist of any args used
+ for one of the regular search methods. Also kwargs will be passed into
+ the search (except the kwargs given below) Keyword Args: return_list (bool): If set, return a list of objects with
@@ -1141,6 +1195,7 @@
The 'control' permission is required. access (str): Which locktype access to check. Unset to disable the security check.
+ **kwargs: Will be passed into the main search. Returns: any: An entity match or None if no match or a list if `return_list` is set.
@@ -1153,30 +1208,38 @@
- "$search(#233)" - "$search(Tom, type=account)" - "$search(meadow, return_list=True)"
+ - "$search(beach, category=outdoors, type=tag) """
- return_list=kwargs.get("return_list","false").lower()=="true"
+ # clean out funcparser-specific kwargs so we can use the kwargs for
+ # searching
+ search_kwargs={
+ key:value
+ forkey,valueinkwargs.items()
+ ifkeynotin("funcparser","raise_errors","type","return_list")
+ }
+ return_list=str(kwargs.pop("return_list","false")).lower()=="true"ifnotargs:return[]ifreturn_listelseNoneifnotcaller:raiseParsingError("$search requires a `caller` passed to the parser.")
- query=str(args[0])
-
typ=kwargs.get("type","obj")targets=[]iftyp=="obj":
- targets=search.search_object(query)
+ targets=search.search_object(*args,**search_kwargs)eliftyp=="account":
- targets=search.search_account(query)
+ targets=search.search_account(*args,**search_kwargs)eliftyp=="script":
- targets=search.search_script(query)
+ targets=search.search_script(*args,**search_kwargs)
+ eliftyp=="tag":
+ targets=search.search_object_by_tag(*args,**search_kwargs)ifnottargets:ifreturn_list:return[]
- raiseParsingError(f"$search: Query '{query}' gave no matches.")
+ raiseParsingError(f"$search: Query '{args[0]}' gave no matches.")iflen(targets)>1andnotreturn_list:raiseParsingError(
@@ -1185,7 +1248,7 @@
)fortargetintargets:
- ifnottarget.access(caller,target,access):
+ ifnottarget.access(caller,access):raiseParsingError("$search Cannot add found entity - access failure.")returnlist(targets)ifreturn_listelsetargets[0]
@@ -83,6 +117,7 @@
"search_script_tag","search_account_tag","search_channel_tag",
+ "search_typeclass",)
@@ -404,46 +439,44 @@
# search for tag objects (not the objects they are attached tosearch_tag_object=ObjectDB.objects.get_tag
+
+
+# Locate Objects by Typeclass
+
+# search_objects_by_typeclass(typeclass="", include_children=False, include_parents=False) (also search_typeclass works)
+# This returns the objects of the given typeclass
+
+
+defsearch_objects_by_typeclass(typeclass,include_children=False,include_parents=False):
+ """
+ Searches through all objects returning those of a certain typeclass.
+
+ Args:
+ typeclass (str or class): A typeclass class or a python path to a typeclass.
+ include_children (bool, optional): Return objects with
+ given typeclass *and* all children inheriting from this
+ typeclass. Mutuall exclusive to `include_parents`.
+ include_parents (bool, optional): Return objects with
+ given typeclass *and* all parents to this typeclass.
+ Mutually exclusive to `include_children`.
+
+ Returns:
+ objects (list): The objects found with the given typeclasses.
+ """
+ returnObjectDB.objects.typeclass_search(
+ typeclass=typeclass,
+ include_children=include_children,
+ include_parents=include_parents,
+ )
+
+
+search_typeclass=search_objects_by_typeclass
@@ -130,8 +164,10 @@
re.S|re.M|re.I,)re_url=re.compile(
- r'(?<!=")((?:ftp|www|https?)\W+(?:(?!\.(?:\s|$)|&\w+;)[^"\',;$*^\\(){}<>\[\]\s])+)(\.(?:\s|$)|&\w+;|)'
+ r'(?<!=")(\b(?:ftp|www|https?)\W+(?:(?!\.(?:\s|$)|&\w+;)[^"\',;$*^\\(){}<>\[\]\s])+)(\.(?:\s|$)|&\w+;|)')
+ re_protocol=re.compile(r'^(?:ftp|https?)://')
+ re_valid_no_protocol=re.compile(r'^(?:www|ftp)\.[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b[-a-zA-Z0-9@:%_\+.~#?&//=]*')re_mxplink=re.compile(r"\|lc(.*?)\|lt(.*?)\|le",re.DOTALL)re_mxpurl=re.compile(r"\|lu(.*?)\|lt(.*?)\|le",re.DOTALL)
@@ -189,9 +225,22 @@
text (str): Processed text. """
- # -> added target to output prevent the web browser from attempting to
- # change pages (and losing our webclient session).
- returnself.re_url.sub(r'<a href="\1" target="_blank">\1</a>\2',text)
+ m=self.re_url.search(text)
+ ifm:
+ href=m.group(1)
+ label=href
+ # if there is no protocol (i.e. starts with www or ftp)
+ # prefix with http:// so the link isn't treated as relative
+ ifnotself.re_protocol.match(href):
+ ifnotself.re_valid_no_protocol.match(href):
+ returntext
+ href="http://"+href
+ rest=m.group(2)
+ # -> added target to output prevent the web browser from attempting to
+ # change pages (and losing our webclient session).
+ returntext[:m.start()]+f'<a href="{href}" target="_blank">{label}</a>{rest}'+text[m.end():]
+ else:
+ returntext
[docs]defstr2int(number):
+ """
+ Converts a string to an integer.
+
+ Args:
+ number (str): The string to convert. It can be a digit such as "1", or a number word such as "one".
+
+ Returns:
+ int: The string represented as an integer.
+ """
+ number=str(number)
+ original_input=number
+ try:
+ # it's a digit already
+ returnint(number)
+ except:
+ # if it's an ordinal number such as "1st", it'll convert to int with the last two characters chopped off
+ try:
+ returnint(number[:-2])
+ except:
+ pass
+
+ # convert sound changes for generic ordinal numbers
+ ifnumber[-2:]=="th":
+ # remove "th"
+ number=number[:-2]
+ ifnumber[-1]=="f":
+ # e.g. twelfth, fifth
+ number=number[:-1]+"ve"
+ elifnumber[-2:]=="ie":
+ # e.g. twentieth, fortieth
+ number=number[:-2]+"y"
+ # custom case for ninth
+ elifnumber[-3:]=="nin":
+ number+="e"
+
+ ifi:=_STR2INT_MAP.get(number):
+ # it's a single number, return it
+ returni
+
+ # remove optional "and"s
+ number=number.replace(" and "," ")
+
+ # split number words by spaces, hyphens and commas, to accommodate multiple styles
+ numbers=[word.lower()forwordinre.split(r"[-\s\,]",number)ifword]
+ sums=[]
+ forwordinnumbers:
+ # check if it's a known number-word
+ ifi:=_STR2INT_MAP.get(word):
+ ifnotlen(sums):
+ # initialize the list with the current value
+ sums=[i]
+ else:
+ # if the previous number was smaller, it's a multiplier
+ # e.g. the "two" in "two hundred"
+ ifsums[-1]<i:
+ sums[-1]=sums[-1]*i
+ # otherwise, it's added on, like the "five" in "twenty five"
+ else:
+ sums.append(i)
+ elifi:=_STR2INT_ADJS.get(word):
+ # it's a special adj word; ordinal case will never be a multiplier
+ sums.append(i)
+ else:
+ # invalid number-word, raise ValueError
+ raiseValueError(f"String {original_input} cannot be converted to int.")
+ returnsum(sums)
Source code for evennia.utils.verb_conjugation.pronouns
-"""
-English pronoun mapping between 1st/2nd person and 3rd person perspective (and vice-versa).
-
-This file is released under the Evennia regular BSD License.
-(Griatch 2021)
-
-Pronouns are words you use instead of a proper name, such as 'him', 'herself', 'theirs' etc. These
-look different depending on who sees the outgoing string. This mapping maps between 1st/2nd case and
-the 3rd person case and back. In some cases, the mapping is not unique; it is assumed the system can
-differentiate between the options in some other way.
-
-
-==================== ======= ======== ========== ========== ===========
-viewpoint/pronouns Subject Object Possessive Possessive Reflexive
- Pronoun Pronoun Adjective Pronoun Pronoun
-==================== ======= ======== ========== ========== ===========
-1st person I me my mine myself
-1st person plural we us our ours ourselves
-2nd person you you your yours yourself
-2nd person plural you you your yours yourselves
-
-3rd person male he him his his himself
-3rd person female she her her hers herself
-3rd person neutral it it its theirs* itself
-3rd person plural they them their theirs themselves
-==================== ======= ======== ========== ========== ===========
-
-> `*`) Not formally used, we use `theirs` here as a filler.
-
-"""
-fromevennia.utils.utilsimportcopy_word_case
-
-DEFAULT_PRONOUN_TYPE="object_pronoun"
-DEFAULT_VIEWPOINT="2nd person"
-DEFAULT_GENDER="neutral"
-
-PRONOUN_MAPPING={
- # 1st/2nd person -> 3rd person mappings
- "I":{"subject pronoun":{"3rd person":{"male":"he","female":"she","neutral":"it"}}},
- "me":{"object pronoun":{"3rd person":{"male":"him","female":"her","neutral":"it"}}},
- "my":{
- "possessive adjective":{"3rd person":{"male":"his","female":"her","neutral":"its"}}
- },
- "mine":{
- "possessive pronoun":{
- "3rd person":{
- "male":"his",
- "female":"hers",
- "neutral":"theirs",# colloqial,
- }
- }
- },
- "myself":{
- "reflexive_pronoun":{
- "3rd person":{
- "male":"himself",
- "female":"herself",
- "neutral":"itself",
- "plural":"themselves",
- }
- }
- },
- "you":{
- "subject pronoun":{
- "3rd person":{
- "male":"he",
- "female":"she",
- "neutral":"it",
- "plural":"they",
- }
- },
- "object pronoun":{
- "3rd person":{
- "male":"him",
- "female":"her",
- "neutral":"it",
- "plural":"them",
- }
- },
- },
- "your":{
- "possessive adjective":{
- "3rd person":{
- "male":"his",
- "female":"her",
- "neutral":"its",
- "plural":"their",
- }
- }
- },
- "yours":{
- "possessive pronoun":{
- "3rd person":{
- "male":"his",
- "female":"hers",
- "neutral":"theirs",# colloqial
- "plural":"theirs",
- }
- }
- },
- "yourself":{
- "reflexive_pronoun":{
- "3rd person":{
- "male":"himself",
- "female":"herself",
- "neutral":"itself",
- }
- }
- },
- "we":{"subject pronoun":{"3rd person":{"plural":"they"}}},
- "us":{"object pronoun":{"3rd person":{"plural":"them"}}},
- "our":{"possessive adjective":{"3rd person":{"plural":"their"}}},
- "ours":{"possessive pronoun":{"3rd person":{"plural":"theirs"}}},
- "ourselves":{"reflexive pronoun":{"3rd person":{"plural":"themselves"}}},
- "ours":{"possessive pronoun":{"3rd person":{"plural":"theirs"}}},
- "ourselves":{"reflexive pronoun":{"3rd person":{"plural":"themselves"}}},
- "yourselves":{"reflexive_pronoun":{"3rd person":{"plural":"themselves"}}},
- # 3rd person to 1st/second person mappings
- "he":{
- "subject pronoun":{
- "1st person":{"neutral":"I","plural":"we"},# pluralis majestatis
- "2nd person":{"neutral":"you","plural":"you"},# pluralis majestatis
- }
- },
- "him":{
- "object pronoun":{
- "1st person":{"neutral":"me","plural":"us"},# pluralis majestatis
- "2nd person":{"neutral":"you","plural":"you"},# pluralis majestatis
- }
- },
- "his":{
- "possessive adjective":{
- "1st person":{"neutral":"my","plural":"our"},# pluralis majestatis
- "2nd person":{"neutral":"your","plural":"your"},# pluralis majestatis
- },
- "possessive pronoun":{
- "1st person":{"neutral":"mine","plural":"ours"},# pluralis majestatis
- "2nd person":{"neutral":"yours","plural":"yours"},# pluralis majestatis
- },
- },
- "himself":{
- "reflexive pronoun":{
- "1st person":{"neutral":"myself","plural":"ourselves"},# pluralis majestatis
- "2nd person":{"neutral":"yours","plural":"yours"},# pluralis majestatis
- },
- },
- "she":{
- "subject pronoun":{
- "1st person":{"neutral":"I","plural":"you"},# pluralis majestatis
- "2nd person":{"neutral":"you","plural":"we"},# pluralis majestatis
- }
- },
- "her":{
- "object pronoun":{
- "1st person":{"neutral":"me","plural":"us"},# pluralis majestatis
- "2nd person":{"neutral":"you","plural":"you"},# pluralis majestatis
- },
- "possessive adjective":{
- "1st person":{"neutral":"my","plural":"our"},# pluralis majestatis
- "2nd person":{"neutral":"your","plural":"your"},# pluralis majestatis
- },
- },
- "hers":{
- "possessive pronoun":{
- "1st person":{"neutral":"mine","plural":"ours"},# pluralis majestatis
- "2nd person":{"neutral":"yours","plural":"yours"},# pluralis majestatis
- }
- },
- "herself":{
- "reflexive pronoun":{
- "1st person":{"neutral":"myself","plural":"ourselves"},# pluralis majestatis
- "2nd person":{"neutral":"yourself","plural":"yourselves"},# pluralis majestatis
- },
- },
- "it":{
- "subject pronoun":{
- "1st person":{"neutral":"I","plural":"we"},# pluralis majestatis
- "2nd person":{"neutral":"you","plural":"you"},# pluralis majestatis
- },
- "object pronoun":{
- "1st person":{"neutral":"me","plural":"us"},# pluralis majestatis
- "2nd person":{"neutral":"you","plural":"you"},# pluralis majestatis
- },
- },
- "its":{
- "possessive adjective":{
- "1st person":{"neutral":"my","plural":"our"},# pluralis majestatis
- "2nd person":{"neutral":"your","plural":"your"},# pluralis majestatis
- }
- },
- "theirs":{
- "possessive pronoun":{
- "1st person":{"neutral":"mine","plural":"ours"},# pluralis majestatis
- "2nd person":{"neutral":"yours","plural":"yours"},# pluralis majestatis
- }
- },
- "itself":{
- "reflexive pronoun":{
- "1st person":{"neutral":"myself","plural":"ourselves"},# pluralis majestatis
- "2nd person":{"neutral":"yourself","plural":"yourselves"},# pluralis majestatis
- },
- },
- "they":{
- "subject pronoun":{
- "1st person":{
- "plural":"we",
- },
- "2nd person":{
- "plural":"you",
- },
- }
- },
- "them":{
- "object pronoun":{
- "1st person":{
- "plural":"us",
- },
- "2nd person":{
- "plural":"you",
- },
- }
- },
- "their":{
- "possessive adjective":{
- "1st person":{
- "plural":"our",
- },
- "2nd person":{
- "plural":"your",
- },
- }
- },
- "themselves":{
- "reflexive pronoun":{
- "1st person":{
- "plural":"ourselves",
- },
- "2nd person":{
- "plural":"yourselves",
- },
- }
- },
-}
-
-
-ALIASES={
- "m":"male",
- "f":"female",
- "n":"neutral",
- "p":"plural",
- "1st":"1st person",
- "2nd":"2nd person",
- "3rd":"3rd person",
- "1":"1st person",
- "2":"2nd person",
- "3":"3rd person",
- "s":"subject pronoun",
- "sp":"subject pronoun",
- "subject":"subject pronoun",
- "op":"object pronoun",
- "object":"object pronoun",
- "pa":"possessive adjective",
- "pp":"possessive pronoun",
-}
-
-PRONOUN_TYPES=[
- "subject pronoun",
- "object pronoun",
- "possessive adjective",
- "possessive pronoun",
- "reflexive pronoun",
-]
-VIEWPOINTS=["1st person","2nd person","3rd person"]
-GENDERS=["male","female","neutral","plural"]# including plural as a gender for simplicity
-
-
-
[docs]defpronoun_to_viewpoints(
- pronoun,options=None,pronoun_type="object_pronoun",gender="neutral",viewpoint="2nd person"
-):
- """
- Access function for determining the forms of a pronount from different viewpoints.
-
- Args:
- pronoun (str): A valid English pronoun, such as 'you', 'his', 'themselves' etc.
- options (str or list, optional): A list or space-separated string of options to help
- the engine when there is no unique mapping to use. This could for example
- be "2nd female" (alias 'f') or "possessive adjective" (alias 'pa' or 'a').
- pronoun_type (str, optional): An explicit object pronoun to separate cases where
- there is no unique mapping. Pronoun types defined in `options` take precedence.
- Values are
-
- - `subject pronoun`/`subject`/`sp` (I, you, he, they)
- - `object pronoun`/`object/`/`op` (me, you, him, them)
- - `possessive adjective`/`adjective`/`pa` (my, your, his, their)
- - `possessive pronoun`/`pronoun`/`pp` (mine, yours, his, theirs)
-
- gender (str, optional): Specific gender to use (plural counts a gender for this purpose).
- A gender specified in `options` takes precedence. Values and aliases are:
-
- - `male`/`m`
- - `female`/`f`
- - `neutral`/`n`
- - `plural`/`p`
-
- viewpoint (str, optional): A specified viewpoint of the one talking, to use
- when there is no unique mapping. A viewpoint given in `options` take
- precedence. Values and aliases are:
-
- - `1st person`/`1st`/`1`
- - `2nd person`/`2nd`/`2`
- - `3rd person`/`3rd`/`3`
-
- Returns:
- tuple: A tuple `(1st/2nd_person_pronoun, 3rd_person_pronoun)` to show to the one sending the
- string and others respectively. If pronoun is invalid, the word is returned verbatim.
-
- Note:
- The capitalization of the original word will be retained.
-
- """
- ifnotpronoun:
- returnpronoun
-
- pronoun_lower="I"ifpronoun=="I"elsepronoun.lower()
-
- ifpronoun_lowernotinPRONOUN_MAPPING:
- returnpronoun
-
- # differentiators
-
- ifpronoun_typenotinPRONOUN_TYPES:
- pronoun_type=DEFAULT_PRONOUN_TYPE
- ifviewpointnotinVIEWPOINTS:
- viewpoint=DEFAULT_VIEWPOINT
- ifgendernotinGENDERS:
- gender=DEFAULT_GENDER
-
- ifoptions:
- # option string/list will override the kwargs differentiators given
- ifisinstance(options,str):
- options=options.split()
- options=[str(part).strip().lower()forpartinoptions]
- options=[ALIASES.get(opt,opt)foroptinoptions]
-
- foroptinoptions:
- ifoptinPRONOUN_TYPES:
- pronoun_type=opt
- elifoptinVIEWPOINTS:
- viewpoint=opt
- elifoptinGENDERS:
- gender=opt
-
- # step down into the mapping, using differentiators as needed
- pronoun_types=PRONOUN_MAPPING[pronoun_lower]
- # this has one or more pronoun-types
- iflen(pronoun_types)==1:
- pronoun_type,viewpoints=next(iter(pronoun_types.items()))
- elifpronoun_typeinpronoun_types:
- viewpoints=pronoun_types[pronoun_type]
- elifDEFAULT_PRONOUN_TYPEinpronoun_types:
- pronoun_type=DEFAULT_PRONOUN_TYPE
- viewpoints=pronoun_types[pronoun_type]
- else:
- # not enough info - grab the first of the mappings
- pronoun_type,viewpoints=next(iter(pronoun_types.items()))
-
- # we have one or more viewpoints at this point
- iflen(viewpoints)==1:
- viewpoint,genders=next(iter(viewpoints.items()))
- elifviewpointinviewpoints:
- genders=viewpoints[viewpoint]
- elifDEFAULT_VIEWPOINTinviewpoints:
- viewpoint=DEFAULT_VIEWPOINT
- genders=viewpoints[viewpoint]
- else:
- # not enough info - grab first of mappings
- viewpoint,genders=next(iter(viewpoints.items()))
-
- # we have one or more possible genders (including plural forms)
- iflen(genders)==1:
- gender,mapped_pronoun=next(iter(genders.items()))
- elifgenderingenders:
- mapped_pronoun=genders[gender]
- elifDEFAULT_GENDERingenders:
- gender=DEFAULT_GENDER
- mapped_pronoun=genders[gender]
- else:
- # not enough info - grab first mapping
- gender,mapped_pronoun=next(iter(genders.items()))
-
- # keep the same capitalization as the original
- ifpronoun!="I":
- # don't remap I, since this is always capitalized.
- mapped_pronoun=copy_word_case(pronoun,mapped_pronoun)
- ifmapped_pronoun=="i":
- mapped_pronoun=mapped_pronoun.upper()
-
- ifviewpoint=="3rd person":
- # the remapped viewpoing is in 3rd person, meaning the ingoing viewpoing
- # must have been 1st or 2nd person.
- returnpronoun,mapped_pronoun
- else:
- # the remapped viewpoint is 1st or 2nd person, so ingoing must have been
- # in 3rd person form.
- returnmapped_pronoun,pronoun
[docs]defpronoun_to_viewpoints(
+ pronoun,options=None,pronoun_type=DEFAULT_PRONOUN_TYPE,gender=DEFAULT_GENDER,viewpoint=DEFAULT_VIEWPOINT
+):
+ """
+ Access function for determining the forms of a pronount from different viewpoints.
+
+ Args:
+ pronoun (str): A valid English pronoun, such as 'you', 'his', 'themselves' etc.
+ options (str or list, optional): A list or space-separated string of options to help
+ the engine when there is no unique mapping to use. This could for example
+ be "2nd female" (alias 'f') or "possessive adjective" (alias 'pa' or 'a').
+ pronoun_type (str, optional): An explicit object pronoun to separate cases where
+ there is no unique mapping. Pronoun types defined in `options` take precedence.
+ Values are
+
+ - `subject pronoun`/`subject`/`sp` (I, you, he, they)
+ - `object pronoun`/`object/`/`op` (me, you, him, them)
+ - `possessive adjective`/`adjective`/`pa` (my, your, his, their)
+ - `possessive pronoun`/`pronoun`/`pp` (mine, yours, his, theirs)
+
+ gender (str, optional): Specific gender to use (plural counts a gender for this purpose).
+ A gender specified in `options` takes precedence. Values and aliases are:
+
+ - `male`/`m`
+ - `female`/`f`
+ - `neutral`/`n`
+ - `plural`/`p`
+
+ viewpoint (str, optional): A specified viewpoint of the one talking, to use
+ when there is no unique mapping. A viewpoint given in `options` take
+ precedence. Values and aliases are:
+
+ - `1st person`/`1st`/`1`
+ - `2nd person`/`2nd`/`2`
+ - `3rd person`/`3rd`/`3`
+
+ Returns:
+ tuple: A tuple `(1st/2nd_person_pronoun, 3rd_person_pronoun)` to show to the one sending the
+ string and others respectively. If pronoun is invalid, the word is returned verbatim.
+
+ Note:
+ The capitalization of the original word will be retained.
+
+ """
+ ifnotpronoun:
+ returnpronoun
+
+ pronoun_lower="I"ifpronoun=="I"elsepronoun.lower()
+
+ ifpronoun_lowernotinPRONOUN_TABLE:
+ returnpronoun
+
+ # get the default data for the input pronoun
+ source_viewpoint,source_gender,source_type=PRONOUN_TABLE[pronoun_lower]
+
+ # differentiators
+ ifpronoun_typenotinPRONOUN_TYPES:
+ pronoun_type=DEFAULT_PRONOUN_TYPE
+ ifviewpointnotinVIEWPOINTS:
+ viewpoint=DEFAULT_VIEWPOINT
+ ifgendernotinGENDERS:
+ gender=DEFAULT_GENDER
+
+ ifoptions:
+ # option string/list will override the kwargs differentiators given
+ ifisinstance(options,str):
+ options=options.split()
+ options=[str(part).strip().lower()forpartinoptions]
+ options=[ALIASES.get(opt,opt)foroptinoptions]
+
+ foroptinoptions:
+ ifoptinPRONOUN_TYPES:
+ pronoun_type=opt
+ elifoptinVIEWPOINTS:
+ viewpoint=opt
+ elifoptinGENDERS:
+ gender=opt
+
+ # check if pronoun maps to multiple options and differentiate
+ # but don't allow invalid differentiators
+ ifis_iter(source_type):
+ pronoun_type=pronoun_typeifpronoun_typeinsource_typeelsesource_type[0]
+ else:
+ pronoun_type=source_type
+ target_viewpoint=VIEWPOINT_CONVERSION[source_viewpoint]
+ ifis_iter(target_viewpoint):
+ viewpoint=viewpointifviewpointintarget_viewpointelsetarget_viewpoint[0]
+ else:
+ viewpoint=target_viewpoint
+
+ # special handling for the royal "we"
+ ifis_iter(source_gender):
+ gender_opts=list(source_gender)
+ else:
+ gender_opts=[source_gender]
+ ifviewpoint=="1st person":
+ # make sure plural is always an option when converting to 1st person
+ # it doesn't matter if it's in the list twice, so don't bother checking
+ gender_opts.append("plural")
+ # if the gender is still not in the extended options, fall back to source pronoun's default
+ gender=genderifgenderingender_optselsegender_opts[0]
+
+ # step down into the mapping
+ viewpoint_map=PRONOUN_MAPPING[viewpoint]
+ pronouns=viewpoint_map.get(pronoun_type,viewpoint_map[DEFAULT_PRONOUN_TYPE])
+ mapped_pronoun=pronouns.get(gender,pronouns[DEFAULT_GENDER])
+
+ # keep the same capitalization as the original
+ ifpronoun!="I":
+ # don't remap I, since this is always capitalized.
+ mapped_pronoun=copy_word_case(pronoun,mapped_pronoun)
+ ifmapped_pronoun=="i":
+ mapped_pronoun=mapped_pronoun.upper()
+
+ ifviewpoint=="3rd person":
+ # the desired viewpoint is 3rd person, meaning the incoming viewpoint
+ # must have been 1st or 2nd person.
+ returnpronoun,mapped_pronoun
+ else:
+ # the desired viewpoint is 1st or 2nd person, so incoming must have been
+ # in 3rd person form.
+ returnmapped_pronoun,pronoun
[docs]defadmin_wrapper(request):
- """
- Wrapper that allows us to properly use the base Django admin site, if needed.
-
- """
- returnstaff_member_required(site.index)(request)
[docs]defadmin_wrapper(request):
+ """
+ Wrapper that allows us to properly use the base Django admin site, if needed.
+
+ """
+ returnstaff_member_required(site.index)(request)
-"""
-
-This sets up how models are displayed
-in the web admin interface.
-
-"""
-
-fromdjango.contribimportadmin
-fromevennia.server.modelsimportServerConfig
-
-
-
+"""
+
+This sets up how models are displayed
+in the web admin interface.
+
+"""
+
+fromdjango.contribimportadmin
+fromevennia.server.modelsimportServerConfig
+
+
+
[docs]defto_be_implemented(request):
- """
- A notice letting the user know that this particular feature hasn't been
- implemented yet.
- """
-
- pagevars={"page_title":"To Be Implemented..."}
-
- returnrender(request,"tbi.html",pagevars)
[docs]defto_be_implemented(request):
+ """
+ A notice letting the user know that this particular feature hasn't been
+ implemented yet.
+ """
+
+ pagevars={"page_title":"To Be Implemented..."}
+
+ returnrender(request,"tbi.html",pagevars)
diff --git a/docs/1.0-dev/_sources/Coding/Changelog.md.txt b/docs/1.0-dev/_sources/Coding/Changelog.md.txt
index 5b5f2c62b9..2e27e93ed5 100644
--- a/docs/1.0-dev/_sources/Coding/Changelog.md.txt
+++ b/docs/1.0-dev/_sources/Coding/Changelog.md.txt
@@ -203,6 +203,8 @@ Up requirements to Django 4.0+, Twisted 22+, Python 3.9 or 3.10
- Add new setting `MAX_NR_SIMULTANEUS_PUPPETS` - how many puppets the account
can run at the same time. Used to limit multi-playing.
- Make setting `MAX_NR_CHARACTERS` interact better with the new settings above.
+- Allow `$search` funcparser func to search tags and to accept kwargs for more
+ powerful searches passed into the regular search functions.
## Evennia 0.9.5
diff --git a/docs/1.0-dev/_sources/Contribs/Contrib-Evadventure.md.txt b/docs/1.0-dev/_sources/Contribs/Contrib-Evadventure.md.txt
index edadac1c39..8e17091baa 100644
--- a/docs/1.0-dev/_sources/Contribs/Contrib-Evadventure.md.txt
+++ b/docs/1.0-dev/_sources/Contribs/Contrib-Evadventure.md.txt
@@ -2,6 +2,13 @@
Contrib by Griatch 2022
+
+```{warning}
+NOTE - this tutorial is WIP and NOT complete! It was put on hold to focus on
+releasing Evennia 1.0. You will still learn things from it, but don't expect
+perfection.
+```
+
A complete example MUD using Evennia. This is the final result of what is
implemented if you follow the Getting-Started tutorial. It's recommended
that you follow the tutorial step by step and write your own code. But if
diff --git a/docs/1.0-dev/_sources/Contribs/Contrib-Git-Integration.md.txt b/docs/1.0-dev/_sources/Contribs/Contrib-Git-Integration.md.txt
new file mode 100644
index 0000000000..eb679df31f
--- /dev/null
+++ b/docs/1.0-dev/_sources/Contribs/Contrib-Git-Integration.md.txt
@@ -0,0 +1,73 @@
+# In-game Git Integration
+
+Contribution by helpme (2022)
+
+A module to integrate a stripped-down version of git within the game, allowing developers to view their git status, change branches, and pull updated code of both their local mygame repo and Evennia core. After a successful pull or checkout, the git command will reload the game: Manual restarts may be required to to apply certain changes that would impact persistent scripts etc.
+
+Once the contrib is set up, integrating remote changes is as simple as entering the following into your game:
+
+```
+git pull
+```
+
+The repositories you want to work with, be it only your local mygame repo, only Evennia core, or both, must be git directories for the command to function. If you are only interested in using this to get upstream Evennia changes, only the Evennia repository needs to be a git repository. [Get started with version control here.](https://www.evennia.com/docs/1.0-dev/Coding/Version-Control.html)
+
+## Dependencies
+
+This package requires the dependency "gitpython", a python library used to interact with git repositories. To install, it's easiest to install Evennia's extra requirements:
+
+- Activate your `virtualenv`
+- `cd` to the root of the Evennia repository. There should be an `requirements_extra.txt` file here.
+- `pip install -r requirements_extra.txt`
+
+## Installation
+
+This utility adds a simple assortment of 'git' commands. Import the module into your commands and add it to your command set to make it available.
+
+Specifically, in `mygame/commands/default_cmdsets.py`:
+
+```python
+...
+from evennia.contrib.utils.git_integration import GitCmdSet # <---
+
+class CharacterCmdset(default_cmds.Character_CmdSet):
+ ...
+ def at_cmdset_creation(self):
+ ...
+ self.add(GitCmdSet) # <---
+
+```
+
+Then `reload` to make the git command available.
+
+## Usage
+
+This utility will only work if the directory you wish to work with is a git directory. If they are not, you will be prompted to initiate your directory as a git repository using the following commands in your terminal:
+
+```
+git init
+git remote add origin 'link to your repository'
+```
+
+By default, the git commands are only available to those with Developer permissions and higher. You can change this by overriding the command and setting its locks from "cmd:pperm(Developer)" to the lock of your choice.
+
+The supported commands are:
+* git status: An overview of your git repository, which files have been changed locally, and the commit you're on.
+* git branch: What branches are available for you to check out.
+* git checkout 'branch': Checkout a branch.
+* git pull: Pull the latest code from your current branch.
+
+* All of these commands are also available with 'evennia', to serve the same functionality related to your Evennia directory. So:
+* git evennia status
+* git evennia branch
+* git evennia checkout 'branch'
+* git evennia pull: Pull the latest Evennia code.
+
+## Settings Used
+
+The utility uses the existing GAME_DIR and EVENNIA_DIR settings from settings.py. You should not need to alter these if you have a standard directory setup, they ought to exist without any setup required from you.
+
+----
+
+This document page is generated from `evennia/contrib/utils/git_integration/README.md`. Changes to this
+file will be overwritten, so edit that file rather than this one.
diff --git a/docs/1.0-dev/_sources/Contribs/Contrib-XYZGrid.md.txt b/docs/1.0-dev/_sources/Contribs/Contrib-XYZGrid.md.txt
index ab87a7fdaf..879b146336 100644
--- a/docs/1.0-dev/_sources/Contribs/Contrib-XYZGrid.md.txt
+++ b/docs/1.0-dev/_sources/Contribs/Contrib-XYZGrid.md.txt
@@ -53,28 +53,31 @@ Exits: northeast and east
(then go back to your mygame/ folder)
This will install all optional requirements of Evennia.
-2. Import and add the `evennia.contrib.commands.XYZGridCmdSet` to the
+2. Import and [add] the `evennia.contrib.grid.xyzgrid.commands.XYZGridCmdSet` to the
`CharacterCmdset` cmdset in `mygame/commands.default_cmds.py`. Reload
the server. This makes the `map`, `goto/path` and the modified `teleport` and
`open` commands available in-game.
+
+[add]: ../Components/Command-Sets
+
3. Edit `mygame/server/conf/settings.py` and add
- EXTRA_LAUNCHER_COMMANDS['xyzgrid'] = 'evennia.contrib.launchcmd.xyzcommand'
-
- and
-
- PROTOTYPE_MODULES += [’evennia.contrib.grid.xyzgrid.prototypes’]
+ EXTRA_LAUNCHER_COMMANDS['xyzgrid'] = 'evennia.contrib.grid.xyzgrid.launchcmd.xyzcommand'
+ PROTOTYPE_MODULES += ['evennia.contrib.grid.xyzgrid.prototypes']
This will add the new ability to enter `evennia xyzgrid
This sub-package defines the out-of-character entities known as
-Accounts. These are equivalent to ‘accounts’ and can puppet one or
-more Objects depending on settings. An Account has no in-game existence.
This sub-package defines the out-of-character entities known as
+Accounts. These are equivalent to ‘accounts’ and can puppet one or
+more Objects depending on settings. An Account has no in-game existence.
-search_index_entry = {'aliases': '@swap @parent @typeclasses @update @type', 'category': 'building', 'key': '@typeclass', 'no_prefix': 'typeclass swap parent typeclasses update type', 'tags': '', 'text': "\n set or change an object's typeclass\n\n Usage:\n typeclass[/switch] <object> [= typeclass.path]\n typeclass/prototype <object> = prototype_key\n\n typeclasses or typeclass/list/show [typeclass.path]\n swap - this is a shorthand for using /force/reset flags.\n update - this is a shorthand for using the /force/reload flag.\n\n Switch:\n show, examine - display the current typeclass of object (default) or, if\n given a typeclass path, show the docstring of that typeclass.\n update - *only* re-run at_object_creation on this object\n meaning locks or other properties set later may remain.\n reset - clean out *all* the attributes and properties on the\n object - basically making this a new clean object. This will also\n reset cmdsets!\n force - change to the typeclass also if the object\n already has a typeclass of the same name.\n list - show available typeclasses. Only typeclasses in modules actually\n imported or used from somewhere in the code will show up here\n (those typeclasses are still available if you know the path)\n prototype - clean and overwrite the object with the specified\n prototype key - effectively making a whole new object.\n\n Example:\n type button = examples.red_button.RedButton\n type/prototype button=a red button\n\n If the typeclass_path is not given, the current object's typeclass is\n assumed.\n\n View or set an object's typeclass. If setting, the creation hooks of the\n new typeclass will be run on the object. If you have clashing properties on\n the old class, use /reset. By default you are protected from changing to a\n typeclass of the same name as the one you already have - use /force to\n override this protection.\n\n The given typeclass must be identified by its location using python\n dot-notation pointing to the correct module and class. If no typeclass is\n given (or a wrong typeclass is given). Errors in the path or new typeclass\n will lead to the old typeclass being kept. The location of the typeclass\n module is searched from the default typeclass directory, as defined in the\n server settings.\n\n "}¶
+search_index_entry = {'aliases': '@typeclasses @swap @type @parent @update', 'category': 'building', 'key': '@typeclass', 'no_prefix': 'typeclass typeclasses swap type parent update', 'tags': '', 'text': "\n set or change an object's typeclass\n\n Usage:\n typeclass[/switch] <object> [= typeclass.path]\n typeclass/prototype <object> = prototype_key\n\n typeclasses or typeclass/list/show [typeclass.path]\n swap - this is a shorthand for using /force/reset flags.\n update - this is a shorthand for using the /force/reload flag.\n\n Switch:\n show, examine - display the current typeclass of object (default) or, if\n given a typeclass path, show the docstring of that typeclass.\n update - *only* re-run at_object_creation on this object\n meaning locks or other properties set later may remain.\n reset - clean out *all* the attributes and properties on the\n object - basically making this a new clean object. This will also\n reset cmdsets!\n force - change to the typeclass also if the object\n already has a typeclass of the same name.\n list - show available typeclasses. Only typeclasses in modules actually\n imported or used from somewhere in the code will show up here\n (those typeclasses are still available if you know the path)\n prototype - clean and overwrite the object with the specified\n prototype key - effectively making a whole new object.\n\n Example:\n type button = examples.red_button.RedButton\n type/prototype button=a red button\n\n If the typeclass_path is not given, the current object's typeclass is\n assumed.\n\n View or set an object's typeclass. If setting, the creation hooks of the\n new typeclass will be run on the object. If you have clashing properties on\n the old class, use /reset. By default you are protected from changing to a\n typeclass of the same name as the one you already have - use /force to\n override this protection.\n\n The given typeclass must be identified by its location using python\n dot-notation pointing to the correct module and class. If no typeclass is\n given (or a wrong typeclass is given). Errors in the path or new typeclass\n will lead to the old typeclass being kept. The location of the typeclass\n module is searched from the default typeclass directory, as defined in the\n server settings.\n\n "}¶
-search_index_entry = {'aliases': '@locate @search', 'category': 'building', 'key': '@find', 'no_prefix': 'find locate search', 'tags': '', 'text': '\n search the database for objects\n\n Usage:\n find[/switches] <name or dbref or *account> [= dbrefmin[-dbrefmax]]\n locate - this is a shorthand for using the /loc switch.\n\n Switches:\n room - only look for rooms (location=None)\n exit - only look for exits (destination!=None)\n char - only look for characters (BASE_CHARACTER_TYPECLASS)\n exact - only exact matches are returned.\n loc - display object location if exists and match has one result\n startswith - search for names starting with the string, rather than containing\n\n Searches the database for an object of a particular name or exact #dbref.\n Use *accountname to search for an account. The switches allows for\n limiting object matches to certain game entities. Dbrefmin and dbrefmax\n limits matches to within the given dbrefs range, or above/below if only\n one is given.\n '}¶
+search_index_entry = {'aliases': '@search @locate', 'category': 'building', 'key': '@find', 'no_prefix': 'find search locate', 'tags': '', 'text': '\n search the database for objects\n\n Usage:\n find[/switches] <name or dbref or *account> [= dbrefmin[-dbrefmax]]\n locate - this is a shorthand for using the /loc switch.\n\n Switches:\n room - only look for rooms (location=None)\n exit - only look for exits (destination!=None)\n char - only look for characters (BASE_CHARACTER_TYPECLASS)\n exact - only exact matches are returned.\n loc - display object location if exists and match has one result\n startswith - search for names starting with the string, rather than containing\n\n Searches the database for an object of a particular name or exact #dbref.\n Use *accountname to search for an account. The switches allows for\n limiting object matches to certain game entities. Dbrefmin and dbrefmax\n limits matches to within the given dbrefs range, or above/below if only\n one is given.\n '}¶
@@ -2233,57 +2280,10 @@ displays a list of available prototypes.
-
This is the cmdset for Account (OOC) commands. These are
-stored on the Account object and should thus be able to handle getting
-an Account object as caller rather than a Character.
-
Note - in order for session-rerouting (in MULTISESSION_MODE=2) to
-function, all commands in this cmdset should use the self.msg()
-command method rather than caller.msg().
This is the cmdset for Account (OOC) commands. These are
+stored on the Account object and should thus be able to handle getting
+an Account object as caller rather than a Character.
+
Note - in order for session-rerouting (in MULTISESSION_MODE=2) to
+function, all commands in this cmdset should use the self.msg()
+command method rather than caller.msg().
This module ties together all the commands default Character objects have
-available (i.e. IC commands). Note that some commands, such as
-communication-commands are instead put on the account level, in the
-Account cmdset. Account commands remain available also to Characters.
This module ties together all the commands default Character objects have
+available (i.e. IC commands). Note that some commands, such as
+communication-commands are instead put on the account level, in the
+Account cmdset. Account commands remain available also to Characters.
This module describes the unlogged state of the default game.
-The setting STATE_UNLOGGED should be set to the python path
-of the state instance in this module.
This module describes the unlogged state of the default game.
+The setting STATE_UNLOGGED should be set to the python path
+of the state instance in this module.
-search_index_entry = {'aliases': '@chan @channels', 'category': 'comms', 'key': '@channel', 'no_prefix': 'channel chan channels', 'tags': '', 'text': "\n Use and manage in-game channels.\n\n Usage:\n channel channelname <msg>\n channel channel name = <msg>\n channel (show all subscription)\n channel/all (show available channels)\n channel/alias channelname = alias[;alias...]\n channel/unalias alias\n channel/who channelname\n channel/history channelname [= index]\n channel/sub channelname [= alias[;alias...]]\n channel/unsub channelname[,channelname, ...]\n channel/mute channelname[,channelname,...]\n channel/unmute channelname[,channelname,...]\n\n channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n channel/desc channelname = description\n channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n channel/ban channelname (list bans)\n channel/ban[/quiet] channelname[, channelname, ...] = subscribername [: reason]\n channel/unban[/quiet] channelname[, channelname, ...] = subscribername\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n\n # subtopics\n\n ## sending\n\n Usage: channel channelname msg\n channel channel name = msg (with space in channel name)\n\n This sends a message to the channel. Note that you will rarely use this\n command like this; instead you can use the alias\n\n channelname <msg>\n channelalias <msg>\n\n For example\n\n public Hello World\n pub Hello World\n\n (this shortcut doesn't work for aliases containing spaces)\n\n See channel/alias for help on setting channel aliases.\n\n ## alias and unalias\n\n Usage: channel/alias channel = alias[;alias[;alias...]]\n channel/unalias alias\n channel - this will list your subs and aliases to each channel\n\n Set one or more personal aliases for referencing a channel. For example:\n\n channel/alias warrior's guild = warrior;wguild;warchannel;warrior guild\n\n You can now send to the channel using all of these:\n\n warrior's guild Hello\n warrior Hello\n wguild Hello\n warchannel Hello\n\n Note that this will not work if the alias has a space in it. So the\n 'warrior guild' alias must be used with the `channel` command:\n\n channel warrior guild = Hello\n\n Channel-aliases can be removed one at a time, using the '/unalias' switch.\n\n ## who\n\n Usage: channel/who channelname\n\n List the channel's subscribers. Shows who are currently offline or are\n muting the channel. Subscribers who are 'muting' will not see messages sent\n to the channel (use channel/mute to mute a channel).\n\n ## history\n\n Usage: channel/history channel [= index]\n\n This will display the last |c20|n lines of channel history. By supplying an\n index number, you will step that many lines back before viewing those 20 lines.\n\n For example:\n\n channel/history public = 35\n\n will go back 35 lines and show the previous 20 lines from that point (so\n lines -35 to -55).\n\n ## sub and unsub\n\n Usage: channel/sub channel [=alias[;alias;...]]\n channel/unsub channel\n\n This subscribes you to a channel and optionally assigns personal shortcuts\n for you to use to send to that channel (see aliases). When you unsub, all\n your personal aliases will also be removed.\n\n ## mute and unmute\n\n Usage: channel/mute channelname\n channel/unmute channelname\n\n Muting silences all output from the channel without actually\n un-subscribing. Other channel members will see that you are muted in the /who\n list. Sending a message to the channel will automatically unmute you.\n\n ## create and destroy\n\n Usage: channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n\n Creates a new channel (or destroys one you control). You will automatically\n join the channel you create and everyone will be kicked and loose all aliases\n to a destroyed channel.\n\n ## lock and unlock\n\n Usage: channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n\n Note: this is an admin command.\n\n A lockstring is on the form locktype:lockfunc(). Channels understand three\n locktypes:\n listen - who may listen or join the channel.\n send - who may send messages to the channel\n control - who controls the channel. This is usually the one creating\n the channel.\n\n Common lockfuncs are all() and perm(). To make a channel everyone can\n listen to but only builders can talk on, use this:\n\n listen:all()\n send: perm(Builders)\n\n ## boot and ban\n\n Usage:\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n channel/ban channelname[, channelname, ...] = subscribername [: reason]\n channel/unban channelname[, channelname, ...] = subscribername\n channel/unban channelname\n channel/ban channelname (list bans)\n\n Booting will kick a named subscriber from channel(s) temporarily. The\n 'reason' will be passed to the booted user. Unless the /quiet switch is\n used, the channel will also be informed of the action. A booted user is\n still able to re-connect, but they'll have to set up their aliases again.\n\n Banning will blacklist a user from (re)joining the provided channels. It\n will then proceed to boot them from those channels if they were connected.\n The 'reason' and `/quiet` works the same as for booting.\n\n Example:\n boot mychannel1 = EvilUser : Kicking you to cool down a bit.\n ban mychannel1,mychannel2= EvilUser : Was banned for spamming.\n\n "}¶
+search_index_entry = {'aliases': '@channels @chan', 'category': 'comms', 'key': '@channel', 'no_prefix': 'channel channels chan', 'tags': '', 'text': "\n Use and manage in-game channels.\n\n Usage:\n channel channelname <msg>\n channel channel name = <msg>\n channel (show all subscription)\n channel/all (show available channels)\n channel/alias channelname = alias[;alias...]\n channel/unalias alias\n channel/who channelname\n channel/history channelname [= index]\n channel/sub channelname [= alias[;alias...]]\n channel/unsub channelname[,channelname, ...]\n channel/mute channelname[,channelname,...]\n channel/unmute channelname[,channelname,...]\n\n channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n channel/desc channelname = description\n channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n channel/ban channelname (list bans)\n channel/ban[/quiet] channelname[, channelname, ...] = subscribername [: reason]\n channel/unban[/quiet] channelname[, channelname, ...] = subscribername\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n\n # subtopics\n\n ## sending\n\n Usage: channel channelname msg\n channel channel name = msg (with space in channel name)\n\n This sends a message to the channel. Note that you will rarely use this\n command like this; instead you can use the alias\n\n channelname <msg>\n channelalias <msg>\n\n For example\n\n public Hello World\n pub Hello World\n\n (this shortcut doesn't work for aliases containing spaces)\n\n See channel/alias for help on setting channel aliases.\n\n ## alias and unalias\n\n Usage: channel/alias channel = alias[;alias[;alias...]]\n channel/unalias alias\n channel - this will list your subs and aliases to each channel\n\n Set one or more personal aliases for referencing a channel. For example:\n\n channel/alias warrior's guild = warrior;wguild;warchannel;warrior guild\n\n You can now send to the channel using all of these:\n\n warrior's guild Hello\n warrior Hello\n wguild Hello\n warchannel Hello\n\n Note that this will not work if the alias has a space in it. So the\n 'warrior guild' alias must be used with the `channel` command:\n\n channel warrior guild = Hello\n\n Channel-aliases can be removed one at a time, using the '/unalias' switch.\n\n ## who\n\n Usage: channel/who channelname\n\n List the channel's subscribers. Shows who are currently offline or are\n muting the channel. Subscribers who are 'muting' will not see messages sent\n to the channel (use channel/mute to mute a channel).\n\n ## history\n\n Usage: channel/history channel [= index]\n\n This will display the last |c20|n lines of channel history. By supplying an\n index number, you will step that many lines back before viewing those 20 lines.\n\n For example:\n\n channel/history public = 35\n\n will go back 35 lines and show the previous 20 lines from that point (so\n lines -35 to -55).\n\n ## sub and unsub\n\n Usage: channel/sub channel [=alias[;alias;...]]\n channel/unsub channel\n\n This subscribes you to a channel and optionally assigns personal shortcuts\n for you to use to send to that channel (see aliases). When you unsub, all\n your personal aliases will also be removed.\n\n ## mute and unmute\n\n Usage: channel/mute channelname\n channel/unmute channelname\n\n Muting silences all output from the channel without actually\n un-subscribing. Other channel members will see that you are muted in the /who\n list. Sending a message to the channel will automatically unmute you.\n\n ## create and destroy\n\n Usage: channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n\n Creates a new channel (or destroys one you control). You will automatically\n join the channel you create and everyone will be kicked and loose all aliases\n to a destroyed channel.\n\n ## lock and unlock\n\n Usage: channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n\n Note: this is an admin command.\n\n A lockstring is on the form locktype:lockfunc(). Channels understand three\n locktypes:\n listen - who may listen or join the channel.\n send - who may send messages to the channel\n control - who controls the channel. This is usually the one creating\n the channel.\n\n Common lockfuncs are all() and perm(). To make a channel everyone can\n listen to but only builders can talk on, use this:\n\n listen:all()\n send: perm(Builders)\n\n ## boot and ban\n\n Usage:\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n channel/ban channelname[, channelname, ...] = subscribername [: reason]\n channel/unban channelname[, channelname, ...] = subscribername\n channel/unban channelname\n channel/ban channelname (list bans)\n\n Booting will kick a named subscriber from channel(s) temporarily. The\n 'reason' will be passed to the booted user. Unless the /quiet switch is\n used, the channel will also be informed of the action. A booted user is\n still able to re-connect, but they'll have to set up their aliases again.\n\n Banning will blacklist a user from (re)joining the provided channels. It\n will then proceed to boot them from those channels if they were connected.\n The 'reason' and `/quiet` works the same as for booting.\n\n Example:\n boot mychannel1 = EvilUser : Kicking you to cool down a bit.\n ban mychannel1,mychannel2= EvilUser : Was banned for spamming.\n\n "}¶
@@ -886,7 +933,7 @@ ban mychannel1,mychannel2= EvilUser : Was banned for spamming.
@@ -906,7 +953,7 @@ ban mychannel1,mychannel2= EvilUser : Was banned for spamming.
-search_index_entry = {'aliases': '@chan @channels', 'category': 'comms', 'key': '@channel', 'no_prefix': 'channel chan channels', 'tags': '', 'text': "\n Use and manage in-game channels.\n\n Usage:\n channel channelname <msg>\n channel channel name = <msg>\n channel (show all subscription)\n channel/all (show available channels)\n channel/alias channelname = alias[;alias...]\n channel/unalias alias\n channel/who channelname\n channel/history channelname [= index]\n channel/sub channelname [= alias[;alias...]]\n channel/unsub channelname[,channelname, ...]\n channel/mute channelname[,channelname,...]\n channel/unmute channelname[,channelname,...]\n\n channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n channel/desc channelname = description\n channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n channel/ban channelname (list bans)\n channel/ban[/quiet] channelname[, channelname, ...] = subscribername [: reason]\n channel/unban[/quiet] channelname[, channelname, ...] = subscribername\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n\n # subtopics\n\n ## sending\n\n Usage: channel channelname msg\n channel channel name = msg (with space in channel name)\n\n This sends a message to the channel. Note that you will rarely use this\n command like this; instead you can use the alias\n\n channelname <msg>\n channelalias <msg>\n\n For example\n\n public Hello World\n pub Hello World\n\n (this shortcut doesn't work for aliases containing spaces)\n\n See channel/alias for help on setting channel aliases.\n\n ## alias and unalias\n\n Usage: channel/alias channel = alias[;alias[;alias...]]\n channel/unalias alias\n channel - this will list your subs and aliases to each channel\n\n Set one or more personal aliases for referencing a channel. For example:\n\n channel/alias warrior's guild = warrior;wguild;warchannel;warrior guild\n\n You can now send to the channel using all of these:\n\n warrior's guild Hello\n warrior Hello\n wguild Hello\n warchannel Hello\n\n Note that this will not work if the alias has a space in it. So the\n 'warrior guild' alias must be used with the `channel` command:\n\n channel warrior guild = Hello\n\n Channel-aliases can be removed one at a time, using the '/unalias' switch.\n\n ## who\n\n Usage: channel/who channelname\n\n List the channel's subscribers. Shows who are currently offline or are\n muting the channel. Subscribers who are 'muting' will not see messages sent\n to the channel (use channel/mute to mute a channel).\n\n ## history\n\n Usage: channel/history channel [= index]\n\n This will display the last |c20|n lines of channel history. By supplying an\n index number, you will step that many lines back before viewing those 20 lines.\n\n For example:\n\n channel/history public = 35\n\n will go back 35 lines and show the previous 20 lines from that point (so\n lines -35 to -55).\n\n ## sub and unsub\n\n Usage: channel/sub channel [=alias[;alias;...]]\n channel/unsub channel\n\n This subscribes you to a channel and optionally assigns personal shortcuts\n for you to use to send to that channel (see aliases). When you unsub, all\n your personal aliases will also be removed.\n\n ## mute and unmute\n\n Usage: channel/mute channelname\n channel/unmute channelname\n\n Muting silences all output from the channel without actually\n un-subscribing. Other channel members will see that you are muted in the /who\n list. Sending a message to the channel will automatically unmute you.\n\n ## create and destroy\n\n Usage: channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n\n Creates a new channel (or destroys one you control). You will automatically\n join the channel you create and everyone will be kicked and loose all aliases\n to a destroyed channel.\n\n ## lock and unlock\n\n Usage: channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n\n Note: this is an admin command.\n\n A lockstring is on the form locktype:lockfunc(). Channels understand three\n locktypes:\n listen - who may listen or join the channel.\n send - who may send messages to the channel\n control - who controls the channel. This is usually the one creating\n the channel.\n\n Common lockfuncs are all() and perm(). To make a channel everyone can\n listen to but only builders can talk on, use this:\n\n listen:all()\n send: perm(Builders)\n\n ## boot and ban\n\n Usage:\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n channel/ban channelname[, channelname, ...] = subscribername [: reason]\n channel/unban channelname[, channelname, ...] = subscribername\n channel/unban channelname\n channel/ban channelname (list bans)\n\n Booting will kick a named subscriber from channel(s) temporarily. The\n 'reason' will be passed to the booted user. Unless the /quiet switch is\n used, the channel will also be informed of the action. A booted user is\n still able to re-connect, but they'll have to set up their aliases again.\n\n Banning will blacklist a user from (re)joining the provided channels. It\n will then proceed to boot them from those channels if they were connected.\n The 'reason' and `/quiet` works the same as for booting.\n\n Example:\n boot mychannel1 = EvilUser : Kicking you to cool down a bit.\n ban mychannel1,mychannel2= EvilUser : Was banned for spamming.\n\n "}¶
+search_index_entry = {'aliases': '@channels @chan', 'category': 'comms', 'key': '@channel', 'no_prefix': 'channel channels chan', 'tags': '', 'text': "\n Use and manage in-game channels.\n\n Usage:\n channel channelname <msg>\n channel channel name = <msg>\n channel (show all subscription)\n channel/all (show available channels)\n channel/alias channelname = alias[;alias...]\n channel/unalias alias\n channel/who channelname\n channel/history channelname [= index]\n channel/sub channelname [= alias[;alias...]]\n channel/unsub channelname[,channelname, ...]\n channel/mute channelname[,channelname,...]\n channel/unmute channelname[,channelname,...]\n\n channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n channel/desc channelname = description\n channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n channel/ban channelname (list bans)\n channel/ban[/quiet] channelname[, channelname, ...] = subscribername [: reason]\n channel/unban[/quiet] channelname[, channelname, ...] = subscribername\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n\n # subtopics\n\n ## sending\n\n Usage: channel channelname msg\n channel channel name = msg (with space in channel name)\n\n This sends a message to the channel. Note that you will rarely use this\n command like this; instead you can use the alias\n\n channelname <msg>\n channelalias <msg>\n\n For example\n\n public Hello World\n pub Hello World\n\n (this shortcut doesn't work for aliases containing spaces)\n\n See channel/alias for help on setting channel aliases.\n\n ## alias and unalias\n\n Usage: channel/alias channel = alias[;alias[;alias...]]\n channel/unalias alias\n channel - this will list your subs and aliases to each channel\n\n Set one or more personal aliases for referencing a channel. For example:\n\n channel/alias warrior's guild = warrior;wguild;warchannel;warrior guild\n\n You can now send to the channel using all of these:\n\n warrior's guild Hello\n warrior Hello\n wguild Hello\n warchannel Hello\n\n Note that this will not work if the alias has a space in it. So the\n 'warrior guild' alias must be used with the `channel` command:\n\n channel warrior guild = Hello\n\n Channel-aliases can be removed one at a time, using the '/unalias' switch.\n\n ## who\n\n Usage: channel/who channelname\n\n List the channel's subscribers. Shows who are currently offline or are\n muting the channel. Subscribers who are 'muting' will not see messages sent\n to the channel (use channel/mute to mute a channel).\n\n ## history\n\n Usage: channel/history channel [= index]\n\n This will display the last |c20|n lines of channel history. By supplying an\n index number, you will step that many lines back before viewing those 20 lines.\n\n For example:\n\n channel/history public = 35\n\n will go back 35 lines and show the previous 20 lines from that point (so\n lines -35 to -55).\n\n ## sub and unsub\n\n Usage: channel/sub channel [=alias[;alias;...]]\n channel/unsub channel\n\n This subscribes you to a channel and optionally assigns personal shortcuts\n for you to use to send to that channel (see aliases). When you unsub, all\n your personal aliases will also be removed.\n\n ## mute and unmute\n\n Usage: channel/mute channelname\n channel/unmute channelname\n\n Muting silences all output from the channel without actually\n un-subscribing. Other channel members will see that you are muted in the /who\n list. Sending a message to the channel will automatically unmute you.\n\n ## create and destroy\n\n Usage: channel/create channelname[;alias;alias[:typeclass]] [= description]\n channel/destroy channelname [= reason]\n\n Creates a new channel (or destroys one you control). You will automatically\n join the channel you create and everyone will be kicked and loose all aliases\n to a destroyed channel.\n\n ## lock and unlock\n\n Usage: channel/lock channelname = lockstring\n channel/unlock channelname = lockstring\n\n Note: this is an admin command.\n\n A lockstring is on the form locktype:lockfunc(). Channels understand three\n locktypes:\n listen - who may listen or join the channel.\n send - who may send messages to the channel\n control - who controls the channel. This is usually the one creating\n the channel.\n\n Common lockfuncs are all() and perm(). To make a channel everyone can\n listen to but only builders can talk on, use this:\n\n listen:all()\n send: perm(Builders)\n\n ## boot and ban\n\n Usage:\n channel/boot[/quiet] channelname[,channelname,...] = subscribername [: reason]\n channel/ban channelname[, channelname, ...] = subscribername [: reason]\n channel/unban channelname[, channelname, ...] = subscribername\n channel/unban channelname\n channel/ban channelname (list bans)\n\n Booting will kick a named subscriber from channel(s) temporarily. The\n 'reason' will be passed to the booted user. Unless the /quiet switch is\n used, the channel will also be informed of the action. A booted user is\n still able to re-connect, but they'll have to set up their aliases again.\n\n Banning will blacklist a user from (re)joining the provided channels. It\n will then proceed to boot them from those channels if they were connected.\n The 'reason' and `/quiet` works the same as for booting.\n\n Example:\n boot mychannel1 = EvilUser : Kicking you to cool down a bit.\n ban mychannel1,mychannel2= EvilUser : Was banned for spamming.\n\n "}¶
@@ -1273,57 +1320,10 @@ must be added to game settings.
-
@@ -251,7 +298,7 @@ for everyone to use, you need build privileges and the alias command.
-search_index_entry = {'aliases': 'nickname nicks', 'category': 'general', 'key': 'nick', 'no_prefix': ' nickname nicks', 'tags': '', 'text': '\n define a personal alias/nick by defining a string to\n match and replace it with another on the fly\n\n Usage:\n nick[/switches] <string> [= [replacement_string]]\n nick[/switches] <template> = <replacement_template>\n nick/delete <string> or number\n nicks\n\n Switches:\n inputline - replace on the inputline (default)\n object - replace on object-lookup\n account - replace on account-lookup\n list - show all defined aliases (also "nicks" works)\n delete - remove nick by index in /list\n clearall - clear all nicks\n\n Examples:\n nick hi = say Hello, I\'m Sarah!\n nick/object tom = the tall man\n nick build $1 $2 = create/drop $1;$2\n nick tell $1 $2=page $1=$2\n nick tm?$1=page tallman=$1\n nick tm\\=$1=page tallman=$1\n\n A \'nick\' is a personal string replacement. Use $1, $2, ... to catch arguments.\n Put the last $-marker without an ending space to catch all remaining text. You\n can also use unix-glob matching for the left-hand side <string>:\n\n * - matches everything\n ? - matches 0 or 1 single characters\n [abcd] - matches these chars in any order\n [!abcd] - matches everything not among these chars\n \\= - escape literal \'=\' you want in your <string>\n\n Note that no objects are actually renamed or changed by this command - your nicks\n are only available to you. If you want to permanently add keywords to an object\n for everyone to use, you need build privileges and the alias command.\n\n '}¶
+search_index_entry = {'aliases': 'nicks nickname', 'category': 'general', 'key': 'nick', 'no_prefix': ' nicks nickname', 'tags': '', 'text': '\n define a personal alias/nick by defining a string to\n match and replace it with another on the fly\n\n Usage:\n nick[/switches] <string> [= [replacement_string]]\n nick[/switches] <template> = <replacement_template>\n nick/delete <string> or number\n nicks\n\n Switches:\n inputline - replace on the inputline (default)\n object - replace on object-lookup\n account - replace on account-lookup\n list - show all defined aliases (also "nicks" works)\n delete - remove nick by index in /list\n clearall - clear all nicks\n\n Examples:\n nick hi = say Hello, I\'m Sarah!\n nick/object tom = the tall man\n nick build $1 $2 = create/drop $1;$2\n nick tell $1 $2=page $1=$2\n nick tm?$1=page tallman=$1\n nick tm\\=$1=page tallman=$1\n\n A \'nick\' is a personal string replacement. Use $1, $2, ... to catch arguments.\n Put the last $-marker without an ending space to catch all remaining text. You\n can also use unix-glob matching for the left-hand side <string>:\n\n * - matches everything\n ? - matches 0 or 1 single characters\n [abcd] - matches these chars in any order\n [!abcd] - matches everything not among these chars\n \\= - escape literal \'=\' you want in your <string>\n\n Note that no objects are actually renamed or changed by this command - your nicks\n are only available to you. If you want to permanently add keywords to an object\n for everyone to use, you need build privileges and the alias command.\n\n '}¶
@@ -763,57 +810,10 @@ which permission groups you are a member of.
-
@@ -680,7 +727,7 @@ to all the variables defined therein.
-search_index_entry = {'aliases': '@delays @task', 'category': 'system', 'key': '@tasks', 'no_prefix': 'tasks delays task', 'tags': '', 'text': "\n Display or terminate active tasks (delays).\n\n Usage:\n tasks[/switch] [task_id or function_name]\n\n Switches:\n pause - Pause the callback of a task.\n unpause - Process all callbacks made since pause() was called.\n do_task - Execute the task (call its callback).\n call - Call the callback of this task.\n remove - Remove a task without executing it.\n cancel - Stop a task from automatically executing.\n\n Notes:\n A task is a single use method of delaying the call of a function. Calls are created\n in code, using `evennia.utils.delay`.\n See |luhttps://www.evennia.com/docs/latest/Command-Duration.html|ltthe docs|le for help.\n\n By default, tasks that are canceled and never called are cleaned up after one minute.\n\n Examples:\n - `tasks/cancel move_callback` - Cancels all movement delays from the slow_exit contrib.\n In this example slow exits creates it's tasks with\n `utils.delay(move_delay, move_callback)`\n - `tasks/cancel 2` - Cancel task id 2.\n\n "}¶
+search_index_entry = {'aliases': '@task @delays', 'category': 'system', 'key': '@tasks', 'no_prefix': 'tasks task delays', 'tags': '', 'text': "\n Display or terminate active tasks (delays).\n\n Usage:\n tasks[/switch] [task_id or function_name]\n\n Switches:\n pause - Pause the callback of a task.\n unpause - Process all callbacks made since pause() was called.\n do_task - Execute the task (call its callback).\n call - Call the callback of this task.\n remove - Remove a task without executing it.\n cancel - Stop a task from automatically executing.\n\n Notes:\n A task is a single use method of delaying the call of a function. Calls are created\n in code, using `evennia.utils.delay`.\n See |luhttps://www.evennia.com/docs/latest/Command-Duration.html|ltthe docs|le for help.\n\n By default, tasks that are canceled and never called are cleaned up after one minute.\n\n Examples:\n - `tasks/cancel move_callback` - Cancels all movement delays from the slow_exit contrib.\n In this example slow exits creates it's tasks with\n `utils.delay(move_delay, move_callback)`\n - `tasks/cancel 2` - Cancel task id 2.\n\n "}¶
@@ -740,57 +787,10 @@ to all the variables defined therein.
-
@@ -108,7 +155,7 @@ there is no object yet before the account has logged in)
-search_index_entry = {'aliases': 'con co conn', 'category': 'general', 'key': 'connect', 'no_prefix': ' con co conn', 'tags': '', 'text': '\n connect to the game\n\n Usage (at login screen):\n connect accountname password\n connect "account name" "pass word"\n\n Use the create command to first create an account before logging in.\n\n If you have spaces in your name, enclose it in double quotes.\n '}¶
+search_index_entry = {'aliases': 'co conn con', 'category': 'general', 'key': 'connect', 'no_prefix': ' co conn con', 'tags': '', 'text': '\n connect to the game\n\n Usage (at login screen):\n connect accountname password\n connect "account name" "pass word"\n\n Use the create command to first create an account before logging in.\n\n If you have spaces in your name, enclose it in double quotes.\n '}¶
-search_index_entry = {'aliases': 'cr cre', 'category': 'general', 'key': 'create', 'no_prefix': ' cr cre', 'tags': '', 'text': '\n create a new account account\n\n Usage (at login screen):\n create <accountname> <password>\n create "account name" "pass word"\n\n This creates a new account account.\n\n If you have spaces in your name, enclose it in double quotes.\n '}¶
+search_index_entry = {'aliases': 'cre cr', 'category': 'general', 'key': 'create', 'no_prefix': ' cre cr', 'tags': '', 'text': '\n create a new account account\n\n Usage (at login screen):\n create <accountname> <password>\n create "account name" "pass word"\n\n This creates a new account account.\n\n If you have spaces in your name, enclose it in double quotes.\n '}¶
@@ -187,7 +234,7 @@ version is a bit more complicated.
@@ -213,7 +260,7 @@ version is a bit more complicated.
-search_index_entry = {'aliases': 'qu q', 'category': 'general', 'key': 'quit', 'no_prefix': ' qu q', 'tags': '', 'text': '\n quit when in unlogged-in state\n\n Usage:\n quit\n\n We maintain a different version of the quit command\n here for unconnected accounts for the sake of simplicity. The logged in\n version is a bit more complicated.\n '}¶
+search_index_entry = {'aliases': 'q qu', 'category': 'general', 'key': 'quit', 'no_prefix': ' q qu', 'tags': '', 'text': '\n quit when in unlogged-in state\n\n Usage:\n quit\n\n We maintain a different version of the quit command\n here for unconnected accounts for the sake of simplicity. The logged in\n version is a bit more complicated.\n '}¶
@@ -286,7 +333,7 @@ for simplicity. It shows a pane of info.
@@ -312,7 +359,7 @@ for simplicity. It shows a pane of info.
-search_index_entry = {'aliases': '? h', 'category': 'general', 'key': 'help', 'no_prefix': ' ? h', 'tags': '', 'text': '\n get help when in unconnected-in state\n\n Usage:\n help\n\n This is an unconnected version of the help command,\n for simplicity. It shows a pane of info.\n '}¶
+search_index_entry = {'aliases': 'h ?', 'category': 'general', 'key': 'help', 'no_prefix': ' h ?', 'tags': '', 'text': '\n get help when in unconnected-in state\n\n Usage:\n help\n\n This is an unconnected version of the help command,\n for simplicity. It shows a pane of info.\n '}¶
@@ -470,57 +517,10 @@ logged in, use option screenreader on).
-
This sub-package contains Evennia’s command system. It handles
-everything related to parsing input from the account, building cmdsets
-and executing the code associated with a found command class.
-
commands.default contains all the default “mux-like” commands of
-Evennia.
This sub-package contains Evennia’s command system. It handles
+everything related to parsing input from the account, building cmdsets
+and executing the code associated with a found command class.
+
commands.default contains all the default “mux-like” commands of
+Evennia.
This sub-package contains Evennia’s comms-system, a set of models and
-handlers for in-game communication via channels and messages as well
-as code related to external communication like IRC or RSS.
This sub-package contains Evennia’s comms-system, a set of models and
+handlers for in-game communication via channels and messages as well
+as code related to external communication like IRC or RSS.
Note: Normally this would be tested by importing the ansi parser and run
-the mappings through it. This is not possible since the ansi module creates
-its mapping at the module/class level; since the ansi module is used by so
-many other modules it appears that trying to overload
-settings to test it causes issues with unrelated tests.
Note: Normally this would be tested by importing the ansi parser and run
+the mappings through it. This is not possible since the ansi module creates
+its mapping at the module/class level; since the ansi module is used by so
+many other modules it appears that trying to overload
+settings to test it causes issues with unrelated tests.
Component Attribute Descriptor.
-Allows you to set attributes related to a component on the class.
-It uses AttributeProperty under the hood but prefixes the key with the component name.
Component In-Memory Attribute Descriptor.
-Allows you to set in-memory attributes related to a component on the class.
-It uses NAttributeProperty under the hood but prefixes the key with the component name.
Component Tags Descriptor.
-Allows you to set Tags related to a component on the class.
-The tags are set with a prefixed category, so it can support
-multiple tags or enforce a single one.
-
Default value of a tag is added when the component is registered.
-Tags are removed if the component itself is removed.
Component Attribute Descriptor.
+Allows you to set attributes related to a component on the class.
+It uses AttributeProperty under the hood but prefixes the key with the component name.
Component In-Memory Attribute Descriptor.
+Allows you to set in-memory attributes related to a component on the class.
+It uses NAttributeProperty under the hood but prefixes the key with the component name.
Component Tags Descriptor.
+Allows you to set Tags related to a component on the class.
+The tags are set with a prefixed category, so it can support
+multiple tags or enforce a single one.
+
Default value of a tag is added when the component is registered.
+Tags are removed if the component itself is removed.
This is a basic Component System.
-It allows you to use components on typeclasses using a simple syntax.
-This helps writing isolated code and reusing it over multiple objects.
This is a basic Component System.
+It allows you to use components on typeclasses using a simple syntax.
+This helps writing isolated code and reusing it over multiple objects.
This is the text to show the user when they first connect to the game (before
-they log in).
-
To change the login screen in this module, do one of the following:
-
-
Define a function connection_screen(), taking no arguments. This will be
-called first and must return the full string to act as the connection screen.
-This can be used to produce more dynamic screens.
-
Alternatively, define a string variable in the outermost scope of this module
-with the connection string that should be displayed. If more than one such
-variable is given, Evennia will pick one of them at random.
-
-
The commands available to the user when the connection screen is shown
-are defined in evennia.default_cmds.UnloggedinCmdSet. The parsing and display
-of the screen is done by the unlogged-in “look” command.
This is the text to show the user when they first connect to the game (before
+they log in).
+
To change the login screen in this module, do one of the following:
+
+
Define a function connection_screen(), taking no arguments. This will be
+called first and must return the full string to act as the connection screen.
+This can be used to produce more dynamic screens.
+
Alternatively, define a string variable in the outermost scope of this module
+with the connection string that should be displayed. If more than one such
+variable is given, Evennia will pick one of them at random.
+
+
The commands available to the user when the connection screen is shown
+are defined in evennia.default_cmds.UnloggedinCmdSet. The parsing and display
+of the screen is done by the unlogged-in “look” command.
@@ -120,7 +167,7 @@ there is no object yet before the account has logged in)
-search_index_entry = {'aliases': 'con co conn', 'category': 'general', 'key': 'connect', 'no_prefix': ' con co conn', 'tags': '', 'text': '\n Connect to the game.\n\n Usage (at login screen):\n connect <email> <password>\n\n Use the create command to first create an account before logging in.\n '}¶
+search_index_entry = {'aliases': 'co conn con', 'category': 'general', 'key': 'connect', 'no_prefix': ' co conn con', 'tags': '', 'text': '\n Connect to the game.\n\n Usage (at login screen):\n connect <email> <password>\n\n Use the create command to first create an account before logging in.\n '}¶
@@ -142,7 +189,7 @@ there is no object yet before the account has logged in)
@@ -223,7 +270,7 @@ version is a bit more complicated.
-search_index_entry = {'aliases': 'qu q', 'category': 'general', 'key': 'quit', 'no_prefix': ' qu q', 'tags': '', 'text': '\n We maintain a different version of the `quit` command\n here for unconnected accounts for the sake of simplicity. The logged in\n version is a bit more complicated.\n '}¶
+search_index_entry = {'aliases': 'q qu', 'category': 'general', 'key': 'quit', 'no_prefix': ' q qu', 'tags': '', 'text': '\n We maintain a different version of the `quit` command\n here for unconnected accounts for the sake of simplicity. The logged in\n version is a bit more complicated.\n '}¶
@@ -286,7 +333,7 @@ for simplicity. It shows a pane of info.
@@ -312,7 +359,7 @@ for simplicity. It shows a pane of info.
-search_index_entry = {'aliases': '? h', 'category': 'general', 'key': 'help', 'no_prefix': ' ? h', 'tags': '', 'text': '\n This is an unconnected version of the help command,\n for simplicity. It shows a pane of info.\n '}¶
+search_index_entry = {'aliases': 'h ?', 'category': 'general', 'key': 'help', 'no_prefix': ' h ?', 'tags': '', 'text': '\n This is an unconnected version of the help command,\n for simplicity. It shows a pane of info.\n '}¶
@@ -320,57 +367,10 @@ for simplicity. It shows a pane of info.
-
-search_index_entry = {'aliases': 'delaliaschan delchanalias', 'category': 'comms', 'key': 'delcom', 'no_prefix': ' delaliaschan delchanalias', 'tags': '', 'text': "\n remove a channel alias and/or unsubscribe from channel\n\n Usage:\n delcom <alias or channel>\n delcom/all <channel>\n\n If the full channel name is given, unsubscribe from the\n channel. If an alias is given, remove the alias but don't\n unsubscribe. If the 'all' switch is used, remove all aliases\n for that channel.\n "}¶
+search_index_entry = {'aliases': 'delchanalias delaliaschan', 'category': 'comms', 'key': 'delcom', 'no_prefix': ' delchanalias delaliaschan', 'tags': '', 'text': "\n remove a channel alias and/or unsubscribe from channel\n\n Usage:\n delcom <alias or channel>\n delcom/all <channel>\n\n If the full channel name is given, unsubscribe from the\n channel. If an alias is given, remove the alias but don't\n unsubscribe. If the 'all' switch is used, remove all aliases\n for that channel.\n "}¶
-search_index_entry = {'aliases': 'quit chicken out q abort', 'category': 'evscaperoom', 'key': 'give up', 'no_prefix': ' quit chicken out q abort', 'tags': '', 'text': '\n Give up\n\n Usage:\n give up\n\n Abandons your attempts at escaping and of ever winning the pie-eating contest.\n\n '}¶
+search_index_entry = {'aliases': 'q abort chicken out quit', 'category': 'evscaperoom', 'key': 'give up', 'no_prefix': ' q abort chicken out quit', 'tags': '', 'text': '\n Give up\n\n Usage:\n give up\n\n Abandons your attempts at escaping and of ever winning the pie-eating contest.\n\n '}¶
-search_index_entry = {'aliases': 'ex examine unfocus e', 'category': 'evscaperoom', 'key': 'focus', 'no_prefix': ' ex examine unfocus e', 'tags': '', 'text': '\n Focus your attention on a target.\n\n Usage:\n focus <obj>\n\n Once focusing on an object, use look to get more information about how it\n looks and what actions is available.\n\n '}¶
+search_index_entry = {'aliases': 'unfocus examine ex e', 'category': 'evscaperoom', 'key': 'focus', 'no_prefix': ' unfocus examine ex e', 'tags': '', 'text': '\n Focus your attention on a target.\n\n Usage:\n focus <obj>\n\n Once focusing on an object, use look to get more information about how it\n looks and what actions is available.\n\n '}¶
@@ -722,7 +769,7 @@ try to influence the other part in the deal.
-search_index_entry = {'aliases': 'deal offers', 'category': 'trading', 'key': 'status', 'no_prefix': ' deal offers', 'tags': '', 'text': "\n show a list of the current deal\n\n Usage:\n status\n deal\n offers\n\n Shows the currently suggested offers on each sides of the deal. To\n accept the current deal, use the 'accept' command. Use 'offer' to\n change your deal. You might also want to use 'say', 'emote' etc to\n try to influence the other part in the deal.\n "}¶
+search_index_entry = {'aliases': 'offers deal', 'category': 'trading', 'key': 'status', 'no_prefix': ' offers deal', 'tags': '', 'text': "\n show a list of the current deal\n\n Usage:\n status\n deal\n offers\n\n Shows the currently suggested offers on each sides of the deal. To\n accept the current deal, use the 'accept' command. Use 'offer' to\n change your deal. You might also want to use 'say', 'emote' etc to\n try to influence the other part in the deal.\n "}¶
@@ -649,7 +696,7 @@ if there are still any actions you can take.
-search_index_entry = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'no_prefix': ' wait hold', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}¶
+search_index_entry = {'aliases': 'hold wait', 'category': 'combat', 'key': 'pass', 'no_prefix': ' hold wait', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}¶
@@ -835,57 +882,10 @@ topics related to the game.
-
@@ -538,7 +585,7 @@ if there are still any actions you can take.
-search_index_entry = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'no_prefix': ' wait hold', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}¶
+search_index_entry = {'aliases': 'hold wait', 'category': 'combat', 'key': 'pass', 'no_prefix': ' hold wait', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}¶
@@ -903,57 +950,10 @@ You can’t use this command in combat.
-
@@ -661,7 +708,7 @@ if there are still any actions you can take.
-search_index_entry = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'no_prefix': ' wait hold', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}¶
+search_index_entry = {'aliases': 'hold wait', 'category': 'combat', 'key': 'pass', 'no_prefix': ' hold wait', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}¶
@@ -879,57 +926,10 @@ to attack others, and as such can only be used in combat.
-
@@ -440,7 +487,7 @@ if there are still any actions you can take.
-search_index_entry = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'no_prefix': ' wait hold', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}¶
+search_index_entry = {'aliases': 'hold wait', 'category': 'combat', 'key': 'pass', 'no_prefix': ' hold wait', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}¶
@@ -763,57 +810,10 @@ topics related to the game.
-
@@ -900,7 +947,7 @@ if there are still any actions you can take.
-search_index_entry = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'no_prefix': ' wait hold', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}¶
+search_index_entry = {'aliases': 'hold wait', 'category': 'combat', 'key': 'pass', 'no_prefix': ' hold wait', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}¶
@@ -1117,57 +1164,10 @@ topics related to the game.
-
@@ -272,7 +329,7 @@ everyone but the person rolling.
-search_index_entry = {'aliases': 'roll @dice', 'category': 'general', 'key': 'dice', 'no_prefix': ' roll dice', 'tags': '', 'text': "\n roll dice\n\n Usage:\n dice[/switch] <nr>d<sides> [modifier] [success condition]\n\n Switch:\n hidden - tell the room the roll is being done, but don't show the result\n secret - don't inform the room about neither roll nor result\n\n Examples:\n dice 3d6 + 4\n dice 1d100 - 2 < 50\n\n This will roll the given number of dice with given sides and modifiers.\n So e.g. 2d6 + 3 means to 'roll a 6-sided die 2 times and add the result,\n then add 3 to the total'.\n Accepted modifiers are +, -, * and /.\n A success condition is given as normal Python conditionals\n (<,>,<=,>=,==,!=). So e.g. 2d6 + 3 > 10 means that the roll will succeed\n only if the final result is above 8. If a success condition is given, the\n outcome (pass/fail) will be echoed along with how much it succeeded/failed\n with. The hidden/secret switches will hide all or parts of the roll from\n everyone but the person rolling.\n "}¶
+search_index_entry = {'aliases': '@dice roll', 'category': 'general', 'key': 'dice', 'no_prefix': ' dice roll', 'tags': '', 'text': "\n roll dice\n\n Usage:\n dice[/switch] <nr>d<sides> [modifier] [success condition]\n\n Switch:\n hidden - tell the room the roll is being done, but don't show the result\n secret - don't inform the room about neither roll nor result\n\n Examples:\n dice 3d6 + 4\n dice 1d100 - 2 < 50\n\n This will roll the given number of dice with given sides and modifiers.\n So e.g. 2d6 + 3 means to 'roll a 6-sided die 2 times and add the result,\n then add 3 to the total'.\n Accepted modifiers are +, -, * and /.\n A success condition is given as normal Python conditionals\n (<,>,<=,>=,==,!=). So e.g. 2d6 + 3 > 10 means that the roll will succeed\n only if the final result is above 8. If a success condition is given, the\n outcome (pass/fail) will be echoed along with how much it succeeded/failed\n with. The hidden/secret switches will hide all or parts of the roll from\n everyone but the person rolling.\n "}¶
@@ -300,67 +357,10 @@ Add with @py self.cmdset.add(“contrib.dice.DiceCmdSet”)
-
-search_index_entry = {'aliases': 'break lid smash lid smash', 'category': 'general', 'key': 'smash glass', 'no_prefix': ' break lid smash lid smash', 'tags': '', 'text': '\n Smash the protective glass.\n\n Usage:\n smash glass\n\n Try to smash the glass of the button.\n\n '}¶
+search_index_entry = {'aliases': 'smash lid smash break lid', 'category': 'general', 'key': 'smash glass', 'no_prefix': ' smash lid smash break lid', 'tags': '', 'text': '\n Smash the protective glass.\n\n Usage:\n smash glass\n\n Try to smash the glass of the button.\n\n '}¶
-search_index_entry = {'aliases': 'get l ex examine listen feel', 'category': 'general', 'key': 'look', 'no_prefix': ' get l ex examine listen feel', 'tags': '', 'text': "\n Looking around in darkness\n\n Usage:\n look <obj>\n\n ... not that there's much to see in the dark.\n\n "}¶
+search_index_entry = {'aliases': 'feel examine l ex listen get', 'category': 'general', 'key': 'look', 'no_prefix': ' feel examine l ex listen get', 'tags': '', 'text': "\n Looking around in darkness\n\n Usage:\n look <obj>\n\n ... not that there's much to see in the dark.\n\n "}¶
@@ -756,7 +803,7 @@ parry - forgoes your attack but will make you harder to hit on next
-search_index_entry = {'aliases': 'kill pierce slash chop thrust fight hit bash stab defend parry', 'category': 'tutorialworld', 'key': 'attack', 'no_prefix': ' kill pierce slash chop thrust fight hit bash stab defend parry', 'tags': '', 'text': '\n Attack the enemy. Commands:\n\n stab <enemy>\n slash <enemy>\n parry\n\n stab - (thrust) makes a lot of damage but is harder to hit with.\n slash - is easier to land, but does not make as much damage.\n parry - forgoes your attack but will make you harder to hit on next\n enemy attack.\n\n '}¶
+search_index_entry = {'aliases': 'fight kill parry bash slash defend stab pierce hit chop thrust', 'category': 'tutorialworld', 'key': 'attack', 'no_prefix': ' fight kill parry bash slash defend stab pierce hit chop thrust', 'tags': '', 'text': '\n Attack the enemy. Commands:\n\n stab <enemy>\n slash <enemy>\n parry\n\n stab - (thrust) makes a lot of damage but is harder to hit with.\n slash - is easier to land, but does not make as much damage.\n parry - forgoes your attack but will make you harder to hit on next\n enemy attack.\n\n '}¶
@@ -963,57 +1010,10 @@ pulling weapons from it indefinitely.
-
@@ -947,7 +994,7 @@ random chance of eventually finding a light source.
-search_index_entry = {'aliases': 'fiddle l feel around search feel', 'category': 'tutorialworld', 'key': 'look', 'no_prefix': ' fiddle l feel around search feel', 'tags': '', 'text': '\n Look around in darkness\n\n Usage:\n look\n\n Look around in the darkness, trying\n to find something.\n '}¶
+search_index_entry = {'aliases': 'feel search feel around l fiddle', 'category': 'tutorialworld', 'key': 'look', 'no_prefix': ' feel search feel around l fiddle', 'tags': '', 'text': '\n Look around in darkness\n\n Usage:\n look\n\n Look around in the darkness, trying\n to find something.\n '}¶
@@ -1273,57 +1320,10 @@ overriding the call (unused by default).
-
Pull the latest code from the evennia core or checkout a different branch.
+
+
Usage:
git evennia status - View an overview of the evennia repository status.
+git evennia branch - View available branches in evennia.
+git evennia checkout <branch> - Checkout a different branch in evennia.
+git evennia pull - Pull the latest evennia code.
+
+
+
For updating your local mygame repository, the same commands are available with ‘git’.
+
If there are any conflicts encountered, the command will abort. The command will reload your game after pulling new code automatically, but for some changes involving persistent scripts etc, you may need to manually restart.
+search_index_entry = {'aliases': '', 'category': 'system', 'key': 'git evennia', 'no_prefix': ' ', 'tags': '', 'text': "\n Pull the latest code from the evennia core or checkout a different branch.\n \n Usage:\n git evennia status - View an overview of the evennia repository status.\n git evennia branch - View available branches in evennia.\n git evennia checkout <branch> - Checkout a different branch in evennia.\n git evennia pull - Pull the latest evennia code.\n \n For updating your local mygame repository, the same commands are available with 'git'.\n \n If there are any conflicts encountered, the command will abort. The command will reload your game after pulling new code automatically, but for some changes involving persistent scripts etc, you may need to manually restart.\n "}¶
Pull the latest code from your repository or checkout a different branch.
+
+
Usage:
git status - View an overview of your git repository.
+git branch - View available branches.
+git checkout main - Checkout the main branch of your code.
+git pull - Pull the latest code from your current branch.
+
+
+
For updating evennia code, the same commands are available with ‘git evennia’.
+
If there are any conflicts encountered, the command will abort. The command will reload your game after pulling new code automatically, but for changes involving persistent scripts etc, you may need to manually restart.
+search_index_entry = {'aliases': '', 'category': 'system', 'key': 'git', 'no_prefix': ' ', 'tags': '', 'text': "\n Pull the latest code from your repository or checkout a different branch.\n\n Usage:\n git status - View an overview of your git repository.\n git branch - View available branches.\n git checkout main - Checkout the main branch of your code.\n git pull - Pull the latest code from your current branch.\n\n For updating evennia code, the same commands are available with 'git evennia'.\n \n If there are any conflicts encountered, the command will abort. The command will reload your game after pulling new code automatically, but for changes involving persistent scripts etc, you may need to manually restart.\n "}¶
+
+
+
\ No newline at end of file
diff --git a/docs/1.0-dev/api/evennia.contrib.utils.html b/docs/1.0-dev/api/evennia.contrib.utils.html
index 476309db2b..1dd338b1d2 100644
--- a/docs/1.0-dev/api/evennia.contrib.utils.html
+++ b/docs/1.0-dev/api/evennia.contrib.utils.html
@@ -46,48 +46,8 @@
This sub-package defines the help system of Evennia. It is pretty
-simple, mainly consisting of a database model to hold help entries.
-The auto-cmd-help is rather handled by the default ‘help’ command
-itself.
This sub-package defines the help system of Evennia. It is pretty
+simple, mainly consisting of a database model to hold help entries.
+The auto-cmd-help is rather handled by the default ‘help’ command
+itself.
This sub-package defines the lock (access) mechanism of Evennia. All
-lock strings are processed through the lockhandler in this package. It
-also contains the default lock functions used in lock definitions.
This sub-package defines the lock (access) mechanism of Evennia. All
+lock strings are processed through the lockhandler in this package. It
+also contains the default lock functions used in lock definitions.
Protfuncs are FuncParser-callables that can be embedded in a prototype to
-provide custom logic without having access to Python. The protfunc is parsed at
-the time of spawning, using the creating object’s session as input. If the
-protfunc returns a non-string, this is what will be added to the prototype.
-
In the prototype dict, the protfunc is specified as a string inside the prototype, e.g.:
-
-
{ …
-
“key”: “$funcname(args, kwargs)”
-
… }
-
-
Available protfuncs are either all callables in one of the modules of settings.PROT_FUNC_MODULES
-or all callables added to a dict FUNCPARSER_CALLABLES in such a module.
At spawn-time the spawner passes the following extra kwargs into each callable (in addition to
-what is added in the call itself):
-
-
-
session (Session): The Session of the entity spawning using this prototype.
-
prototype (dict): The dict this protfunc is a part of.
-
current_key (str): The active key this value belongs to in the prototype.
-
-
-
Any traceback raised by this function will be handled at the time of spawning and abort the spawn
-before any object is created/updated. It must otherwise return the value to store for the specified
-prototype key (this value must be possible to serialize in an Attribute).
Protfuncs are FuncParser-callables that can be embedded in a prototype to
+provide custom logic without having access to Python. The protfunc is parsed at
+the time of spawning, using the creating object’s session as input. If the
+protfunc returns a non-string, this is what will be added to the prototype.
+
In the prototype dict, the protfunc is specified as a string inside the prototype, e.g.:
+
+
{ …
+
“key”: “$funcname(args, kwargs)”
+
… }
+
+
Available protfuncs are either all callables in one of the modules of settings.PROT_FUNC_MODULES
+or all callables added to a dict FUNCPARSER_CALLABLES in such a module.
At spawn-time the spawner passes the following extra kwargs into each callable (in addition to
+what is added in the call itself):
+
+
+
session (Session): The Session of the entity spawning using this prototype.
+
prototype (dict): The dict this protfunc is a part of.
+
current_key (str): The active key this value belongs to in the prototype.
+
+
+
Any traceback raised by this function will be handled at the time of spawning and abort the spawn
+before any object is created/updated. It must otherwise return the value to store for the specified
+prototype key (this value must be possible to serialize in an Attribute).
This sub-package holds the Scripts system. Scripts are database
-entities that can store data both in connection to Objects and Accounts
-or globally. They may also have a timer-component to execute various
-timed effects.
This sub-package holds the Scripts system. Scripts are database
+entities that can store data both in connection to Objects and Accounts
+or globally. They may also have a timer-component to execute various
+timed effects.
This module brings Django Signals into Evennia. These are events that can be
-subscribed to by importing a given Signal and using the following code.
-
THIS_SIGNAL.connect(callback,sender_object)
-
-
-
When other code calls THIS_SIGNAL.send(sender, **kwargs), the callback will
-be triggered.
-
Callbacks must be on the following format:
-
defmy_callback(sender,**kwargs):
- # ...
-
-
-
This is used on top of hooks to make certain features easier to add to contribs
-without necessitating a full takeover of hooks that may be in high demand.
This module brings Django Signals into Evennia. These are events that can be
+subscribed to by importing a given Signal and using the following code.
+
THIS_SIGNAL.connect(callback,sender_object)
+
+
+
When other code calls THIS_SIGNAL.send(sender, **kwargs), the callback will
+be triggered.
+
Callbacks must be on the following format:
+
defmy_callback(sender,**kwargs):
+ # ...
+
+
+
This is used on top of hooks to make certain features easier to add to contribs
+without necessitating a full takeover of hooks that may be in high demand.
NOTE: NO MODIFICATIONS SHOULD BE MADE TO THIS FILE!
-
All settings changes should be done by copy-pasting the variable and
-its value to <gamedir>/server/conf/settings.py.
-
Hint: Don’t copy&paste over more from this file than you actually want
-to change. Anything you don’t copy&paste will thus retain its default
-value - which may change as Evennia is developed. This way you can
-always be sure of what you have changed and what is default behaviour.
NOTE: NO MODIFICATIONS SHOULD BE MADE TO THIS FILE!
+
All settings changes should be done by copy-pasting the variable and
+its value to <gamedir>/server/conf/settings.py.
+
Hint: Don’t copy&paste over more from this file than you actually want
+to change. Anything you don’t copy&paste will thus retain its default
+value - which may change as Evennia is developed. This way you can
+always be sure of what you have changed and what is default behaviour.
This sub-package defines the typeclass-system, a way to wrap database
-access into almost-normal Python classes. Using typeclasses one can
-work in normal Python while having the luxury of persistent data
-storage at every turn. ObjectDB, ChannelDB, AccountDB and ScriptDB all
-inherit from the models in this package. Here is also were the
-Attribute and Tag models are defined along with their handlers.
This sub-package defines the typeclass-system, a way to wrap database
+access into almost-normal Python classes. Using typeclasses one can
+work in normal Python while having the luxury of persistent data
+storage at every turn. ObjectDB, ChannelDB, AccountDB and ScriptDB all
+inherit from the models in this package. Here is also were the
+Attribute and Tag models are defined along with their handlers.
Searches through all objects returning those which has a
-certain typeclass. If location is set, limit search to objects
-in that location.
+
Searches through all objects returning those which are of the
+specified typeclass.
Parameters
typeclass (str or class) – A typeclass class or a python path to a typeclass.
include_children (bool, optional) – Return objects with
given typeclass and all children inheriting from this
-typeclass. Mutuall exclusive to include_parents.
+typeclass. Mutually exclusive to include_parents.
include_parents (bool, optional) – Return objects with
given typeclass and all parents to this typeclass.
Mutually exclusive to include_children.
@@ -454,6 +500,10 @@ Mutually exclusive to include_children.
Returns
objects (list) – The objects found with the given typeclasses.
+
Raises
+
ImportError – If the provided typeclass is not a valid typeclass or the
+path to an existing typeclass.
+
@@ -462,57 +512,10 @@ Mutually exclusive to include_children.
-
-search_index_entry = {'aliases': 'n no yes __nomatch_command a abort y', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' n no yes __nomatch_command a abort y', 'tags': '', 'text': '\n Handle a prompt for yes or no. Press [return] for the default choice.\n\n '}¶
+search_index_entry = {'aliases': 'no n yes abort a __nomatch_command y', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' no n yes abort a __nomatch_command y', 'tags': '', 'text': '\n Handle a prompt for yes or no. Press [return] for the default choice.\n\n '}¶
@@ -1133,65 +1188,10 @@ Must be on the form callable(caller, raw_string, **kwargs).
-
@@ -114,7 +161,7 @@ the caller.msg() construct every time the page is updated.
-search_index_entry = {'aliases': 'next n top end a previous abort quit t p q e', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' next n top end a previous abort quit t p q e', 'tags': '', 'text': '\n Manipulate the text paging. Catch no-input with aliases.\n '}¶
+search_index_entry = {'aliases': 't top n p abort previous e next end a quit q', 'category': 'general', 'key': '__noinput_command', 'no_prefix': ' t top n p abort previous e next end a quit q', 'tags': '', 'text': '\n Manipulate the text paging. Catch no-input with aliases.\n '}¶
@@ -514,57 +561,10 @@ the evmore commands will be available when this is run).
-
This parses a string and if the string only contains a “$func(…)”,
the return will be the return value of that function, even if it’s not
a string. If mixed in with other strings, the result will still always
@@ -247,6 +294,10 @@ be a string.
raise_errors (bool, optional) – If unset, leave a failing (or
unrecognized) inline function as unparsed in the string. If set,
raise an ParsingError.
+
escape (bool, optional) – If set, escape all found functions so they
+are not executed by later parsing.
+
strip (bool, optional) – If set, strip any inline funcs from string
+as if they were not there.
**reserved_kwargs – If given, these are guaranteed to _always_ pass
as part of each parsed callable’s kwargs. These override
same-named default options given in **__init__ as well as any
@@ -424,8 +475,11 @@ integer value in the given range.
FuncParser callable. Picks a random choice from a list.
Parameters
-
listing (list) – A list of items to randomly choose between.
-This will be converted from a string to a real list.
+
+
listing (list) – A list of items to randomly choose between.
+This will be converted from a string to a real list.
+
*args – If multiple args are given, will pick one randomly from them.
+
Returns
any – The randomly chosen element.
@@ -433,7 +487,7 @@ This will be converted from a string to a real list.
Example
-
$choice([key, flower, house])
+
$choice(key, flower, house)
$choice([1, 2, 3, 4])
@@ -588,7 +642,9 @@ this requries the parser be called with the caller’s Session for proper
security. If called without session, the call is aborted.
Parameters
-
query (str) – The key or dbref to search for.
+
query (str) – The key or dbref to search for. This can consist of any args used
+for one of the regular search methods. Also kwargs will be passed into
+the search (except the kwargs given below)
Keyword Arguments
@@ -600,6 +656,7 @@ be passed into the access check for the entity being searched for.
The ‘control’ permission is required.
access (str) – Which locktype access to check. Unset to disable the
security check.
+
**kwargs – Will be passed into the main search.
Returns
@@ -615,6 +672,7 @@ passed into parser.
“$search(#233)”
“$search(Tom, type=account)”
“$search(meadow, return_list=True)”
+
“$search(beach, category=outdoors, type=tag)
@@ -919,57 +977,10 @@ and the mapping can always be auto-detected.
-
Searches through all objects returning those of a certain typeclass.
+
+
Parameters
+
+
typeclass (str or class) – A typeclass class or a python path to a typeclass.
+
include_children (bool, optional) – Return objects with
+given typeclass and all children inheriting from this
+typeclass. Mutuall exclusive to include_parents.
+
include_parents (bool, optional) – Return objects with
+given typeclass and all parents to this typeclass.
+Mutually exclusive to include_children.
+
+
+
Returns
+
objects (list) – The objects found with the given typeclasses.
English pronoun mapping between 1st/2nd person and 3rd person perspective (and vice-versa).
This file is released under the Evennia regular BSD License.
-(Griatch 2021)
+(Griatch 2021) - revised by InspectorCaracal 2022
Pronouns are words you use instead of a proper name, such as ‘him’, ‘herself’, ‘theirs’ etc. These
look different depending on who sees the outgoing string. This mapping maps between 1st/2nd case and
the 3rd person case and back. In some cases, the mapping is not unique; it is assumed the system can
@@ -130,7 +177,7 @@ Pronoun
it
it
its
-
theirs*
+
its
itself
3rd person plural
@@ -142,10 +189,9 @@ Pronoun
-
> *) Not formally used, we use theirs here as a filler.
Specific gender to use (plural counts a gender for this purpose).
@@ -198,57 +244,10 @@ string and others respectively. If pronoun is invalid, the word is returned verb
-
The Django Rest Framework provides a way of generating urls for different
-views that implement standard CRUD operations in a quick way, using ‘routers’
-and ‘viewsets’. A viewset implements standard CRUD actions and any custom actions
-that you want, and then a router will automatically generate URLs based on the
-actions that it detects for a viewset. For example, below we create a DefaultRouter.
-We then register ObjectDBViewSet, a viewset for CRUD operations for ObjectDB
-instances, to the ‘objects’ base endpoint. That will generate a number of URLs
-like the following:
The Django Rest Framework provides a way of generating urls for different
+views that implement standard CRUD operations in a quick way, using ‘routers’
+and ‘viewsets’. A viewset implements standard CRUD actions and any custom actions
+that you want, and then a router will automatically generate URLs based on the
+actions that it detects for a viewset. For example, below we create a DefaultRouter.
+We then register ObjectDBViewSet, a viewset for CRUD operations for ObjectDB
+instances, to the ‘objects’ base endpoint. That will generate a number of URLs
+like the following:
File that determines what each URL points to. This uses Python regular expressions.
-This is the starting point when a user enters an URL.
-
-
The URL is matched with a regex, tying it to a given view. Note that this central url.py
-file includes url.py from all the various web-components found in views/ so the search
-space is much larger than what is shown here.
-
The view (a Python function or class is executed)
-
The view uses a template (a HTML file which may contain template markers for dynamically
-modifying its contents; the locations of such templates are given by
-settings.TEMPLATES[0][‘DIRS’]) and which may in turn may include static
-assets (CSS, images etc).
-
The view ‘renders’ the template into a finished HTML page, replacing all
-dynamic content as appropriate.
File that determines what each URL points to. This uses Python regular expressions.
+This is the starting point when a user enters an URL.
+
+
The URL is matched with a regex, tying it to a given view. Note that this central url.py
+file includes url.py from all the various web-components found in views/ so the search
+space is much larger than what is shown here.
+
The view (a Python function or class is executed)
+
The view uses a template (a HTML file which may contain template markers for dynamically
+modifying its contents; the locations of such templates are given by
+settings.TEMPLATES[0][‘DIRS’]) and which may in turn may include static
+assets (CSS, images etc).
+
The view ‘renders’ the template into a finished HTML page, replacing all
+dynamic content as appropriate.
By default ModelBackend does case _sensitive_ username
-authentication, which isn’t what is generally expected. This
-backend supports case insensitive username authentication.
By default ModelBackend does case _sensitive_ username
+authentication, which isn’t what is generally expected. This
+backend supports case insensitive username authentication.