home · contact · privacy
Extend sitting message with info about weariness mechanic.
[plomrogue2] / rogue_chat.html
index 31a85a56d3d45e787b7f6d11f92b9fc6ecdac4df..84d481c806218a35570d937cd49e485aacbff054 100644 (file)
@@ -14,8 +14,10 @@ terminal rows: <input id="n_rows" type="number" step=4 min=24 value=24 />
 / terminal columns: <input id="n_cols" type="number" step=4 min=80 value=80 />
 / <a href="https://plomlompom.com/repos/?p=plomrogue2;a=summary">source code</a> (includes proper terminal/ncurses client)
 </div>
+<div style="position: relative; display: inline-block;">
 <pre id="terminal"></pre>
-<textarea id="input" style="opacity: 0; width: 0px;"></textarea>
+<textarea id="input" style="position: absolute; left: 0; height: 100%; width: 100%; opacity: 0; z-index: -1;"></textarea>
+</div>
 <h3>button controls for hard-to-remember keybindings</h3>
 <table id="move_table" style="float: left">
   <tr>
@@ -148,7 +150,7 @@ let mode_helps = {
     'name_thing': {
         'short': 'name thing',
         'intro': '',
-        'long': 'Give name to/change name of thing here.'
+        'long': 'Give name to/change name of carried thing.'
     },
     'command_thing': {
         'short': 'command',
@@ -168,7 +170,7 @@ let mode_helps = {
     'admin_thing_protect': {
         'short': 'change thing protection',
         'intro': '@ enter thing protection character:',
-        'long': 'Change protection character for thing here.'
+        'long': 'Change protection character for carried thing.'
     },
     'enter_face': {
         'short': 'edit face',
@@ -483,11 +485,13 @@ let server = {
         let tokens = parser.tokenize(event.data);
         if (tokens[0] === 'TURN') {
             game.turn_complete = false;
-            game.turn = parseInt(tokens[1]);
         } else if (tokens[0] === 'OTHER_WIPE') {
             game.portals_new = {};
             explorer.annotations_new = {};
             game.things_new = [];
+        } else if (tokens[0] === 'STATS') {
+            game.bladder_pressure_new = parseInt(tokens[1])
+            game.weariness_new = parseInt(tokens[2])
         } else if (tokens[0] === 'THING') {
             let t = game.get_thing_temp(tokens[4], true);
             t.position = parser.parse_yx(tokens[1]);
@@ -517,7 +521,7 @@ let server = {
             game.thing_types[tokens[1]] = tokens[2]
         } else if (tokens[0] === 'THING_CARRYING') {
             let t = game.get_thing_temp(tokens[1]);
-            t.carrying = game.get_thing(tokens[2], false);
+            t.carrying = game.get_thing_temp(tokens[2], false);
         } else if (tokens[0] === 'THING_INSTALLED') {
             let t = game.get_thing_temp(tokens[1]);
             t.installed = true;
@@ -544,6 +548,8 @@ let server = {
             game.things = game.things_new;
             game.player = game.things[game.player_id];
             game.players_hat_chars = game.players_hat_chars_new;
+            game.bladder_pressure = game.bladder_pressure_new
+            game.weariness = game.weariness_new
             game.turn_complete = true;
             if (tui.mode.name == 'post_login_wait') {
                 tui.switch_mode('play');
@@ -785,7 +791,7 @@ let tui = {
   },
   switch_mode: function(mode_name) {
 
-    function fail(msg, return_mode) {
+    function fail(msg, return_mode='play') {
         tui.log_msg('? ' + msg);
         terminal.blink_screen();
         tui.switch_mode(return_mode);
@@ -798,34 +804,20 @@ let tui = {
     this.tile_draw = false;
     if (mode_name == 'command_thing' && (!game.player.carrying
                                          || !game.player.carrying.commandable)) {
-        return fail('not carrying anything commandable', 'play');
+        return fail('not carrying anything commandable');
+    } else if (mode_name == 'name_thing' && !game.player.carrying) {
+        return fail('not carrying anything to re-name');
+    } else if (mode_name == 'admin_thing_protect' && !game.player.carrying) {
+        return fail('not carrying anything to protect')
     } else if (mode_name == 'take_thing' && game.player.carrying) {
-        return fail('already carrying something', 'play');
+        return fail('already carrying something');
     } else if (mode_name == 'drop_thing' && !game.player.carrying) {
-        return fail('not carrying anything droppable', 'play');
+        return fail('not carrying anything droppable');
     } else if (mode_name == 'enter_hat' && !game.player.hat) {
         return fail('not wearing hat to edit', 'edit');
     }
     if (mode_name == 'admin_enter' && this.is_admin) {
         mode_name = 'admin';
-    } else if (['name_thing', 'admin_thing_protect'].includes(mode_name)) {
-        let thing_id = null;
-        for (let t_id in game.things) {
-            if (t_id == game.player_id) {
-                continue;
-            }
-            let t = game.things[t_id];
-            if (game.player.position[0] == t.position[0]
-                && game.player.position[1] == t.position[1]) {
-                thing_id = t_id;
-                break;
-            }
-        }
-        if (!thing_id) {
-            return fail('not standing over thing', 'fail');
-        } else {
-            this.selected_thing_id = thing_id;
-        }
     };
     this.mode = this['mode_' + mode_name];
     if (["control_tile_draw", "control_tile_type", "control_pw_type"].includes(this.mode.name)) {
@@ -873,29 +865,45 @@ let tui = {
         this.log_msg("Portable things in reach for pick-up:");
         const y = game.player.position[0]
         const x = game.player.position[1]
-        let select_range = [y.toString() + ':' + x.toString(),
-                            (y + 0).toString() + ':' + (x - 1).toString(),
-                            (y + 0).toString() + ':' + (x + 1).toString(),
-                            (y - 1).toString() + ':' + (x).toString(),
-                            (y + 1).toString() + ':' + (x).toString()];
-        if (game.map_geometry == 'Hex') {
+        let directed_moves = {
+            'HERE': [0, 0], 'LEFT': [0, -1], 'RIGHT': [0, 1]
+        }
+        if (game.map_geometry == 'Square') {
+            directed_moves['UP'] = [-1, 0];
+            directed_moves['DOWN'] = [1, 0];
+        } else if (game.map_geometry == 'Hex') {
             if (y % 2) {
-                select_range.push((y - 1).toString() + ':' + (x + 1).toString());
-                select_range.push((y + 1).toString() + ':' + (x + 1).toString());
+                directed_moves['UPLEFT'] = [-1, 0];
+                directed_moves['UPRIGHT'] = [-1, 1];
+                directed_moves['DOWNLEFT'] = [1, 0];
+                directed_moves['DOWNRIGHT'] = [1, 1];
             } else {
-                select_range.push((y - 1).toString() + ':' + (x - 1).toString());
-                select_range.push((y + 1).toString() + ':' + (x - 1).toString());
+                directed_moves['UPLEFT'] = [-1, -1];
+                directed_moves['UPRIGHT'] = [-1, 0];
+                directed_moves['DOWNLEFT'] = [1, -1];
+                directed_moves['DOWNRIGHT'] = [1, 0];
             }
-        };
+        }
+        console.log(directed_moves);
+        let select_range = {};
+        for (const direction in directed_moves) {
+            const move = directed_moves[direction];
+            select_range[direction] = [y + move[0], x + move[1]];
+        }
         this.selectables = [];
-        for (const t_id in game.things) {
-            const t = game.things[t_id];
-            if (select_range.includes(t.position[0].toString()
-                                      + ':' + t.position[1].toString())
-                && t.portable) {
-                this.selectables.push(t_id);
+        let directions = [];
+        for (const direction in select_range) {
+            for (const t_id in game.things) {
+                const t = game.things[t_id];
+                const position = select_range[direction];
+                if (t.portable
+                    && t.position[0] == position[0]
+                    && t.position[1] == position[1]) {
+                    this.selectables.push(t_id);
+                    directions.push(direction);
+                }
             }
-        };
+        }
         if (this.selectables.length == 0) {
             this.log_msg('none');
             terminal.blink_screen();
@@ -904,7 +912,8 @@ let tui = {
         } else {
             for (let [i, t_id] of this.selectables.entries()) {
                 const t = game.things[t_id];
-                this.log_msg(i + ': ' + explorer.get_thing_info(t));
+                const direction = directions[i];
+                this.log_msg(i + ' ' + direction + ': ' + explorer.get_thing_info(t));
             }
         }
     } else if (this.mode.name == 'drop_thing') {
@@ -948,14 +957,12 @@ let tui = {
       } else if (this.mode.name == 'password') {
           this.inputEl.value = this.password;
       } else if (this.mode.name == 'name_thing') {
-          let t = game.get_thing(this.selected_thing_id);
-          if (t && t.name_) {
-              this.inputEl.value = t.name_;
+          if (game.player.carrying && game.player.carrying.name_) {
+              this.inputEl.value = game.player.carrying.name_;
           }
       } else if (this.mode.name == 'admin_thing_protect') {
-          let t = game.get_thing(this.selected_thing_id);
-          if (t && t.protection) {
-              this.inputEl.value = t.protection;
+          if (game.player.carrying && game.player.carrying.protection) {
+              this.inputEl.value = game.player.carrying.protection;
           }
       } else if (['enter_face', 'enter_hat'].includes(this.mode.name)) {
           const start = this.ascii_draw_stage * 6;
@@ -970,7 +977,7 @@ let tui = {
   recalc_input_lines: function() {
       if (this.mode.has_input_prompt) {
           let _ = null;
-          [this.input_lines, _] = this.msg_into_lines_of_width(this.input_prompt + this.inputEl.value, this.window_width);
+          [this.input_lines, _] = this.msg_into_lines_of_width(this.input_prompt + this.inputEl.value + '█', this.window_width);
       } else {
           this.input_lines = [];
       }
@@ -983,10 +990,11 @@ let tui = {
           };
           inner_links[y].push([url_start_x, end_x, url]);
       };
-      const matches = msg.matchAll(/https?:\/\/[^\s]+/g)
       let link_data = {};
       let url_ends = [];
-      for (const match of matches) {
+      const regexp = RegExp('https?://[^\\s]+', 'g');
+      let match;
+      while ((match = regexp.exec(msg)) !== null) {
           const url = match[0];
           const url_start = match.index;
           const url_end = match.index + match[0].length;
@@ -1206,10 +1214,10 @@ let tui = {
       }
       terminal.write(0, this.window_width, 'MODE: ' + this.mode.short_desc + ' – ' + help);
   },
-  draw_turn_line: function(n) {
-      if (game.turn_complete) {
-          terminal.write(1, this.window_width, 'TURN: ' + game.turn);
-      }
+  draw_stats_line: function(n) {
+      terminal.write(1, this.window_width,
+                     'WEARINESS: ' + game.weariness +
+                     ' BLADDER: ' + game.bladder_pressure);
   },
   draw_history: function() {
       let log_display_lines = [];
@@ -1324,7 +1332,7 @@ let tui = {
         this.draw_input();
     } else {
         this.draw_map();
-        this.draw_turn_line();
+        this.draw_stats_line();
         this.draw_mode_line();
         if (this.mode.shows_info) {
           this.draw_info();
@@ -1364,6 +1372,8 @@ let game = {
         this.portals = {};
         this.portals_new = {};
         this.players_hat_chars = "";
+        this.bladder_pressure = 0;
+        this.bladder_pressure_new = 0;
     },
     get_thing_temp: function(id_, create_if_not_found=false) {
         if (id_ in game.things_new) {
@@ -1554,7 +1564,7 @@ document.onclick = function() {
 };
 tui.inputEl.addEventListener('keydown', (event) => {
     tui.show_help = false;
-    if (event.key == 'Enter') {
+    if (['Enter', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
         event.preventDefault();
     }
     if ((!tui.mode.is_intro && event.key == 'Escape')
@@ -1604,8 +1614,7 @@ tui.inputEl.addEventListener('keydown', (event) => {
         if (tui.inputEl.value.length == 0) {
             tui.inputEl.value = " ";
         }
-        server.send(["THING_NAME", tui.selected_thing_id, tui.inputEl.value,
-                     tui.password]);
+        server.send(["THING_NAME", tui.inputEl.value, tui.password]);
         tui.switch_mode('edit');
     } else if (tui.mode.name == 'annotate' && event.key == 'Enter') {
         explorer.annotate(tui.inputEl.value);
@@ -1639,7 +1648,7 @@ tui.inputEl.addEventListener('keydown', (event) => {
         if (tui.inputEl.value.length != 1) {
             tui.log_msg('@ entered non-single-char, therefore aborted');
         } else {
-            server.send(['THING_PROTECTION', tui.selected_thing_id, tui.inputEl.value])
+            server.send(['THING_PROTECTION', tui.inputEl.value])
             tui.log_msg('@ sent new protection character for thing');
         }
         tui.switch_mode('admin');
@@ -1750,10 +1759,7 @@ window.setInterval(function() {
 }, 1000);
 window.setInterval(function() {
     if (document.activeElement.tagName.toLowerCase() != 'input') {
-        const scroll_x = window.scrollX;
-        const scroll_y = window.scrollY;
         tui.inputEl.focus();
-        window.scrollTo(scroll_x, scroll_y);
     };
 }, 100);
 document.getElementById("help").onclick = function() {