Implemented Lures using the same vars as repels

This commit is contained in:
Eduardo Quezada 2022-09-11 19:48:27 -04:00
parent e3c19f5df5
commit 2d78ac0192
10 changed files with 175 additions and 39 deletions

View File

@ -19,7 +19,7 @@ EventScript_UsedRepel:
bufferitemname 0, VAR_LAST_REPEL_USED
playse SE_REPEL
lock
msgbox Text_UsedNewRepel, MSGBOX_SIGN
msgbox Text_UsedNewRepelLure, MSGBOX_SIGN
removeitem VAR_LAST_REPEL_USED, 1
waitse
callnative HandleUseExpiredRepel
@ -33,6 +33,41 @@ Text_UseAnother::
.string "REPEL's effect wore off!\n"
.string "Use another?$"
Text_UsedNewRepel::
Text_UsedNewRepelLure::
.string "{PLAYER} used the\n"
.string "{STR_VAR_1}.$"
EventScript_LureWoreOff::
checkitem VAR_LAST_REPEL_USED, 1
compare VAR_RESULT, TRUE
goto_if_eq EventScript_LureUseAnother
lock
msgbox Text_LureWoreOff, MSGBOX_SIGN
release
end
EventScript_LureUseAnother:
lock
msgbox Text_UseAnotherLure, MSGBOX_YESNO
compare VAR_RESULT, YES
goto_if_eq EventScript_UsedLure
release
end
EventScript_UsedLure:
bufferitemname 0, VAR_LAST_REPEL_USED
playse SE_REPEL
lock
msgbox Text_UsedNewRepelLure, MSGBOX_SIGN
removeitem VAR_LAST_REPEL_USED, 1
waitse
callnative HandleUseExpiredLure
release
end
Text_LureWoreOff:
.string "Lure's effect wore off…$"
Text_UseAnotherLure::
.string "Lure's effect wore off!\n"
.string "Use another?$"

View File

@ -16,4 +16,10 @@
#define KEYITEMS_POCKET 4
#define POCKETS_COUNT 5
#define REPEL_LURE_MASK (1 << 15)
#define IS_LAST_USED_LURE(var) (var & REPEL_LURE_MASK)
#define REPEL_LURE_STEPS(var) (var & (REPEL_LURE_MASK - 1))
#define LURE_STEPS(var) (IS_LAST_USED_LURE(var) ? REPEL_LURE_STEPS(var) : 0)
#define REPEL_STEPS(var) (!IS_LAST_USED_LURE(var) ? REPEL_LURE_STEPS(var) : 0)
#endif // GUARD_ITEM_CONSTANTS_H

View File

@ -47,7 +47,7 @@
// general purpose vars
#define VAR_RECYCLE_GOODS 0x4020
#define VAR_REPEL_STEP_COUNT 0x4021
#define VAR_REPEL_LURE_STEP_COUNT 0x4021
#define VAR_ICE_STEP_COUNT 0x4022
#define VAR_STARTER_MON 0x4023 // 0=Treecko, 1=Torchic, 2=Mudkip
#define VAR_MIRAGE_RND_H 0x4024

View File

@ -20,6 +20,7 @@ void ItemUseOutOfBattle_PPUp(u8);
void ItemUseOutOfBattle_RareCandy(u8);
void ItemUseOutOfBattle_TMHM(u8);
void ItemUseOutOfBattle_Repel(u8);
void ItemUseOutOfBattle_Lure(u8);
void ItemUseOutOfBattle_EscapeRope(u8);
void ItemUseOutOfBattle_BlackWhiteFlute(u8);
void ItemUseOutOfBattle_EvolutionStone(u8);

View File

@ -936,6 +936,7 @@ extern const u8 gText_BootedUpTM[];
extern const u8 gText_TMHMContainedVar1[];
extern const u8 gText_PlayerUsedVar2[];
extern const u8 gText_RepelEffectsLingered[];
extern const u8 gText_LureEffectsLingered[];
extern const u8 gText_UsedVar2WildLured[];
extern const u8 gText_UsedVar2WildRepelled[];
extern const u8 gText_BoxFull[];

View File

