let server = {
init: function(url) {
- this.websocket = new WebSocket(url);
+ this.url = url;
+ this.websocket = new WebSocket(this.url);
this.websocket.onopen = function(event) {
window.setInterval(function() { server.send(['PING']) }, 30000);
tui.log_msg("@ server connected! :)");
tui.init_login();
};
this.websocket.onclose = function(event) {
- tui.log_msg('@ server disconnected :(');
- }
+ tui.log_msg("@ server disconnected :(");
+ tui.log_msg("@ hint: try the ':reconnect' command");
+ };
+ this.websocket.onmessage = this.handle_event;
+ },
+ reconnect: function() {
+ this.reconnect_to(this.url);
+ },
+ reconnect_to: function(url) {
+ this.websocket.close();
+ this.init(url);
},
send: function(tokens) {
this.websocket.send(unparser.untokenize(tokens));
+ },
+ handle_event: function(event) {
+ let tokens = parser.tokenize(event.data)[0];
+ if (tokens[0] === 'TURN') {
+ game.things = {};
+ game.portals = {};
+ game.turn = parseInt(tokens[1]);
+ } else if (tokens[0] === 'THING_POS') {
+ game.things[tokens[1]] = parser.parse_yx(tokens[2]);
+ } else if (tokens[0] === 'MAP') {
+ game.map_size = parser.parse_yx(tokens[1]);
+ game.map = tokens[2]
+ } else if (tokens[0] === 'GAME_STATE_COMPLETE') {
+ explorer.empty_info_db();
+ if (tui.mode == mode_study) {
+ explorer.query_info();
+ }
+ let player_position = [0,0];
+ for (const thing_id in game.things) {
+ if (game.player_id == thing_id) {
+ let t = game.things[thing_id];
+ player_position = t;
+ }
+ }
+ if (player_position in game.portals) {
+ tui.teleport_target = game.portals[player_position];
+ tui.switch_mode(mode_teleport);
+ return;
+ }
+ tui.full_refresh();
+ } else if (tokens[0] === 'CHAT') {
+ tui.log_msg('# ' + tokens[1], 1);
+ } else if (tokens[0] === 'PLAYER_ID') {
+ game.player_id = parseInt(tokens[1]);
+ } else if (tokens[0] === 'LOGIN_OK') {
+ this.send(['GET_GAMESTATE']);
+ tui.log_help();
+ tui.switch_mode(mode_play);
+ } else if (tokens[0] === 'PORTAL') {
+ let position = parser.parse_yx(tokens[1]);
+ game.portals[position] = tokens[2];
+ } else if (tokens[0] === 'ANNOTATION') {
+ let position = parser.parse_yx(tokens[1]);
+ explorer.update_info_db(position, tokens[2]);
+ } else if (tokens[0] === 'UNHANDLED_INPUT') {
+ tui.log_msg('? unknown command');
+ } else if (tokens[0] === 'PLAY_ERROR') {
+ terminal.blink_screen();
+ } else if (tokens[0] === 'ARGUMENT_ERROR') {
+ tui.log_msg('? syntax error: ' + tokens[1]);
+ } else if (tokens[0] === 'GAME_ERROR') {
+ tui.log_msg('? game error: ' + tokens[1]);
+ } else if (tokens[0] === 'PONG') {
+ console.log('PONG');
+ } else {
+ tui.log_msg('? unhandled input: ' + event.data);
+ }
}
}
}
class Mode {
- constructor(name, has_input_prompt=false, shows_annotations=false, is_intro=false) {
+ constructor(name, has_input_prompt=false, shows_info=false, is_intro=false) {
this.name = name;
this.has_input_prompt = has_input_prompt;
- this.shows_annotations = shows_annotations;
+ this.shows_info= shows_info;
this.is_intro = is_intro;
}
}
let mode_play = new Mode('play / move around', false, false);
let mode_study = new Mode('check map tiles for messages', false, true);
let mode_edit = new Mode('write ASCII char to map tile', false, false);
+let mode_teleport = new Mode('teleport away?');
+let mode_portal = new Mode('add portal to map tile', true, true);
let tui = {
mode: mode_waiting_for_server,
height_turn_line: 1,
height_mode_line: 1,
height_input: 1,
- key_up: 'w',
- key_down: 's',
- key_left: 'a',
- key_right: 'd',
- movement_keys_desc: 'w, a, s, d',
init: function() {
this.inputEl = document.getElementById("input");
this.inputEl.focus();
this.recalc_input_lines();
this.height_header = this.height_turn_line + this.height_mode_line;
this.log_msg("@ waiting for server connection ...");
+ this.init_wasd();
+ },
+ init_wasd: function() {
+ if (wasd_selector.value == 'w, a, s, d') {
+ tui.key_up = 'w';
+ tui.key_down = 's';
+ tui.key_left = 'a';
+ tui.key_right = 'd';
+ } else if (wasd_selector.value == 'arrow keys') {
+ tui.key_up = 'ArrowUp';
+ tui.key_down = 'ArrowDown';
+ tui.key_left = 'ArrowLeft';
+ tui.key_right = 'ArrowRight';
+ };
+ tui.movement_keys_desc = wasd_selector.value;
},
init_login: function() {
this.log_msg("@ please enter your username:");
if (mode == mode_annotate && explorer.position in explorer.info_db) {
let info = explorer.info_db[explorer.position];
if (info != "(none)") {
- this.inputEl.value = explorer.info_db[explorer.position];
+ this.inputEl.value = info;
this.recalc_input_lines();
}
}
+ if (mode == mode_portal && explorer.position in game.portals) {
+ let portal = game.portals[explorer.position]
+ this.inputEl.value = portal;
+ this.recalc_input_lines();
+ } else if (mode == mode_teleport) {
+ tui.log_msg("@ May teleport to: " + tui.teleport_target);
+ tui.log_msg("@ Type Y or y to affirm, other keys to abort.");
+ }
this.full_refresh();
},
empty_input: function(str) {
let chunk = "";
let lines = [];
for (let i = 0, x = 0; i < msg.length; i++, x++) {
- if (x >= width) {
+ if (x >= width || msg[i] == "\n") {
lines.push(chunk);
chunk = "";
x = 0;
};
- chunk += msg[i];
+ if (msg[i] != "\n") {
+ chunk += msg[i];
+ }
}
lines.push(chunk);
return lines;
line.push(game.map[i]);
};
map_lines.push(line);
- let player_position = [0,0];
let center_pos = [Math.floor(game.map_size[0] / 2),
Math.floor(game.map_size[1] / 2)];
for (const thing_id in game.things) {
center_pos = t;
}
};
- if (tui.mode.shows_annotations) {
+ if (tui.mode.shows_info) {
map_lines[explorer.position[0]][explorer.position[1]] = '?';
center_pos = explorer.position;
}
this.draw_map();
this.draw_turn_line();
this.draw_mode_line();
- if (this.mode.shows_annotations) {
+ if (this.mode.shows_info) {
this.draw_info();
} else {
this.draw_history();
}
let game = {
- things: {},
- turn: 0,
- map: "",
- map_size: [0,0],
- player_id: -1
+ init: function() {
+ this.things = {};
+ this.turn = -1;
+ this.map = "";
+ this.map_size = [0,0];
+ this.player_id = -1;
+ this.portals = {};
+ },
}
+game.init();
tui.init();
tui.full_refresh();
-
server.init(websocket_location);
-server.websocket.onmessage = function (event) {
- let tokens = parser.tokenize(event.data)[0];
- if (tokens[0] === 'TURN') {
- game.things = {}
- game.turn = parseInt(tokens[1]);
- } else if (tokens[0] === 'THING_POS') {
- game.things[tokens[1]] = parser.parse_yx(tokens[2]);
- } else if (tokens[0] === 'MAP') {
- game.map_size = parser.parse_yx(tokens[1]);
- game.map = tokens[2]
- } else if (tokens[0] === 'GAME_STATE_COMPLETE') {
- explorer.empty_info_db();
- if (tui.mode == mode_study) {
- explorer.query_info();
- }
- tui.full_refresh();
- } else if (tokens[0] === 'CHAT') {
- tui.log_msg('# ' + tokens[1], 1);
- } else if (tokens[0] === 'PLAYER_ID') {
- game.player_id = parseInt(tokens[1]);
- } else if (tokens[0] === 'LOGIN_OK') {
- server.send(['GET_GAMESTATE']);
- tui.log_help();
- tui.switch_mode(mode_play);
- } else if (tokens[0] === 'ANNOTATION') {
- let position = parser.parse_yx(tokens[1]);
- explorer.update_info_db(position, tokens[2]);
- } else if (tokens[0] === 'UNHANDLED_INPUT') {
- tui.log_msg('? unknown command');
- } else if (tokens[0] === 'PLAY_ERROR') {
- terminal.blink_screen();
- } else if (tokens[0] === 'ARGUMENT_ERROR') {
- tui.log_msg('? syntax error: ' + tokens[1]);
- } else if (tokens[0] === 'GAME_ERROR') {
- tui.log_msg('? game error: ' + tokens[1]);
- } else if (tokens[0] === 'PONG') {
- console.log('PONG');
- } else {
- tui.log_msg('? unhandled input: ' + event.data);
- }
-}
let explorer = {
position: [0,0],
server.send(["GET_ANNOTATION", unparser.to_yx(explorer.position)]);
},
get_info: function() {
+ let info = "";
+ if (this.position in game.portals) {
+ info += "PORTAL: " + game.portals[this.position] + "\n";
+ }
if (this.position in this.info_db) {
- return this.info_db[this.position];
+ info += "ANNOTATIONS: " + this.info_db[this.position];
} else {
- return 'waiting …';
+ info += 'waiting …';
}
+ return info;
},
annotate: function(msg) {
if (msg.length == 0) {
msg = " "; // triggers annotation deletion
}
server.send(["ANNOTATE", unparser.to_yx(explorer.position), msg]);
+ },
+ set_portal: function(msg) {
+ if (msg.length == 0) {
+ msg = " "; // triggers portal deletion
+ }
+ server.send(["PORTAL", unparser.to_yx(explorer.position), msg]);
}
}
} else if (tui.mode == mode_edit && tui.inputEl.value.length > 0) {
server.send(["TASK:WRITE", tui.inputEl.value[0]]);
tui.switch_mode(mode_play);
+ } else if (tui.mode == mode_teleport) {
+ if (['Y', 'y'].includes(tui.inputEl.value[0])) {
+ server.reconnect_to(tui.teleport_target);
+ } else {
+ tui.log_msg("@ teleportation aborted");
+ tui.switch_mode(mode_play);
+ }
}
}, false);
tui.inputEl.addEventListener('keydown', (event) => {
if (tui.mode == mode_login && event.key == 'Enter') {
server.send(['LOGIN', tui.inputEl.value]);
tui.switch_mode(mode_login);
+ } else if (tui.mode == mode_portal && event.key == 'Enter') {
+ explorer.set_portal(tui.inputEl.value);
+ tui.switch_mode(mode_study, true);
} else if (tui.mode == mode_annotate && event.key == 'Enter') {
explorer.annotate(tui.inputEl.value);
tui.switch_mode(mode_study, true);
} else {
tui.log_msg('? need message target and message');
}
+ } else if (tokens[0] == ':reconnect') {
+ if (tokens.length > 1) {
+ server.reconnect_to(tokens[1]);
+ } else {
+ server.reconnect();
+ }
} else {
tui.log_msg('? unknown command');
}
tui.switch_mode(mode_chat);
} else if (event.key == 'p') {
tui.switch_mode(mode_play);
+ } else if (event.key === 'P') {
+ event.preventDefault();
+ tui.switch_mode(mode_portal);
} else if (event.key === tui.key_left) {
explorer.move('left');
} else if (event.key === tui.key_right) {
}, false);
wasd_selector.addEventListener('input', function() {
- if (wasd_selector.value == 'w, a, s, d') {
- tui.key_up = 'w';
- tui.key_down = 's';
- tui.key_left = 'a';
- tui.key_right = 'd';
- } else if (wasd_selector.value == 'arrow keys') {
- tui.key_up = 'ArrowUp';
- tui.key_down = 'ArrowDown';
- tui.key_left = 'ArrowLeft';
- tui.key_right = 'ArrowRight';
- };
- tui.movement_keys_desc = wasd_selector.value;
+ tui.init_wasd();
}, false);
rows_selector.addEventListener('input', function() {
+ if (rows_selector.value % 2 != 0) {
+ return;
+ }
terminal.initialize();
tui.full_refresh();
}, false);
cols_selector.addEventListener('input', function() {
+ if (cols_selector.value % 4 != 0) {
+ return;
+ }
terminal.initialize();
tui.window_width = terminal.cols / 2,
tui.full_refresh();