2019-03-21 12:13:46 +01:00
|
|
|
class OnlineMatchManager
|
|
|
|
{
|
2019-04-04 14:58:29 +02:00
|
|
|
constructor(grid, info_func, matches_container, control_container, end_button, game_server_connection, match_id, match_state, revoke_time, player_name, ranked)
|
2019-03-21 12:13:46 +01:00
|
|
|
{
|
|
|
|
this.grid = grid;
|
|
|
|
|
|
|
|
this.match_id = match_id;
|
|
|
|
|
2019-03-29 12:47:49 +01:00
|
|
|
this.info_func = info_func;
|
|
|
|
|
2019-03-21 12:13:46 +01:00
|
|
|
this.game_server_connection = game_server_connection;
|
|
|
|
|
2019-04-04 14:58:29 +02:00
|
|
|
this.ranked = ranked;
|
|
|
|
|
2019-03-21 12:13:46 +01:00
|
|
|
|
|
|
|
this.match_state = match_state;
|
2019-04-01 16:17:20 +02:00
|
|
|
this.revoke_time = Date.create_from_mysql(revoke_time);
|
|
|
|
this.player_name = player_name;
|
2019-03-21 12:13:46 +01:00
|
|
|
|
|
|
|
var player_a = this.match_state.player_a;
|
|
|
|
var player_b = this.match_state.player_b;
|
|
|
|
|
|
|
|
this.online_opponent = new Player(player_a == this.player_name ? player_b : player_a, 255,0,0);
|
|
|
|
this.local_player = new Player(this.player_name, 0,255,0);
|
|
|
|
|
|
|
|
// create match button in match list:
|
|
|
|
this.control_container = control_container;
|
2019-03-29 12:47:49 +01:00
|
|
|
this.end_button = end_button;
|
2019-03-24 16:43:29 +01:00
|
|
|
this.matches_container = matches_container;
|
|
|
|
|
|
|
|
var tmp = matches_container.create_double_button("" + this.online_opponent.get_name(), "+")
|
|
|
|
|
|
|
|
this.match_button = tmp[1];
|
|
|
|
this.match_button_div = tmp[0];
|
|
|
|
this.match_button_option = tmp[2];
|
|
|
|
|
2019-04-04 16:39:23 +02:00
|
|
|
// Note: unranked matches means that not both users have a full account, so they cannot be friends
|
|
|
|
|
|
|
|
if (!this.ranked || this.game_server_connection.is_friend(this.online_opponent.get_name()))
|
2019-03-24 16:43:29 +01:00
|
|
|
{
|
|
|
|
this.match_button_option.disabled = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.match_button_option.addEventListener("click", () => {
|
|
|
|
this.game_server_connection.send_friend_request(this.online_opponent.get_name());
|
|
|
|
this.match_button_option.disabled = true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-03-21 12:13:46 +01:00
|
|
|
this.match_button.addEventListener("click", () => this.open_match());
|
|
|
|
|
2019-03-22 22:05:30 +01:00
|
|
|
if (this.online_opponent.get_name() == this.match_state.active_player)
|
|
|
|
{
|
|
|
|
this.match_button.className = "infobar-button-red";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.match_button.className = "infobar-button-green"
|
|
|
|
}
|
2019-03-21 12:13:46 +01:00
|
|
|
|
|
|
|
this.is_closed = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
click_listener(sub_x, sub_y, x,y)
|
|
|
|
{
|
|
|
|
this.grid.block_all();
|
|
|
|
|
|
|
|
this.game_server_connection.send_move(sub_x, sub_y, x, y, this.match_id);
|
|
|
|
|
2019-03-29 20:41:15 +01:00
|
|
|
this.info_func("waiting for " + encodeHTML(this.online_opponent.get_name()) + "'s move", false);
|
2019-03-21 12:13:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
on_user_close()
|
|
|
|
{
|
|
|
|
|
|
|
|
// send end match message:
|
|
|
|
if (!this.match_state.game_over)
|
|
|
|
{
|
|
|
|
this.game_server_connection.send_end_match(this.match_id);
|
|
|
|
}
|
|
|
|
|
2019-03-24 16:43:29 +01:00
|
|
|
if (this.match_button_div != null)
|
|
|
|
{
|
|
|
|
clearInner(this.match_button_div)
|
|
|
|
this.matches_container.container.removeChild(this.match_button_div);
|
|
|
|
this.match_button_div = null;
|
|
|
|
}
|
2019-03-29 12:47:49 +01:00
|
|
|
this.info_func("match is closed");
|
2019-03-21 12:13:46 +01:00
|
|
|
this.control_container.hide();
|
|
|
|
this.is_closed = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
remove_match()
|
|
|
|
{
|
2019-03-24 16:43:29 +01:00
|
|
|
if (this.match_button_div != null)
|
2019-03-21 12:13:46 +01:00
|
|
|
{
|
2019-03-24 19:10:46 +01:00
|
|
|
clearInner(this.match_button_div);
|
2019-03-24 16:43:29 +01:00
|
|
|
this.matches_container.container.removeChild(this.match_button_div);
|
|
|
|
this.match_button_div = null;
|
2019-03-21 12:13:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-01 16:17:20 +02:00
|
|
|
update_match_state(match_state, revoke_time)
|
2019-03-21 12:13:46 +01:00
|
|
|
{
|
|
|
|
this.match_state = match_state;
|
2019-04-01 16:17:20 +02:00
|
|
|
this.revoke_time = Date.create_from_mysql(revoke_time);
|
2019-03-22 22:05:30 +01:00
|
|
|
|
|
|
|
if (this.online_opponent.get_name() == this.match_state.active_player)
|
|
|
|
{
|
|
|
|
this.match_button.className = "infobar-button-red";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.match_button.className = "infobar-button-green"
|
|
|
|
}
|
2019-03-21 12:13:46 +01:00
|
|
|
|
2019-03-21 14:15:00 +01:00
|
|
|
if (this.match_state.active_player == this.local_player.get_name())
|
2019-03-21 12:13:46 +01:00
|
|
|
{
|
2019-03-29 20:41:15 +01:00
|
|
|
this.game_server_connection.notify("your turn against " + encodeHTML(this.online_opponent.get_name()));
|
2019-03-21 12:13:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-22 22:05:30 +01:00
|
|
|
on_focus_loose()
|
|
|
|
{
|
|
|
|
if (this.online_opponent.get_name() == this.match_state.active_player)
|
|
|
|
{
|
|
|
|
this.match_button.className = "infobar-button-red";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.match_button.className = "infobar-button-green"
|
|
|
|
}
|
2019-03-29 12:47:49 +01:00
|
|
|
|
|
|
|
this.control_container.clear_background_color();
|
|
|
|
this.control_container.update_head("");
|
|
|
|
}
|
|
|
|
|
|
|
|
update_button_text()
|
|
|
|
{
|
|
|
|
|
|
|
|
if (this.match_state.game_over)
|
|
|
|
{
|
|
|
|
this.end_button.innerHTML = "Close Match";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var contains_move_of_a = false;
|
|
|
|
var contains_move_of_b = false;
|
|
|
|
var i;
|
|
|
|
for (i = 0; i < this.match_state.complete_field.length; i++)
|
|
|
|
{
|
|
|
|
if (this.match_state.complete_field[i].includes(1))
|
|
|
|
{
|
|
|
|
contains_move_of_a = true;
|
|
|
|
}
|
|
|
|
if (this.match_state.complete_field[i].includes(2))
|
|
|
|
{
|
|
|
|
contains_move_of_b = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (contains_move_of_a && contains_move_of_b)
|
|
|
|
{
|
|
|
|
this.end_button.innerHTML = "Abandon Match";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.match_state.player_a == this.player_name && !contains_move_of_a)
|
|
|
|
{
|
|
|
|
this.end_button.innerHTML = "Reject Invite";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.match_state.player_b == this.player_name && !contains_move_of_b)
|
|
|
|
{
|
|
|
|
this.end_button.innerHTML = "Reject Invite";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.end_button.innerHTML = "Close Match";
|
|
|
|
|
2019-03-22 22:05:30 +01:00
|
|
|
}
|
|
|
|
|
2019-03-21 12:13:46 +01:00
|
|
|
open_match()
|
|
|
|
{
|
|
|
|
this.grid.register_click_callback(null);
|
|
|
|
|
|
|
|
this.grid.deactivate_all();
|
|
|
|
this.grid.unblock_all();
|
|
|
|
|
2019-03-22 22:05:30 +01:00
|
|
|
this.match_button.className = "infobar-button-active";
|
2019-03-21 12:13:46 +01:00
|
|
|
|
|
|
|
this.game_server_connection.set_active_match(this.match_id);
|
|
|
|
|
|
|
|
this.control_container.show();
|
|
|
|
|
|
|
|
var complete_field = this.match_state.complete_field;
|
|
|
|
var global_field = this.match_state.global_field;
|
|
|
|
|
|
|
|
var sub_x = null;
|
|
|
|
var sub_y = null;
|
|
|
|
var x = null;
|
|
|
|
var y = null;
|
|
|
|
|
|
|
|
if (this.match_state.last_move != null)
|
|
|
|
{
|
|
|
|
sub_x = this.match_state.last_move.sub_x;
|
|
|
|
sub_y = this.match_state.last_move.sub_y;
|
|
|
|
x = this.match_state.last_move.x;
|
|
|
|
y = this.match_state.last_move.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
var game_over = this.match_state.game_over;
|
|
|
|
var player_won = this.match_state.player_won;
|
|
|
|
var current_player_name = this.match_state.active_player;
|
|
|
|
|
|
|
|
var player_a = this.match_state.player_a;
|
|
|
|
var player_b = this.match_state.player_b;
|
|
|
|
|
|
|
|
var FIELD_EMPTY = 0
|
|
|
|
var FIELD_USER = player_a == this.player_name ? 1 : 2;
|
|
|
|
var FIELD_OPPONENT = player_a == this.player_name ? 2 : 1;
|
|
|
|
var FIELD_DRAW = 3
|
|
|
|
|
|
|
|
this.online_opponent = new Player(player_a == this.player_name ? player_b : player_a, 255,0,0);
|
|
|
|
this.local_player = new Player(this.player_name, 0,255,0);
|
|
|
|
|
|
|
|
var i,j;
|
|
|
|
for(j = 0; j < 9; j++)
|
|
|
|
{
|
|
|
|
for(i = 0; i < 9; i++)
|
|
|
|
{
|
|
|
|
var si = Math.floor(i / 3);
|
|
|
|
var sj = Math.floor(j / 3);
|
|
|
|
if (complete_field[j][i] == FIELD_USER)
|
|
|
|
{
|
|
|
|
this.grid.subgrids[sj][si].player_change_listener(this.local_player);
|
|
|
|
this.grid.subgrids[sj][si].cells[j % 3][i % 3].on_click();
|
|
|
|
}
|
|
|
|
if (complete_field[j][i] == FIELD_OPPONENT)
|
|
|
|
{
|
|
|
|
this.grid.subgrids[sj][si].player_change_listener(this.online_opponent);
|
|
|
|
this.grid.subgrids[sj][si].cells[j % 3][i % 3].on_click();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-04 15:01:42 +02:00
|
|
|
var control_head = this.ranked ? "Ranked Match<br>" : "Unranked Match<br>";
|
2019-03-29 12:47:49 +01:00
|
|
|
this.control_container.clear_background_color();
|
|
|
|
|
|
|
|
this.update_button_text();
|
|
|
|
|
2019-03-21 12:13:46 +01:00
|
|
|
this.grid.block_all();
|
|
|
|
this.grid.register_click_callback((i,j,k,l) => this.click_listener(i,j,k,l));
|
|
|
|
|
|
|
|
if (game_over && player_won != null)
|
|
|
|
{
|
|
|
|
if (player_won == this.player_name)
|
|
|
|
{
|
2019-03-29 12:47:49 +01:00
|
|
|
this.info_func("Congratulation, you won!");
|
|
|
|
control_head += "You won!"
|
|
|
|
this.control_container.set_background_color(this.local_player.get_color_with_alpha(0.4));
|
|
|
|
|
2019-03-21 12:13:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-03-31 16:38:34 +02:00
|
|
|
this.info_func("Game Over, you lost!");
|
2019-03-29 12:47:49 +01:00
|
|
|
control_head += "You lost";
|
|
|
|
this.control_container.set_background_color(this.online_opponent.get_color_with_alpha(0.4));
|
2019-03-21 12:13:46 +01:00
|
|
|
}
|
2019-03-29 12:47:49 +01:00
|
|
|
this.control_container.update_head(control_head);
|
2019-03-21 12:13:46 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(game_over)
|
|
|
|
{
|
2019-03-22 22:05:30 +01:00
|
|
|
if (this.grid.is_complete())
|
|
|
|
{
|
2019-03-29 12:47:49 +01:00
|
|
|
this.info_func("Draw. Everyone looses!");
|
|
|
|
control_head += "Draw";
|
|
|
|
this.control_container.set_background_color(theme_color_highlight);
|
2019-03-22 22:05:30 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-03-29 12:47:49 +01:00
|
|
|
this.info_func("Game was closed by server or opponent");
|
|
|
|
control_head += "Game Closed"
|
|
|
|
this.control_container.set_background_color(theme_color_highlight);
|
2019-03-22 22:05:30 +01:00
|
|
|
}
|
2019-03-29 12:47:49 +01:00
|
|
|
this.control_container.update_head(control_head);
|
2019-03-21 12:13:46 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var current_player = this.player_name == current_player_name ? this.local_player : this.online_opponent;
|
|
|
|
this.grid.player_change_listener(current_player);
|
|
|
|
|
2019-04-01 16:17:20 +02:00
|
|
|
|
|
|
|
// date difference in hours:
|
|
|
|
var dt = Math.floor(Math.abs(Date.now() - this.revoke_time) / 36e5);
|
|
|
|
|
2019-03-21 12:13:46 +01:00
|
|
|
|
|
|
|
if (this.player_name == current_player_name)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (this.match_state.last_move != null)
|
|
|
|
{
|
|
|
|
if (this.grid.subgrids[y][x].is_won() || this.grid.subgrids[y][x].is_draw())
|
|
|
|
{
|
|
|
|
this.grid.unblock_all_non_completed();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.grid.unblock(x,y);
|
|
|
|
}
|
2019-04-01 16:17:20 +02:00
|
|
|
this.info_func("It's your turn! (" + dt + "h left)", false);
|
2019-03-29 12:47:49 +01:00
|
|
|
this.control_container.blink(theme_color_highlight);
|
2019-03-21 12:13:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-04-01 16:17:20 +02:00
|
|
|
this.info_func("It's your turn! (" + dt + "h left)", false);
|
2019-03-29 12:47:49 +01:00
|
|
|
this.control_container.blink(theme_color_highlight);
|
2019-03-21 12:13:46 +01:00
|
|
|
this.grid.unblock_all();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-04-01 16:17:20 +02:00
|
|
|
this.info_func("waiting for " + encodeHTML(this.online_opponent.get_name()) + "'s move (" + dt + "h left)", false);
|
2019-03-29 12:47:49 +01:00
|
|
|
this.control_container.blink(theme_color_highlight);
|
2019-03-21 12:13:46 +01:00
|
|
|
}
|
|
|
|
|
2019-04-04 14:58:29 +02:00
|
|
|
control_head += "" + encodeHTML(current_player_name) + "'s move";
|
2019-03-29 12:47:49 +01:00
|
|
|
|
2019-04-04 14:58:29 +02:00
|
|
|
this.control_container.update_head(control_head);
|
2019-03-29 12:47:49 +01:00
|
|
|
|
2019-03-21 12:13:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
}
|
2019-03-31 16:38:34 +02:00
|
|
|
}
|