Continue with doc writing for xyzgrid

This commit is contained in:
Griatch 2021-07-21 01:35:57 +02:00
parent cf3cbed5d2
commit a140c68247
10 changed files with 1285 additions and 264 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
# Toc # Toc
- [API root](api/evennia-api.rst)
- [Coding/Coding Introduction](Coding/Coding-Introduction) - [Coding/Coding Introduction](Coding/Coding-Introduction)
- [Coding/Coding Overview](Coding/Coding-Overview) - [Coding/Coding Overview](Coding/Coding-Overview)
- [Coding/Continuous Integration](Coding/Continuous-Integration) - [Coding/Continuous Integration](Coding/Continuous-Integration)
@ -82,6 +82,7 @@
- [Contribs/Dialogues in events](Contribs/Dialogues-in-events) - [Contribs/Dialogues in events](Contribs/Dialogues-in-events)
- [Contribs/Dynamic In Game Map](Contribs/Dynamic-In-Game-Map) - [Contribs/Dynamic In Game Map](Contribs/Dynamic-In-Game-Map)
- [Contribs/Static In Game Map](Contribs/Static-In-Game-Map) - [Contribs/Static In Game Map](Contribs/Static-In-Game-Map)
- [Contribs/XYZGrid](Contribs/XYZGrid)
- [./Contributing](./Contributing) - [./Contributing](./Contributing)
- [./Contributing Docs](./Contributing-Docs) - [./Contributing Docs](./Contributing-Docs)
- [./Evennia API](./Evennia-API) - [./Evennia API](./Evennia-API)

View file

@ -16,7 +16,7 @@ your current visual-range and a lot of related features.
The rooms of the grid are entirely controlled from outside the game, using The rooms of the grid are entirely controlled from outside the game, using
python modules with strings and dicts defining the map(s) of the game. It's python modules with strings and dicts defining the map(s) of the game. It's
possible to combine grid- with non-grid rooms, and you can decorate possible to combine grid- with non-grid rooms, and you can decorate
grid rooms as much as you like in-game, but you cannot build new grid grid rooms as much as you like in-game, but you cannot spawn new grid
rooms without editing the map files outside of the game. rooms without editing the map files outside of the game.
The full docs are found as The full docs are found as
@ -33,7 +33,7 @@ in the docs.
EXTRA_LAUNCHER_COMMANDS['xyzgrid'] = 'evennia.contrib.launchcmd.xyzcommand' EXTRA_LAUNCHER_COMMANDS['xyzgrid'] = 'evennia.contrib.launchcmd.xyzcommand'
3. Run the new `evennia xyzgrid help` for instructions on how to build the grid. 3. Run the new `evennia xyzgrid help` for instructions on how to spawn the grid.
## Example usage ## Example usage
@ -41,14 +41,14 @@ After installation, do the following (from your command line, where the
`evennia` command is available) to install an example grid: `evennia` command is available) to install an example grid:
evennia xyzgrid init evennia xyzgrid init
evennia xyzgrid add evennia.contrib.xyzgrid.map_example evennia xyzgrid add evennia.contrib.xyzgrid.example
evennia xyzgrid list evennia xyzgrid list
evennia xyzgrid show "the large tree" evennia xyzgrid show "the large tree"
evennia xyzgrid show "the small cave" evennia xyzgrid show "the small cave"
evennia xyzgrid build evennia xyzgrid spawn
evennia reload evennia reload
(remember to reload the server after build operations). (remember to reload the server after spawn operations).
Now you can log into the Now you can log into the
server and do `teleport (3,0,the large tree)` to teleport into the map. server and do `teleport (3,0,the large tree)` to teleport into the map.

View file

