142 lines
5.8 KiB
TypeScript
142 lines
5.8 KiB
TypeScript
import { turnOrderUtil } from "../../../util/turnOrderUtil";
|
|
import getTotalBuyingPower from "../../../util/getTotalBuyingPower";
|
|
import { AppState, CardData, PlayerCards, ResourceCost, setStateType } from "../../../util/types";
|
|
import cardTierToKey from "../../../util/cardTierToKey";
|
|
import { canPickUpNoble } from "../../Nobles/canPickUpNoble";
|
|
import { initialActions, setStateGetNoble } from "../../../hooks/stateSetters";
|
|
import { useCurrentPlayer } from "../../../hooks/useCurrentPlayer";
|
|
import usePreviousPlayer from "../../../hooks/usePreviousPlayer";
|
|
|
|
export const tooExpensive = (card: CardData, state: AppState): boolean => {
|
|
const currentPlayer = useCurrentPlayer(state);
|
|
if (!currentPlayer) return true;
|
|
|
|
let availableGold = currentPlayer.inventory.gold || 0;
|
|
|
|
// iterate through resource costs on card
|
|
for (let [cardResource, cardQuantity] of Object.entries(card.resourceCost)) {
|
|
let totalBuyingPower = getTotalBuyingPower(currentPlayer);
|
|
// iterate through each section of player's total buying power
|
|
for (let [heldResource, heldQuantity] of Object.entries(totalBuyingPower)) {
|
|
// match card resource to held quantity
|
|
if (cardResource === heldResource) {
|
|
let adjustedQuantity = heldQuantity;
|
|
// enter while loop if adjustedQuantity does not cover cost
|
|
while (adjustedQuantity < cardQuantity) {
|
|
// if there is no gold available to modify cost, card is too expensive
|
|
if (!availableGold) return true;
|
|
// else, add to the insufficient quantity and decrement available gold
|
|
adjustedQuantity++;
|
|
availableGold--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
export const buyCard = (state: AppState, setState: setStateType, card: CardData) => {
|
|
const currentPlayer = useCurrentPlayer(state);
|
|
if (!currentPlayer) return;
|
|
|
|
setState((prev) => {
|
|
// shift turn order and identify current player in new player state
|
|
const { newPlayers, roundIncrement } = turnOrderUtil(prev, currentPlayer);
|
|
const idx = newPlayers.indexOf(currentPlayer);
|
|
|
|
const newResourcePool = prev.gameboard.tradingResources;
|
|
const cardCost = card.resourceCost;
|
|
const updatedPlayer = newPlayers[idx];
|
|
const totalBuyingPower = getTotalBuyingPower(updatedPlayer);
|
|
|
|
let availableGold = updatedPlayer.inventory['gold'] || 0;
|
|
|
|
for (let key of Object.keys(totalBuyingPower)) {
|
|
const typedKey = key as keyof ResourceCost;
|
|
if (key === 'gold') continue;
|
|
if (cardCost[typedKey] === 0) continue;
|
|
|
|
let tempPlayerInventory = updatedPlayer.inventory[typedKey] || 0;
|
|
let tempResourcePool = newResourcePool[typedKey] || 0;
|
|
let cardCostPointer = cardCost[typedKey] || 0;
|
|
let goldToReturn = 0;
|
|
|
|
while (cardCostPointer > tempPlayerInventory && availableGold > 0) {
|
|
availableGold--;
|
|
goldToReturn++;
|
|
tempPlayerInventory++;
|
|
}
|
|
|
|
while (goldToReturn) {
|
|
goldToReturn--;
|
|
cardCostPointer--;
|
|
tempPlayerInventory--;
|
|
newResourcePool['gold'] && newResourcePool['gold']++;
|
|
}
|
|
|
|
while (cardCostPointer > 0) {
|
|
cardCostPointer--;
|
|
tempPlayerInventory--;
|
|
tempResourcePool++;
|
|
}
|
|
|
|
newResourcePool[typedKey] = tempResourcePool;
|
|
updatedPlayer.inventory[typedKey] = tempPlayerInventory;
|
|
updatedPlayer.inventory['gold'] = availableGold;
|
|
}
|
|
|
|
updatedPlayer.cards = { ...updatedPlayer.cards, [card.gemValue]: [...updatedPlayer.cards[card.gemValue as keyof PlayerCards], card] }
|
|
|
|
let reservedCardCheck = false;
|
|
// checks if current card was bought from reserved cards, removing it if so
|
|
if (updatedPlayer.reservedCards) {
|
|
let beforeLength = updatedPlayer.reservedCards.length;
|
|
updatedPlayer.reservedCards = updatedPlayer.reservedCards.filter((each: CardData) => each.resourceCost !== card.resourceCost);
|
|
let afterLength = updatedPlayer.reservedCards.length;
|
|
if (beforeLength !== afterLength) reservedCardCheck = true;
|
|
}
|
|
|
|
const typedCardTier = cardTierToKey(card.tier);
|
|
let newFullDeckTargetTier = prev.gameboard.deck[typedCardTier];
|
|
let newTargetCardRow = prev.gameboard.cardRows[typedCardTier];
|
|
|
|
if (!reservedCardCheck) {
|
|
const replacementCard = newFullDeckTargetTier.shift();
|
|
newTargetCardRow = newTargetCardRow.filter((data: CardData) => data.resourceCost !== card.resourceCost);
|
|
if (replacementCard) newTargetCardRow.push(replacementCard);
|
|
}
|
|
|
|
return {
|
|
...prev,
|
|
players: newPlayers,
|
|
round: (roundIncrement ? prev.round + 1 : prev.round),
|
|
actions: initialActions,
|
|
gameboard: {
|
|
...prev.gameboard,
|
|
tradingResources: newResourcePool,
|
|
cardRows: {
|
|
...prev.gameboard.cardRows,
|
|
[typedCardTier]: newTargetCardRow
|
|
},
|
|
deck: {
|
|
...prev.gameboard.deck,
|
|
[typedCardTier]: newFullDeckTargetTier
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
console.log(state.players);
|
|
|
|
// iterates through gameboard nobles to determine if any can be acquired
|
|
for (let noble of state.gameboard.nobles) {
|
|
const previousPlayer = usePreviousPlayer(state);
|
|
if (!previousPlayer) return;
|
|
|
|
if (canPickUpNoble(previousPlayer, noble)) {
|
|
setState((prev) => setStateGetNoble(prev, noble, previousPlayer));
|
|
}
|
|
}
|
|
}
|