static VOID PAL_SellMenu_OnItemChange( WORD wCurrentItem ) /*++ Purpose: Callback function which is called when player selected another item in the sell item menu. Parameters: [IN] wCurrentItem - current item on the menu, indicates the object ID of the currently selected item. Return value: None. --*/ { // // Draw the cash amount // PAL_CreateSingleLineBox(PAL_XY(100, 150), 5, FALSE); PAL_DrawText(PAL_GetWord(CASH_LABEL), PAL_XY(110, 160), 0, FALSE, FALSE); PAL_DrawNumber(gpGlobals->dwCash, 6, PAL_XY(149, 164), kNumColorYellow, kNumAlignRight); // // Draw the price // PAL_CreateSingleLineBox(PAL_XY(220, 150), 5, FALSE); if (gpGlobals->g.rgObject[wCurrentItem].item.wFlags & kItemFlagSellable) { PAL_DrawText(PAL_GetWord(SELLMENU_LABEL_PRICE), PAL_XY(230, 160), 0, FALSE, FALSE); PAL_DrawNumber(gpGlobals->g.rgObject[wCurrentItem].item.wPrice / 2, 6, PAL_XY(269, 164), kNumColorYellow, kNumAlignRight); } }
LPBOX PAL_ShowCash( DWORD dwCash ) /*++ Purpose: Show the cash amount at the top left corner of the screen. Parameters: [IN] dwCash - amount of cash. Return value: pointer to the saved screen part. --*/ { LPBOX lpBox; // // Create the box. // lpBox = PAL_CreateSingleLineBox(PAL_XY(0, 0), 5, TRUE); if (lpBox == NULL) { return NULL; } // // Draw the text label. // PAL_DrawText(PAL_GetWord(CASH_LABEL), PAL_XY(10, 10), 0, FALSE, FALSE); // // Draw the cash amount. // PAL_DrawNumber(dwCash, 6, PAL_XY(49, 14), kNumColorYellow, kNumAlignRight); return lpBox; }
/*++ Show the "you win" message and add the experience points for players. --*/ static VOID PAL_BattleWon(void) { const SDL_Rect rect = {65, 60, 200, 100}; const SDL_Rect rect1 = {80, 0, 180, 200}; int i, j, iTotalCount; DWORD dwExp; WORD w; BOOL fLevelUp; PLAYERROLES OrigPlayerRoles; // // Backup the initial player stats // OrigPlayerRoles = gpGlobals->g.PlayerRoles; if (g_Battle.iExpGained > 0) { // // Play the "battle win" music // PAL_PlayMUS(g_Battle.fIsBoss ? 2 : 3, FALSE, 0); // // Show the message about the total number of exp. and cash gained // PAL_CreateSingleLineBox(PAL_XY(83, 60), 8, FALSE); PAL_CreateSingleLineBox(PAL_XY(65, 105), 10, FALSE); PAL_DrawText(PAL_GetWord(BATTLEWIN_GETEXP_LABEL), PAL_XY(95, 70), 0, FALSE, FALSE); PAL_DrawText(PAL_GetWord(BATTLEWIN_BEATENEMY_LABEL), PAL_XY(77, 115), 0, FALSE, FALSE); PAL_DrawText(PAL_GetWord(BATTLEWIN_DOLLAR_LABEL), PAL_XY(197, 115), 0, FALSE, FALSE); PAL_DrawNumber(g_Battle.iExpGained, 5, PAL_XY(182, 74), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(g_Battle.iCashGained, 5, PAL_XY(162, 119), kNumColorYellow, kNumAlignMid); VIDEO_UpdateScreen(&rect); PAL_WaitForKey(g_Battle.fIsBoss ? 5500 : 3000); } // // Add the cash value // gpGlobals->dwCash += g_Battle.iCashGained; // // Add the experience points for each players // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { fLevelUp = FALSE; w = gpGlobals->rgParty[i].wPlayerRole; if (gpGlobals->g.PlayerRoles.rgwHP[w] == 0) { continue; // don't care about dead players } dwExp = gpGlobals->Exp.rgPrimaryExp[w].wExp; dwExp += g_Battle.iExpGained; if (gpGlobals->g.PlayerRoles.rgwLevel[w] > MAX_LEVELS) { gpGlobals->g.PlayerRoles.rgwLevel[w] = MAX_LEVELS; } while (dwExp >= gpGlobals->g.rgLevelUpExp[gpGlobals->g.PlayerRoles.rgwLevel[w]]) { dwExp -= gpGlobals->g.rgLevelUpExp[gpGlobals->g.PlayerRoles.rgwLevel[w]]; if (gpGlobals->g.PlayerRoles.rgwLevel[w] < MAX_LEVELS) { fLevelUp = TRUE; PAL_PlayerLevelUp(w, 1); gpGlobals->g.PlayerRoles.rgwHP[w] = gpGlobals->g.PlayerRoles.rgwMaxHP[w]; gpGlobals->g.PlayerRoles.rgwMP[w] = gpGlobals->g.PlayerRoles.rgwMaxMP[w]; } } gpGlobals->Exp.rgPrimaryExp[w].wExp = (WORD)dwExp; if (fLevelUp) { // // Player has gained a level. Show the message // PAL_CreateSingleLineBox(PAL_XY(80, 0), 10, FALSE); PAL_CreateBox(PAL_XY(82, 32), 7, 8, 1, FALSE); PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[w]), PAL_XY(110, 10), 0, FALSE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_LEVEL), PAL_XY(110 + 16 * 3, 10), 0, FALSE, FALSE); PAL_DrawText(PAL_GetWord(BATTLEWIN_LEVELUP_LABEL), PAL_XY(110 + 16 * 5, 10), 0, FALSE, FALSE); for (j = 0; j < 8; j++) { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_ARROW), gpScreen, PAL_XY(183, 48 + 18 * j)); } PAL_DrawText(PAL_GetWord(STATUS_LABEL_LEVEL), PAL_XY(100, 44), BATTLEWIN_LEVELUP_LABEL_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_HP), PAL_XY(100, 62), BATTLEWIN_LEVELUP_LABEL_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_MP), PAL_XY(100, 80), BATTLEWIN_LEVELUP_LABEL_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_ATTACKPOWER), PAL_XY(100, 98), BATTLEWIN_LEVELUP_LABEL_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_MAGICPOWER), PAL_XY(100, 116), BATTLEWIN_LEVELUP_LABEL_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_RESISTANCE), PAL_XY(100, 134), BATTLEWIN_LEVELUP_LABEL_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_DEXTERITY), PAL_XY(100, 152), BATTLEWIN_LEVELUP_LABEL_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_FLEERATE), PAL_XY(100, 170), BATTLEWIN_LEVELUP_LABEL_COLOR, TRUE, FALSE); // // Draw the original stats and stats after level up // PAL_DrawNumber(OrigPlayerRoles.rgwLevel[w], 4, PAL_XY(133, 47), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwLevel[w], 4, PAL_XY(195, 47), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(OrigPlayerRoles.rgwHP[w], 4, PAL_XY(133, 64), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(OrigPlayerRoles.rgwMaxHP[w], 4, PAL_XY(154, 68), kNumColorBlue, kNumAlignRight); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(156, 66)); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwHP[w], 4, PAL_XY(195, 64), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxHP[w], 4, PAL_XY(216, 68), kNumColorBlue, kNumAlignRight); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(218, 66)); PAL_DrawNumber(OrigPlayerRoles.rgwMP[w], 4, PAL_XY(133, 82), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(OrigPlayerRoles.rgwMaxMP[w], 4, PAL_XY(154, 86), kNumColorBlue, kNumAlignRight); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(156, 84)); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMP[w], 4, PAL_XY(195, 82), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxMP[w], 4, PAL_XY(216, 86), kNumColorBlue, kNumAlignRight); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(218, 84)); PAL_DrawNumber(OrigPlayerRoles.rgwAttackStrength[w] + PAL_GetPlayerAttackStrength(w) - gpGlobals->g.PlayerRoles.rgwAttackStrength[w], 4, PAL_XY(133, 101), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerAttackStrength(w), 4, PAL_XY(195, 101), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(OrigPlayerRoles.rgwMagicStrength[w] + PAL_GetPlayerMagicStrength(w) - gpGlobals->g.PlayerRoles.rgwMagicStrength[w], 4, PAL_XY(133, 119), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerMagicStrength(w), 4, PAL_XY(195, 119), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(OrigPlayerRoles.rgwDefense[w] + PAL_GetPlayerDefense(w) - gpGlobals->g.PlayerRoles.rgwDefense[w], 4, PAL_XY(133, 137), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDefense(w), 4, PAL_XY(195, 137), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(OrigPlayerRoles.rgwDexterity[w] + PAL_GetPlayerDexterity(w) - gpGlobals->g.PlayerRoles.rgwDexterity[w], 4, PAL_XY(133, 155), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDexterity(w), 4, PAL_XY(195, 155), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(OrigPlayerRoles.rgwFleeRate[w] + PAL_GetPlayerFleeRate(w) - gpGlobals->g.PlayerRoles.rgwFleeRate[w], 4, PAL_XY(133, 173), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerFleeRate(w), 4, PAL_XY(195, 173), kNumColorYellow, kNumAlignRight); // // Update the screen and wait for key // VIDEO_UpdateScreen(&rect1); PAL_WaitForKey(3000); OrigPlayerRoles = gpGlobals->g.PlayerRoles; } // // Increasing of other hidden levels // iTotalCount = 0; iTotalCount += gpGlobals->Exp.rgAttackExp[w].wCount; iTotalCount += gpGlobals->Exp.rgDefenseExp[w].wCount; iTotalCount += gpGlobals->Exp.rgDexterityExp[w].wCount; iTotalCount += gpGlobals->Exp.rgFleeExp[w].wCount; iTotalCount += gpGlobals->Exp.rgHealthExp[w].wCount; iTotalCount += gpGlobals->Exp.rgMagicExp[w].wCount; iTotalCount += gpGlobals->Exp.rgMagicPowerExp[w].wCount; if (iTotalCount > 0) { #define CHECK_HIDDEN_EXP(expname, statname, label) \ { \ dwExp = g_Battle.iExpGained; \ dwExp *= gpGlobals->Exp.expname[w].wCount; \ dwExp /= iTotalCount; \ dwExp *= 2; \ \ dwExp += gpGlobals->Exp.expname[w].wExp; \ \ if (gpGlobals->Exp.expname[w].wLevel > MAX_LEVELS) \ { \ gpGlobals->Exp.expname[w].wLevel = MAX_LEVELS; \ } \ \ while (dwExp >= gpGlobals->g.rgLevelUpExp[gpGlobals->Exp.expname[w].wLevel]) \ { \ dwExp -= gpGlobals->g.rgLevelUpExp[gpGlobals->Exp.expname[w].wLevel]; \ gpGlobals->g.PlayerRoles.statname[w] += RandomLong(1, 2); \ if (gpGlobals->Exp.expname[w].wLevel < MAX_LEVELS) \ { \ gpGlobals->Exp.expname[w].wLevel++; \ } \ } \ \ gpGlobals->Exp.expname[w].wExp = (WORD)dwExp; \ \ if (gpGlobals->g.PlayerRoles.statname[w] != \ OrigPlayerRoles.statname[w]) \ { \ PAL_CreateSingleLineBox(PAL_XY(83, 60), 8, FALSE); \ PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[w]), PAL_XY(95, 70), \ 0, FALSE, FALSE); \ PAL_DrawText(PAL_GetWord(label), PAL_XY(143, 70), \ 0, FALSE, FALSE); \ PAL_DrawText(PAL_GetWord(BATTLEWIN_LEVELUP_LABEL), PAL_XY(175, 70), \ 0, FALSE, FALSE); \ PAL_DrawNumber(gpGlobals->g.PlayerRoles.statname[w] - \ OrigPlayerRoles.statname[w], \ 5, PAL_XY(188, 74), kNumColorYellow, kNumAlignRight); \ VIDEO_UpdateScreen(&rect); \ PAL_WaitForKey(3000); \ } \ } CHECK_HIDDEN_EXP(rgHealthExp, rgwMaxHP, STATUS_LABEL_HP); CHECK_HIDDEN_EXP(rgMagicExp, rgwMaxMP, STATUS_LABEL_MP); CHECK_HIDDEN_EXP(rgAttackExp, rgwAttackStrength, STATUS_LABEL_ATTACKPOWER); CHECK_HIDDEN_EXP(rgMagicPowerExp, rgwMagicStrength, STATUS_LABEL_MAGICPOWER); CHECK_HIDDEN_EXP(rgDefenseExp, rgwDefense, STATUS_LABEL_RESISTANCE); CHECK_HIDDEN_EXP(rgDexterityExp, rgwDexterity, STATUS_LABEL_DEXTERITY); CHECK_HIDDEN_EXP(rgFleeExp, rgwFleeRate, STATUS_LABEL_FLEERATE); #undef CHECK_HIDDEN_EXP } // // Learn all magics at the current level // j = 0; while (j < gpGlobals->g.nLevelUpMagic) { if (gpGlobals->g.lprgLevelUpMagic[j].m[w].wMagic == 0 || gpGlobals->g.lprgLevelUpMagic[j].m[w].wLevel > gpGlobals->g.PlayerRoles.rgwLevel[w]) { j++; continue; } if (PAL_AddMagic(w, gpGlobals->g.lprgLevelUpMagic[j].m[w].wMagic)) { PAL_CreateSingleLineBox(PAL_XY(65, 105), 10, FALSE); PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[w]), PAL_XY(75, 115), 0, FALSE, FALSE); PAL_DrawText(PAL_GetWord(BATTLEWIN_ADDMAGIC_LABEL), PAL_XY(75 + 16 * 3, 115), 0, FALSE, FALSE); PAL_DrawText(PAL_GetWord(gpGlobals->g.lprgLevelUpMagic[j].m[w].wMagic), PAL_XY(75 + 16 * 5, 115), 0x1B, FALSE, FALSE); VIDEO_UpdateScreen(&rect); PAL_WaitForKey(3000); } j++; } } // // Run the post-battle scripts // for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++) { PAL_RunTriggerScript(g_Battle.rgEnemy[i].wScriptOnBattleEnd, i); } // // Recover automatically after each battle // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { w = gpGlobals->rgParty[i].wPlayerRole; #if 1//def PAL_CLASSIC gpGlobals->g.PlayerRoles.rgwHP[w] += (gpGlobals->g.PlayerRoles.rgwMaxHP[w] - gpGlobals->g.PlayerRoles.rgwHP[w]) / 2; gpGlobals->g.PlayerRoles.rgwMP[w] += (gpGlobals->g.PlayerRoles.rgwMaxMP[w] - gpGlobals->g.PlayerRoles.rgwMP[w]) / 2; #else if (gpGlobals->g.PlayerRoles.rgwHP[w] == 0) { gpGlobals->g.PlayerRoles.rgwHP[w] = 1; } else if (g_Battle.iExpGained > 0) { FLOAT f = (gpGlobals->g.rgLevelUpExp[gpGlobals->g.PlayerRoles.rgwLevel[w]] / 5.0f) / g_Battle.iExpGained; if (f < 2) { f = 2; } gpGlobals->g.PlayerRoles.rgwHP[w] += (gpGlobals->g.PlayerRoles.rgwMaxHP[w] - gpGlobals->g.PlayerRoles.rgwHP[w]) / f; gpGlobals->g.PlayerRoles.rgwMP[w] += (gpGlobals->g.PlayerRoles.rgwMaxMP[w] - gpGlobals->g.PlayerRoles.rgwMP[w]) / f / 1.2; } #endif } }
WORD PAL_ItemSelectMenuUpdate( VOID ) /*++ Purpose: Initialize the item selection menu. Parameters: None. Return value: The object ID of the selected item. 0 if cancelled, 0xFFFF if not confirmed. --*/ { #ifndef PAL_WIN95 int i, j, k; WORD wObject; #else int i, j, k, line; WORD wObject, wScript; #endif BYTE bColor; static BYTE bufImage[2048]; static WORD wPrevImageIndex = 0xFFFF; // // Process input // if (g_InputState.dwKeyPress & kKeyUp) { gpGlobals->iCurInvMenuItem -= 3; } else if (g_InputState.dwKeyPress & kKeyDown) { gpGlobals->iCurInvMenuItem += 3; } else if (g_InputState.dwKeyPress & kKeyLeft) { gpGlobals->iCurInvMenuItem--; } else if (g_InputState.dwKeyPress & kKeyRight) { gpGlobals->iCurInvMenuItem++; } else if (g_InputState.dwKeyPress & kKeyPgUp) { gpGlobals->iCurInvMenuItem -= 3 * 7; } else if (g_InputState.dwKeyPress & kKeyPgDn) { gpGlobals->iCurInvMenuItem += 3 * 7; } else if (g_InputState.dwKeyPress & kKeyMenu) { return 0; } // // Make sure the current menu item index is in bound // if (gpGlobals->iCurInvMenuItem < 0) { gpGlobals->iCurInvMenuItem = 0; } else if (gpGlobals->iCurInvMenuItem >= g_iNumInventory) { gpGlobals->iCurInvMenuItem = g_iNumInventory - 1; } // // Redraw the box // PAL_CreateBox(PAL_XY(2, 0), 6, 17, 1, FALSE); // // Draw the texts in the current page // i = gpGlobals->iCurInvMenuItem / 3 * 3 - 3 * 4; if (i < 0) { i = 0; } for (j = 0; j < 7; j++) { for (k = 0; k < 3; k++) { wObject = gpGlobals->rgInventory[i].wItem; bColor = MENUITEM_COLOR; if (i >= MAX_INVENTORY || wObject == 0) { // // End of the list reached // j = 7; break; } if (i == gpGlobals->iCurInvMenuItem) { if (!(gpGlobals->g.rgObject[wObject].item.wFlags & g_wItemFlags) || (SHORT)gpGlobals->rgInventory[i].nAmount <= (SHORT)gpGlobals->rgInventory[i].nAmountInUse) { // // This item is not selectable // bColor = MENUITEM_COLOR_SELECTED_INACTIVE; } else { // // This item is selectable // if (gpGlobals->rgInventory[i].nAmount == 0) { bColor = MENUITEM_COLOR_EQUIPPEDITEM; } else { bColor = MENUITEM_COLOR_SELECTED; } } } else if (!(gpGlobals->g.rgObject[wObject].item.wFlags & g_wItemFlags) || (SHORT)gpGlobals->rgInventory[i].nAmount <= (SHORT)gpGlobals->rgInventory[i].nAmountInUse) { // // This item is not selectable // bColor = MENUITEM_COLOR_INACTIVE; } else if (gpGlobals->rgInventory[i].nAmount == 0) { bColor = MENUITEM_COLOR_EQUIPPEDITEM; } // // Draw the text // PAL_DrawText(PAL_GetWord(wObject), PAL_XY(15 + k * 100, 12 + j * 18), bColor, TRUE, FALSE); // // Draw the cursor on the current selected item // if (i == gpGlobals->iCurInvMenuItem) { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_CURSOR), gpScreen, PAL_XY(40 + k * 100, 22 + j * 18)); } // // Draw the amount of this item // if ((SHORT)gpGlobals->rgInventory[i].nAmount - (SHORT)gpGlobals->rgInventory[i].nAmountInUse > 1) { PAL_DrawNumber(gpGlobals->rgInventory[i].nAmount - gpGlobals->rgInventory[i].nAmountInUse, 2, PAL_XY(96 + k * 100, 17 + j * 18), kNumColorCyan, kNumAlignRight); } i++; } } // // Draw the picture of current selected item // PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_ITEMBOX), gpScreen, PAL_XY(5, 140)); wObject = gpGlobals->rgInventory[gpGlobals->iCurInvMenuItem].wItem; if (gpGlobals->g.rgObject[wObject].item.wBitmap != wPrevImageIndex) { if (PAL_MKFReadChunk(bufImage, 2048, gpGlobals->g.rgObject[wObject].item.wBitmap, gpGlobals->f.fpBALL) > 0) { wPrevImageIndex = gpGlobals->g.rgObject[wObject].item.wBitmap; } else { wPrevImageIndex = 0xFFFF; } } if (wPrevImageIndex != 0xFFFF) { PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(12, 148)); } // // Draw the description of the selected item // #ifndef PAL_WIN95 if (!g_fNoDesc && gpGlobals->lpObjectDesc != NULL) { char szDesc[512], *next; const char *d = PAL_GetObjectDesc(gpGlobals->lpObjectDesc, wObject); if (d != NULL) { k = 150; strcpy(szDesc, d); d = szDesc; while (TRUE) { next = strchr(d, '*'); if (next != NULL) { *next = '\0'; next++; } PAL_DrawText(d, PAL_XY(75, k), DESCTEXT_COLOR, TRUE, FALSE); k += 16; if (next == NULL) { break; } d = next; } } } #else if (!g_fNoDesc) { wScript = gpGlobals->g.rgObject[wObject].item.wScriptDesc; line = 0; while (wScript && gpGlobals->g.lprgScriptEntry[wScript].wOperation != 0) { if (gpGlobals->g.lprgScriptEntry[wScript].wOperation == 0xFFFF) { wScript = PAL_RunAutoScript(wScript, (1 << 15) | line); line++; } else { wScript = PAL_RunAutoScript(wScript, 0); } } } #endif if (g_InputState.dwKeyPress & kKeySearch) { if ((gpGlobals->g.rgObject[wObject].item.wFlags & g_wItemFlags) && (SHORT)gpGlobals->rgInventory[gpGlobals->iCurInvMenuItem].nAmount > (SHORT)gpGlobals->rgInventory[gpGlobals->iCurInvMenuItem].nAmountInUse) { if (gpGlobals->rgInventory[gpGlobals->iCurInvMenuItem].nAmount > 0) { j = (gpGlobals->iCurInvMenuItem < 3 * 4) ? (gpGlobals->iCurInvMenuItem / 3) : 4; k = gpGlobals->iCurInvMenuItem % 3; PAL_DrawText(PAL_GetWord(wObject), PAL_XY(15 + k * 100, 12 + j * 18), MENUITEM_COLOR_CONFIRMED, FALSE, FALSE); } return wObject; } } return 0xFFFF; }
WORD PAL_MagicSelectionMenuUpdate( VOID ) /*++ Purpose: Update the magic selection menu. Parameters: None. Return value: The selected magic. 0 if cancelled, 0xFFFF if not confirmed. --*/ { int i, j, k; BYTE bColor; // // Check for inputs // if (g_InputState.dwKeyPress & kKeyUp) { g_iCurrentItem -= 3; } else if (g_InputState.dwKeyPress & kKeyDown) { g_iCurrentItem += 3; } else if (g_InputState.dwKeyPress & kKeyLeft) { g_iCurrentItem--; } else if (g_InputState.dwKeyPress & kKeyRight) { g_iCurrentItem++; } else if (g_InputState.dwKeyPress & kKeyPgUp) { g_iCurrentItem -= 3 * 5; } else if (g_InputState.dwKeyPress & kKeyPgDn) { g_iCurrentItem += 3 * 5; } else if (g_InputState.dwKeyPress & kKeyMenu) { return 0; } // // Make sure the current menu item index is in bound // if (g_iCurrentItem < 0) { g_iCurrentItem = 0; } else if (g_iCurrentItem >= g_iNumMagic) { g_iCurrentItem = g_iNumMagic - 1; } // // Create the box. // PAL_CreateBox(PAL_XY(10, 42), 4, 16, 1, FALSE); if (gpGlobals->lpObjectDesc == NULL) { // // Draw the cash amount. // PAL_CreateSingleLineBox(PAL_XY(0, 0), 5, FALSE); PAL_DrawText(PAL_GetWord(CASH_LABEL), PAL_XY(10, 10), 0, FALSE, FALSE); PAL_DrawNumber(gpGlobals->dwCash, 6, PAL_XY(49, 14), kNumColorYellow, kNumAlignRight); // // Draw the MP of the selected magic. // PAL_CreateSingleLineBox(PAL_XY(215, 0), 5, FALSE); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(260, 14)); PAL_DrawNumber(rgMagicItem[g_iCurrentItem].wMP, 4, PAL_XY(230, 14), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(g_wPlayerMP, 4, PAL_XY(265, 14), kNumColorCyan, kNumAlignRight); } else { char szDesc[512], *next; const char *d = PAL_GetObjectDesc(gpGlobals->lpObjectDesc, rgMagicItem[g_iCurrentItem].wMagic); // // Draw the magic description. // if (d != NULL) { k = 3; strcpy(szDesc, d); d = szDesc; while (TRUE) { next = strchr(d, '*'); if (next != NULL) { *next = '\0'; next++; } PAL_DrawText(d, PAL_XY(100, k), DESCTEXT_COLOR, TRUE, FALSE); k += 16; if (next == NULL) { break; } d = next; } } // // Draw the MP of the selected magic. // PAL_CreateSingleLineBox(PAL_XY(0, 0), 5, FALSE); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(45, 14)); PAL_DrawNumber(rgMagicItem[g_iCurrentItem].wMP, 4, PAL_XY(15, 14), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(g_wPlayerMP, 4, PAL_XY(50, 14), kNumColorCyan, kNumAlignRight); } // // Draw the texts of the current page // i = g_iCurrentItem / 3 * 3 - 3 * 2; if (i < 0) { i = 0; } for (j = 0; j < 5; j++) { for (k = 0; k < 3; k++) { bColor = MENUITEM_COLOR; if (i >= g_iNumMagic) { // // End of the list reached // j = 5; break; } if (i == g_iCurrentItem) { if (rgMagicItem[i].fEnabled) { bColor = MENUITEM_COLOR_SELECTED; } else { bColor = MENUITEM_COLOR_SELECTED_INACTIVE; } } else if (!rgMagicItem[i].fEnabled) { bColor = MENUITEM_COLOR_INACTIVE; } // // Draw the text // PAL_DrawText(PAL_GetWord(rgMagicItem[i].wMagic), PAL_XY(35 + k * 87, 54 + j * 18), bColor, TRUE, FALSE); // // Draw the cursor on the current selected item // if (i == g_iCurrentItem) { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_CURSOR), gpScreen, PAL_XY(60 + k * 87, 64 + j * 18)); } i++; } } if (g_InputState.dwKeyPress & kKeySearch) { if (rgMagicItem[g_iCurrentItem].fEnabled) { j = g_iCurrentItem % 3; k = (g_iCurrentItem < 3 * 2) ? (g_iCurrentItem / 3) : 2; j = 35 + j * 87; k = 54 + k * 18; PAL_DrawText(PAL_GetWord(rgMagicItem[g_iCurrentItem].wMagic), PAL_XY(j, k), MENUITEM_COLOR_CONFIRMED, FALSE, TRUE); return rgMagicItem[g_iCurrentItem].wMagic; } } return 0xFFFF; }
VOID PAL_EquipItemMenu( WORD wItem ) /*++ Purpose: Show the menu which allow players to equip the specified item. Parameters: [IN] wItem - the object ID of the item. Return value: None. --*/ { PAL_LARGE BYTE bufBackground[320 * 200]; PAL_LARGE BYTE bufImage[2048]; WORD w; int iCurrentPlayer, i; BYTE bColor, bSelectedColor; DWORD dwColorChangeTime; gpGlobals->wLastUnequippedItem = wItem; PAL_MKFDecompressChunk(bufBackground, 320 * 200, EQUIPMENU_BACKGROUND_FBPNUM, gpGlobals->f.fpFBP); iCurrentPlayer = 0; bSelectedColor = MENUITEM_COLOR_SELECTED_FIRST; dwColorChangeTime = SDL_GetTicks() + (600 / MENUITEM_COLOR_SELECTED_TOTALNUM); while (TRUE) { wItem = gpGlobals->wLastUnequippedItem; // // Draw the background // PAL_FBPBlitToSurface(bufBackground, gpScreen); // // Draw the item picture // if (PAL_MKFReadChunk(bufImage, 2048, gpGlobals->g.rgObject[wItem].item.wBitmap, gpGlobals->f.fpBALL) > 0) { PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(16, 16)); } // // Draw the current equipment of the selected player // w = gpGlobals->rgParty[iCurrentPlayer].wPlayerRole; for (i = 0; i < MAX_PLAYER_EQUIPMENTS; i++) { if (gpGlobals->g.PlayerRoles.rgwEquipment[i][w] != 0) { PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwEquipment[i][w]), PAL_XY(130, 11 + i * 22), MENUITEM_COLOR, TRUE, FALSE); } } // // Draw the stats of the currently selected player // PAL_DrawNumber(PAL_GetPlayerAttackStrength(w), 4, PAL_XY(260, 14), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerMagicStrength(w), 4, PAL_XY(260, 36), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDefense(w), 4, PAL_XY(260, 58), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDexterity(w), 4, PAL_XY(260, 80), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerFleeRate(w), 4, PAL_XY(260, 102), kNumColorCyan, kNumAlignRight); // // Draw a box for player selection // PAL_CreateBox(PAL_XY(2, 95), gpGlobals->wMaxPartyMemberIndex, 2, 0, FALSE); // // Draw the label of players // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { w = gpGlobals->rgParty[i].wPlayerRole; if (iCurrentPlayer == i) { if (gpGlobals->g.rgObject[wItem].item.wFlags & (kItemFlagEquipableByPlayerRole_First << w)) { bColor = bSelectedColor; } else { bColor = MENUITEM_COLOR_SELECTED_INACTIVE; } } else { if (gpGlobals->g.rgObject[wItem].item.wFlags & (kItemFlagEquipableByPlayerRole_First << w)) { bColor = MENUITEM_COLOR; } else { bColor = MENUITEM_COLOR_INACTIVE; } } PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[w]), PAL_XY(15, 108 + 18 * i), bColor, TRUE, FALSE); } // // Draw the text label and amount of the item // if (wItem != 0) { PAL_DrawText(PAL_GetWord(wItem), PAL_XY(5, 70), MENUITEM_COLOR_CONFIRMED, TRUE, FALSE); PAL_DrawNumber(PAL_GetItemAmount(wItem), 2, PAL_XY(65, 73), kNumColorCyan, kNumAlignRight); } // // Update the screen // VIDEO_UpdateScreen(NULL); // // Accept input // PAL_ClearKeyState(); while (TRUE) { PAL_ProcessEvent(); // // See if we should change the highlight color // if (SDL_GetTicks() > dwColorChangeTime) { if ((WORD)bSelectedColor + 1 >= (WORD)MENUITEM_COLOR_SELECTED_FIRST + MENUITEM_COLOR_SELECTED_TOTALNUM) { bSelectedColor = MENUITEM_COLOR_SELECTED_FIRST; } else { bSelectedColor++; } dwColorChangeTime = SDL_GetTicks() + (600 / MENUITEM_COLOR_SELECTED_TOTALNUM); // // Redraw the selected item if needed. // w = gpGlobals->rgParty[iCurrentPlayer].wPlayerRole; if (gpGlobals->g.rgObject[wItem].item.wFlags & (kItemFlagEquipableByPlayerRole_First << w)) { PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[w]), PAL_XY(15, 108 + 18 * iCurrentPlayer), bSelectedColor, TRUE, TRUE); } } if (g_InputState.dwKeyPress != 0) { break; } SDL_Delay(1); } if (wItem == 0) { return; } if (g_InputState.dwKeyPress & (kKeyUp | kKeyLeft)) { iCurrentPlayer--; if (iCurrentPlayer < 0) { iCurrentPlayer = 0; } } else if (g_InputState.dwKeyPress & (kKeyDown | kKeyRight)) { iCurrentPlayer++; if (iCurrentPlayer > gpGlobals->wMaxPartyMemberIndex) { iCurrentPlayer = gpGlobals->wMaxPartyMemberIndex; } } else if (g_InputState.dwKeyPress & kKeyMenu) { return; } else if (g_InputState.dwKeyPress & kKeySearch) { w = gpGlobals->rgParty[iCurrentPlayer].wPlayerRole; if (gpGlobals->g.rgObject[wItem].item.wFlags & (kItemFlagEquipableByPlayerRole_First << w)) { // // Run the equip script // gpGlobals->g.rgObject[wItem].item.wScriptOnEquip = PAL_RunTriggerScript(gpGlobals->g.rgObject[wItem].item.wScriptOnEquip, gpGlobals->rgParty[iCurrentPlayer].wPlayerRole); } } } }
static VOID PAL_BuyMenu_OnItemChange( WORD wCurrentItem ) /*++ Purpose: Callback function which is called when player selected another item in the buy menu. Parameters: [IN] wCurrentItem - current item on the menu, indicates the object ID of the currently selected item. Return value: None. --*/ { const SDL_Rect rect = {20, 8, 128, 175}; int i, n; PAL_LARGE BYTE bufImage[2048]; // // Draw the picture of current selected item // PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_ITEMBOX), gpScreen, PAL_XY(35, 8)); if (PAL_MKFReadChunk(bufImage, 2048, gpGlobals->g.rgObject[wCurrentItem].item.wBitmap, gpGlobals->f.fpBALL) > 0) { PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(42, 16)); } // // See how many of this item we have in the inventory // n = 0; for (i = 0; i < MAX_INVENTORY; i++) { if (gpGlobals->rgInventory[i].wItem == 0) { break; } else if (gpGlobals->rgInventory[i].wItem == wCurrentItem) { n = gpGlobals->rgInventory[i].nAmount; break; } } // // Draw the amount of this item in the inventory // PAL_CreateSingleLineBox(PAL_XY(20, 105), 5, FALSE); PAL_DrawText(PAL_GetWord(BUYMENU_LABEL_CURRENT), PAL_XY(30, 115), 0, FALSE, FALSE); PAL_DrawNumber(n, 6, PAL_XY(69, 119), kNumColorYellow, kNumAlignRight); // // Draw the cash amount // PAL_CreateSingleLineBox(PAL_XY(20, 145), 5, FALSE); PAL_DrawText(PAL_GetWord(CASH_LABEL), PAL_XY(30, 155), 0, FALSE, FALSE); PAL_DrawNumber(gpGlobals->dwCash, 6, PAL_XY(69, 159), kNumColorYellow, kNumAlignRight); VIDEO_UpdateScreen(&rect); }
VOID PAL_BuyMenu( WORD wStoreNum ) /*++ Purpose: Show the buy item menu. Parameters: [IN] wStoreNum - number of the store to buy items from. Return value: None. --*/ { MENUITEM rgMenuItem[MAX_STORE_ITEM]; int i, y; WORD w; SDL_Rect rect = {125, 8, 190, 190}; // // create the menu items // y = 22; for (i = 0; i < MAX_STORE_ITEM; i++) { if (gpGlobals->g.lprgStore[wStoreNum].rgwItems[i] == 0) { break; } rgMenuItem[i].wValue = gpGlobals->g.lprgStore[wStoreNum].rgwItems[i]; rgMenuItem[i].wNumWord = gpGlobals->g.lprgStore[wStoreNum].rgwItems[i]; rgMenuItem[i].fEnabled = TRUE; rgMenuItem[i].pos = PAL_XY(150, y); y += 18; } // // Draw the box // PAL_CreateBox(PAL_XY(125, 8), 8, 8, 1, FALSE); // // Draw the number of prices // for (y = 0; y < i; y++) { w = gpGlobals->g.rgObject[rgMenuItem[y].wValue].item.wPrice; PAL_DrawNumber(w, 6, PAL_XY(235, 25 + y * 18), kNumColorCyan, kNumAlignRight); } VIDEO_UpdateScreen(&rect); w = 0; while (TRUE) { w = PAL_ReadMenu(PAL_BuyMenu_OnItemChange, rgMenuItem, i, w, MENUITEM_COLOR); if (w == MENUITEM_VALUE_CANCELLED) { break; } if (gpGlobals->g.rgObject[w].item.wPrice <= gpGlobals->dwCash) { if (PAL_ConfirmMenu()) { // // Player bought an item // gpGlobals->dwCash -= gpGlobals->g.rgObject[w].item.wPrice; PAL_AddItemToInventory(w, 1); } } // // Place the cursor to the current item on next loop // for (y = 0; y < i; y++) { if (w == rgMenuItem[y].wValue) { w = y; break; } } } }
INT PAL_SaveSlotMenu( WORD wDefaultSlot ) /*++ Purpose: Show the load game menu. Parameters: [IN] wDefaultSlot - default save slot number (1-5). Return value: Which saved slot to load from (1-5). MENUITEM_VALUE_CANCELLED if cancelled. --*/ { LPBOX rgpBox[5]; int i; FILE *fp; WORD wItemSelected; WORD wSavedTimes; MENUITEM rgMenuItem[5]; const SDL_Rect rect = {195, 7, 120, 190}; // // Create the boxes and create the menu items // for (i = 0; i < 5; i++) { rgpBox[i] = PAL_CreateSingleLineBox(PAL_XY(195, 7 + 38 * i), 6, TRUE); rgMenuItem[i].wValue = i + 1; rgMenuItem[i].fEnabled = TRUE; rgMenuItem[i].wNumWord = LOADMENU_LABEL_SLOT_FIRST + i; rgMenuItem[i].pos = PAL_XY(210, 17 + 38 * i); } // // Draw the numbers of saved times // for (i = 1; i <= 5; i++) { fp = fopen(va("%s%d%s", PAL_SAVE_PREFIX, i, ".rpg"), "rb"); if (fp == NULL) { wSavedTimes = 0; } else { fread(&wSavedTimes, sizeof(WORD), 1, fp); wSavedTimes = SWAP16(wSavedTimes); fclose(fp); } // // Draw the number // PAL_DrawNumber((UINT)wSavedTimes, 4, PAL_XY(270, 38 * i - 17), kNumColorYellow, kNumAlignRight); } VIDEO_UpdateScreen(&rect); // // Activate the menu // wItemSelected = PAL_ReadMenu(NULL, rgMenuItem, 5, wDefaultSlot - 1, MENUITEM_COLOR); // // Delete the boxes // for (i = 0; i < 5; i++) { PAL_DeleteBox(rgpBox[i]); } VIDEO_UpdateScreen(&rect); return wItemSelected; }
WORD PAL_ItemUseMenu( WORD wItemToUse ) /*++ Purpose: Show the use item menu. Parameters: [IN] wItemToUse - the object ID of the item to use. Return value: The selected player to use the item onto. MENUITEM_VALUE_CANCELLED if user cancelled. --*/ { BYTE bColor, bSelectedColor; PAL_LARGE BYTE bufImage[2048]; DWORD dwColorChangeTime; static WORD wSelectedPlayer = 0; SDL_Rect rect = {110, 2, 200, 180}; int i; bSelectedColor = MENUITEM_COLOR_SELECTED_FIRST; dwColorChangeTime = 0; while (TRUE) { if (wSelectedPlayer > gpGlobals->wMaxPartyMemberIndex) { wSelectedPlayer = 0; } // // Draw the box // PAL_CreateBox(PAL_XY(110, 2), 7, 9, 0, FALSE); // // Draw the stats of the selected player // PAL_DrawText(PAL_GetWord(STATUS_LABEL_LEVEL), PAL_XY(200, 16), ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_HP), PAL_XY(200, 34), ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_MP), PAL_XY(200, 52), ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_ATTACKPOWER), PAL_XY(200, 70), ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_MAGICPOWER), PAL_XY(200, 88), ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_RESISTANCE), PAL_XY(200, 106), ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_DEXTERITY), PAL_XY(200, 124), ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_FLEERATE), PAL_XY(200, 142), ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE); i = gpGlobals->rgParty[wSelectedPlayer].wPlayerRole; PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwLevel[i], 4, PAL_XY(240, 20), kNumColorYellow, kNumAlignRight); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(263, 38)); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxHP[i], 4, PAL_XY(261, 40), kNumColorBlue, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwHP[i], 4, PAL_XY(240, 37), kNumColorYellow, kNumAlignRight); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(263, 56)); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxMP[i], 4, PAL_XY(261, 58), kNumColorBlue, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMP[i], 4, PAL_XY(240, 55), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerAttackStrength(i), 4, PAL_XY(240, 74), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerMagicStrength(i), 4, PAL_XY(240, 92), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDefense(i), 4, PAL_XY(240, 110), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDexterity(i), 4, PAL_XY(240, 128), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerFleeRate(i), 4, PAL_XY(240, 146), kNumColorYellow, kNumAlignRight); // // Draw the names of the players in the party // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { if (i == wSelectedPlayer) { bColor = bSelectedColor; } else { bColor = MENUITEM_COLOR; } PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[gpGlobals->rgParty[i].wPlayerRole]), PAL_XY(125, 16 + 20 * i), bColor, TRUE, FALSE); } PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_ITEMBOX), gpScreen, PAL_XY(120, 80)); i = PAL_GetItemAmount(wItemToUse); if (i > 0) { // // Draw the picture of the item // if (PAL_MKFReadChunk(bufImage, 2048, gpGlobals->g.rgObject[wItemToUse].item.wBitmap, gpGlobals->f.fpBALL) > 0) { PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(127, 88)); } // // Draw the amount and label of the item // PAL_DrawText(PAL_GetWord(wItemToUse), PAL_XY(116, 143), STATUS_COLOR_EQUIPMENT, TRUE, FALSE); PAL_DrawNumber(i, 2, PAL_XY(170, 133), kNumColorCyan, kNumAlignRight); } // // Update the screen area // VIDEO_UpdateScreen(&rect); // // Wait for key // PAL_ClearKeyState(); while (TRUE) { // // See if we should change the highlight color // if (SDL_GetTicks() > dwColorChangeTime) { if ((WORD)bSelectedColor + 1 >= (WORD)MENUITEM_COLOR_SELECTED_FIRST + MENUITEM_COLOR_SELECTED_TOTALNUM) { bSelectedColor = MENUITEM_COLOR_SELECTED_FIRST; } else { bSelectedColor++; } dwColorChangeTime = SDL_GetTicks() + (600 / MENUITEM_COLOR_SELECTED_TOTALNUM); // // Redraw the selected item. // PAL_DrawText( PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[gpGlobals->rgParty[wSelectedPlayer].wPlayerRole]), PAL_XY(125, 16 + 20 * wSelectedPlayer), bSelectedColor, FALSE, TRUE); } PAL_ProcessEvent(); if (g_InputState.dwKeyPress != 0) { break; } SDL_Delay(1); } if (i <= 0) { return MENUITEM_VALUE_CANCELLED; } if (g_InputState.dwKeyPress & (kKeyUp | kKeyLeft)) { wSelectedPlayer--; } else if (g_InputState.dwKeyPress & (kKeyDown | kKeyRight)) { if (wSelectedPlayer < gpGlobals->wMaxPartyMemberIndex) { wSelectedPlayer++; } } else if (g_InputState.dwKeyPress & kKeyMenu) { break; } else if (g_InputState.dwKeyPress & kKeySearch) { return gpGlobals->rgParty[wSelectedPlayer].wPlayerRole; } } return MENUITEM_VALUE_CANCELLED; }
VOID PAL_PlayerStatus( VOID ) /*++ Purpose: Show the player status. Parameters: None. Return value: None. --*/ { PAL_LARGE BYTE bufBackground[320 * 200]; PAL_LARGE BYTE bufImage[16384]; int iCurrent; int iPlayerRole; int i, y; WORD w; const int rgEquipPos[MAX_PLAYER_EQUIPMENTS][2] = { {190, 0}, {248, 40}, {252, 102}, {202, 134}, {142, 142}, {82, 126} }; PAL_MKFDecompressChunk(bufBackground, 320 * 200, STATUS_BACKGROUND_FBPNUM, gpGlobals->f.fpFBP); iCurrent = 0; while (iCurrent >= 0 && iCurrent <= gpGlobals->wMaxPartyMemberIndex) { iPlayerRole = gpGlobals->rgParty[iCurrent].wPlayerRole; // // Draw the background image // PAL_FBPBlitToSurface(bufBackground, gpScreen); // // Draw the text labels // PAL_DrawText(PAL_GetWord(STATUS_LABEL_EXP), PAL_XY(6, 6), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_LEVEL), PAL_XY(6, 32), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_HP), PAL_XY(6, 54), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_MP), PAL_XY(6, 76), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_ATTACKPOWER), PAL_XY(6, 98), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_MAGICPOWER), PAL_XY(6, 118), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_RESISTANCE), PAL_XY(6, 138), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_DEXTERITY), PAL_XY(6, 158), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_FLEERATE), PAL_XY(6, 178), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[iPlayerRole]), PAL_XY(110, 8), MENUITEM_COLOR_CONFIRMED, TRUE, FALSE); // // Draw the stats // PAL_DrawNumber(gpGlobals->Exp.rgPrimaryExp[iPlayerRole].wExp, 5, PAL_XY(58, 6), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.rgLevelUpExp[gpGlobals->g.PlayerRoles.rgwLevel[iPlayerRole]], 5, PAL_XY(58, 15), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwLevel[iPlayerRole], 2, PAL_XY(54, 35), kNumColorYellow, kNumAlignRight); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(65, 58)); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(65, 80)); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwHP[iPlayerRole], 4, PAL_XY(42, 56), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxHP[iPlayerRole], 4, PAL_XY(63, 61), kNumColorBlue, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMP[iPlayerRole], 4, PAL_XY(42, 78), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxMP[iPlayerRole], 4, PAL_XY(63, 83), kNumColorBlue, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerAttackStrength(iPlayerRole), 4, PAL_XY(42, 102), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerMagicStrength(iPlayerRole), 4, PAL_XY(42, 122), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDefense(iPlayerRole), 4, PAL_XY(42, 142), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDexterity(iPlayerRole), 4, PAL_XY(42, 162), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerFleeRate(iPlayerRole), 4, PAL_XY(42, 182), kNumColorYellow, kNumAlignRight); // // Draw the equipments // for (i = 0; i < MAX_PLAYER_EQUIPMENTS; i++) { w = gpGlobals->g.PlayerRoles.rgwEquipment[i][iPlayerRole]; if (w == 0) { continue; } // // Draw the image // if (PAL_MKFReadChunk(bufImage, 16384, gpGlobals->g.rgObject[w].item.wBitmap, gpGlobals->f.fpBALL) > 0) { PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(rgEquipPos[i][0], rgEquipPos[i][1])); } // // Draw the text label // PAL_DrawText(PAL_GetWord(w), PAL_XY(rgEquipPos[i][0] + 5, rgEquipPos[i][1] + 38), STATUS_COLOR_EQUIPMENT, TRUE, FALSE); } // // Draw the image of player role // if (PAL_MKFReadChunk(bufImage, 16384, gpGlobals->g.PlayerRoles.rgwAvatar[iPlayerRole], gpGlobals->f.fpRGM) > 0) { PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(110, 30)); } // // Draw all poisons // y = 58; for (i = 0; i < MAX_POISONS; i++) { w = gpGlobals->rgPoisonStatus[i][iCurrent].wPoisonID; if (w != 0 && gpGlobals->g.rgObject[w].poison.wPoisonLevel <= 3) { PAL_DrawText(PAL_GetWord(w), PAL_XY(185, y), (BYTE)(gpGlobals->g.rgObject[w].poison.wColor + 10), TRUE, FALSE); y += 18; } } // // Update the screen // VIDEO_UpdateScreen(NULL); // // Wait for input // PAL_ClearKeyState(); while (TRUE) { UTIL_Delay(1); if (g_InputState.dwKeyPress & kKeyMenu) { iCurrent = -1; break; } else if (g_InputState.dwKeyPress & (kKeyLeft | kKeyUp)) { iCurrent--; break; } else if (g_InputState.dwKeyPress & (kKeyRight | kKeyDown | kKeySearch)) { iCurrent++; break; } } } }
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(); }
VOID PAL_PlayerInfoBox( PAL_POS pos, WORD wPlayerRole, INT iTimeMeter, BYTE bTimeMeterColor, BOOL fUpdate ) /*++ Purpose: Show the player info box. Parameters: [IN] pos - the top-left corner position of the box. [IN] wPlayerRole - the player role ID to be shown. [IN] iTimeMeter - the value of time meter. 0 = empty, 100 = full. [IN] bTimeMeterColor - the color of time meter. [IN] fUpdate - whether to update the screen area or not. Return value: None. --*/ { SDL_Rect rect; BYTE bPoisonColor; int i, iPartyIndex; WORD wMaxLevel, w; const BYTE rgStatusPos[kStatusAll][2] = { {35, 19}, // confused {0, 0}, // slow {54, 1}, // sleep {55, 20}, // silence {0, 0}, // puppet {0, 0}, // bravery {0, 0}, // protect {0, 0}, // haste {0, 0}, // dualattack }; const WORD rgwStatusWord[kStatusAll] = { 0x1D, // confused 0x00, // slow 0x1C, // sleep 0x1A, // silence 0x00, // puppet 0x00, // bravery 0x00, // protect 0x00, // haste 0x00, // dualattack }; const BYTE rgbStatusColor[kStatusAll] = { 0x5F, // confused 0x00, // slow 0x0E, // sleep 0x3C, // silence 0x00, // puppet 0x00, // bravery 0x00, // protect 0x00, // haste 0x00, // dualattack }; // // Draw the box // PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_PLAYERINFOBOX), gpScreen, pos); // // Draw the player face // wMaxLevel = 0; bPoisonColor = 0xFF; for (iPartyIndex = 0; iPartyIndex <= gpGlobals->wMaxPartyMemberIndex; iPartyIndex++) { if (gpGlobals->rgParty[iPartyIndex].wPlayerRole == wPlayerRole) { break; } } if (iPartyIndex <= gpGlobals->wMaxPartyMemberIndex) { for (i = 0; i < MAX_POISONS; i++) { w = gpGlobals->rgPoisonStatus[i][iPartyIndex].wPoisonID; if (w != 0 && gpGlobals->g.rgObject[w].poison.wPoisonLevel <= 3) { if (gpGlobals->g.rgObject[w].poison.wPoisonLevel >= wMaxLevel) { wMaxLevel = gpGlobals->g.rgObject[w].poison.wPoisonLevel; bPoisonColor = (BYTE)(gpGlobals->g.rgObject[w].poison.wColor); } } } } if (gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole] == 0) { // // Always use the black/white color for dead players // and do not use the time meter // bPoisonColor = 0; iTimeMeter = 0; } if (bPoisonColor == 0xFF) { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_PLAYERFACE_FIRST + wPlayerRole), gpScreen, PAL_XY(PAL_X(pos) - 2, PAL_Y(pos) - 4)); } else { PAL_RLEBlitMonoColor(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_PLAYERFACE_FIRST + wPlayerRole), gpScreen, PAL_XY(PAL_X(pos) - 2, PAL_Y(pos) - 4), bPoisonColor, 0); } #ifndef PAL_CLASSIC // // Draw a border for the Time Meter // rect.x = PAL_X(pos) + 31; rect.y = PAL_Y(pos) + 4; rect.w = 1; rect.h = 6; SDL_FillRect(gpScreen, &rect, 0xBD); rect.x += 39; SDL_FillRect(gpScreen, &rect, 0xBD); rect.x = PAL_X(pos) + 32; rect.y = PAL_Y(pos) + 3; rect.w = 38; rect.h = 1; SDL_FillRect(gpScreen, &rect, 0xBD); rect.y += 7; SDL_FillRect(gpScreen, &rect, 0xBD); // // Draw the Time meter bar // if (iTimeMeter >= 100) { rect.x = PAL_X(pos) + 33; rect.y = PAL_Y(pos) + 6; rect.w = 36; rect.h = 2; SDL_FillRect(gpScreen, &rect, 0x2C); } else if (iTimeMeter > 0) { rect.x = PAL_X(pos) + 33; rect.y = PAL_Y(pos) + 5; rect.w = iTimeMeter * 36 / 100; rect.h = 4; SDL_FillRect(gpScreen, &rect, bTimeMeterColor); } #endif // // Draw the HP and MP value // #ifdef PAL_CLASSIC PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(PAL_X(pos) + 49, PAL_Y(pos) + 6)); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxHP[wPlayerRole], 4, PAL_XY(PAL_X(pos) + 47, PAL_Y(pos) + 8), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole], 4, PAL_XY(PAL_X(pos) + 26, PAL_Y(pos) + 5), kNumColorYellow, kNumAlignRight); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(PAL_X(pos) + 49, PAL_Y(pos) + 22)); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxMP[wPlayerRole], 4, PAL_XY(PAL_X(pos) + 47, PAL_Y(pos) + 24), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMP[wPlayerRole], 4, PAL_XY(PAL_X(pos) + 26, PAL_Y(pos) + 21), kNumColorCyan, kNumAlignRight); #else PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(PAL_X(pos) + 49, PAL_Y(pos) + 14)); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxHP[wPlayerRole], 4, PAL_XY(PAL_X(pos) + 47, PAL_Y(pos) + 16), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole], 4, PAL_XY(PAL_X(pos) + 26, PAL_Y(pos) + 13), kNumColorYellow, kNumAlignRight); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(PAL_X(pos) + 49, PAL_Y(pos) + 24)); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxMP[wPlayerRole], 4, PAL_XY(PAL_X(pos) + 47, PAL_Y(pos) + 26), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMP[wPlayerRole], 4, PAL_XY(PAL_X(pos) + 26, PAL_Y(pos) + 23), kNumColorCyan, kNumAlignRight); #endif // // Draw Statuses // if (gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole] > 0) { for (i = 0; i < kStatusAll; i++) { if (gpGlobals->rgPlayerStatus[wPlayerRole][i] > 0 && rgwStatusWord[i] != 0) { PAL_DrawText(PAL_GetWord(rgwStatusWord[i]), PAL_XY(PAL_X(pos) + rgStatusPos[i][0], PAL_Y(pos) + rgStatusPos[i][1]), rgbStatusColor[i], TRUE, FALSE); } } } // // Update the screen area if needed // if (fUpdate) { rect.x = PAL_X(pos) - 2; rect.y = PAL_Y(pos) - 4; rect.w = 77; rect.h = 39; VIDEO_UpdateScreen(&rect); } }