diff --git a/components.js b/components.js
index db55f8b..c39e3e8 100644
--- a/components.js
+++ b/components.js
@@ -29,6 +29,7 @@ const component = {
tapped : {},
attacking : {},
inspected : {},
+ targetable : {},
},
cardAttack : {},
cardColours : {}, // Replace with colour
diff --git a/gameHelper.js b/gameHelper.js
index 1c7e150..d607a48 100644
--- a/gameHelper.js
+++ b/gameHelper.js
@@ -47,8 +47,46 @@ function moveElementPositions(roomId, player, direction, element, position){
}
+function canAttack(roomId, playerId, cardId){
+
+ if(cardId in global.roomData[roomId].itemData.component.cardStatus.tapped){
+ return false;
+ }
+
+ return true;
+
+}
+function getTargetableCards(roomId, playerId, cardId){
+
+ // i.e. If no flight/reach, you cant attack flight, if not all shield tapped, cant attack tapped shield
+ // TODO: The above, for now just letting all units/shields targetable
+
+ let targetable = {};
+ // Board
+ for (const [key, value] of Object.entries(global.roomData[roomId].itemData.component.board)) {
+ // If not the players card (for now, will need better checks in future)
+ if(global.roomData[roomId].itemData.player[key] !== playerId){
+ targetable[key] = key;
+ }
+ }
+ // Shield
+ for (const [key, value] of Object.entries(global.roomData[roomId].itemData.component.shield)) {
+ // If not the players card (for now, will need better checks in future)
+ if(global.roomData[roomId].itemData.player[key] !== playerId){
+ //if(!(key in global.roomData[roomId].itemData.player[playerId])){
+ targetable[key] = key;
+ }
+ }
+
+ console.log(targetable);
+ return targetable;
+
+}
+
module.exports = {
- setCardPosition
+ setCardPosition
+ ,canAttack
+ ,getTargetableCards
};
diff --git a/gameMod.js b/gameMod.js
index 50c7eda..74c749f 100644
--- a/gameMod.js
+++ b/gameMod.js
@@ -539,6 +539,27 @@ function untapCard(roomId, playerId, cardId){
}
+function startAttack(roomId, playerId, cardId){
+
+ console.log('start attack');
+ if(!gameHelper.canAttack){
+ return false;
+ }
+
+ // Set the card to 'attacking'
+ global.roomData[roomId].itemData.component.cardStatus.attacking[cardId] = cardId;
+
+ // TODO: Maybe set targetable as component and return that
+ global.roomData[roomId].itemData.component.cardStatus.targetable = gameHelper.getTargetableCards(roomId, playerId, cardId);
+
+ // Return the available targets (give them a border in UI)
+ global.socketResponseUpdateTargetable(roomId, playerId,
+ global.roomData[roomId].itemData.component.cardStatus.targetable
+ );
+
+}
+
+
// DATA RETURNER DUDES
// TODO: Where to put this? Kind of a helper, kind of functionality. Hmmmmm
// maybe do a dataHelper? then anything to return data can be included there?
@@ -599,6 +620,7 @@ module.exports = {
,playManaFromHand
,acceptResolveStack
,gameStart
+ ,startAttack
// TEMP
,tapCard
,untapCard
diff --git a/public/index.html b/public/index.html
index adde21e..cdd5a5f 100644
--- a/public/index.html
+++ b/public/index.html
@@ -22,6 +22,7 @@
+
diff --git a/public/js/canvas/draw.js b/public/js/canvas/draw.js
index 286280b..6f09840 100644
--- a/public/js/canvas/draw.js
+++ b/public/js/canvas/draw.js
@@ -350,13 +350,15 @@ function drawCardInHand(entity){
// TODO: Change card colour based on its colours
// Draw the card shape
+ let strokeStyle = '#AAA';
+ if(entity in gameData.cardStatus.targetable){ strokeStyle = '#222'; }
let shape = new Shape({
x: gameData.position[entity][0],
y: gameData.position[entity][1],
width: gameData.size[entity][0],
height: gameData.size[entity][1],
fillStyle: '#EEE',
- strokeStyle: '#AAA',
+ strokeStyle: strokeStyle,
});
shape.draw();
@@ -370,7 +372,9 @@ function drawCardOnBoard(entity){
// TODO: Passives, flight, etc. effects
let strokeStyle = '#AAA';
- if(entity in gameData.cardStatus.tapped){ strokeStyle = '#555'; }
+ if(entity in gameData.cardStatus.tapped){ strokeStyle = '#6D0202'; }
+ if(entity in gameData.cardStatus.targetable){ strokeStyle = '#FF9A00'; }
+ if(entity in gameData.cardStatus.targetted){ strokeStyle = '#EC5300'; }
// Draw the card shape
let shape = new Shape({
x: gameData.position[entity][0],
@@ -392,6 +396,7 @@ function drawShield(entity){
let strokeStyle = '#AAA';
if(entity in gameData.cardStatus.tapped){ strokeStyle = '#555'; }
+ if(entity in gameData.cardStatus.targetable){ strokeStyle = '#222'; }
// Draw the card shape
let shape = new Shape({
x: gameData.position[entity][0],
@@ -416,6 +421,7 @@ function drawMana(entity){
let strokeStyle = '#AAA';
if(entity in gameData.cardStatus.tapped){ strokeStyle = '#555'; }
+ if(entity in gameData.cardStatus.targetable){ strokeStyle = '#222'; }
// Draw the card shape
let shape = new Shape({
x: gameData.position[entity][0],
diff --git a/public/js/canvas/interactionMenu.js b/public/js/canvas/interactionMenu.js
index 0ad0d25..992151e 100644
--- a/public/js/canvas/interactionMenu.js
+++ b/public/js/canvas/interactionMenu.js
@@ -35,6 +35,18 @@ function openInteractionMenu(entity){
// Interact
// Attack
+ // Start Attack
+ if(entity in gameData.board && !(entity in gameData.cardStatus.tapped)){
+
+ // TODO: Make the object within each interationOption a function to return instead of duping
+ gameData.interactionOption['Attack'] = {
+ x: gameData.position[entity][0] + gameData.size[entity][0]*.1/2,
+ y: gameData.position[entity][1] + gameData.size[entity][1] - (35 * (Object.entries(gameData.interactionOption).length + 1)),
+ width: gameData.size[entity][0]*.9,
+ height: 30
+ }
+ }
+ // Target Attack Target
// Tap
// TAP (TEMP TODO: remove or add in a statement to hide)
@@ -77,6 +89,28 @@ function openInteractionMenu(entity){
}
+ // If selectable, give option to select. If selected, deselect
+ if(gameData.cardStatus.targetable[entity] !== undefined){
+
+ gameData.interactionOption['Target'] = {
+ x: gameData.position[entity][0] + gameData.size[entity][0]*.1/2,
+ y: gameData.position[entity][1] + gameData.size[entity][1] - (35 * (Object.entries(gameData.interactionOption).length + 1)),
+ width: gameData.size[entity][0]*.9,
+ height: 30
+ }
+
+ }
+ if(gameData.cardStatus.targetable[entity] !== undefined && gameData.cardStatus.targetted[entity] !== undefined){
+
+ gameData.interactionOption['Untarget'] = {
+ x: gameData.position[entity][0] + gameData.size[entity][0]*.1/2,
+ y: gameData.position[entity][1] + gameData.size[entity][1] - (35 * (Object.entries(gameData.interactionOption).length + 1)),
+ width: gameData.size[entity][0]*.9,
+ height: 30
+ }
+
+ }
+
drawGameBoard();
}
@@ -117,6 +151,19 @@ function doiMenuPressed(iMenuKey){
iMenuUntap();
}
+ // Attack
+ // Start Attack (Card that's to attack)
+ if(iMenuKey == 'Attack'){
+ iMenuStartAttack();
+ }
+
+ // Target
+ if(iMenuKey == 'Target'){
+ iMenuTarget();
+ }
+ if(iMenuKey == 'Untarget'){
+ iMenuUntarget();
+ }
}
function iMenuPlayToBoard(){
@@ -143,4 +190,16 @@ function iMenuUntap(){
console.log(Object.keys(gameData.inInteractionMenu)[0]);
requestUntapCard(gameData.inInteractionMenu[Object.keys(gameData.inInteractionMenu)[0]]);
}
+function iMenuStartAttack(){
+ requestStartAttack(Object.keys(gameData.inInteractionMenu)[0]);
+}
+function iMenuTarget(){
+ gameData.cardStatus.targetted[Object.keys(gameData.inInteractionMenu)[0]] = Object.keys(gameData.inInteractionMenu)[0];
+ clearInteractionMenu(); // Clears and redraws the board
+ console.log('target');
+}
+function iMenuUntarget(){
+ delete(gameData.cardStatus.targetted[Object.keys(gameData.inInteractionMenu)[0]]);
+ console.log('UNtarget');
+}
diff --git a/public/js/game/components.js b/public/js/game/components.js
index c7f874c..eae0173 100644
--- a/public/js/game/components.js
+++ b/public/js/game/components.js
@@ -34,6 +34,8 @@ let gameData = {
tapped : {},
attacking : {},
inspected : {},
+ targetable : {},
+ targetted : {},
},
diff --git a/public/js/game/dataUpdate.js b/public/js/game/dataUpdate.js
index df9324d..ba35e2b 100644
--- a/public/js/game/dataUpdate.js
+++ b/public/js/game/dataUpdate.js
@@ -104,6 +104,13 @@ function updateTapped(data){
gameData.cardStatus.tapped = data;
console.log(gameData.cardStatus.tapped);
}
+// Targetable
+function updateTargetable(data){
+ console.log(data);
+ // Clear targetable if null returned
+ if(data == null){ gameData.cardStatus.targetable = {}; }
+ gameData.cardStatus.targetable = data;
+}
// To prevent typical functionality (draw, etc.)
// if there's a stack in play.
diff --git a/public/js/game/socket.js b/public/js/game/socket.js
index 4d525c7..f0a3c9f 100644
--- a/public/js/game/socket.js
+++ b/public/js/game/socket.js
@@ -121,6 +121,19 @@ socket.on('responseUntapped', function (data) {
});
+function requestStartAttack(card){
+ console.log('>> startAttack');
+ socket.emit('requestStartAttack', gameData.roomId, gameData.playerId, card);
+}
+socket.on('responseTargetable', function (data) {
+ // The playerId that played it for animations
+ console.log('<< responseTargetable');
+ console.log(data);
+ updateTargetable(data);
+ drawGameBoard();
+});
+
+
// Stack
socket.on('responseAddToStack', function (data) {
console.log('<< addToStack');
@@ -148,7 +161,6 @@ function requestResolveStack(){
socket.emit('requestResolveStack', gameData.roomId, gameData.playerId);
}
-
// Functions like this would be elsewhere, do client-side
// validation THEN request stuff from the server?
// This is here for now, as it's used by the button
diff --git a/server.js b/server.js
index eed3f07..b7c079f 100644
--- a/server.js
+++ b/server.js
@@ -84,6 +84,10 @@ function onConnection(socket){
gameMod.untapCard(roomId, playerId, card);
});
+ socket.on('requestStartAttack', function(roomId, playerId, card) {
+ gameMod.startAttack(roomId, playerId, card);
+ });
+
}
global.getPlayerSocketFromRoom = function(playerId, roomId){
@@ -246,6 +250,22 @@ global.socketResponseUntapped = function(roomId, card){
global.sendToEachSocket(roomId, 'responseUntapped', data);
}
+
+/*
+global.socketResponseStartAttack = function(roomId, playerId, targetable){
+ global.socketResponseUpdateTargetable(roomId, playerId, targetable);
+}
+*/
+global.socketResponseUpdateTargetable = function(roomId, playerId, targetable){
+
+ global.io.to(global.getPlayerSocketFromRoom(playerId, roomId)).emit(
+ 'responseTargetable'
+ ,targetable
+ );
+
+}
+// Attack (return the attacking and 'defending' card and allow for interactions/stack
+
// Stack
global.socketResponseAddToStack = function(roomId){
global.sendToEachSocket(roomId, 'responseAddToStack', 'testData');