Merge branch 'evennia:main' into hex_colors

This commit is contained in:
Michael Faith 2024-04-07 14:27:50 -07:00 committed by GitHub
commit aa9ed83a26
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 55 additions and 31 deletions

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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")

View file

@ -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

View file

@ -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)

View file

@ -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()

View file

@ -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

View file

@ -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":