VOID PAL_SellMenu( VOID ) /*++ Purpose: Show the sell item menu. Parameters: None. Return value: None. --*/ { WORD w; while (TRUE) { w = PAL_ItemSelectMenu(PAL_SellMenu_OnItemChange, kItemFlagSellable); if (w == 0) { break; } if (PAL_ConfirmMenu()) { if (PAL_AddItemToInventory(w, -1)) { gpGlobals->dwCash += gpGlobals->g.rgObject[w].item.wPrice / 2; } } } }
VOID PAL_BattlePlayerPerformAction( WORD wPlayerIndex ) /*++ Purpose: Perform the selected action for a player. Parameters: [IN] wPlayerIndex - the index of the player. Return value: None. --*/ { // TODO SHORT sDamage; WORD wPlayerRole = gpGlobals->rgParty[wPlayerIndex].wPlayerRole; SHORT sTarget = g_Battle.rgPlayer[wPlayerIndex].action.sTarget; int x, y; int i, t; WORD str, def, res, wObject; BOOL fCritical, fPoisoned; PAL_BattlePlayerValidateAction(wPlayerIndex); PAL_BattleBackupStat(); switch (g_Battle.rgPlayer[wPlayerIndex].action.ActionType) { case kBattleActionAttack: if (sTarget != -1) { // // Attack one enemy // if (g_Battle.rgEnemy[sTarget].wObjectID == 0) { sTarget = PAL_BattleSelectAutoTarget(); g_Battle.rgPlayer[wPlayerIndex].action.sTarget = sTarget; } for (t = 0; t < (gpGlobals->rgPlayerStatus[wPlayerRole][kStatusDualAttack] ? 2 : 1); t++) { str = PAL_GetPlayerAttackStrength(wPlayerRole); def = g_Battle.rgEnemy[sTarget].e.wDefense; def += (g_Battle.rgEnemy[sTarget].e.wLevel + 6) * 4; res = g_Battle.rgEnemy[sTarget].e.wAttackResistance; fCritical = FALSE; sDamage = PAL_CalcPhysicalAttackDamage(str, def, res); if (RandomLong(0, 5) == 0) { // // Critical Hit // sDamage *= 3; fCritical = TRUE; } if (wPlayerRole == 0 && RandomLong(0, 11) == 0) { // // Bonus hit for Li Xiaoyao // sDamage *= 2; fCritical = TRUE; } if (sDamage <= 0) { sDamage = 1; } if (g_Battle.rgEnemy[sTarget].e.wHealth > (WORD)sDamage) { g_Battle.rgEnemy[sTarget].e.wHealth -= sDamage; } else { g_Battle.rgEnemy[sTarget].e.wHealth = 0; } if (t == 0) { g_Battle.rgPlayer[wPlayerIndex].wCurrentFrame = 7; PAL_BattleDelay(4, 0); } PAL_BattleShowPlayerAttackAnim(wPlayerIndex, fCritical); // // Show the number of damage // x = PAL_X(g_Battle.rgEnemy[sTarget].pos); y = PAL_Y(g_Battle.rgEnemy[sTarget].pos) - 70; x += PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.rgEnemy[sTarget].lpSprite, g_Battle.rgEnemy[sTarget].wCurrentFrame)) / 2; y += PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.rgEnemy[sTarget].lpSprite, g_Battle.rgEnemy[sTarget].wCurrentFrame)) / 2; if (y < 10) { y = 10; } PAL_BattleUIShowNum((WORD)sDamage, PAL_XY(x, y), kNumColorBlue); } } else { // // Attack all enemies // for (t = 0; t < (gpGlobals->rgPlayerStatus[wPlayerRole][kStatusDualAttack] ? 2 : 1); t++) { int division = 1; const int index[MAX_ENEMIES_IN_TEAM] = {2, 1, 0, 4, 3}; fCritical = (RandomLong(0, 5) == 0); if (t == 0) { g_Battle.rgPlayer[wPlayerIndex].wCurrentFrame = 7; PAL_BattleDelay(4, 0); } PAL_BattleShowPlayerAttackAnim(wPlayerIndex, fCritical); for (i = 0; i < MAX_ENEMIES_IN_TEAM; i++) { if (g_Battle.rgEnemy[index[i]].wObjectID == 0 || index[i] > g_Battle.wMaxEnemyIndex) { continue; } str = PAL_GetPlayerAttackStrength(wPlayerRole); def = g_Battle.rgEnemy[index[i]].e.wDefense; def += (g_Battle.rgEnemy[index[i]].e.wLevel + 6) * 4; res = g_Battle.rgEnemy[index[i]].e.wAttackResistance; sDamage = PAL_CalcPhysicalAttackDamage(str, def, res); if (fCritical) { // // Critical Hit // sDamage *= 3; } sDamage /= division; if (sDamage <= 0) { sDamage = 1; } if (g_Battle.rgEnemy[index[i]].e.wHealth > (WORD)sDamage) { g_Battle.rgEnemy[index[i]].e.wHealth -= sDamage; } else { g_Battle.rgEnemy[index[i]].e.wHealth = 0; } // // Show the number of damage // x = PAL_X(g_Battle.rgEnemy[index[i]].pos); y = PAL_Y(g_Battle.rgEnemy[index[i]].pos) - 70; x += PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.rgEnemy[index[i]].lpSprite, g_Battle.rgEnemy[index[i]].wCurrentFrame)) / 2; y += PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.rgEnemy[index[i]].lpSprite, g_Battle.rgEnemy[index[i]].wCurrentFrame)) / 2; if (y < 10) { y = 10; } PAL_BattleUIShowNum((WORD)sDamage, PAL_XY(x, y), kNumColorBlue); division++; if (division > 3) { division = 3; } } } } PAL_BattleUpdateFighters(); PAL_BattleMakeScene(); PAL_BattleDelay(5, 0); break; case kBattleActionAttackMate: break; case kBattleActionCoopMagic: break; case kBattleActionDefend: g_Battle.rgPlayer[wPlayerIndex].fDefending = TRUE; break; case kBattleActionFlee: break; case kBattleActionMagic: break; case kBattleActionThrowItem: break; case kBattleActionUseItem: wObject = g_Battle.rgPlayer[wPlayerIndex].action.wActionID; PAL_BattleShowPlayerUseItemAnim(wPlayerIndex, wObject, sTarget); // // Run the script // gpGlobals->g.rgObject[wObject].item.wScriptOnUse = PAL_RunTriggerScript(gpGlobals->g.rgObject[wObject].item.wScriptOnUse, (sTarget == -1) ? 0xFFFF : gpGlobals->rgParty[sTarget].wPlayerRole); // // Remove the item if the item is consuming and the script succeeded // if ((gpGlobals->g.rgObject[wObject].item.wFlags & kItemFlagConsuming) && g_fScriptSuccess) { PAL_AddItemToInventory(wObject, -1); } PAL_BattleUpdateFighters(); PAL_BattleDisplayStatChange(); PAL_BattleDelay(8, 0); break; case kBattleActionPass: break; } PAL_BattlePostActionCheck(FALSE); // // Check for poisons // fPoisoned = FALSE; PAL_BattleBackupStat(); for (i = 0; i < MAX_POISONS; i++) { wObject = gpGlobals->rgPoisonStatus[i][wPlayerIndex].wPoisonID; if (wObject != 0) { fPoisoned = TRUE; gpGlobals->rgPoisonStatus[i][wPlayerIndex].wPoisonScript = PAL_RunTriggerScript(gpGlobals->rgPoisonStatus[i][wPlayerIndex].wPoisonScript, wPlayerRole); } } if (fPoisoned) { PAL_BattleDelay(3, 0); PAL_BattleUpdateFighters(); if (PAL_BattleDisplayStatChange()) { PAL_BattleDelay(12, 0); } } // // Update statuses // for (i = 0; i < kStatusAll; i++) { if (gpGlobals->rgPlayerStatus[wPlayerRole][i] > 0) { gpGlobals->rgPlayerStatus[wPlayerRole][i]--; } } }
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; } } } }
VOID PAL_GameUseItem( VOID ) /*++ Purpose: Allow player use an item in the game. Parameters: None. Return value: None. --*/ { WORD wObject; while (TRUE) { wObject = PAL_ItemSelectMenu(NULL, kItemFlagUsable); if (wObject == 0) { return; } if (!(gpGlobals->g.rgObject[wObject].item.wFlags & kItemFlagApplyToAll)) { // // Select the player to use the item on // WORD wPlayer = 0; while (TRUE) { wPlayer = PAL_ItemUseMenu(wObject); if (wPlayer == MENUITEM_VALUE_CANCELLED) { break; } // // Run the script // gpGlobals->g.rgObject[wObject].item.wScriptOnUse = PAL_RunTriggerScript(gpGlobals->g.rgObject[wObject].item.wScriptOnUse, wPlayer); // // Remove the item if the item is consuming and the script succeeded // if ((gpGlobals->g.rgObject[wObject].item.wFlags & kItemFlagConsuming) && g_fScriptSuccess) { PAL_AddItemToInventory(wObject, -1); } } } else { // // Run the script // gpGlobals->g.rgObject[wObject].item.wScriptOnUse = PAL_RunTriggerScript(gpGlobals->g.rgObject[wObject].item.wScriptOnUse, 0xFFFF); // // Remove the item if the item is consuming and the script succeeded // if ((gpGlobals->g.rgObject[wObject].item.wFlags & kItemFlagConsuming) && g_fScriptSuccess) { PAL_AddItemToInventory(wObject, -1); } return; } } }