mirror of
https://github.com/evennia/evennia.git
synced 2026-03-26 09:46:32 +01:00
Start add evennia xyzgrid launch command
This commit is contained in:
parent
0e3ce49a5a
commit
2af82b19e1
4 changed files with 266 additions and 7 deletions
181
evennia/contrib/xyzgrid/launchcmd.py
Normal file
181
evennia/contrib/xyzgrid/launchcmd.py
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
"""
|
||||
Custom Evennia launcher command option for building/rebuilding the grid in a separate process than
|
||||
the main server (since this can be slow).
|
||||
|
||||
To use, add to the settings:
|
||||
::
|
||||
|
||||
EXTRA_LAUNCHER_COMMANDS.update({'xyzgrid': 'evennia.contrib.xyzgrid.launchcmd.xyzcommand'})
|
||||
|
||||
You should now be able to do
|
||||
::
|
||||
|
||||
evennia xyzgrid <options>
|
||||
|
||||
Use `evennia xyzgrid help` for usage help.
|
||||
|
||||
"""
|
||||
|
||||
from evennia.contrib.xyzgrid.xyzgrid import get_xyzgrid
|
||||
|
||||
_HELP_SHORT = """
|
||||
evennia xyzgrid help|list|init|add|build|initpath|delete [<options>]
|
||||
Manages the XYZ grid. Use 'xyzgrid help' for documentation.
|
||||
"""
|
||||
|
||||
_HELP_LONG = """
|
||||
evennia xyzgrid list
|
||||
|
||||
Lists the map grid structure and any loaded maps.
|
||||
|
||||
evennia xyzgrid list Z|mapname
|
||||
|
||||
Display the given XYmap in more detail. Also 'show' works.
|
||||
|
||||
evennia xyzgrid init
|
||||
|
||||
First start of the grid. This will create the XYZGrid global script. No maps are loaded yet!
|
||||
It's safe to run this command multiple times; the grid will only be initialized once.
|
||||
|
||||
evennia xyzgrid add path.to.xymap.module
|
||||
|
||||
Add one or more XYmaps (each a string-map representing one Z position along with prototypes
|
||||
etc). The module will be parsed for
|
||||
|
||||
- a XYMAP_DATA a dict
|
||||
{"map": mapstring, "zcoord": mapname/zcoord, "legend": dict, "prototypes": dict}
|
||||
describing one single XYmap, or
|
||||
- a XYMAP_LIST - a list of multiple dicts on the XYMAP_DATA form. This allows to load
|
||||
multiple maps from the same module.
|
||||
|
||||
Note that adding a map does *not* build it. If maps are linked to one another, you should add
|
||||
all linked maps before building, or you'll get errors when spawning the linking exits.
|
||||
|
||||
evennia xyzgrid build
|
||||
|
||||
Builds/updates the entire database grid based on the added maps. For a new grid, this will spawn
|
||||
all new rooms/exits (and may take a good while!). For updating, rooms may be removed/spawned if
|
||||
a map changed since the last build.
|
||||
|
||||
evennia xyzgrid build (X,Y,Z|mapname)
|
||||
|
||||
Builds/updates only a part of the grid. This should usually only be used if the full grid has
|
||||
already been built once - otherwise inter-map transitions may fail! Z is the name/z-coordinate
|
||||
of the map. Use '*' as a wildcard. For example (*, *, mymap) will only update map `mymap` and
|
||||
(12, 6, mymap) will only update position (12, 6) on the map 'mymap'.
|
||||
|
||||
evennia xyzgrid initpath
|
||||
|
||||
Recreates the pathfinder matrices for the entire grid. These are used for all shortest-path
|
||||
calculations. The result will be cached to disk (in mygame/server/.cache/). If not run, each map
|
||||
will run this automatically first time it's used. Running this will always force to rebuild the
|
||||
cache.
|
||||
|
||||
evennia xyzgrid initpath Z|mapname
|
||||
|
||||
recreate the pathfinder matrix for a specific map only. Z is the name/z-coordinate of the map.
|
||||
|
||||
evennia xyzgrid delete Z|mapname
|
||||
|
||||
Remove a previously added XYmap with the name/z-coordinate Z. E.g. 'remove mymap'. If the map
|
||||
was built, this will also wipe all its spawned rooms/exits. You will be asked to confirm before
|
||||
continuing with this operation.
|
||||
|
||||
evennia xyzgrid delete
|
||||
|
||||
WARNING: This will delete the entire xyz-grid (all maps), and *all* rooms/exits built to match
|
||||
it (they serve no purpose without the grid). You will be asked to confirm before continuing with
|
||||
this operation.
|
||||
|
||||
"""
|
||||
|
||||
def _option_list(**suboptions):
|
||||
"""
|
||||
List/view grid.
|
||||
|
||||
"""
|
||||
xyzgrid = get_xyzgrid()
|
||||
xymap_data = xyzgrid.grid
|
||||
if not xymap_data:
|
||||
print("The XYZgrid is currently empty. Use 'add' to add paths to your map data.")
|
||||
return
|
||||
|
||||
if not suboptions:
|
||||
print("XYMaps stored in grid:")
|
||||
for zcoord, xymap in sorted(xymap_data.items(), key=lambda tup: tup[0]):
|
||||
print(str(xymap))
|
||||
|
||||
|
||||
def _option_init(**suboptions):
|
||||
"""
|
||||
Initialize a new grid. Will fail if a Grid already exists.
|
||||
|
||||
"""
|
||||
grid = get_xyzgrid()
|
||||
print(f"The grid is initalized as the Script 'XYZGrid'({grid.dbref})")
|
||||
|
||||
def _option_add(**suboptions):
|
||||
"""
|
||||
Add a new map to the grid.
|
||||
|
||||
"""
|
||||
|
||||
def _option_build(**suboptions):
|
||||
"""
|
||||
Build the grid or part of it.
|
||||
|
||||
"""
|
||||
|
||||
def _option_initpath(**suboptions):
|
||||
"""
|
||||
Initialize the pathfinding matrices for grid or part of it.
|
||||
|
||||
"""
|
||||
|
||||
def _option_delete(**suboptions):
|
||||
"""
|
||||
Delete the grid or parts of it.
|
||||
|
||||
"""
|
||||
|
||||
if not suboptions:
|
||||
repl = input("WARNING: This will delete the ENTIRE Grid and wipe all rooms/exits!"
|
||||
"\nObjects/Chars inside deleted rooms will be moved to their home locations."
|
||||
"\nThis can't be undone. Are you sure you want to continue? Y/[N]?")
|
||||
if repl.lower() not in ('yes', 'y'):
|
||||
print("Aborted.")
|
||||
else:
|
||||
print("Deleting grid ...")
|
||||
grid = get_xyzgrid()
|
||||
grid.delete()
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
def xyzcommand(*args):
|
||||
"""
|
||||
Evennia launcher command. This is made available as `evennia xyzgrid` on the command line,
|
||||
once `settings.EXTRA_LAUNCHER_COMMANDS` is updated.
|
||||
|
||||
"""
|
||||
if not args:
|
||||
print(_HELP_SHORT.strip())
|
||||
return
|
||||
|
||||
option, *suboptions = args
|
||||
|
||||
if option in ('help', 'h'):
|
||||
print(f"{_HELP_SHORT.strip()}\n{_HELP_LONG.rstrip()}")
|
||||
|
||||
if option in ('list', 'show'):
|
||||
_option_list(*suboptions)
|
||||
elif option == 'init':
|
||||
_option_init(*suboptions)
|
||||
elif option == 'add':
|
||||
_option_add(*suboptions)
|
||||
elif option == 'build':
|
||||
_option_build(*suboptions)
|
||||
elif option == 'initpath':
|
||||
_option_initpath(*suboptions)
|
||||
elif option == 'delete':
|
||||
_option_delete(*suboptions)
|
||||
|
|
@ -62,3 +62,7 @@ MAP_DATA = {
|
|||
"legend": LEGEND,
|
||||
"rooms": ROOMS,
|
||||
}
|
||||
|
||||
XYMAP_LIST = [
|
||||
MAP_DATA
|
||||
]
|
||||
|
|
|
|||
35
evennia/contrib/xyzgrid/prototypes.py
Normal file
35
evennia/contrib/xyzgrid/prototypes.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
"""
|
||||
Prototypes for building the XYZ-grid into actual game-rooms.
|
||||
|
||||
Add this to mygame/conf/settings/settings.py:
|
||||
|
||||
PROTOTYPE_MODULES += ['evennia.contrib.xyzgrid.prototypes']
|
||||
|
||||
"""
|
||||
|
||||
# Note - the XYZRoom/exit parents track the XYZ coordinates automatically
|
||||
# so we don't need to add custom tags to them here.
|
||||
_ROOM_PARENT = {
|
||||
'prototype_tags': ("xyzroom", ),
|
||||
'typeclass': 'evennia.contrib.xyzgrid.xyzroom.XYZRoom'
|
||||
}
|
||||
|
||||
_EXIT_PARENT = {
|
||||
'prototype_tags': ("xyzexit", ),
|
||||
'typeclass': 'evennia.contrib.xyzgrid.xyzroom.XYZExit'
|
||||
}
|
||||
|
||||
PROTOTYPE_LIST = [
|
||||
{
|
||||
'prototype_key': 'xyz_room_prototype',
|
||||
'prototype_parent': _ROOM_PARENT,
|
||||
'key': "A non-descript room",
|
||||
},{
|
||||
'prototype_key': 'xyz_transition_room_prototype',
|
||||
'prototype_parent': _ROOM_PARENT,
|
||||
'typeclass': 'evennia.contrib.xyzgrid.xyzroom.XYZMapTransitionRoom',
|
||||
},{
|
||||
'prototype_key': 'xyz_exit_prototype',
|
||||
'prototype_parent': _EXIT_PARENT,
|
||||
}
|
||||
]
|
||||
|
|
@ -16,11 +16,10 @@ The grid has three main functions:
|
|||
|
||||
|
||||
"""
|
||||
import itertools
|
||||
from evennia.scripts.scripts import DefaultScript
|
||||
from evennia.utils import logger
|
||||
from .xymap import XYMap
|
||||
from .xyzroom import XYZRoom, XYZExit
|
||||
from .xyzroom import XYZRoom
|
||||
|
||||
|
||||
class XYZGrid(DefaultScript):
|
||||
|
|
@ -41,8 +40,28 @@ class XYZGrid(DefaultScript):
|
|||
self.reload()
|
||||
return self.ndb.grid
|
||||
|
||||
def get(self, mapname, default=None):
|
||||
return self.grid.get(mapname, default)
|
||||
def get(self, zcoord):
|
||||
"""
|
||||
Get a specific xymap.
|
||||
|
||||
Args:
|
||||
zcoord (str): The name/zcoord of the xymap.
|
||||
|
||||
Returns:
|
||||
XYMap: Or None if no map was found.
|
||||
|
||||
"""
|
||||
return self.grid.get(zcoord)
|
||||
|
||||
def all(self):
|
||||
"""
|
||||
Get all xymaps stored in the grid.
|
||||
|
||||
Returns:
|
||||
dict: All initialized xymaps stored with this grid.
|
||||
|
||||
"""
|
||||
return self.grid
|
||||
|
||||
def reload(self):
|
||||
"""
|
||||
|
|
@ -119,10 +138,11 @@ class XYZGrid(DefaultScript):
|
|||
|
||||
def delete(self):
|
||||
"""
|
||||
Clear the entire grid, including database entities.
|
||||
Clear the entire grid, including database entities, then the grid too.
|
||||
|
||||
"""
|
||||
self.remove_map(*(zcoord for zcoord in self.db.map_data), remove_objects=True)
|
||||
super().delete()
|
||||
|
||||
def spawn(self, xyz=('*', '*', '*'), directions=None):
|
||||
"""
|
||||
|
|
@ -161,5 +181,24 @@ class XYZGrid(DefaultScript):
|
|||
|
||||
# next build all links between nodes (including between maps)
|
||||
for zcoord, xymap in xymaps.items():
|
||||
logger.log_info(f"[grid] spawning/updating links for {zcoord} ...")
|
||||
xymap.spawn_links(xy=(x, y), directions=directions)
|
||||
logger.log_info(f"[grid] spawning/updating links for {zcoord} ...")
|
||||
xymap.spawn_links(xy=(x, y), directions=directions)
|
||||
|
||||
|
||||
def get_xyzgrid():
|
||||
"""
|
||||
Helper for getting the grid. This will create the XYZGrid global script if it didn't
|
||||
previously exist.
|
||||
|
||||
"""
|
||||
xyzgrid = XYZGrid.objects.all()
|
||||
if not xyzgrid:
|
||||
# create a new one
|
||||
xyzgrid, err = XYZGrid.create("XYZGrid")
|
||||
if err:
|
||||
raise RuntimeError(err)
|
||||
return xyzgrid
|
||||
elif len(xyzgrid) > 1:
|
||||
("Warning: More than one XYZGrid instances were found. This is an error and "
|
||||
"only the first one will be used. Delete the other one(s) manually.")
|
||||
return xyzgrid[0]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue