source: nagslang/puzzle.py @ 282:9d186b897d82

Last change on this file since 282:9d186b897d82 was 282:9d186b897d82, checked in by Jeremy Thurgood <firxen@…>, 7 years ago

Toggle switch, sans art.

File size: 2.9 KB
Line 
1from nagslang.constants import COLLISION_TYPE_PLAYER
2
3
4def get_editable_puzzlers():
5    classes = []
6    for cls_name, cls in globals().iteritems():
7        if isinstance(cls, type) and hasattr(cls, 'requires'):
8            classes.append((cls_name, cls))
9    return classes
10
11
12class PuzzleGlue(object):
13    """Glue that holds bits of a puzzle together.
14    """
15    def __init__(self):
16        self._components = {}
17
18    def add_component(self, name, puzzler):
19        if not isinstance(puzzler, Puzzler):
20            puzzler = puzzler.puzzler
21        self._components[name] = puzzler
22        puzzler.set_glue(self)
23
24    def get_state_of(self, name):
25        return self._components[name].get_state()
26
27
28class Puzzler(object):
29    """Behaviour specific to a puzzle component.
30    """
31    def set_glue(self, glue):
32        self.glue = glue
33
34    def set_game_object(self, game_object):
35        self.game_object = game_object
36
37    def get_state(self):
38        raise NotImplementedError()
39
40    @classmethod
41    def requires(cls):
42        """Tell the level editor the arguments we require
43
44           Format is a list of name: type hint tuples"""
45        return [("name", "string")]
46
47
48class YesPuzzler(Puzzler):
49    """Yes sir, I'm always on.
50    """
51    def get_state(self):
52        return True
53
54
55class NoPuzzler(Puzzler):
56    """No sir, I'm always off.
57    """
58    def get_state(self):
59        return False
60
61
62class CollidePuzzler(Puzzler):
63    def __init__(self, *collision_types):
64        if not collision_types:
65            collision_types = (COLLISION_TYPE_PLAYER,)
66        self._collision_types = collision_types
67
68    def get_state(self):
69        space = self.game_object.get_space()
70        for shape in space.shape_query(self.game_object.get_shape()):
71            if shape.collision_type in self._collision_types:
72                return True
73        return False
74
75    @classmethod
76    def requires(cls):
77        return [("name", "string"), ("collision_types", "list of ints")]
78
79
80class ParentAttrPuzzler(Puzzler):
81    def __init__(self, attr_name):
82        self._attr_name = attr_name
83
84    def get_state(self):
85        return getattr(self.game_object, self._attr_name)
86
87    @classmethod
88    def requires(cls):
89        return [("name", "string"), ("attr_name", "string")]
90
91
92class StateProxyPuzzler(Puzzler):
93    def __init__(self, state_source):
94        self._state_source = state_source
95
96    def get_state(self):
97        return self.glue.get_state_of(self._state_source)
98
99    @classmethod
100    def requires(cls):
101        return [("name", "string"), ("sources", "list of names")]
102
103
104class StateLogicalAndPuzzler(Puzzler):
105    def __init__(self, *state_sources):
106        self._state_sources = state_sources
107
108    def get_state(self):
109        for state_source in self._state_sources:
110            if not self.glue.get_state_of(state_source):
111                return False
112        return True
113
114    @classmethod
115    def requires(cls):
116        return [("name", "string"), ("sources", "list of names")]
Note: See TracBrowser for help on using the repository browser.