/*++ Initialize the game data (used when starting a new game or loading a saved game). Parameters: [IN] iSaveSlot - Slot of saved game. --*/ VOID PAL_InitGameData(INT iSaveSlot) { PAL_InitGlobalGameData(); gpGlobals->bCurrentSaveSlot = (BYTE)iSaveSlot; // // try loading from the saved game file. // if (iSaveSlot == 0 || PAL_LoadGame(va("%s%d%s", PAL_SAVE_PREFIX, iSaveSlot, ".rpg")) != 0) { // // Cannot load the saved game file. Load the defaults. // PAL_LoadDefaultGame(); } gpGlobals->fGameStart = TRUE; gpGlobals->fNeedToFadeIn = FALSE; gpGlobals->iCurInvMenuItem = 0; gpGlobals->fInBattle = FALSE; memset(gpGlobals->rgPlayerStatus, 0, sizeof(gpGlobals->rgPlayerStatus)); PAL_UpdateEquipments(); }
VOID PAL_InitGameData( INT iSaveSlot ) /*++ Purpose: Initialize the game data (used when starting a new game or loading a saved game). Parameters: [IN] iSaveSlot - Slot of saved game. Return value: None. --*/ { PAL_InitGlobalGameData(); gpGlobals->bCurrentSaveSlot = (BYTE)iSaveSlot; // // try loading from the saved game file. // if (iSaveSlot == 0 || PAL_LoadGame(va("%s%d%s", PAL_SAVE_PREFIX, iSaveSlot, ".rpg")) != 0) { // // Cannot load the saved game file. Load the defaults. // PAL_LoadDefaultGame(); } gpGlobals->fGameStart = TRUE; gpGlobals->fNeedToFadeIn = FALSE; gpGlobals->iCurInvMenuItem = 0; gpGlobals->fInBattle = FALSE; memset(gpGlobals->rgPlayerStatus, 0, sizeof(gpGlobals->rgPlayerStatus)); PAL_UpdateEquipments(); }
/*++ Start a battle. Parameters: [IN] wEnemyTeam - the number of the enemy team. [IN] fIsBoss - TRUE for boss fight (not allowed to flee). Return value: The result of the battle. --*/ BATTLERESULT PAL_StartBattle(WORD wEnemyTeam, BOOL fIsBoss) { int i; WORD w, wPrevWaveLevel; SHORT sPrevWaveProgression; // // Set the screen waving effects // wPrevWaveLevel = gpGlobals->wScreenWave; sPrevWaveProgression = gpGlobals->sWaveProgression; gpGlobals->sWaveProgression = 0; gpGlobals->wScreenWave = gpGlobals->g.lprgBattleField[gpGlobals->wNumBattleField].wScreenWave; // // Make sure everyone in the party is alive, also clear all hidden // EXP count records // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { w = gpGlobals->rgParty[i].wPlayerRole; if (gpGlobals->g.PlayerRoles.rgwHP[w] == 0) { gpGlobals->g.PlayerRoles.rgwHP[w] = 1; gpGlobals->rgPlayerStatus[w][kStatusPuppet] = 0; } gpGlobals->Exp.rgHealthExp[w].wCount = 0; gpGlobals->Exp.rgMagicExp[w].wCount = 0; gpGlobals->Exp.rgAttackExp[w].wCount = 0; gpGlobals->Exp.rgMagicPowerExp[w].wCount = 0; gpGlobals->Exp.rgDefenseExp[w].wCount = 0; gpGlobals->Exp.rgDexterityExp[w].wCount = 0; gpGlobals->Exp.rgFleeExp[w].wCount = 0; } // // Clear all item-using records // for (i = 0; i < MAX_INVENTORY; i++) { gpGlobals->rgInventory[i].nAmountInUse = 0; } // // Store all enemies // for (i = 0; i < MAX_ENEMIES_IN_TEAM; i++) { memset(&(g_Battle.rgEnemy[i]), 0, sizeof(BATTLEENEMY)); w = gpGlobals->g.lprgEnemyTeam[wEnemyTeam].rgwEnemy[i]; if (w == 0xFFFF) { break; } if (w != 0) { g_Battle.rgEnemy[i].e = gpGlobals->g.lprgEnemy[gpGlobals->g.rgObject[w].enemy.wEnemyID]; g_Battle.rgEnemy[i].wObjectID = w; g_Battle.rgEnemy[i].state = kFighterWait; g_Battle.rgEnemy[i].wScriptOnTurnStart = gpGlobals->g.rgObject[w].enemy.wScriptOnTurnStart; g_Battle.rgEnemy[i].wScriptOnBattleEnd = gpGlobals->g.rgObject[w].enemy.wScriptOnBattleEnd; g_Battle.rgEnemy[i].wScriptOnReady = gpGlobals->g.rgObject[w].enemy.wScriptOnReady; g_Battle.rgEnemy[i].iColorShift = 0; g_Battle.rgEnemy[i].dwMaxHealth = g_Battle.rgEnemy[i].e.wHealth; #ifndef PAL_CLASSIC g_Battle.rgEnemy[i].flTimeMeter = 50; // // HACK: Otherwise the black thief lady will be too hard to beat // if (g_Battle.rgEnemy[i].e.wDexterity == 164) { g_Battle.rgEnemy[i].e.wDexterity /= ((gpGlobals->wMaxPartyMemberIndex == 0) ? 6 : 3); } // // HACK: Heal up automatically for final boss // if (g_Battle.rgEnemy[i].e.wHealth == 32760) { for (w = 0; w < MAX_PLAYER_ROLES; w++) { gpGlobals->g.PlayerRoles.rgwHP[w] = gpGlobals->g.PlayerRoles.rgwMaxHP[w]; gpGlobals->g.PlayerRoles.rgwMP[w] = gpGlobals->g.PlayerRoles.rgwMaxMP[w]; } } // // Yet another HACKs // if ((SHORT)g_Battle.rgEnemy[i].e.wDexterity == -32) { g_Battle.rgEnemy[i].e.wDexterity = 0; // for Grandma Knife } else if (g_Battle.rgEnemy[i].e.wDexterity == 20) { // // for Fox Demon // if (gpGlobals->g.PlayerRoles.rgwLevel[0] < 15) { g_Battle.rgEnemy[i].e.wDexterity = 8; } else if (gpGlobals->g.PlayerRoles.rgwLevel[4] > 28 || gpGlobals->Exp.rgPrimaryExp[4].wExp > 0) { g_Battle.rgEnemy[i].e.wDexterity = 60; } } else if (g_Battle.rgEnemy[i].e.wExp == 250 && g_Battle.rgEnemy[i].e.wCash == 1100) { g_Battle.rgEnemy[i].e.wDexterity += 12; // for Snake Demon } else if ((SHORT)g_Battle.rgEnemy[i].e.wDexterity == -60) { g_Battle.rgEnemy[i].e.wDexterity = 15; // for Spider } else if ((SHORT)g_Battle.rgEnemy[i].e.wDexterity == -30) { g_Battle.rgEnemy[i].e.wDexterity = (WORD)-10; // for Stone Head } else if ((SHORT)g_Battle.rgEnemy[i].e.wDexterity == -16) { g_Battle.rgEnemy[i].e.wDexterity = 0; // for Zombie } else if ((SHORT)g_Battle.rgEnemy[i].e.wDexterity == -20) { g_Battle.rgEnemy[i].e.wDexterity = -8; // for Flower Demon } else if (g_Battle.rgEnemy[i].e.wLevel < 20 && gpGlobals->wNumScene >= 0xD8 && gpGlobals->wNumScene <= 0xE2) { // // for low-level monsters in the Cave of Trial // g_Battle.rgEnemy[i].e.wLevel += 15; g_Battle.rgEnemy[i].e.wDexterity += 25; } else if (gpGlobals->wNumScene == 0x90) { g_Battle.rgEnemy[i].e.wDexterity += 25; // for Tower Dragons } else if (g_Battle.rgEnemy[i].e.wLevel == 2 && g_Battle.rgEnemy[i].e.wCash == 48) { g_Battle.rgEnemy[i].e.wDexterity += 8; // for Miao Fists } else if (g_Battle.rgEnemy[i].e.wLevel == 4 && g_Battle.rgEnemy[i].e.wCash == 240) { g_Battle.rgEnemy[i].e.wDexterity += 18; // for Fat Miao } else if (g_Battle.rgEnemy[i].e.wLevel == 16 && g_Battle.rgEnemy[i].e.wMagicRate == 4 && g_Battle.rgEnemy[i].e.wAttackEquivItemRate == 4) { g_Battle.rgEnemy[i].e.wDexterity += 50; // for Black Spider } #endif } } g_Battle.wMaxEnemyIndex = i - 1; // // Store all players // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { g_Battle.rgPlayer[i].flTimeMeter = 15.0f; #ifndef PAL_CLASSIC g_Battle.rgPlayer[i].flTimeSpeedModifier = 2.0f; g_Battle.rgPlayer[i].sTurnOrder = -1; #endif g_Battle.rgPlayer[i].wHidingTime = 0; g_Battle.rgPlayer[i].state = kFighterWait; g_Battle.rgPlayer[i].action.sTarget = -1; g_Battle.rgPlayer[i].fDefending = FALSE; g_Battle.rgPlayer[i].wCurrentFrame = 0; g_Battle.rgPlayer[i].iColorShift = FALSE; } // // Load sprites and background // PAL_LoadBattleSprites(); PAL_LoadBattleBackground(); // // Create the surface for scene buffer // g_Battle.lpSceneBuf = SDL_CreateRGBSurface(gpScreen->flags & ~SDL_HWSURFACE, 320, 200, 8, gpScreen->format->Rmask, gpScreen->format->Gmask, gpScreen->format->Bmask, gpScreen->format->Amask); if (g_Battle.lpSceneBuf == NULL) { TerminateOnError("PAL_StartBattle(): creating surface for scene buffer failed!"); } #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfacePalette(g_Battle.lpSceneBuf, gpScreen->format->palette); #else SDL_SetPalette(g_Battle.lpSceneBuf, SDL_PHYSPAL | SDL_LOGPAL, VIDEO_GetPalette(), 0, 256); #endif PAL_UpdateEquipments(); g_Battle.iExpGained = 0; g_Battle.iCashGained = 0; g_Battle.fIsBoss = fIsBoss; g_Battle.fEnemyCleared = FALSE; g_Battle.fEnemyMoving = FALSE; g_Battle.iHidingTime = 0; g_Battle.wMovingPlayerIndex = 0; g_Battle.UI.szMsg[0] = '\0'; g_Battle.UI.szNextMsg[0] = '\0'; g_Battle.UI.dwMsgShowTime = 0; g_Battle.UI.state = kBattleUIWait; g_Battle.UI.fAutoAttack = FALSE; g_Battle.UI.wSelectedIndex = 0; g_Battle.UI.wPrevEnemyTarget = 0; memset(g_Battle.UI.rgShowNum, 0, sizeof(g_Battle.UI.rgShowNum)); g_Battle.lpSummonSprite = NULL; g_Battle.sBackgroundColorShift = 0; gpGlobals->fInBattle = TRUE; g_Battle.BattleResult = kBattleResultPreBattle; PAL_BattleUpdateFighters(); // // Load the battle effect sprite. // i = PAL_MKFGetChunkSize(10, gpGlobals->f.fpDATA); g_Battle.lpEffectSprite = UTIL_malloc(i); PAL_MKFReadChunk(g_Battle.lpEffectSprite, i, 10, gpGlobals->f.fpDATA); #ifdef PAL_CLASSIC g_Battle.Phase = kBattlePhaseSelectAction; g_Battle.fRepeat = FALSE; g_Battle.fForce = FALSE; g_Battle.fFlee = FALSE; #endif #ifdef PAL_ALLOW_KEYREPEAT SDL_EnableKeyRepeat(120, 75); #endif // // Run the main battle routine. // i = PAL_BattleMain(); #ifdef PAL_ALLOW_KEYREPEAT SDL_EnableKeyRepeat(0, 0); PAL_ClearKeyState(); g_InputState.prevdir = kDirUnknown; #endif if (i == kBattleResultWon) { // // Player won the battle. Add the Experience points. // PAL_BattleWon(); } // // Clear all item-using records // for (w = 0; w < MAX_INVENTORY; w++) { gpGlobals->rgInventory[w].nAmountInUse = 0; } // // Clear all player status, poisons and temporary effects // PAL_ClearAllPlayerStatus(); for (w = 0; w < MAX_PLAYER_ROLES; w++) { PAL_CurePoisonByLevel(w, 3); PAL_RemoveEquipmentEffect(w, kBodyPartExtra); } // // Free all the battle sprites // PAL_FreeBattleSprites(); free(g_Battle.lpEffectSprite); // // Free the surfaces for the background picture and scene buffer // SDL_FreeSurface(g_Battle.lpBackground); SDL_FreeSurface(g_Battle.lpSceneBuf); g_Battle.lpBackground = NULL; g_Battle.lpSceneBuf = NULL; gpGlobals->fInBattle = FALSE; PAL_PlayMUS(gpGlobals->wNumMusic, TRUE, 1); // // Restore the screen waving effects // gpGlobals->sWaveProgression = sPrevWaveProgression; gpGlobals->wScreenWave = wPrevWaveLevel; return i; }