Created
January 14, 2016 02:27
-
-
Save whutch/7a73bd404efde2f051cd to your computer and use it in GitHub Desktop.
Patch for Atria to turn it into a map generation server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/atria/core/server.py b/atria/core/server.py | |
index f85c091..0c180b2 100644 | |
--- a/atria/core/server.py | |
+++ b/atria/core/server.py | |
@@ -23,6 +23,7 @@ from .storage import STORES | |
from .timing import TIMERS | |
from .utils.exceptions import ServerReboot, ServerReload, ServerShutdown | |
from .utils.funcs import joins | |
+from .world import MapShell | |
log = get_logger("server") | |
@@ -255,7 +256,7 @@ def _hook_client_connected(client): | |
session = SESSIONS.create(client) | |
with EVENTS.fire("session_started", session): | |
session.send(SESSIONS.connect_greeting) | |
- session.menu = ConnectMenu | |
+ session.shell = MapShell | |
@EVENTS.hook("client_disconnected") | |
diff --git a/atria/core/world.py b/atria/core/world.py | |
index 4149676..9db118d 100644 | |
--- a/atria/core/world.py | |
+++ b/atria/core/world.py | |
@@ -4,12 +4,17 @@ | |
+import random | |
import re | |
from weakref import WeakSet | |
+from .commands import Command, COMMANDS | |
+from .const import * | |
from .entities import Attribute, ENTITIES, Entity, Unset | |
+from .events import EVENTS | |
from .logs import get_logger | |
from .pickle import PickleStore | |
+from .shells import Shell, SHELLS | |
from .storage import STORES | |
from .utils.funcs import joins | |
@@ -177,3 +182,133 @@ def get_movement_strings(change): | |
""" | |
return _movement_strings.get(change, ("nowhere", "nowhere")) | |
+ | |
+ | |
[email protected] | |
+class MapShell(Shell): | |
+ | |
+ state = STATE_PLAYING | |
+ | |
+ def init(self): | |
+ self.session.color = True | |
+ | |
+ | |
[email protected] | |
+class MapGenCommand(Command): | |
+ | |
+ def _action(self): | |
+ m = Map() | |
+ m.generate_square(78, 40) | |
+ m.print_square(self.session, 78, 40) | |
+ | |
+ | |
[email protected]("server_boot") | |
+def _hook_server_boot(): | |
+ from .cmds.cmd_basic import QuitCommand | |
+ MapShell.add_verbs(MapGenCommand, "mapgen") | |
+ MapShell.add_verbs(QuitCommand, "q", "quit", "logout", "done", "exit", truncate=False) | |
+ | |
+ | |
+# Coordinate deltas for each direction | |
+_DIRS = [(1,0),(1,-1),(0,-1),(-1,-1),(-1,0),(-1,1),(0,1),(1,1)] | |
+# east ne north nw west sw south se | |
+ | |
+ | |
+class _Tile: | |
+ | |
+ def __init__(self, x, y, map): | |
+ self._map = map | |
+ self.x = x | |
+ self.y = y | |
+ self.elevation = None | |
+ | |
+ def _get_neighbor(self, dir): | |
+ coord = (self.x + _DIRS[dir][0], self.y + _DIRS[dir][1]) | |
+ return self._map._tiles.get(coord) | |
+ | |
+ def choose_elevation(self, ignore_dirs = ()): | |
+ choices = [] | |
+ for n in range(8): | |
+ if n in ignore_dirs: | |
+ continue | |
+ tile = self._get_neighbor(n) | |
+ if tile: | |
+ threshold = self._map.ELEVATION_THRESHOLD | |
+ elevation_min = max(tile.elevation - threshold, self._map.MIN_ELEVATION) | |
+ elevation_max = min(tile.elevation + threshold, self._map.MAX_ELEVATION) | |
+ choices.extend(range(elevation_min, elevation_max + 1)) | |
+ choices.extend([tile.elevation] * self._map.NEIGHBOR_WEIGHT) | |
+ if choices: | |
+ self.elevation = random.choice(choices) | |
+ else: | |
+ self.elevation = self._map.base_elevation | |
+ | |
+ | |
+class Map: | |
+ | |
+ MIN_ELEVATION = -8 | |
+ MAX_ELEVATION = 12 | |
+ SEA_LEVEL = 0 | |
+ ELEVATION_THRESHOLD = 1 | |
+ NEIGHBOR_WEIGHT = 3 | |
+ | |
+ def __init__(self, base_elevation=4): | |
+ self._tiles = {} | |
+ self.base_elevation = max(self.MIN_ELEVATION, min(base_elevation, self.MAX_ELEVATION)) | |
+ | |
+ def _get_terrain_symbol(self, elevation): | |
+ #### adjust to be based on variables like SEA_LEVEL | |
+ if elevation is None: | |
+ return "^R!" | |
+ if elevation >= 12: | |
+ return '^k^^' | |
+ if elevation >= 10: | |
+ return "^K^^" | |
+ if elevation >= 9: | |
+ return '^yn' | |
+ if elevation >= 7: | |
+ return "^Yn" | |
+ if elevation >= 6: | |
+ return '^g"' | |
+ if elevation >= 3: | |
+ return '^G"' | |
+ if elevation >= 1: | |
+ return "^Y." | |
+ if elevation >= 0: | |
+ return "^y." | |
+ if elevation >= -3: | |
+ return '^C,' | |
+ if elevation >= -4: | |
+ return "^c," | |
+ if elevation >= -7: | |
+ return "^B~" | |
+ if elevation >= -8: | |
+ return "^b~" | |
+ return '^R?' | |
+ | |
+ def add_tile(self, x, y): | |
+ tile = _Tile(x, y, self) | |
+ self._tiles[(x, y)] = tile | |
+ return tile | |
+ | |
+ def generate_square(self, width=3, height=3): | |
+ max_x = width // 2 | |
+ max_y = height // 2 | |
+ for x in range(-max_x, max_x + (width % 2)): | |
+ for y in range(-max_y, max_y + (height % 2)): | |
+ if not (x, y) in self._tiles: | |
+ tile = self.add_tile(x, y) | |
+ tile.choose_elevation() | |
+ | |
+ def print_square(self, session, width=3, height=3, center = (0, 0)): | |
+ max_x = width // 2 | |
+ max_y = height // 2 | |
+ for y in range(center[1] - max_y, center[1] + max_y + (height % 2)): | |
+ row = [] | |
+ for x in range(center[0] - max_x, center[1] + max_x + (width % 2)): | |
+ tile = self._tiles.get((x, y)) | |
+ row.append(self._get_terrain_symbol(tile.elevation) if tile else " ") | |
+ session.send("".join(row)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment