From 52b01fc00d6ea2c053f9022981498b97ebd05839 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Wed, 9 Dec 2020 04:08:12 +0100 Subject: [PATCH] Add bottle spinning. --- plomrogue/game.py | 1 + plomrogue/tasks.py | 16 ++++++++++++++-- plomrogue/things.py | 23 ++++++++++++++++++++++- rogue_chat.html | 11 ++++++++++- rogue_chat.py | 3 ++- rogue_chat_curses.py | 7 ++++++- 6 files changed, 55 insertions(+), 6 deletions(-) diff --git a/plomrogue/game.py b/plomrogue/game.py index 31c9f2f..36a7656 100755 --- a/plomrogue/game.py +++ b/plomrogue/game.py @@ -356,6 +356,7 @@ class Game(GameBase): y_range_end = absolute_position.y + fov_radius x_range_start = absolute_position.x - fov_radius x_range_end = absolute_position.x + fov_radius + # TODO: refactor with SourcedMap.inside? for position in self.changed_tiles: if position.y < y_range_start\ or position.y > y_range_end: diff --git a/plomrogue/tasks.py b/plomrogue/tasks.py index d8d118a..1e6737b 100644 --- a/plomrogue/tasks.py +++ b/plomrogue/tasks.py @@ -1,4 +1,5 @@ from plomrogue.errors import PlayError, GameError +from plomrogue.misc import quote @@ -190,7 +191,6 @@ class Task_COMMAND(Task): raise PlayError('cannot command this item type') def do(self): - from plomrogue.misc import quote reply_lines = self.thing.carrying.interpret(self.args[0]) for line in reply_lines: self.thing.send_msg('REPLY ' + quote(line)) @@ -249,8 +249,20 @@ class Task_WEAR(Task): remixer.accept(t) break else: - from plomrogue.misc import quote self.thing.game.hats[self.thing.name] = self.thing.carrying.design self.thing.game.remove_thing(self.thing.carrying) self.thing.carrying = None self.thing.send_msg('CHAT "You put on a hat."') + + + +class Task_SPIN(Task): + + def check(self): + if not self.thing.carrying: + raise PlayError('holding nothing to spin') + if not hasattr(self.thing.carrying, 'spinnable'): + raise PlayError('held object not spinnable') + + def do(self): + self.thing.carrying.spin() diff --git a/plomrogue/things.py b/plomrogue/things.py index 4f802db..7234d8e 100644 --- a/plomrogue/things.py +++ b/plomrogue/things.py @@ -1,5 +1,6 @@ from plomrogue.errors import GameError, PlayError from plomrogue.mapping import YX +from plomrogue.misc import quote import random @@ -40,7 +41,6 @@ class Thing(ThingBase): def sound(self, name, msg): from plomrogue.mapping import DijkstraMap - from plomrogue.misc import quote def lower_msg_by_volume(msg, volume, largest_audible_distance): import random @@ -151,11 +151,32 @@ class Thing_Bottle(Thing): portable = True full = True thing_char = '~' + spinnable = True def empty(self): self.thing_char = '_' self.full = False + def spin(self): + import random + all_players = [t for t in self.game.things if t.type_ == 'Player'] + # TODO: refactor with ThingPlayer.prepare_multiprocessible_fov_stencil + # and ThingPlayer.fov_test + fov_map_class = self.game.map_geometry.fov_map_class + fov_radius = 12 + fov = fov_map_class(self.game.things, self.game.maps, + self.position, fov_radius, self.game.get_map) + fov.init_terrain() + visible_players = [] + for p in all_players: + test_position = fov.target_yx(p.position[0], p.position[1]) + if fov.inside(test_position) and fov[test_position] == '.': + visible_players += [p] + if len(visible_players) == 0: + self.sound('BOTTLE', 'no visible players in spin range') + pick = random.choice(visible_players) + self.sound('BOTTLE', 'BOTTLE picks: ' + pick.name) + class Thing_BottleSpawner(ThingSpawner): diff --git a/rogue_chat.html b/rogue_chat.html index 1c1fd1a..9740fff 100644 --- a/rogue_chat.html +++ b/rogue_chat.html @@ -59,6 +59,7 @@ keyboard input/control: + @@ -99,6 +100,7 @@ keyboard input/control:
  • help:
  • flatten surroundings:
  • teleport: +
  • spin:
  • open/close:
  • consume:
  • install: @@ -253,6 +255,7 @@ let key_descriptions = { 'consume': 'consume', 'install': '(un-)install', 'wear': '(un-)wear', + 'spin': 'spin', 'toggle_map_mode': 'toggle map view', 'toggle_tile_draw': 'toggle protection character drawing', 'hex_move_upleft': 'up-left', @@ -693,6 +696,7 @@ let tui = { 'wear': 'WEAR', 'command': 'COMMAND', 'consume': 'INTOXICATE', + 'spin': 'SPIN', }, offset: [0,0], map_lines: [], @@ -701,7 +705,7 @@ let tui = { this.mode_play.available_modes = ["chat", "study", "edit", "admin_enter", "command_thing", "take_thing", "drop_thing"] this.mode_play.available_actions = ["move", "teleport", "door", "consume", - "install", "wear"]; + "install", "wear", "spin"]; this.mode_study.available_modes = ["chat", "play", "admin_enter", "edit"] this.mode_study.available_actions = ["toggle_map_mode", "move_explorer"]; this.mode_admin.available_modes = ["admin_thing_protect", "control_pw_type", @@ -1588,6 +1592,8 @@ tui.inputEl.addEventListener('keydown', (event) => { server.send(["TASK:INSTALL"]); } else if (event.key === tui.keys.wear && tui.task_action_on('wear')) { server.send(["TASK:WEAR"]); + } else if (event.key === tui.keys.spin && tui.task_action_on('spin')) { + server.send(["TASK:SPIN"]); } else if (event.key in tui.movement_keys && tui.task_action_on('move')) { server.send(['TASK:MOVE', tui.movement_keys[event.key]]); } else if (event.key === tui.keys.teleport) { @@ -1710,6 +1716,9 @@ document.getElementById("install").onclick = function() { document.getElementById("wear").onclick = function() { server.send(['TASK:WEAR']); }; +document.getElementById("spin").onclick = function() { + server.send(['TASK:SPIN']); +}; document.getElementById("teleport").onclick = function() { game.teleport(); }; diff --git a/rogue_chat.py b/rogue_chat.py index 8e4fd1b..8187583 100755 --- a/rogue_chat.py +++ b/rogue_chat.py @@ -17,7 +17,7 @@ from plomrogue.commands import (cmd_ALL, cmd_LOGIN, cmd_NICK, cmd_PING, cmd_THIN 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, - Task_WEAR) + Task_WEAR, Task_SPIN) from plomrogue.things import (Thing_Player, Thing_Item, Thing_ItemSpawner, Thing_SpawnPoint, Thing_SpawnPointSpawner, Thing_Door, Thing_DoorSpawner, Thing_Bottle, @@ -73,6 +73,7 @@ game.register_task(Task_INTOXICATE) game.register_task(Task_COMMAND) game.register_task(Task_INSTALL) game.register_task(Task_WEAR) +game.register_task(Task_SPIN) game.register_thing_type(Thing_Player) game.register_thing_type(Thing_Item) game.register_thing_type(Thing_ItemSpawner) diff --git a/rogue_chat_curses.py b/rogue_chat_curses.py index 2d51ce8..6f13638 100755 --- a/rogue_chat_curses.py +++ b/rogue_chat_curses.py @@ -463,7 +463,7 @@ class TUI: "command_thing", "take_thing", "drop_thing"] self.mode_play.available_actions = ["move", "teleport", "door", "consume", - "install", "wear"] + "install", "wear", "spin"] self.mode_study.available_modes = ["chat", "play", "admin_enter", "edit"] self.mode_study.available_actions = ["toggle_map_mode", "move_explorer"] self.mode_admin.available_modes = ["admin_thing_protect", "control_pw_type", @@ -513,6 +513,7 @@ class TUI: 'door': 'D', 'install': 'I', 'wear': 'W', + 'spin': 'S', 'help': 'h', 'toggle_map_mode': 'L', 'toggle_tile_draw': 'm', @@ -1030,6 +1031,7 @@ class TUI: 'wear': '(un-)wear', 'door': 'open/close', 'consume': 'consume', + 'spin': 'spin', } action_tasks = { @@ -1042,6 +1044,7 @@ class TUI: 'move': 'MOVE', 'command': 'COMMAND', 'consume': 'INTOXICATE', + 'spin': 'SPIN', } curses.curs_set(False) # hide cursor @@ -1212,6 +1215,8 @@ class TUI: self.send('TASK:INSTALL') elif key == self.keys['wear'] and task_action_on('wear'): self.send('TASK:WEAR') + elif key == self.keys['spin'] and task_action_on('spin'): + self.send('TASK:SPIN') elif key == self.keys['teleport']: player = self.game.get_thing(self.game.player_id) if player.position in self.game.portals: -- 2.30.2