Ejemplo n.º 1
0
VOID
PAL_NEW_EndingScreen1(
VOID
)
/*++
Purpose:

显示结尾处的消灭合体水魔兽的动画,对应95/98版的第4、5个avi视频

Parameters:

None.

Return value:

None.

--*/
{
	//1128 0043 0019 0000 0000 设置播放音乐 25
	PAL_PlayMUS(0x19, TRUE, 0);

	//1129 008B 0005 0000 0000 改变调色板 05
	PAL_SetPalette(5, FALSE);

	//112A 00A4 0044 0000 000F 卷动FBP图片 68 00 15
	PAL_ScrollFBP(68, 0xf, TRUE);

	//112B 0050 0000 0000 0000 全屏淡出
	PAL_FadeOut(1);

	SDL_FillRect(gpScreen, NULL, 0);
	//112C 008B 0004 0000 0000 改变调色板 04
	PAL_SetPalette(4, FALSE);

	//112D 0096 0000 0000 0000 播放结束动画
	PAL_EndingAnimation();


	gpGlobals->wNumPalette = 4;
	//112E 0077 0001 0000 0000 停止播放音乐 01
	PAL_PlayMUS(0, FALSE, 1);

	//112F 008C 000F 0007 0000 屏幕逐渐褪色 15 07 00
	PAL_ColorFade(7, 15, FALSE);

	//1131 00A3 0002 0011 0000 播放CD音轨 02 若失败 则播放RIX 17
	if (!SOUND_PlayCDA(2))
	{
		RIX_Play(0x11, TRUE, 0);
	}

	SDL_FillRect(gpScreen, NULL, 0);

	//1132 0036 000B 0000 0000 设置动画 11
	//1133 0037 0000 0001 0000 播放动画 00 01 00
	PAL_RNGPlay(0xb, 0, 1, 7);

	//1134 008B 0000 0000 0000 改变调色板 00
	PAL_SetPalette(0, FALSE);

	//1135 0037 0002 0000 0007 播放动画 02 00 07
	PAL_RNGPlay(0xb, 2, 999, 7);

	//1136 0050 0003 0000 0000 全屏淡出
	PAL_FadeOut(3);

	SDL_FillRect(gpScreen, NULL, 0);
	//1137 008B 0008 0000 0000 改变调色板 08
	PAL_SetPalette(8, FALSE);

	//1138 0036 000A 0000 0000 设置动画 10
	//1139 0037 0000 0000 0006 播放动画 00 00 06
	PAL_RNGPlay(10, 0, 999, 6);

	//113A 0076 0047 000A 0000 显示FBP图像 71 10
	PAL_EndingSetEffectSprite(0);
	PAL_ShowFBP(71, 10);

	//113B 00A6 0000 0000 0000 备份画面
	VIDEO_BackupScreen();

	//113C 00A5 0046 027B 0007 淡入FBP图片 70 635 07
	PAL_EndingSetEffectSprite(0x27b);
	PAL_ShowFBP(70, 7);

	//113D 008B 0005 0000 0000 改变调色板 05
	PAL_SetPalette(5, FALSE);

	//113E 00A5 0043 FFFF 0007 淡入FBP图片 67 65535 07
	PAL_ShowFBP(67, 7);

	//113F 00A4 0042 FFFF 0007 卷动FBP图片 66 65535 07
	PAL_ScrollFBP(66, 0xf, TRUE);

	//1140 00A5 0041 FFFF 0007 淡入FBP图片 65 65535 07
	PAL_ShowFBP(65, 7);
}
Ejemplo n.º 2
0
VOID
PAL_EndingScreen(
VOID
)
{
	RIX_Play(0x1a, TRUE, 0);
	PAL_RNGPlay(gpGlobals->iCurPlayingRNG, 110, 150, 7);
	PAL_RNGPlay(gpGlobals->iCurPlayingRNG, 151, 999, 9);

	PAL_FadeOut(2);

	RIX_Play(0x19, TRUE, 0);

	PAL_ShowFBP(75, 0);
	PAL_FadeIn(5, FALSE, 1);
	PAL_ScrollFBP(74, 0xf, TRUE);

	PAL_FadeOut(1);

	SDL_FillRect(gpScreen, NULL, 0);
	gpGlobals->wNumPalette = 4;
	gpGlobals->fNeedToFadeIn = TRUE;
	PAL_EndingAnimation();

	RIX_Play(0, FALSE, 2);
	PAL_ColorFade(7, 15, FALSE);

	if (!SOUND_PlayCDA(2))
	{
		RIX_Play(0x11, TRUE, 0);
	}

	SDL_FillRect(gpScreen, NULL, 0);
	PAL_SetPalette(0, FALSE);
	PAL_RNGPlay(0xb, 0, 999, 7);

	PAL_FadeOut(2);

	SDL_FillRect(gpScreen, NULL, 0);
	gpGlobals->wNumPalette = 8;
	gpGlobals->fNeedToFadeIn = TRUE;
	PAL_RNGPlay(10, 0, 999, 6);

	PAL_EndingSetEffectSprite(0);
	PAL_ShowFBP(77, 10);

	VIDEO_BackupScreen();

	PAL_EndingSetEffectSprite(0x27b);
	PAL_ShowFBP(76, 7);

	PAL_SetPalette(5, FALSE);
	PAL_ShowFBP(73, 7);
	PAL_ScrollFBP(72, 0xf, TRUE);

	PAL_ShowFBP(71, 7);
	PAL_ShowFBP(68, 7);

	PAL_EndingSetEffectSprite(0);
	PAL_ShowFBP(68, 6);

	PAL_WaitForKey(0);
	RIX_Play(0, FALSE, 1);
	UTIL_Delay(500);

	if (!SOUND_PlayCDA(13))
	{
		RIX_Play(9, TRUE, 0);
	}

	PAL_ScrollFBP(67, 0xf, TRUE);
	PAL_ScrollFBP(66, 0xf, TRUE);
	PAL_ScrollFBP(65, 0xf, TRUE);
	PAL_ScrollFBP(64, 0xf, TRUE);
	PAL_ScrollFBP(63, 0xf, TRUE);
	PAL_ScrollFBP(62, 0xf, TRUE);
	PAL_ScrollFBP(61, 0xf, TRUE);
	PAL_ScrollFBP(60, 0xf, TRUE);
	PAL_ScrollFBP(59, 0xf, TRUE);

	RIX_Play(0, FALSE, 6);
	PAL_FadeOut(3);
}
Ejemplo n.º 3
0
static BATTLERESULT
PAL_BattleMain(
   VOID
)
/*++
  Purpose:

    The main battle routine.

  Parameters:

    None.

  Return value:

    The result of the battle.

--*/
{
   int         i;
   DWORD       dwTime;
   
   UTIL_WriteLog(LOG_DEBUG, "[0x%08x][%s][%s] - %s", (long)PAL_BattleMain, "PAL_BattleMain", __FILE__, "entry");

   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
   //
   RIX_Play(0, FALSE, 1);
   UTIL_Delay(200);

   //
   // Switch the screen
   //
   VIDEO_SwitchScreen(5);

   //
   // Play the battle music
   //
   RIX_Play(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);
   }
   
   UTIL_WriteLog(LOG_DEBUG, "[0x%08x][%s][%s] - %s", (long)PAL_BattleMain, "PAL_BattleMain", __FILE__, "end");
   
   //
   // Return the battle result
   //
   return g_Battle.BattleResult;
}
Ejemplo n.º 4
0
static VOID
PAL_BattleWon(
   VOID
)
/*++
  Purpose:

    Show the "you win" message and add the experience points for players.

  Parameters:

    None.

  Return value:

    None.

--*/
{
   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;
   
   UTIL_WriteLog(LOG_DEBUG, "[0x%08x][%s][%s] - %s", (long)PAL_BattleWon, "PAL_BattleWon", __FILE__, "start");
   
   //
   // Backup the initial player stats
   //
   OrigPlayerRoles = gpGlobals->g.PlayerRoles;

   if (g_Battle.iExpGained > 0)
   {
      //
      // Play the "battle win" music
      //
      RIX_Play(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
   }
   UTIL_WriteLog(LOG_DEBUG, "[0x%08x][%s][%s] - %s", (long)PAL_BattleWon, "PAL_BattleWon", __FILE__, "end");
}
Ejemplo n.º 5
0
BATTLERESULT
PAL_StartBattle(
   WORD        wEnemyTeam,
   BOOL        fIsBoss
)
/*++
  Purpose:

    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.

--*/
{
   int            i;
   WORD           w, wPrevWaveLevel;
   SHORT          sPrevWaveProgression;
   
   UTIL_WriteLog(LOG_DEBUG, "[0x%08x][%s][%s] - [%d],[%d]", (long)PAL_StartBattle, "PAL_StartBattle", __FILE__, wEnemyTeam, fIsBoss);

   //
   // 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;

#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!");
   }

   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;

   RIX_Play(gpGlobals->wNumMusic, TRUE, 1);

   //
   // Restore the screen waving effects
   //
   gpGlobals->sWaveProgression = sPrevWaveProgression;
   gpGlobals->wScreenWave = wPrevWaveLevel;

   UTIL_WriteLog(LOG_DEBUG, "[0x%08x][%s][%s] - %s", (long)PAL_StartBattle, "PAL_StartBattle", __FILE__, "end");
   
   return i;
}