0 Make Cleanse Tag Avoid All Wild Encounters and Usable If Held By Anyone in Your Party; Make PokeDoll Do the Same for Trainers Seeing You
voloved edited this page 2023-06-08 22:24:45 -04:00

by devolov

De-Nerf Cleanse Tag

The current cleanse tag brings the encounter rate down by 1/3 and must be held by the first Pokemon in the party. Changing ApplyCleanseTagEncounterRateMod in wild_encoutner.c will make it block all wild battles if any Pokemon in the party is holding:

static void ApplyCleanseTagEncounterRateMod(u32 *encRate)
{
-    if (GetMonData(&gPlayerParty[0], MON_DATA_HELD_ITEM) == ITEM_CLEANSE_TAG)
-        *encRate = *encRate * 2 / 3;
+    int i;
+    for (i = 0; i < PARTY_SIZE; i++){
+        if (GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM) == ITEM_CLEANSE_TAG){
+            *encRate = 0;
+            break;
+        }
+    }
}

Then, you can add it to your PC for a new game in player_pc.c:

static const struct ItemSlot sNewGamePCItems[] =
{
    { ITEM_POTION, 1 },
+    {ITEM_CLEANSE_TAG, 1},
    { ITEM_NONE, 0 }
};

Pokedoll to Avoid Battles

Also, I changed the Pokedoll to also be a held item that avoids trainers seeing you. In trainer_see.c:

static u8 GetTrainerApproachDistanceWest(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y);
static u8 GetTrainerApproachDistanceEast(struct ObjectEvent *trainerObj, s16 range, s16 x, s16 y);

+static bool8 ignoreIfPokeDoll(void);
static bool8 TrainerSeeIdle(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
static bool8 TrainerExclamationMark(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
static bool8 WaitTrainerExclamationMark(u8 taskId, struct Task *task, struct ObjectEvent *trainerObj);
    .affineAnims = gDummySpriteAffineAnimTable,
    .callback = SpriteCB_TrainerIcons
};


+static bool8 ignoreIfPokeDoll(void)
+{
+    int i;
+    for (i = 0; i < PARTY_SIZE; i++){
+        if (GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM) == ITEM_POKE_DOLL){
+            return TRUE;
+        }
+    }
+    return FALSE;
+}

// code
bool8 CheckForTrainersWantingBattle(void)
{
    u8 i;

+    if (ignoreIfPokeDoll())
        return FALSE;
    gNoOfApproachingTrainers = 0;
    gApproachingTrainerId = 0;

    for (i = 0; i < OBJECT_EVENTS_COUNT; i++)
    {
        u8 numTrainers;

In item_descriptions.h, I changed its text to:

static const u8 sPokeDollDesc[] = _(
    "Hold to avoid\n"
    "trainers. Use to\n"
    "flee a wild battle.");

Make Cleanse Tag a Toggle-Able Use Item

In flags.h, create a flag for when the cleanse tag is on:

-#define FLAG_UNUSED_0x4EB                                           0x4EB // Unused Flag
+#define FLAG_CLEANSE_TAG                                            0x4EB
 #define FLAG_UNUSED_0x4EC                                           0x4EC // Unused Flag

In item_use.c, define what happens when you select the cleanse tag:

        if (gTasks[taskId].tUsingRegisteredKeyItem) // to account for pressing select in the overworld
            DisplayItemMessageOnField(taskId, gText_ExpShareTurnOff, Task_CloseCantUseKeyItemMessage);
        else
            DisplayItemMessage(taskId, 1, gText_ExpShareTurnOff, CloseItemMessage);
    }
}
+
+void ItemUseOutOfBattle_CleanseTag(u8 taskId)
+{
+    bool8  cleanseTagOn = FlagGet(FLAG_CLEANSE_TAG);
+    if (!cleanseTagOn)
+    {
+        FlagSet(FLAG_CLEANSE_TAG);
+        PlaySE(SE_EXP_MAX);
+        else if (!InBattlePyramid())
+            DisplayItemMessage(taskId, FONT_NORMAL, gText_CleanseTagTurnOn, CloseItemMessage);
+        else
+            DisplayItemMessageInBattlePyramid(taskId, gText_CleanseTagTurnOn, Task_CloseBattlePyramidBagMessage);
+    }
+    else
+    {
+        FlagClear(FLAG_CLEANSE_TAG);
+        PlaySE(SE_PC_OFF);
+        else if (!InBattlePyramid())
+            DisplayItemMessage(taskId, FONT_NORMAL, gText_CleanseTagTurnOff, CloseItemMessage);
+        else
+            DisplayItemMessageInBattlePyramid(taskId, gText_CleanseTagTurnOff, Task_CloseBattlePyramidBagMessage);
+    }
+}

Make that newly togge-able flag affect the encounter rate in wild_enocunters.c:

#include "constants/weather.h"
#include "constants/flags.h"
#include "pokedex.h"
+#include "item.h"

 ...

static void ApplyCleanseTagEncounterRateMod(u32 *encRate)
{
     int i;
+    if (FlagGet(FLAG_CLEANSE_TAG)){
+        if (CheckBagHasItem(ITEM_CLEANSE_TAG, 1)){
+            *encRate = 0;
+            return;
+        }
+        FlagClear(FLAG_CLEANSE_TAG);
+    }
     for (i = 0; i < PARTY_SIZE; i++){
         if (GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM) == ITEM_CLEANSE_TAG){
             *encRate = 0;
             break;
         }
     }
}

In include/item_use.h, add its declaration:

 void ItemUseOutOfBattle_EnigmaBerry(u8);
 void ItemUseOutOfBattle_CannotUse(u8);
+void ItemUseOutOfBattle_CleanseTag(u8);
 void ItemUseInBattle_PokeBall(u8);
 void ItemUseInBattle_StatIncrease(u8);

Add in new text in strings.c:

+const u8 gText_CleanseTagTurnOn[] = _("Turned on Cleanse Tag.\nAll wild encounters will be avoided.{PAUSE_UNTIL_PRESS}");
+const u8 gText_CleanseTagTurnOff[] = _("Turned off Cleanse Tag.{PAUSE_UNTIL_PRESS}");
 const u8 gText_CantDismountBike[] = _("You can't dismount your BIKE here.{PAUSE_UNTIL_PRESS}");
 const u8 gText_ItemFinderNearby[] = _("Huh?\nThe ITEMFINDER's responding!\pThere's an item buried around here!{PAUSE_UNTIL_PRESS}");

In include/strings.h, add the new texts' declarations:

+extern const u8 gText_CleanseTagTurnOn[];
+extern const u8 gText_CleanseTagTurnOff[];
 extern const u8 gText_OaksAdvice[];
 extern const u8 gText_CantDismountBike[];
 extern const u8 gText_ItemFinderNothing[];

Attach the out of battle usage to the item in data/items.h:

     [ITEM_CLEANSE_TAG] =
     {
         .name = _("CLEANSE TAG"),
         .itemId = ITEM_CLEANSE_TAG,
         .price = 200,
         .holdEffect = HOLD_EFFECT_REPEL,
        .description = sCleanseTagDesc,
         .pocket = POCKET_ITEMS,
         .type = ITEM_USE_BAG_MENU,
-        .fieldUseFunc = ItemUseOutOfBattle_CannotUse,
+        .fieldUseFunc = ItemUseOutOfBattle_CleanseTag,
     },