home · contact · privacy
Add colourful intoxication beverage.
authorChristian Heller <c.heller@plomlompom.de>
Tue, 1 Dec 2020 05:24:11 +0000 (06:24 +0100)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 1 Dec 2020 05:24:11 +0000 (06:24 +0100)
config.json
plomrogue/tasks.py
plomrogue/things.py
rogue_chat.html
rogue_chat.py
rogue_chat_curses.py

index 33243afab11043aea621f74eb283a4f70e098d31..d381939af6181de6be1518a6c34b38088dd700f8 100644 (file)
@@ -17,6 +17,7 @@
     "drop_thing": "u",
     "teleport": "p",
     "door": "D",
+    "consume": "C",
     "help": "h",
     "toggle_map_mode": "L",
     "toggle_tile_draw": "m",
index a7f1dcf3f1d174ba43b7f3bd969a36cba2a65978..8b831313c9d69a14f5b92b9f81273a13274e27b3 100644 (file)
@@ -4,7 +4,7 @@ from plomrogue.errors import PlayError, GameError
 
 class Task:
     argtypes = ''
-    todo = 3
+    todo = 1
 
     def __init__(self, thing, args=()):
         self.thing = thing
@@ -16,7 +16,6 @@ class Task:
 
 
 class Task_WAIT(Task):
-    todo = 1
 
     def do(self):
         pass
@@ -24,7 +23,6 @@ class Task_WAIT(Task):
 
 
 class Task_MOVE(Task):
-    todo = 1
     argtypes = 'string:direction'
 
     def get_move_target(self):
@@ -47,7 +45,6 @@ class Task_MOVE(Task):
 
 
 class Task_WRITE(Task):
-    todo = 1
     argtypes = 'string:char string'
 
     def check(self):
@@ -63,7 +60,6 @@ class Task_WRITE(Task):
 
 
 class Task_FLATTEN_SURROUNDINGS(Task):
-    todo = 10
     argtypes = 'string'
 
     def check(self):
@@ -80,7 +76,6 @@ class Task_FLATTEN_SURROUNDINGS(Task):
 
 
 class Task_PICK_UP(Task):
-    todo = 1
 
     def check(self):
         if self.thing.carrying:
@@ -104,7 +99,6 @@ class Task_PICK_UP(Task):
 
 
 class Task_DROP(Task):
-    todo = 1
 
     def check(self):
         if not self.thing.carrying:
@@ -116,7 +110,6 @@ class Task_DROP(Task):
 
 
 class Task_DOOR(Task):
-    todo = 1
 
     def do(self):
         self.thing.carrying = None
@@ -128,3 +121,22 @@ class Task_DOOR(Task):
                 t.open()
             else:
                 t.close()
+
+
+
+class Task_INTOXICATE(Task):
+
+    def check(self):
+        if self.thing.carrying is None:
+            raise PlayError('nothing to consume')
+        if self.thing.carrying.type_ != 'Consumable':
+            raise PlayError('cannot consume non-consumable')
+
+    def do(self):
+        self.thing.game.things.remove(self.thing.carrying)
+        self.thing.carrying = None
+        for c_id in self.thing.game.sessions:
+            if self.thing.game.sessions[c_id]['thing_id'] == self.thing.id_:
+                self.thing.game.io.send('RANDOM_COLORS', c_id)
+                self.thing.game.io.send('CHAT "You are drunk now."', c_id)
+        self.thing.drunk = 10000
index b757157d99cef4375f344ec0038f83599503cae6..2146c1a222f48a78b4e3abe9187e09aa86909ba2 100644 (file)
@@ -96,8 +96,20 @@ class Thing_Door(Thing):
 
 
 
+class Thing_Consumable(Thing):
+    symbol_hint = 'B'
+    portable = True
+
+
+
+class Thing_ConsumableSpawner(ThingSpawner):
+    child_type = 'Consumable'
+
+
+
 class ThingAnimate(Thing):
     blocking = True
+    drunk = 0
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
@@ -123,11 +135,17 @@ class ThingAnimate(Thing):
             return None
 
     def proceed(self):
