Merge branch 'feature/basicEffects' into develop
commit
71b3451bf7
@ -0,0 +1,124 @@
|
||||
CREATE TABLE IF NOT EXISTS `basic_effect` (
|
||||
`id` smallint(6) NOT NULL AUTO_INCREMENT,
|
||||
`effectName` tinytext DEFAULT NULL,
|
||||
`effectDescription` varchar(250) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `basic_effect` (`id`, `effectName`, `effectDescription`) VALUES
|
||||
(1, 'Equip', 'Add this cards attack, and effect(s) to another'),
|
||||
(2, 'Heal', 'Untap X shield(s)'),
|
||||
(3, 'Hurt', 'Deal X damage to target unit, this combat'),
|
||||
(4, 'Recruit', 'Play from Hand'),
|
||||
(5, 'Give Flight', 'Give a unit [Flight]');
|
||||
|
||||
|
||||
DROP TABLE `card_effect`;
|
||||
CREATE TABLE IF NOT EXISTS `card_effect` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`cardId` int(11) DEFAULT NULL,
|
||||
`effectId` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `card_effect` (`id`, `cardId`, `effectId`) VALUES
|
||||
(1, 1, 1);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `card_passive` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`cardId` int(11) DEFAULT NULL,
|
||||
`passiveId` tinyint(4) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
|
||||
DROP TABLE `effect`;
|
||||
CREATE TABLE IF NOT EXISTS `effect` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`description` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `effect` (`id`, `description`) VALUES
|
||||
(1, '(Tap and Pay 1 Red): [Recruit] a [Red][Orc] unit; Give it [Flight] this turn.');
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `effect_step` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`effectId` int(11) DEFAULT NULL,
|
||||
`stepOrder` tinyint(4) DEFAULT NULL,
|
||||
`basicEffectId` tinyint(4) DEFAULT NULL,
|
||||
`amount` smallint(6) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `effect_step` (`id`, `effectId`, `stepOrder`, `basicEffectId`, `amount`) VALUES
|
||||
(1, 1, 1, 4, 1),
|
||||
(2, 1, 2, 5, 1);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `effect_step_target` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`effectStep` int(11) DEFAULT NULL,
|
||||
`colourId` tinyint(4) DEFAULT NULL,
|
||||
`typeId` tinyint(4) DEFAULT NULL,
|
||||
`classId` tinyint(4) DEFAULT NULL,
|
||||
`passiveId` tinyint(4) DEFAULT NULL,
|
||||
`itemFromStep` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `effect_step_target` (`id`, `effectStep`, `colourId`, `typeId`, `classId`, `passiveId`, `itemFromStep`) VALUES
|
||||
(1, 1, 3, 1, 5, NULL, NULL),
|
||||
(2, 2, NULL, NULL, NULL, NULL, 1);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `effect_trigger` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`triggerTypeId` int(11) DEFAULT NULL,
|
||||
`cardEffectId` int(11) DEFAULT NULL,
|
||||
`amount` smallint(6) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `effect_trigger` (`id`, `triggerTypeId`, `cardEffectId`, `amount`) VALUES
|
||||
(1, 1, 1, NULL),
|
||||
(2, 2, 1, 1);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `effect_trigger_target` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`effectTriggerId` int(11) DEFAULT NULL,
|
||||
`colourId` tinyint(4) DEFAULT NULL,
|
||||
`typeId` tinyint(4) DEFAULT NULL,
|
||||
`classId` tinyint(4) DEFAULT NULL,
|
||||
`passiveId` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `effect_trigger_target` (`id`, `effectTriggerId`, `colourId`, `typeId`, `classId`, `passiveId`) VALUES
|
||||
(1, 2, 3, NULL, NULL, NULL);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `passive` (
|
||||
`id` tinyint(4) NOT NULL AUTO_INCREMENT,
|
||||
`passiveName` varchar(50) DEFAULT NULL,
|
||||
`passiveDescription` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `passive` (`id`, `passiveName`, `passiveDescription`) VALUES
|
||||
(1, 'Flight', 'Ignore taunt, unattackable by non-[Flight] units'),
|
||||
(2, 'Reach', 'Can attack [Flight] units');
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `trigger_type` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(50) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
INSERT INTO `trigger_type` (`id`, `name`) VALUES
|
||||
(1, 'Tap'),
|
||||
(2, 'Pay');
|
||||
@ -0,0 +1,3 @@
|
||||
INSERT INTO `card_passive` (`id`, `cardId`, `passiveId`) VALUES (1, 1, 1);
|
||||
INSERT INTO `card_passive` (`id`, `cardId`, `passiveId`) VALUES (2, 5, 2);
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
INSERT INTO `passive` (`id`, `passiveName`, `passiveDescription`) VALUES (3, 'Taunt', 'Must be targetted by attacks');
|
||||
|
||||
@ -0,0 +1,207 @@
|
||||
// For front-end debugging
|
||||
// Anything to be tested that would otherwise need server logs, etc.
|
||||
// should go here
|
||||
|
||||
function debugEffect(){
|
||||
|
||||
let damageAmount = document.getElementById("effectDamageAmount").value;
|
||||
if(damageAmount == ""){ damageAmount = null; }
|
||||
|
||||
let targetId = document.getElementById("effectTargetId").value;
|
||||
if(targetId == ""){ targetId = null; }
|
||||
|
||||
let targetId2 = document.getElementById("effectTargetId2").value;
|
||||
if(targetId2 == ""){ targetId2 = null; }
|
||||
|
||||
let targetPlayer = document.getElementById("effectTargetPlayer").value;
|
||||
if(targetPlayer == ""){ targetPlayer = null; }
|
||||
|
||||
let effectAddRemove = document.getElementById("effectAddRemove").value;
|
||||
if(effectAddRemove == ""){ effectAddRemove = null; }
|
||||
|
||||
let effect = document.getElementById("effect").value;
|
||||
if(effect == ""){ effect = null; }
|
||||
|
||||
debugEffectFunction(damageAmount, targetId, targetId2, targetPlayer, effectAddRemove, effect);
|
||||
|
||||
}
|
||||
|
||||
function debugEffectFunction(damageAmount = null, targetId = null, targetId2 = null, targetPlayer = null, effectAddRemove = null, effect = null){
|
||||
|
||||
if(effect == 'hurt'){
|
||||
hurt(damageAmount, targetId, targetPlayer);
|
||||
}
|
||||
if(effect == 'heal'){
|
||||
heal(damageAmount, targetPlayer);
|
||||
}
|
||||
if(effect == 'flight'){
|
||||
console.log(targetId+' Flight: '+flight[targetId]);
|
||||
|
||||
console.log(effectAddRemove);
|
||||
|
||||
if(effectAddRemove == 'remove'){
|
||||
removeFlight(targetId);
|
||||
}else{
|
||||
giveFlight(targetId);
|
||||
}
|
||||
|
||||
console.log(targetId+' Flight: '+flight[targetId]);
|
||||
}
|
||||
if(effect == 'reach'){
|
||||
console.log(targetId+' Reach: '+reach[targetId]);
|
||||
|
||||
console.log(effectAddRemove);
|
||||
|
||||
if(effectAddRemove == 'remove'){
|
||||
removeReach(targetId);
|
||||
}else{
|
||||
giveReach(targetId);
|
||||
}
|
||||
|
||||
console.log(targetId+' Reach: '+reach[targetId]);
|
||||
}
|
||||
if(effect == 'taunt'){
|
||||
console.log(targetId+' Taunt: '+taunt[targetId]);
|
||||
|
||||
console.log(effectAddRemove);
|
||||
|
||||
if(effectAddRemove == 'remove'){
|
||||
removeTaunt(targetId);
|
||||
}else{
|
||||
giveTaunt(targetId);
|
||||
}
|
||||
|
||||
console.log(targetId+' Taunt: '+reach[targetId]);
|
||||
}
|
||||
if(effect == 'draw'){
|
||||
drawCard(damageAmount, targetPlayer);
|
||||
}
|
||||
if(effect == 'equip'){}
|
||||
|
||||
board.drawBoard();
|
||||
}
|
||||
|
||||
|
||||
function debugTrigger(){
|
||||
let targetId = document.getElementById("triggerTargetId").value;
|
||||
if(targetId == ""){ targetId = null; }
|
||||
|
||||
let trigger = document.getElementById("trigger").value;
|
||||
if(trigger == ""){ trigger = null; }
|
||||
|
||||
let triggerAmount = document.getElementById("triggerAmount").value;
|
||||
if(triggerAmount == ""){ triggerAmount = null; }
|
||||
|
||||
debugTriggerFunction(targetId, trigger, triggerAmount);
|
||||
}
|
||||
function debugTriggerFunction(targetId = null, trigger = null, triggerAmount = null){
|
||||
|
||||
if(targetId == null){ return false; }
|
||||
|
||||
if(trigger == 'tap'){
|
||||
triggerTap(targetId);
|
||||
}
|
||||
if(trigger == 'pay'){
|
||||
triggerPay(triggerAmount);
|
||||
}
|
||||
|
||||
board.drawBoard();
|
||||
}
|
||||
|
||||
// Builds console log for card effect (inc.
|
||||
// all triggers, etc)
|
||||
function debugGetCardEffects(itemKey){
|
||||
|
||||
let effectData = cardEffect[itemKey];
|
||||
console.log(effectData);
|
||||
if(effectData === undefined){ return false; }
|
||||
|
||||
effectData.forEach((effect, effectIndex) => {
|
||||
|
||||
console.log('--- Effect '+ effectIndex +' ---');
|
||||
console.log(effect['description']);
|
||||
|
||||
// Loop the triggers
|
||||
for (const [key, value] of Object.entries(effect['trigger'])) {
|
||||
|
||||
console.log('--- Trigger ---');
|
||||
let effectTrigger = effect['trigger'][key];
|
||||
console.log(triggerTypes[effectTrigger['triggerTypeId']]);
|
||||
|
||||
console.log('--- Trigger Amount ---');
|
||||
console.log(effectTrigger['amount']);
|
||||
|
||||
// Loop targets for said trigger
|
||||
effectTrigger['target'].forEach((effectTriggerTarget) => {
|
||||
console.log('--- Trigger Target ---');
|
||||
console.log(effectTriggerTarget.classId);
|
||||
console.log(effectTriggerTarget.colourId);
|
||||
console.log(effectTriggerTarget.passiveId);
|
||||
console.log(effectTriggerTarget.typeId);
|
||||
});
|
||||
}
|
||||
|
||||
// Loop the effects
|
||||
for (const [key, value] of Object.entries(effect['step'])) {
|
||||
// amoutn, basicEffectId, stepOrder, target (also itemfromstep)
|
||||
console.log(effect['step'][key]);
|
||||
|
||||
console.log('--- Effect Step ---');
|
||||
let effectStep = effect['step'][key];
|
||||
console.log(basicEffects[effectStep['basicEffectId']]);
|
||||
|
||||
console.log('--- Effect Step Amount ---');
|
||||
console.log(effectStep['amount']);
|
||||
|
||||
// Loop targets for effectStep
|
||||
effectStep['target'].forEach((effectStepTarget) => {
|
||||
console.log('--- Effect Step Target ---');
|
||||
console.log(effectStepTarget.classId);
|
||||
console.log(effectStepTarget.colourId);
|
||||
console.log(effectStepTarget.passiveId);
|
||||
console.log(effectStepTarget.typeId);
|
||||
console.log(effectStepTarget.itemFromStep);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function debugEffectCanTrigger(){
|
||||
|
||||
let ecTriggerTargetId = document.getElementById("ecTriggerTargetId").value;
|
||||
if(ecTriggerTargetId == ""){ ecTriggerTargetId = null; }
|
||||
|
||||
let ecTriggerIndex = document.getElementById("ecTriggerIndex").value;
|
||||
if(ecTriggerIndex == ""){ ecTriggerIndex = 0; }
|
||||
|
||||
let ecDoTrigger = document.getElementById("ecDoTrigger").value;
|
||||
if(ecDoTrigger == ""){ ecDoTrigger = 0; }
|
||||
|
||||
if(doEffectTriggers(ecTriggerTargetId, ecTriggerIndex, true) != true){
|
||||
console.log('Effect cannot be triggered');
|
||||
//queueEffect(ecTriggerTargetId, ecTriggerIndex);
|
||||
//doNextInQueue();
|
||||
//loopTriggerQueue();
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('Effect CAN be triggered');
|
||||
|
||||
if(ecDoTrigger){
|
||||
// Do everything needed in triggers
|
||||
doEffectTriggers(ecTriggerTargetId, ecTriggerIndex);
|
||||
|
||||
// Then queue the effects to happen (queued so they can be chained/countered)
|
||||
queueEffect(ecTriggerTargetId, ecTriggerIndex);
|
||||
|
||||
// Do all effects in queue (for debug), in actual will do one, then allow chain triggers, etc.
|
||||
loopTriggerQueue();
|
||||
}
|
||||
|
||||
board.drawBoard();
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,680 @@
|
||||
// Theorising, if this is what's wanted then will need doing for everything
|
||||
// not just in effects. eg. 'attack', 'effect1p1', 'flip', yadda yadda
|
||||
let triggerQueue = [];
|
||||
let triggerId = 1; // So any other effects, etc. queued for a destroyed card can be removed at once
|
||||
let triggerDone = []; // The triggers that have completed
|
||||
let triggerQueueTargets = []; // Whatever was targetted by the effect, etc. in triggerQueue (for ref by effectStep, etc)
|
||||
|
||||
// Passive effects (just does stuff)
|
||||
let flight = {};
|
||||
let reach = {};
|
||||
let taunt = {};
|
||||
let equipped = {}; // Entity x has [a,b,c] equipped to it
|
||||
|
||||
|
||||
// Events (when these occur check if this is part of an effect trigger)
|
||||
// startOfGame, startOfTurn, endOfTurn
|
||||
// cardSummoned, cardRecruited, effectTriggered
|
||||
// etc.
|
||||
|
||||
|
||||
// Trigger types
|
||||
const triggerTypes = {
|
||||
'tap': 1,
|
||||
'pay': 2,
|
||||
};
|
||||
// Basic effects
|
||||
// TODO: Pull display name/description from DB?
|
||||
const basicEffects = {
|
||||
1: 'Equip',
|
||||
2: 'Heal',
|
||||
3: 'Hurt',
|
||||
4: 'Recruit',
|
||||
5: 'Give Flight',
|
||||
6: 'Taunt',
|
||||
};
|
||||
|
||||
|
||||
// Actives to add passives
|
||||
function giveFlight(card){
|
||||
flight[card] = true;
|
||||
}
|
||||
function removeFlight(card){
|
||||
// If the card has flight delete entity component
|
||||
if(card in flight){
|
||||
delete flight[card];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function giveReach(card){
|
||||
reach[card] = true;
|
||||
}
|
||||
function removeReach(card){
|
||||
if(card in reach){
|
||||
delete reach[card];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function giveTaunt(card){
|
||||
taunt[card] = true;
|
||||
}
|
||||
function removeTaunt(card){
|
||||
// If the card has flight delete entity component
|
||||
if(card in taunt){
|
||||
delete taunt[card];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Active
|
||||
function equip(){
|
||||
// Equip card to another unit
|
||||
|
||||
}
|
||||
function unequip(){
|
||||
// Remove card from its equipped to unit
|
||||
|
||||
}
|
||||
|
||||
function drawCard(drawAmount, player){
|
||||
board.drawACard(player, drawAmount);
|
||||
}
|
||||
|
||||
function heal(healAmount, healPlayer){
|
||||
// For each heal 1..4
|
||||
for(let i = 0; i < healAmount; i++){
|
||||
// Loop shield
|
||||
let items = this.getItems('shield', healPlayer, null, null);
|
||||
for(let item = 0; item < items.length; item++){
|
||||
|
||||
let itemKey = items[item];
|
||||
// If a shield is tapped, untap it to 'heal'
|
||||
if(board.isTapped(itemKey)){
|
||||
board.untapCard(itemKey);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hurt(hurtDamage, hurtTarget = null, hurtPlayer = null){
|
||||
// Deal X000 damage to unit this turn, or deal Y to opponent's shield
|
||||
|
||||
// Set player/element
|
||||
if(hurtPlayer == null && hurtTarget != null){
|
||||
hurtPlayer = player[hurtTarget];
|
||||
hurtElement = boardElement[hurtTarget];
|
||||
}else{
|
||||
hurtElement = 'shield'
|
||||
}
|
||||
|
||||
switch(hurtElement){
|
||||
case 'board':
|
||||
// TODO: Make temp damage this turn as well
|
||||
if(hurtDamage >= cardAttack[hurtTarget][0]){
|
||||
board.sendToGrave(hurtTarget);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'shield':
|
||||
let destroyCount = cardAttackToShieldDamage(hurtDamage);
|
||||
console.log(destroyCount);
|
||||
// TODO: loop player's shield, tap if they can be tapped, destroy
|
||||
// if all already tapped
|
||||
|
||||
// While there's still damage to deal
|
||||
while(destroyCount > 0){
|
||||
|
||||
// Keep looping through the shield belonging to target user
|
||||
let items = board.getItems('shield', hurtPlayer, null, null);
|
||||
let tappedItems = board.getItems('shield', hurtPlayer, 'tapped', null);
|
||||
|
||||
for(let item = 0; item < items.length; item++){
|
||||
|
||||
// If nothing more to destroy, exit loop
|
||||
if(destroyCount <= 0){ break; }
|
||||
|
||||
let itemKey = items[item];
|
||||
console.log(itemKey);
|
||||
console.log(cardStatus[itemKey]);
|
||||
|
||||
// If there's anything to tap, tap it
|
||||
if(cardStatus[itemKey] == null){
|
||||
console.log('been tapped');
|
||||
board.tapCard(itemKey);
|
||||
destroyCount--;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there's nothing to tap, destroy it
|
||||
if(items.length == tappedItems.length){
|
||||
console.log('been destroyed');
|
||||
board.destroyShield(itemKey);
|
||||
destroyCount--;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
board.drawBoard();
|
||||
break; // end case 'shield'
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Effect Trigger(s)
|
||||
// Non-event triggers. i.e. these are activated triggers
|
||||
// rather than things such as 'On attack', 'When opponent draws'
|
||||
|
||||
// When card has been actively tapped
|
||||
function triggerTap(card){
|
||||
if(canTriggerTap(card) == false){ return false; }
|
||||
|
||||
board.tapCard(card);
|
||||
|
||||
console.log('triggerTap');
|
||||
return true;
|
||||
|
||||
}
|
||||
// Check a card can actively be tapped, otherwise don't start trigger
|
||||
function canTriggerTap(card){
|
||||
if(board.isTapped(card)){
|
||||
return false;
|
||||
}
|
||||
if(boardElement[card] != 'board'){
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('can triggerTap');
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pay the mana cost(s) to trigger event
|
||||
function triggerPay(triggerAmount){
|
||||
if(canTriggerPay(triggerAmount) == false){
|
||||
return false;
|
||||
}
|
||||
|
||||
let effectCosts = [{1:0,2:0,3:0,4:0}, triggerAmount];
|
||||
board.tapManaRequired(null, 0, false, effectCosts);
|
||||
|
||||
console.log('triggerPay');
|
||||
return true;
|
||||
|
||||
}
|
||||
// Check the mana cost(s) can be paid, otherwise don't start trigger
|
||||
function canTriggerPay(triggerAmount){
|
||||
// For player0 only at the mo. and with no specific colour costs
|
||||
let effectCosts = [{1:0,2:0,3:0,4:0}, triggerAmount];
|
||||
if(board.tapManaRequired(null, 0, true, effectCosts) == false){
|
||||
console.log('cannot trigger pay');
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('Can trigger pay');
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// Pay/Activate (all) the triggers
|
||||
function doEffectTriggers(itemKey, effectIndex, checkOnly = false){
|
||||
|
||||
// Check card has effectData
|
||||
let effectData = cardEffect[itemKey];
|
||||
if(effectData === undefined){ return false; } // No effect
|
||||
|
||||
// Check effectData contains target effect
|
||||
let effect = effectData[effectIndex];
|
||||
if(effect === undefined){ return false; } // No effect
|
||||
|
||||
// Loop each trigger, AND activate them
|
||||
for (const [key, value] of Object.entries(effect['trigger'])) {
|
||||
|
||||
let effectTrigger = effect['trigger'][key];
|
||||
console.log('--- Trigger '+key+' ---');
|
||||
console.log(effectTrigger['triggerTypeId']);
|
||||
|
||||
// TAP TRIGGER
|
||||
if(effectTrigger['triggerTypeId'] == triggerTypes.tap){
|
||||
if(canTriggerTap(itemKey) == false){
|
||||
console.log('Tap trigger, cannot be triggered');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do the trigger, then continue to next trigger
|
||||
if(!checkOnly){board.tapCard(itemKey);}
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// PAY TRIGGER
|
||||
if(effectTrigger['triggerTypeId'] == triggerTypes.pay){
|
||||
|
||||
// To build the colourReq TODO: Change as could be 1 of either red/blue
|
||||
// for instance
|
||||
let colourReq = {1:0,2:0,3:0,4:0};
|
||||
|
||||
// Loop pay required (colours) for said trigger
|
||||
// BUILD the colourReq loop needed for tapMana check
|
||||
effectTrigger['target'].forEach((effectTriggerTarget) => {
|
||||
|
||||
// Increment colourReq by one of that colour
|
||||
// THIS WILL NEED REDOING, AS MAYBE IT'S 2 OF RED OR BLUE!!
|
||||
colourReq[effectTriggerTarget.colourId]++;
|
||||
|
||||
});
|
||||
|
||||
// Check if the cost (and colour req.) can be paid
|
||||
canPay = board.tapManaRequired(null, null, true, [colourReq, effectTrigger['amount']]);
|
||||
if(canPay !== true){
|
||||
console.log('Pay trigger, cannot be triggered');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Pay trigger costs, then continue to next trigger
|
||||
if(!checkOnly){
|
||||
board.tapManaRequired(null, null, false, [colourReq, effectTrigger['amount']]);
|
||||
}
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
// OTHER TRIGGERS
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function activateEffect(){
|
||||
// Do effect triggers, then doEffect once payed
|
||||
}
|
||||
|
||||
function getEffect(itemKey, effectIndex){
|
||||
// Check card has effectData
|
||||
let effectData = cardEffect[itemKey];
|
||||
if(effectData === undefined){ return false; } // No effect
|
||||
|
||||
// Check effectData contains target effect
|
||||
let effect = effectData[effectIndex];
|
||||
if(effect === undefined){ return false; } // No effect
|
||||
|
||||
return effect;
|
||||
}
|
||||
// Get all the targets for effect step, so they can be targgeted
|
||||
// by the effect/selected by the player
|
||||
function getEffectStepTargets(itemKey, effectIndex, effectStep, fromBoardElement, playerId, effectTriggerId = null){
|
||||
|
||||
// Get Effect
|
||||
let effect = getEffect(itemKey, effectIndex);
|
||||
if(effect == false){ return false; }
|
||||
|
||||
// Get the step
|
||||
let step = effect['step'][effectStep];
|
||||
if(step == undefined){ return false; }
|
||||
|
||||
// The items that can be targetted with the effectStep
|
||||
let itemsToSelectFrom = [];
|
||||
|
||||
// Loop the target location (or all locations)
|
||||
// Check which cards meet the criteria in the DB
|
||||
|
||||
|
||||
// TODO: Not 100% sure how to keep track. May need a var for each item in previous steps
|
||||
// or previous chains so they can be accessed, and used
|
||||
// If itemFromStep, return the itemKeys of the items selected from a previous step
|
||||
|
||||
console.log('HELLOO');
|
||||
console.log(step['target']);
|
||||
|
||||
// TODO: If target is 'itemFromStep', then get whatever item(s) were selected in
|
||||
// said step, and add them to the thing
|
||||
// TODO TODO
|
||||
|
||||
// If the target requirement is something from a previous step
|
||||
// Check if target criteria is something from another step
|
||||
let isFromStep = false;
|
||||
step['target'].forEach((target) => {
|
||||
if(target['itemFromStep'] != null){
|
||||
|
||||
console.log(target['itemFromStep']);
|
||||
console.log(effectTriggerId);
|
||||
//console.log(triggerQueue);
|
||||
//console.log(triggerDone);
|
||||
|
||||
// Loop all triggers that have been done (completed)
|
||||
triggerDone.forEach((oldTrigger) => {
|
||||
|
||||
// If not same triggerId, or the effectStep is not that of itemFromStep
|
||||
if(oldTrigger['triggerId'] != effectTriggerId || target['itemFromStep'] != oldTrigger['effectStep']){
|
||||
return isFromStep = false;
|
||||
}
|
||||
|
||||
console.log(oldTrigger);
|
||||
return isFromStep = oldTrigger['targets'];
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
// If above returns a step, need to get the target(s) from that prior step to use a targets now
|
||||
if(isFromStep){
|
||||
console.log(isFromStep);
|
||||
console.log('AAAAAAAAAAAAAAAAAAAAAA');
|
||||
}
|
||||
|
||||
|
||||
let items = [];
|
||||
// If from a previous step, loop those
|
||||
if(isFromStep !== null && isFromStep !== undefined && isFromStep !== false){ items = isFromStep; }
|
||||
// If not, get all the related doodads
|
||||
else{
|
||||
items = board.getItems(fromBoardElement, playerId, null, null);
|
||||
}
|
||||
|
||||
// Loop the boardlements and compare the colours, classes, etc. to match effect target criteria
|
||||
// boardElement, playerId, cardStatus, listPosition
|
||||
for(let item = 0; item < items.length; item++){
|
||||
// TODO: MAYBE ADD THE COLOUR/PASSIVE CHECKS to the getItems itself
|
||||
|
||||
let itemKey = items[item];
|
||||
//console.log(cardColours[itemKey]);
|
||||
|
||||
// If the item from getItems meets the criterias of target DB
|
||||
step['target'].forEach((target) => {
|
||||
|
||||
//console.log(target);
|
||||
//console.log(triggerDone);
|
||||
|
||||
|
||||
// Check the class the same for target, and item
|
||||
// If targetDB has null this means 'any' so is always correct
|
||||
// Check Class (TODO: mixed classes, colours, etc ie select 1 red+blue card)
|
||||
/*
|
||||
if(class[itemKey] == target['classId'] || target['classId'] == null){
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
// Check colour
|
||||
// If not null check the colours, otherwise null means any colour is ok
|
||||
if(target['colourId'] !== null){
|
||||
// Check the colours to see if one is of requirement
|
||||
cardColours[itemKey].forEach((colour) => {
|
||||
// If the colour doesn't match, continue to next target (forEach)
|
||||
if(colour[0] != target['colourId']){
|
||||
// The return below is just a 'continue' in forEach terms
|
||||
return; // forEach jank. forEach executes the 'function' 'target' each loop
|
||||
}
|
||||
// If the colour is correct, keep checking requirements
|
||||
});
|
||||
}
|
||||
|
||||
// Check passive (If hasPassive(id))
|
||||
/*
|
||||
if(cardColours[itemKey] == target['passiveId'] || target['passiveId'] == null){
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
if(cardType[itemKey] == target['typeId'] || target['typeId'] == null){
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
// Once all the target Req. have been checked against the item
|
||||
// and they match, add to selectable list
|
||||
itemsToSelectFrom.push(itemKey);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return itemsToSelectFrom;
|
||||
|
||||
|
||||
}
|
||||
|
||||
function addTargettedCardsToQueueEvent(queueTriggerId, triggerStep, targets){
|
||||
|
||||
console.log('ADD TARGETTED TO QUEUED TRIGGER');
|
||||
console.log(queueTriggerId);
|
||||
console.log(triggerStep);
|
||||
console.log(targets);
|
||||
|
||||
//console.log(triggerQueue[queueTriggerId]);
|
||||
//console.log(targets);
|
||||
|
||||
console.log(triggerQueue);
|
||||
|
||||
triggerQueue.forEach((queued) => {
|
||||
console.log(queued);
|
||||
if(
|
||||
queued.triggerId == queueTriggerId
|
||||
&&
|
||||
queued.effectStep == triggerStep
|
||||
){
|
||||
console.log('THIS SHOULD HAVE TARGETS ADDED');
|
||||
queued['targets'] = targets;
|
||||
}
|
||||
});
|
||||
|
||||
console.log(triggerQueue);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function queueEffect(itemKey, effectIndex){
|
||||
|
||||
let effect = getEffect(itemKey, effectIndex);
|
||||
if(effect == false){ return false; }
|
||||
|
||||
// TODO: Sort steps by stepOrder incase wrong in DB, etc.
|
||||
for (const [stepKey, step] of Object.entries(effect['step'])) {
|
||||
triggerQueue.push(
|
||||
// event, item, effectId, target, triggerId (commented atop)
|
||||
{
|
||||
'event': 'effect' // Which event. attack, destroy, effect, etc.
|
||||
,'item': itemKey // Which card is doing event
|
||||
,'effectIndex': effectIndex // Which effect (if effect)
|
||||
,'effectStep': stepKey // Which effect (if effect)
|
||||
,'target': null // ?
|
||||
,'triggerId': triggerId
|
||||
,'targets': null // ?
|
||||
}
|
||||
);
|
||||
}
|
||||
// Increment triggerId
|
||||
triggerId++;
|
||||
console.log(triggerQueue);
|
||||
}
|
||||
|
||||
function doNextInQueue(){
|
||||
|
||||
if(triggerQueue.length <= 0){
|
||||
console.log('Nothing in queue, doing next phase/event/whatever');
|
||||
}
|
||||
|
||||
// If effect, trigger it (should already have paid the trigger costs)
|
||||
switch(triggerQueue[0].event){
|
||||
case 'effect':
|
||||
// Do the effect
|
||||
doEffect(triggerQueue[0].item, triggerQueue[0].effectIndex, triggerQueue[0].effectStep, triggerQueue[0].triggerId);
|
||||
break;
|
||||
|
||||
default:
|
||||
alert('Error in doNextInQueue');
|
||||
return 0;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Add to completed triggers
|
||||
triggerDone.push(triggerQueue[0]);
|
||||
|
||||
// And remove from the triggerQueue (first index)
|
||||
triggerQueue.shift();
|
||||
|
||||
}
|
||||
function loopTriggerQueue(){
|
||||
|
||||
while(triggerQueue.length > 0){
|
||||
doNextInQueue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Recusively call doEffect until each is done?
|
||||
// Once recruit (play from hand) is triggered, need to allow user to select
|
||||
// then when done move to next step
|
||||
function doEffect(itemKey, effectIndex, effectStep, effectTriggerId){
|
||||
|
||||
console.log('doEffect');
|
||||
|
||||
let effect = getEffect(itemKey, effectIndex);
|
||||
if(effect == false){ return false; }
|
||||
|
||||
// Get the step
|
||||
let step = effect['step'][effectStep];
|
||||
if(step == undefined){ return false; }
|
||||
|
||||
|
||||
// For each step, activate the correct effect type on
|
||||
// the correct targets.
|
||||
|
||||
|
||||
// Get targets TODO: Use this instead of each case having it
|
||||
//let targets = getEffectStepTargets(itemKey, effectIndex, effectStep, fromBoardElement, playerId, effectTriggerId);
|
||||
|
||||
switch (step['basicEffectId']){
|
||||
|
||||
// Recruit
|
||||
case 4:
|
||||
recruitCard(itemKey, effectIndex, effectStep, step['amount'], effectTriggerId);
|
||||
break;
|
||||
|
||||
// Give Flight
|
||||
case 5:
|
||||
givePassive(itemKey, effectIndex, effectStep, step['amount'], effectTriggerId, 'flight');
|
||||
break;
|
||||
|
||||
// Give Taunt
|
||||
case 6:
|
||||
givePassive(itemKey, effectIndex, effectStep, step['amount'], effectTriggerId, 'taunt');
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Add the selected targets to the queuedItem so it can be referred to in future
|
||||
|
||||
// Now do the next step, if there's another in the effect
|
||||
// Commented out while testing triggerQueue
|
||||
/*
|
||||
if(effect['step'][effectStep++] !== undefined){
|
||||
doEffect(itemKey, effectIndex, effectStep++);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
function givePassive(itemKey, effectIndex, effectStep, targetAmount, effectTriggerId, passive){
|
||||
|
||||
console.log('GIVE PASSIVE: '+passive);
|
||||
|
||||
let effect = getEffect(itemKey, effectIndex);
|
||||
if(effect == false){ return false; }
|
||||
|
||||
// Get the step
|
||||
let step = effect['step'][effectStep];
|
||||
if(step == undefined){ return false; }
|
||||
|
||||
console.log(step);
|
||||
//return false;
|
||||
|
||||
// TODO: null, 0 are boardElement/playerId (for now) need to redo, rethink
|
||||
console.log('HELP ME');
|
||||
let targets = getEffectStepTargets(itemKey, effectIndex, effectStep, null, 0, effectTriggerId);
|
||||
console.log(targets);
|
||||
|
||||
if(targetAmount > 0 && targets.length > 0){
|
||||
|
||||
// TODO: better, and if just one thing omit, and do automatically
|
||||
let selectedTarget = prompt("Select a card to gain flight: \n"+targets, targets[0]);
|
||||
// User didn't select anything
|
||||
if (selectedTarget == null || selectedTarget == "") {
|
||||
alert('No card recruited, c ya');
|
||||
return false;
|
||||
}
|
||||
// User inputted card not in ID (obv temp, as will be done in game UI)
|
||||
// Huh I forgot why this is written like this, maybe it doens't work?
|
||||
if (!selectedTarget.includes(selectedTarget)){
|
||||
alert('Not in selection');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Remove the card from the selection (in case there's another in this loop)
|
||||
targets.splice(targets.indexOf(selectedTarget), 1);
|
||||
|
||||
// Give the passive
|
||||
if(passive == 'flight'){
|
||||
giveFlight(selectedTarget);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function removePassive(){}
|
||||
function hasPassive(){}
|
||||
|
||||
function recruitCard(itemKey, effectIndex, effectStep, targetAmount, effectTriggerId = null){
|
||||
console.log('RECRUIT');
|
||||
|
||||
let fromBoardElement = 'hand'; // FOR NOW, JUST TO TEST, THIS WILL BE PER BASIC EFFECT
|
||||
let playerId = 0;
|
||||
|
||||
let targets = getEffectStepTargets(itemKey, effectIndex, effectStep, fromBoardElement, playerId, effectTriggerId);
|
||||
let targettedCards = [];
|
||||
|
||||
//console.log(targets);
|
||||
|
||||
if(targetAmount > 0 && targets.length > 0){
|
||||
|
||||
let selectedTarget = prompt("Select a card to recruit: \n"+targets, targets[0]);
|
||||
// User didn't select anything
|
||||
if (selectedTarget == null || selectedTarget == "") {
|
||||
alert('No card recruited, c ya');
|
||||
return false;
|
||||
}
|
||||
// User inputted card not in ID (obv temp, as will be done in game UI)
|
||||
if (!selectedTarget.includes(selectedTarget)){
|
||||
alert('Not in selection');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the card from the selection (in case there's another)
|
||||
targets.splice(targets.indexOf(selectedTarget), 1);
|
||||
|
||||
// Add to targetted (for future ref)
|
||||
targettedCards.push(selectedTarget);
|
||||
|
||||
// Play recruited card
|
||||
// TODO: Need to pass player/listPosition better?
|
||||
board.playRecruitedCard(player[selectedTarget], listPosition[selectedTarget]);
|
||||
|
||||
}
|
||||
|
||||
addTargettedCardsToQueueEvent(effectTriggerId, effectStep, targettedCards);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
function cardAttackToShieldDamage(attack){
|
||||
if (attack >= 10000){ return 3; }
|
||||
if (attack >= 5001){ return 2; }
|
||||
if (attack >= 1){ return 1; }
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue