Пример #1
0
/*++
 Update the effects of all equipped items for all players.
 --*/
VOID PAL_UpdateEquipments(void)
{
   int      i, j;
   WORD     w;

   memset(&(gpGlobals->rgEquipmentEffect), 0, sizeof(gpGlobals->rgEquipmentEffect));

   for (i = 0; i < MAX_PLAYER_ROLES; i++)
   {
      for (j = 0; j < MAX_PLAYER_EQUIPMENTS; j++)
      {
         w = gpGlobals->g.PlayerRoles.rgwEquipment[j][i];

         if (w != 0)
         {
            gpGlobals->g.rgObject[w].item.wScriptOnEquip =
               PAL_RunTriggerScript(gpGlobals->g.rgObject[w].item.wScriptOnEquip, (WORD)i);
         }
      }
   }
}
Пример #2
0
VOID
PAL_UpdateEquipments(
   VOID
)
/*++
  Purpose:

    Update the effects of all equipped items for all players.

  Parameters:

    None.

  Return value:

    None.

--*/
{
   int      i, j;
   WORD     w;

   memset(&(gpGlobals->rgEquipmentEffect), 0, sizeof(gpGlobals->rgEquipmentEffect));

   for (i = 0; i < MAX_PLAYER_ROLES; i++)
   {
      for (j = 0; j < MAX_PLAYER_EQUIPMENTS; j++)
      {
         w = gpGlobals->g.PlayerRoles.rgwEquipment[j][i];

         if (w != 0)
         {
            gpGlobals->g.rgObject[w].item.wScriptOnEquip =
               PAL_RunTriggerScript(gpGlobals->g.rgObject[w].item.wScriptOnEquip, (WORD)i);
         }
      }
   }
}
Пример #3
0
/*++
 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
    }
}
Пример #4
0
/*++
 The main battle routine.
 
 Return value:
 The result of the battle.
 --*/
static BATTLERESULT PAL_BattleMain(void)
{
    int         i;
    DWORD       dwTime;
    
    VIDEO_BackupScreen();
    
    //
    // Generate the scene and draw the scene to the screen buffer
    //
    PAL_BattleMakeScene();
    SDL_BlitSurface(g_Battle.lpSceneBuf, NULL, gpScreen, NULL);
    
    //
    // Fade out the music and delay for a while
    //
    PAL_PlayMUS(0, FALSE, 1);
    UTIL_Delay(200);
    
    //
    // Switch the screen
    //
    VIDEO_SwitchScreen(5);
    
    //
    // Play the battle music
    //
    PAL_PlayMUS(gpGlobals->wNumBattleMusic, TRUE, 0);
    
    //
    // Fade in the screen when needed
    //
    if (gpGlobals->fNeedToFadeIn)
    {
        PAL_FadeIn(gpGlobals->wNumPalette, gpGlobals->fNightPalette, 1);
        gpGlobals->fNeedToFadeIn = FALSE;
    }
    
    //
    // Run the pre-battle scripts for each enemies
    //
    for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++)
    {
        g_Battle.rgEnemy[i].wScriptOnTurnStart =
        PAL_RunTriggerScript(g_Battle.rgEnemy[i].wScriptOnTurnStart, i);
        
        if (g_Battle.BattleResult != kBattleResultPreBattle)
        {
            break;
        }
    }
    
    if (g_Battle.BattleResult == kBattleResultPreBattle)
    {
        g_Battle.BattleResult = kBattleResultOnGoing;
    }
    
#ifndef PAL_CLASSIC
    PAL_UpdateTimeChargingUnit();