@ -21,15 +21,16 @@ from evennia.contrib.xyzgrid import xymap_legend
# default prototype parent. It's important that # default prototype parent. It's important that
# the typeclass inherits from the XYZRoom (or XYZExit) # the typeclass inherits from the XYZRoom (or XYZExit)
# the xymap_legend.XYZROOM_PARENT and XYZEXIT_PARENTS can also # if adding the evennia.contrib.xyzgrid.prototypes to
# be used as a shortcut. # settings.PROTOTYPE_MODULES, one could just set the
# prototype_parent to 'xyz_room' and 'xyz_exit' respectively
# instead.
PARENT = { PARENT = {
"key": "An empty room", "key": "An empty room",
"prototype_key": "xyzmap_room_map1", "prototype_key": "xyzmap_room_map1",
"typeclass": "evennia.contrib.xyzgrid.xyzroom.XYZRoom", "typeclass": "evennia.contrib.xyzgrid.xyzroom.XYZRoom",
"desc": "An empty room.", "desc": "An empty room.",
"options": {}
} }
@ -66,7 +67,7 @@ MAP1 = r"""
""" """
class TransitionToCave(xymap_legend.MapTransitionMapNode): class TransitionToCave(xymap_legend.TransitionMapNode):
""" """
A transition from 'the large tree' to 'the small cave' map. This node is never spawned A transition from 'the large tree' to 'the small cave' map. This node is never spawned
into a room but only acts as a target for finding the exit's destination. into a room but only acts as a target for finding the exit's destination.
@ -169,7 +170,7 @@ MAP2 = r"""
""" """
# custom map node # custom map node
class TransitionToLargeTree(xymap_legend.MapTransitionMapNode): class TransitionToLargeTree(xymap_legend.TransitionMapNode):
""" """
A transition from 'the small cave' to 'the large tree' map. This node is never spawned A transition from 'the small cave' to 'the large tree' map. This node is never spawned
into a room by only acts as a target for finding the exit's destination. into a room by only acts as a target for finding the exit's destination.

View file

