mirror of
https://github.com/AndrioCelos/TableturfBattleApp.git
synced 2026-04-24 15:27:00 -05:00
Implement replay format v3
This stores deck data in a more efficient manner, and includes deck names, sleeves and (currently unused) upgrade level fields.
This commit is contained in:
parent
3a1df937f4
commit
4a2bd4d5f9
|
|
@ -39,6 +39,7 @@ let currentReplay: {
|
|||
}[],
|
||||
turns: Move[][],
|
||||
}[],
|
||||
decks: Deck[],
|
||||
turns: Move[][],
|
||||
placements: PlacementResults[],
|
||||
watchingPlayer: number
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class ReplayLoader {
|
|||
throw new Error('Game data not loaded');
|
||||
|
||||
const version = this.readUint8();
|
||||
const players = [ ];
|
||||
const players: Player[] = [ ];
|
||||
let goalWinCount = null;
|
||||
switch (version) {
|
||||
case 1: {
|
||||
|
|
@ -35,7 +35,7 @@ class ReplayLoader {
|
|||
const initialDrawOrder = [ ];
|
||||
const drawOrder = [ ];
|
||||
for (let j = 0; j < 15; j++) {
|
||||
cards.push(this.loadCardFromReplay());
|
||||
cards.push(this.readCard());
|
||||
}
|
||||
for (let j = 0; j < 2; j++) {
|
||||
const n = this.readUint8();
|
||||
|
|
@ -68,7 +68,7 @@ class ReplayLoader {
|
|||
playerData.push({ deck: new Deck("Deck", 0, cards, new Array(15)), initialDrawOrder, drawOrder, won: false });
|
||||
}
|
||||
|
||||
const turns = this.replayLoadTurns(numPlayers);
|
||||
const turns = this.readTurns(numPlayers);
|
||||
currentReplay.games.push({ stage, playerData, turns });
|
||||
break;
|
||||
}
|
||||
|
|
@ -79,27 +79,7 @@ class ReplayLoader {
|
|||
if (goalWinCount == 0) goalWinCount = null;
|
||||
|
||||
currentReplay = { gameNumber: 0, decks: [ ], games: [ ], turns: [ ], placements: [ ], watchingPlayer: 0 };
|
||||
for (let i = 0; i < numPlayers; i++) {
|
||||
const colour = this.readColour();
|
||||
const specialColour = this.readColour();
|
||||
const specialAccentColour = this.readColour();
|
||||
const n2 = this.readUint8();
|
||||
const len = n2 & 0x7F;
|
||||
const player = {
|
||||
name: this.readString(len),
|
||||
specialPoints: 0,
|
||||
isReady: false,
|
||||
colour,
|
||||
specialColour,
|
||||
specialAccentColour,
|
||||
uiBaseColourIsSpecialColour: (n2 & 0x80) != 0,
|
||||
sleeves: 0,
|
||||
totalSpecialPoints: 0,
|
||||
passes: 0,
|
||||
gamesWon: 0
|
||||
};
|
||||
players.push(player);
|
||||
}
|
||||
this.readPlayers(numPlayers, players);
|
||||
|
||||
while (this.pos < this.dataView.byteLength) {
|
||||
const stage = stageDatabase.stages[this.readUint8()];
|
||||
|
|
@ -110,7 +90,7 @@ class ReplayLoader {
|
|||
const drawOrder = [ ];
|
||||
let won = false;
|
||||
for (let j = 0; j < 15; j++) {
|
||||
cards.push(this.loadCardFromReplay());
|
||||
cards.push(this.readCard());
|
||||
}
|
||||
for (let j = 0; j < 2; j++) {
|
||||
const n = this.readUint8();
|
||||
|
|
@ -127,7 +107,64 @@ class ReplayLoader {
|
|||
}
|
||||
playerData.push({ deck: new Deck("Deck", 0, cards, new Array(15)), initialDrawOrder, drawOrder, won });
|
||||
}
|
||||
const turns = this.replayLoadTurns(numPlayers);
|
||||
const turns = this.readTurns(numPlayers);
|
||||
currentReplay.games.push({ stage, playerData, turns });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
const n = this.readUint8();
|
||||
const numPlayers = n & 0x0F;
|
||||
goalWinCount = n >> 4;
|
||||
if (goalWinCount == 0) goalWinCount = null;
|
||||
|
||||
currentReplay = { gameNumber: 0, decks: [ ], games: [ ], turns: [ ], placements: [ ], watchingPlayer: 0 };
|
||||
this.readPlayers(numPlayers, players);
|
||||
|
||||
// Decks
|
||||
const decks = [ ];
|
||||
const numDecks = this.read7BitEncodedInt();
|
||||
for (let i = 0; i < numDecks; i++) {
|
||||
const name = this.readString();
|
||||
const sleeves = this.readUint8();
|
||||
const cards = [ ];
|
||||
for (let i = 0; i < 15; i++) cards.push(this.readCard());
|
||||
const upgrades = [ ];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
const b = this.readUint8();
|
||||
upgrades.push(b & 3);
|
||||
upgrades.push(b >> 2 & 3);
|
||||
upgrades.push(b >> 4 & 3);
|
||||
if (i < 3) upgrades.push(b >> 6 & 3);
|
||||
}
|
||||
decks.push(new Deck(name, sleeves, cards, upgrades));
|
||||
}
|
||||
|
||||
// Games
|
||||
while (this.pos < this.dataView.byteLength) {
|
||||
const stage = stageDatabase.stages[this.readUint8()];
|
||||
const playerData = [ ];
|
||||
for (let i = 0; i < numPlayers; i++) {
|
||||
const deck = decks[this.read7BitEncodedInt()];
|
||||
const initialDrawOrder = [ ];
|
||||
const drawOrder = [ ];
|
||||
let won = false;
|
||||
for (let j = 0; j < 2; j++) {
|
||||
const n = this.readUint8();
|
||||
initialDrawOrder.push(n & 0xF);
|
||||
initialDrawOrder.push(n >> 4 & 0xF);
|
||||
}
|
||||
for (let j = 0; j < 8; j++) {
|
||||
const n = this.readUint8();
|
||||
drawOrder.push(n & 0xF);
|
||||
if (j == 7)
|
||||
won = (n & 0x80) != 0;
|
||||
else
|
||||
drawOrder.push(n >> 4 & 0xF);
|
||||
}
|
||||
playerData.push({ deck, initialDrawOrder, drawOrder, won });
|
||||
}
|
||||
const turns = this.readTurns(numPlayers);
|
||||
currentReplay.games.push({ stage, playerData, turns });
|
||||
}
|
||||
break;
|
||||
|
|
@ -178,12 +215,36 @@ class ReplayLoader {
|
|||
return n;
|
||||
}
|
||||
|
||||
private replayLoadTurns(numPlayers: number) {
|
||||
private readPlayers(numPlayers: number, players: Player[]) {
|
||||
for (let i = 0; i < numPlayers; i++) {
|
||||
const colour = this.readColour();
|
||||
const specialColour = this.readColour();
|
||||
const specialAccentColour = this.readColour();
|
||||
const n2 = this.readUint8();
|
||||
const len = n2 & 0x7F;
|
||||
const player = {
|
||||
name: this.readString(len),
|
||||
specialPoints: 0,
|
||||
isReady: false,
|
||||
colour,
|
||||
specialColour,
|
||||
specialAccentColour,
|
||||
uiBaseColourIsSpecialColour: (n2 & 0x80) != 0,
|
||||
sleeves: 0,
|
||||
totalSpecialPoints: 0,
|
||||
passes: 0,
|
||||
gamesWon: 0
|
||||
};
|
||||
players.push(player);
|
||||
}
|
||||
}
|
||||
|
||||
private readTurns(numPlayers: number) {
|
||||
const turns = [ ];
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const turn = [ ];
|
||||
for (let j = 0; j < numPlayers; j++) {
|
||||
const card = this.loadCardFromReplay();
|
||||
const card = this.readCard();
|
||||
const b = this.readUint8();
|
||||
const x = this.readInt8();
|
||||
const y = this.readInt8();
|
||||
|
|
@ -199,7 +260,7 @@ class ReplayLoader {
|
|||
return turns;
|
||||
}
|
||||
|
||||
private loadCardFromReplay() {
|
||||
private readCard() {
|
||||
const num = this.readUint8();
|
||||
return cardDatabase.get(num > cardDatabase.lastOfficialCardNumber ? num - 256 : num);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,9 +70,14 @@ public class Game {
|
|||
return false;
|
||||
}
|
||||
|
||||
public Deck GetDeck(string name, int sleeves, IEnumerable<int> cardNumbers, IEnumerable<int> cardUpgrades)
|
||||
=> this.deckCache.FirstOrDefault(d => d.Name == name && d.Sleeves == sleeves && cardNumbers.SequenceEqual(from c in d.Cards select c.Number) && cardUpgrades.SequenceEqual(d.Upgrades))
|
||||
?? new(name, sleeves, (from i in cardNumbers select CardDatabase.GetCard(i)).ToArray(), cardUpgrades.ToArray());
|
||||
public Deck GetDeck(string name, int sleeves, IEnumerable<int> cardNumbers, IEnumerable<int> cardUpgrades) {
|
||||
var deck = this.deckCache.FirstOrDefault(d => d.Name == name && d.Sleeves == sleeves && cardNumbers.SequenceEqual(from c in d.Cards select c.Number) && cardUpgrades.SequenceEqual(d.Upgrades));
|
||||
if (deck == null) {
|
||||
deck = new(name, sleeves, (from i in cardNumbers select CardDatabase.GetCard(i)).ToArray(), cardUpgrades.ToArray());
|
||||
this.deckCache.Add(deck);
|
||||
}
|
||||
return deck;
|
||||
}
|
||||
|
||||
public bool CanPlay(int playerIndex, Card card, int x, int y, int rotation, bool isSpecialAttack) {
|
||||
if (card is null) throw new ArgumentNullException(nameof(card));
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user