diff options
author | ExpoSeed <43502820+ExpoSeed@users.noreply.github.com> | 2020-07-09 16:06:09 -0500 |
---|---|---|
committer | ExpoSeed <43502820+ExpoSeed@users.noreply.github.com> | 2020-07-09 16:06:09 -0500 |
commit | ab5eced4c236988a4e5e2646276e0ccca4bd0a5b (patch) | |
tree | 92eeea0198fa7fda6a9fec3778f2725b6eb0200f | |
parent | 2f54cd2480b684b0f3b4c0b7a6a1bcfa83944ae8 (diff) |
i'm not done yet
-rw-r--r-- | Gen-6-Exp-Share.md | 226 |
1 files changed, 214 insertions, 12 deletions
diff --git a/Gen-6-Exp-Share.md b/Gen-6-Exp-Share.md index 95b6845..7dccf41 100644 --- a/Gen-6-Exp-Share.md +++ b/Gen-6-Exp-Share.md @@ -35,16 +35,218 @@ We also need to change the Exp Share's item description. Edit [src/data/text/ite Now that out of battle strings are taken care of, let's work on the item properties. Edit [src/data/items.h](../blob/master/src/data/items.h): ```diff - [ITEM_EXP_SHARE] = - { - .name = _("EXP. SHARE"), - .itemId = ITEM_EXP_SHARE, - .price = 3000, - .holdEffect = HOLD_EFFECT_EXP_SHARE, - .description = sExpShareDesc, - .pocket = POCKET_ITEMS, - .type = 4, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, - .secondaryId = 0, - }, + [ITEM_EXP_SHARE] = + { + .name = _("EXP. SHARE"), + .itemId = ITEM_EXP_SHARE, + .price = 3000, + .holdEffect = HOLD_EFFECT_EXP_SHARE, + .description = sExpShareDesc, +- .pocket = POCKET_ITEMS, +- .type = 4, +- .fieldUseFunc = ItemUseOutOfBattle_CannotUse, ++ .importance = 1, ++ .pocket = POCKET_KEY_ITEMS, ++ .type = 2, ++ .fieldUseFunc = ItemUseOutOfBattle_ExpShare, + .secondaryId = 0, + }, +``` +We've changed the pocket, set the type to be the same type as other key items (this value only gets read by specific field callbacks like medicines, stones, and the bike anyways, so it's irrelevant), given the item an importance of 1 (so it cannot be tossed or deposited in the PC), and also gave it a function for field use. We will define the field use function next. + +Edit [include/global.h](../blob/master/include/global.h): +```diff + struct SaveBlock2 + { + /*0x00*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; + /*0x08*/ u8 playerGender; // MALE, FEMALE + /*0x09*/ u8 specialSaveWarpFlags; + /*0x0A*/ u8 playerTrainerId[TRAINER_ID_LENGTH]; + /*0x0E*/ u16 playTimeHours; + /*0x10*/ u8 playTimeMinutes; + /*0x11*/ u8 playTimeSeconds; + /*0x12*/ u8 playTimeVBlanks; + /*0x13*/ u8 optionsButtonMode; // OPTIONS_BUTTON_MODE_[NORMAL/LR/L_EQUALS_A] + /*0x14*/ u16 optionsTextSpeed:3; // OPTIONS_TEXT_SPEED_[SLOW/MID/FAST] + u16 optionsWindowFrameType:5; // Specifies one of the 20 decorative borders for text boxes + u16 optionsSound:1; // OPTIONS_SOUND_[MONO/STEREO] + u16 optionsBattleStyle:1; // OPTIONS_BATTLE_STYLE_[SHIFT/SET] + u16 optionsBattleSceneOff:1; // whether battle animations are disabled + u16 regionMapZoom:1; // whether the map is zoomed in ++ u16 expShare:1; + /*0x18*/ struct Pokedex pokedex; + /*0x90*/ u8 filler_90[0x8]; + /*0x98*/ struct Time localTimeOffset; + /*0xA0*/ struct Time lastBerryTreeUpdate; + /*0xA8*/ u32 gcnLinkFlags; // Read by Pokemon Colosseum/XD + /*0xAC*/ u32 encryptionKey; + /*0xB0*/ struct PlayersApprentice playerApprentice; + /*0xDC*/ struct Apprentice apprentices[APPRENTICE_COUNT]; + /*0x1EC*/ struct BerryCrush berryCrush; + /*0x1FC*/ struct PokemonJumpResults pokeJump; + /*0x20C*/ struct BerryPickingResults berryPick; + /*0x21C*/ struct RankingHall1P hallRecords1P[HALL_FACILITIES_COUNT][2][3]; // From record mixing. + /*0x57C*/ struct RankingHall2P hallRecords2P[2][3]; // From record mixing. + /*0x624*/ u16 contestLinkResults[5][4]; // 4 positions for 5 categories. + /*0x64C*/ struct BattleFrontier frontier; + }; // sizeof=0xF2C +``` +Declare a new function in [include/item_use.h](../blob/master/include/item_use.h): +```c +void ItemUseOutOfBattle_ExpShare(u8); +``` +Insert this function into [src/item_use.c](../blob/master/src/item_use.c): +```c +void ItemUseOutOfBattle_ExpShare(u8 taskId) +{ + if (!gSaveBlock2Ptr->expShare) + { + PlaySE(SE_EXPMAX); + if (!gTasks[taskId].data[2]) // to account for pressing select in the overworld + { + DisplayItemMessageOnField(taskId, gText_ExpShareOn, Task_CloseCantUseKeyItemMessage); + } + else + { + DisplayItemMessage(taskId, 1, gText_ExpShareOn, BagMenu_InitListsMenu); + } + } + else + { + PlaySE(SE_PC_OFF); + if (!gTasks[taskId].data[2]) // to account for pressing select in the overworld + { + DisplayItemMessageOnField(taskId, gText_ExpShareOff, Task_CloseCantUseKeyItemMessage); + } + else + { + DisplayItemMessage(taskId, 1, gText_ExpShareOff, BagMenu_InitListsMenu); + } + } + gSaveBlock2Ptr->expShare = !gSaveBlock2Ptr->expShare; +} +``` +This function will toggle `expShare` on or off and display the appropriate message. It is also possible to register the item, so we need to account for that as well. + +Now, all our changes out of battle are complete. In the next step, we will focus on having the new sharing functionality work properly. + +## 2. Edit behavior in battle + +First, we will need some new text for the new Exp. Share. We need to define a new id. Edit [include/constants/battle_string_ids.h](../blob/master/include/constants/battle_string_ids.h): +```diff +-#define BATTLESTRINGS_COUNT 369 ++#define BATTLESTRINGS_COUNT 370 +``` +```diff ++#define STRINGID_TEAMGAINEDEXP 381 +``` + +Add this to [src/battle_message.c](../blob/master/src/battle_message.c). This can be done anywhere as long as it is before `gBattleStringsTable`: +```c +static const u8 sText_TeamGainedEXP[] = _("The rest of the team gained EXP. Points\nthanks to the EXP. SHARE!\p"); +``` +Then add this to `gBattleStringsTable`: +```diff + [STRINGID_PKMNBOXLANETTESPCFULL - 12] = gText_PkmnTransferredLanettesPCBoxFull, + [STRINGID_TRAINER1WINTEXT - 12] = sText_Trainer1WinText, + [STRINGID_TRAINER2WINTEXT - 12] = sText_Trainer2WinText, ++ [STRINGID_TEAMGAINEDEXP - 12] = sText_TeamGainedEXP, + }; +``` + +Now, the rest of our changes will be in `Cmd_getexp` of [src/battle_script_commands.c](../blob/master/src/battle_script_commands.c): +```diff + case 1: // calculate experience points to redistribute + { + u16 calculatedExp; + s32 viaSentIn; + + for (viaSentIn = 0, i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == SPECIES_NONE || GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0) + continue; + if (gBitTable[i] & sentIn) + viaSentIn++; + + item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + if (holdEffect == HOLD_EFFECT_EXP_SHARE) + viaExpShare++; + } + + calculatedExp = gBaseStats[gBattleMons[gBattlerFainted].species].expYield * gBattleMons[gBattlerFainted].level / 7; + + if (viaExpShare) // at least one mon is getting exp via exp share + { + *exp = calculatedExp / 2 / viaSentIn; + if (*exp == 0) + *exp = 1; + + gExpShareExp = calculatedExp / 2 / viaExpShare; + if (gExpShareExp == 0) + gExpShareExp = 1; + } + else + { + *exp = calculatedExp / viaSentIn; + if (*exp == 0) + *exp = 1; + gExpShareExp = 0; + } + + gBattleScripting.getexpState++; + gBattleStruct->expGetterMonId = 0; + gBattleStruct->sentInPokes = sentIn; + } + // fall through + case 2: // set exp value to the poke in expgetter_id and print message + if (gBattleControllerExecFlags == 0) + { + item = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HELD_ITEM); + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + if (holdEffect != HOLD_EFFECT_EXP_SHARE && !(gBattleStruct->sentInPokes & 1)) + { + *(&gBattleStruct->sentInPokes) >>= 1; + gBattleScripting.getexpState = 5; + gBattleMoveDamage = 0; // used for exp + } + else if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL) == MAX_LEVEL) + { + *(&gBattleStruct->sentInPokes) >>= 1; + gBattleScripting.getexpState = 5; + gBattleMoveDamage = 0; // used for exp + } + else + { + // music change in wild battle after fainting a poke + if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) && gBattleMons[0].hp && !gBattleStruct->wildVictorySong) + { + BattleStopLowHpSound(); + PlayBGM(MUS_KACHI2); + gBattleStruct->wildVictorySong++; + } + + if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP)) + { + if (gBattleStruct->sentInPokes & 1) + gBattleMoveDamage = *exp; + else + gBattleMoveDamage = 0; + + if (holdEffect == HOLD_EFFECT_EXP_SHARE) + gBattleMoveDamage += gExpShareExp; + if (holdEffect == HOLD_EFFECT_LUCKY_EGG) + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; ```
\ No newline at end of file |