Merge branch 'evennia:main' into hex_colors
This commit is contained in:
commit
aa9ed83a26
9 changed files with 55 additions and 31 deletions
|
|
@ -5,8 +5,14 @@
|
||||||
- [Feature][pull3470]: New `exit_order` kwarg to
|
- [Feature][pull3470]: New `exit_order` kwarg to
|
||||||
`DefaultObject.get_display_exits` to easier customize the order in which
|
`DefaultObject.get_display_exits` to easier customize the order in which
|
||||||
standard exits are displayed in a room (chiizujin)
|
standard exits are displayed in a room (chiizujin)
|
||||||
|
- [Fix][pull3495]: Fix rate in Trait contribs not updating after reload (jaborsh)
|
||||||
|
- [Fix][pull3491]: Fix traceback in EvEditor when searching with malformed regex (chiizujin)
|
||||||
|
- [Docs]: Doc fixes (Griatch, chiizujin)
|
||||||
|
|
||||||
[pull3470]: https://github.com/evennia/evennia/pull/3470
|
[pull3470]: https://github.com/evennia/evennia/pull/3470
|
||||||
|
[pull3495]: https://github.com/evennia/evennia/pull/3495
|
||||||
|
[pull3491]: https://github.com/evennia/evennia/pull/3491
|
||||||
|
|
||||||
|
|
||||||
## Evennia 4.1.1
|
## Evennia 4.1.1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ ABILITY_REVERSE_MAP = {
|
||||||
|
|
||||||
Above, the `Ability` class holds some basic properties of a character sheet.
|
Above, the `Ability` class holds some basic properties of a character sheet.
|
||||||
|
|
||||||
The `ABILITY_REVERSE_MAP` is a convenient map to go the other way &mdas; if in some command we were to enter the string 'cha', we could use this mapping to directly convert your input to the correct `Ability`. For example:
|
The `ABILITY_REVERSE_MAP` is a convenient map to go the other way — if in some command we were to enter the string 'cha', we could use this mapping to directly convert your input to the correct `Ability`. For example:
|
||||||
|
|
||||||
ability = ABILITY_REVERSE_MAP.get(your_input)
|
ability = ABILITY_REVERSE_MAP.get(your_input)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@ This file contains the Descriptors used to set Fields in Components
|
||||||
|
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from evennia.typeclasses.attributes import (AttributeProperty,
|
from evennia.typeclasses.attributes import AttributeProperty, NAttributeProperty
|
||||||
NAttributeProperty)
|
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
from .components import Component
|
from .components import Component
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ class TestComponents(EvenniaTest):
|
||||||
|
|
||||||
def test_mutables_are_not_shared_when_autocreate(self):
|
def test_mutables_are_not_shared_when_autocreate(self):
|
||||||
self.char1.test_a.my_list.append(1)
|
self.char1.test_a.my_list.append(1)
|
||||||
self.assertNotEqual(id(self.char1.test_a.my_list), id(self.char2.test_a.my_list))
|
self.assertIsNot(self.char1.test_a.my_list, self.char2.test_a.my_list)
|
||||||
|
|
||||||
def test_replacing_class_component_slot_with_runtime_component(self):
|
def test_replacing_class_component_slot_with_runtime_component(self):
|
||||||
self.char1.components.add_default("replacement_inherited_test_a")
|
self.char1.components.add_default("replacement_inherited_test_a")
|
||||||
|
|
|
||||||
|
|
@ -661,7 +661,12 @@ class TraitHandler:
|
||||||
return trait
|
return trait
|
||||||
|
|
||||||
def add(
|
def add(
|
||||||
self, trait_key, name=None, trait_type=DEFAULT_TRAIT_TYPE, force=True, **trait_properties
|
self,
|
||||||
|
trait_key,
|
||||||
|
name=None,
|
||||||
|
trait_type=DEFAULT_TRAIT_TYPE,
|
||||||
|
force=True,
|
||||||
|
**trait_properties,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Create a new Trait and add it to the handler.
|
Create a new Trait and add it to the handler.
|
||||||
|
|
@ -945,7 +950,12 @@ class Trait:
|
||||||
|
|
||||||
def __getattr__(self, key):
|
def __getattr__(self, key):
|
||||||
"""Access extra parameters as attributes."""
|
"""Access extra parameters as attributes."""
|
||||||
if key in ("default_keys", "data_default", "trait_type", "allow_extra_properties"):
|
if key in (
|
||||||
|
"default_keys",
|
||||||
|
"data_default",
|
||||||
|
"trait_type",
|
||||||
|
"allow_extra_properties",
|
||||||
|
):
|
||||||
return _GA(self, key)
|
return _GA(self, key)
|
||||||
try:
|
try:
|
||||||
return self._data[key]
|
return self._data[key]
|
||||||
|
|
@ -1276,7 +1286,7 @@ class CounterTrait(Trait):
|
||||||
)
|
)
|
||||||
# set up rate
|
# set up rate
|
||||||
if trait_data["rate"] != 0:
|
if trait_data["rate"] != 0:
|
||||||
trait_data["last_update"] = time()
|
trait_data["last_update"] = trait_data.get("last_update", time())
|
||||||
else:
|
else:
|
||||||
trait_data["last_update"] = None
|
trait_data["last_update"] = None
|
||||||
return trait_data
|
return trait_data
|
||||||
|
|
@ -1552,6 +1562,7 @@ class GaugeTrait(CounterTrait):
|
||||||
rate = self.rate
|
rate = self.rate
|
||||||
if rate != 0 and self._data["last_update"] is not None:
|
if rate != 0 and self._data["last_update"] is not None:
|
||||||
now = time()
|
now = time()
|
||||||
|
|
||||||
tdiff = now - self._data["last_update"]
|
tdiff = now - self._data["last_update"]
|
||||||
current += rate * tdiff
|
current += rate * tdiff
|
||||||
value = current
|
value = current
|
||||||
|
|
|
||||||
|
|
@ -1588,6 +1588,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
||||||
obj.get_display_name(looker, exit_order=('north', 'south'))
|
obj.get_display_name(looker, exit_order=('north', 'south'))
|
||||||
-> "Exits: north, south, out, and portal." (markup not shown here)
|
-> "Exits: north, south, out, and portal." (markup not shown here)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _sort_exit_names(names):
|
def _sort_exit_names(names):
|
||||||
exit_order = kwargs.get("exit_order")
|
exit_order = kwargs.get("exit_order")
|
||||||
if not exit_order:
|
if not exit_order:
|
||||||
|
|
@ -1595,7 +1596,7 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase):
|
||||||
sort_index = {name: key for key, name in enumerate(exit_order)}
|
sort_index = {name: key for key, name in enumerate(exit_order)}
|
||||||
names = sorted(names)
|
names = sorted(names)
|
||||||
end_pos = len(names) + 1
|
end_pos = len(names) + 1
|
||||||
names.sort(key=lambda name:sort_index.get(name, end_pos))
|
names.sort(key=lambda name: sort_index.get(name, end_pos))
|
||||||
return names
|
return names
|
||||||
|
|
||||||
exits = self.filter_visible(self.contents_get(content_type="exit"), looker, **kwargs)
|
exits = self.filter_visible(self.contents_get(content_type="exit"), looker, **kwargs)
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,12 @@ from unittest import skip
|
||||||
from evennia import DefaultCharacter, DefaultExit, DefaultObject, DefaultRoom
|
from evennia import DefaultCharacter, DefaultExit, DefaultObject, DefaultRoom
|
||||||
from evennia.objects.models import ObjectDB
|
from evennia.objects.models import ObjectDB
|
||||||
from evennia.typeclasses.attributes import AttributeProperty
|
from evennia.typeclasses.attributes import AttributeProperty
|
||||||
from evennia.typeclasses.tags import (AliasProperty, PermissionProperty,
|
from evennia.typeclasses.tags import (
|
||||||
TagCategoryProperty, TagProperty)
|
AliasProperty,
|
||||||
|
PermissionProperty,
|
||||||
|
TagCategoryProperty,
|
||||||
|
TagProperty,
|
||||||
|
)
|
||||||
from evennia.utils import create, search
|
from evennia.utils import create, search
|
||||||
from evennia.utils.ansi import strip_ansi
|
from evennia.utils.ansi import strip_ansi
|
||||||
from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTestCase
|
from evennia.utils.test_resources import BaseEvenniaTest, EvenniaTestCase
|
||||||
|
|
@ -102,7 +106,7 @@ class DefaultObjectTest(BaseEvenniaTest):
|
||||||
self.assertEqual(exits, "Exits: out, south, portal, north, and aperture")
|
self.assertEqual(exits, "Exits: out, south, portal, north, and aperture")
|
||||||
|
|
||||||
# in specified order with unspecified exits alpbabetically on the end
|
# in specified order with unspecified exits alpbabetically on the end
|
||||||
exit_order = ('north', 'south', 'out')
|
exit_order = ("north", "south", "out")
|
||||||
exits = strip_ansi(self.room1.get_display_exits(self.char1, exit_order=exit_order))
|
exits = strip_ansi(self.room1.get_display_exits(self.char1, exit_order=exit_order))
|
||||||
self.assertEqual(exits, "Exits: north, south, out, aperture, and portal")
|
self.assertEqual(exits, "Exits: north, south, out, aperture, and portal")
|
||||||
|
|
||||||
|
|
@ -589,7 +593,6 @@ class TestProperties(EvenniaTestCase):
|
||||||
# check cross-instance sharing
|
# check cross-instance sharing
|
||||||
self.assertEqual(obj2.attr5, [], "cross-instance sharing detected")
|
self.assertEqual(obj2.attr5, [], "cross-instance sharing detected")
|
||||||
|
|
||||||
|
|
||||||
def test_mutable_defaults__autocreate_false(self):
|
def test_mutable_defaults__autocreate_false(self):
|
||||||
"""
|
"""
|
||||||
Test https://github.com/evennia/evennia/issues/3488, where a mutable default value (like a
|
Test https://github.com/evennia/evennia/issues/3488, where a mutable default value (like a
|
||||||
|
|
@ -631,7 +634,6 @@ class TestProperties(EvenniaTestCase):
|
||||||
# check cross-instance sharing
|
# check cross-instance sharing
|
||||||
self.assertEqual(obj2.attr7, [])
|
self.assertEqual(obj2.attr7, [])
|
||||||
|
|
||||||
|
|
||||||
def test_mutable_defaults__autocreate_true(self):
|
def test_mutable_defaults__autocreate_true(self):
|
||||||
"""
|
"""
|
||||||
Test mutable defaults with autocreate=True.
|
Test mutable defaults with autocreate=True.
|
||||||
|
|
@ -652,4 +654,3 @@ class TestProperties(EvenniaTestCase):
|
||||||
|
|
||||||
obj1.delete()
|
obj1.delete()
|
||||||
obj2.delete()
|
obj2.delete()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ from copy import copy
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
|
|
||||||
from evennia.locks.lockhandler import LockHandler
|
from evennia.locks.lockhandler import LockHandler
|
||||||
from evennia.utils.dbserialize import from_pickle, to_pickle
|
from evennia.utils.dbserialize import from_pickle, to_pickle
|
||||||
from evennia.utils.idmapper.models import SharedMemoryModel
|
from evennia.utils.idmapper.models import SharedMemoryModel
|
||||||
|
|
|
||||||
|
|
@ -654,29 +654,34 @@ class CmdEditorGroup(CmdEditorBase):
|
||||||
if not self.linerange:
|
if not self.linerange:
|
||||||
lstart = 0
|
lstart = 0
|
||||||
lend = self.cline + 1
|
lend = self.cline + 1
|
||||||
caller.msg(
|
|
||||||
_("Search-replaced {arg1} -> {arg2} for lines {l1}-{l2}.").format(
|
|
||||||
arg1=self.arg1, arg2=self.arg2, l1=lstart + 1, l2=lend
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
caller.msg(
|
|
||||||
_("Search-replaced {arg1} -> {arg2} for {line}.").format(
|
|
||||||
arg1=self.arg1, arg2=self.arg2, line=self.lstr
|
|
||||||
)
|
|
||||||
)
|
|
||||||
sarea = "\n".join(linebuffer[lstart:lend])
|
sarea = "\n".join(linebuffer[lstart:lend])
|
||||||
|
|
||||||
regex = r"%s|^%s(?=\s)|(?<=\s)%s(?=\s)|^%s$|(?<=\s)%s$"
|
regex = r"%s|^%s(?=\s)|(?<=\s)%s(?=\s)|^%s$|(?<=\s)%s$"
|
||||||
regarg = self.arg1.strip("'").strip('"')
|
regarg = self.arg1.strip("'").strip('"')
|
||||||
if " " in regarg:
|
if " " in regarg:
|
||||||
regarg = regarg.replace(" ", " +")
|
regarg = regarg.replace(" ", " +")
|
||||||
sarea = re.sub(
|
try:
|
||||||
regex % (regarg, regarg, regarg, regarg, regarg),
|
sarea = re.sub(
|
||||||
self.arg2.strip("'").strip('"'),
|
regex % (regarg, regarg, regarg, regarg, regarg),
|
||||||
sarea,
|
self.arg2.strip("'").strip('"'),
|
||||||
re.MULTILINE,
|
sarea,
|
||||||
)
|
re.MULTILINE,
|
||||||
|
)
|
||||||
|
except re.error as e:
|
||||||
|
caller.msg(_("Invalid regular expression."))
|
||||||
|
else:
|
||||||
|
if not self.linerange:
|
||||||
|
caller.msg(
|
||||||
|
_("Search-replaced {arg1} -> {arg2} for lines {l1}-{l2}.").format(
|
||||||
|
arg1=self.arg1, arg2=self.arg2, l1=lstart + 1, l2=lend
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
caller.msg(
|
||||||
|
_("Search-replaced {arg1} -> {arg2} for {line}.").format(
|
||||||
|
arg1=self.arg1, arg2=self.arg2, line=self.lstr
|
||||||
|
)
|
||||||
|
)
|
||||||
buf = linebuffer[:lstart] + sarea.split("\n") + linebuffer[lend:]
|
buf = linebuffer[:lstart] + sarea.split("\n") + linebuffer[lend:]
|
||||||
editor.update_buffer(buf)
|
editor.update_buffer(buf)
|
||||||
elif cmd == ":f":
|
elif cmd == ":f":
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue