diff options
author | Daniel Weipert <code@drogueronin.de> | 2023-08-18 23:19:13 +0200 |
---|---|---|
committer | Daniel Weipert <code@drogueronin.de> | 2023-08-18 23:19:13 +0200 |
commit | 91d048ef0f994446aaee91e3afcbd99788e439d7 (patch) | |
tree | 30063656343d7c3c0f9ebd37b2eb1896bfa76820 /resources/js/game.js | |
parent | f9b00e47e04eac414d892a08136a90833abeefd6 (diff) |
item effects,conditions
Diffstat (limited to 'resources/js/game.js')
-rw-r--r-- | resources/js/game.js | 405 |
1 files changed, 189 insertions, 216 deletions
diff --git a/resources/js/game.js b/resources/js/game.js index 1ca9387..f68e2fb 100644 --- a/resources/js/game.js +++ b/resources/js/game.js @@ -12,6 +12,132 @@ const Game = { turn: 0, + /** + * @returns {string} + */ + save () { + const saveMonster = (monsterData, monsterState) => { + monsterData.level = monsterState.level; + monsterData.hp = monsterState.hp; + + if (monsterData.statusEffect && monsterData.statusEffect.slug === 'lifeleech') { + monsterData.statusEffect = null; + } + + return monsterData; + }; + + const saveData = JSON.parse(JSON.stringify(state)); + + for (const idx in saveData.monsters) { + saveData.monsters[idx] = saveMonster(saveData.monsters[idx], state.monsters[idx]); + } + + for (const idx in saveData.partyMonsters) { + saveData.partyMonsters[idx] = saveMonster(saveData.partyMonsters[idx], state.partyMonsters[idx]); + } + + saveData.activeMonsterIdx = state.partyMonsters.indexOf(state.activeMonster); + + saveData.enemy.monster = saveMonster(saveData.enemy.monster, state.enemy.monster); + + return btoa(JSON.stringify(saveData)); + }, + + /** + * @param {string} saveData + */ + async load (saveData) { + /** + * @param {Monster} monsterData + */ + const loadMonster = async (monsterData) => { + const monster = await fetchMonster(monsterData.slug); + + monster.level = monsterData.level; + monster.hp = monsterData.hp; + monster.exp = monsterData.exp; + monster.tasteWarm = monsterData.tasteWarm; + monster.tasteCold = monsterData.tasteCold; + monster.gender = monsterData.gender; + monster.heldItem = await loadItem(monsterData.heldItem); + monster.statusEffect = await loadStatusEffect(monsterData.statusEffect); + monster.statModifiers = monsterData.statModifiers; + monster.experienceModifier = monsterData.experienceModifier; + monster.moneyModifier = monsterData.moneyModifier; + monster.activeTechniques = await Promise.all(monsterData.activeTechniques.map(async (technique) => { + return loadTechnique(technique); + })); + + return monster; + }; + + /** + * @param {InventoryItem} inventoryItemData + */ + const loadInventoryItem = async (inventoryItemData) => { + const inventoryItem = new InventoryItem(await fetchItem(inventoryItemData.item.slug)); + + inventoryItem.quantity = inventoryItemData.quantity; + + return inventoryItem; + }; + + /** + * @param {Item} itemData + */ + const loadItem = async (itemData) => { + if (!itemData) { + return null; + } + + const item = await fetchItem(itemData.slug); + + return item; + }; + + /** + * @param {StatusEffect} statusEffectData + */ + const loadStatusEffect = async (statusEffectData) => { + if (!statusEffectData) { + return null; + } + + const statusEffect = await fetchStatusEffect(statusEffectData.slug); + + statusEffect.turnsLeft = statusEffectData.turnsLeft; + + return statusEffect; + }; + + /** + * @param {Technique} techniqueData + */ + const loadTechnique = async (techniqueData) => { + const technique = await fetchTechnique(techniqueData.slug); + + return technique; + }; + + /** + * @type {State} + */ + const loadedState = JSON.parse(atob(saveData)); + + state.money = loadedState.money; + state.monsters = await Promise.all(loadedState.monsters.map(async (monsterData) => await loadMonster(monsterData))); + state.inventory = await Promise.all(loadedState.inventory.map(async (itemData) => await loadInventoryItem(itemData))); + state.partyMonsters = await Promise.all(loadedState.partyMonsters.map(async (monsterData) => await loadMonster(monsterData))); + state.activeMonster = state.partyMonsters[loadedState.activeMonsterIdx]; + state.activeTechnique = await loadTechnique(loadedState.activeTechnique); + state.enemy.monster = await loadMonster(loadedState.enemy.monster); + + UI.drawEnemyMonster(); + UI.drawActiveMonster(); + UI.drawActiveTechniques(); + }, + async progressTurn () { Game.turn++; @@ -62,18 +188,56 @@ const Game = { * @param {Monster} user * @param {Monster} target */ - async useTechnique (technique, user, target) { - technique.use(); + async tryUseTechnique (technique, user, target) { + let canUse = true; - if (!Game.didTechniqueHit) { - UI.drawDamageMiss(UI.createDamageMiss()); - return; + // recharge + if (technique.isRecharging()) { + const feedbackNode = UI.createActionFeedback('recharge'); + UI.drawActionFeedback(feedbackNode); + + canUse = false; } - for (const techniqueEffect of technique.effects) { + // noddingoff + if (user.statusEffect && user.statusEffect.slug === StatusEffectType.noddingoff) { + const feedbackNode = UI.createActionFeedback('noddingoff'); + UI.drawActionFeedback(feedbackNode); + + canUse = false; + } + + if (canUse) { + + // hit? + const accuracy = Math.random(); + Game.didTechniqueHit = technique.accuracy >= accuracy; + if (!Game.didTechniqueHit) { + technique.use(); + UI.drawDamageMiss(UI.createDamageMiss()); + + return; + } + + await Game.useTechnique(technique, user, target); + } + }, + + /** + * @param {Technique} technique + * @param {Monster} user + * @param {Monster} target + */ + async useTechnique (technique, user, target) { + technique.use(); + + for (const techniqueEffectCode of technique.effects) { + const techniqueEffect = new TechniqueEffect(techniqueEffectCode); + techniqueEffect.setUser(user); + techniqueEffect.setTarget(target); // damage - if (['damage', 'splash', 'area'].includes(techniqueEffect)) { + if (['damage', 'splash', 'area'].includes(techniqueEffect.type)) { Game.phases.action.push(() => { const damage = simpleDamageCalculation(state.activeTechnique, state.activeMonster, state.enemy.monster); @@ -82,11 +246,12 @@ const Game = { UI.applyMultiplierToDamage(damageNode, simpleDamageMultiplier(state.activeTechnique.types, state.enemy.monster.types)); UI.applyTechniqueToDamage(damageNode, state.activeTechnique); UI.drawDamage(damageNode); - UI.drawTechniqueAnimation(); + UI.drawTechniqueAnimation(technique); }); } - else if (techniqueEffect === 'money') { + // money + else if (techniqueEffect.type === 'money') { Game.phases.action.push(() => { const money = Math.max(1, Math.floor(Math.random() * target.level)); state.money += money; @@ -94,34 +259,28 @@ const Game = { const damageNode = UI.createDamage(`${money} €`); UI.applyTechniqueToDamage(damageNode, state.activeTechnique); UI.drawDamage(damageNode); - UI.drawTechniqueAnimation(); + UI.drawTechniqueAnimation(technique); }); } - else if (techniqueEffect === 'enhance') { - UI.drawTechniqueAnimation(); + // healing + else if (techniqueEffect.type === 'healing') { + techniqueEffect.recipient.hp = techniqueEffect.recipient.stats.hp; } - // status effect - else if (techniqueEffect.includes('status_')) { - const statusEffect_recipient = techniqueEffect.split(',')[1]; - const statusEffect_application = techniqueEffect.split(' ')[0]; - const statusEffect_type = techniqueEffect.split(',')[0].split(' ')[1].split('_')[0]; - const statusEffect_effect = techniqueEffect.split(',')[0].split(' ')[1].split('_')[1]; + // enhance + else if (techniqueEffect.type === 'enhance') { + UI.drawTechniqueAnimation(technique); + } - const statusEffect = await fetchStatusEffect(statusEffect_effect); + // status effect + else if (techniqueEffect.type === 'status') { + const statusEffect = await fetchStatusEffect(techniqueEffect.statusEffect); if (statusEffect.slug === 'lifeleech') { statusEffect.issuer = user; } - let recipient; - if (statusEffect_recipient === 'user') { - recipient = user; - } else { - recipient = target; - } - Game.phases.postAction.push(() => { // add status effect const potency = Math.random(); @@ -129,22 +288,17 @@ const Game = { if (success) { // TODO: check replace - if (recipient.statusEffect) return; + if (techniqueEffect.recipient.statusEffect) return; - recipient.statusEffect = statusEffect; + techniqueEffect.recipient.statusEffect = statusEffect; } }); - UI.drawTechniqueAnimation(); + UI.drawTechniqueAnimation(technique); } } }, - rechargeTechnique () { - const feedbackNode = UI.createActionFeedback('recharge'); - UI.drawActionFeedback(feedbackNode); - }, - /** * @param {Monster} monster */ @@ -288,15 +442,7 @@ const Game = { async battleClick (event) { UI.battleClickEvent = event; - // hit? - const accuracy = Math.random(); - Game.didTechniqueHit = state.activeTechnique.accuracy >= accuracy; - - if (state.activeTechnique.isUsable()) { - await Game.useTechnique(state.activeTechnique, state.activeMonster, state.enemy.monster); - } else { - Game.rechargeTechnique(); - } + await Game.tryUseTechnique(state.activeTechnique, state.activeMonster, state.enemy.monster); Game.progressTurn(); }, @@ -338,182 +484,9 @@ const Game = { Game.spawnEnemyMonster(); }, - - /** - * @returns {string} - */ - save () { - const saveMonster = (monsterData, monsterState) => { - monsterData.level = monsterState.level; - monsterData.hp = monsterState.hp; - - if (monsterData.statusEffect && monsterData.statusEffect.slug === 'lifeleech') { - monsterData.statusEffect = null; - } - - return monsterData; - }; - - const saveData = JSON.parse(JSON.stringify(state)); - - for (const idx in saveData.monsters) { - saveData.monsters[idx] = saveMonster(saveData.monsters[idx], state.monsters[idx]); - } - - for (const idx in saveData.partyMonsters) { - saveData.partyMonsters[idx] = saveMonster(saveData.partyMonsters[idx], state.partyMonsters[idx]); - } - - saveData.activeMonsterIdx = state.partyMonsters.indexOf(state.activeMonster); - - saveData.enemy.monster = saveMonster(saveData.enemy.monster, state.enemy.monster); - - return btoa(JSON.stringify(saveData)); - }, - - /** - * @param {string} saveData - */ - async load (saveData) { - /** - * @param {Monster} monsterData - */ - const loadMonster = async (monsterData) => { - const monster = await fetchMonster(monsterData.slug); - - monster.level = monsterData.level; - monster.hp = monsterData.hp; - monster.exp = monsterData.exp; - monster.tasteWarm = monsterData.tasteWarm; - monster.tasteCold = monsterData.tasteCold; - monster.gender = monsterData.gender; - monster.heldItem = await loadItem(monsterData.heldItem); - monster.statusEffect = await loadStatusEffect(monsterData.statusEffect); - monster.statModifiers = monsterData.statModifiers; - monster.experienceModifier = monsterData.experienceModifier; - monster.moneyModifier = monsterData.moneyModifier; - monster.activeTechniques = await Promise.all(monsterData.activeTechniques.map(async (technique) => { - return loadTechnique(technique); - })); - - return monster; - }; - - /** - * @param {InventoryItem} inventoryItemData - */ - const loadInventoryItem = async (inventoryItemData) => { - const inventoryItem = new InventoryItem(await fetchItem(inventoryItemData.item.slug)); - - inventoryItem.quantity = inventoryItemData.quantity; - - return inventoryItem; - }; - - /** - * @param {Item} itemData - */ - const loadItem = async (itemData) => { - if (!itemData) { - return null; - } - - const item = await fetchItem(itemData.slug); - - return item; - }; - - /** - * @param {StatusEffect} statusEffectData - */ - const loadStatusEffect = async (statusEffectData) => { - if (!statusEffectData) { - return null; - } - - const statusEffect = await fetchStatusEffect(statusEffectData.slug); - - statusEffect.turnsLeft = statusEffectData.turnsLeft; - - return statusEffect; - }; - - /** - * @param {Technique} techniqueData - */ - const loadTechnique = async (techniqueData) => { - const technique = await fetchTechnique(techniqueData.slug); - - return technique; - }; - - /** - * @type {State} - */ - const loadedState = JSON.parse(atob(saveData)); - - state.money = loadedState.money; - state.monsters = await Promise.all(loadedState.monsters.map(async (monsterData) => await loadMonster(monsterData))); - state.inventory = await Promise.all(loadedState.inventory.map(async (itemData) => await loadInventoryItem(itemData))); - state.partyMonsters = await Promise.all(loadedState.partyMonsters.map(async (monsterData) => await loadMonster(monsterData))); - state.activeMonster = state.partyMonsters[loadedState.activeMonsterIdx]; - state.activeTechnique = await loadTechnique(loadedState.activeTechnique); - state.enemy.monster = await loadMonster(loadedState.enemy.monster); - - UI.drawEnemyMonster(); - UI.drawActiveMonster(); - UI.drawActiveTechniques(); - }, }; // Game click bindings UI.elements.battleEnemy.addEventListener('click', Game.battleClick); UI.elements.techniques.addEventListener('click', Game.techniqueClick); UI.elements.menuCatch.addEventListener('click', Game.catchMonster); - - -(async function () { - await initializeDB(); - - const possibleStarterMonsters = ['budaye', 'dollfin', 'grintot', 'ignibus', 'memnomnom']; - - // state.enemy.monster = await fetchMonster('grintot'); - state.enemy.monster = await fetchMonster(possibleStarterMonsters[Math.round(Math.random() * (possibleStarterMonsters.length - 1))]); - - state.partyMonsters = [ - await fetchMonster('dollfin'), - await fetchMonster(possibleStarterMonsters[Math.round(Math.random() * (possibleStarterMonsters.length - 1))]), - await fetchMonster('corvix'), - await fetchMonster('lunight'), - await fetchMonster('prophetoise'), - await fetchMonster('drashimi'), - await fetchMonster('glombroc'), - await fetchMonster('uneye'), - await fetchMonster('nostray'), - await fetchMonster('dragarbor'), - await fetchMonster('mk01_omega'), - ]; - - state.activeMonster = state.partyMonsters[0]; - state.activeTechnique = state.activeMonster.activeTechniques[0]; - - state.inventory = [ - new InventoryItem(await fetchItem('tuxeball')), - new InventoryItem(await fetchItem('ancient_egg')), - new InventoryItem(await fetchItem('sweet_sand')), - new InventoryItem(await fetchItem('tectonic_drill')), - new InventoryItem(await fetchItem('surfboard')), - new InventoryItem(await fetchItem('sledgehammer')), - new InventoryItem(await fetchItem('raise_melee')), - new InventoryItem(await fetchItem('raise_speed')), - new InventoryItem(await fetchItem('mm_fire')), - new InventoryItem(await fetchItem('mm_water')), - new InventoryItem(await fetchItem('cureall')), - new InventoryItem(await fetchItem('potion')), - new InventoryItem(await fetchItem('super_potion')), - ]; - - UI.drawEnemyMonster(); - UI.drawActiveMonster(); - UI.drawActiveTechniques(); -})(); |