From 3f72d66bfa6fe83bd124ab8dabbc583c5c9efa57 Mon Sep 17 00:00:00 2001 From: dan-atack Date: Wed, 28 Apr 2021 19:22:25 -0400 Subject: [PATCH 1/2] changed playerAttacksInQueue state to array and updated all components to use it this way --- .../components/Game/CombatEnvironment/CombatEnvironment.js | 2 +- .../components/Game/CombatEnvironment/CombatUi/CombatUi.js | 6 +++--- .../Game/CombatEnvironment/CombatUi/ResetButton.js | 2 +- client/src/state/combatState.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/components/Game/CombatEnvironment/CombatEnvironment.js b/client/src/components/Game/CombatEnvironment/CombatEnvironment.js index 3ed9d85..327b13f 100644 --- a/client/src/components/Game/CombatEnvironment/CombatEnvironment.js +++ b/client/src/components/Game/CombatEnvironment/CombatEnvironment.js @@ -125,7 +125,7 @@ const CombatEnvironment = () => { } break; // Await input from the attack selection inputs and no more. case 'specialEvent': - setPlayerAttacksInQueue(0); + setPlayerAttacksInQueue([]); specialEventLogic(dispatch, setCombatPhase, level); break; case 'baddieMove': diff --git a/client/src/components/Game/CombatEnvironment/CombatUi/CombatUi.js b/client/src/components/Game/CombatEnvironment/CombatUi/CombatUi.js index 411bbd6..31e39b2 100644 --- a/client/src/components/Game/CombatEnvironment/CombatUi/CombatUi.js +++ b/client/src/components/Game/CombatEnvironment/CombatUi/CombatUi.js @@ -54,7 +54,7 @@ const CombatUi = ({turn, setEnemyAttackRadius}) => { setPlayerMoveOptions([]) const range = await attackRange(skill, playerCoords, seed.width, seed.height, seed.obstructions); setPlayerAttackRadius(range); - setPlayerAttacksInQueue(playerAttacksInQueue + 1); + setPlayerAttacksInQueue(playerAttacksInQueue.push(skill)); // NOTE TO SELF: MAKE THE QUEUE AN ARRAY IN THE STATE FILE, then push the skill to it here! Then instead of using the number in other calculations (find all with ctrl + shift + h) use the length of the array. Reset button brings it to [] instead of zero. } } @@ -68,7 +68,7 @@ const CombatUi = ({turn, setEnemyAttackRadius}) => { move.id === reflexCheckId)} combo={randomCombo} - numPrevMoves={playerAttacksInQueue} + numPrevMoves={playerAttacksInQueue.length} style={{ position: 'absolute', top: '0px', right: '50px' }} />} @@ -83,7 +83,7 @@ const CombatUi = ({turn, setEnemyAttackRadius}) => { key={`player-move-${skill.id}`} skill={skill} handleClick={handleClick} - numPrevMoves={playerAttacksInQueue} + numPrevMoves={playerAttacksInQueue.length} playerHype={playerHype} /> })} diff --git a/client/src/components/Game/CombatEnvironment/CombatUi/ResetButton.js b/client/src/components/Game/CombatEnvironment/CombatUi/ResetButton.js index 27488fc..e0b91d8 100644 --- a/client/src/components/Game/CombatEnvironment/CombatUi/ResetButton.js +++ b/client/src/components/Game/CombatEnvironment/CombatUi/ResetButton.js @@ -22,7 +22,7 @@ const ResetButton = () => { const handleClick = () => { // This is ugly AF and terribly not dry... but it *does* work! // TODO: Make default values object for greater flexibility if you ever wanna reset these hard-coded bastards. - setPlayerAttacksInQueue(0); + setPlayerAttacksInQueue([]); setPlayerHealth(100); setPlayerAttackRadius([]); setPlayerHype(0); diff --git a/client/src/state/combatState.js b/client/src/state/combatState.js index 82ea3b8..ae9a479 100644 --- a/client/src/state/combatState.js +++ b/client/src/state/combatState.js @@ -14,7 +14,7 @@ export const playerAP = atom({ export const playerAttacksInQueue = atom({ key: 'playerMovesInQueue', - default: 0, // this just counts how many moves you've made in a given combat round. + default: [], // every move in the queue increases hype cost; list is reset each combat round. }) export const playerHype = atom({ From 20bda313d1545fec882b3bbeed576d2ece45fe20 Mon Sep 17 00:00:00 2001 From: dan-atack Date: Wed, 5 May 2021 20:59:25 -0400 Subject: [PATCH 2/2] added hype chaining and hype cost --- .../CombatEnvironment/CombatEnvironment.js | 5 +- .../CombatEnvironment/CombatUi/CombatUi.js | 7 +- .../CombatEnvironment/CombatUi/SkillButton.js | 11 ++- .../Game/CombatEnvironment/DevD/DevDisplay.js | 4 +- .../CombatEnvironment/LevelVisualGenerator.js | 2 +- .../Game/ReflexCheck/ReflexCheck.js | 89 ++++++++++++------- 6 files changed, 76 insertions(+), 42 deletions(-) diff --git a/client/src/components/Game/CombatEnvironment/CombatEnvironment.js b/client/src/components/Game/CombatEnvironment/CombatEnvironment.js index 327b13f..64dd9c1 100644 --- a/client/src/components/Game/CombatEnvironment/CombatEnvironment.js +++ b/client/src/components/Game/CombatEnvironment/CombatEnvironment.js @@ -116,12 +116,10 @@ const CombatEnvironment = () => { }); // If none of the player's moves is in range of the baddie, skip to the next phase: if (!(baddieInXRange && baddieInYRange)) { - // This code down here is from the combat ui for the attack button handlers: IT SHOULD BE IN A HELPER FUNCTION! + // This code down here is the same as that in the combat ui for the attack button handlers: setEnemyAttackRadius([]); setPlayerMoveOptions([]); dispatch(setCombatPhase('specialEvent')); - } else { - console.log(baddieInXRange, baddieInYRange, 'Baddie should be in range.') } break; // Await input from the attack selection inputs and no more. case 'specialEvent': @@ -195,6 +193,7 @@ const CombatEnvironment = () => { baddieCoords={baddieCoords} baddieOrientation={baddieOrientation} baddieDecision={baddieDecision} + playerAttacksInQueue={playerAttacksInQueue} />} {/* */} { const encounter = baddieData.find(obj => obj.level === level); // This handles the clicking of any skill button, generated by the map function. - const handleClick = async (skill) => { + const handleClick = async (skill, cost) => { if (!playerIsDead && combatPhase === 'playerAction') { // Skill can only be used if player is alive and it's their action phase dispatch(setReflexCheck(skill.id)) setSelectedSkill(skill); @@ -54,7 +54,8 @@ const CombatUi = ({turn, setEnemyAttackRadius}) => { setPlayerMoveOptions([]) const range = await attackRange(skill, playerCoords, seed.width, seed.height, seed.obstructions); setPlayerAttackRadius(range); - setPlayerAttacksInQueue(playerAttacksInQueue.push(skill)); // NOTE TO SELF: MAKE THE QUEUE AN ARRAY IN THE STATE FILE, then push the skill to it here! Then instead of using the number in other calculations (find all with ctrl + shift + h) use the length of the array. Reset button brings it to [] instead of zero. + setPlayerAttacksInQueue([...playerAttacksInQueue, skill]); + setPlayerHype(playerHype - cost); } } @@ -66,9 +67,7 @@ const CombatUi = ({turn, setEnemyAttackRadius}) => { {combatPhase === 'victory' && } {doReflexCheck && move.id === reflexCheckId)} combo={randomCombo} - numPrevMoves={playerAttacksInQueue.length} style={{ position: 'absolute', top: '0px', right: '50px' }} />} diff --git a/client/src/components/Game/CombatEnvironment/CombatUi/SkillButton.js b/client/src/components/Game/CombatEnvironment/CombatUi/SkillButton.js index 1b6d4e3..cd3bb81 100644 --- a/client/src/components/Game/CombatEnvironment/CombatUi/SkillButton.js +++ b/client/src/components/Game/CombatEnvironment/CombatUi/SkillButton.js @@ -17,7 +17,7 @@ const SkillButton = (props) => { // Hype cost is equal to the baseline cost times the amount of attacks already selected (the first one is free though) // E.G. 1st attack = 0 hype, 2nd attack = 10 hype, 3rd attack = 30 hype, etc. handleClick(skill)} + onClick={() => handleClick(skill, currentHypeCost)} onMouseEnter={() => setOpen(true)} onMouseLeave={() => setOpen(false)} > @@ -27,8 +27,13 @@ const SkillButton = (props) => { ) } else { return ( - - Too expensive! + setOpen(true)} + onMouseLeave={() => setOpen(false)} + > + {skill.icon && {skill.name}/ || skill.name} + {open && } ) } diff --git a/client/src/components/Game/CombatEnvironment/DevD/DevDisplay.js b/client/src/components/Game/CombatEnvironment/DevD/DevDisplay.js index 1cd65f0..439ea13 100644 --- a/client/src/components/Game/CombatEnvironment/DevD/DevDisplay.js +++ b/client/src/components/Game/CombatEnvironment/DevD/DevDisplay.js @@ -10,7 +10,8 @@ const DevDisplay = ({ baddieHP, baddieCoords, baddieOrientation, - baddieDecision + baddieDecision, + playerAttacksInQueue, }) => { return ( @@ -23,6 +24,7 @@ const DevDisplay = ({