+        self.drunk -= 1
+        if self.drunk == 0:
+            for c_id in self.game.sessions:
+                if self.game.sessions[c_id]['thing_id'] == self.id_:
+                    self.game.io.send('DEFAULT_COLORS', c_id)
+                    self.game.io.send('CHAT "You sober up."', c_id)
+            self.game.changed = True
         self._fov = None
         if self.task is None:
             self.task = self.get_next_task()
             return
-
         try:
             self.task.check()
         except GameError as e:
index 554c5945232f7aac6d57d786b02b206c7f8052cf..17747ff55462b67c66337727ad51d67d02f55b2e 100644 (file)
@@ -54,6 +54,7 @@ keyboard input/control: <span id="keyboard_control"></span>
       <button id="take_thing"></button>
       <button id="drop_thing"></button>
       <button id="door"></button>
+      <button id="consume"></button>
       <button id="teleport"></button>
     </td>
   </tr>
@@ -97,6 +98,7 @@ keyboard input/control: <span id="keyboard_control"></span>
 <li>pick up thing: <input id="key_take_thing" type="text" value="z" />
 <li>drop thing: <input id="key_drop_thing" type="text" value="u" />
 <li>open/close: <input id="key_door" type="text" value="D" />
+<li>consume: <input id="key_consume" type="text" value="C" />
 <li><input id="key_switch_to_chat" type="text" value="t" />
 <li><input id="key_switch_to_play" type="text" value="p" />
 <li><input id="key_switch_to_study" type="text" value="?" />