@ -1,6 +1,6 @@
""" """
Custom Evennia launcher command option for building/rebuilding the grid in a separate process than Custom Evennia launcher command option for maintaining the grid in a separate process than the main
the main server (since this can be slow). server (since this can be slow).
To use, add to the settings: To use, add to the settings:
:: ::
@ -22,7 +22,7 @@ from evennia.utils import ansi
from evennia.contrib.xyzgrid.xyzgrid import get_xyzgrid from evennia.contrib.xyzgrid.xyzgrid import get_xyzgrid
_HELP_SHORT = """ _HELP_SHORT = """
evennia xyzgrid help|list|init|add|build|initpath|delete [<options>] evennia xyzgrid help|list|init|add|spawn|initpath|delete [<options>]
Manages the XYZ grid. Use 'xyzgrid help <option>' for documentation. Manages the XYZ grid. Use 'xyzgrid help <option>' for documentation.
""" """
@ -34,7 +34,7 @@ help <command> - get help about each command:
list - show list list - show list
init - initialize grid (only one time) init - initialize grid (only one time)
add - add new maps to grid add - add new maps to grid
build - build added maps into actual db-rooms/exits spawn - spawn added maps into actual db-rooms/exits
initpath - (re)creates pathfinder matrices initpath - (re)creates pathfinder matrices
delete - delete part or all of grid delete - delete part or all of grid
""" """
@ -78,38 +78,38 @@ add <path.to.xymap.module> [<path> <path>,...]
{"map": mapstring, "zcoord": mapname/zcoord, "legend": dict, "prototypes": dict} {"map": mapstring, "zcoord": mapname/zcoord, "legend": dict, "prototypes": dict}
describing one single XYmap, or describing one single XYmap, or
- a XYMAP_DATA_LIST - a list of multiple dicts on the XYMAP_DATA form. This allows for - a XYMAP_DATA_LIST - a list of multiple dicts on the XYMAP_DATA form. This allows for
embedding multiple maps in the same module. See evennia/contrib/xyzgrid/map_example.py embedding multiple maps in the same module. See evennia/contrib/xyzgrid/example.py
for an example of how this looks. for an example of how this looks.
Note that adding a map does *not* build it. If maps are linked to one another, you should Note that adding a map does *not* spawn it. If maps are linked to one another, you should
add all linked maps before running 'build', or you'll get errors when creating transitional add all linked maps before running 'spawn', or you'll get errors when creating transitional
exits between maps. exits between maps.
Examples: Examples:
evennia xyzgrid add evennia.contrib.xyzgrid.map_example evennia xyzgrid add evennia.contrib.xyzgrid.example
evennia xyzgrid add world.mymap1 world.mymap2 world.mymap3 evennia xyzgrid add world.mymap1 world.mymap2 world.mymap3
""" """
_HELP_BUILD = """ _HELP_SPAWN = """
build spawn
Builds/updates the entire database grid based on the added maps. For a new grid, this will spawns/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 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. removed/spawned if a map changed since the last spawn.
build "(X,Y,Z|mapname)" spawn "(X,Y,Z|mapname)"
Builds/updates only a part of the grid. Remember the quotes around the coordinate (this spawns/updates only a part of the grid. Remember the quotes around the coordinate (this
is mostly because shells don't like them)! Use '*' as a wild card for XY coordinates. is mostly because shells don't like them)! Use '*' as a wild card for XY coordinates.
This should usually only be used if the full grid has already been built once - otherwise 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 to build. inter-map transitions may fail! Z is the name/z-coordinate of the map to spawn.
Examples: Examples:
evennia xyzgrid build - build all evennia xyzgrid spawn - spawn all
evennia xyzgrid "(*, *, mymap1)" - build everything of map/zcoord mymap1 evennia xyzgrid "(*, *, mymap1)" - spawn everything of map/zcoord mymap1
evennia xyzgrid "(12, 5, mymap1)" - build only coordinate (12, 5) on map/zcoord mymap1 evennia xyzgrid "(12, 5, mymap1)" - spawn only coordinate (12, 5) on map/zcoord mymap1
""" """
_HELP_INITPATH = """ _HELP_INITPATH = """
@ -118,7 +118,7 @@ initpath
Recreates the pathfinder matrices for the entire grid. These are used for all shortest-path 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 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 map will run this automatically first time it's used. Running this will always force to
rebuild the cache. respawn the cache.
initpath Z|mapname initpath Z|mapname
@ -156,7 +156,7 @@ _TOPICS_MAP = {
"list": _HELP_LIST, "list": _HELP_LIST,
"init": _HELP_INIT, "init": _HELP_INIT,
"add": _HELP_ADD, "add": _HELP_ADD,
"build": _HELP_BUILD, "spawn": _HELP_SPAWN,
"initpath": _HELP_INITPATH, "initpath": _HELP_INITPATH,
"delete": _HELP_DELETE "delete": _HELP_DELETE
} }
@ -216,14 +216,14 @@ def _option_list(*suboptions):
"to another map), so the 'missing room(s)' may just be from such nodes.") "to another map), so the 'missing room(s)' may just be from such nodes.")
elif nrooms > nnodes: elif nrooms > nnodes:
print(f"{nrooms} / {nnodes} rooms are spawned\n" print(f"{nrooms} / {nnodes} rooms are spawned\n"
"Note: Maybe some rooms were removed from map. Run 'build' to re-sync.") "Note: Maybe some rooms were removed from map. Run 'spawn' to re-sync.")
else: else:
print(f"{nrooms} / {nnodes} rooms are spawned\n") print(f"{nrooms} / {nnodes} rooms are spawned\n")
if checkwarning: if checkwarning:
print("Note: This check is not complete; it does not consider changed map " print("Note: This check is not complete; it does not consider changed map "
"topology\nlike relocated nodes/rooms and new/removed links/exits - this " "topology\nlike relocated nodes/rooms and new/removed links/exits - this "
"is calculated only during a build.") "is calculated only during a spawn.")
print("\nDisplayed map (as appearing in-game):\n\n" + ansi.parse_ansi(str(xymap))) print("\nDisplayed map (as appearing in-game):\n\n" + ansi.parse_ansi(str(xymap)))
print("\nRaw map string (including axes and invisible nodes/links):\n" print("\nRaw map string (including axes and invisible nodes/links):\n"
+ str(xymap.mapstring)) + str(xymap.mapstring))
@ -268,9 +268,9 @@ def _option_add(*suboptions):
print(f"Added (or readded) {len(xymap_data_list)} XYMaps to grid.") print(f"Added (or readded) {len(xymap_data_list)} XYMaps to grid.")
def _option_build(*suboptions): def _option_spawn(*suboptions):
""" """
Build the grid or part of it. spawn the grid or part of it.
""" """
grid = get_xyzgrid() grid = get_xyzgrid()
@ -286,14 +286,14 @@ def _option_build(*suboptions):
try: try:
x, y, z = (part.strip() for part in opts.split(",")) x, y, z = (part.strip() for part in opts.split(","))
except ValueError: except ValueError:
print("Build coordinate must be given as (X, Y, Z) tuple, where '*' act " print("spawn coordinate must be given as (X, Y, Z) tuple, where '*' act "
"wild cards and Z is the mapname/z-coord of the map to load.") "wild cards and Z is the mapname/z-coord of the map to load.")
return return
else: else:
x, y, z = '*', '*', '*' x, y, z = '*', '*', '*'
if x == y == z == '*': if x == y == z == '*':
inp = input("This will (re)build the entire grid. If it was built before, it may spawn \n" inp = input("This will (re)spawn the entire grid. If it was built before, it may spawn \n"
"new rooms or delete rooms that no longer matches the grid.\nDo you want to " "new rooms or delete rooms that no longer matches the grid.\nDo you want to "
"continue? [Y]/N? ") "continue? [Y]/N? ")
else: else:
@ -303,9 +303,9 @@ def _option_build(*suboptions):
print("Aborted.") print("Aborted.")
return return
print("Starting build ...") print("Starting spawn ...")
grid.spawn(xyz=(x, y, z)) grid.spawn(xyz=(x, y, z))
print("... build complete!\nIt's recommended to reload the server to refresh caches if this " print("... spawn complete!\nIt's recommended to reload the server to refresh caches if this "
"modified an existing grid.") "modified an existing grid.")

