« get me outta code hell

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:
Diffstat (limited to 'index.js')
-rw-r--r--index.js60
1 files changed, 43 insertions, 17 deletions
diff --git a/index.js b/index.js
index 01902c5..be34775 100644
--- a/index.js
+++ b/index.js
@@ -563,7 +563,8 @@ class TargetMenu extends BaseBattleMenu {
 
     // If the top action is a 'cure' action, pick the character with the least health by default.
     // TODO: Some property like "healsAlive" on the action itself, so things like potions (which target one) are also affected by this
-    if (last(this.battle.playerCharacter.atbBar.queuedActions).chain === 'cure') {
+    const lastAction = last(this.battle.playerCharacter.atbBar.queuedActions)
+    if (lastAction && lastAction.chain === 'cure') {
       const allies = this.battle.playerCharacter.team.characters
       const aliveCharacter = allies.find(c => !c.dead)
       const mostHurtCharacter = allies.reduce((a, b) => (b.hp < a.hp && !b.dead ? b : a), aliveCharacter)
@@ -836,10 +837,12 @@ class Battle {
     this.playerCharacter = this.teams[0].characters[0]
 
     this.targetMenu = new TargetMenu(this)
+    this.targetLeaderMenu = new TargetMenu(this)
 
     this.targetTypeMenu = new BaseBattleMenu({options: [
       {label: 'Aggression', targetType: 'enemy'},
-      {label: 'Reinforcement', targetType: 'ally'}
+      {label: 'Reinforcement', targetType: 'ally'},
+      {label: 'Change Leader', changeLeader: true}
     ]})
 
     this.backdrop = new Backdrop()
@@ -1029,15 +1032,7 @@ class Battle {
 
     // Assign a new player character if the current one died
     if (this.playerCharacter.dead) {
-      const newCharacter = this.playerCharacter.team.characters.find(c => !c.dead)
-      if (newCharacter) {
-        this.playerCharacter = newCharacter
-        this.camera.follow(newCharacter)
-        newCharacter.atbBar.queuedActions.splice(0)
-        newCharacter.isExecutingChain = false
-        this.showTargetTypeMenu()
-        this.slideacrossMessage.showMessage('Leader changed: ' + newCharacter.name)
-      }
+      this.changeLeader(this.playerCharacter.team.characters.find(c => !c.dead))
     }
 
     // SOMEHOW managed to have all teams die in the same instant? Player wins :)
@@ -1050,6 +1045,17 @@ class Battle {
     }
   }
 
+  changeLeader(newCharacter) {
+    if (newCharacter) {
+      this.playerCharacter = newCharacter
+      this.camera.follow(newCharacter)
+      newCharacter.atbBar.queuedActions.splice(0)
+      newCharacter.isExecutingChain = false
+      this.showTargetTypeMenu()
+      this.slideacrossMessage.showMessage('Leader changed: ' + newCharacter.name)
+    }
+  }
+
   preWinUpdate(dt) {
     this.preEndUpdate(dt, 'win')
   }
@@ -1087,6 +1093,14 @@ class Battle {
     this.targetMenu.buildOptions(this.playerCharacter.targetType)
   }
 
+  showTargetLeaderMenu() {
+    this.changeMenuAnim = {old: this.currentMenu, direction: 1, time: 1}
+    this.currentMenu = this.targetLeaderMenu
+    this.targetLeaderMenu.buildOptions('ally')
+    // TODO: This may need tweaking when there's 3+ characters
+    this.targetLeaderMenu.currentOptionIndex = this.targetLeaderMenu.options.findIndex(opt => opt.battleCharacter !== this.playerCharacter)
+  }
+
   hideCurrentMenu() {
     this.changeMenuAnim = {old: this.currentMenu, direction: 1, time: 1}
     this.currentMenu = null
@@ -1319,7 +1333,7 @@ canvas.addEventListener('keypress', evt => {
     return
   }
 
-  const { targetTypeMenu, actionMenu, targetMenu, currentMenu } = battle
+  const { targetTypeMenu, actionMenu, targetMenu, targetLeaderMenu, currentMenu } = battle
   const { atbBar } = battle.playerCharacter
 
   if (currentMenu) {
@@ -1332,12 +1346,17 @@ canvas.addEventListener('keypress', evt => {
 
   if (currentMenu === targetTypeMenu) {
     if (evt.keyCode === 13 || evt.which === 32) {
-      const newTargetType = targetTypeMenu.getCurrentOption().targetType
-      if (battle.playerCharacter.targetType !== newTargetType) {
-        battle.playerCharacter.targetType = newTargetType
-        atbBar.queuedActions.splice(0) // Changed target type, empty queue
+      const option = targetTypeMenu.getCurrentOption()
+      if (option.changeLeader) {
+        battle.showTargetLeaderMenu()
+      } else {
+        const newTargetType = option.targetType
+        if (battle.playerCharacter.targetType !== newTargetType) {
+          battle.playerCharacter.targetType = newTargetType
+          atbBar.queuedActions.splice(0) // Changed target type, empty queue
+        }
+        battle.showActionMenu({direction: 1})
       }
-      battle.showActionMenu({direction: 1})
     } else if (evt.keyCode === 8 && battle.playerCharacter.targetType) {
       if (battle.playerCharacter.isExecutingChain || battle.playerCharacter.willExecuteChain) {
         battle.hideCurrentMenu()
@@ -1366,6 +1385,13 @@ canvas.addEventListener('keypress', evt => {
           battle.showTargetMenu()
         }
       }
+    } else if (currentMenu === targetLeaderMenu) {
+      if (evt.keyCode === 13 || evt.which === 32) {
+        const option = targetLeaderMenu.getCurrentOption()
+        battle.changeLeader(option.battleCharacter)
+      } else if (evt.keyCode === 8) {
+        battle.showTargetTypeMenu()
+      }
     } else if (currentMenu instanceof TargetMenu) {
       if (evt.keyCode === 13 || evt.key.toLowerCase() === 'e' || evt.which === 32) {
         battle.playerCharacter.targetCharacter = currentMenu.getCurrentOption().battleCharacter