update wilderness contrib
This commit is contained in:
parent
86318b7559
commit
a69f416162
1 changed files with 83 additions and 97 deletions
|
|
@ -34,10 +34,11 @@ The defaults, while useable, are meant to be customised. When creating a
|
||||||
new wilderness map it is possible to give a "map provider": this is a
|
new wilderness map it is possible to give a "map provider": this is a
|
||||||
python object that is smart enough to create the map.
|
python object that is smart enough to create the map.
|
||||||
|
|
||||||
The default provider, `WildernessMapProvider`, just creates a grid area that
|
The default provider, `WildernessMapProvider`, creates a grid area that
|
||||||
is unlimited in size.
|
is unlimited in size.
|
||||||
This `WildernessMapProvider` can be subclassed to create more interesting
|
|
||||||
maps and also to customize the room/exit typeclass used.
|
`WildernessMapProvider` can be subclassed to create more interesting maps
|
||||||
|
and also to customize the room/exit typeclass used.
|
||||||
|
|
||||||
There is also no command that allows players to enter the wilderness. This
|
There is also no command that allows players to enter the wilderness. This
|
||||||
still needs to be added: it can be a command or an exit, depending on your
|
still needs to be added: it can be a command or an exit, depending on your
|
||||||
|
|
@ -121,7 +122,7 @@ from evennia import (
|
||||||
create_script,
|
create_script,
|
||||||
)
|
)
|
||||||
from evennia.utils import inherits_from
|
from evennia.utils import inherits_from
|
||||||
|
from evennia.typeclasses.attributes import AttributeProperty
|
||||||
|
|
||||||
def create_wilderness(name="default", mapprovider=None):
|
def create_wilderness(name="default", mapprovider=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -161,10 +162,12 @@ def enter_wilderness(obj, coordinates=(0, 0), name="default"):
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if obj successfully moved into the wilderness.
|
bool: True if obj successfully moved into the wilderness.
|
||||||
"""
|
"""
|
||||||
if not WildernessScript.objects.filter(db_key=name).exists():
|
script = WildernessScript.objects.filter(db_key=name)
|
||||||
|
if not script.exists():
|
||||||
return False
|
return False
|
||||||
|
else:
|
||||||
|
script = script[0]
|
||||||
|
|
||||||
script = WildernessScript.objects.get(db_key=name)
|
|
||||||
if script.is_valid_coordinates(coordinates):
|
if script.is_valid_coordinates(coordinates):
|
||||||
script.move_obj(obj, coordinates)
|
script.move_obj(obj, coordinates)
|
||||||
return True
|
return True
|
||||||
|
|
@ -205,6 +208,18 @@ class WildernessScript(DefaultScript):
|
||||||
into storage when they are not needed anymore.
|
into storage when they are not needed anymore.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Stores the MapProvider class
|
||||||
|
mapprovider = AttributeProperty()
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
itemcoordinates = AttributeProperty()
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# in order to preserve the object
|
||||||
|
preserve_items = AttributeProperty(default=False)
|
||||||
|
|
||||||
def at_script_creation(self):
|
def at_script_creation(self):
|
||||||
"""
|
"""
|
||||||
Only called once, when the script is created. This is a default Evennia
|
Only called once, when the script is created. This is a default Evennia
|
||||||
|
|
@ -225,38 +240,15 @@ class WildernessScript(DefaultScript):
|
||||||
# create it.
|
# create it.
|
||||||
self.db.unused_rooms = []
|
self.db.unused_rooms = []
|
||||||
|
|
||||||
@property
|
def at_server_start(self):
|
||||||
def mapprovider(self):
|
|
||||||
"""
|
"""
|
||||||
Shortcut property to the map provider.
|
Called after the server is started or reloaded.
|
||||||
|
|
||||||
Returns:
|
|
||||||
MapProvider: the mapprovider used with this wilderness
|
|
||||||
"""
|
|
||||||
return self.db.mapprovider
|
|
||||||
|
|
||||||
@property
|
|
||||||
def itemcoordinates(self):
|
|
||||||
"""
|
|
||||||
Returns a dictionary with the coordinates of every item inside this
|
|
||||||
wilderness map. The key is the item, the value are the coordinates as
|
|
||||||
(x, y) tuple.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
{item: coordinates}
|
|
||||||
"""
|
|
||||||
return self.db.itemcoordinates
|
|
||||||
|
|
||||||
def at_start(self):
|
|
||||||
"""
|
|
||||||
Called when the script is started and also after server reloads.
|
|
||||||
"""
|
"""
|
||||||
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
|
||||||
for item in list(self.db.itemcoordinates.keys()):
|
for item in self.db.itemcoordinates.keys():
|
||||||
# Items deleted from the wilderness leave None type 'ghosts'
|
# Items deleted from the wilderness can leave None type 'ghosts'
|
||||||
# that must be cleaned out
|
|
||||||
if item is None:
|
if item is None:
|
||||||
del self.db.itemcoordinates[item]
|
del self.db.itemcoordinates[item]
|
||||||
continue
|
continue
|
||||||
|
|
@ -303,15 +295,7 @@ class WildernessScript(DefaultScript):
|
||||||
Returns:
|
Returns:
|
||||||
[Object, ]: list of Objects at coordinates
|
[Object, ]: list of Objects at coordinates
|
||||||
"""
|
"""
|
||||||
result = []
|
result = [ item for item, item_coords in self.itemcoordinates.items() if item_coords == coordinates and item is not None ]
|
||||||
for item, item_coordinates in list(self.itemcoordinates.items()):
|
|
||||||
# Items deleted from the wilderness leave None type 'ghosts'
|
|
||||||
# that must be cleaned out
|
|
||||||
if item is None:
|
|
||||||
del self.db.itemcoordinates[item]
|
|
||||||
continue
|
|
||||||
if coordinates == item_coordinates:
|
|
||||||
result.append(item)
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def move_obj(self, obj, new_coordinates):
|
def move_obj(self, obj, new_coordinates):
|
||||||
|
|
@ -330,44 +314,37 @@ 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
|
||||||
|
|
||||||
try:
|
# By default, we'll assume we won't be making a new room and change this flag if necessary.
|
||||||
# See if we already have a room for that location
|
create_room = False
|
||||||
room = self.db.rooms[new_coordinates]
|
|
||||||
|
# See if we already have a room for that location
|
||||||
|
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)
|
||||||
except KeyError:
|
else:
|
||||||
# There is no room yet at new_location
|
# There is no room yet at new_location
|
||||||
if (old_room and not inherits_from(old_room, WildernessRoom)) or (not old_room):
|
# Is the old room in this wilderness?
|
||||||
# Obj doesn't originally come from a wilderness room.
|
if old_room in self.db.rooms.keys():
|
||||||
# We'll create a new one then.
|
# Is there anything still left in the old_room, besides the exits?
|
||||||
room = self._create_room(new_coordinates, obj)
|
if len([ob for ob in old_room.contents if not inherits_from(ob, WildernessExit)]):
|
||||||
else:
|
# There is, so we'll create a new room
|
||||||
# Obj does come from another wilderness room
|
|
||||||
create_new_room = False
|
|
||||||
|
|
||||||
if old_room.wilderness != self:
|
|
||||||
# ... but that other wilderness room belongs to another
|
|
||||||
# wilderness map
|
|
||||||
create_new_room = True
|
|
||||||
old_room.wilderness.at_post_object_leave(obj)
|
|
||||||
else:
|
|
||||||
for item in old_room.contents:
|
|
||||||
if item.has_account:
|
|
||||||
# There is still a player in the old room.
|
|
||||||
# Let's create a new room and not touch that old
|
|
||||||
# room.
|
|
||||||
create_new_room = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if create_new_room:
|
|
||||||
# Create a new room to hold obj, not touching any obj's in
|
|
||||||
# the old room
|
|
||||||
room = self._create_room(new_coordinates, obj)
|
room = self._create_room(new_coordinates, obj)
|
||||||
else:
|
else:
|
||||||
# The old_room is empty: we are just going to reuse that
|
# The room is empty, so we'll just reuse it
|
||||||
# room instead of creating a new one
|
|
||||||
room = old_room
|
room = old_room
|
||||||
|
|
||||||
|
# Is the previous room from a different wilderness?
|
||||||
|
elif inherits_from(old_room, WildernessRoom) and old_room.wilderness != self:
|
||||||
|
# It does, so we make sure to leave the other wilderness properly
|
||||||
|
old_room.wilderness.at_post_object_leave(obj)
|
||||||
|
# We'll also need to create a new room in this wilderness
|
||||||
|
room = self._create_room(new_coordinates, obj)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Obj comes from outside the wilderness entirely
|
||||||
|
# We need to make a new room
|
||||||
|
room = self._create_room(new_coordinates, obj)
|
||||||
|
|
||||||
room.set_active_coordinates(new_coordinates, obj)
|
room.set_active_coordinates(new_coordinates, obj)
|
||||||
obj.location = room
|
obj.location = room
|
||||||
obj.ndb.wilderness = self
|
obj.ndb.wilderness = self
|
||||||
|
|
@ -425,7 +402,11 @@ class WildernessScript(DefaultScript):
|
||||||
def _destroy_room(self, room):
|
def _destroy_room(self, room):
|
||||||
"""
|
"""
|
||||||
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 a player 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
|
||||||
|
objects left in the rooms will be moved to None. You may want to implement
|
||||||
|
your own cleanup or recycling routine for these objects.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
room (WildernessRoom): the room to put in storage
|
room (WildernessRoom): the room to put in storage
|
||||||
|
|
@ -433,25 +414,30 @@ class WildernessScript(DefaultScript):
|
||||||
if not room or not inherits_from(room, WildernessRoom):
|
if not room or not inherits_from(room, WildernessRoom):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Check the contents of the room before recycling
|
||||||
for item in room.contents:
|
for item in room.contents:
|
||||||
if item.has_account:
|
if item.has_account:
|
||||||
# There is still a character in that room. We can't get rid of
|
# There is still a player in this room, we can't delete it yet.
|
||||||
# it just yet
|
return
|
||||||
break
|
|
||||||
else:
|
|
||||||
# No characters left in the room.
|
|
||||||
|
|
||||||
# Clear the location of every obj in that room first
|
if not (item.destination and item.destination == room):
|
||||||
for item in room.contents:
|
# There is still a non-exit object in the room. Should we preserve it?
|
||||||
if item.destination and item.destination == room:
|
if self.preserve_items:
|
||||||
# Ignore the exits, they stay in the room
|
# Yes, so we can't get rid of the room just yet
|
||||||
continue
|
return
|
||||||
item.location = None
|
|
||||||
|
|
||||||
# Then delete its reference
|
# If we get here, the room can be recycled
|
||||||
del self.db.rooms[room.ndb.active_coordinates]
|
# Clear the location of any objects left in that room first
|
||||||
# And finally put this room away in storage
|
for item in room.contents:
|
||||||
self.db.unused_rooms.append(room)
|
if item.destination and item.destination == room:
|
||||||
|
# Ignore the exits, they stay in the room
|
||||||
|
continue
|
||||||
|
item.location = None
|
||||||
|
|
||||||
|
# Then delete its coordinate reference
|
||||||
|
del self.db.rooms[room.ndb.active_coordinates]
|
||||||
|
# And finally put this room away in storage
|
||||||
|
self.db.unused_rooms.append(room)
|
||||||
|
|
||||||
def at_post_object_leave(self, obj):
|
def at_post_object_leave(self, obj):
|
||||||
"""
|
"""
|
||||||
|
|
@ -460,13 +446,13 @@ class WildernessScript(DefaultScript):
|
||||||
Args:
|
Args:
|
||||||
obj (object): the object that left
|
obj (object): the object that left
|
||||||
"""
|
"""
|
||||||
# Remove that obj from the wilderness's coordinates dict
|
# Try removing the object from the coordinates system
|
||||||
loc = self.db.itemcoordinates[obj]
|
if loc := self.db.itemcoordinates.pop(obj, None):
|
||||||
del self.db.itemcoordinates[obj]
|
# The object was removed successfully
|
||||||
|
# Make sure there was a room at that location
|
||||||
# And see if we can put that room away into storage.
|
if room := self.db.rooms.get(loc):
|
||||||
room = self.db.rooms[loc]
|
# If so, try to clean up the room
|
||||||
self._destroy_room(room)
|
self._destroy_room(room)
|
||||||
|
|
||||||
|
|
||||||
class WildernessRoom(DefaultRoom):
|
class WildernessRoom(DefaultRoom):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue