# HG changeset patch # User Neil Muller # Date 1378322169 -7200 # Node ID 831e4f6b3d18712d5ac7d6a4ca7356ef496a33a5 # Parent aa11ecee56b8d434b8956ec9cdc2d82c1459494e Add hints for the level editor diff -r aa11ecee56b8 -r 831e4f6b3d18 nagslang/enemies.py --- a/nagslang/enemies.py Wed Sep 04 19:11:00 2013 +0200 +++ b/nagslang/enemies.py Wed Sep 04 21:16:09 2013 +0200 @@ -10,6 +10,15 @@ from nagslang.resources import resources +def get_editable_enemies(): + classes = [] + for cls_name, cls in globals().iteritems(): + if isinstance(cls, type) and issubclass(cls, Enemy): + if hasattr(cls, 'requires'): + classes.append((cls_name, cls)) + return classes + + class Enemy(GameObject): """A base class for mobile enemies""" @@ -33,6 +42,10 @@ def attack(self): raise NotImplementedError + @classmethod + def requires(cls): + return [("name", "string"), ("position", "coordinates")] + class PatrollingAlien(Enemy): is_moving = True # Always walking. @@ -112,3 +125,8 @@ self._switch_direction() self.set_direction(x_step, y_step) super(PatrollingAlien, self).animate() + + @classmethod + def requires(cls): + return [("name", "string"), ("position", "coordinates"), + ("end_position", "coordinates")] diff -r aa11ecee56b8 -r 831e4f6b3d18 nagslang/game_object.py --- a/nagslang/game_object.py Wed Sep 04 19:11:00 2013 +0200 +++ b/nagslang/game_object.py Wed Sep 04 21:16:09 2013 +0200 @@ -10,6 +10,14 @@ from nagslang.events import DoorEvent +def get_editable_game_objects(): + classes = [] + for cls_name, cls in globals().iteritems(): + if isinstance(cls, type) and hasattr(cls, 'requires'): + classes.append((cls_name, cls)) + return classes + + class Physicser(object): def __init__(self, space): self._space = space @@ -136,6 +144,11 @@ """ return True + @classmethod + def requires(cls): + """Hints for the level editor""" + return [("name", "string")] + class FloorSwitch(GameObject): zorder = ZORDER_FLOOR @@ -154,6 +167,10 @@ puzzle.CollidePuzzler(*SWITCH_PUSHERS), ) + @classmethod + def requires(cls): + return [("name", "string"), ("position", "coordinates")] + class Note(GameObject): zorder = ZORDER_FLOOR @@ -169,6 +186,11 @@ render.TextOverlay(message), ) + @classmethod + def requires(cls): + return [("name", "string"), ("position", "coordinates"), + ("message", "text")] + class FloorLight(GameObject): zorder = ZORDER_FLOOR @@ -187,6 +209,11 @@ puzzle.StateProxyPuzzler(state_source), ) + @classmethod + def requires(cls): + return [("name", "string"), ("position", "coordinates"), + ("state_source", "puzzler")] + class Box(GameObject): def __init__(self, space, position): @@ -200,6 +227,11 @@ render.ImageRenderer(resources.get_image('objects', 'crate.png')), ) + @classmethod + def requires(cls): + return [("name", "string"), ("position", "coordinates"), + ("state_source", "puzzler")] + class Door(GameObject): zorder = ZORDER_FLOOR @@ -226,6 +258,12 @@ if self.puzzler.get_state(): DoorEvent.post(self.destination, self.dest_pos) + @classmethod + def requires(cls): + return [("name", "string"), ("position", "coordinates"), + ("destination", "level name"), ("dest_pos", "coordinate"), + ("key_state", "puzzler")] + class Bulkhead(GameObject): zorder = ZORDER_FLOOR @@ -249,3 +287,8 @@ # Reject the collision, we can walk through. return False return True + + @classmethod + def requires(cls): + return [("name", "string"), ("end1", "coordinates"), + ("end2", "coordinates"), ("key_state", "puzzler")] diff -r aa11ecee56b8 -r 831e4f6b3d18 nagslang/puzzle.py --- a/nagslang/puzzle.py Wed Sep 04 19:11:00 2013 +0200 +++ b/nagslang/puzzle.py Wed Sep 04 21:16:09 2013 +0200 @@ -1,6 +1,14 @@ from nagslang.constants import COLLISION_TYPE_PLAYER +def get_editable_puzzlers(): + classes = [] + for cls_name, cls in globals().iteritems(): + if isinstance(cls, type) and hasattr(cls, 'requires'): + classes.append((cls_name, cls)) + return classes + + class PuzzleGlue(object): """Glue that holds bits of a puzzle together. """ @@ -29,6 +37,13 @@ def get_state(self): raise NotImplementedError() + @classmethod + def requires(cls): + """Tell the level editor the arguments we require + + Format is a list of name: type hint tuples""" + return [("name", "string")] + class YesPuzzler(Puzzler): """Yes sir, I'm always on. @@ -57,6 +72,10 @@ return True return False + @classmethod + def requires(cls): + return [("name", "string"), ("collision_types", "list of ints")] + class StateProxyPuzzler(Puzzler): def __init__(self, state_source): @@ -65,6 +84,10 @@ def get_state(self): return self.glue.get_state_of(self._state_source) + @classmethod + def requires(cls): + return [("name", "string"), ("sources", "list of names")] + class StateLogicalAndPuzzler(Puzzler): def __init__(self, *state_sources): @@ -75,3 +98,7 @@ if not self.glue.get_state_of(state_source): return False return True + + @classmethod + def requires(cls): + return [("name", "string"), ("sources", "list of names")]