home · contact · privacy
Add door keys and door locking.
authorChristian Heller <c.heller@plomlompom.de>
Wed, 16 Dec 2020 19:57:23 +0000 (20:57 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 16 Dec 2020 19:57:23 +0000 (20:57 +0100)
plomrogue/commands.py
plomrogue/game.py
plomrogue/tasks.py
plomrogue/things.py
rogue_chat.py

index 653fc74ff7ecb3c0d4d44f2570f3fe03df7c30ea..074cc343873a80b17e6383b604c7e109217210c6 100644 (file)
@@ -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'
index ec663b7b4b5bf362b9a4f801fd9d1c78dec421c6..d3ab1e73b08b8b19d6bcc81f3832d6a72811d963 100755 (executable)
@@ -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]))
 
index 4cf8700b1f5b93473fabb70c3acedf471167667d..6ee273164f19dd33422c99c21d708f71cab21dc8 100644 (file)
@@ -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')
 
index 98d056ac650508b239a284d84ee99cf40dc8b736..3686ab0c2a2b78f41e024a5f9c8ef14958fc285d 100644 (file)
@@ -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):
index 31e53e4af5435b498c1ff80a6f507b10567f37e7..a3654b0908c29464f05b6e7109deb0a29b30bdc8 100755 (executable)
@@ -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)