From 6826ab4317bf9be02310652bd23c011dd2a9c1eb Mon Sep 17 00:00:00 2001 From: dan-atack Date: Wed, 14 Jul 2021 18:54:13 -0400 Subject: [PATCH 1/2] implemented attack-related time delays for player and baddie --- client/src/Helpers/generalCombatHelpers.js | 22 ++++++++++++------- .../CombatEnvironment/CombatEnvironment.js | 8 +++---- .../Game/ReflexCheck/ReflexCheck.js | 13 ++++++----- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/client/src/Helpers/generalCombatHelpers.js b/client/src/Helpers/generalCombatHelpers.js index 858f64e..6b4b160 100644 --- a/client/src/Helpers/generalCombatHelpers.js +++ b/client/src/Helpers/generalCombatHelpers.js @@ -1,10 +1,10 @@ // When either the player's attack throws a baddie, or the baddie's attack throws the player, // find out if there's an obstacle in the path to the destination and return the closest possible coords: export const determineObstacle = (distance, direction, attackerCoords, victimCoords, seed) => { - // console.log(`distance: ${distance}, ${typeof distance}`); - // console.log(`direction: ${direction}, ${typeof direction}`); - // console.log(`attacker coords: ${attackerCoords.x}, ${attackerCoords.y}`); - // console.log(`victim coords: ${victimCoords.x}, ${victimCoords.y}`); + console.log(`distance: ${distance}, ${typeof distance}`); + console.log(`direction: ${direction}, ${typeof direction}`); + console.log(`attacker coords: ${attackerCoords.x}, ${attackerCoords.y}`); + console.log(`victim coords: ${victimCoords.x}, ${victimCoords.y}`); // Return the location the victim is currently standing in if there is no distance to be thrown: if (distance === 0) return victimCoords; // For each cardinal direction, make a list of all the squares the victim will cross to travel the distance, in that direction: @@ -57,13 +57,15 @@ export const determineObstacle = (distance, direction, attackerCoords, victimCoo return victimCoords; } } + console.log(potentialPositions); // If no valid positions have been generated by this point, the victim is at the edge of the map. Return original coords: if (potentialPositions.length === 0) { console.log('No valid found for attack throw destination. Returning original coordinates.'); return victimCoords; } // Ensure the attacker's own location is not among the potential destinations to prevent rendering errors: - potentialPositions = potentialPositions.filter(position => position.x != attackerCoords.x && position.y != attackerCoords.y); + potentialPositions = potentialPositions.filter(position => !(position.x === attackerCoords.x && position.y === attackerCoords.y)); + console.log(potentialPositions); // Next, find which obstacles are potentially in the way of the attack's throw, based on the target's original position: let possibleObstacles = []; switch (direction) { @@ -127,11 +129,15 @@ export const advanceCombatSequence = (time, nextPhase, dispatch, setNextPhase) = }, time); } -// This function implements a one-time timeout to delay between the start of a MOVEMENT combat phase and its outcome (e.g. between when you click on a tile (or when a baddie 'decides' where to go), and when your character's sprite actually arrives there): +// This function implements a one-time timeout to delay between the start of a MOVEMENT or ATTACK combat phase and its outcome (e.g. between when you click on a tile or hit the baddie, or he moves/hits you, and when the character's sprite actually arrives there). +// PROPS: time = delay in milliseconds, nextPhase = string name of combat phase OR NULL (in the case that a phase advance is actually NOT required, such as the first hit in a queue of attacks), dispatch = literally the redux dispatcher (ew), setNextPhase = REDUX setPhase action, setPosition = RECOIL position setter for either the player or the baddie, and coords = {x:number, y:number} export const advanceCombatWithMovement = async (time, nextPhase, dispatch, setNextPhase, setPosition, coords) => { - console.log(`delaying for ${time/1000} seconds for movement animation`); + console.log(`delaying for ${time/1000} seconds before ${nextPhase}`); setTimeout(() => { + console.log(`time to move to ${coords.x}, ${coords.y}`); setPosition(coords); - dispatch(setNextPhase(nextPhase)); + if (nextPhase) { + dispatch(setNextPhase(nextPhase)); + } }, time); } \ No newline at end of file diff --git a/client/src/components/Game/CombatEnvironment/CombatEnvironment.js b/client/src/components/Game/CombatEnvironment/CombatEnvironment.js index b9463ad..8624828 100644 --- a/client/src/components/Game/CombatEnvironment/CombatEnvironment.js +++ b/client/src/components/Game/CombatEnvironment/CombatEnvironment.js @@ -122,12 +122,12 @@ const CombatEnvironment = () => { } // Baddie throw logic goes here! const destination = determineObstacle(baddieDecision.throwDistances[0], baddieOrientation, baddieCoords, playerCoords, seed); - // console.log(`DESTINATION: ${destination.x}, ${destination.y}`); - setPlayerCoords(destination); + console.log(`DESTINATION: ${destination.x}, ${destination.y}`); + advanceCombatWithMovement(1000, 'playerAction', dispatch, setCombatPhase, setPlayerCoords, destination); } + // If no collision occurs on the baddie's attack phase, advance the combat sequence without delay: + dispatch(setCombatPhase('playerAction')); }); - advanceCombatSequence(1000, 'playerAction', dispatch, setCombatPhase); - // dispatch(setCombatPhase('playerAction')); break; case 'playerAction': // Go through the player's list of attacks and see if the baddie is within range of any of them: diff --git a/client/src/components/Game/ReflexCheck/ReflexCheck.js b/client/src/components/Game/ReflexCheck/ReflexCheck.js index 43f076f..c5ce076 100644 --- a/client/src/components/Game/ReflexCheck/ReflexCheck.js +++ b/client/src/components/Game/ReflexCheck/ReflexCheck.js @@ -7,8 +7,8 @@ import { useDispatch } from 'react-redux'; import combatState from '../../../state'; import globalState from '../../../state'; import { useRecoilState, useRecoilValue } from 'recoil'; -import { setCombatPhase, stopReflexCheck } from '../../../actions'; -import { determineObstacle, advanceCombatSequence } from '../../../Helpers/generalCombatHelpers'; +import { setCombatPhase, setPlayerCoords, stopReflexCheck } from '../../../actions'; +import { determineObstacle, advanceCombatSequence, advanceCombatWithMovement } from '../../../Helpers/generalCombatHelpers'; import data from '../../../data/mapSeed.json'; // Combo = integer for which of the 3 possible key combos to use for the reflex check: @@ -78,13 +78,14 @@ function ReflexCheck({ combo }) { } const destination = determineObstacle(distance, playerOrientation, playerCoords, baddieCoords, seed); console.log(`DESTINATION: ${destination.x}, ${destination.y}`); - setBaddieCoords(destination); + return destination; } // What happens if you complete the LAST combo in the queue: const finalAttackSuccess = () => { setSuccessStatus(true); - const attackAnimationDelay = playerMovesInQueue.length * 1000; // Delay for 1 second per attack + const attackAnimationDelay = playerMovesInQueue.length * 1000; // TODO: consider making this depend on what the last attack in the queue was, to allow for more time for a more dramatic animation for the final move or for specific 'ultimate' moves. + // Firing alongside the regular attackSuccess function, this function introduces a longer delay and then advances the combat phase: advanceCombatSequence(attackAnimationDelay, 'specialEvent', dispatch, setCombatPhase); dispatch(stopReflexCheck()); } @@ -119,9 +120,11 @@ function ReflexCheck({ combo }) { } // Determine if baddie should be moved, and set his coords if so. - determineThrow(); + const destination = determineThrow(); setBaddieHP(baddieHP - determineDamage()); setPlayerHype(Math.min(playerHype + determineHype(), 100)); + // Introduce a short delay before updating baddie position: + advanceCombatWithMovement(250, null, dispatch, setCombatPhase, setBaddieCoords, destination); // If there are multiple attacks queued and you didn't just do the last one, setup the next move: if (playerMovesInQueue.length > 1 && attackQueueIndexPosition < playerMovesInQueue.length - 1) { setAttackQueueIndexPosition(attackQueueIndexPosition + 1); From 2a71272eb86a1131cbbefc389de1baf088c72e8a Mon Sep 17 00:00:00 2001 From: dan-atack Date: Wed, 14 Jul 2021 19:57:28 -0400 Subject: [PATCH 2/2] fixed issue with player action phase premature start and commented console logs --- client/src/Helpers/generalCombatHelpers.js | 18 ++++++++--------- .../CombatEnvironment/CombatEnvironment.js | 20 +++++++++++-------- .../Game/ReflexCheck/ReflexCheck.js | 2 +- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/client/src/Helpers/generalCombatHelpers.js b/client/src/Helpers/generalCombatHelpers.js index 6b4b160..dbcdc1f 100644 --- a/client/src/Helpers/generalCombatHelpers.js +++ b/client/src/Helpers/generalCombatHelpers.js @@ -1,10 +1,10 @@ // When either the player's attack throws a baddie, or the baddie's attack throws the player, // find out if there's an obstacle in the path to the destination and return the closest possible coords: export const determineObstacle = (distance, direction, attackerCoords, victimCoords, seed) => { - console.log(`distance: ${distance}, ${typeof distance}`); - console.log(`direction: ${direction}, ${typeof direction}`); - console.log(`attacker coords: ${attackerCoords.x}, ${attackerCoords.y}`); - console.log(`victim coords: ${victimCoords.x}, ${victimCoords.y}`); + // console.log(`distance: ${distance}, ${typeof distance}`); + // console.log(`direction: ${direction}, ${typeof direction}`); + // console.log(`attacker coords: ${attackerCoords.x}, ${attackerCoords.y}`); + // console.log(`victim coords: ${victimCoords.x}, ${victimCoords.y}`); // Return the location the victim is currently standing in if there is no distance to be thrown: if (distance === 0) return victimCoords; // For each cardinal direction, make a list of all the squares the victim will cross to travel the distance, in that direction: @@ -57,15 +57,15 @@ export const determineObstacle = (distance, direction, attackerCoords, victimCoo return victimCoords; } } - console.log(potentialPositions); + // console.log(potentialPositions); // If no valid positions have been generated by this point, the victim is at the edge of the map. Return original coords: if (potentialPositions.length === 0) { - console.log('No valid found for attack throw destination. Returning original coordinates.'); + // console.log('No valid found for attack throw destination. Returning original coordinates.'); return victimCoords; } // Ensure the attacker's own location is not among the potential destinations to prevent rendering errors: potentialPositions = potentialPositions.filter(position => !(position.x === attackerCoords.x && position.y === attackerCoords.y)); - console.log(potentialPositions); + // console.log(potentialPositions); // Next, find which obstacles are potentially in the way of the attack's throw, based on the target's original position: let possibleObstacles = []; switch (direction) { @@ -132,9 +132,9 @@ export const advanceCombatSequence = (time, nextPhase, dispatch, setNextPhase) = // This function implements a one-time timeout to delay between the start of a MOVEMENT or ATTACK combat phase and its outcome (e.g. between when you click on a tile or hit the baddie, or he moves/hits you, and when the character's sprite actually arrives there). // PROPS: time = delay in milliseconds, nextPhase = string name of combat phase OR NULL (in the case that a phase advance is actually NOT required, such as the first hit in a queue of attacks), dispatch = literally the redux dispatcher (ew), setNextPhase = REDUX setPhase action, setPosition = RECOIL position setter for either the player or the baddie, and coords = {x:number, y:number} export const advanceCombatWithMovement = async (time, nextPhase, dispatch, setNextPhase, setPosition, coords) => { - console.log(`delaying for ${time/1000} seconds before ${nextPhase}`); + // console.log(`delaying for ${time/1000} seconds before ${nextPhase}`); setTimeout(() => { - console.log(`time to move to ${coords.x}, ${coords.y}`); + // console.log(`time to move to ${coords.x}, ${coords.y}`); setPosition(coords); if (nextPhase) { dispatch(setNextPhase(nextPhase)); diff --git a/client/src/components/Game/CombatEnvironment/CombatEnvironment.js b/client/src/components/Game/CombatEnvironment/CombatEnvironment.js index 8624828..7ab49cd 100644 --- a/client/src/components/Game/CombatEnvironment/CombatEnvironment.js +++ b/client/src/components/Game/CombatEnvironment/CombatEnvironment.js @@ -87,7 +87,7 @@ const CombatEnvironment = () => { const decision = baddieMakeDecision(baddieCoords, baddieOrientation, playerCoords, playerOrientation, baddie); setBaddieDecision(decision); // Pass baddie's move data to recoil // Helper function advances to next phase AFTER a given time delay, to allow for an animation 'telegraphing' the decision: - console.log(`Baddie move choice: ${decision.name}`); + // console.log(`Baddie move choice: ${decision.name}`); advanceCombatSequence(1500, 'playerMove', dispatch, setCombatPhase); // IDEA: Use time hook to make this phase last 1 - 2 seconds; use that time to show a GIF that telegraphs the move! break; @@ -103,9 +103,9 @@ const CombatEnvironment = () => { // This will change the Level Visual Generator's props, causing it to reload: setEnemyAttackRadius(dangerZone); // Determine here if the player gets hit: - dangerZone.forEach((point) => { - if (point.x === playerCoords.x && point.y === playerCoords.y) { // Baddie attack success effects begin here: - setPlayerHealth(playerHealth - baddieDecision.damage); + const point = dangerZone.filter(point => point.x === playerCoords.x && point.y === playerCoords.y); + if (point.length === 1) { // If there is a hit, it will be the only member of this list + setPlayerHealth(playerHealth - baddieDecision.damage); // if the move has an effect then it attaches the effect here if (baddieDecision.effect) { const { effect, duration } = baddieDecision; @@ -122,12 +122,12 @@ const CombatEnvironment = () => { } // Baddie throw logic goes here! const destination = determineObstacle(baddieDecision.throwDistances[0], baddieOrientation, baddieCoords, playerCoords, seed); - console.log(`DESTINATION: ${destination.x}, ${destination.y}`); + // console.log(`DESTINATION: ${destination.x}, ${destination.y}`); advanceCombatWithMovement(1000, 'playerAction', dispatch, setCombatPhase, setPlayerCoords, destination); + } else { + // console.log('no hit on player'); + dispatch(setCombatPhase('playerAction')); } - // If no collision occurs on the baddie's attack phase, advance the combat sequence without delay: - dispatch(setCombatPhase('playerAction')); - }); break; case 'playerAction': // Go through the player's list of attacks and see if the baddie is within range of any of them: @@ -137,6 +137,10 @@ const CombatEnvironment = () => { inRange = true; }; }) + // Uncomment for help troubleshooting: + // console.log(inRange); + // console.log(playerCoords); + // console.log(baddieCoords); // If none of the player's moves is in range of the baddie, skip to the next phase: if (!inRange) { // This code down here is the same as that in the combat ui for the attack button handlers: diff --git a/client/src/components/Game/ReflexCheck/ReflexCheck.js b/client/src/components/Game/ReflexCheck/ReflexCheck.js index c5ce076..6eb3374 100644 --- a/client/src/components/Game/ReflexCheck/ReflexCheck.js +++ b/client/src/components/Game/ReflexCheck/ReflexCheck.js @@ -124,7 +124,7 @@ function ReflexCheck({ combo }) { setBaddieHP(baddieHP - determineDamage()); setPlayerHype(Math.min(playerHype + determineHype(), 100)); // Introduce a short delay before updating baddie position: - advanceCombatWithMovement(250, null, dispatch, setCombatPhase, setBaddieCoords, destination); + advanceCombatWithMovement(500, null, dispatch, setCombatPhase, setBaddieCoords, destination); // If there are multiple attacks queued and you didn't just do the last one, setup the next move: if (playerMovesInQueue.length > 1 && attackQueueIndexPosition < playerMovesInQueue.length - 1) { setAttackQueueIndexPosition(attackQueueIndexPosition + 1);