Пример #1
0
/*++
 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();
}
Пример #2
0
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();
}
Пример #3
0
/*++
 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;
}