#endif
    
    dwTime = SDL_GetTicks();
    
    PAL_ClearKeyState();
    
    //
    // Run the main battle loop.
    //
    while (TRUE)
    {
        //
        // Break out if the battle ended.
        //
        if (g_Battle.BattleResult != kBattleResultOnGoing)
        {
            break;
        }
        
        //
        // Wait for the time of one frame. Accept input here.
        //
        PAL_ProcessEvent();
        while (SDL_GetTicks() <= dwTime)
        {
            PAL_ProcessEvent();
            SDL_Delay(1);
        }
        
        //
        // Set the time of the next frame.
        //
        dwTime = SDL_GetTicks() + BATTLE_FRAME_TIME;
        
        //
        // Run the main frame routine.
        //
        PAL_BattleStartFrame();
        
        //
        // Update the screen.
        //
        VIDEO_UpdateScreen(NULL);
    }
    
    //
    // Return the battle result
    //
    return g_Battle.BattleResult;
}
Пример #5
0
VOID
PAL_InGameMagicMenu(
   VOID
)
/*++
  Purpose:

    Show the magic menu.

  Parameters:

    None.

  Return value:

    None.

--*/
{
   MENUITEM         rgMenuItem[MAX_PLAYERS_IN_PARTY];
   int              i, y;
   static WORD      w;
   WORD             wMagic;
   const SDL_Rect   rect = {35, 62, 95, 90};

   //
   // Draw the player info boxes
   //
   y = 45;

   for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++)
   {
      PAL_PlayerInfoBox(PAL_XY(y, 165), gpGlobals->rgParty[i].wPlayerRole, 100,
         TIMEMETER_COLOR_DEFAULT, TRUE);
      y += 78;
   }

   y = 75;

   //
   // Generate one menu items for each player in the party
   //
   for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++)
   {
      assert(i <= MAX_PLAYERS_IN_PARTY);

      rgMenuItem[i].wValue = i;
      rgMenuItem[i].wNumWord =
         gpGlobals->g.PlayerRoles.rgwName[gpGlobals->rgParty[i].wPlayerRole];
      rgMenuItem[i].fEnabled =
         (gpGlobals->g.PlayerRoles.rgwHP[gpGlobals->rgParty[i].wPlayerRole] > 0);
      rgMenuItem[i].pos = PAL_XY(48, y);

      y += 18;
   }

   //
   // Draw the box
   //
   PAL_CreateBox(PAL_XY(35, 62), gpGlobals->wMaxPartyMemberIndex, 2, 0, FALSE);
   VIDEO_UpdateScreen(&rect);

   w = PAL_ReadMenu(NULL, rgMenuItem, gpGlobals->wMaxPartyMemberIndex + 1, w, MENUITEM_COLOR);

   if (w == MENUITEM_VALUE_CANCELLED)
   {
      return;
   }

   wMagic = 0;

   while (TRUE)
   {
      wMagic = PAL_MagicSelectionMenu(gpGlobals->rgParty[w].wPlayerRole, FALSE, wMagic);
      if (wMagic == 0)
      {
         break;
      }

      if (gpGlobals->g.rgObject[wMagic].magic.wFlags & kMagicFlagApplyToAll)
      {
         gpGlobals->g.rgObject[wMagic].magic.wScriptOnUse =
            PAL_RunTriggerScript(gpGlobals->g.rgObject[wMagic].magic.wScriptOnUse, 0);

         if (g_fScriptSuccess)
         {
            gpGlobals->g.rgObject[wMagic].magic.wScriptOnSuccess =
               PAL_RunTriggerScript(gpGlobals->g.rgObject[wMagic].magic.wScriptOnSuccess, 0);

            gpGlobals->g.PlayerRoles.rgwMP[gpGlobals->rgParty[w].wPlayerRole] -=
               gpGlobals->g.lprgMagic[gpGlobals->g.rgObject[wMagic].magic.wMagicNumber].wCostMP;
         }

         if (gpGlobals->fNeedToFadeIn)
         {
            PAL_FadeIn(gpGlobals->wNumPalette, gpGlobals->fNightPalette, 1);
            gpGlobals->fNeedToFadeIn = FALSE;
         }
      }
      else
      {
         //
         // Need to select which player to use the magic on.
         //
         WORD       wPlayer = 0;
         SDL_Rect   rect;

         while (wPlayer != MENUITEM_VALUE_CANCELLED)
         {
            //
            // Redraw the player info boxes first
            //
            y = 45;

            for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++)
            {
               PAL_PlayerInfoBox(PAL_XY(y, 165), gpGlobals->rgParty[i].wPlayerRole, 100,
                  TIMEMETER_COLOR_DEFAULT, TRUE);
               y += 78;
            }

            //
            // Draw the cursor on the selected item
            //
            rect.x = 70 + 78 * wPlayer;
            rect.y = 193;
            rect.w = 9;
            rect.h = 6;

            PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_CURSOR),
               gpScreen, PAL_XY(rect.x, rect.y));

            VIDEO_UpdateScreen(&rect);

            while (TRUE)
            {
               PAL_ClearKeyState();
               PAL_ProcessEvent();

               if (g_InputState.dwKeyPress & kKeyMenu)
               {
                  wPlayer = MENUITEM_VALUE_CANCELLED;
                  break;
               }
               else if (g_InputState.dwKeyPress & kKeySearch)
               {
                  gpGlobals->g.rgObject[wMagic].magic.wScriptOnUse =
                     PAL_RunTriggerScript(gpGlobals->g.rgObject[wMagic].magic.wScriptOnUse,
                        gpGlobals->rgParty[wPlayer].wPlayerRole);

                  if (g_fScriptSuccess)
                  {
                     gpGlobals->g.rgObject[wMagic].magic.wScriptOnSuccess =
                        PAL_RunTriggerScript(gpGlobals->g.rgObject[wMagic].magic.wScriptOnSuccess,
                           gpGlobals->rgParty[wPlayer].wPlayerRole);

                     if (g_fScriptSuccess)
                     {
                        gpGlobals->g.PlayerRoles.rgwMP[gpGlobals->rgParty[w].wPlayerRole] -=
                           gpGlobals->g.lprgMagic[gpGlobals->g.rgObject[wMagic].magic.wMagicNumber].wCostMP;

                        //
                        // Check if we have run out of MP
                        //
                        if (gpGlobals->g.PlayerRoles.rgwMP[gpGlobals->rgParty[w].wPlayerRole] <
                           gpGlobals->g.lprgMagic[gpGlobals->g.rgObject[wMagic].magic.wMagicNumber].wCostMP)
                        {
                           //
                           // Don't go further if run out of MP
                           //
                           wPlayer = MENUITEM_VALUE_CANCELLED;
                        }
                     }
                  }

                  break;
               }
               else if (g_InputState.dwKeyPress & (kKeyLeft | kKeyUp))
               {
                  if (wPlayer > 0)
                  {
                     wPlayer--;
                     break;
                  }
               }
               else if (g_InputState.dwKeyPress & (kKeyRight | kKeyDown))
               {
                  if (wPlayer < gpGlobals->wMaxPartyMemberIndex)
                  {
                     wPlayer++;
                     break;
                  }
               }

               SDL_Delay(1);
            }
         }
      }

      //
      // Redraw the player info boxes
      //
      y = 45;

      for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++)
      {
         PAL_PlayerInfoBox(PAL_XY(y, 165), gpGlobals->rgParty[i].wPlayerRole, 100,
            TIMEMETER_COLOR_DEFAULT, TRUE);
         y += 78;
      }
   }
}
Пример #6
0
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);
         }
      }
   }
}
Пример #7
0
VOID
PAL_BattleStartFrame(
   VOID
)
/*++
  Purpose:

    Called once per video frame in battle.

  Parameters:

    None.

  Return value:

    None.

--*/
{
   int                      i;
   int                      iMax;
   BOOL                     fEnded;
   WORD                     wPlayerRole;
   WORD                     wDexterity;
   FLOAT                    flMax;

   PAL_BattleUpdateFighters();

   //
   // Update the scene
   //
   PAL_BattleMakeScene();
   SDL_BlitSurface(g_Battle.lpSceneBuf, NULL, gpScreen, NULL);

   //
   // Check if the battle is over
   //
   fEnded = TRUE;

   for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++)
   {
      if (g_Battle.rgEnemy[i].wObjectID != 0)
      {
         fEnded = FALSE;
         break;
      }
   }

   if (fEnded)
   {
      //
      // All enemies are cleared. Won the battle.
      //
      g_Battle.BattleResult = kBattleResultWon;
      SOUND_Play(-1);
      return;
   }
   else
   {
      fEnded = TRUE;

      for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++)
      {
         wPlayerRole = gpGlobals->rgParty[i].wPlayerRole;
         if (gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole] != 0 ||
            gpGlobals->rgPlayerStatus[wPlayerRole][kStatusPuppet] != 0)
         {
            fEnded = FALSE;
            break;
         }
      }

      if (fEnded)
      {
         //
         // All players are dead. Lost the battle.
         //
         g_Battle.BattleResult = kBattleResultLost;
         return;
      }
   }

   //
   // Run the logic for all enemies
   //
   for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++)
   {
      if (g_Battle.rgEnemy[i].wObjectID == 0)
      {
         continue;
      }

      if (g_Battle.rgEnemy[i].fTurnStart)
      {
         g_Battle.rgEnemy[i].wScriptOnTurnStart =
            PAL_RunTriggerScript(g_Battle.rgEnemy[i].wScriptOnTurnStart, i);

         g_Battle.rgEnemy[i].fTurnStart = FALSE;
      }
   }

   for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++)
   {
      if (g_Battle.rgEnemy[i].wObjectID == 0)
      {
         continue;
      }

      switch (g_Battle.rgEnemy[i].state)
      {
      case kFighterWait:
         flMax = PAL_GetTimeChargingSpeed(PAL_GetEnemyDexterity(i));

         if (flMax != 0)
         {
            g_Battle.rgEnemy[i].flTimeMeter += flMax;

            if (g_Battle.rgEnemy[i].flTimeMeter > 100 && flMax > 0)
            {
               g_Battle.rgEnemy[i].state = kFighterCom;
            }
         }
         break;

      case kFighterCom:
         g_Battle.rgEnemy[i].wScriptOnReady =
            PAL_RunTriggerScript(g_Battle.rgEnemy[i].wScriptOnReady, i);
         g_Battle.rgEnemy[i].state = kFighterAct;
         break;

      case kFighterAct:
////TEST///////////////////////////////////////////////////////////
SOUND_Play(g_Battle.rgEnemy[i].e.wAttackSound);
if (g_Battle.rgEnemy[i].fFirstMoveDone)
PAL_BattleUIShowText(va("enemy %d attack (2nd)",i), 500);
else PAL_BattleUIShowText(va("enemy %d attack",i), 500);
g_Battle.rgEnemy[i].flTimeMeter =0;
g_Battle.rgEnemy[i].state = kFighterWait;
////////////////////////////////////////////////////////////////////
         if (!g_Battle.rgEnemy[i].fFirstMoveDone)
         {
            if (g_Battle.rgEnemy[i].e.wDualMove >= 2 ||
               (g_Battle.rgEnemy[i].e.wDualMove != 0 && RandomLong(0, 1)))
            {
               g_Battle.rgEnemy[i].flTimeMeter = 100;
               g_Battle.rgEnemy[i].state = kFighterWait;
               g_Battle.rgEnemy[i].fFirstMoveDone = TRUE;
               break;
            }
         }

         g_Battle.rgEnemy[i].fFirstMoveDone = FALSE;
         g_Battle.rgEnemy[i].fTurnStart = TRUE;
         break;
      }
   }

   //
   // Update the battle UI
   //
   PAL_BattleUIUpdate();

   //
   // Run the logic for all players
   //
   for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++)
   {
      wPlayerRole = gpGlobals->rgParty[i].wPlayerRole;

      //
      // Skip dead players
      //
      if (gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole] == 0 &&
         gpGlobals->rgPlayerStatus[wPlayerRole][kStatusPuppet] == 0)
      {
         g_Battle.rgPlayer[i].state = kFighterWait;
         g_Battle.rgPlayer[i].flTimeMeter = 0;
         continue;
      }

      switch (g_Battle.rgPlayer[i].state)
      {
      case kFighterWait:
         wDexterity = PAL_GetPlayerActualDexterity(wPlayerRole);
         g_Battle.rgPlayer[i].flTimeMeter +=
            PAL_GetTimeChargingSpeed(wDexterity) * g_Battle.rgPlayer[i].flTimeSpeedModifier;
         break;

      case kFighterCom:
         if (g_Battle.UI.state == kBattleUIWait)
         {
            PAL_BattleUIPlayerReady(i);
         }
         break;

      case kFighterAct:
         wDexterity = PAL_GetPlayerActualDexterity(wPlayerRole);
         g_Battle.rgPlayer[i].action.flRemainingTime -= PAL_GetTimeChargingSpeed(wDexterity);

         if (g_Battle.rgPlayer[i].action.flRemainingTime < 0)
         {
            //
            // Perform the action for this player.
            //
            PAL_BattlePlayerPerformAction(i);

            //
            // Reduce the time for other players when uses coopmagic
            //
            if (g_Battle.rgPlayer[i].action.ActionType == kBattleActionCoopMagic)
            {
               for (iMax = 0; iMax <= gpGlobals->wMaxPartyMemberIndex; iMax++)
               {
                  g_Battle.rgPlayer[iMax].flTimeMeter = 0;
                  g_Battle.rgPlayer[iMax].flTimeSpeedModifier = 2.0f;
               }
            }
            else
            {
               g_Battle.rgPlayer[i].flTimeMeter = 0;
            }

            //
            // Revert this player back to waiting state.
            //
            g_Battle.rgPlayer[i].state = kFighterWait;
            g_Battle.rgPlayer[i].flTimeSpeedModifier = 1.0f;
         }
         break;
      }
   }

   //
   // Start the UI for the fastest and ready player
   //
   flMax = 0;
   iMax = 0;

   for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++)
   {
      if (g_Battle.rgPlayer[i].state == kFighterCom ||
         (g_Battle.rgPlayer[i].state == kFighterAct && g_Battle.rgPlayer[i].action.ActionType == kBattleActionCoopMagic))
      {
         flMax = 0;
         break;
      }
      else if (g_Battle.rgPlayer[i].state == kFighterWait)
      {
         if (g_Battle.rgPlayer[i].flTimeMeter > flMax)
         {
            iMax = i;
            flMax = g_Battle.rgPlayer[i].flTimeMeter;
         }
      }
   }

   if (flMax > 100.0f)
   {
      g_Battle.rgPlayer[iMax].state = kFighterCom;
      g_Battle.rgPlayer[iMax].fDefending = FALSE;
   }

