X-Git-Url: https://git.ctpug.org.za/?a=blobdiff_plain;f=koperkapel%2Fworld.py;h=a07b719a41a79e5882d8fcb7b2da03dfdb8bb7b9;hb=HEAD;hp=28f98b3da91ccad0365c2eb45ef0c12b3373ac23;hpb=caff26b2bd7a76141bd9ebd3258b1941eb30064b;p=koperkapel.git diff --git a/koperkapel/world.py b/koperkapel/world.py index 28f98b3..a07b719 100644 --- a/koperkapel/world.py +++ b/koperkapel/world.py @@ -1,6 +1,7 @@ """ World and player state. """ from .scenes.base import WorldEvent +from .roaches import build_roach class World: @@ -20,48 +21,68 @@ class World: def _build_initial_state(self): state = {} state["roaches"] = [ - self._build_roach("roachel", intelligence=3), - self._build_roach("roeginald", strength=3), - self._build_roach("roichard", quickness=3), + build_roach(self, "roupert"), ] + state["serums"] = [] + state["vehicles"] = { + "current": "walking", + "walking": { + "seating": [ + "roachel", None, "roeginald", + None, None, None, + ] + }, + "robot": {"seating": []}, + "roomba": {"seating": []}, + "quadcopter": {"seating": []}, + } + state["weapons"] = { + "current": "spit", + } state["level"] = { "name": "level1", } return state - def _build_roach(self, name, **kw): - attributes = { - "intelligence": 1, - "strength": 1, - "quickness": 1, - "health": 5, - } - attributes.update(kw) - return { - "name": name, - "attributes": attributes, - } + def _get_obj(self, name): + parts = name.split(".") + obj = self._state + for p in parts[:-1]: + if isinstance(obj, dict): + obj = obj[p] + elif isinstance(obj, list): + obj = obj[int(p)] + else: + raise KeyError("%r not found in world" % (name,)) + return obj, parts[-1] + + def _apply_set(self, action, updates): + for name, value in updates.items(): + obj, key = self._get_obj(name) + obj[key] = value - def _apply_set(self, updates): + def _apply_append(self, action, updates): for name, value in updates.items(): - parts = name.split(".") - obj = self._state - for p in parts[:-1]: - if isinstance(obj, dict): - obj = obj[p] - elif isinstance(obj, list): - obj = obj[int(p)] - else: - raise KeyError("%r not found in world" % (name,)) - obj[parts[-1]] = value + obj, key = self._get_obj(name) + obj.append(value) + + def _apply_pop(self, action, updates): + for name, pos in updates.items(): + obj, key = self._get_obj(name) + obj.pop(pos) + + def _apply_reset(self, action): + self._state = self._build_initial_state() + + def _apply_unknown(self, action, *args, **kw): + raise ValueError("Unknown world event action: %r" % (action,)) def proxy(self): return WorldDictProxy(self._state) def apply_event(self, action, *args, **kw): - if action == "set": - return self._apply_set(*args, **kw) - raise ValueError("Unknown world event action: %r" % (action,)) + handler = getattr(self, "_apply_%s" % (action,)) + return handler(action, *args, **kw) def _maybe_subproxy(proxy, name, value): @@ -91,8 +112,8 @@ class WorldBaseProxy: "_events": _events, }) - def _record_change(self, fullname, value): - self._events.append(WorldEvent("set", { + def _record_change(self, fullname, value, action="set"): + self._events.append(WorldEvent(action, { fullname: value })) @@ -104,15 +125,23 @@ class WorldBaseProxy: class WorldDictProxy(WorldBaseProxy): """ World dictionary proxy that records changes and produces events. """ - def items(self): - return ( - (k, _maybe_subproxy(self, k, v)) for k, v in self._state.items()) - def __setattr__(self, name, value): self._top._record_change("%s%s" % (self._prefix, name), value) def __getattr__(self, name): - return _maybe_subproxy(self, name, self._state[name]) + # return None for attributes that don't exist + value = self._state.get(name) + return _maybe_subproxy(self, name, value) + + def __setitem__(self, name, value): + return self.__setattr__(name, value) + + def __getitem__(self, name): + return self.__getattr__(name) + + def items(self): + return ( + (k, _maybe_subproxy(self, k, v)) for k, v in self._state.items()) class WorldListProxy(WorldBaseProxy): @@ -123,3 +152,15 @@ class WorldListProxy(WorldBaseProxy): def __getitem__(self, index): return _maybe_subproxy(self, index, self._state[index]) + + def __len__(self): + return len(self._state) + + def __bool__(self): + return bool(self._state) + + def append(self, value): + self._top._record_change(self._prefix, value, action="append") + + def pop(self, pos=0): + self._top._record_change(self._prefix, pos, action="pop")