From 5cd44408532e23648ddcd1d59004a9dae59694af Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Wed, 16 Dec 2020 20:57:23 +0100 Subject: [PATCH] Add door keys and door locking. --- plomrogue/commands.py | 20 ++++++++++++++++++-- plomrogue/game.py | 4 +++- plomrogue/tasks.py | 19 +++++++++++++++++-- plomrogue/things.py | 23 +++++++++++++++++++++-- rogue_chat.py | 6 ++++-- 5 files changed, 63 insertions(+), 9 deletions(-) diff --git a/plomrogue/commands.py b/plomrogue/commands.py index 653fc74..074cc34 100644 --- a/plomrogue/commands.py +++ b/plomrogue/commands.py @@ -277,14 +277,16 @@ def cmd_GOD_THING_PROTECTION(game, thing_id, protection_char): t.protection = protection_char cmd_GOD_THING_PROTECTION.argtypes = 'int:pos char' -def cmd_THING_DOOR_CLOSED(game, thing_id): +def cmd_THING_DOOR_CLOSED(game, thing_id, locked): t = game.get_thing(thing_id) if not t: raise GameError('thing of ID %s not found' % thing_id) if not t.type_ == 'Door': raise GameError('thing of ID %s not door' % thing_id) t.close() -cmd_THING_DOOR_CLOSED.argtypes = 'int:pos' + if locked: + t.lock() +cmd_THING_DOOR_CLOSED.argtypes = 'int:pos bool' def cmd_THING_MUSICPLAYER_SETTINGS(game, thing_id, playing, index, repeat): t = game.get_thing(thing_id) @@ -380,3 +382,17 @@ def cmd_THING_HAT_DESIGN(game, thing_id, design): raise GameError('thing of ID %s not a hat' % thing_id) t.design = design cmd_THING_HAT_DESIGN.argtypes = 'int:pos string' + +def cmd_THING_DOOR_KEY(game, key_id, door_id): + key = game.get_thing(key_id) + if not key: + raise GameError('thing of ID %s not found' % key_id) + if key.type_ != 'DoorKey': + raise GameError('thing of ID %s not a door key' % key_id) + door = game.get_thing(door_id) + if not door: + raise GameError('thing of ID %s not found' % door_id) + if door.type_ != 'Door': + raise GameError('thing of ID %s not a door' % key_id) + key.door = door +cmd_THING_DOOR_KEY.argtypes = 'int:pos int:pos' diff --git a/plomrogue/game.py b/plomrogue/game.py index ec663b7..d3ab1e7 100755 --- a/plomrogue/game.py +++ b/plomrogue/game.py @@ -545,7 +545,7 @@ class Game(GameBase): if hasattr(t, 'installable') and (not t.portable): write(f, 'THING_INSTALLED %s' % t.id_) if t.type_ == 'Door' and t.blocks_movement: - write(f, 'THING_DOOR_CLOSED %s' % t.id_) + write(f, 'THING_DOOR_CLOSED %s %s' % (t.id_, int(t.locked))) elif t.type_ == 'Hat': write(f, 'THING_HAT_DESIGN %s %s' % (t.id_, quote(t.design))) @@ -557,6 +557,8 @@ class Game(GameBase): (t.id_, quote(item[0]), item[1])) elif t.type_ == 'Bottle' and not t.full: write(f, 'THING_BOTTLE_EMPTY %s' % t.id_) + elif t.type_ == 'DoorKey': + write(f, 'THING_DOOR_KEY %s %s' % (t.id_, t.door.id_)) write(f, 'SPAWN_POINT %s %s' % (self.spawn_point[0], self.spawn_point[1])) diff --git a/plomrogue/tasks.py b/plomrogue/tasks.py index 4cf8700..6ee2731 100644 --- a/plomrogue/tasks.py +++ b/plomrogue/tasks.py @@ -190,9 +190,19 @@ class Task_DOOR(Task): def check(self): action_radius = list(self.thing.game.map_geometry. get_neighbors_yxyx(self.thing.position).values()) - if len([t for t in self.thing.game.things if - t.type_ == 'Door' and t.position in action_radius]) == 0: + reachable_doors = [t for t in self.thing.game.things if + t.type_ == 'Door' and t.position in action_radius] + if len(reachable_doors) == 0: raise PlayError('not standing next to a door to open/close') + for door in reachable_doors: + if not door.blocks_movement: + return + if not door.locked: + return + if self.thing.carrying and self.thing.carrying.type_ == 'DoorKey'\ + and self.thing.carrying.door == door: + return + raise PlayError('cannot open locked door without its key') def do(self): action_radius = list(self.thing.game.map_geometry. @@ -203,6 +213,11 @@ class Task_DOOR(Task): t.open() else: t.close() + if self.thing.carrying and\ + self.thing.carrying.type_ == 'DoorKey' and\ + self.thing.carrying.door == t: + self.thing.send_msg('CHAT "You lock the door."') + t.lock() self.thing.game.record_change(t.position, 'other') self.thing.game.record_change(t.position, 'fov') diff --git a/plomrogue/things.py b/plomrogue/things.py index 98d056a..3686ab0 100644 --- a/plomrogue/things.py +++ b/plomrogue/things.py @@ -127,8 +127,8 @@ class ThingSpawner(Thing): def proceed(self): for t in [t for t in self.game.things if t != self and t.position == self.position]: - return - self.game.add_thing(self.child_type, self.position) + return None + return self.game.add_thing(self.child_type, self.position) @@ -164,16 +164,31 @@ class ThingInstallable(Thing): class Thing_DoorSpawner(ThingSpawner): child_type = 'Door' + def proceed(self): + door = super().proceed() + if door: + key = self.game.add_thing('DoorKey', self.position) + key.door = door + + + +class Thing_DoorKey(Thing): + portable = True + symbol_hint = 'k' + + class Thing_Door(ThingInstallable): symbol_hint = 'D' blocks_movement = False + locked = False def open(self): self.blocks_movement = False self.blocks_light = False self.blocks_sound = False + self.locked = False del self.thing_char def close(self): @@ -182,6 +197,10 @@ class Thing_Door(ThingInstallable): self.blocks_sound = True self.thing_char = '#' + def lock(self): + self.locked = True + self.thing_char = 'L' + class Thing_Psychedelic(Thing): diff --git a/rogue_chat.py b/rogue_chat.py index 31e53e4..a3654b0 100755 --- a/rogue_chat.py +++ b/rogue_chat.py @@ -15,7 +15,7 @@ from plomrogue.commands import (cmd_ALL, cmd_LOGIN, cmd_NICK, cmd_PING, cmd_THIN cmd_THING_BOTTLE_EMPTY, cmd_PLAYER_FACE, cmd_GOD_PLAYER_FACE, cmd_GOD_PLAYER_HAT, cmd_GOD_PLAYERS_HAT_CHARS, cmd_PLAYER_HAT, - cmd_TERRAIN_TAG) + cmd_TERRAIN_TAG, cmd_THING_DOOR_KEY) from plomrogue.tasks import (Task_WAIT, Task_MOVE, Task_WRITE, Task_PICK_UP, Task_DROP, Task_FLATTEN_SURROUNDINGS, Task_DOOR, Task_INTOXICATE, Task_COMMAND, Task_INSTALL, @@ -26,7 +26,7 @@ from plomrogue.things import (Thing_Player, Thing_Item, Thing_ItemSpawner, Thing_BottleSpawner, Thing_BottleDeposit, Thing_MusicPlayer, Thing_Hat, Thing_HatRemixer, Thing_Cookie, Thing_CookieSpawner, Thing_Psychedelic, - Thing_PsychedelicSpawner) + Thing_PsychedelicSpawner, Thing_DoorKey) from plomrogue.config import config game = Game(config['savefile']) @@ -70,6 +70,7 @@ game.register_command(cmd_GOD_PLAYER_HAT) game.register_command(cmd_GOD_PLAYERS_HAT_CHARS) game.register_command(cmd_PLAYER_HAT) game.register_command(cmd_THING_HAT_DESIGN) +game.register_command(cmd_THING_DOOR_KEY) game.register_task(Task_WAIT) game.register_task(Task_MOVE) game.register_task(Task_WRITE) @@ -88,6 +89,7 @@ game.register_thing_type(Thing_ItemSpawner) game.register_thing_type(Thing_SpawnPoint) game.register_thing_type(Thing_SpawnPointSpawner) game.register_thing_type(Thing_Door) +game.register_thing_type(Thing_DoorKey) game.register_thing_type(Thing_DoorSpawner) game.register_thing_type(Thing_Bottle) game.register_thing_type(Thing_BottleSpawner) -- 2.30.2