View file

@ -14,19 +14,34 @@ and/or
{'prototype_parent': 'xyz_exit', ...} {'prototype_parent': 'xyz_exit', ...}
""" """
from django.conf import settings
# required by the prototype importer try:
PROTOTYPE_LIST = [ room_override = settings.XYZROOM_PROTOTYPE_OVERRIDE
{ except AttributeError:
'prototype_key': 'xyz_room', room_override = {}
'typeclass': 'evennia.contrib.xyzgrid.xyzroom.XYZRoom',
'prototype_tags': ("xyzroom", ), try:
'key': "A room", exit_override = settings.XYZEXIT_PROTOTYPE_OVERRIDE
'desc': "An empty room." except AttributeError:
}, { exit_override = {}
'prototype_key': 'xyz_exit',
'prototype_tags': ("xyzexit", ), room_prototype = {
'typeclass': 'evennia.contrib.xyzgrid.xyzroom.XYZExit', 'prototype_key': 'xyz_room',
'desc': "An exit." 'typeclass': 'evennia.contrib.xyzgrid.xyzroom.XYZRoom',
} 'prototype_tags': ("xyzroom", ),
] 'key': "A room",
'desc': "An empty room."
}
room_prototype.update(room_override)
exit_prototype = {
'prototype_key': 'xyz_exit',
'typeclass': 'evennia.contrib.xyzgrid.xyzroom.XYZExit',
'prototype_tags': ("xyzexit", ),
'desc': "An exit."
}
exit_prototype.update(exit_override)
# accessed by the prototype importer
PROTOTYPE_LIST = [room_prototype, exit_prototype]