Baddie Coords: ({baddieCoords.x}, {baddieCoords.y})

Baddie Orientation: {baddieOrientation}

Baddie Decision: {baddieDecision.name}

+

playerAttacksInQueue: {playerAttacksInQueue.length}

) } diff --git a/client/src/components/Game/CombatEnvironment/LevelVisualGenerator.js b/client/src/components/Game/CombatEnvironment/LevelVisualGenerator.js index ff08c81..05819f0 100644 --- a/client/src/components/Game/CombatEnvironment/LevelVisualGenerator.js +++ b/client/src/components/Game/CombatEnvironment/LevelVisualGenerator.js @@ -50,7 +50,7 @@ const LevelVisualGenerator = ({row, baddieCoords, playerMove, playerAttack, enem seed.obstructions.find((obs) => sq.x === obs.x && sq.y === obs.y) ) { // This renders an obstacle if the map file contains an obstacle at the specified coords: - console.log(sq.x, sq.y); + // console.log(sq.x, sq.y); return ( { - const remainder = timeLeft / move.time * 100; + const remainder = timeLeft / playerMovesInQueue[attackQueueIndexPosition].time * 100; if (remainder > 75) { - return move.baseDmg * 2; // Double damage if you have more than 75% time left + return playerMovesInQueue[attackQueueIndexPosition].baseDmg * 2; // Double damage if you have more than 75% time left } else if (remainder > 50) { - return Math.ceil(move.baseDmg * 1.5); // 50% bonus damage if you have more than 50% time left + return Math.ceil(playerMovesInQueue[attackQueueIndexPosition].baseDmg * 1.5); // 50% bonus damage if you have more than 50% time left } else { - return move.baseDmg; // Otherwise you just do the base dmg. + return playerMovesInQueue[attackQueueIndexPosition].baseDmg; // Otherwise you just do the base dmg. } } // If you hit, Hype earned = (max hype plus combo length in letters) times time remaining. const determineHype = () => { - const remainder = timeLeft / move.time; // Just the fraction this time - const stringLength = move.combos[0].length // Find how many keys were needed to complete the move - return Math.floor((move.maxHype + stringLength) * remainder); + const remainder = timeLeft / playerMovesInQueue[attackQueueIndexPosition].time; // Just the fraction this time + const stringLength = playerMovesInQueue[attackQueueIndexPosition].combos[combo].length // Find how many keys were needed to complete the move + return Math.floor((playerMovesInQueue[attackQueueIndexPosition].maxHype + stringLength) * remainder); } + + // What happens if you complete the LAST combo in the queue: + const finalAttackSuccess = () => { + setSuccessStatus(true); + dispatch(setCombatPhase('specialEvent')); + dispatch(stopReflexCheck()); + } + + // What happens if you are NOT on the last combo in the queue: + const setupNextAttack = () => { + // Reset timer to the time value of the next move, minus 10 percent per previously executed move: + setTimeLeft(playerMovesInQueue[attackQueueIndexPosition].time * (1 - playerMovesInQueue.length * 0.1)); + // Reset keystroke tracker: + setCurrentKey(0); + setKeystrokes(0); + } + + // What happens when you complete a combo (regardless of how many attacks are queued): + const attackSuccess = () => { + playUghSound(); + console.log(`Player hits baddie with ${playerMovesInQueue[attackQueueIndexPosition].name} for ${determineDamage()} damage!`); + console.log(`Player gains ${determineHype()} hype points!`); + setBaddieHP(baddieHP - determineDamage()); + setPlayerHype(playerHype + determineHype()); + // 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); + setupNextAttack(); + } else { + finalAttackSuccess(); + } + } + // One Effect to handle all the keys: React.useEffect(() => { // If you've failed, ensure the string is exactly zero, and dispatch to advance state AND declare an end to the reflex check): @@ -76,7 +113,7 @@ function ReflexCheck({ move, combo, numPrevMoves }) { if (!failStatus) { setFailStatus(true); // Check each key in the combo against the keydown event: - move.combos[combo].forEach((key, idx) => { + playerMovesInQueue[attackQueueIndexPosition].combos[combo].forEach((key, idx) => { if (ev.code === `Key${key}`) { // If the index of the event key is the current key, advance the sequence: if (idx === currentKey) { @@ -87,21 +124,13 @@ function ReflexCheck({ move, combo, numPrevMoves }) { }) setKeystrokes(keystrokes + 1); } - }; // IF SUCCESS: - if (move.combos[combo].length === currentKey && !failStatus) { - setSuccessStatus(true); - playUghSound(); - console.log(`Player hits baddie with ${move.name} for ${determineDamage()} damage!`); - console.log(`Player gains ${determineHype()} hype points!`); - setBaddieHP(baddieHP - determineDamage()); - setPlayerHype(playerHype + determineHype()); - dispatch(setCombatPhase('specialEvent')); - dispatch(stopReflexCheck()); + }; // IF COMBO IS EXECUTED SUCCESSFULLY: + if (playerMovesInQueue[attackQueueIndexPosition].combos[combo].length === currentKey && !failStatus) { + attackSuccess(); } window.addEventListener('keydown', handleKeydown); return () => { - window.removeEventListener('keydown', handleKeydown); }; } @@ -109,10 +138,10 @@ function ReflexCheck({ move, combo, numPrevMoves }) { return ( - MOVE: {move.name.toUpperCase()} + MOVE: {playerMovesInQueue[attackQueueIndexPosition].name.toUpperCase()}

KEYS:

- {move.combos[combo].map((key, idx) => { + {playerMovesInQueue[attackQueueIndexPosition].combos[combo].map((key, idx) => { return( {key} )