Add latest play images.

This commit is contained in:
yukirij 2024-10-13 20:27:07 -07:00
parent b272bf1b64
commit 22153a1dd0
8 changed files with 130 additions and 26 deletions

View File

@ -5,6 +5,7 @@ pub struct Play {
pub source:u8, pub source:u8,
pub from:u8, pub from:u8,
pub to:u8, pub to:u8,
pub meta:u8,
} }
impl Play { impl Play {
pub fn new() -> Self pub fn new() -> Self
@ -13,6 +14,7 @@ impl Play {
source:0, source:0,
from:0, from:0,
to:0, to:0,
meta:0,
} }
} }
@ -22,6 +24,7 @@ impl Play {
source:0, source:0,
from, from,
to, to,
meta:0,
} }
} }
@ -31,6 +34,7 @@ impl Play {
source:2, source:2,
from, from,
to, to,
meta:0,
} }
} }
@ -40,6 +44,7 @@ impl Play {
source:1, source:1,
from:piece, from:piece,
to:tile, to:tile,
meta:0,
} }
} }
} }

View File

@ -200,6 +200,8 @@ impl Game {
let player = (self.turn & 1) as u8; let player = (self.turn & 1) as u8;
if self.play_is_valid(play) { if self.play_is_valid(play) {
let mut meta = 0;
// Move piece on board. // Move piece on board.
match play.source { match play.source {
0 | 2 => { 0 | 2 => {
@ -207,6 +209,8 @@ impl Game {
if let Some(mut piece) = self.board.pieces[piece_id as usize] { if let Some(mut piece) = self.board.pieces[piece_id as usize] {
let mut swap = false; let mut swap = false;
meta = piece.class | ((piece.promoted as u8) << 3) | (piece.player << 4);
if let Some(tid) = self.board.tiles[play.to as usize].piece { if let Some(tid) = self.board.tiles[play.to as usize].piece {
if let Some(target) = &mut self.board.pieces[tid as usize] { if let Some(target) = &mut self.board.pieces[tid as usize] {
@ -258,6 +262,8 @@ impl Game {
// Place piece from pool. // Place piece from pool.
1 => { 1 => {
meta = play.from | (player << 4);
self.pool[player as usize][play.from as usize] -= 1; self.pool[player as usize][play.from as usize] -= 1;
let piece = Piece::new(play.from, player); let piece = Piece::new(play.from, player);
self.board.set_piece(piece, play.to); self.board.set_piece(piece, play.to);
@ -273,7 +279,12 @@ impl Game {
_ => { } _ => { }
} }
self.history.push(*play); self.history.push(Play {
source: play.source,
from: play.from,
to: play.to,
meta,
});
self.update_board(); self.update_board();
Ok(()) Ok(())
@ -511,7 +522,7 @@ impl Game {
plays.push(PlayInfo { plays.push(PlayInfo {
valid, valid,
threat, threat,
play:Play { source:0, from:piece.tile, to:current_hex.tile, }, play:Play { source:0, from:piece.tile, to:current_hex.tile, meta:0 },
check:checkstate.immediate(), check:checkstate.immediate(),
blocking:blocking, blocking:blocking,
}); });

View File

@ -458,6 +458,20 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
user.handle.clone() user.handle.clone()
} else { String::new() }; } else { String::new() };
let mut last_move = 0;
let mut index = session.game.history.len();
let mut move_count = 0;
while move_count < 4 && index > 0 {
let play = session.game.history[index - 1];
if play.source <= 2 {
last_move <<= 8;
last_move |= 0x80 | play.meta as u32;
move_count += 1;
}
index -= 1;
}
response.records.push(PacketSessionListResponseRecord { response.records.push(PacketSessionListResponseRecord {
token:session.token, token:session.token,
handles:[ handles:[
@ -465,7 +479,7 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
dusk_handle, dusk_handle,
], ],
turn:session.game.turn, turn:session.game.turn,
last_move:[0; 3], last_move,
viewers:session.connections.len() as u32, viewers:session.connections.len() as u32,
player, player,
is_turn, is_turn,
@ -551,6 +565,7 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
source: 0xF, source: 0xF,
from: 0, from: 0,
to: 0, to: 0,
meta: 0,
}; };
if let Some(session) = app.sessions.get_mut(&request.token) { if let Some(session) = app.sessions.get_mut(&request.token) {
@ -652,6 +667,7 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
_ => 0, _ => 0,
}, },
from, to, from, to,
meta: 0,
}; };
let text = format!("PLAY {} {} {}", play.source, play.from, play.to); let text = format!("PLAY {} {} {}", play.source, play.from, play.to);
@ -685,6 +701,7 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
_ => 0, _ => 0,
}, },
from, to, from, to,
meta: 0,
}; };
if session.game.process(&play).is_ok() { if session.game.process(&play).is_ok() {

View File

@ -57,7 +57,7 @@ pub struct PacketSessionListResponseRecord {
pub token:SessionToken, pub token:SessionToken,
pub handles:[String; 2], pub handles:[String; 2],
pub turn:u16, pub turn:u16,
pub last_move:[u8; 3], pub last_move:u32,
pub viewers:u32, pub viewers:u32,
pub player:u8, pub player:u8,
pub is_turn:bool, pub is_turn:bool,
@ -108,7 +108,7 @@ impl Packet for PacketSessionListResponse {
chunk.append(&mut pack_u16(record.turn)); chunk.append(&mut pack_u16(record.turn));
// Last move // Last move
chunk.append(&mut record.last_move.to_vec()); chunk.append(&mut pack_u32(record.last_move));
// Spectator count // Spectator count
chunk.append(&mut pack_u32(record.viewers)); chunk.append(&mut pack_u32(record.viewers));

View File

@ -299,6 +299,7 @@ impl FileSystem {
source:(data & 0xF) as u8, source:(data & 0xF) as u8,
from:((data >> 4) & 0x3F) as u8, from:((data >> 4) & 0x3F) as u8,
to:((data >> 10) & 0x3F) as u8, to:((data >> 10) & 0x3F) as u8,
meta:0,
}; };
result.push(play); result.push(play);

View File

@ -74,6 +74,14 @@ main>table.list td:last-child>button:hover{
background-color:#303030; background-color:#303030;
} }
main>table.list td>canvas {
display: block;
position: relative;
width: 8em;
height: 2em;
margin: 0 -1rem 0 -1rem;
}
main>article{ main>article{
display:block; display:block;
position:relative; position:relative;

View File

@ -188,7 +188,7 @@ function MESSAGE(event) {
dawn: "", dawn: "",
dusk: "", dusk: "",
turn: 0, turn: 0,
move: "", moves: [ ],
viewers: 0, viewers: 0,
player: false, player: false,
is_turn: false, is_turn: false,
@ -227,14 +227,15 @@ function MESSAGE(event) {
index = result.index; index = result.index;
record.turn = result.data; record.turn = result.data;
// Last move // Last moves
if(index <= bytes.length + 3) { result = UNPACK.u32(bytes, index);
let move = new Uint8Array(3); index = result.index;
for(let i = 0; i < 3; ++i) { let moves = result.data;
move[i] = bytes[index]; for(let m = 0; m < 4; ++m) {
index += 1; if((moves & 0x80) != 0) {
record.moves.push(moves & 0xFF);
moves >>= 8;
} }
record.move = UNPACK.move(move);
} }
// Reviewer count // Reviewer count

View File

@ -1,4 +1,11 @@
const UI = { const UI = {
Row:class{
constructor(element, css_class) {
this.element = element;
this.css_class = css_class;
}
},
text(value) { text(value) {
return document.createTextNode(value); return document.createTextNode(value);
}, },
@ -185,6 +192,8 @@ const UI = {
let rows = [ ]; let rows = [ ];
for(let r = 0; r < records.length; ++r) { for(let r = 0; r < records.length; ++r) {
let record = records[r];
let buttons = [ ]; let buttons = [ ];
let join_callback = function() { let join_callback = function() {
LOAD(SCENES.GameLoad, { LOAD(SCENES.GameLoad, {
@ -193,7 +202,7 @@ const UI = {
}); });
}; };
join_callback = join_callback.bind({ join_callback = join_callback.bind({
token: records[r].token, token: record.token,
}); });
let spectate_callback = function() { let spectate_callback = function() {
@ -203,12 +212,12 @@ const UI = {
}); });
}; };
spectate_callback = spectate_callback.bind({ spectate_callback = spectate_callback.bind({
token: records[r].token, token: record.token,
}); });
if(records[r].player != 0) { if(record.player != 0) {
let button_resume = UI.button(LANG("resume"), join_callback); let button_resume = UI.button(LANG("resume"), join_callback);
if(records[r].is_turn) { if(record.is_turn) {
button_resume.setAttribute("class", "highlight"); button_resume.setAttribute("class", "highlight");
} }
@ -218,20 +227,45 @@ const UI = {
buttons.push(UI.button(LANG("view"), spectate_callback)); buttons.push(UI.button(LANG("view"), spectate_callback));
} }
let dawn = UI.text(records[r].dawn); let dawn = UI.text(record.dawn);
let dusk = UI.text(records[r].dusk); let dusk = UI.text(record.dusk);
let moves = document.createElement("canvas");
setTimeout((canvas, moves) => {
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
let ctx = canvas.getContext("2d");
let size = canvas.height / 2;
for(let i = 0; i < moves.length; ++i) {
let piece = moves[i] & 0x7;
let promoted = (moves[i] & 0x8) >> 3;
let player = (moves[i] & 0x10) >> 4;
let color = null;
if(player == 0) { color = INTERFACE.Color.Dawn; } else { color = INTERFACE.Color.Dusk; }
let piece_name = GAME.Const.Piece[piece].name;
if(promoted) {
GAME_ASSET.Image.Promote.draw(ctx, 1.5 * size, [size * (1 + (2 * i)), size], INTERFACE.Color.Promote);
}
GAME_ASSET.Image[piece_name].draw(ctx, 1.5 * size, [size * (1 + (2 * i)), size], color);
}
}, 10, moves, record.moves);
rows.push([ rows.push([
dawn, dawn,
dusk, dusk,
UI.text(records[r].turn), UI.text(records[r].turn),
moves,
UI.text(records[r].viewers), UI.text(records[r].viewers),
buttons, buttons,
]); ]);
} }
let tbody = UI.table_content( let tbody = UI.table_content(
[ LANG("dawn"), LANG("dusk"), LANG("turns"), LANG("viewers"), "" ], [ LANG("dawn"), LANG("dusk"), LANG("turns"), "", LANG("viewers"), "" ],
rows, rows,
); );
@ -329,6 +363,8 @@ const UI = {
let rows = [ ]; let rows = [ ];
for(let r = 0; r < records.length; ++r) { for(let r = 0; r < records.length; ++r) {
let record = records[r];
let buttons = [ ]; let buttons = [ ];
let view_callback = function() { let view_callback = function() {
SCENE_FORWARD = SCENE; SCENE_FORWARD = SCENE;
@ -338,28 +374,53 @@ const UI = {
}); });
MESSAGE_SESSION_VIEW(this.token, false); MESSAGE_SESSION_VIEW(this.token, false);
}; };
view_callback = view_callback.bind({token: records[r].token}); view_callback = view_callback.bind({token: record.token});
buttons.push(UI.button(LANG("review"), view_callback)); buttons.push(UI.button(LANG("review"), view_callback));
let dawn = UI.text(records[r].dawn); let dawn = UI.text(record.dawn);
let dusk = UI.text(records[r].dusk); let dusk = UI.text(record.dusk);
switch(records[r].is_complete) { switch(record.is_complete) {
case 1: dawn = UI.span([dawn], "c_dawn bold"); break; case 1: dawn = UI.span([dawn], "c_dawn bold"); break;
case 2: dusk = UI.span([dusk], "c_dusk bold"); break; case 2: dusk = UI.span([dusk], "c_dusk bold"); break;
} }
let moves = document.createElement("canvas");
setTimeout((canvas, moves) => {
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
let ctx = canvas.getContext("2d");
let size = canvas.height / 2;
for(let i = 0; i < moves.length; ++i) {
let piece = moves[i] & 0x7;
let promoted = (moves[i] & 0x8) >> 3;
let player = (moves[i] & 0x10) >> 4;
let color = null;
if(player == 0) { color = INTERFACE.Color.Dawn; } else { color = INTERFACE.Color.Dusk; }
let piece_name = GAME.Const.Piece[piece].name;
if(promoted) {
GAME_ASSET.Image.Promote.draw(ctx, 1.5 * size, [size * (1 + (2 * i)), size], INTERFACE.Color.Promote);
}
GAME_ASSET.Image[piece_name].draw(ctx, 1.5 * size, [size * (1 + (2 * i)), size], color);
}
}, 10, moves, record.moves);
rows.push([ rows.push([
dawn, dawn,
dusk, dusk,
UI.text(records[r].turn), UI.text(record.turn),
moves,
buttons, buttons,
]); ]);
} }
let tbody = UI.table_content( let tbody = UI.table_content(
[ LANG("dawn"), LANG("dusk"), LANG("turns"), "" ], [ LANG("dawn"), LANG("dusk"), LANG("turns"), "", "" ],
rows, rows,
); );