@ -1565,7 +1565,7 @@ const struct Item gItems[] =
.description = sLureDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.fieldUseFunc = ItemUseOutOfBattle_Lure,
.secondaryId = 0,
.flingPower = 30,
},
@ -1579,7 +1579,7 @@ const struct Item gItems[] =
.description = sSuperLureDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.fieldUseFunc = ItemUseOutOfBattle_Lure,
.secondaryId = 0,
.flingPower = 30,
},
@ -1593,7 +1593,7 @@ const struct Item gItems[] =
.description = sMaxLureDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.fieldUseFunc = ItemUseOutOfBattle_Lure,
.secondaryId = 0,
.flingPower = 30,
},

View File

@ -952,8 +952,3 @@ u8 ItemId_GetFlingPower(u16 itemId)
{
return gItems[SanitizeItemId(itemId)].flingPower;
}
void HandleUseExpiredRepel(void)
{
VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(VarGet(VAR_LAST_REPEL_USED)));
}

View File

@ -67,7 +67,9 @@ static void Task_ShowTMHMContainedMessage(u8);
static void UseTMHMYesNo(u8);
static void UseTMHM(u8);
static void Task_StartUseRepel(u8);
static void Task_StartUseLure(u8 taskId);
static void Task_UseRepel(u8);
static void Task_UseLure(u8 taskId);
static void Task_CloseCantUseKeyItemMessage(u8);
static void SetDistanceOfClosestHiddenItem(u8, s16, s16);
static void CB2_OpenPokeblockFromBag(void);
@ -846,7 +848,7 @@ static void RemoveUsedItem(void)
void ItemUseOutOfBattle_Repel(u8 taskId)
{
if (VarGet(VAR_REPEL_STEP_COUNT) == 0)
if (REPEL_STEPS(VarGet(VAR_REPEL_LURE_STEP_COUNT)) == 0)
gTasks[taskId].func = Task_StartUseRepel;
else if (!InBattlePyramid())
DisplayItemMessage(taskId, FONT_NORMAL, gText_RepelEffectsLingered, CloseItemMessage);
@ -870,7 +872,7 @@ static void Task_UseRepel(u8 taskId)
{
if (!IsSEPlaying())
{
VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_ItemId));
VarSet(VAR_REPEL_LURE_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_ItemId));
VarSet(VAR_LAST_REPEL_USED, gSpecialVar_ItemId);
RemoveUsedItem();
if (!InBattlePyramid())
@ -879,6 +881,51 @@ static void Task_UseRepel(u8 taskId)
DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage);
}
}
void HandleUseExpiredRepel(void)
{
VarSet(VAR_REPEL_LURE_STEP_COUNT, ItemId_GetHoldEffectParam(VarGet(VAR_LAST_REPEL_USED)));
}
void ItemUseOutOfBattle_Lure(u8 taskId)
{
if (LURE_STEPS(VarGet(VAR_REPEL_LURE_STEP_COUNT)) == 0)
gTasks[taskId].func = Task_StartUseLure;
else if (!InBattlePyramid())
DisplayItemMessage(taskId, FONT_NORMAL, gText_LureEffectsLingered, CloseItemMessage);
else
DisplayItemMessageInBattlePyramid(taskId, gText_LureEffectsLingered, Task_CloseBattlePyramidBagMessage);
}
static void Task_StartUseLure(u8 taskId)
{
s16* data = gTasks[taskId].data;
if (++data[8] > 7)
{
data[8] = 0;
PlaySE(SE_REPEL);
gTasks[taskId].func = Task_UseLure;
}
}
static void Task_UseLure(u8 taskId)
{
if (!IsSEPlaying())
{
VarSet(VAR_REPEL_LURE_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_ItemId) | REPEL_LURE_MASK);
VarSet(VAR_LAST_REPEL_USED, gSpecialVar_ItemId);
RemoveUsedItem();
if (!InBattlePyramid())
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage);
else
DisplayItemMessageInBattlePyramid(taskId, gStringVar4, Task_CloseBattlePyramidBagMessage);
}
}
void HandleUseExpiredLure(void)
{
VarSet(VAR_REPEL_LURE_STEP_COUNT, ItemId_GetHoldEffectParam(VarGet(VAR_LAST_REPEL_USED)) | REPEL_LURE_MASK);
}
static void Task_UsedBlackWhiteFlute(u8 taskId)
{

View File

@ -244,6 +244,7 @@ const u8 gText_BootedUpHM[] = _("Booted up an HM.");
const u8 gText_TMHMContainedVar1[] = _("It contained\n{STR_VAR_1}.\pTeach {STR_VAR_1}\nto a POKéMON?");
const u8 gText_PlayerUsedVar2[] = _("{PLAYER} used the\n{STR_VAR_2}.{PAUSE_UNTIL_PRESS}");
const u8 gText_RepelEffectsLingered[] = _("But the effects of a REPEL\nlingered from earlier.{PAUSE_UNTIL_PRESS}");
const u8 gText_LureEffectsLingered[] = _("But the effects of a Lure\nlingered from earlier.{PAUSE_UNTIL_PRESS}");
const u8 gText_UsedVar2WildLured[] = _("{PLAYER} used the\n{STR_VAR_2}.\pWild POKéMON will be lured.{PAUSE_UNTIL_PRESS}");
const u8 gText_UsedVar2WildRepelled[] = _("{PLAYER} used the\n{STR_VAR_2}.\pWild POKéMON will be repelled.{PAUSE_UNTIL_PRESS}");
const u8 gText_BoxFull[] = _("The BOX is full.{PAUSE_UNTIL_PRESS}");

View File

@ -20,11 +20,13 @@
#include "constants/abilities.h"
#include "constants/battle_config.h"
#include "constants/game_stat.h"
#include "constants/item.h"
#include "constants/items.h"
#include "constants/layouts.h"
#include "constants/weather.h"
extern const u8 EventScript_RepelWoreOff[];
extern const u8 EventScript_LureWoreOff[];
#define MAX_ENCOUNTER_RATE 2880
@ -181,58 +183,82 @@ static void FeebasSeedRng(u16 seed)
// LAND_WILD_COUNT
static u8 ChooseWildMonIndex_Land(void)
{
u8 wildMonIndex = 0;
bool8 swap = FALSE;
u8 rand = Random() % ENCOUNTER_CHANCE_LAND_MONS_TOTAL;
if (rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_0)
return 0;
wildMonIndex = 0;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_0 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_1)
return 1;
wildMonIndex = 1;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_1 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_2)
return 2;
wildMonIndex = 2;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_2 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_3)
return 3;
wildMonIndex = 3;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_3 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_4)
return 4;
wildMonIndex = 4;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_4 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_5)
return 5;
wildMonIndex = 5;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_5 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_6)
return 6;
wildMonIndex = 6;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_6 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_7)
return 7;
wildMonIndex = 7;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_7 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_8)
return 8;
wildMonIndex = 8;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_8 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_9)
return 9;
wildMonIndex = 9;
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_9 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_10)
return 10;
wildMonIndex = 10;
else
return 11;
wildMonIndex = 11;
if (LURE_STEPS(VarGet(VAR_REPEL_LURE_STEP_COUNT)) && (Random() % 10 < 2))
swap = TRUE;
if (swap)
wildMonIndex = 11 - wildMonIndex;
return wildMonIndex;
}
// ROCK_WILD_COUNT / WATER_WILD_COUNT
static u8 ChooseWildMonIndex_WaterRock(void)
{
u8 wildMonIndex = 0;
bool8 swap = FALSE;
u8 rand = Random() % ENCOUNTER_CHANCE_WATER_MONS_TOTAL;
if (rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_0)
return 0;
wildMonIndex = 0;
else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_0 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_1)
return 1;
wildMonIndex = 1;
else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_1 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_2)
return 2;
wildMonIndex = 2;
else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_2 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_3)
return 3;
wildMonIndex = 3;
else
return 4;
wildMonIndex = 4;
if (LURE_STEPS(VarGet(VAR_REPEL_LURE_STEP_COUNT)) && (Random() % 10 < 2))
swap = TRUE;
if (swap)
wildMonIndex = 4 - wildMonIndex;
return wildMonIndex;
}
// FISH_WILD_COUNT
static u8 ChooseWildMonIndex_Fishing(u8 rod)
{
u8 wildMonIndex = 0;
bool8 swap = FALSE;
u8 rand = Random() % max(max(ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_TOTAL, ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_TOTAL),
ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_TOTAL);
if (LURE_STEPS(VarGet(VAR_REPEL_LURE_STEP_COUNT)) && (Random() % 10 < 2))
swap = TRUE;
switch (rod)
{
case OLD_ROD:
@ -241,6 +267,9 @@ static u8 ChooseWildMonIndex_Fishing(u8 rod)
else
wildMonIndex = 1;
break;
if (swap)
wildMonIndex = 1 - wildMonIndex;
case GOOD_ROD:
if (rand < ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_2)
wildMonIndex = 2;
@ -248,6 +277,9 @@ static u8 ChooseWildMonIndex_Fishing(u8 rod)
wildMonIndex = 3;
if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_3 && rand < ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_4)
wildMonIndex = 4;
if (swap)
wildMonIndex = 6 - wildMonIndex;
break;
case SUPER_ROD:
if (rand < ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_5)
@ -260,6 +292,9 @@ static u8 ChooseWildMonIndex_Fishing(u8 rod)
wildMonIndex = 8;
if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_8 && rand < ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_9)
wildMonIndex = 9;
if (swap)
wildMonIndex = 14 - wildMonIndex;
break;
}
return wildMonIndex;
@ -521,6 +556,8 @@ static bool8 DoWildEncounterRateTest(u32 encounterRate, bool8 ignoreAbility)
encounterRate = encounterRate * 80 / 100;
ApplyFluteEncounterRateMod(&encounterRate);
ApplyCleanseTagEncounterRateMod(&encounterRate);
if (LURE_STEPS(VarGet(VAR_REPEL_LURE_STEP_COUNT)) != 0)
encounterRate *= 2;
if (!ignoreAbility && !GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG))
{
u32 ability = GetMonAbility(&gPlayerParty[0]);
@ -892,24 +929,37 @@ u16 GetLocalWaterMon(void)
bool8 UpdateRepelCounter(void)
{
u16 steps;
u16 repelLureVar = VarGet(VAR_REPEL_LURE_STEP_COUNT);
u16 steps = REPEL_LURE_STEPS(repelLureVar);
bool32 isLure = IS_LAST_USED_LURE(repelLureVar);
if (InBattlePike() || InBattlePyramid())
return FALSE;
if (InUnionRoom() == TRUE)
return FALSE;
steps = VarGet(VAR_REPEL_STEP_COUNT);
if (steps != 0)
{
steps--;
VarSet(VAR_REPEL_STEP_COUNT, steps);
if (steps == 0)
if (!isLure)
{
ScriptContext_SetupScript(EventScript_RepelWoreOff);
return TRUE;
VarSet(VAR_REPEL_LURE_STEP_COUNT, steps);
if (steps == 0)
{
ScriptContext_SetupScript(EventScript_RepelWoreOff);
return TRUE;
}
}
else
{
VarSet(VAR_REPEL_LURE_STEP_COUNT, steps | REPEL_LURE_MASK);
if (steps == 0)
{
ScriptContext_SetupScript(EventScript_LureWoreOff);
return TRUE;
}
}
}
return FALSE;
}
@ -918,7 +968,7 @@ static bool8 IsWildLevelAllowedByRepel(u8 wildLevel)
{
u8 i;
if (!VarGet(VAR_REPEL_STEP_COUNT))
if (!VarGet(VAR_REPEL_LURE_STEP_COUNT))
return TRUE;
for (i = 0; i < PARTY_SIZE; i++)
@ -1006,7 +1056,7 @@ bool8 TryDoDoubleWildBattle(void)
{
if (GetSafariZoneFlag() || GetMonsStateToDoubles() != PLAYER_HAS_TWO_USABLE_MONS)
return FALSE;
#if B_FLAG_FORCE_DOUBLE_WILD != 0
#if B_FLAG_FORCE_DOUBLE_WILD != 0
else if (FlagGet(B_FLAG_FORCE_DOUBLE_WILD))
return TRUE;
#endif