From 0007e50506ebaa61554bfd11e98581dada7e0cdd Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Tue, 15 Aug 2023 15:10:04 +0200 Subject: animations!! --- script.js | 110 +++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 88 insertions(+), 22 deletions(-) (limited to 'script.js') diff --git a/script.js b/script.js index c5c2028..ee8414d 100644 --- a/script.js +++ b/script.js @@ -1,5 +1,6 @@ const DB = { allMonsters: [], + allAnimations: {}, monsters: {}, shapes: {}, elements: {}, @@ -74,7 +75,6 @@ class Monster { tasteWarm = TasteWarm.tasteless; tasteCold = TasteCold.tasteless; - name = ''; gender = ''; statusModifiers = { @@ -163,16 +163,16 @@ class Monster { ); } - canEvolve () { - if (this.evolutions.length === 0) { - return; - } + getPossibleEvolutions () { + return this.evolutions.filter((evolution) => this.level >= evolution.at_level && (!evolution.item || this.heldItem === evolution.item)); + } - return this.level >= this.evolutions[0].at_level; + canEvolve () { + return this.getPossibleEvolutions().length > 0; } evolve () { - const evolution = this.evolutions[0]; + const evolution = this.getPossibleEvolutions[0]; const statusPreEvolve = this.status; const hpPreEvolve = this.hp; @@ -264,6 +264,10 @@ class Technique { get range () { return DB.techniques[this.slug].range; } + + get animation () { + return DB.techniques[this.slug].animation; + } } function simpleDamageMultiplier (techniqueTypes, targetTypes) { @@ -374,13 +378,14 @@ function slugToName (slug) { (async function () { DB.allMonsters = await fetch('/db/all-monsters.json').then((response) => response.json()); + DB.allAnimations = await fetch('/db/animations.json').then((response) => response.json()); DB.shapes = await fetch('/modules/tuxemon/mods/tuxemon/db/shape/shapes.json').then((response) => response.json()); for (const element of Object.keys(ElementType)) { DB.elements[element] = await fetch(`/modules/tuxemon/mods/tuxemon/db/element/${element}.json`).then((response) => response.json()); } const state = new State(); - state.enemy.monster = await fetchMonster('drashimi'); + state.enemy.monster = await fetchMonster('grintot'); state.partyMonsters = [ await fetchMonster('corvix'), @@ -407,6 +412,9 @@ function slugToName (slug) { const UI = { activeMonster: null, + damageAnimationInterval: null, + damageAnimationNumber: 0, + getTemplate (template) { var tpl = document.createElement('div'); tpl.innerHTML = template.trim(); @@ -449,8 +457,8 @@ function slugToName (slug) { const damageMultiplier = simpleDamageMultiplier(state.activeTechnique.types, state.enemy.monster.types); damageNode.style.fontSize = damageMultiplier + 'rem'; - damageNode.style.left = event.pageX - battleEnemy.offsetLeft; - damageNode.style.top = event.pageY - battleEnemy.offsetTop; + damageNode.style.top = event.pageY - battleEnemy.offsetTop + (Math.random() * 40 - 20); + damageNode.style.left = event.pageX - battleEnemy.offsetLeft + (Math.random() * 40 - 20); damageNode.style.color = mixColors(...state.activeTechnique.types.map((type) => standardizeColor(ElementTypeColor[type]))); @@ -460,12 +468,33 @@ function slugToName (slug) { battleEnemy.appendChild(damageNode); setTimeout(() => damageNode.remove(), (damageNodeDuration * 1000) - 500); - const enemyImg = battleEnemy.querySelector('img'); + const enemyImg = battleEnemy.querySelector('.battle__monster-img'); const imgClickDuration = 0.1; enemyImg.style.transitionDuration = imgClickDuration + 's'; enemyImg.classList.add('damaged'); clearTimeout(clickTimeout); clickTimeout = setTimeout(() => enemyImg.classList.remove('damaged'), imgClickDuration * 1000); + + var enemyAnimation = battleEnemy.querySelector('.battle__monster-sprite__animation'); + // enemyAnimation.style.top = enemyImg.getBoundingClientRect().top; + // enemyAnimation.style.left = enemyImg.getBoundingClientRect().left; + if (!this.damageAnimationInterval) { + this.damageAnimationInterval = setInterval(() => { + enemyAnimation.src = `/modules/tuxemon/mods/tuxemon/animations/technique/${state.activeTechnique.animation}_0${this.damageAnimationNumber}.png`; + enemyAnimation.style.top = event.clientY - (enemyAnimation.clientHeight / 2); + enemyAnimation.style.left = event.clientX - (enemyAnimation.clientWidth / 2); + console.log(enemyAnimation.src); + + this.damageAnimationNumber++; + + if (this.damageAnimationNumber === DB.allAnimations[state.activeTechnique.animation].length) { + clearInterval(this.damageAnimationInterval); + this.damageAnimationInterval = null; + this.damageAnimationNumber = 0; + enemyAnimation.src = ''; + } + }, 50); + } }, addPartyMonster (slug) { @@ -476,22 +505,30 @@ function slugToName (slug) { partyMonster.dataset.slug = slug; partyMonster.querySelector('img').src = `/modules/tuxemon/mods/tuxemon/gfx/sprites/battle/${slug}-front.png`; - partyMonster.addEventListener('click', async (event) => { + partyMonster.addEventListener('click', (event) => { let target = event.target; while (target.parentNode.id !== 'party') { target = target.parentNode; } state.activeMonster = state.partyMonsters[Array.prototype.indexOf.call(document.querySelector('#party').children, target)]; - state.activeTechnique = await fetchTechnique(state.activeMonster.moveset[0].technique); - - UI.setBattleMonster(state.activeMonster, 'player'); + UI.setActiveMonster(); }); partyMonster.style.cursor = 'pointer'; party.appendChild(partyMonster); }, + async setActiveMonster () { + let activeMoveIndex = 0; + while ((await fetchTechnique(state.activeMonster.moveset[activeMoveIndex].technique)).power === 0) { + activeMoveIndex++; + } + state.activeTechnique = await fetchTechnique(state.activeMonster.moveset[activeMoveIndex].technique); + + UI.setBattleMonster(state.activeMonster, 'player'); + }, + setBattleMonster (monster, where) { let battleMonster = document.createElement('div'); battleMonster.innerHTML = templateBattleMonster.trim(); @@ -526,22 +563,43 @@ function slugToName (slug) { const movesetList = UI.getTemplate(templateMovesetList); for (const move of state.activeMonster.moveset) { const technique = await fetchTechnique(move.technique); + + if (technique.power === 0) { + continue; + } + const movesetItem = UI.getTemplate(templateMovesetItem); - movesetItem.textContent = slugToName(technique.slug) + ' - ' + technique.types + ' - ' + technique.power; + movesetItem.textContent = slugToName(technique.slug) + ' - ' + technique.types + ' - ' + technique.power + ' - ' + move.level_learned; movesetItem.addEventListener('click', () => { + if (movesetItem.getAttribute('disabled')) { + return false; + } + state.activeTechnique = technique; UI.setBattleMonster(state.activeMonster, 'player'); popup.remove(); }); + if (state.activeMonster.level < move.level_learned) { + movesetItem.setAttribute('disabled', true); + } + movesetList.appendChild(movesetItem); } popup.querySelector('.popup').appendChild(movesetList); document.body.appendChild(popup); }, + + async createNewEnemyMonster () { + state.enemy.monster = await fetchMonster(DB.allMonsters[Math.floor(Math.random() * DB.allMonsters.length)]); + state.enemy.monster.level = Math.ceil(Math.random() * state.activeMonster.level); + // state.enemy.monster.experienceModifier = state.enemy.monster.level; + state.enemy.monster.moneyModifier = state.enemy.monster.level; + UI.setBattleMonster(state.enemy.monster, 'enemy'); + }, }; for (const monster of state.partyMonsters) { @@ -550,6 +608,7 @@ function slugToName (slug) { UI.setBattleMonster(state.activeMonster, 'player'); UI.setBattleMonster(state.enemy.monster, 'enemy'); + UI.setActiveMonster(); var clickTimeout; document.querySelector('#battle__enemy').addEventListener('click', async (event) => { @@ -560,19 +619,16 @@ function slugToName (slug) { if (state.enemy.monster.hp <= 0) { const faintedMonster = state.enemy.monster; - state.enemy.monster = await fetchMonster(DB.allMonsters[Math.floor(Math.random() * DB.allMonsters.length)]); - state.enemy.monster.level = Math.ceil(Math.random() * state.activeMonster.level); - state.enemy.monster.moneyModifier = state.enemy.monster.level; - UI.setBattleMonster(state.enemy.monster, 'enemy'); + await UI.createNewEnemyMonster(); state.money += faintedMonster.level * faintedMonster.moneyModifier; - state.activeMonster.exp += calculateAwardedExperience(state.activeMonster, faintedMonster); + state.activeMonster.exp += calculateAwardedExperience(state.activeMonster, faintedMonster) * 50; state.activeMonster.levelUp(); if (state.activeMonster.canEvolve()) { await fetchMonster(state.activeMonster.evolutions[0].monster_slug); state.activeMonster.evolve(); - state.activeTechnique = await fetchTechnique(state.activeMonster.moveset[0].technique); + UI.setActiveMonster(); } UI.setBattleMonster(state.activeMonster, 'player'); @@ -580,4 +636,14 @@ function slugToName (slug) { UI.setHp(state.enemy.monster, battleEnemy); money.textContent = state.money; }); + + document.querySelector('#catch').addEventListener('click', async (event) => { + const caughtMonster = new Monster(state.enemy.monster.slug); + caughtMonster.level = state.enemy.monster.level; + + state.partyMonsters.push(caughtMonster); + + UI.createNewEnemyMonster(); + UI.addPartyMonster(caughtMonster.slug); + }); })(); -- cgit v1.2.3