@@ -203,6 +205,7 @@ let key_descriptions = {
     'take_thing': 'pick up thing',
     'drop_thing': 'drop thing',
     'door': 'open/close',
+    'consume': 'consume',
     'toggle_map_mode': 'toggle map view',
     'toggle_tile_draw': 'toggle protection character drawing',
     'hex_move_upleft': 'up-left',
@@ -251,14 +254,12 @@ function escapeHTML(str) {
 };
 
 let terminal = {
-  foreground: 'white',
-  background: 'black',
   initialize: function() {
     this.rows = rows_selector.value;
     this.cols = cols_selector.value;
     this.pre_el = document.getElementById("terminal");
-    this.pre_el.style.color = this.foreground;
-    this.pre_el.style.backgroundColor = this.background;
+    this.set_default_colors();
+    this.apply_colors();
     this.content = [];
       let line = []
     for (let y = 0, x = 0; y <= this.rows; x++) {
@@ -274,6 +275,23 @@ let terminal = {
         line.push(' ');
     }
   },
+  apply_colors: function() {
+    this.pre_el.style.color = this.foreground;
+    this.pre_el.style.backgroundColor = this.background;
+  },
+  set_default_colors: function() {
+      this.foreground = 'white';
+      this.background = 'black';
+      this.apply_colors();
+  },
+  set_random_colors: function() {
+      function rand(offset) {
+          return Math.floor(offset + Math.random() * 96).toString(16);
+      }
+      this.foreground = '#' + rand(159) + rand(159) + rand(159);
+      this.background = '#' + rand(0) + rand(0) + rand(0);
+      this.apply_colors();
+  },
   blink_screen: function() {
       this.pre_el.style.color = this.background;
       this.pre_el.style.backgroundColor = this.foreground;
@@ -434,7 +452,6 @@ let server = {
             };
         } else if (tokens[0] === 'TASKS') {
             game.tasks = tokens[1].split(',');
-            console.log(game.tasks);
             tui.mode_write.legal = game.tasks.includes('WRITE');
         } else if (tokens[0] === 'THING_TYPE') {
             game.thing_types[tokens[1]] = tokens[2]
@@ -464,6 +481,10 @@ let server = {
         } else if (tokens[0] === 'LOGIN_OK') {
             this.send(['GET_GAMESTATE']);
             tui.switch_mode('post_login_wait');
+        } else if (tokens[0] === 'DEFAULT_COLORS') {
+            terminal.set_default_colors();
+        } else if (tokens[0] === 'RANDOM_COLORS') {
+            terminal.set_random_colors();
         } else if (tokens[0] === 'ADMIN_OK') {
             tui.is_admin = true;
             tui.log_msg('@ you now have admin rights');
@@ -604,12 +625,13 @@ let tui = {
       'drop_thing': 'DROP',
       'move': 'MOVE',
       'door': 'DOOR',
+      'consume': 'INTOXICATE',
   },
   init: function() {
       this.mode_chat.available_modes = ["play", "study", "edit", "admin_enter"]
       this.mode_play.available_modes = ["chat", "study", "edit", "admin_enter"]
       this.mode_play.available_actions = ["move", "take_thing", "drop_thing",
-                                          "teleport", "door"];
+                                          "teleport", "door", "consume"];
       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",
@@ -1388,6 +1410,8 @@ tui.inputEl.addEventListener('keydown', (event) => {
               server.send(["TASK:PICK_UP"]);
           } else if (event.key === tui.keys.drop_thing && tui.task_action_on('drop_thing')) {
               server.send(["TASK:DROP"]);
+          } else if (event.key === tui.keys.consume && tui.task_action_on('consume')) {
+              server.send(["TASK:INTOXICATE"]);
           } else if (event.key === tui.keys.door && tui.task_action_on('door')) {
               server.send(["TASK:DOOR"]);
           } else if (event.key in tui.movement_keys && tui.task_action_on('move')) {
@@ -1509,6 +1533,9 @@ document.getElementById("flatten").onclick = function() {
 document.getElementById("door").onclick = function() {
     server.send(['TASK:DOOR']);
 };
+document.getElementById("consume").onclick = function() {
+    server.send(['TASK:INTOXICATE']);
+};
 document.getElementById("teleport").onclick = function() {
     game.teleport();
 };
index c4a44008c4b20bf78df8148ba38b3bebf2191286..3d9bf18d4a3b2f89905e97c7ada9f71a2e481947 100755 (executable)
@@ -11,10 +11,12 @@ from plomrogue.commands import (cmd_ALL, cmd_LOGIN, cmd_NICK, cmd_PING, cmd_THIN
                                 cmd_GOD_THING_PROTECTION, cmd_THING_PROTECTION,
                                 cmd_SET_MAP_CONTROL_PASSWORD, cmd_SPAWN_POINT)
 from plomrogue.tasks import (Task_WAIT, Task_MOVE, Task_WRITE, Task_PICK_UP,
-                             Task_DROP, Task_FLATTEN_SURROUNDINGS, Task_DOOR)
+                             Task_DROP, Task_FLATTEN_SURROUNDINGS, Task_DOOR,
+                             Task_INTOXICATE)
 from plomrogue.things import (Thing_Player, Thing_Item, Thing_ItemSpawner,
                               Thing_SpawnPoint, Thing_SpawnPointSpawner,
-                              Thing_Door, Thing_DoorSpawner)
+                              Thing_Door, Thing_DoorSpawner, Thing_Consumable,
+                              Thing_ConsumableSpawner)
 
 from plomrogue.config import config
 game = Game(config['savefile'])
@@ -54,6 +56,7 @@ game.register_task(Task_FLATTEN_SURROUNDINGS)
 game.register_task(Task_PICK_UP)
 game.register_task(Task_DROP)
 game.register_task(Task_DOOR)
+game.register_task(Task_INTOXICATE)
 game.register_thing_type(Thing_Player)
 game.register_thing_type(Thing_Item)
 game.register_thing_type(Thing_ItemSpawner)
@@ -61,6 +64,8 @@ game.register_thing_type(Thing_SpawnPoint)
 game.register_thing_type(Thing_SpawnPointSpawner)
 game.register_thing_type(Thing_Door)
 game.register_thing_type(Thing_DoorSpawner)
+game.register_thing_type(Thing_Consumable)
+game.register_thing_type(Thing_ConsumableSpawner)
 game.read_savefile()
 game.io.start_loop()
 for port in config['servers']:
index cb5042d5a8d4b620448083e3a8a2b31363b83e71..127c98921b7f501dca310c03709642aca4200e5f 100755 (executable)
@@ -268,6 +268,14 @@ def cmd_PONG(game):
     pass
 cmd_PONG.argtypes = ''
 
+def cmd_DEFAULT_COLORS(game):
+    game.tui.set_default_colors()
+cmd_DEFAULT_COLORS.argtypes = ''
+
+def cmd_RANDOM_COLORS(game):
+    game.tui.set_random_colors()
+cmd_RANDOM_COLORS.argtypes = ''
+
 class Game(GameBase):
     turn_complete = False
     tasks = {}
@@ -297,6 +305,8 @@ class Game(GameBase):
         self.register_command(cmd_PLAY_ERROR)
         self.register_command(cmd_TASKS)
         self.register_command(cmd_FOV)
+        self.register_command(cmd_DEFAULT_COLORS)
+        self.register_command(cmd_RANDOM_COLORS)
         self.map_content = ''
         self.player_id = -1
         self.info_db = {}
@@ -383,7 +393,7 @@ class TUI:
         import json
         self.mode_play.available_modes = ["chat", "study", "edit", "admin_enter"]
         self.mode_play.available_actions = ["move", "take_thing", "drop_thing",
-                                            "teleport", "door"]
+                                            "teleport", "door", "consume"]
         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",
@@ -427,6 +437,7 @@ class TUI:
             'take_thing': 'z',
             'drop_thing': 'u',
             'teleport': 'p',
+            'consume': 'C',
             'door': 'D',
             'help': 'h',
             'toggle_map_mode': 'L',
@@ -596,19 +607,34 @@ class TUI:
         self.input_ = ""
         self.restore_input_values()
 
+    def set_default_colors(self):
+        curses.init_color(1, 1000, 1000, 1000)
+        curses.init_color(2, 0, 0, 0)
+        self.do_refresh = True
+
+    def set_random_colors(self):
+
+        def rand(offset):
+            import random
+            return int(offset + random.random()*375)
+
+        curses.init_color(1, rand(625), rand(625), rand(625))
+        curses.init_color(2, rand(0), rand(0), rand(0))
+        self.do_refresh = True
+
     def loop(self, stdscr):
         import datetime
 
         def safe_addstr(y, x, line):
             if y < self.size.y - 1 or x + len(line) < self.size.x:
-                stdscr.addstr(y, x, line)
+                stdscr.addstr(y, x, line, curses.color_pair(1))
             else:  # workaround to <https://stackoverflow.com/q/7063128>
                 cut_i = self.size.x - x - 1
                 cut = line[:cut_i]
                 last_char = line[cut_i]
-                stdscr.addstr(y, self.size.x - 2, last_char)
+                stdscr.addstr(y, self.size.x - 2, last_char, curses.color_pair(1))
                 stdscr.insstr(y, self.size.x - 2, ' ')
-                stdscr.addstr(y, x, cut)
+                stdscr.addstr(y, x, cut, curses.color_pair(1))
 
         def handle_input(msg):
             command, args = self.parser.parse(msg)
@@ -836,6 +862,7 @@ class TUI:
 
         def draw_screen():
             stdscr.clear()
+            stdscr.bkgd(' ', curses.color_pair(1))
             recalc_input_lines()
             if self.mode.has_input_prompt:
                 draw_input()
@@ -859,6 +886,7 @@ class TUI:
             'toggle_map_mode': 'toggle map view',
             'toggle_tile_draw': 'toggle protection character drawing',
             'door': 'open/close',
+            'consume': 'consume',
         }
 
         action_tasks = {
@@ -867,10 +895,13 @@ class TUI:
             'drop_thing': 'DROP',
             'door': 'DOOR',
             'move': 'MOVE',
+            'consume': 'INTOXICATE',
         }
 
         curses.curs_set(False)  # hide cursor
-        curses.use_default_colors()
+        curses.start_color()
+        self.set_default_colors()
+        curses.init_pair(1, 1, 2)
         stdscr.timeout(10)
         reset_screen_size()
         self.explorer = YX(0, 0)
@@ -1021,6 +1052,8 @@ class TUI:
                     self.send('TASK:DROP')
                 elif key == self.keys['door'] and task_action_on('door'):
                     self.send('TASK:DOOR')
+                elif key == self.keys['consume'] and task_action_on('consume'):
+                    self.send('TASK:INTOXICATE')
                 elif key == self.keys['teleport']:
                     player = self.game.get_thing(self.game.player_id)
                     if player.position in self.game.portals: