X-Git-Url: https://plomlompom.com/repos/?a=blobdiff_plain;f=new2%2Frogue_chat_nocanvas_monochrome.html;h=82df80c5ac78af50d86fac88ef1aa9cdd5897e1f;hb=f571ed54e432ba540b4a1b2a4ad63f71aa91ef40;hp=0ca95ed908a1a8d3c42bcf276e896560a2b7db85;hpb=ad8904ecc8fccd0ce52225d86e48c5f767b16daa;p=plomrogue2-experiments diff --git a/new2/rogue_chat_nocanvas_monochrome.html b/new2/rogue_chat_nocanvas_monochrome.html index 0ca95ed..82df80c 100644 --- a/new2/rogue_chat_nocanvas_monochrome.html +++ b/new2/rogue_chat_nocanvas_monochrome.html @@ -27,7 +27,6 @@ let terminal = { } line.push(' '); } - console.log(this.content); }, refresh: function() { let pre_string = ''; @@ -38,19 +37,22 @@ let terminal = { this.pre_el.textContent = pre_string; }, write: function(start_y, start_x, msg) { - for (let x = start_x, i = 0; x < this.cols, i < msg.length; x++, i++) { + for (let x = start_x, i = 0; x < this.cols && i < msg.length; x++, i++) { this.content[start_y][x] = msg[i]; } }, drawBox: function(start_y, start_x, height, width) { let end_y = start_y + height; let end_x = start_x + width; - for (let y = start_y, x = start_x; y < end_y; x++) { - this.content[y][x] = ' '; + for (let y = start_y, x = start_x;; x++) { if (x == end_x) { - x = start_x - 1; - y += 1; - } + x = start_x; + y += 1; + if (y == end_y) { + break; + } + }; + this.content[y][x] = ' '; } }, } @@ -96,10 +98,31 @@ let parser = { position[0] = parseInt(coordinate_strings[0].slice(2)); position[1] = parseInt(coordinate_strings[1].slice(2)); return position; - } + }, +} + +function quote(str) { + let quoted = ['"']; + for (let i = 0; i < str.length; i++) { + let c = str[i]; + if (c in ['"', '\\']) { + quoted.push('\\'); + }; + quoted.push(c); + } + quoted.push('"'); + return quoted.join(''); } let tui = { + mode: 'chat', + switch_mode: function(mode_name) { + if (mode_name == 'explore') { + explorer.position = game.things[game.player_id]; + } + this.mode = mode_name; + this.full_refresh(); + }, draw_history: function() { terminal.drawBox(1, terminal.cols / 2, terminal.rows - 2, terminal.cols / 2); let i = 0; @@ -109,22 +132,40 @@ let tui = { } }, draw_map: function() { + terminal.drawBox(0, 0, terminal.rows, terminal.cols / 2); let map_lines = []; - let line = ''; + let line = []; for (let i = 0, j = 0; i < game.map.length; i++, j++) { if (j == game.map_size[1]) { map_lines.push(line); - line = ''; + line = []; j = 0; }; - line += game.map[i]; + line.push(game.map[i]); }; map_lines.push(line); - for (let y = 0; y < game.map_size[0]; y++) { - terminal.write(y, 0, map_lines[y]); + let player_position = [0,0]; + for (const thing_id in game.things) { + let t = game.things[thing_id]; + map_lines[t[0]][t[1]] = '@'; + if (game.player_id == thing_id) { + player_position = t; + } + }; + let center_pos = player_position; + if (tui.mode == 'explore') { + map_lines[explorer.position[0]][explorer.position[1]] = '?'; + center_pos = explorer.position; } - for (const t in game.things) { - terminal.write(game.things[t][0], game.things[t][1], '@'); + let offset = [(terminal.rows / 2) - center_pos[0], + terminal.cols / 4 - center_pos[1]]; + for (let term_y = offset[0], map_y = 0; + term_y < terminal.rows && map_y < game.map_size[0]; + term_y++, map_y++) { + if (term_y >= 0) { + let to_draw = map_lines[map_y].join('').slice(0, terminal.cols / 2 - offset[1]); + terminal.write(term_y, offset[1], to_draw); + } } }, draw_turn_line: function(n) { @@ -135,18 +176,18 @@ let tui = { terminal.drawBox(terminal.rows - 1, terminal.cols / 2, 1, terminal.cols / 2); terminal.write(terminal.rows - 1, terminal.cols / 2, chat.input_line); }, - log_msg: function(msg, indent=0) { - let line_length = (terminal.cols / 2) - indent; + log_msg: function(msg) { + let line_length = (terminal.cols / 2); let chunk = ""; for (let i = 0, x = 0; i < msg.length; i++, x++) { if (x >= line_length) { - chat.history.unshift(' '.repeat(indent) + chunk); - chunk = ""; + chat.history.unshift(chunk); + chunk = ""; x = 0; }; chunk += msg[i]; } - chat.history.unshift(' '.repeat(indent) + chunk); + chat.history.unshift(chunk); while (chat.history.length > terminal.rows - 2) { chat.history.pop(); }; @@ -154,6 +195,43 @@ let tui = { }, refresh: function() { terminal.refresh(); + }, + log_help: function() { + tui.log_msg(""); + tui.log_msg("HELP"); + tui.log_msg("chat mode commands:"); + tui.log_msg(""); + tui.log_msg("/login USER - register as USER"); + tui.log_msg("/msg USER TEXT - send TEXT to USER"); + tui.log_msg("/help - show this help"); + tui.log_msg("/play - switch to play mode"); + tui.log_msg(""); + tui.log_msg("play mode commands:"); + tui.log_msg("w, a, s, d - move avatar"); + tui.log_msg("f - flatten surroundings"); + tui.log_msg("e - write following ASCII character"); + tui.log_msg("c - switch to chat mode"); + tui.log_msg("? - switch to explore mode"); + tui.log_msg(""); + tui.log_msg("explore mode commands:"); + tui.log_msg("w, a, s, d - move question mark"); + tui.log_msg("c - switch to chat mode"); + tui.log_msg("p - switch to play mode"); + tui.log_msg(""); + }, + draw_info: function() { + terminal.drawBox(0, terminal.cols / 2, terminal.rows, terminal.cols / 2); + let lines = ['unfinished info screen']; + for (let y = 0, i = 0; y < terminal.rows && i < lines.length; y++, i++) { + terminal.write(y, terminal.cols / 2, lines[i]); + } + }, + full_refresh: function() { + this.draw_map(); + this.draw_turn_line(); + this.draw_history(); + this.draw_input_line(); + this.refresh(); } } @@ -161,36 +239,18 @@ let game = { things: {}, turn: 0, map: "", - map_size: [0,0] + map_size: [0,0], + player_id: 0 } let chat = { input_line: "", - history: [] + history: [], } terminal.initialize(); - -tui.draw_map(); -tui.draw_turn_line(); -tui.draw_history(); -tui.draw_input_line(); -tui.refresh(); - -tui.log_msg("basic commands:", 1); -tui.log_msg("LOGIN USER - register as USER", 3); -tui.log_msg("ALL TEXT - send TEXT to all users", 3); -tui.log_msg("QUERY USER TEXT - send TEXT to USER", 3); -tui.log_msg(""); -tui.log_msg("Use arrow keys to move your avatar. You can only move over \".\" map cells.", 1); -tui.log_msg(""); -tui.log_msg("Use double quotes for strings that contain whitespace, escape them with \\.", 1); -tui.log_msg(""); -tui.log_msg("To change the map cell you are standing on, type the desired ASCII character into the prompt and hit Return.", 1); -tui.log_msg(""); -tui.log_msg("more commands:", 1); -tui.log_msg("FLATTEN - transform surrounding map cells to \".\" ones", 3); -tui.log_msg(""); +tui.log_help(); +tui.full_refresh(); let websocket = new WebSocket(websocket_location); websocket.onmessage = function (event) { @@ -207,61 +267,142 @@ websocket.onmessage = function (event) { tui.draw_turn_line(); tui.draw_map(); tui.refresh(); - } else if (tokens[0] === 'LOG') { - tui.log_msg(tokens[1], 1); + } else if (tokens[0] === 'CHAT') { + tui.log_msg('# ' + tokens[1], 1); tui.refresh(); + } else if (tokens[0] === 'PLAYER_ID') { + game.player_id = parseInt(tokens[1]); } else if (tokens[0] === 'META') { - tui.log_msg(tokens[1]); + tui.log_msg('@ ' + tokens[1]); tui.refresh(); } else if (tokens[0] === 'UNHANDLED_INPUT') { - tui.log_msg('unknown command'); + tui.log_msg('? unknown command'); tui.refresh(); } else if (tokens[0] === 'ARGUMENT_ERROR') { - tui.log_msg('syntax error: ' + tokens[1]); + tui.log_msg('? syntax error: ' + tokens[1]); tui.refresh(); } else if (tokens[0] === 'GAME_ERROR') { - tui.log_msg('game error: ' + tokens[1]); + tui.log_msg('? game error: ' + tokens[1]); tui.refresh(); } else if (tokens[0] === 'PONG') { console.log('PONG'); } else { - tui.log_msg('unhandled input: ' + event.data); + tui.log_msg('? unhandled input: ' + event.data); tui.refresh(); } } +let explorer = { + position: [0,0], + move: function(direction) { + let try_pos = [0,0]; + try_pos[0] = this.position[0]; + try_pos[1] = this.position[1]; + if (direction == 'left') { + try_pos[1] -= 1; + } else if (direction == 'right') { + try_pos[1] += 1; + } else if (direction == 'up') { + try_pos[0] -= 1; + } else if (direction == 'down') { + try_pos[0] += 1; + }; + if (!(try_pos[0] < 0) && + !(try_pos[1] < 0) && + !(try_pos[0] >= game.map_size[0]) + && !(try_pos[1] >= game.map_size[1])) { + this.position = try_pos; + tui.draw_map(); + tui.draw_info(); + tui.refresh(); + } + } +} + document.addEventListener('keydown', (event) => { - if (chat.input_line === '') { - tui.draw_input_line(); - tui.refresh(); - } - if (event.key && event.key.length === 1) { - chat.input_line += event.key; - tui.draw_input_line(); - tui.refresh(); - } else if (event.key === 'Backspace') { - chat.input_line = chat.input_line.slice(0, -1); - tui.draw_input_line(); - tui.refresh(); - } else if (event.key === 'Enter') { - if (chat.input_line.length === 1) { - websocket.send("TASK:WRITE " + chat.input_line); - } else if (chat.input_line.trimEnd() === 'FLATTEN') { - websocket.send("TASK:FLATTEN_SURROUNDINGS"); - } else { - websocket.send(chat.input_line); + if (tui.mode == 'chat') { + if (event.key.length === 1) { + chat.input_line += event.key; + tui.draw_input_line(); + tui.refresh(); + } else if (event.key == 'Backspace') { + chat.input_line = chat.input_line.slice(0, -1); + tui.draw_input_line(); + tui.refresh(); + } else if (event.key == 'Enter') { + let tokens = parser.tokenize(chat.input_line); + if (tokens.length > 0 && tokens[0].length > 0) { + if (tokens[0][0] == '/') { + if (tokens[0] == '/play') { + tui.switch_mode('play'); + } else if (tokens[0] == '/?') { + tui.log_help(); + tui.refresh(); + } else if (tokens[0] == '/login') { + if (tokens.length > 1) { + websocket.send('LOGIN ' + quote(tokens[1])); + } else { + tui.log_msg('? need login name'); + } + } else if (tokens[0] == '/msg') { + if (tokens.length > 2) { + // FIXME only sends first word + websocket.send('QUERY ' + quote(tokens[1]) + ' ' + quote(tokens[2])); + } else { + tui.log_msg('? need message target and message'); + } + } else { + tui.log_msg('? unknown command'); + } + } else { + websocket.send('ALL ' + quote(chat.input_line)); + } + } + chat.input_line = ''; + tui.draw_input_line(); + tui.refresh(); + } + } else if (tui.mode == 'play') { + if (event.key === 'c') { + tui.switch_mode('chat'); + } else if (event.key === 'e') { + tui.switch_mode('edit'); + } else if (event.key === '?') { + tui.switch_mode('explore'); + } else if (event.key === 'F1') { + tui.log_help(); + tui.refresh(); + } else if (event.key === 'f') { + websocket.send("TASK:FLATTEN_SURROUNDINGS"); + } else if (event.key === 'a') { + websocket.send('TASK:MOVE LEFT'); + } else if (event.key === 'd') { + websocket.send('TASK:MOVE RIGHT'); + } else if (event.key === 'w') { + websocket.send('TASK:MOVE UP'); + } else if (event.key === 's') { + websocket.send('TASK:MOVE DOWN'); + }; + } else if (tui.mode == 'edit') { + if (event.key.length === 1) { + websocket.send("TASK:WRITE " + quote(event.key)); + } + tui.switch_mode('play'); + } else if (tui.mode == 'explore') { + if (event.key === 'c') { + tui.switch_mode('chat'); + } else if (event.key == 'p') { + tui.switch_mode('play'); + } else if (event.key === 'a') { + explorer.move('left'); + } else if (event.key === 'd') { + explorer.move('right'); + } else if (event.key === 'w') { + explorer.move('up'); + } else if (event.key === 's') { + explorer.move('down'); + }; } - chat.input_line = ''; - tui.draw_input_line(); - } else if (event.key === 'ArrowLeft') { - websocket.send('TASK:MOVE LEFT'); - } else if (event.key === 'ArrowRight') { - websocket.send('TASK:MOVE RIGHT'); - } else if (event.key === 'ArrowUp') { - websocket.send('TASK:MOVE UP'); - } else if (event.key === 'ArrowDown') { - websocket.send('TASK:MOVE DOWN'); - }; }, false); window.setInterval(function() { websocket.send('PING') }, 30000);