diff options
author | LOuroboros <lunosouroboros@gmail.com> | 2020-12-12 14:05:46 -0300 |
---|---|---|
committer | LOuroboros <lunosouroboros@gmail.com> | 2020-12-12 14:05:46 -0300 |
commit | d72d60b66408109a4db56d832c04cc18853883fb (patch) | |
tree | 2fa573c0e2124e3beb27893d4572155de11ce4a5 | |
parent | 0aafde88223f64ef13092511de34c317b8e844d1 (diff) |
Created FRLG/DP+ White Out Money Calculation (markdown)
-rw-r--r-- | FRLG-DP--White-Out-Money-Calculation.md | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/FRLG-DP--White-Out-Money-Calculation.md b/FRLG-DP--White-Out-Money-Calculation.md new file mode 100644 index 0000000..ac050ac --- /dev/null +++ b/FRLG-DP--White-Out-Money-Calculation.md @@ -0,0 +1,159 @@ +*Credits to **[AsparagusEduardo](https://github.com/AsparagusEduardo)** for creating the implementation of this feature that I will be explaining here, and to **[lightgod87](https://github.com/lightgod87)** for extra polishing it.* + +In Pokémon Emerald, whenever you lose a battle you always lose half of your money. + +In Pokémon FireRed/LeafGreen, Diamond/Pearl and subsequent games, you lose a more sensible amount influenced by the Pokémon with the highest level of your party and the amount of badges you have. + +Today we'll be implementing that in Pokeemerald. + +## 1. Adding in some new battle strings + +This implementation introduces 2 text strings from FireRed/LeafGreen for extra flavor and faithfulness. This is super easy, so let's get it out of the way. + +First we define them by adding a constant in **[include/constants/battle_string_ids.h](https://github.com/pret/pokeemerald/blob/master/include/constants/battle_string_ids.h)**: + +```diff ++#define STRINGID_PLAYERLOSTTOENEMYTRAINER 381 ++#define STRINGID_PLAYERPAIDPRIZEMONEY 382 +``` + +*Don't forget to add 2 to the current value of your `BATTLESTRINGS_COUNT` in the same file!* + +And then we add the actual text strings to **[src/battle_message.c](https://github.com/pret/pokeemerald/blob/master/src/battle_message.c)**. + +As to not complicate things, I suggest to put them right below `sText_YouThrowABallNowRight`, but you can add them wherever you want. + +```diff ++static const u8 sText_PlayerLostToEnemyTrainer[] = _("{B_PLAYER_NAME} is out of\nusable POKéMON!\pPlayer lost against\n{B_TRAINER1_CLASS} {B_TRAINER1_NAME}!{PAUSE_UNTIL_PRESS}"); ++static const u8 sText_PlayerPaidPrizeMoney[] = _("{B_PLAYER_NAME} paid ¥{B_BUFF1} as the prize\nmoney…\p… … … …\p{B_PLAYER_NAME} whited out!{PAUSE_UNTIL_PRESS}"); +``` + +Now we have to link the constants we added previously to the labels of these new text strings by registering them in the `gBattleStringsTable`. + +```diff ++ [STRINGID_PLAYERLOSTTOENEMYTRAINER - 12] = sText_PlayerLostToEnemyTrainer, ++ [STRINGID_PLAYERPAIDPRIZEMONEY - 12] = sText_PlayerPaidPrizeMoney, +``` + +Again, you can add these wherever you want. If you want to remain consistent, you would add them right after Line 849, but it doesn't matter as long as you add them to the table. + +## 2. Modifying the White Out BattleScript + +Let's put these new battle strings to use, shall we? To do that, we'll do some quick changes to the BattleScript that triggers when you lose a battle, i.e. `BattleScript_LocalBattleLostPrintWhiteOut` in **[data/battle_scrpts_1.s](https://github.com/pret/pokeemerald/blob/master/data/battle_scripts_1.s)**. + +```diff +BattleScript_LocalBattleLostPrintWhiteOut:: + printstring STRINGID_PLAYERWHITEOUT + waitmessage 0x40 ++ getmoneyreward + printstring STRINGID_PLAYERWHITEOUT2 + waitmessage 0x40 ++ end2 +BattleScript_LocalBattleLostEnd:: ++ printstring STRINGID_PLAYERLOSTTOENEMYTRAINER ++ waitmessage 0x40 ++ getmoneyreward ++ printstring STRINGID_PLAYERPAIDPRIZEMONEY ++ waitmessage 0x40 + end2 +``` + +Here we're setting up the BattleScript so the `Cmd_getmoneyreward` function will be triggered if the Player loses a battle, and we're also putting our new text strings to use. + +Now, normally, `Cmd_getmoneyreward` is in charge of calculating the money you receive as a reward for winning and that alone. + +You can guess what are we going to modify next, can't you? + +## 3. Modifying the `Cmd_getmoneyreward` function + +Before anything, we have to define a new variable and 2 array lists that we're going to use soon enough. + +```diff ++extern u8 gMaxPartyLevel; + ++static const u16 sBadgeFlags[8] = { ++ FLAG_BADGE01_GET, FLAG_BADGE02_GET, FLAG_BADGE03_GET, FLAG_BADGE04_GET, ++ FLAG_BADGE05_GET, FLAG_BADGE06_GET, FLAG_BADGE07_GET, FLAG_BADGE08_GET, ++}; + ++static const u16 sWhiteOutBadgeMoney[9] = { 8, 16, 24, 36, 48, 60, 80, 100, 120 }; +``` + +If I were you I'd add them right below `sBattlePalaceNatureToFlavorTextId`, that is right before the first function in the file. + +And now we're ready to actually modify `Cmd_getmoneyreward`: + +```diff +static void Cmd_getmoneyreward(void) +{ +- u32 moneyReward = GetTrainerMoneyToGive(gTrainerBattleOpponent_A); +- if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) +- moneyReward += GetTrainerMoneyToGive(gTrainerBattleOpponent_B); ++ u32 money; + +- AddMoney(&gSaveBlock1Ptr->money, moneyReward); +- PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff1, 5, moneyReward); ++ if (gBattleOutcome == B_OUTCOME_WON) ++ { ++ money = GetTrainerMoneyToGive(gTrainerBattleOpponent_A); ++ if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) ++ money += GetTrainerMoneyToGive(gTrainerBattleOpponent_B); ++ AddMoney(&gSaveBlock1Ptr->money, money); ++ } ++ else ++ { ++ s32 i, count; ++ for (i = 0; i < PARTY_SIZE; i++) ++ { ++ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) != SPECIES_NONE ++ && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) != SPECIES_EGG) ++ { ++ if (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL) > gMaxPartyLevel) ++ gMaxPartyLevel = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); ++ } ++ } ++ for (count = 0, i = 0; i < ARRAY_COUNT(sBadgeFlags); i++) ++ { ++ if (FlagGet(sBadgeFlags[i]) == TRUE) ++ ++count; ++ } ++ money = sWhiteOutBadgeMoney[count] * gMaxPartyLevel; ++ RemoveMoney(&gSaveBlock1Ptr->money, money); ++ } + ++ PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff1, 5, money); + gBattlescriptCurrInstr++; +} +``` + +Here, we're making `Cmd_getmoneyreward` handle not only the money calculation for winning a battle, but we're also making it calculate how much money should be removed from the Player when they lose a battle, and then we're storing that amount in a buffer to display it in the `STRINGID_PLAYERPAIDPRIZEMONEY` we added earlier. + +As you can see, we're introducing a new extern variable; `gMaxPartyLevel`. + +As this variable plays a central role in `Cmd_getmoneyreward` which is a function that can only be triggered In Battle, we have to make the battle system recognize it. + +To do that, we'll visit the **[src/battle_main.c](https://github.com/pret/pokeemerald/blob/master/src/battle_main.c)** file and throw it in at the end of the EWRAM vars list like so: + +```diff ++EWRAM_DATA u8 gMaxPartyLevel = 1; +``` + +## 4. Modifying the `DoWhiteOut` function + +This function which can be found in the **[src/overworld.c file](https://github.com/pret/pokeemerald/blob/master/src/overworld.c)** is always triggered whenever you lose a battle and it's also in charge of cutting the Player's money by half whenever they lose a battle, as you can easily tell by reading it. + +As the last step of this process, we'll remove that bit because we naturally don't want that to happen. + +```diff +void DoWhiteOut(void) +{ + ScriptContext2_RunNewScript(EventScript_WhiteOut); +- SetMoney(&gSaveBlock1Ptr->money, GetMoney(&gSaveBlock1Ptr->money) / 2); + HealPlayerParty(); + Overworld_ResetStateAfterWhiteOut(); + SetWarpDestinationToLastHealLocation(); + WarpIntoMap(); +} +``` + +And just like that, we're done. Go build a ROM and let a Magikarp faint your party or something.
\ No newline at end of file |