////TEST/////////////////////////////////////////////////////////-START
if (g_InputState.dwKeyPress & kKeyFlee){
    for (i = 0; i < 5; i++){
        gpGlobals->g.PlayerRoles.rgwHP[i] = 0;
    }
   return;
}
////TEST/////////////////////////////////////////////////////////-END
}
Пример #8
0
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]--;
      }
   }
}
Пример #9
0
VOID
PAL_Search(
VOID
)
/*++
  Purpose:

  Process searching trigger events.

  Parameters:

  None.

  Return value:

  None.

  --*/
{
	int                x, y, xOffset, yOffset, dx, dy, dh, ex, ey, eh, i, k, l;
	LPEVENTOBJECT      p;
	PAL_POS            rgPos[13];

	//
	// Get the party location
	//
	x = PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset);
	y = PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset);

	if (gpGlobals->wPartyDirection == kDirNorth || gpGlobals->wPartyDirection == kDirEast)
	{
		xOffset = 16;
	}
	else
	{
		xOffset = -16;
	}

	if (gpGlobals->wPartyDirection == kDirEast || gpGlobals->wPartyDirection == kDirSouth)
	{
		yOffset = 8;
	}
	else
	{
		yOffset = -8;
	}

	rgPos[0] = PAL_XY(x, y);

	for (i = 0; i < 4; i++)
	{
		rgPos[i * 3 + 1] = PAL_XY(x + xOffset, y + yOffset);
		rgPos[i * 3 + 2] = PAL_XY(x, y + yOffset * 2);
		rgPos[i * 3 + 3] = PAL_XY(x + xOffset, y);
		x += xOffset;
		y += yOffset;
	}

	for (i = 0; i < 13; i++)
	{
		//
		// Convert to map location
		//
		dh = ((PAL_X(rgPos[i]) % 32) ? 1 : 0);
		dx = PAL_X(rgPos[i]) / 32;
		dy = PAL_Y(rgPos[i]) / 16;

		//
		// Loop through all event objects
		//
		for (k = gpGlobals->g.rgScene[gpGlobals->wNumScene - 1].wEventObjectIndex;
			k < gpGlobals->g.rgScene[gpGlobals->wNumScene].wEventObjectIndex; k++)
		{
			p = &(gpGlobals->g.lprgEventObject[k]);
			ex = p->x / 32;
			ey = p->y / 16;
			eh = ((p->x % 32) ? 1 : 0);

			if (p->sState <= 0 || p->wTriggerMode >= kTriggerTouchNear ||
				p->wTriggerMode * 6 - 4 < i || dx != ex || dy != ey || dh != eh)
			{
				continue;
			}

			//
			// Adjust direction/gesture for party members and the event object
			//
			if (p->nSpriteFrames * 4 > p->wCurrentFrameNum)
			{
				p->wCurrentFrameNum = 0; // use standing gesture
				p->wDirection = (gpGlobals->wPartyDirection + 2) % 4; // face the party

				for (l = 0; l <= gpGlobals->wMaxPartyMemberIndex; l++)
				{
					//
					// All party members should face the event object
					//
					gpGlobals->rgParty[l].wFrame = gpGlobals->wPartyDirection * 3;
				}

				//
				// Redraw everything
				//
				PAL_MakeScene();
				VIDEO_UpdateScreen(NULL);
			}

			//
			// Execute the script
			//
			p->wTriggerScript = PAL_RunTriggerScript(p->wTriggerScript, k + 1);

			//
			// Clear inputs and delay for a short time
			//
			UTIL_Delay(50);
			PAL_ClearKeyState();

			return; // don't go further
		}
	}
}
Пример #10
0
VOID
PAL_GameUpdate(
BOOL       fTrigger
)
/*++
  Purpose:

  The main game logic routine. Update the status of everything.

  Parameters:

  [IN]  fTrigger - whether to process trigger events or not.

  Return value:

  None.

  --*/
{
	WORD            wEventObjectID, wDir;
	int             i;
	LPEVENTOBJECT   p;

	//
	// Check for trigger events
	//
	if (fTrigger)
	{
		//
		// Check if we are entering a new scene
		//
		if (gpGlobals->fEnteringScene)
		{
			//
			// Run the script for entering the scene
			//
			gpGlobals->fEnteringScene = FALSE;

			i = gpGlobals->wNumScene - 1;
			gpGlobals->g.rgScene[i].wScriptOnEnter =
				PAL_RunTriggerScript(gpGlobals->g.rgScene[i].wScriptOnEnter, 0xFFFF);

			if (gpGlobals->fEnteringScene || gpGlobals->fGameStart)
			{
				//
				// Don't go further as we're switching to another scene
				//
				return;
			}

			PAL_ClearKeyState();
			PAL_MakeScene();
		}

		//
		// Update the vanish time for all event objects
		//
		for (wEventObjectID = 0; wEventObjectID < gpGlobals->g.nEventObject; wEventObjectID++)
		{
			p = &gpGlobals->g.lprgEventObject[wEventObjectID];

			if (p->sVanishTime != 0)
			{
				p->sVanishTime += ((p->sVanishTime < 0) ? 1 : -1);
			}
		}

		//
		// Loop through all event objects in the current scene
		//
		for (wEventObjectID = gpGlobals->g.rgScene[gpGlobals->wNumScene - 1].wEventObjectIndex + 1;
			wEventObjectID <= gpGlobals->g.rgScene[gpGlobals->wNumScene].wEventObjectIndex;
			wEventObjectID++)
		{
			p = &gpGlobals->g.lprgEventObject[wEventObjectID - 1];

			if (p->sVanishTime != 0)
			{
				continue;
			}

			if (p->sState < 0)
			{
				if (p->x < PAL_X(gpGlobals->viewport) ||
					p->x > PAL_X(gpGlobals->viewport) + 320 ||
					p->y < PAL_Y(gpGlobals->viewport) ||
					p->y > PAL_Y(gpGlobals->viewport) + 320)
				{
					p->sState = abs(p->sState);
					p->wCurrentFrameNum = 0;
				}
			}
			else if (p->sState > 0 && p->wTriggerMode >= kTriggerTouchNear)
			{
				//
				// This event object can be triggered without manually exploring
				//
				if (abs(PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset) - p->x) +
					abs(PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset) - p->y) * 2 <
					(p->wTriggerMode - kTriggerTouchNear) * 32 + 16)
				{
					//
					// Player is in the trigger zone.
					//

					if (p->nSpriteFrames)
					{
						//
						// The sprite has multiple frames. Try to adjust the direction.
						//
						int                xOffset, yOffset;

						p->wCurrentFrameNum = 0;

						xOffset = PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset) - p->x;
						yOffset = PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset) - p->y;

						if (xOffset > 0)
						{
							p->wDirection = ((yOffset > 0) ? kDirEast : kDirNorth);
						}
						else
						{
							p->wDirection = ((yOffset > 0) ? kDirSouth : kDirWest);
						}

						//
						// Redraw the scene
						//
						PAL_UpdatePartyGestures(FALSE);

						PAL_MakeScene();
						VIDEO_UpdateScreen(NULL);
					}

					//
					// Execute the script.
					//
					p->wTriggerScript = PAL_RunTriggerScript(p->wTriggerScript, wEventObjectID);

					PAL_ClearKeyState();

					if (gpGlobals->fEnteringScene || gpGlobals->fGameStart)
					{
						//
						// Don't go further on scene switching
						//
						return;
					}
				}
			}
		}
	}

	//
	// Run autoscript for each event objects
	//
	for (wEventObjectID = gpGlobals->g.rgScene[gpGlobals->wNumScene - 1].wEventObjectIndex + 1;
		wEventObjectID <= gpGlobals->g.rgScene[gpGlobals->wNumScene].wEventObjectIndex;
		wEventObjectID++)
	{
		p = &gpGlobals->g.lprgEventObject[wEventObjectID - 1];

		if (p->sState > 0 && p->sVanishTime == 0)
		{
			WORD wScriptEntry = p->wAutoScript;
			if (wScriptEntry != 0)
			{
				p->wAutoScript = PAL_RunAutoScript(wScriptEntry, wEventObjectID);
				if (gpGlobals->fEnteringScene || gpGlobals->fGameStart)
				{
					//
					// Don't go further on scene switching
					//
					return;
				}
			}
		}

		//
		// Check if the player is in the way
		//
		if (fTrigger && p->sState >= kObjStateBlocker && p->wSpriteNum != 0 &&
			abs(p->x - PAL_X(gpGlobals->viewport) - PAL_X(gpGlobals->partyoffset)) +
			abs(p->y - PAL_Y(gpGlobals->viewport) - PAL_Y(gpGlobals->partyoffset)) * 2 <= 12)
		{
			//
			// Player is in the way, try to move a step
			//
			wDir = (p->wDirection + 1) % 4;
			for (i = 0; i < 4; i++)
			{
				int              x, y;
				PAL_POS          pos;

				x = PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset);
				y = PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset);

				x += ((wDir == kDirWest || wDir == kDirSouth) ? -16 : 16);
				y += ((wDir == kDirWest || wDir == kDirNorth) ? -8 : 8);

				pos = PAL_XY(x, y);

				if (!PAL_CheckObstacle(pos, TRUE, 0))
				{
					//
					// move here
					//
					gpGlobals->viewport = PAL_XY(
						PAL_X(pos) - PAL_X(gpGlobals->partyoffset),
						PAL_Y(pos) - PAL_Y(gpGlobals->partyoffset));

					break;
				}

				wDir = (wDir + 1) % 4;
			}
		}
	}

	gpGlobals->dwFrameNum++;
}
Пример #11
0
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;
		}
	}
}