VOID PAL_BattleStartFrame( VOID ) /*++ Purpose: Called once per video frame in battle. Parameters: None. Return value: None. --*/ { int i; int iMax; BOOL fEnded; WORD wPlayerRole; WORD wDexterity; FLOAT flMax; PAL_BattleUpdateFighters(); // // Update the scene // PAL_BattleMakeScene(); SDL_BlitSurface(g_Battle.lpSceneBuf, NULL, gpScreen, NULL); // // Check if the battle is over // fEnded = TRUE; for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++) { if (g_Battle.rgEnemy[i].wObjectID != 0) { fEnded = FALSE; break; } } if (fEnded) { // // All enemies are cleared. Won the battle. // g_Battle.BattleResult = kBattleResultWon; SOUND_Play(-1); return; } else { fEnded = TRUE; for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { wPlayerRole = gpGlobals->rgParty[i].wPlayerRole; if (gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole] != 0 || gpGlobals->rgPlayerStatus[wPlayerRole][kStatusPuppet] != 0) { fEnded = FALSE; break; } } if (fEnded) { // // All players are dead. Lost the battle. // g_Battle.BattleResult = kBattleResultLost; return; } } // // Run the logic for all enemies // for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++) { if (g_Battle.rgEnemy[i].wObjectID == 0) { continue; } if (g_Battle.rgEnemy[i].fTurnStart) { g_Battle.rgEnemy[i].wScriptOnTurnStart = PAL_RunTriggerScript(g_Battle.rgEnemy[i].wScriptOnTurnStart, i); g_Battle.rgEnemy[i].fTurnStart = FALSE; } } for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++) { if (g_Battle.rgEnemy[i].wObjectID == 0) { continue; } switch (g_Battle.rgEnemy[i].state) { case kFighterWait: flMax = PAL_GetTimeChargingSpeed(PAL_GetEnemyDexterity(i)); if (flMax != 0) { g_Battle.rgEnemy[i].flTimeMeter += flMax; if (g_Battle.rgEnemy[i].flTimeMeter > 100 && flMax > 0) { g_Battle.rgEnemy[i].state = kFighterCom; } } break; case kFighterCom: g_Battle.rgEnemy[i].wScriptOnReady = PAL_RunTriggerScript(g_Battle.rgEnemy[i].wScriptOnReady, i); g_Battle.rgEnemy[i].state = kFighterAct; break; case kFighterAct: ////TEST/////////////////////////////////////////////////////////// SOUND_Play(g_Battle.rgEnemy[i].e.wAttackSound); if (g_Battle.rgEnemy[i].fFirstMoveDone) PAL_BattleUIShowText(va("enemy %d attack (2nd)",i), 500); else PAL_BattleUIShowText(va("enemy %d attack",i), 500); g_Battle.rgEnemy[i].flTimeMeter =0; g_Battle.rgEnemy[i].state = kFighterWait; //////////////////////////////////////////////////////////////////// if (!g_Battle.rgEnemy[i].fFirstMoveDone) { if (g_Battle.rgEnemy[i].e.wDualMove >= 2 || (g_Battle.rgEnemy[i].e.wDualMove != 0 && RandomLong(0, 1))) { g_Battle.rgEnemy[i].flTimeMeter = 100; g_Battle.rgEnemy[i].state = kFighterWait; g_Battle.rgEnemy[i].fFirstMoveDone = TRUE; break; } } g_Battle.rgEnemy[i].fFirstMoveDone = FALSE; g_Battle.rgEnemy[i].fTurnStart = TRUE; break; } } // // Update the battle UI // PAL_BattleUIUpdate(); // // Run the logic for all players // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { wPlayerRole = gpGlobals->rgParty[i].wPlayerRole; // // Skip dead players // if (gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole] == 0 && gpGlobals->rgPlayerStatus[wPlayerRole][kStatusPuppet] == 0) { g_Battle.rgPlayer[i].state = kFighterWait; g_Battle.rgPlayer[i].flTimeMeter = 0; continue; } switch (g_Battle.rgPlayer[i].state) { case kFighterWait: wDexterity = PAL_GetPlayerActualDexterity(wPlayerRole); g_Battle.rgPlayer[i].flTimeMeter += PAL_GetTimeChargingSpeed(wDexterity) * g_Battle.rgPlayer[i].flTimeSpeedModifier; break; case kFighterCom: if (g_Battle.UI.state == kBattleUIWait) { PAL_BattleUIPlayerReady(i); } break; case kFighterAct: wDexterity = PAL_GetPlayerActualDexterity(wPlayerRole); g_Battle.rgPlayer[i].action.flRemainingTime -= PAL_GetTimeChargingSpeed(wDexterity); if (g_Battle.rgPlayer[i].action.flRemainingTime < 0) { // // Perform the action for this player. // PAL_BattlePlayerPerformAction(i); // // Reduce the time for other players when uses coopmagic // if (g_Battle.rgPlayer[i].action.ActionType == kBattleActionCoopMagic) { for (iMax = 0; iMax <= gpGlobals->wMaxPartyMemberIndex; iMax++) { g_Battle.rgPlayer[iMax].flTimeMeter = 0; g_Battle.rgPlayer[iMax].flTimeSpeedModifier = 2.0f; } } else { g_Battle.rgPlayer[i].flTimeMeter = 0; } // // Revert this player back to waiting state. // g_Battle.rgPlayer[i].state = kFighterWait; g_Battle.rgPlayer[i].flTimeSpeedModifier = 1.0f; } break; } } // // Start the UI for the fastest and ready player // flMax = 0; iMax = 0; for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { if (g_Battle.rgPlayer[i].state == kFighterCom || (g_Battle.rgPlayer[i].state == kFighterAct && g_Battle.rgPlayer[i].action.ActionType == kBattleActionCoopMagic)) { flMax = 0; break; } else if (g_Battle.rgPlayer[i].state == kFighterWait) { if (g_Battle.rgPlayer[i].flTimeMeter > flMax) { iMax = i; flMax = g_Battle.rgPlayer[i].flTimeMeter; } } } if (flMax > 100.0f) { g_Battle.rgPlayer[iMax].state = kFighterCom; g_Battle.rgPlayer[iMax].fDefending = FALSE; } ////TEST/////////////////////////////////////////////////////////-START if (g_InputState.dwKeyPress & kKeyFlee){ for (i = 0; i < 5; i++){ gpGlobals->g.PlayerRoles.rgwHP[i] = 0; } return; } ////TEST/////////////////////////////////////////////////////////-END }
VOID PAL_BattleUIUpdate( VOID ) /*++ Purpose: Update the status of battle UI. Parameters: None. Return value: None. --*/ { int i, j, x, y; WORD wPlayerRole, w; static int s_iFrame = 0; s_iFrame++; if (g_Battle.UI.fAutoAttack && !gpGlobals->fAutoBattle) { // // Draw the "auto attack" message if in the autoattack mode. // if (g_InputState.dwKeyPress & kKeyMenu) { g_Battle.UI.fAutoAttack = FALSE; } else { PAL_DrawText(PAL_GetWord(BATTLEUI_LABEL_AUTO), PAL_XY(280, 10), MENUITEM_COLOR_CONFIRMED, TRUE, FALSE); } } if (gpGlobals->fAutoBattle) { PAL_BattlePlayerCheckReady(); for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { if (g_Battle.rgPlayer[i].state == kFighterCom) { PAL_BattleUIPlayerReady(i); break; } } if (g_Battle.UI.state != kBattleUIWait) { w = PAL_BattleUIPickAutoMagic(gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole, 9999); if (w == 0) { g_Battle.UI.wActionType = kBattleActionAttack; g_Battle.UI.wSelectedIndex = PAL_BattleSelectAutoTarget(); } else { g_Battle.UI.wActionType = kBattleActionMagic; g_Battle.UI.wObjectID = w; if (gpGlobals->g.rgObject[w].magic.wFlags & kMagicFlagApplyToAll) { g_Battle.UI.wSelectedIndex = -1; } else { g_Battle.UI.wSelectedIndex = PAL_BattleSelectAutoTarget(); } } PAL_BattleCommitAction(FALSE); } goto end; } if (g_InputState.dwKeyPress & kKeyAuto) { g_Battle.UI.fAutoAttack = !g_Battle.UI.fAutoAttack; g_Battle.UI.MenuState = kBattleMenuMain; } #ifdef PAL_CLASSIC if (g_Battle.Phase == kBattlePhasePerformAction) { goto end; } if (!g_Battle.UI.fAutoAttack) #endif { // // Draw the player info boxes. // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { wPlayerRole = gpGlobals->rgParty[i].wPlayerRole; w = F2int(g_Battle.rgPlayer[i].flTimeMeter); j = TIMEMETER_COLOR_DEFAULT; #ifndef PAL_CLASSIC if (gpGlobals->rgPlayerStatus[wPlayerRole][kStatusHaste] > 0) { j = TIMEMETER_COLOR_HASTE; } else if (gpGlobals->rgPlayerStatus[wPlayerRole][kStatusSlow] > 0) { j = TIMEMETER_COLOR_SLOW; } #endif if (gpGlobals->rgPlayerStatus[wPlayerRole][kStatusSleep] != 0 || gpGlobals->rgPlayerStatus[wPlayerRole][kStatusConfused] != 0 || gpGlobals->rgPlayerStatus[wPlayerRole][kStatusPuppet] != 0) { w = 0; } PAL_PlayerInfoBox(PAL_XY(91 + 77 * i, 165), wPlayerRole, w, j, FALSE); } } if (g_InputState.dwKeyPress & kKeyStatus) { PAL_PlayerStatus(); goto end; } if (g_Battle.UI.state != kBattleUIWait) { wPlayerRole = gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole; if (gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole] == 0 && gpGlobals->rgPlayerStatus[wPlayerRole][kStatusPuppet]) { g_Battle.UI.wActionType = kBattleActionAttack; if (PAL_PlayerCanAttackAll(gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole)) { g_Battle.UI.wSelectedIndex = -1; } else { g_Battle.UI.wSelectedIndex = PAL_BattleSelectAutoTarget(); } PAL_BattleCommitAction(FALSE); goto end; // don't go further } // // Cancel any actions if player is dead or sleeping. // if (gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole] == 0 || gpGlobals->rgPlayerStatus[wPlayerRole][kStatusSleep] != 0 || gpGlobals->rgPlayerStatus[wPlayerRole][kStatusParalyzed] != 0) { g_Battle.UI.wActionType = kBattleActionPass; PAL_BattleCommitAction(FALSE); goto end; // don't go further } if (gpGlobals->rgPlayerStatus[wPlayerRole][kStatusConfused] != 0) { g_Battle.UI.wActionType = kBattleActionAttackMate; PAL_BattleCommitAction(FALSE); goto end; // don't go further } if (g_Battle.UI.fAutoAttack) { g_Battle.UI.wActionType = kBattleActionAttack; if (PAL_PlayerCanAttackAll(gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole)) { g_Battle.UI.wSelectedIndex = -1; } else { g_Battle.UI.wSelectedIndex = PAL_BattleSelectAutoTarget(); } PAL_BattleCommitAction(FALSE); goto end; // don't go further } // // Draw the arrow on the player's head. // i = SPRITENUM_BATTLE_ARROW_CURRENTPLAYER_RED; if (s_iFrame & 1) { i = SPRITENUM_BATTLE_ARROW_CURRENTPLAYER; } x = g_rgPlayerPos[gpGlobals->wMaxPartyMemberIndex][g_Battle.UI.wCurPlayerIndex][0] - 8; y = g_rgPlayerPos[gpGlobals->wMaxPartyMemberIndex][g_Battle.UI.wCurPlayerIndex][1] - 74; PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, i), gpScreen, PAL_XY(x, y)); } switch (g_Battle.UI.state) { case kBattleUIWait: if (!g_Battle.fEnemyCleared) { PAL_BattlePlayerCheckReady(); for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { if (g_Battle.rgPlayer[i].state == kFighterCom) { PAL_BattleUIPlayerReady(i); break; } } } break; case kBattleUISelectMove: // // Draw the icons // { struct { int iSpriteNum; PAL_POS pos; BATTLEUIACTION action; } rgItems[] = { {SPRITENUM_BATTLEICON_ATTACK, PAL_XY(27, 140), kBattleUIActionAttack}, {SPRITENUM_BATTLEICON_MAGIC, PAL_XY(0, 155), kBattleUIActionMagic}, {SPRITENUM_BATTLEICON_COOPMAGIC, PAL_XY(54, 155), kBattleUIActionCoopMagic}, {SPRITENUM_BATTLEICON_MISCMENU, PAL_XY(27, 170), kBattleUIActionMisc} }; if (g_Battle.UI.MenuState == kBattleMenuMain) { if (g_InputState.dir == kDirNorth) { g_Battle.UI.wSelectedAction = 0; } else if (g_InputState.dir == kDirSouth) { g_Battle.UI.wSelectedAction = 3; } else if (g_InputState.dir == kDirWest) { if (PAL_BattleUIIsActionValid(kBattleUIActionMagic)) { g_Battle.UI.wSelectedAction = 1; } } else if (g_InputState.dir == kDirEast) { if (PAL_BattleUIIsActionValid(kBattleUIActionCoopMagic)) { g_Battle.UI.wSelectedAction = 2; } } } if (!PAL_BattleUIIsActionValid(rgItems[g_Battle.UI.wSelectedAction].action)) { g_Battle.UI.wSelectedAction = 0; } for (i = 0; i < 4; i++) { if (g_Battle.UI.wSelectedAction == i) { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, rgItems[i].iSpriteNum), gpScreen, rgItems[i].pos); } else if (PAL_BattleUIIsActionValid(rgItems[i].action)) { PAL_RLEBlitMonoColor(PAL_SpriteGetFrame(gpSpriteUI, rgItems[i].iSpriteNum), gpScreen, rgItems[i].pos, 0, -4); } else { PAL_RLEBlitMonoColor(PAL_SpriteGetFrame(gpSpriteUI, rgItems[i].iSpriteNum), gpScreen, rgItems[i].pos, 0x10, -4); } } switch (g_Battle.UI.MenuState) { case kBattleMenuMain: if (g_InputState.dwKeyPress & kKeySearch) { switch (g_Battle.UI.wSelectedAction) { case 0: // // Attack // g_Battle.UI.wActionType = kBattleActionAttack; if (PAL_PlayerCanAttackAll(gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole)) { g_Battle.UI.state = kBattleUISelectTargetEnemyAll; } else { g_Battle.UI.wSelectedIndex = g_Battle.UI.wPrevEnemyTarget; g_Battle.UI.state = kBattleUISelectTargetEnemy; } break; case 1: // // Magic // g_Battle.UI.MenuState = kBattleMenuMagicSelect; PAL_MagicSelectionMenuInit(wPlayerRole, TRUE, 0); break; case 2: // // Cooperative magic // w = gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole; w = PAL_GetPlayerCooperativeMagic(w); g_Battle.UI.wActionType = kBattleActionCoopMagic; g_Battle.UI.wObjectID = w; if (gpGlobals->g.rgObject[w].magic.wFlags & kMagicFlagUsableToEnemy) { if (gpGlobals->g.rgObject[w].magic.wFlags & kMagicFlagApplyToAll) { g_Battle.UI.state = kBattleUISelectTargetEnemyAll; } else { g_Battle.UI.wSelectedIndex = g_Battle.UI.wPrevEnemyTarget; g_Battle.UI.state = kBattleUISelectTargetEnemy; } } else { if (gpGlobals->g.rgObject[w].magic.wFlags & kMagicFlagApplyToAll) { g_Battle.UI.state = kBattleUISelectTargetPlayerAll; } else { #ifdef PAL_CLASSIC g_Battle.UI.wSelectedIndex = 0; #else g_Battle.UI.wSelectedIndex = g_Battle.UI.wCurPlayerIndex; #endif g_Battle.UI.state = kBattleUISelectTargetPlayer; } } break; case 3: // // Misc menu // g_Battle.UI.MenuState = kBattleMenuMisc; g_iCurMiscMenuItem = 0; break; } } else if (g_InputState.dwKeyPress & kKeyDefend) { g_Battle.UI.wActionType = kBattleActionDefend; PAL_BattleCommitAction(FALSE); } else if (g_InputState.dwKeyPress & kKeyForce) { w = PAL_BattleUIPickAutoMagic(gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole, 60); if (w == 0) { g_Battle.UI.wActionType = kBattleActionAttack; if (PAL_PlayerCanAttackAll(gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole)) { g_Battle.UI.wSelectedIndex = -1; } else { g_Battle.UI.wSelectedIndex = PAL_BattleSelectAutoTarget(); } } else { g_Battle.UI.wActionType = kBattleActionMagic; g_Battle.UI.wObjectID = w; if (gpGlobals->g.rgObject[w].magic.wFlags & kMagicFlagApplyToAll) { g_Battle.UI.wSelectedIndex = -1; } else { g_Battle.UI.wSelectedIndex = PAL_BattleSelectAutoTarget(); } } PAL_BattleCommitAction(FALSE); } else if (g_InputState.dwKeyPress & kKeyFlee) { g_Battle.UI.wActionType = kBattleActionFlee; PAL_BattleCommitAction(FALSE); } else if (g_InputState.dwKeyPress & kKeyUseItem) { g_Battle.UI.MenuState = kBattleMenuUseItemSelect; PAL_ItemSelectMenuInit(kItemFlagUsable); } else if (g_InputState.dwKeyPress & kKeyThrowItem) { g_Battle.UI.MenuState = kBattleMenuThrowItemSelect; PAL_ItemSelectMenuInit(kItemFlagThrowable); } else if (g_InputState.dwKeyPress & kKeyRepeat) { PAL_BattleCommitAction(TRUE); } #ifdef PAL_CLASSIC else if (g_InputState.dwKeyPress & kKeyMenu) { g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].state = kFighterWait; g_Battle.UI.state = kBattleUIWait; if (g_Battle.UI.wCurPlayerIndex > 0) { // // Revert to the previous player // do { g_Battle.rgPlayer[--g_Battle.UI.wCurPlayerIndex].state = kFighterWait; if (g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.ActionType == kBattleActionThrowItem) { for (i = 0; i < MAX_INVENTORY; i++) { if (gpGlobals->rgInventory[i].wItem == g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.wActionID) { gpGlobals->rgInventory[i].nAmountInUse--; break; } } } else if (g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.ActionType == kBattleActionUseItem) { if (gpGlobals->g.rgObject[g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.wActionID].item.wFlags & kItemFlagConsuming) { for (i = 0; i < MAX_INVENTORY; i++) { if (gpGlobals->rgInventory[i].wItem == g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].action.wActionID) { gpGlobals->rgInventory[i].nAmountInUse--; break; } } } } } while (g_Battle.UI.wCurPlayerIndex > 0 && (gpGlobals->g.PlayerRoles.rgwHP[gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole] == 0 || gpGlobals->rgPlayerStatus[gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole][kStatusConfused] > 0 || gpGlobals->rgPlayerStatus[gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole][kStatusSleep] > 0 || gpGlobals->rgPlayerStatus[gpGlobals->rgParty[g_Battle.UI.wCurPlayerIndex].wPlayerRole][kStatusParalyzed] > 0)); } } #else else if (g_InputState.dwKeyPress & kKeyMenu) { FLOAT flMin = int2F(-1); j = -1; for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { if (g_Battle.rgPlayer[i].flTimeMeter >= 100) { g_Battle.rgPlayer[i].flTimeMeter += 100; // HACKHACK: Prevent the time meter from going below 100 if ((g_Battle.rgPlayer[i].flTimeMeter < flMin || flMin < 0) && i != (int)g_Battle.UI.wCurPlayerIndex && g_Battle.rgPlayer[i].state == kFighterWait) { flMin = g_Battle.rgPlayer[i].flTimeMeter; j = i; } } } if (j != -1) { g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].flTimeMeter = flMin - int2F(99); g_Battle.rgPlayer[g_Battle.UI.wCurPlayerIndex].state = kFighterWait; g_Battle.UI.state = kBattleUIWait; } } #endif break; case kBattleMenuMagicSelect: w = PAL_MagicSelectionMenuUpdate(); if (w != 0xFFFF) { g_Battle.UI.MenuState = kBattleMenuMain; if (w != 0) { g_Battle.UI.wActionType = kBattleActionMagic; g_Battle.UI.wObjectID = w; if (gpGlobals->g.rgObject[w].magic.wFlags & kMagicFlagUsableToEnemy) { if (gpGlobals->g.rgObject[w].magic.wFlags & kMagicFlagApplyToAll) { g_Battle.UI.state = kBattleUISelectTargetEnemyAll; } else { g_Battle.UI.wSelectedIndex = g_Battle.UI.wPrevEnemyTarget; g_Battle.UI.state = kBattleUISelectTargetEnemy; } } else { if (gpGlobals->g.rgObject[w].magic.wFlags & kMagicFlagApplyToAll) { g_Battle.UI.state = kBattleUISelectTargetPlayerAll; } else { #ifdef PAL_CLASSIC g_Battle.UI.wSelectedIndex = 0; #else g_Battle.UI.wSelectedIndex = g_Battle.UI.wCurPlayerIndex; #endif g_Battle.UI.state = kBattleUISelectTargetPlayer; } } } } break; case kBattleMenuUseItemSelect: PAL_BattleUIUseItem(); break; case kBattleMenuThrowItemSelect: PAL_BattleUIThrowItem(); break; case kBattleMenuMisc: w = PAL_BattleUIMiscMenuUpdate(); if (w != 0xFFFF) { g_Battle.UI.MenuState = kBattleMenuMain; switch (w) { #ifdef PAL_CLASSIC case 2: // item #else case 1: // item #endif g_Battle.UI.MenuState = kBattleMenuMiscItemSubMenu; g_iCurSubMenuItem = 0; break; #ifdef PAL_CLASSIC case 3: // defend #else case 2: // defend #endif g_Battle.UI.wActionType = kBattleActionDefend; PAL_BattleCommitAction(FALSE); break; #ifdef PAL_CLASSIC case 1: // auto #else case 3: // auto #endif g_Battle.UI.fAutoAttack = TRUE; break; case 4: // flee g_Battle.UI.wActionType = kBattleActionFlee; PAL_BattleCommitAction(FALSE); break; case 5: // status PAL_PlayerStatus(); break; } } break; case kBattleMenuMiscItemSubMenu: w = PAL_BattleUIMiscItemSubMenuUpdate(); if (w != 0xFFFF) { g_Battle.UI.MenuState = kBattleMenuMain; switch (w) { case 1: // use g_Battle.UI.MenuState = kBattleMenuUseItemSelect; PAL_ItemSelectMenuInit(kItemFlagUsable); break; case 2: // throw g_Battle.UI.MenuState = kBattleMenuThrowItemSelect; PAL_ItemSelectMenuInit(kItemFlagThrowable); break; } } break; } } break; case kBattleUISelectTargetEnemy: x = -1; y = 0; for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++) { if (g_Battle.rgEnemy[i].wObjectID != 0) { x = i; y++; } } if (x == -1) { g_Battle.UI.state = kBattleUISelectMove; break; } if (g_Battle.UI.wActionType == kBattleActionCoopMagic) { if (!PAL_BattleUIIsActionValid(kBattleActionCoopMagic)) { g_Battle.UI.state = kBattleUISelectMove; break; } } #ifdef PAL_CLASSIC // // Don't bother selecting when only 1 enemy left // if (y == 1) { g_Battle.UI.wPrevEnemyTarget = (WORD)x; PAL_BattleCommitAction(FALSE); break; } #endif if (g_Battle.UI.wSelectedIndex > x) { g_Battle.UI.wSelectedIndex = x; } for (i = 0; i <= x; i++) { if (g_Battle.rgEnemy[g_Battle.UI.wSelectedIndex].wObjectID != 0) { break; } g_Battle.UI.wSelectedIndex++; g_Battle.UI.wSelectedIndex %= x + 1; } // // Highlight the selected enemy // if (s_iFrame & 1) { i = g_Battle.UI.wSelectedIndex; x = PAL_X(g_Battle.rgEnemy[i].pos); y = PAL_Y(g_Battle.rgEnemy[i].pos); x -= PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame)) / 2; y -= PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame)); PAL_RLEBlitWithColorShift(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame), gpScreen, PAL_XY(x, y), 7); } if (g_InputState.dwKeyPress & kKeyMenu) { g_Battle.UI.state = kBattleUISelectMove; } else if (g_InputState.dwKeyPress & kKeySearch) { g_Battle.UI.wPrevEnemyTarget = g_Battle.UI.wSelectedIndex; PAL_BattleCommitAction(FALSE); } else if (g_InputState.dwKeyPress & (kKeyLeft | kKeyDown)) { if (g_Battle.UI.wSelectedIndex != 0) { g_Battle.UI.wSelectedIndex--; while (g_Battle.UI.wSelectedIndex != 0 && g_Battle.rgEnemy[g_Battle.UI.wSelectedIndex].wObjectID == 0) { g_Battle.UI.wSelectedIndex--; } } } else if (g_InputState.dwKeyPress & (kKeyRight | kKeyUp)) { if (g_Battle.UI.wSelectedIndex < x) { g_Battle.UI.wSelectedIndex++; while (g_Battle.UI.wSelectedIndex < x && g_Battle.rgEnemy[g_Battle.UI.wSelectedIndex].wObjectID == 0) { g_Battle.UI.wSelectedIndex++; } } } break; case kBattleUISelectTargetPlayer: #ifdef PAL_CLASSIC // // Don't bother selecting when only 1 player is in the party // if (gpGlobals->wMaxPartyMemberIndex == 0) { g_Battle.UI.wSelectedIndex = 0; PAL_BattleCommitAction(FALSE); } #endif j = SPRITENUM_BATTLE_ARROW_SELECTEDPLAYER; if (s_iFrame & 1) { j = SPRITENUM_BATTLE_ARROW_SELECTEDPLAYER_RED; } // // Draw arrows on the selected player // x = g_rgPlayerPos[gpGlobals->wMaxPartyMemberIndex][g_Battle.UI.wSelectedIndex][0] - 8; y = g_rgPlayerPos[gpGlobals->wMaxPartyMemberIndex][g_Battle.UI.wSelectedIndex][1] - 67; PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, j), gpScreen, PAL_XY(x, y)); if (g_InputState.dwKeyPress & kKeyMenu) { g_Battle.UI.state = kBattleUISelectMove; } else if (g_InputState.dwKeyPress & kKeySearch) { PAL_BattleCommitAction(FALSE); } else if (g_InputState.dwKeyPress & (kKeyLeft | kKeyDown)) { if (g_Battle.UI.wSelectedIndex != 0) { g_Battle.UI.wSelectedIndex--; } else { g_Battle.UI.wSelectedIndex = gpGlobals->wMaxPartyMemberIndex; } } else if (g_InputState.dwKeyPress & (kKeyRight | kKeyUp)) { if (g_Battle.UI.wSelectedIndex < gpGlobals->wMaxPartyMemberIndex) { g_Battle.UI.wSelectedIndex++; } else { g_Battle.UI.wSelectedIndex = 0; } } break; case kBattleUISelectTargetEnemyAll: #ifdef PAL_CLASSIC // // Don't bother selecting // g_Battle.UI.wSelectedIndex = (WORD)-1; PAL_BattleCommitAction(FALSE); #else if (g_Battle.UI.wActionType == kBattleActionCoopMagic) { if (!PAL_BattleUIIsActionValid(kBattleActionCoopMagic)) { g_Battle.UI.state = kBattleUISelectMove; break; } } if (s_iFrame & 1) { // // Highlight all enemies // for (i = g_Battle.wMaxEnemyIndex; i >= 0; i--) { if (g_Battle.rgEnemy[i].wObjectID == 0) { continue; } x = PAL_X(g_Battle.rgEnemy[i].pos); y = PAL_Y(g_Battle.rgEnemy[i].pos); x -= PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame)) / 2; y -= PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame)); PAL_RLEBlitWithColorShift(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame), gpScreen, PAL_XY(x, y), 7); } } if (g_InputState.dwKeyPress & kKeyMenu) { g_Battle.UI.state = kBattleUISelectMove; } else if (g_InputState.dwKeyPress & kKeySearch) { g_Battle.UI.wSelectedIndex = (WORD)-1; PAL_BattleCommitAction(FALSE); } #endif break; case kBattleUISelectTargetPlayerAll: #ifdef PAL_CLASSIC // // Don't bother selecting // g_Battle.UI.wSelectedIndex = (WORD)-1; PAL_BattleCommitAction(FALSE); #else j = SPRITENUM_BATTLE_ARROW_SELECTEDPLAYER; if (s_iFrame & 1) { j = SPRITENUM_BATTLE_ARROW_SELECTEDPLAYER_RED; } for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { if (g_Battle.UI.wActionType == kBattleActionMagic) { w = gpGlobals->g.rgObject[g_Battle.UI.wObjectID].magic.wMagicNumber; if (gpGlobals->g.lprgMagic[w].wType == kMagicTypeTrance) { if (i != g_Battle.UI.wCurPlayerIndex) continue; } } // // Draw arrows on all players, despite of dead or not // x = g_rgPlayerPos[gpGlobals->wMaxPartyMemberIndex][i][0] - 8; y = g_rgPlayerPos[gpGlobals->wMaxPartyMemberIndex][i][1] - 67; PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, j), gpScreen, PAL_XY(x, y)); } if (g_InputState.dwKeyPress & kKeyMenu) { g_Battle.UI.state = kBattleUISelectMove; } else if (g_InputState.dwKeyPress & kKeySearch) { g_Battle.UI.wSelectedIndex = (WORD)-1; PAL_BattleCommitAction(FALSE); } #endif break; } end: // // Show the text message if there is one. // #ifndef PAL_CLASSIC if (SDL_GetTicks() < g_Battle.UI.dwMsgShowTime) { // // The text should be shown in a small window at the center of the screen // PAL_POS pos; int len = strlen(g_Battle.UI.szMsg); // // Create the window box // pos = PAL_XY(160 - len * 4, 40); PAL_CreateSingleLineBox(pos, (len + 1) / 2, FALSE); // // Show the text on the screen // pos = PAL_XY(PAL_X(pos) + 8 + ((len & 1) << 2), PAL_Y(pos) + 10); PAL_DrawText(g_Battle.UI.szMsg, pos, 0, FALSE, FALSE); } else if (g_Battle.UI.szNextMsg[0] != '\0') { strcpy(g_Battle.UI.szMsg, g_Battle.UI.szNextMsg); g_Battle.UI.dwMsgShowTime = SDL_GetTicks() + g_Battle.UI.wNextMsgDuration; g_Battle.UI.szNextMsg[0] = '\0'; } #endif // // Draw the numbers // for (i = 0; i < BATTLEUI_MAX_SHOWNUM; i++) { if (g_Battle.UI.rgShowNum[i].wNum > 0) { if ((SDL_GetTicks() - g_Battle.UI.rgShowNum[i].dwTime) / BATTLE_FRAME_TIME > 10) { g_Battle.UI.rgShowNum[i].wNum = 0; } else { PAL_DrawNumber(g_Battle.UI.rgShowNum[i].wNum, 5, PAL_XY(PAL_X(g_Battle.UI.rgShowNum[i].pos), PAL_Y(g_Battle.UI.rgShowNum[i].pos) - (SDL_GetTicks() - g_Battle.UI.rgShowNum[i].dwTime) / BATTLE_FRAME_TIME), g_Battle.UI.rgShowNum[i].color, kNumAlignRight); } } } PAL_ClearKeyState(); }