|
|
|
@ -103,6 +103,165 @@ function drawACard(roomId, playerId){
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Rename and rejig the 3 play from hand functions
|
|
|
|
|
|
|
|
function playFromHand(roomId, playerId, position){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let cardId = null;
|
|
|
|
|
|
|
|
// Get the cardId of the card from position within players hand
|
|
|
|
|
|
|
|
for (const [key, value] of Object.entries(global.roomData[roomId].itemData.component.hand)) {
|
|
|
|
|
|
|
|
// Key is the entity here
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If the card in hand's position does not match the position passed, skip it
|
|
|
|
|
|
|
|
if(global.roomData[roomId].itemData.component.listPosition[key] != position){
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cardId = key;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Then play the card
|
|
|
|
|
|
|
|
if(cardId == null){
|
|
|
|
|
|
|
|
// TODO: Respond to player (who triggered play) that this
|
|
|
|
|
|
|
|
// is an 'illegal/errored' move via socket
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
playACardFromHand(roomId, playerId, cardId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function playACardFromHand(roomId, playerId, cardId){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add the card to field (and its effect to 'stack') or spell to the 'stack'
|
|
|
|
|
|
|
|
if(playACard(roomId, playerId, cardId, 'hand') !== true){
|
|
|
|
|
|
|
|
// TODO: Return socket to player about 'illegal move' and why
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If the card can be played/had been
|
|
|
|
|
|
|
|
// Reduce handSize by 1 for the player that played the card
|
|
|
|
|
|
|
|
global.roomData[roomId].itemData.component.cardCount.hand[playerId]--;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Send a socket response for 'played a card from hand' with cardData
|
|
|
|
|
|
|
|
// of said card. This is sent so that it can be 'chained' and added to the stack
|
|
|
|
|
|
|
|
// On play, it is put onto field/activated but the effect(s) don't occur until both/all
|
|
|
|
|
|
|
|
// players have a chance to 'chain', once the 'chain' is completed, the effect(s) trigger
|
|
|
|
|
|
|
|
global.socketResponsePlayFromHand(roomId, playerId, cardId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 'Play' a card is activation with cost (triggering play events)
|
|
|
|
|
|
|
|
// 'Summon' puts it onto the board without play events
|
|
|
|
|
|
|
|
// yada yada to think about in future
|
|
|
|
|
|
|
|
function playACard(roomId, playerId, cardId, playedFrom){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Play a unit
|
|
|
|
|
|
|
|
if(cardId in global.roomData[roomId].itemData.component.type.unit){
|
|
|
|
|
|
|
|
// Play to board. If there's a 'onPlay' effect, add that to the 'stack'
|
|
|
|
|
|
|
|
return playAUnit(roomId, playerId, cardId, playedFrom);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Cast a spell
|
|
|
|
|
|
|
|
if(cardId in global.roomData[roomId].itemData.component.type.spell){
|
|
|
|
|
|
|
|
// Add the card/effect onto the 'stack'. When complete/cancelled send to grave
|
|
|
|
|
|
|
|
return playASpell(roomId, playerId, cardId, playedFrom);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add a token
|
|
|
|
|
|
|
|
if(cardId in global.roomData[roomId].itemData.component.type.token){
|
|
|
|
|
|
|
|
// ???? Tokens maybe just onto other cards as 'equips' or as standalones? IDK
|
|
|
|
|
|
|
|
return playAToken(roomId, playerId, cardId, playedFrom);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function playAUnit(roomId, playerId, cardId, playedFrom){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log('playAUnit');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Costs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function playASpell(roomId, playerId, cardId, playedFrom){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log('playASpell');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Pay costs (Need to play mana first...)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: If spell has different effects, select which one/ensure
|
|
|
|
|
|
|
|
// correct one is used based on criteria
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add to stack (each part of the spells effect)
|
|
|
|
|
|
|
|
// TODO: Use actual effects, for now just adding a 'drawCard' for testing
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addToStack(roomId, playerId, cardId, null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function playAToken(roomId, playerId, cardId, playedFrom){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Not 100% sure how to implement the stack
|
|
|
|
|
|
|
|
// TODO: Make it better
|
|
|
|
|
|
|
|
// TODO: Make it do actual things, currently just adds 'drawCard' effect
|
|
|
|
|
|
|
|
function addToStack(roomId, playerId, cardId, effectId){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Stack does its own effect, or 'counter' etc. the card prior to it on the stack
|
|
|
|
|
|
|
|
// etc. etc.
|
|
|
|
|
|
|
|
// TODO: Add card effect to stack in reverse order OR have the stack work from x..0
|
|
|
|
|
|
|
|
// prolly the latter, makes sense to me
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let stack = global.roomData[roomId].itemData.component.stack;
|
|
|
|
|
|
|
|
let stackLength = Object.keys(stack).length;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: First ensure the cardEffects are added in their step order 1..x
|
|
|
|
|
|
|
|
// Add as next event in the stack 1..x
|
|
|
|
|
|
|
|
// TODO: Use actual effect, not just 'draw' as that's just for testing
|
|
|
|
|
|
|
|
global.roomData[roomId].itemData.component.stack[stackLength + 1] =
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
'cardId': cardId
|
|
|
|
|
|
|
|
,'effect': null
|
|
|
|
|
|
|
|
,'effectStep': null
|
|
|
|
|
|
|
|
,'targetCard': null
|
|
|
|
|
|
|
|
,'targetPlayer': playerId
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(global.roomData[roomId].itemData.component.stack);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: TEMP, this will need to wait for a 'resolve' accept from both players before the stack
|
|
|
|
|
|
|
|
// would trigger.
|
|
|
|
|
|
|
|
resolveStack(roomId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function resolveStack(roomId){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Does the next effect in the stack, if something
|
|
|
|
|
|
|
|
// is to chain onto the stack that would instead trigger
|
|
|
|
|
|
|
|
// 'addToStack' after paying any costs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If there is anything in the stack
|
|
|
|
|
|
|
|
let stackLength = Object.keys(global.roomData[roomId].itemData.component.stack).length;
|
|
|
|
|
|
|
|
if(stackLength > 0){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Trigger the last (most recently added to) the stack effect
|
|
|
|
|
|
|
|
// THIS WILL NOW ACTUALLY CAST THE EFFECT STEP WITHOUT INTERRUPT
|
|
|
|
|
|
|
|
// While the stack is being resolved their are no counters/chains until
|
|
|
|
|
|
|
|
// the next stack action which players will get option to chain or not again
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
|
|
global.roomData[roomId].itemData.component.stack[stackLength]
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Shuffle the deck 'randomly' for a certain player
|
|
|
|
// Shuffle the deck 'randomly' for a certain player
|
|
|
|
function shuffleDeck(roomId, playerId){
|
|
|
|
function shuffleDeck(roomId, playerId){
|
|
|
|
|
|
|
|
|
|
|
|
@ -191,5 +350,6 @@ module.exports = {
|
|
|
|
,getPlayerHandData
|
|
|
|
,getPlayerHandData
|
|
|
|
,drawACard
|
|
|
|
,drawACard
|
|
|
|
,shuffleDeck
|
|
|
|
,shuffleDeck
|
|
|
|
|
|
|
|
,playFromHand
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|