View file

@ -1182,12 +1182,12 @@ class TestXYZGrid(EvenniaTest):
# map transitions # map transitions
class Map12aTransition(xymap_legend.MapTransitionMapNode): class Map12aTransition(xymap_legend.TransitionMapNode):
symbol = "T" symbol = "T"
target_map_xyz = (1, 0, "map12b") target_map_xyz = (1, 0, "map12b")
class Map12bTransition(xymap_legend.MapTransitionMapNode): class Map12bTransition(xymap_legend.TransitionMapNode):
symbol = "T" symbol = "T"
target_map_xyz = (0, 1, "map12a") target_map_xyz = (0, 1, "map12a")
@ -1251,7 +1251,7 @@ class TestXYZGridTransition(EvenniaTest):
class TestBuildExampleGrid(EvenniaTest): class TestBuildExampleGrid(EvenniaTest):
""" """
Test building the map_example (this takes about 30s) Test building the map-example (this takes about 30s)
""" """
def setUp(self): def setUp(self):
@ -1271,7 +1271,7 @@ class TestBuildExampleGrid(EvenniaTest):
Build the map example. Build the map example.
""" """
mapdatas = self.grid.maps_from_module("evennia.contrib.xyzgrid.map_example") mapdatas = self.grid.maps_from_module("evennia.contrib.xyzgrid.example")
self.assertEqual(len(mapdatas), 2) self.assertEqual(len(mapdatas), 2)
self.grid.add_maps(*mapdatas) self.grid.add_maps(*mapdatas)

View file

