Fix merge conflicts
This commit is contained in:
commit
a974a2843c
2 changed files with 188 additions and 140 deletions
|
|
@ -24,7 +24,7 @@ class NameChanger:
|
||||||
class MyObject(DefaultObject):
|
class MyObject(DefaultObject):
|
||||||
@lazy_property:
|
@lazy_property:
|
||||||
def namechange(self):
|
def namechange(self):
|
||||||
return MyHandler(self)
|
return NameChanger(self)
|
||||||
|
|
||||||
|
|
||||||
obj = create_object(MyObject, key="test")
|
obj = create_object(MyObject, key="test")
|
||||||
|
|
@ -35,13 +35,23 @@ print(obj.key)
|
||||||
>>> "test_extra"
|
>>> "test_extra"
|
||||||
```
|
```
|
||||||
|
|
||||||
What happens here is that we make a new class `MyHandler`. We use the `@lazy_property` decorator to set it up - this means the handler will not be actually created until someone really wants to use it, by accessing `obj.namechange` later. The decorated `namechange` method returns the handler and makes sure to initialize it with `self` - this becomes the `obj` inside the handler!
|
What happens here is that we make a new class `NameChanger`. We use the
|
||||||
|
`@lazy_property` decorator to set it up - this means the handler will not be
|
||||||
|
actually created until someone really wants to use it, by accessing
|
||||||
|
`obj.namechange` later. The decorated `namechange` method returns the handler
|
||||||
|
and makes sure to initialize it with `self` - this becomes the `obj` inside the
|
||||||
|
handler!
|
||||||
|
|
||||||
We then make a silly method `add_to_key` that uses the handler to manipulate the key of the object. In this example, the handler is pretty pointless, but grouping functionality this way can both make for an easy-to-remember API and can also allow you cache data for easy access - this is how the `AttributeHandler` (`.attributes`) and `TagHandler` (`.tags`) works.
|
We then make a silly method `add_to_key` that uses the handler to manipulate the
|
||||||
|
key of the object. In this example, the handler is pretty pointless, but
|
||||||
|
grouping functionality this way can both make for an easy-to-remember API and
|
||||||
|
can also allow you cache data for easy access - this is how the
|
||||||
|
`AttributeHandler` (`.attributes`) and `TagHandler` (`.tags`) works.
|
||||||
|
|
||||||
## Persistent storage of data in handler
|
## Persistent storage of data in handler
|
||||||
|
|
||||||
Let's say we want to track 'quests' in our handler. A 'quest' is a regular class that represents the quest. Let's make it simple as an example:
|
Let's say we want to track 'quests' in our handler. A 'quest' is a regular class
|
||||||
|
that represents the quest. Let's make it simple as an example:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# for example in mygame/world/quests.py
|
# for example in mygame/world/quests.py
|
||||||
|
|
@ -103,7 +113,6 @@ class QuestHandler:
|
||||||
self._save()
|
self._save()
|
||||||
|
|
||||||
def check_progress(self):
|
def check_progress(self):
|
||||||
for quest in self.storage.values():
|
|
||||||
quest.check_progress()
|
quest.check_progress()
|
||||||
if self.do_save:
|
if self.do_save:
|
||||||
# .do_save is set on handler by Quest if it wants to save progress
|
# .do_save is set on handler by Quest if it wants to save progress
|
||||||
|
|
@ -159,9 +168,18 @@ class Quest:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The `Quest.__init__` now takes `obj` as argument, to match what we pass to it in `QuestHandler.add`. We want to monitor the changing of `current_step`, so we make it into a `property`. When we edit that value, we set the `do_save` flag on the handler, which means it will save the status to database once it has checked progress on all its quests.
|
The `Quest.__init__` now takes `obj` as argument, to match what we pass to it in
|
||||||
|
`QuestHandler.add`. We want to monitor the changing of `current_step`, so we
|
||||||
|
make it into a `property`. When we edit that value, we set the `do_save` flag on
|
||||||
|
the handler, which means it will save the status to database once it has checked
|
||||||
|
progress on all its quests. The `Quest.questhandler` property allows to easily
|
||||||
|
get back to the handler (and the object on which it sits).
|
||||||
|
|
||||||
The `__serialize__dbobjs__` and `__deserialize_dbobjs__` methods are needed because `Attributes` can't store 'hidden' database objects (the `Quest.obj` property. The methods help Evennia serialize/deserialize `Quest` propertly when the handler saves it. For more information, see [Storing Single objects](../Components/Attributes.md#storing-single-objects) in the Attributes documentation.
|
The `__serialize__dbobjs__` and `__deserialize_dbobjs__` methods are needed
|
||||||
|
because `Attributes` can't store 'hidden' database objects (the `Quest.obj`
|
||||||
|
property. The methods help Evennia serialize/deserialize `Quest` propertly when
|
||||||
|
the handler saves it. For more information, see [Storing Single
|
||||||
|
objects](../Components/Attributes.md#storing-single-objects) in the Attributes
|
||||||
|
|
||||||
### Tying it all together
|
### Tying it all together
|
||||||
|
|
||||||
|
|
@ -184,14 +202,21 @@ class Character(DefaultCharacter):
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
You can now make your Quest classes to describe your quests and add them to characters with
|
You can now make your Quest classes to describe your quests and add them to
|
||||||
|
characters with
|
||||||
|
|
||||||
character.quests.add(FindTheRedKey)
|
```python
|
||||||
|
character.quests.add(FindTheRedKey)
|
||||||
|
```
|
||||||
|
|
||||||
and can later do
|
and can later do
|
||||||
|
|
||||||
character.quests.check_progress()
|
```python
|
||||||
|
character.quests.check_progress()
|
||||||
|
```
|
||||||
|
|
||||||
and be sure that quest data is not lost between reloads.
|
and be sure that quest data is not lost between reloads.
|
||||||
|
|
||||||
You can find a full-fledged quest-handler example as [EvAdventure quests](evennia.contribs.tutorials.evadventure.quests) contrib in the Evennia repository.
|
You can find a full-fledged quest-handler example as [EvAdventure
|
||||||
|
quests](evennia.contribs.tutorials.evadventure.quests) contrib in the Evennia
|
||||||
|
repository.
|
||||||
|
|
|
||||||
|
|
@ -17,110 +17,133 @@ in the game in various ways:
|
||||||
overhear (for example "s" sounds tend to be audible even when no other
|
overhear (for example "s" sounds tend to be audible even when no other
|
||||||
meaning can be determined).
|
meaning can be determined).
|
||||||
|
|
||||||
Usage:
|
## Usage
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from evennia.contrib import rplanguage
|
from evennia.contrib import rplanguage
|
||||||
|
|
||||||
# need to be done once, here we create the "default" lang
|
# need to be done once, here we create the "default" lang
|
||||||
rplanguage.add_language()
|
rplanguage.add_language()
|
||||||
|
|
||||||
say = "This is me talking."
|
say = "This is me talking."
|
||||||
whisper = "This is me whispering.
|
whisper = "This is me whispering.
|
||||||
|
|
||||||
print rplanguage.obfuscate_language(say, level=0.0)
|
print rplanguage.obfuscate_language(say, level=0.0)
|
||||||
<<< "This is me talking."
|
<<< "This is me talking."
|
||||||
print rplanguage.obfuscate_language(say, level=0.5)
|
print rplanguage.obfuscate_language(say, level=0.5)
|
||||||
<<< "This is me byngyry."
|
<<< "This is me byngyry."
|
||||||
print rplanguage.obfuscate_language(say, level=1.0)
|
print rplanguage.obfuscate_language(say, level=1.0)
|
||||||
<<< "Daly ly sy byngyry."
|
<<< "Daly ly sy byngyry."
|
||||||
|
|
||||||
result = rplanguage.obfuscate_whisper(whisper, level=0.0)
|
result = rplanguage.obfuscate_whisper(whisper, level=0.0)
|
||||||
<<< "This is me whispering"
|
<<< "This is me whispering"
|
||||||
result = rplanguage.obfuscate_whisper(whisper, level=0.2)
|
result = rplanguage.obfuscate_whisper(whisper, level=0.2)
|
||||||
<<< "This is m- whisp-ring"
|
<<< "This is m- whisp-ring"
|
||||||
result = rplanguage.obfuscate_whisper(whisper, level=0.5)
|
result = rplanguage.obfuscate_whisper(whisper, level=0.5)
|
||||||
<<< "---s -s -- ---s------"
|
<<< "---s -s -- ---s------"
|
||||||
result = rplanguage.obfuscate_whisper(whisper, level=0.7)
|
result = rplanguage.obfuscate_whisper(whisper, level=0.7)
|
||||||
<<< "---- -- -- ----------"
|
<<< "---- -- -- ----------"
|
||||||
result = rplanguage.obfuscate_whisper(whisper, level=1.0)
|
result = rplanguage.obfuscate_whisper(whisper, level=1.0)
|
||||||
<<< "..."
|
<<< "..."
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
To set up new languages, import and use the `add_language()`
|
## Custom languages
|
||||||
helper method in this module. This allows you to customize the
|
|
||||||
"feel" of the semi-random language you are creating. Especially
|
|
||||||
the `word_length_variance` helps vary the length of translated
|
|
||||||
words compared to the original and can help change the "feel" for
|
|
||||||
the language you are creating. You can also add your own
|
|
||||||
dictionary and "fix" random words for a list of input words.
|
|
||||||
|
|
||||||
Below is an example of "elvish", using "rounder" vowels and sounds:
|
To set up new languages, you need to run `add_language()`
|
||||||
|
helper function in this module. The arguments of this function (see below)
|
||||||
|
are used to store the new language in the database (in the LanguageHandler,
|
||||||
|
which is a type of Script).
|
||||||
|
|
||||||
```python
|
If you want to remember the language definitions, you could put them all
|
||||||
# vowel/consonant grammar possibilities
|
in a module along with the `add_language` call as a quick way to
|
||||||
grammar = ("v vv vvc vcc vvcc cvvc vccv vvccv vcvccv vcvcvcc vvccvvcc "
|
rebuild the language on a db reset:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# a stand-alone module somewhere under mygame. Just import this
|
||||||
|
# once to automatically add the language!
|
||||||
|
|
||||||
|
from evennia.contrib.rpg.rpsystem import rplanguage
|
||||||
|
grammar = (...)
|
||||||
|
vowels = "eaouy"
|
||||||
|
# etc
|
||||||
|
|
||||||
|
rplanguage.add_language(grammar=grammar, vowels=vowels, ...)
|
||||||
|
```
|
||||||
|
|
||||||
|
The variables of `add_language` allows you to customize the "feel" of
|
||||||
|
the semi-random language you are creating. Especially
|
||||||
|
the `word_length_variance` helps vary the length of translated
|
||||||
|
words compared to the original. You can also add your own
|
||||||
|
dictionary and "fix" random words for a list of input words.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Below is an example module creating "elvish", using "rounder" vowels and sounds:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# vowel/consonant grammar possibilities
|
||||||
|
grammar = ("v vv vvc vcc vvcc cvvc vccv vvccv vcvccv vcvcvcc vvccvvcc "
|
||||||
"vcvvccvvc cvcvvcvvcc vcvcvvccvcvv")
|
"vcvvccvvc cvcvvcvvcc vcvcvvccvcvv")
|
||||||
|
|
||||||
# all not in this group is considered a consonant
|
# all not in this group is considered a consonant
|
||||||
vowels = "eaoiuy"
|
vowels = "eaoiuy"
|
||||||
|
|
||||||
# you need a representative of all of the minimal grammars here, so if a
|
# you need a representative of all of the minimal grammars here, so if a
|
||||||
# grammar v exists, there must be atleast one phoneme available with only
|
# grammar v exists, there must be atleast one phoneme available with only
|
||||||
# one vowel in it
|
# one vowel in it
|
||||||
phonemes = ("oi oh ee ae aa eh ah ao aw ay er ey ow ia ih iy "
|
phonemes = ("oi oh ee ae aa eh ah ao aw ay er ey ow ia ih iy "
|
||||||
"oy ua uh uw y p b t d f v t dh s z sh zh ch jh k "
|
"oy ua uh uw y p b t d f v t dh s z sh zh ch jh k "
|
||||||
"ng g m n l r w")
|
"ng g m n l r w")
|
||||||
|
|
||||||
# how much the translation varies in length compared to the original. 0 is
|
# how much the translation varies in length compared to the original. 0 is
|
||||||
# smallest, higher values give ever bigger randomness (including removing
|
# smallest, higher values give ever bigger randomness (including removing
|
||||||
# short words entirely)
|
# short words entirely)
|
||||||
word_length_variance = 1
|
word_length_variance = 1
|
||||||
|
|
||||||
# if a proper noun (word starting with capitalized letter) should be
|
# if a proper noun (word starting with capitalized letter) should be
|
||||||
# translated or not. If not (default) it means e.g. names will remain
|
# translated or not. If not (default) it means e.g. names will remain
|
||||||
# unchanged across languages.
|
# unchanged across languages.
|
||||||
noun_translate = False
|
noun_translate = False
|
||||||
|
|
||||||
# all proper nouns (words starting with a capital letter not at the beginning
|
# all proper nouns (words starting with a capital letter not at the beginning
|
||||||
# of a sentence) can have either a postfix or -prefix added at all times
|
# of a sentence) can have either a postfix or -prefix added at all times
|
||||||
noun_postfix = "'la"
|
noun_postfix = "'la"
|
||||||
|
|
||||||
# words in dict will always be translated this way. The 'auto_translations'
|
# words in dict will always be translated this way. The 'auto_translations'
|
||||||
# is instead a list or filename to file with words to use to help build a
|
# is instead a list or filename to file with words to use to help build a
|
||||||
# bigger dictionary by creating random translations of each word in the
|
# bigger dictionary by creating random translations of each word in the
|
||||||
# list *once* and saving the result for subsequent use.
|
# list *once* and saving the result for subsequent use.
|
||||||
manual_translations = {"the":"y'e", "we":"uyi", "she":"semi", "he":"emi",
|
manual_translations = {"the":"y'e", "we":"uyi", "she":"semi", "he":"emi",
|
||||||
"you": "do", 'me':'mi','i':'me', 'be':"hy'e", 'and':'y'}
|
"you": "do", 'me':'mi','i':'me', 'be':"hy'e", 'and':'y'}
|
||||||
|
|
||||||
rplanguage.add_language(key="elvish", phonemes=phonemes, grammar=grammar,
|
rplanguage.add_language(key="elvish", phonemes=phonemes, grammar=grammar,
|
||||||
word_length_variance=word_length_variance,
|
word_length_variance=word_length_variance,
|
||||||
noun_translate=noun_translate,
|
noun_translate=noun_translate,
|
||||||
noun_postfix=noun_postfix, vowels=vowels,
|
noun_postfix=noun_postfix, vowels=vowels,
|
||||||
manual_translations=manual_translations,
|
manual_translations=manual_translations,
|
||||||
auto_translations="my_word_file.txt")
|
auto_translations="my_word_file.txt")
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This will produce a decicively more "rounded" and "soft" language
|
This will produce a decicively more "rounded" and "soft" language
|
||||||
than the default one. The few manual_translations also make sure
|
than the default one. The few manual_translations also make sure
|
||||||
to make it at least look superficially "reasonable".
|
to make it at least look superficially "reasonable".
|
||||||
|
|
||||||
The `auto_translations` keyword is useful, this accepts either a
|
The `auto_translations` keyword is useful, this accepts either a
|
||||||
list or a path to a file of words (one per line) to automatically
|
list or a path to a file of words (one per line) to automatically
|
||||||
create fixed translations for according to the grammatical rules.
|
create fixed translations for according to the grammatical rules.
|
||||||
This allows to quickly build a large corpus of translated words
|
This allows to quickly build a large corpus of translated words
|
||||||
that never change (if this is desired).
|
that never change (if this is desired).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
from random import choice, randint
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from random import choice, randint
|
||||||
|
|
||||||
from evennia import DefaultScript
|
from evennia import DefaultScript
|
||||||
from evennia.utils import logger
|
from evennia.utils import logger
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Obfuscate language
|
# Obfuscate language
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue