diff --git a/phaser/src/assets/images/boardAssets/purchase_button.png b/phaser/src/assets/images/boardAssets/purchase_button.png new file mode 100644 index 0000000..2481476 Binary files /dev/null and b/phaser/src/assets/images/boardAssets/purchase_button.png differ diff --git a/phaser/src/assets/images/boardAssets/reserve_button.png b/phaser/src/assets/images/boardAssets/reserve_button.png new file mode 100644 index 0000000..61fee7f Binary files /dev/null and b/phaser/src/assets/images/boardAssets/reserve_button.png differ diff --git a/phaser/src/assets/images/boardAssets/take_chips.png b/phaser/src/assets/images/boardAssets/take_chips.png index d173ac7..839e39c 100644 Binary files a/phaser/src/assets/images/boardAssets/take_chips.png and b/phaser/src/assets/images/boardAssets/take_chips.png differ diff --git a/phaser/src/classes/card.js b/phaser/src/classes/card.js index f44c100..28440d8 100644 --- a/phaser/src/classes/card.js +++ b/phaser/src/classes/card.js @@ -1,79 +1,382 @@ -export function drawCost(x, y, serverCost, gemToSprite, board, scale) { - x += 8; - y -= 4; - //console.log(gemToSprite) - for (var gemtype in gemToSprite) { - //console.log("Drawing: " + gemtype); - var cost = serverCost[gemtype]; - if (cost === 0) { - continue; - } - - board.f_cards.push(board.add.sprite(x + 16, y - 16, gemToSprite[gemtype]).setScale(scale)); - board.f_cards.push(board.add.sprite(x + 16, y - 16, cost + "x128").setScale(scale / 2)); - - //TODO: this probably needs to be spaced better - y -= 64 * scale + 4; - } -} +import * as globals from "../globals.js"; +import eventHandler from "../scenes/eventHandler.js"; +export class card { + constructor(board, cardID) { + this.board = board; + this.cardID = cardID; + this.cardMap = { + onyx: "brown", + ruby: "red", + emerald: "green", + sapphire: "blue", + diamond: "white", + }; -export class card { - constructor(board, cardID) { - this.board = board; - this.cardID = cardID; - - this.cardMap = { - "onyx": "brown", - "ruby": "red", - "emerald": "green", - "sapphire": "blue", - "diamond": "white" - }; - - this.spriteCostMap = {}; - for (var color in this.cardMap) { - this.spriteCostMap[color] = this.cardMap[color] + "_circle_x64"; - } - } - - getCardName(color) { - return "card_" + color + "_731x1024"; - } - - drawCard(x, y, width, height, isReserved) { - if (this.cardID == null) { - this.board.f_cards.push(this.board.add.sprite(x, y, "card_outline_x1024").setScale(this.board.scales)); - return; - } - - var dicEntry = this.board.server.lookUpCard(this.board.cardsDatabase, this.cardID); - - const gemScale = 48 / 128; - const gemLength = 128 * gemScale; - const gemHalfLength = gemLength / 2; - - var upperCornerX = x - width * .5; - var upperCornerY = y - height * .5; - - var cardColor = this.cardMap[dicEntry["gem_type"]]; - this.board.f_cards.push(this.board.add.sprite(x, y, this.getCardName(cardColor)).setScale(this.board.scales)); - this.board.f_cards.push(this.board.add.sprite(upperCornerX + width - gemHalfLength, - upperCornerY + gemHalfLength + 5, cardColor + "_symbol_x128") - .setScale(gemScale)); - - var prestige = dicEntry["prestige_points"]; - - if (prestige != 0) { - var numHalfLength = 64 / 2; - this.board.f_cards.push(this.board.add.sprite(upperCornerX + numHalfLength - 8, upperCornerY + numHalfLength - 3, prestige + "x128").setScale(64 / 128)); - } - - if (isReserved) { - var numHalfLength = 64 / 2; - this.board.f_cards.push(this.board.add.sprite(x + width * 0.5 - numHalfLength - 8, y + width * 0.5 - numHalfLength + 14, "r" + dicEntry["rank"] + "x128").setScale(80 / 128)); - } - - drawCost(upperCornerX, upperCornerY + height, dicEntry, this.spriteCostMap, this.board, 30 / 64); - } -} \ No newline at end of file + this.spriteCostMap = {}; + for (var color in this.cardMap) { + this.spriteCostMap[color] = this.cardMap[color] + "_circle_x64"; + } + } + + getCardName(color) { + return "card_" + color + "_731x1024"; + } + + drawCard(x, y, width, height, isReserved) { + this.group = this.board.add.group(); + + if (this.cardID == null) { + this.group.add(this.board.add.sprite(x, y, "card_outline_x1024").setScale(this.board.scales)); + this.board.cardObjects.push(this.group); + return; + } + + var dicEntry = this.board.server.lookUpCard(this.board.cardsDatabase, this.cardID); + + const gemScale = 48 / 128; + const gemLength = 128 * gemScale; + const gemHalfLength = gemLength / 2; + + var upperCornerX = x - width * 0.5; + var upperCornerY = y - height * 0.5; + + var cardColor = this.cardMap[dicEntry["gem_type"]]; + this.group.add(this.board.add.sprite(x, y, this.getCardName(cardColor)).setScale(this.board.scales)); + this.group.add( + this.board.add + .sprite( + upperCornerX + width - gemHalfLength, + upperCornerY + gemHalfLength + 5, + cardColor + "_symbol_x128" + ) + .setScale(gemScale) + ); + + var prestige = dicEntry["prestige_points"]; + + if (prestige !== 0) { + var numHalfLength = 64 / 2; + this.group.add( + this.board.add + .sprite(upperCornerX + numHalfLength - 8, upperCornerY + numHalfLength - 3, prestige + "x128") + .setScale(64 / 128) + ); + } + + if (isReserved) { + var numHalfLength = 64 / 2; + this.group.add( + this.board.add + .sprite( + x + width * 0.5 - numHalfLength - 8, + y + width * 0.5 - numHalfLength + 14, + "r" + dicEntry["rank"] + "x128" + ) + .setScale(80 / 128) + ); + } + + this.drawCost(upperCornerX, upperCornerY + height, dicEntry, 30 / 64); + this.board.cardObjects.push(this.group); + + if (this.board.gameState != null) { + if (this.board.gameState.player_turn === globals.playerID) { + const player = this.board.gameState.players[globals.playerID.toString()]; + const buyBehavior = this.purchaseable(dicEntry); + const hoverRect = this.board.add.zone(x, y, 731, 1024).setScale(this.board.scales).setDepth(0); + const hoverScale = 1.2; + const adjustedScale = 0.8; + hoverRect.setInteractive(); + this.board.input.setTopOnly(false); + + const purchaseButton = this.board.add + .image(x, y - 20, "purchase_button") + .setScale(this.board.scales * adjustedScale) + .setVisible(false) + .setFrame(3) + .setDepth(1); + const reserveButton = this.board.add + .image(x, y + 25, "reserve_button") + .setScale(this.board.scales * adjustedScale) + .setVisible(false) + .setFrame(1) + .setDepth(1); + + this.group.addMultiple([hoverRect, purchaseButton, reserveButton]); + + if (isReserved) { + reserveButton.setActive(false); + } + + this.board.boardEvents.on("disable_interactive", disabled => { + if (disabled) { + hoverRect.disableInteractive(); + purchaseButton.disableInteractive(); + if (!isReserved) reserveButton.disableInteractive(); + } else { + hoverRect.setInteractive(); + if (buyBehavior === "free_buy" || buyBehavior === "regular_buy" || buyBehavior === "joker_buy") + purchaseButton.setInteractive({useHandCursor: true}); + if (player.private_reserved_cards.length < 3 && !isReserved) + reserveButton.setInteractive({useHandCursor: true}); + } + }); + + const thisCard = this; + + hoverRect.on("pointerover", function () { + thisCard.changeScale(hoverScale); + purchaseButton.setVisible(true); + if (!isReserved) reserveButton.setVisible(true); + }); + + hoverRect.on("pointerout", function (pointer) { + thisCard.changeScale(hoverScale, true); + purchaseButton.setVisible(false); + reserveButton.setVisible(false); + }); + if (buyBehavior === "free_buy") { + purchaseButton.setFrame(0).setInteractive({useHandCursor: true}); + } else if (buyBehavior === "regular_buy") { + purchaseButton.setFrame(1).setInteractive({useHandCursor: true}); + } else if (buyBehavior === "joker_buy") { + purchaseButton.setFrame(2).setInteractive({useHandCursor: true}); + } + + if (player.private_reserved_cards != null) { + if (player.private_reserved_cards.length < 3 && !isReserved) + reserveButton.setFrame(0).setInteractive({useHandCursor: true}); + } else if (!isReserved) { + reserveButton.setFrame(0).setInteractive({useHandCursor: true}); + } + + purchaseButton.on("pointerover", function () { + this.setTint(0xdfdfdf).setScale(thisCard.board.scales * adjustedScale * hoverScale * 1.05); + }); + + purchaseButton.on("pointerdown", function () { + this.setTint(0xcccccc).setScale(thisCard.board.scales * adjustedScale * hoverScale * 0.95); + }); + + purchaseButton.on("pointerout", function () { + this.setScale(thisCard.board.scales * hoverScale * adjustedScale); + this.clearTint(); + }); + + purchaseButton.on("pointerup", function () { + this.setScale(thisCard.board.scales * hoverScale * adjustedScale); + this.clearTint(); + + let returned_chips = {diamond: 0, sapphire: 0, emerald: 0, ruby: 0, onyx: 0, joker: 0}; + + if (buyBehavior !== "free_buy" && player.player_chips["joker"] > 0) { + thisCard.board.returnBox.createReturnChips("buy_card", thisCard.cardID); + eventHandler.emit("disable_interactive", true); + thisCard.board.boardEvents.on("chips_returned", new_return => { + returned_chips = new_return; + thisCard.buy(returned_chips); + }); + } else { + returned_chips = thisCard.board.calculateReturn(thisCard.cardID); + thisCard.buy(returned_chips); + } + }); + + reserveButton.on("pointerover", function () { + this.setTint(0xdfdfdf).setScale(thisCard.board.scales * adjustedScale * hoverScale * 1.05); + }); + + reserveButton.on("pointerdown", function () { + this.setTint(0xcccccc).setScale(thisCard.board.scales * adjustedScale * hoverScale * 0.95); + }); + + reserveButton.on("pointerout", function () { + this.setScale(thisCard.board.scales); + this.clearTint(); + }); + + reserveButton.on("pointerup", function () { + this.setScale(thisCard.board.scales); + this.clearTint(); + + let returned_chips = {diamond: 0, sapphire: 0, emerald: 0, ruby: 0, onyx: 0, joker: 0}; + + if (1 + thisCard.sumObj(player.player_chips) > 10 && thisCard.board.gameState.field_chips["joker"] > 0) { + thisCard.board.returnBox.createReturnChips("chip_overflow_2"); + eventHandler.emit("disable_interactive", true); + thisCard.board.boardEvents.on("chips_returned", new_return => { + returned_chips = new_return; + thisCard.reserve(returned_chips); + }); + } else { + thisCard.reserve(returned_chips); + } + }); + } + } + } + + drawCost(x, y, serverCost, scale) { + x += 8; + y -= 4; + + for (var gemtype in this.spriteCostMap) { + var cost = serverCost[gemtype]; + if (cost === 0) { + continue; + } + + this.group.addMultiple([ + this.board.add.sprite(x + 16, y - 16, this.spriteCostMap[gemtype]).setScale(scale), + this.board.add.sprite(x + 16, y - 16, cost + "x128").setScale(scale / 2), + ]); + + //TODO: this probably needs to be spaced better + y -= 64 * scale + 4; + } + } + + changeScale(scale, down = false) { + if (down) { + for (let i = 0; i < this.group.getLength(); i++) { + let childScale = this.group.getChildren()[i].scale; + this.group.getChildren()[i].setScale(childScale * (1 / scale)); + } + } else { + for (let i = 0; i < this.group.getLength(); i++) { + let childScale = this.group.getChildren()[i].scale; + this.group.getChildren()[i].setScale(childScale * scale); + } + } + } + + purchaseable(serverCost) { + let costDeltas = [Infinity, Infinity, Infinity, Infinity, Infinity]; + let cardDeltas = [Infinity, Infinity, Infinity, Infinity, Infinity]; + const chipOrder = new Map([ + [0, "diamond"], + [1, "sapphire"], + [2, "emerald"], + [3, "ruby"], + [4, "onyx"], + [5, "joker"], + ]); + const player = this.board.gameState.players[globals.playerID.toString()]; + + for (let i = 0; i < costDeltas.length; i++) { + let playerWorth = player.player_num_gem_cards[chipOrder.get(i)] + player.player_chips[chipOrder.get(i)]; + let cardWorth = player.player_num_gem_cards[chipOrder.get(i)]; + cardDeltas[i] = serverCost[chipOrder.get(i)] - cardWorth; + if (cardDeltas[i] < 0) cardDeltas[i] = 0; + costDeltas[i] = serverCost[chipOrder.get(i)] - playerWorth; + if (costDeltas[i] < 0) costDeltas[i] = 0; + } + + const costDifference = this.sumArr(costDeltas); + const cardDifference = this.sumArr(cardDeltas); + + if (cardDifference === 0) { + return "free_buy"; + } else if (costDifference === 0) { + return "regular_buy"; + } else if (costDifference <= player.player_chips["joker"]) { + return "joker_buy"; + } + + return "no_buy"; + } + + reserve(return_obj) { + const args = { + player_id: globals.playerID, + session_id: globals.lobbyID, + reserved_card: this.cardID, + returned_chips: return_obj, + }; + fetch(globals.fullAddr + "/api/reserve_card/", { + method: "POST", + headers: globals.headers, + body: JSON.stringify(args), + }) + .then(this.handleErrors) + .then(result => { + if (result === "OK") { + } else { + console.warn(result); + } + }) + .catch(error => { + console.error(error); + }); + } + + buy(return_obj) { + let noble = -1; + const dicEntry = this.board.server.lookUpCard(this.board.cardsDatabase, this.cardID); + const playerCards = this.board.gameState.players[globals.playerID.toString()].player_num_gem_cards; + if (this.board.gameState.field_nobles != null) { + for (let i = 0; i < this.board.gameState.field_nobles.length; i++) { + let thisNoble = this.board.server.lookUpNoble( + this.board.noblesDatabase, + this.board.gameState.field_nobles[i] + ); + thisNoble[dicEntry.gem_type] -= 1; + if ( + playerCards.diamond >= thisNoble.diamond && + playerCards.sapphire >= thisNoble.sapphire && + playerCards.emerald >= thisNoble.emerald && + playerCards.ruby >= thisNoble.ruby && + playerCards.onyx >= thisNoble.onyx + ) { + noble = thisNoble.noble_id; + break; + } + } + } + + const args = { + player_id: globals.playerID, + session_id: globals.lobbyID, + purchased_card: this.cardID, + returned_chips: return_obj, + noble_acquired: noble, + }; + fetch(globals.fullAddr + "/api/buy_card/", { + method: "POST", + headers: globals.headers, + body: JSON.stringify(args), + }) + .then(this.handleErrors) + .then(result => { + if (result === "OK") { + } else { + console.warn(result); + } + }) + .catch(error => { + console.error(error); + }); + } + + sumObj(obj) { + const sum = Object.values(obj).reduce((n, x) => n + x, 0); + return sum; + } + + /** + * @param {Array} arr + */ + + sumArr(arr) { + const sum = arr.reduce((n, x) => n + x, 0); + return sum; + } + + handleErrors(response) { + if (!response.ok) { + throw Error(response.statusText); + } + return response.json(); + } +} diff --git a/phaser/src/classes/returnChips.js b/phaser/src/classes/returnChips.js index 011ba29..64c02f8 100644 --- a/phaser/src/classes/returnChips.js +++ b/phaser/src/classes/returnChips.js @@ -9,7 +9,6 @@ export class returnChips extends Phaser.GameObjects.DOMElement { * @param {integer} x * @param {integer} y * @param {string} cache - * @param {string} use */ constructor(scene, x, y, cache) { @@ -19,7 +18,7 @@ export class returnChips extends Phaser.GameObjects.DOMElement { this.setDepth(2); } - createReturnChips(use) { + createReturnChips(use, cardID = -1) { const chipReturn = this; const board = chipReturn.scene; const chipOrder = new Map([ @@ -41,11 +40,15 @@ export class returnChips extends Phaser.GameObjects.DOMElement { this.setVisible(true); this.removeAllListeners(); - if (use === "chip_overflow") { - const chipsNeeded = - chipReturn.sumObj(board.gameState.players[globals.playerID.toString()].player_chips) + - chipReturn.sumArr(board.cachedChips) - - 10; + if (use === "chip_overflow" || use === "chip_overflow_2") { + if (use === "chip_overflow") { + var chipsNeeded = + chipReturn.sumObj(board.gameState.players[globals.playerID.toString()].player_chips) + + chipReturn.sumArr(board.cachedChips) - + 10; + } else { + var chipsNeeded = 1; + } chipReturn.getChildByID("return_title").innerHTML = "Too Many Gems!"; chipReturn.getChildByID("return_subtitle").innerHTML = "Please return " + chipsNeeded.toString(); if (chipsNeeded === 1) { @@ -70,10 +73,17 @@ export class returnChips extends Phaser.GameObjects.DOMElement { .getChildByID("chip_container") .getElementsByClassName("chip_and_num") .item(i).lastElementChild; - og_chipValues[i] = - board.gameState.players[globals.playerID.toString()].player_chips[chipOrder.get(i)] + - (i < 5 ? board.cachedChips[i] : 0); + if (use === "chip_overflow") { + og_chipValues[i] = + board.gameState.players[globals.playerID.toString()].player_chips[chipOrder.get(i)] + + (i < 5 ? board.cachedChips[i] : 0); + } else { + og_chipValues[i] = + board.gameState.players[globals.playerID.toString()].player_chips[chipOrder.get(i)] + + (i < 5 ? 0 : 1); + } og_chipNums[i].innerHTML = og_chipValues[i].toString(); + og_chipNums[i].style.color = "white"; if (og_chipValues[i] >= 1) { plusButtons[i] = chipReturn @@ -94,6 +104,13 @@ export class returnChips extends Phaser.GameObjects.DOMElement { .item(i).firstElementChild; minusButtons[i].disabled = true; + if (i === inverseChipMap["joker"]) { + chipReturn + .getChildByID("plus_minus_container") + .getElementsByClassName("plus_minus") + .item(i).style.opacity = 1; + } + returnNums[i] = chipReturn.getChildByID("num_container").children.item(i); returnNums[i].innerHTML = returnValues[i].toString(); } @@ -161,6 +178,136 @@ export class returnChips extends Phaser.GameObjects.DOMElement { joker: returnValues[5], }; + board.boardEvents.emit("chips_returned", returnObj); + chipReturn.reset(); + } else if (pressedButton.type === "cancel") { + board.boardEvents.off("chips_returned"); + chipReturn.reset(); + } + }); + } else if (use === "buy_card") { + chipReturn.getChildByID("return_title").innerHTML = "Buy Card"; + chipReturn.getChildByID("return_subtitle").innerHTML = "Please spend necessary gems"; + chipReturn.getChildByID("submit_chips").disabled = false; + + const player = board.gameState.players[globals.playerID.toString()]; + + let og_chipNums = []; + let og_chipValues = []; + let plusButtons = []; + let minusButtons = []; + let returnNums = []; + let returnValues = []; + + let returnDict = board.calculateReturn(cardID); + let emptyJokers = player.player_chips["joker"] - returnDict.joker; + + for (let i = 0; i < Object.keys(returnDict).length; i++) { + og_chipValues[i] = returnDict[chipOrder.get(i)]; + returnValues[i] = returnDict[chipOrder.get(i)]; + + og_chipNums[i] = chipReturn + .getChildByID("chip_container") + .getElementsByClassName("chip_and_num") + .item(i).lastElementChild; + + og_chipNums[i].innerHTML = player.player_chips[chipOrder.get(i)].toString(); + if (og_chipValues[i] > player.player_chips[chipOrder.get(i)]) og_chipNums[i].style.color = "yellow"; + else og_chipNums[i].style.color = "white"; + + if (emptyJokers >= 1 && chipOrder.get(i) !== "joker" && og_chipValues[i] > 0) { + minusButtons[i] = chipReturn + .getChildByID("plus_minus_container") + .getElementsByClassName("plus_minus") + .item(i).firstElementChild; + minusButtons[i].disabled = false; + } else { + minusButtons[i] = chipReturn + .getChildByID("plus_minus_container") + .getElementsByClassName("plus_minus") + .item(i).firstElementChild; + minusButtons[i].disabled = true; + } + plusButtons[i] = chipReturn + .getChildByID("plus_minus_container") + .getElementsByClassName("plus_minus") + .item(i).lastElementChild; + plusButtons[i].disabled = true; + + if (i === inverseChipMap["joker"]) { + chipReturn + .getChildByID("plus_minus_container") + .getElementsByClassName("plus_minus") + .item(i).style.opacity = 0; + } + + returnNums[i] = chipReturn.getChildByID("num_container").children.item(i); + returnNums[i].innerHTML = returnValues[i].toString(); + } + + chipReturn.addListener("click").on("click", function (event) { + let pressedButton = {type: "", id: -1}; + if (event.target.parentNode.className === "plus_minus") { + pressedButton.type = event.target.className; + pressedButton.id = inverseChipMap[event.target.parentNode.id.split("_").pop()]; + } else if (event.target.id === "submit_chips") { + pressedButton.type = "submit"; + } else if (event.target.id === "cancel_chips") { + pressedButton.type = "cancel"; + } + + if (pressedButton.type === "plus") { + returnValues[pressedButton.id] += 1; + returnValues[inverseChipMap.joker] -= 1; + emptyJokers += 1; + + if (returnValues[pressedButton.id] === og_chipValues[pressedButton.id]) { + og_chipNums[pressedButton.id].style.color = "white"; + } + + returnNums[pressedButton.id].innerHTML = returnValues[pressedButton.id].toString(); + returnNums[inverseChipMap.joker].innerHTML = returnValues[inverseChipMap.joker].toString(); + + if ( + returnValues[pressedButton.id] >= og_chipValues[pressedButton.id] || + returnValues[pressedButton.id] >= player.player_chips[chipOrder.get(pressedButton.id)] + ) { + plusButtons[pressedButton.id].disabled = true; + } + + for (let i = 0; i < minusButtons.length; i++) + minusButtons[i].disabled = !(returnValues[i] > 0 && i !== inverseChipMap.joker); + } else if (pressedButton.type === "minus") { + returnValues[pressedButton.id] -= 1; + returnValues[inverseChipMap.joker] += 1; + emptyJokers -= 1; + + returnNums[pressedButton.id].innerHTML = returnValues[pressedButton.id].toString(); + returnNums[inverseChipMap.joker].innerHTML = returnValues[inverseChipMap.joker].toString(); + og_chipNums[pressedButton.id].style.color = "yellow"; + + if (returnValues[pressedButton.id] <= 0) { + minusButtons[pressedButton.id].disabled = true; + } + + plusButtons[pressedButton.id].disabled = false; + + for (let i = 0; i < minusButtons.length; i++) + minusButtons[i].disabled = !( + returnValues[i] > 0 && + emptyJokers >= 1 && + i !== inverseChipMap.joker + ); + } else if (pressedButton.type === "submit") { + const returnObj = { + diamond: returnValues[0], + sapphire: returnValues[1], + emerald: returnValues[2], + ruby: returnValues[3], + onyx: returnValues[4], + joker: returnValues[5], + }; + board.boardEvents.emit("chips_returned", returnObj); chipReturn.reset(); } else if (pressedButton.type === "cancel") { diff --git a/phaser/src/classes/serverManager.js b/phaser/src/classes/serverManager.js index ece8569..e171b93 100644 --- a/phaser/src/classes/serverManager.js +++ b/phaser/src/classes/serverManager.js @@ -1,67 +1,66 @@ -import { card } from "./card"; +import {card} from "./card"; export class serverManager { - lookUpCard(database, cardId) { - //TODO: actual numbers - if (cardId == -1) { - return { - "card_id" : 0, - "rank" : 1, - "prestige_points" : 0, - "gem_type" : "diamond", - "diamond" : 0, - "sapphire" : 0, - "emerald" : 0, - "ruby" : 0, - "onyx" : 0 - }; - } + lookUpCard(database, cardId) { + //TODO: actual numbers + if (cardId == -1) { + return { + card_id: 0, + rank: 1, + prestige_points: 0, + gem_type: "diamond", + diamond: 0, + sapphire: 0, + emerald: 0, + ruby: 0, + onyx: 0, + }; + } - let card = database[cardId] + let card = database[cardId]; - return { - "card_id" : card.card_id, - "rank" : card.rank, - "prestige_points" : card.prestige_points, - "gem_type" : card.gem_type, - "diamond" : card.diamond, - "sapphire" : card.sapphire, - "emerald" : card.emerald, - "ruby" : card.ruby, - "onyx" : card.onyx - }; - } + return { + card_id: card.card_id, + rank: card.rank, + prestige_points: card.prestige_points, + gem_type: card.gem_type, + diamond: card.diamond, + sapphire: card.sapphire, + emerald: card.emerald, + ruby: card.ruby, + onyx: card.onyx, + }; + } - lookUpNoble(database, nobleId) { - //TODO: actual numbers - if (nobleId == -1) { - return { - "noble_id" : 0, - "prestige_points" : 0, - "diamond" : 0, - "sapphire" : 0, - "emerald" : 0, - "ruby" : 0, - "onyx" : 0 - }; - } + lookUpNoble(database, nobleId) { + //TODO: actual numbers + if (nobleId == -1) { + return { + noble_id: 0, + prestige_points: 0, + diamond: 0, + sapphire: 0, + emerald: 0, + ruby: 0, + onyx: 0, + }; + } - let noble = database[nobleId] + let noble = database[nobleId]; - return { - "noble_id" : noble.noble_id, - "prestige_points" : noble.prestige_points, - "diamond" : noble.diamond, - "sapphire" : noble.sapphire, - "emerald" : noble.emerald, - "ruby" : noble.ruby, - "onyx" : noble.onyx - }; - } + return { + noble_id: noble.noble_id, + prestige_points: noble.prestige_points, + diamond: noble.diamond, + sapphire: noble.sapphire, + emerald: noble.emerald, + ruby: noble.ruby, + onyx: noble.onyx, + }; + } - lookUpFieldChips(game, chipType) { - if (game == null) - return 0; - return game.field_chips[chipType]; - } -} \ No newline at end of file + lookUpFieldChips(game, chipType) { + if (game == null) return 0; + return game.field_chips[chipType]; + } +} diff --git a/phaser/src/scenes/board.js b/phaser/src/scenes/board.js index 83b0028..227fc37 100644 --- a/phaser/src/scenes/board.js +++ b/phaser/src/scenes/board.js @@ -18,7 +18,7 @@ export default class board extends Phaser.Scene { } init() { - this.cards = [[], [], []]; + this.cards = [[], [], [], []]; this.scales = 0.1875; //TODO: this should be auto-detected @@ -49,6 +49,7 @@ export default class board extends Phaser.Scene { const sizes = ["64", "128", "256"]; const colors = ["blue", "brown", "green", "red", "white", "gold"]; + const rsvd = ["r1", "r2", "r3"]; this.load.path = "src/assets/images/boardAssets/"; @@ -66,6 +67,11 @@ export default class board extends Phaser.Scene { this.load.image(name, name + fExtension); } } + + for (var rank of rsvd) { + var name = rank + "x" + size; + this.load.image(name, name + fExtension); + } } for (var color of colors) { @@ -97,6 +103,14 @@ export default class board extends Phaser.Scene { frameWidth: 128, frameHeight: 64, }); + this.load.spritesheet("purchase_button", "purchase_button" + fExtension, { + frameWidth: 768, + frameHeight: 192, + }); + this.load.spritesheet("reserve_button", "reserve_button" + fExtension, { + frameWidth: 768, + frameHeight: 192, + }); } create() { @@ -105,11 +119,12 @@ export default class board extends Phaser.Scene { thisBoard.boardOn = false; thisBoard.updatable = false; thisBoard.gameState = null; - thisBoard.f_cards = []; + thisBoard.f_cardbacks = []; thisBoard.f_nobles = []; thisBoard.f_chips = []; thisBoard.f_chipNumbers = []; thisBoard.f_UI = []; + thisBoard.cardObjects = []; thisBoard.scene.sendToBack(); //#region Game Variables @@ -177,18 +192,20 @@ export default class board extends Phaser.Scene { //#region Idk whatever Nathan did so idk what to name the region, but it should be renamed function draw_board() { - for (i = 0; i < thisBoard.f_cards.length; ++i) thisBoard.f_cards[i].destroy(); + for (i = 0; i < thisBoard.f_cardbacks.length; ++i) thisBoard.f_cardbacks[i].destroy(); for (i = 0; i < thisBoard.f_nobles.length; ++i) thisBoard.f_nobles[i].destroy(); for (i = 0; i < thisBoard.f_chips.length; ++i) thisBoard.f_chips[i].destroy(); for (i = 0; i < thisBoard.f_chipNumbers.length; ++i) thisBoard.f_chipNumbers[i].destroy(); for (i = 0; i < thisBoard.f_UI.length; ++i) thisBoard.f_UI[i].destroy(); + for (i = 0; i < thisBoard.cardObjects.length; ++i) thisBoard.cardObjects[i].destroy(true); thisBoard.boardEvents.removeAllListeners(); - thisBoard.f_cards = []; + thisBoard.f_cardbacks = []; thisBoard.f_nobles = []; thisBoard.f_chips = []; thisBoard.f_chipNumbers = []; thisBoard.f_UI = []; + thisBoard.cardObjects = []; thisBoard.cachedChips = [0, 0, 0, 0, 0]; @@ -208,7 +225,7 @@ export default class board extends Phaser.Scene { for (var row = 0; row < numRows; row++) { //Display cards if (!thisBoard.gameState || thisBoard.gameState.cards_remaining[row] > 0) { - thisBoard.f_cards.push( + thisBoard.f_cardbacks.push( thisBoard.add .sprite( flippedCardStartX - spacedWidth - 16, @@ -218,7 +235,7 @@ export default class board extends Phaser.Scene { .setScale(thisBoard.scales) ); } else { - thisBoard.f_cards.push( + thisBoard.f_cardbacks.push( thisBoard.add .sprite( flippedCardStartX - spacedWidth - 16, @@ -230,18 +247,33 @@ export default class board extends Phaser.Scene { } for (var column = 0; column < numColumns; column++) { - if (thisBoard.gameState != null && thisBoard.cardsDatabase != undefined) + if (thisBoard.gameState != null && thisBoard.cardsDatabase != undefined) { thisBoard.cards[row][column] = new card( thisBoard, thisBoard.gameState.field_cards[row][column] ); - else thisBoard.cards[row][column] = new card(thisBoard, -1); + } else thisBoard.cards[row][column] = new card(thisBoard, -1); thisBoard.cards[row][column].drawCard( flippedCardStartX + spacedWidth * column, flippedCardStartY + spacedHeight * (numRows - 1 - row), width, - height + height, + false + ); + } + } + + if (thisBoard.gameState != null && thisBoard.cardsDatabase != undefined && globals.playerID >= 0) { + let curPlayer = thisBoard.gameState.players[globals.playerID]; + for (let count = 0; count < curPlayer.private_reserved_cards.length; ++count) { + thisBoard.cards[numRows][count] = new card(thisBoard, curPlayer.private_reserved_cards[count]); + thisBoard.cards[numRows][count].drawCard( + flippedCardStartX + 46 + spacedWidth * 1.2 * count, + flippedCardStartY + 60 + spacedHeight * numRows, + width, + height, + true ); } } @@ -330,7 +362,7 @@ export default class board extends Phaser.Scene { "/api/get_game_state?" + new URLSearchParams({ session_id: globals.lobbyID, - playerID: globals.playerID, + player_id: globals.playerID, }) ) .then(handleErrors) @@ -471,4 +503,37 @@ export default class board extends Phaser.Scene { return response.json(); } } + + calculateReturn(cardID) { + let needed_chips = {diamond: 0, sapphire: 0, emerald: 0, ruby: 0, onyx: 0, joker: 0}; + const chipOrder = new Map([ + [0, "diamond"], + [1, "sapphire"], + [2, "emerald"], + [3, "ruby"], + [4, "onyx"], + [5, "joker"], + ]); + const player = this.gameState.players[globals.playerID.toString()]; + let jokers = 0; + + for (let i = 0; i < Object.keys(needed_chips).length - 1; i++) { + let cardCost = this.server.lookUpCard(this.cardsDatabase, cardID)[chipOrder.get(i)]; + let cardWorth = player.player_num_gem_cards[chipOrder.get(i)]; + let adjustedCost = cardCost - cardWorth; + if (adjustedCost < 0) { + adjustedCost = 0; + } + + if (adjustedCost > player.player_chips[chipOrder.get(i)]) { + jokers += adjustedCost - player.player_chips[chipOrder.get(i)]; + adjustedCost -= adjustedCost - player.player_chips[chipOrder.get(i)]; + } + needed_chips[chipOrder.get(i)] = adjustedCost; + } + + needed_chips.joker = jokers; + + return needed_chips; + } } diff --git a/server/game.py b/server/game.py index fd89f14..593daee 100644 --- a/server/game.py +++ b/server/game.py @@ -476,13 +476,17 @@ def reserve_card(args, games): game.field_chips[5] -= 1 game.most_recent_action += " and earned a " + gems[5] + " token" + if returned > 0: + game.most_recent_action += ", while returning " + token_str(returned, returned_chips) + game.most_recent_action += "!" game.cards_remaining[index[0]] -= 1 if returned > 0: for x in range(0, 6): - player.player_chips -= returned_chips[x] + player.player_chips[x] -= returned_chips[x] + game.field_chips[x] += returned_chips[x] next_turn(game)