@ -88,7 +88,7 @@ The nodes and links can be customized by add your own implementation of `MapNode
the LEGEND dict, mapping them to a particular character symbol. A `MapNode` can only be added the LEGEND dict, mapping them to a particular character symbol. A `MapNode` can only be added
on an even XY coordinate while `MapLink`s can be added anywhere on the xygrid. on an even XY coordinate while `MapLink`s can be added anywhere on the xygrid.
See `./map_example.py` for some empty grid areas to start from. See `./example.py` for a full grid example.
---- ----
""" """
@ -456,11 +456,12 @@ class XYMap:
xygrid[ix][iy] = XYgrid[iX][iY] = node_index_map[node_index] = \ xygrid[ix][iy] = XYgrid[iX][iY] = node_index_map[node_index] = \
mapnode_or_link_class(x=ix, y=iy, Z=self.Z, mapnode_or_link_class(x=ix, y=iy, Z=self.Z,
node_index=node_index, xymap=self) node_index=node_index, symbol=char, xymap=self)
else: else:
# we have a link at this xygrid position (this is ok everywhere) # we have a link at this xygrid position (this is ok everywhere)
xygrid[ix][iy] = mapnode_or_link_class(x=ix, y=iy, Z=self.Z, xymap=self) xygrid[ix][iy] = mapnode_or_link_class(x=ix, y=iy, Z=self.Z, symbol=char,
xymap=self)
# store the symbol mapping for transition lookups # store the symbol mapping for transition lookups
symbol_map[char].append(xygrid[ix][iy]) symbol_map[char].append(xygrid[ix][iy])

View file

@ -45,14 +45,13 @@ class MapNode:
- `display_symbol` (str or `None`) - This is what is used to visualize this node later. This - `display_symbol` (str or `None`) - This is what is used to visualize this node later. This
symbol must still only have a visual size of 1, but you could e.g. use some fancy unicode symbol must still only have a visual size of 1, but you could e.g. use some fancy unicode
character (be aware of encodings to different clients though) or, commonly, add color character (be aware of encodings to different clients though) or, commonly, add color
tags around it. For further customization, the `.get_display_symbol` method receives tags around it. For further customization, the `.get_display_symbol` method
the full grid and can return a dynamically determined display symbol. If set to `None`, can return a dynamically determined display symbol. If set to `None`, the `symbol` is used.
the `symbol` is used.
- `interrupt_path` (bool): If this is set, the shortest-path algorithm will include this - `interrupt_path` (bool): If this is set, the shortest-path algorithm will include this
node as normally, but stop when reaching it, even if not having reached its target yet. This node as normally, but the auto-stepper will stop when reaching it, even if not having reached
is useful for marking 'points of interest' along a route, or places where you are not its target yet. This is useful for marking 'points of interest' along a route, or places where
expected to be able to continue without some further in-game action not covered by the map you are not expected to be able to continue without some further in-game action not covered by
(such as a guard or locked gate etc). the map (such as a guard or locked gate etc).
- `prototype` (dict) - The default `prototype` dict to use for reproducing this map component - `prototype` (dict) - The default `prototype` dict to use for reproducing this map component
on the game grid. This is used if not overridden specifically for this coordinate. If this on the game grid. This is used if not overridden specifically for this coordinate. If this
is not given, nothing will be spawned for this coordinate (a 'virtual' node can be useful is not given, nothing will be spawned for this coordinate (a 'virtual' node can be useful
@ -88,7 +87,7 @@ class MapNode:
'u': ('up', 'u'), 'u': ('up', 'u'),
} }
def __init__(self, x, y, Z, node_index=0, xymap=None): def __init__(self, x, y, Z, node_index=0, symbol=None, xymap=None):
""" """
Initialize the mapnode. Initialize the mapnode.
@ -99,6 +98,8 @@ class MapNode:
node_index (int): This identifies this node with a running node_index (int): This identifies this node with a running
index number required for pathfinding. This is used index number required for pathfinding. This is used
internally and should not be set manually. internally and should not be set manually.
symbol (str, optional): Set during parsing - allows to override
the symbol based on what's set in the legend.
xymap (XYMap, optional): The map object this sits on. xymap (XYMap, optional): The map object this sits on.
""" """
@ -115,6 +116,8 @@ class MapNode:
self.Z = Z self.Z = Z
self.node_index = node_index self.node_index = node_index
if symbol is not None:
self.symbol = symbol
# this indicates linkage in 8 cardinal directions on the string-map, # this indicates linkage in 8 cardinal directions on the string-map,
# n,ne,e,se,s,sw,w,nw and link that to a node (always) # n,ne,e,se,s,sw,w,nw and link that to a node (always)
@ -501,8 +504,8 @@ class MapLink:
symbol must still only have a visual size of 1, but you could e.g. use some fancy unicode symbol must still only have a visual size of 1, but you could e.g. use some fancy unicode
character (be aware of encodings to different clients though) or, commonly, add color character (be aware of encodings to different clients though) or, commonly, add color
tags around it. For further customization, the `.get_display_symbol` can be used. tags around it. For further customization, the `.get_display_symbol` can be used.
- `default_weight` (int) - Each link direction covered by this link can have its seprate weight, - `default_weight` (int) - Each link direction covered by this link can have its separate
this is used if none is specified in a particular direction. This value must be >= 1, weight, this is used if none is specified in a particular direction. This value must be >= 1,
and can be higher than 1 if a link should be less favored. and can be higher than 1 if a link should be less favored.
- `directions` (dict) - this specifies which link edge to which other link-edge this link - `directions` (dict) - this specifies which link edge to which other link-edge this link
is connected; A link connecting the link's sw edge to its easted edge would be written is connected; A link connecting the link's sw edge to its easted edge would be written
@ -577,7 +580,7 @@ class MapLink:
# will be used. # will be used.
spawn_aliases = {} spawn_aliases = {}
def __init__(self, x, y, Z, xymap=None): def __init__(self, x, y, Z, symbol=None, xymap=None):
""" """
Initialize the link. Initialize the link.
@ -585,6 +588,8 @@ class MapLink:
x (int): The xygrid x coordinate x (int): The xygrid x coordinate
y (int): The xygrid y coordinate. y (int): The xygrid y coordinate.
X (int or str): The name/Z-coord of this map we are on. X (int or str): The name/Z-coord of this map we are on.
symbol (str, optional): Set during parsing, allows to override
the default symbol with the one set in the legend.
xymap (XYMap, optional): The map object this sits on. xymap (XYMap, optional): The map object this sits on.
""" """
@ -597,6 +602,9 @@ class MapLink:
self.Y = y / 2 self.Y = y / 2
self.Z = Z self.Z = Z
if symbol is not None:
self.symbol = symbol
def __str__(self): def __str__(self):
return f"<LinkNode '{self.symbol}' XY=({self.X:g},{self.Y:g})>" return f"<LinkNode '{self.symbol}' XY=({self.X:g},{self.Y:g})>"
@ -1117,7 +1125,7 @@ class InterruptMapNode(MapNode):
interrupt_path = True interrupt_path = True
prototype = "xyz_room" prototype = "xyz_room"
class MapTransitionMapNode(TransitionMapNode): class MapTransitionNode(TransitionMapNode):
"""Transition-target node to other map. This is not actually spawned in-game.""" """Transition-target node to other map. This is not actually spawned in-game."""
symbol = "T" symbol = "T"
display_symbol = " " display_symbol = " "
@ -1256,7 +1264,7 @@ class TeleporterMapLink(SmartTeleporterMapLink):
LEGEND = { LEGEND = {
# nodes # nodes
"#": BasicMapNode, "#": BasicMapNode,
"T": MapTransitionMapNode, "T": MapTransitionNode,
"I": InterruptMapNode, "I": InterruptMapNode,
# links # links
"|": NSMapLink, "|": NSMapLink,

View file

@ -241,6 +241,9 @@ class XYZRoom(DefaultRoom):
map_area_client (bool): If True, map area will always fill the entire map_area_client (bool): If True, map area will always fill the entire
client width. If False, the map area's width will vary with the client width. If False, the map area's width will vary with the
width of the currently displayed location description. width of the currently displayed location description.
map_fill_all (bool): I the map area should fill the client width or not.
map_separator_char (str): The char to use to separate the map area from
the room description.
""" """
@ -255,6 +258,7 @@ class XYZRoom(DefaultRoom):
map_align = 'c' map_align = 'c'
map_target_path_style = "|y{display_symbol}|n" map_target_path_style = "|y{display_symbol}|n"
map_fill_all = True map_fill_all = True
map_separator_char = "|x~|n"
def __str__(self): def __str__(self):
return repr(self) return repr(self)
@ -431,6 +435,9 @@ class XYZRoom(DefaultRoom):
xymap.options.get("map_target_path_style", self.map_target_path_style)) xymap.options.get("map_target_path_style", self.map_target_path_style))
map_area_client = kwargs.get( map_area_client = kwargs.get(
"map_fill_all", xymap.options.get("map_fill_all", self.map_fill_all)) "map_fill_all", xymap.options.get("map_fill_all", self.map_fill_all))
map_separator_char = kwargs.get(
"map_separator_char",
xymap.options.get("map_separator_char", self.map_separator_char))
client_width, _ = looker.sessions.get()[0].get_client_size() client_width, _ = looker.sessions.get()[0].get_client_size()
@ -465,8 +472,8 @@ class XYZRoom(DefaultRoom):
max_size=(display_width, None), max_size=(display_width, None),
indent=map_indent indent=map_indent
) )
sep = "~" * sep_width sep = map_separator_char * sep_width
map_display = f"|x{sep}|n\n{map_display}\n|x{sep}" map_display = f"{sep}|n\n{map_display}\n{sep}"
# echo directly to make easier to separate in client # echo directly to make easier to separate in client
looker.msg(text=(map_display, {"type": "xymap"}), options=None) looker.msg(text=(map_display, {"type": "xymap"}), options=None)