from plomrogue.errors import GameError, PlayError
from plomrogue.commands import (cmd_ALL, cmd_LOGIN, cmd_QUERY, cmd_PING,
cmd_TURN, cmd_MAP_LINE, cmd_MAP, cmd_GET_ANNOTATION,
- cmd_ANNOTATE, cmd_GET_GAMESTATE)
+ cmd_ANNOTATE, cmd_PORTAL, cmd_GET_GAMESTATE)
from plomrogue.io import GameIO
from plomrogue.misc import quote
from plomrogue.things import Thing, ThingPlayer
'TURN': cmd_TURN,
'MAP_LINE': cmd_MAP_LINE,
'GET_ANNOTATION': cmd_GET_ANNOTATION,
+ 'PORTAL': cmd_PORTAL,
'GET_GAMESTATE': cmd_GET_GAMESTATE,
'ANNOTATE': cmd_ANNOTATE,
'MAP': cmd_MAP,
self.sessions = {}
self.map = Map(self.map_geometry.size)
self.annotations = {}
+ self.portals = {}
if os.path.exists(self.io.save_file):
if not os.path.isfile(self.io.save_file):
raise GameError('save file path refers to non-file')
for t in self.things:
send_thing(t)
self.io.send('MAP %s %s' % (self.map_geometry.size, quote(self.map.terrain)))
+ for yx in self.portals:
+ self.io.send('PORTAL %s %s' % (yx, self.portals[yx]))
self.io.send('GAME_STATE_COMPLETE')
def run_tick(self):
write(f, 'MAP_LINE %5s %s' % (y, quote(line)))
for yx in self.annotations:
write(f, 'ANNOTATE %s %s' % (yx, quote(self.annotations[yx])))
+ for yx in self.portals:
+ write(f, 'PORTAL %s %s' % (yx, self.portals[yx]))
def new_world(self, size):
self.map_geometry = MapGeometrySquare(YX(size.y, size.x))
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.things = {};
+ game.portals = {};
game.turn = parseInt(tokens[1]);
} else if (tokens[0] === 'THING_POS') {
game.things[tokens[1]] = parser.parse_yx(tokens[2]);
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);
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]);
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 tui = {
mode: mode_waiting_for_server,
this.inputEl.value = explorer.info_db[explorer.position];
this.recalc_input_lines();
}
+ } else if (mode == mode_teleport) {
+ tui.log_msg("Type Y or y to affirm teleportation, any other key to abort.");
+ tui.log_msg("target: " + tui.teleport_target);
}
this.full_refresh();
},
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) {
}
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.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) {
} 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.switch_mode(mode_play);
+ }
}
}, false);
tui.inputEl.addEventListener('keydown', (event) => {
} 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');
}