« get me outta code hell

'knownActions' property for battle characters - csb-game - Pixelly spin-off of the Command Synergy Battle system used in Final Fantasy XIII
summary refs log tree commit diff
path: root/index.js
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2018-08-16 15:40:26 -0300
committerFlorrie <towerofnix@gmail.com>2018-08-16 15:40:28 -0300
commit1815db2bc3cc4572b68aa4df0428763af62b6607 (patch)
tree1572a68cec6fdb07d936584d6f444564bc070a8a /index.js
parent95fa9eda8c260ce73bad889e6c2a0e03e6a7d0b3 (diff)
'knownActions' property for battle characters
Also tweaked Cure to be a lot weaker.
Diffstat (limited to 'index.js')
-rw-r--r--index.js78
1 files changed, 51 insertions, 27 deletions
diff --git a/index.js b/index.js
index abc5d46..fa9df29 100644
--- a/index.js
+++ b/index.js
@@ -4,20 +4,20 @@ const canvas = document.getElementById('canvas')
 
 const last = arr => arr[arr.length - 1]
 
+const chainDatabase = {
+  fire: ['fire', 'fira', 'firaga'],
+  cure: ['cure'],
+  blizz: ['blizz', 'blizzara', 'blizzaga']
+}
+
 const actionDatabase = {
-  fire: [
-    {id: 'fire',   chain: 'fire', label: 'Fire',   size: 1, target: 'enemy', color: '#F77'},
-    {id: 'fira',   chain: 'fire', label: 'Fira',   size: 2, target: 'enemy', color: '#F77'},
-    {id: 'firaga', chain: 'fire', label: 'Firaga', size: 3, target: 'enemy', color: '#F77'}
-  ],
-  cure: [
-    {id: 'cure', chain: 'cure', label: 'Cure', size: 1, target: 'ally', color: '#AFA'}
-  ],
-  blizz: [
-    {id: 'blizz',    chain: 'blizz', label: 'Blizz',    size: 1, target: 'enemy', color: '#AAF'},
-    {id: 'blizzara', chain: 'blizz', label: 'Blizzara', size: 2, target: 'enemy', color: '#AAF'},
-    {id: 'blizzaga', chain: 'blizz', label: 'Blizzaga', size: 3, target: 'enemy', color: '#AAF'}
-  ]
+  fire: {id: 'fire',   chain: 'fire', label: 'Fire',   size: 1, target: 'enemy', color: '#F77'},
+  fira: {id: 'fira',   chain: 'fire', label: 'Fira',   size: 2, target: 'enemy', color: '#F77'},
+  firaga: {id: 'firaga', chain: 'fire', label: 'Firaga', size: 3, target: 'enemy', color: '#F77'},
+  cure: {id: 'cure', chain: 'cure', label: 'Cure', size: 1, target: 'ally', color: '#AFA'},
+  blizz: {id: 'blizz',    chain: 'blizz', label: 'Blizz',    size: 1, target: 'enemy', color: '#AAF'},
+  blizzara: {id: 'blizzara', chain: 'blizz', label: 'Blizzara', size: 2, target: 'enemy', color: '#AAF'},
+  blizzaga: {id: 'blizzaga', chain: 'blizz', label: 'Blizzaga', size: 3, target: 'enemy', color: '#AAF'}
 }
 
 class Sprite {
@@ -186,7 +186,7 @@ class ATBBar {
     if (!this.battleCharacter.isExecutingChain && this.battleCharacter.targetCharacter && this.getRemainingSpace() >= 0) {
       // TODO: More moves
       while (this.getRemainingSpace()) {
-        this.enqueue(actionDatabase.fire[0])
+        this.enqueue(actionDatabase.fire)
       }
     }
 
@@ -404,21 +404,41 @@ class BaseBattleMenu {
 }
 
 class ActionMenu extends BaseBattleMenu {
-  constructor(battle, targetType) {
-    super({
-      options: Object.values(actionDatabase)
-        .filter(chain => chain[0].target === targetType) // Assume all actions have the same target type
-        .map(chain => ({chain, levelTexts: chain.map(action => action.label)}))
-    })
+  constructor({battle, battleCharacter, targetType}) {
+    super({options: []})
 
     this.battle = battle
-    this.uiLevel = 2 // 1-3 -- which of "fire", "fira", "firaga" is selected.
+    this.battleCharacter = battleCharacter
+    this.targetType = targetType
+    this.uiLevel = 1 // 1-3 -- which of "fire", "fira", "firaga" is selected.
+  }
+
+  buildOptions() {
+    const chains = {}
+    const otherAbilities = []
+
+    for (const action of this.battleCharacter.knownActions.map(actionID => actionDatabase[actionID]).filter(action => action.target === this.targetType)) {
+      if (action.chain) {
+        if (chains[action.chain]) {
+          chains[action.chain]++
+        } else {
+          chains[action.chain] = 1
+        }
+      } else {
+        otherAbilities.push(action)
+      }
+    }
+
+    this.options = [
+      ...Object.entries(chains).map(([ chainID, numLearned ]) => chainDatabase[chainID].slice(0, numLearned).map(actionID => actionDatabase[actionID])),
+      ...otherAbilities.map(ability => [ability])
+    ].map(chain => ({chain}))
   }
 
   drawOption(option, ctx) {
     const maxLevel = this.getMaxLevel(option)
     const effectiveLevel = this.getEffectiveLevel(option)
-    option.label = option.levelTexts[effectiveLevel - 1]
+    option.label = option.chain[effectiveLevel - 1].label
     if (effectiveLevel < maxLevel) {
       const ghostRectW = this.getLevelW(maxLevel)
       ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'
@@ -438,7 +458,7 @@ class ActionMenu extends BaseBattleMenu {
   }
 
   getMaxLevel(option) {
-    return option.levelTexts.length
+    return option.chain.length
   }
 
   getLevelW(level) {
@@ -500,8 +520,8 @@ class BattleCharacter extends Sprite {
     this.atbBar = new ATBBar(this)
     this.image.src = 'img/char.png'
 
-    this.targetAllyActionMenu = new ActionMenu(battle, 'ally')
-    this.targetEnemyActionMenu = new ActionMenu(battle, 'enemy')
+    this.targetAllyActionMenu = new ActionMenu({battle, battleCharacter: this, targetType: 'ally'})
+    this.targetEnemyActionMenu = new ActionMenu({battle, battleCharacter: this, targetType: 'enemy'})
 
     // State
 
@@ -550,6 +570,9 @@ class BattleCharacter extends Sprite {
     // passes a certain threshold. For example, while a single light attack may
     // not significantly stun a character, a persistent barrage may be able to.
     this.stunIsSignificant = null
+
+    // Array of action IDs.
+    this.knownActions = []
   }
 
   update(dt) {
@@ -890,6 +913,7 @@ class Battle {
     } else {
       this.currentMenu = this.playerCharacter.targetAllyActionMenu
     }
+    this.currentMenu.buildOptions()
   }
 
   showTargetMenu() {
@@ -1006,7 +1030,7 @@ class MagicProjectile {
         this.target.takeDamage(this.action.size * 20)
         this.target.addStunTime([0.1, 0.25, 0.4][this.action.size - 1])
       } else if (this.action.id === 'cure') {
-        this.target.recoverHP(200)
+        this.target.recoverHP(40)
       }
       this.discarded = true
     }
@@ -1069,7 +1093,7 @@ class SlideacrossMessage {
 const battle = new Battle({
   teamData: [
     {characterData: [
-      {x: -70, y: 200, name: 'Ren'}
+      {x: -70, y: 200, name: 'Ren', knownActions: ['fire', 'fira', 'firaga', 'blizz', 'blizzara', 'blizzaga', 'cure']}
     ]},
     {characterData: [
       {x: 70, y: 200, name: 'Manasvin Warmech'}