add test for preserve_items opt and fix
This commit is contained in:
parent
ab317a691e
commit
de24d2646d
2 changed files with 81 additions and 31 deletions
|
|
@ -136,3 +136,30 @@ class TestWilderness(BaseEvenniaTest):
|
||||||
for direction, correct_loc in directions.items():
|
for direction, correct_loc in directions.items():
|
||||||
new_loc = wilderness.get_new_coordinates(loc, direction)
|
new_loc = wilderness.get_new_coordinates(loc, direction)
|
||||||
self.assertEqual(new_loc, correct_loc, direction)
|
self.assertEqual(new_loc, correct_loc, direction)
|
||||||
|
|
||||||
|
def test_preserve_items(self):
|
||||||
|
wilderness.create_wilderness()
|
||||||
|
w = self.get_wilderness_script()
|
||||||
|
|
||||||
|
# move char and obj to wilderness
|
||||||
|
wilderness.enter_wilderness(self.char1)
|
||||||
|
wilderness.enter_wilderness(self.obj1)
|
||||||
|
|
||||||
|
# move to a new room
|
||||||
|
w.move_obj(self.char1, (1, 1))
|
||||||
|
# the room should be remapped and 0,0 should not exist
|
||||||
|
self.assertTrue((0, 0) not in w.db.rooms)
|
||||||
|
self.assertEqual(1, len(w.db.rooms))
|
||||||
|
# verify obj1 moved to None
|
||||||
|
self.assertIsNone(self.obj1.location)
|
||||||
|
|
||||||
|
# now change to preserve items
|
||||||
|
w.preserve_items = True
|
||||||
|
wilderness.enter_wilderness(self.obj1, (1, 1))
|
||||||
|
# move the character again
|
||||||
|
w.move_obj(self.char1, (0, 1))
|
||||||
|
# check that the previous room was preserved
|
||||||
|
self.assertIn((1, 1), w.db.rooms)
|
||||||
|
self.assertEqual(2, len(w.db.rooms))
|
||||||
|
# and verify that obj1 is still at 1,1
|
||||||
|
self.assertEqual(self.obj1.location, w.db.rooms[(1, 1)])
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,11 @@ needs.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
To give an example of how to customize, we will create a very simple (and
|
To give an example of how to customize, we will create a very simple (and
|
||||||
small) wilderness map that is shaped like a pyramid. The map will be
|
small) wilderness map that is shaped like a pyramid. The map will be
|
||||||
provided as a string: a "." symbol is a location we can walk on.
|
provided as a string: a "." symbol is a location we can walk on.
|
||||||
|
|
||||||
Let's create a file world/pyramid.py:
|
Let's create a file world/pyramid.py:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
map_str = '''
|
map_str = '''
|
||||||
|
|
@ -113,7 +113,6 @@ separate rooms.
|
||||||
|
|
||||||
Rooms are created as needed. Unneeded rooms are stored away to avoid the
|
Rooms are created as needed. Unneeded rooms are stored away to avoid the
|
||||||
overhead cost of creating new rooms again in the future.
|
overhead cost of creating new rooms again in the future.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from evennia import (
|
from evennia import (
|
||||||
|
|
@ -126,6 +125,7 @@ from evennia import (
|
||||||
from evennia.utils import inherits_from
|
from evennia.utils import inherits_from
|
||||||
from evennia.typeclasses.attributes import AttributeProperty
|
from evennia.typeclasses.attributes import AttributeProperty
|
||||||
|
|
||||||
|
|
||||||
def create_wilderness(name="default", mapprovider=None):
|
def create_wilderness(name="default", mapprovider=None):
|
||||||
"""
|
"""
|
||||||
Creates a new wilderness map. Does nothing if a wilderness map already
|
Creates a new wilderness map. Does nothing if a wilderness map already
|
||||||
|
|
@ -216,7 +216,7 @@ class WildernessScript(DefaultScript):
|
||||||
# Stores a dictionary of items on the map with their coordinates
|
# Stores a dictionary of items on the map with their coordinates
|
||||||
# The key is the item, the value are the coordinates as (x, y) tuple.
|
# The key is the item, the value are the coordinates as (x, y) tuple.
|
||||||
itemcoordinates = AttributeProperty()
|
itemcoordinates = AttributeProperty()
|
||||||
|
|
||||||
# Determines whether or not rooms are recycled despite containing non-player objects
|
# Determines whether or not rooms are recycled despite containing non-player objects
|
||||||
# True means that leaving behind a non-player object will prevent the room from being recycled
|
# True means that leaving behind a non-player object will prevent the room from being recycled
|
||||||
# in order to preserve the object
|
# in order to preserve the object
|
||||||
|
|
@ -241,7 +241,7 @@ class WildernessScript(DefaultScript):
|
||||||
# allows quick retrieval if a new room is needed without having to
|
# allows quick retrieval if a new room is needed without having to
|
||||||
# create it.
|
# create it.
|
||||||
self.db.unused_rooms = []
|
self.db.unused_rooms = []
|
||||||
|
|
||||||
def at_server_start(self):
|
def at_server_start(self):
|
||||||
"""
|
"""
|
||||||
Called after the server is started or reloaded.
|
Called after the server is started or reloaded.
|
||||||
|
|
@ -249,7 +249,6 @@ class WildernessScript(DefaultScript):
|
||||||
for coordinates, room in self.db.rooms.items():
|
for coordinates, room in self.db.rooms.items():
|
||||||
room.ndb.wildernessscript = self
|
room.ndb.wildernessscript = self
|
||||||
room.ndb.active_coordinates = coordinates
|
room.ndb.active_coordinates = coordinates
|
||||||
self.wilderness.mapprovider.at_prepare_room(coordinates, None, self)
|
|
||||||
for item in self.db.itemcoordinates.keys():
|
for item in self.db.itemcoordinates.keys():
|
||||||
# Items deleted while in the wilderness can leave None-type 'ghosts'
|
# Items deleted while in the wilderness can leave None-type 'ghosts'
|
||||||
# These need to be cleaned up
|
# These need to be cleaned up
|
||||||
|
|
@ -299,7 +298,11 @@ class WildernessScript(DefaultScript):
|
||||||
Returns:
|
Returns:
|
||||||
[Object, ]: list of Objects at coordinates
|
[Object, ]: list of Objects at coordinates
|
||||||
"""
|
"""
|
||||||
result = [ item for item, item_coords in self.itemcoordinates.items() if item_coords == coordinates and item is not None ]
|
result = [
|
||||||
|
item
|
||||||
|
for item, item_coords in self.itemcoordinates.items()
|
||||||
|
if item_coords == coordinates and item is not None
|
||||||
|
]
|
||||||
return list(result)
|
return list(result)
|
||||||
|
|
||||||
def move_obj(self, obj, new_coordinates):
|
def move_obj(self, obj, new_coordinates):
|
||||||
|
|
@ -318,38 +321,56 @@ class WildernessScript(DefaultScript):
|
||||||
# appear in its old room should that room be deleted.
|
# appear in its old room should that room be deleted.
|
||||||
obj.location = None
|
obj.location = None
|
||||||
|
|
||||||
# By default, we'll assume we won't be making a new room and change this flag if necessary.
|
|
||||||
create_room = False
|
|
||||||
|
|
||||||
# See if we already have a room for that location
|
# See if we already have a room for that location
|
||||||
if room := self.db.rooms.get(new_coordinates):
|
if room := self.db.rooms.get(new_coordinates):
|
||||||
# There is. Try to destroy the old_room if it is not needed anymore
|
# There is. Try to destroy the old_room if it is not needed anymore
|
||||||
self._destroy_room(old_room)
|
self._destroy_room(old_room)
|
||||||
else:
|
else:
|
||||||
# There is no room yet at new_location
|
# There is no room yet at new_location
|
||||||
# Is the old room in this wilderness?
|
# Is the old room in a wilderness?
|
||||||
if old_room in self.db.rooms.keys():
|
if hasattr(old_room, "wilderness"):
|
||||||
# Is there anything still left in the old_room, besides the exits?
|
# Yes. Is it in THIS wilderness?
|
||||||
if len([ob for ob in old_room.contents if not inherits_from(ob, WildernessExit)]):
|
if old_room.wilderness == self:
|
||||||
# There is, so we'll create a new room
|
# Should we preserve rooms with any objects?
|
||||||
room = self._create_room(new_coordinates, obj)
|
if self.preserve_items:
|
||||||
else:
|
# Yes - check if ANY objects besides the exits are in old_room
|
||||||
# The room is empty, so we'll just reuse it
|
if len(
|
||||||
room = old_room
|
[
|
||||||
|
ob
|
||||||
|
for ob in old_room.contents
|
||||||
|
if not inherits_from(ob, WildernessExit)
|
||||||
|
]
|
||||||
|
):
|
||||||
|
# There is, so we'll create a new room
|
||||||
|
room = self._create_room(new_coordinates, obj)
|
||||||
|
else:
|
||||||
|
# The room is empty, so we'll reuse it
|
||||||
|
room = old_room
|
||||||
|
else:
|
||||||
|
# Only preserve rooms if there are players behind
|
||||||
|
if len([ob for ob in old_room.contents if ob.has_account]):
|
||||||
|
# There is still a player there; create a new room
|
||||||
|
room = self._create_room(new_coordinates, obj)
|
||||||
|
else:
|
||||||
|
# The room is empty of players, so we'll reuse it
|
||||||
|
room = old_room
|
||||||
|
|
||||||
# Is the previous room from a different wilderness?
|
# It's in a different wilderness
|
||||||
elif inherits_from(old_room, WildernessRoom) and old_room.wilderness != self:
|
else:
|
||||||
# It does, so we make sure to leave the other wilderness properly
|
# It does, so we make sure to leave the other wilderness properly
|
||||||
old_room.wilderness.at_post_object_leave(obj)
|
old_room.wilderness.at_post_object_leave(obj)
|
||||||
# We'll also need to create a new room in this wilderness
|
# We'll also need to create a new room in this wilderness
|
||||||
room = self._create_room(new_coordinates, obj)
|
room = self._create_room(new_coordinates, obj)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Obj comes from outside the wilderness entirely
|
# Obj comes from outside the wilderness entirely
|
||||||
# We need to make a new room
|
# We need to make a new room
|
||||||
room = self._create_room(new_coordinates, obj)
|
room = self._create_room(new_coordinates, obj)
|
||||||
|
|
||||||
room.set_active_coordinates(new_coordinates, obj)
|
# Set `room` to the new coordinates, however it was made
|
||||||
|
room.set_active_coordinates(new_coordinates, obj)
|
||||||
|
|
||||||
|
# Put obj back, now in the correct room
|
||||||
obj.location = room
|
obj.location = room
|
||||||
obj.ndb.wilderness = self
|
obj.ndb.wilderness = self
|
||||||
|
|
||||||
|
|
@ -407,7 +428,7 @@ class WildernessScript(DefaultScript):
|
||||||
"""
|
"""
|
||||||
Moves a room back to storage. If room is not a WildernessRoom or there
|
Moves a room back to storage. If room is not a WildernessRoom or there
|
||||||
is something left inside the room, then this does nothing.
|
is something left inside the room, then this does nothing.
|
||||||
|
|
||||||
Implementation note: If `preserve_items` is False (the default) then any
|
Implementation note: If `preserve_items` is False (the default) then any
|
||||||
objects left in the rooms will be moved to None. You may want to implement
|
objects left in the rooms will be moved to None. You may want to implement
|
||||||
your own cleanup or recycling routine for these objects.
|
your own cleanup or recycling routine for these objects.
|
||||||
|
|
@ -555,6 +576,7 @@ class WildernessRoom(DefaultRoom):
|
||||||
rooms[self.coordinates] = self
|
rooms[self.coordinates] = self
|
||||||
|
|
||||||
# Any object inside this room will get its location set to None
|
# Any object inside this room will get its location set to None
|
||||||
|
# unless it's a wilderness exit
|
||||||
for item in self.contents:
|
for item in self.contents:
|
||||||
if not item.destination or item.destination != item.location:
|
if not item.destination or item.destination != item.location:
|
||||||
item.location = None
|
item.location = None
|
||||||
|
|
@ -608,11 +630,11 @@ class WildernessRoom(DefaultRoom):
|
||||||
|
|
||||||
name += " {0}".format(self.coordinates)
|
name += " {0}".format(self.coordinates)
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def get_display_desc(self, looker, **kwargs):
|
def get_display_desc(self, looker, **kwargs):
|
||||||
"""
|
"""
|
||||||
Displays the description of the room. This is a core evennia hook.
|
Displays the description of the room. This is a core evennia hook.
|
||||||
|
|
||||||
Allows the room's description to be customized in an ndb value,
|
Allows the room's description to be customized in an ndb value,
|
||||||
avoiding having to write to the database on moving.
|
avoiding having to write to the database on moving.
|
||||||
"""
|
"""
|
||||||
|
|
@ -624,6 +646,7 @@ class WildernessRoom(DefaultRoom):
|
||||||
# Otherwise, use the normal description hook.
|
# Otherwise, use the normal description hook.
|
||||||
return super().get_display_desc(looker, **kwargs)
|
return super().get_display_desc(looker, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class WildernessExit(DefaultExit):
|
class WildernessExit(DefaultExit):
|
||||||
"""
|
"""
|
||||||
This is an Exit object used inside a WildernessRoom. Instead of changing
|
This is an Exit object used inside a WildernessRoom. Instead of changing
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue