Skip to content

Commit

Permalink
Nature Changer NPC
Browse files Browse the repository at this point in the history
  • Loading branch information
Pseurae committed Oct 5, 2024
1 parent b9f7578 commit 3008001
Show file tree
Hide file tree
Showing 20 changed files with 426 additions and 3 deletions.
1 change: 1 addition & 0 deletions assembly/event_scripts.s
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
.include "assembly/events/elevator_fixing.inc"
.include "assembly/events/field_moves.inc"
.include "assembly/events/movement_repl.inc"
.include "assembly/events/nature_changer.inc"
.include "assembly/events/registered_item.inc"
.include "assembly/events/repel_script.inc"
.include "assembly/events/roclobster.inc"
Expand Down
89 changes: 89 additions & 0 deletions assembly/events/nature_changer.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
.global EventScript_NatureChanger

EventScript_NatureChanger:
lock
faceplayer
msgbox Text_Intro, MSGBOX_YESNO
compare VAR_RESULT, 0
goto_if_eq EventScript_NatureChangerCancel
call EventScript_NatureChanger_ChoosePokemon

compare VAR_0x8004, 255
goto_if_eq EventScript_NatureChangerCancel

call EventScript_NatureChanger_CheckIfEgg

bufferpartymonnick 1, VAR_0x8004

EventScript_NatureChanger_SelectNature:
message Text_WhichNature
waitmessage

call EventScript_NatureChanger_ShowNatureWindow
closemessage

@ B Button check
compare VAR_RESULT, 127
goto_if_eq EventScript_NatureChangerCancel

@ Cancel option check
compare VAR_RESULT, 25
goto_if_eq EventScript_NatureChangerCancel

callnative BufferNatureName

copyvar VAR_0x8005, VAR_RESULT
msgbox Text_AreYouSure, MSGBOX_YESNO
compare VAR_RESULT, 0
goto_if_eq EventScript_NatureChanger_SelectNature

callnative ChangePartyMonNature
release

msgbox Text_Changed, MSGBOX_NPC
end

EventScript_NatureChangerCancel:
msgbox Text_Canceled, MSGBOX_NPC
releaseall
end

EventScript_NatureChangerIsEgg:
msgbox Text_IsEgg, MSGBOX_NPC
releaseall
end

EventScript_NatureChanger_ChoosePokemon:
callnative (0x80f9a0c | 1)
waitstate
return

EventScript_NatureChanger_CheckIfEgg:
specialvar_ VAR_RESULT, 0x147
compare VAR_RESULT, SPECIES_EGG

goto_if_eq EventScript_NatureChangerIsEgg
return

EventScript_NatureChanger_ShowNatureWindow:
callnative DrawNaturesWindow
waitstate
return

Text_Intro:
.string "Would you like me to change one of your\nPOKéMON's NATURE?$"

Text_WhichNature:
.string "Which nature should I give\n{STR_VAR_2}?$"

Text_Canceled:
.string "Come visit me if you have a change of\nheart.$"

Text_IsEgg:
.string "I can't change the NATURE of an EGG!$"

Text_AreYouSure:
.string "Are you sure you want to change\n{STR_VAR_2}'s NATURE to {STR_VAR_1}?$"

Text_Changed:
.string "I've changed your {STR_VAR_2}'s NATURE\nto {STR_VAR_1}!$"
6 changes: 6 additions & 0 deletions assembly/macros/events.inc
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@
.2byte SPECIAL_\function
.endm

.macro specialvar_ output:req, function:req
.byte 0x26
.2byte \output
.2byte \function
.endm

@ Blocks script execution until a command or ASM code manually unblocks it. Generally used with specific commands and specials. If this command runs, and a subsequent command or piece of ASM does not unblock state, the script will remain blocked indefinitely (essentially a hang).
.macro waitstate
.byte 0x27
Expand Down
3 changes: 3 additions & 0 deletions config.asm
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
; New Game speech uses the dialogue box instead of the normal menu box.
.definelabel BIRCH_SPEECH_DBOX, 1

; Adds a Nature Changer NPC to Verdanturf's Endless Plains.
.definelabel NATURE_CHANGER, 1

; Bugfixes
; --------

Expand Down
4 changes: 4 additions & 0 deletions include/menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ void LONG_CALL Menu_EraseWindowRect(u8, u8, u8, u8);
void LONG_CALL Menu_BlankWindowRect(u8 left, u8 top, u8 right, u8 bottom);
u8 LONG_CALL PrintStringWithNewlines(
void *win, u8 *dest, const u8 *src, u16 tileDataStartOffset, u8 left, u16 top, u8 width, u32 a8);
void LONG_CALL Menu_PrintItems(u8, u8, u8, const void *);
void LONG_CALL Menu_DestroyCursor(void);
u8 LONG_CALL InitMenu(u8, u8, u8, u8, u8, u8);
u8 LONG_CALL Menu_MoveCursor(s8);
22 changes: 22 additions & 0 deletions include/palette.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,25 @@ bool8 LONG_CALL BeginNormalPaletteFade(u32 selectedPalettes, s8 delay, u8 startY
void LONG_CALL LoadPalette(const void *, u16, u16);
void LONG_CALL LoadCompressedPalette(const void *, u16, u16);
void LONG_CALL TransferPlttBuffer(void);

struct PaletteFadeControl
{
/*0x00*/ u32 multipurpose1;
/*0x04*/ u8 delayCounter:6;
/*0x05*/ u16 y:5; // blend coefficient
/*0x05-06*/ u16 targetY:5; // target blend coefficient
/*0x07*/ u16 blendColor:15;
/*0x07*/ u16 active:1;
/*0x08*/ u16 multipurpose2:6;
/*0x08*/ u16 yDec:1; // whether blend coefficient is decreasing
/*0x08*/ u16 bufferTransferDisabled:1;
/*0x09*/ u16 mode:2;
/*0x09*/ u16 shouldResetBlendRegisters:1;
/*0x09*/ u16 hardwareFadeFinishing:1;
/*0x09-0a*/ u16 softwareFadeFinishingCounter:5;
/*0x0a*/ u16 softwareFadeFinishing:1;
/*0x0a*/ u16 objPaletteToggle:1;
/*0x0a*/ u8 deltaY:4; // rate of change of blend coefficient
};

extern struct PaletteFadeControl gPaletteFade;
41 changes: 39 additions & 2 deletions include/pokemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,38 @@ struct ContestMove
u8 comboMoves[4];
};

struct PACKED BoxPokemon
{
u32 personality;
u32 otId;
u8 nickname[POKEMON_NAME_LENGTH];
u8 language;
u8 isBadEgg:1;
u8 hasSpecies:1;
u8 isEgg:1;
u8 blockBoxRS:1; // Unused, but Pokémon Box Ruby & Sapphire will refuse to deposit a Pokémon with this flag set
u8 otName[7];
u8 markings;
u16 checksum;
u16 nature:5;
u16 unk0:11;

u8 unk1[80 - 32];
};

struct PACKED Pokemon
{
u8 unk0[100];
/*0x00*/ struct BoxPokemon box;
/*0x50*/ u32 status;
/*0x54*/ u8 level;
/*0x55*/ u8 mail;
/*0x56*/ u16 hp;
/*0x58*/ u16 maxHP;
/*0x5A*/ u16 attack;
/*0x5C*/ u16 defense;
/*0x5E*/ u16 speed;
/*0x60*/ u16 spAttack;
/*0x62*/ u16 spDefense;
};

#define BATTLE_STATS_NO 8
Expand Down Expand Up @@ -87,12 +116,19 @@ extern const struct BattleMove gBattleMoves[];
u32 LONG_CALL CanMonLearnTMHM(struct Pokemon *mon, u8 tm);
bool8 LONG_CALL MonKnowsMove(struct Pokemon *mon, u16 move);
u32 LONG_CALL GetMonData(struct Pokemon *mon, s32 field);
void LONG_CALL SetMonData(struct Pokemon *mon, s32 field, u32 dataArg);
u8 LONG_CALL CountAliveMons(u8 a1);
bool8 CheckIfMonCanUseHM(struct Pokemon *mon, u16 hm);
bool8 LONG_CALL CheckIfPartyCanUseTM(u16 tm);
u8 LONG_CALL CalculatePPWithBonus(u16 move, u8 ppBonuses, u8 moveIndex);
bool8 LONG_CALL IsHMMove(u16 move);
u8 LONG_CALL GetNature(struct Pokemon *mon);
u8 LONG_CALL GetNatureFromPersonality(u32 personality);
u16 LONG_CALL CalculateBoxMonChecksum(struct BoxPokemon *boxMon);
void LONG_CALL EncryptBoxMon(struct BoxPokemon *boxMon);
void LONG_CALL DecryptBoxMon(struct BoxPokemon *boxMon);
void LONG_CALL SetBoxMonData(struct BoxPokemon *boxMon, s32 field, u32 dataArg);
void LONG_CALL CalculateMonStats(struct Pokemon *mon);

enum
{
Expand All @@ -106,4 +142,5 @@ enum
STAT_STAGE_EVASION, // 7
};

extern const s8 gNatureStatTable[25][5];
extern const s8 gNatureStatTable[25][5];
extern const u8 *const gNatureNames[25];
4 changes: 4 additions & 0 deletions include/random.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

u16 LONG_CALL Random16(void);
#define Random32() (Random16() << 16 | Random16())
1 change: 1 addition & 0 deletions include/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ void LONG_CALL ScriptContext1_SetupScript(const u8 *ptr);
void LONG_CALL ScriptContext2_Enable(void);
void LONG_CALL ScriptContext1_Stop(void);
bool8 LONG_CALL ScriptContext2_IsEnabled(void);
void LONG_CALL EnableBothScriptContexts(void);
2 changes: 2 additions & 0 deletions include/script_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ struct MenuAction
};

extern u16 gSpecialVar_0x8004;
extern u16 gSpecialVar_0x8005;
extern u16 gSpecialVar_Result;
extern u8 gRepelMenuChoices[3];

void LONG_CALL DrawMultichoiceMenu(
u8 left, u8 top, u8 count, const struct MenuAction *list, u8 ignoreBPress, u8 cursorPos);
u8 LONG_CALL CreateTrainerSprite(u8 trainerSpriteID, s16 x, s16 y, u8 subpriority, u8 *buffer);
void DrawListMenu(u8 left, u8 top, u8 displayCount, u8 totalCount, const struct MenuAction *list, u8 ignoreBPress, u8 cursorPos);
5 changes: 5 additions & 0 deletions linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ SECTIONS {
ALIGN(4)
{
*(.rodata);
} > rom = 0xff

.script_data :
ALIGN(4)
{
*(.script_data);
} > rom = 0xff

Expand Down
2 changes: 2 additions & 0 deletions linker/ram.ld
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ gMapHeader = 0x202e828;
gPlayerAvatar = 0x202e858;
gFieldMessageBoxWindow = 0x0202e87c;
gSpecialVar_0x8004 = 0x202e8cc;
gSpecialVar_0x8005 = 0x202e8ce;
gSpecialVar_Result = 0x202e8dc;
gPartyMenuUseExitCallback = 0x202e8f4;
gMenuWindowPtr = 0x202e9c8;
gMenuTextTileOffset = 0x202e9ce;
gPlttBufferUnfaded = 0x202eac8;
gPlttBufferFaded = 0x202eec8;
gPaletteFade = 0x202f388;
gTrainerBattleOpponent = 0x202ff5e;
gFieldEffectArguments = 0x202ff84;
sPokeMenuCursorPos = 0x202ffa8;
Expand Down
1 change: 1 addition & 0 deletions linker/rodata.ld
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ gOtherText_Pokedex = 0x842c992;
gOtherText_PlayTime = 0x842c99a;

gStatStageRatios = 0x8208244;
gNatureNames = 0x83c1004;
14 changes: 14 additions & 0 deletions linker/text.ld
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ SetMonSpriteTemplate = 0x803c56c | 1;
GetMonData = 0x803cb60 | 1;
CalculatePPWithBonus = 0x803ddec | 1;
GetNature = 0x803f464 | 1;
GetNatureFromPersonality = 0x803f47c | 1;
CanMonLearnTMHM = 0x8040374 | 1;
InitMapView = 0x8053220 | 1;
LoadMapTilesetPalettes = 0x8056d84 | 1;
Expand Down Expand Up @@ -217,3 +218,16 @@ UpdateShadowFieldEffect = 0x8126d10 | 1;
SetSurfBlob_BobState = 0x8127ed0 | 1;
CB2_ShowDiploma = 0x8145d88 | 1;
LoadCompressedObjectPic = 0x800d250 | 1;
GetStringWidthInTilesForScriptMenu = 0x80b511d | 1;
Menu_PrintItems = 0x80728a0 | 1;
Menu_DestroyCursor = 0x8072dec | 1;
InitMenu = 0x8072d40 | 1;
EnableBothScriptContexts = 0x80655fc | 1;
Menu_MoveCursor = 0x80720c4 | 1;
Random16 = 0x8040e84 | 1;
SetMonData = 0x803d1fc | 1;
SetBoxMonData = 0x803d2ec | 1;
CalculateBoxMonChecksum = 0x803b124 | 1;
EncryptBoxMon = 0x803c5f0 | 1;
DecryptBoxMon = 0x803c614 | 1;
CalculateMonStats = 0x803b1b8 | 1;
1 change: 1 addition & 0 deletions main.asm
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
.include "scripts/exp_on_capture.asm"
.include "scripts/hm_system.asm"
.include "scripts/more_exp.asm"
.include "scripts/nature_changer.asm"
.include "scripts/new_title_screen.asm"
.include "scripts/ow_shadows.asm"
.include "scripts/ps_split.asm"
Expand Down
12 changes: 12 additions & 0 deletions scripts/nature_changer.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.if NATURE_CHANGER

.org 0x86C9A10
.word EventScript_NatureChanger

.org 0x803f464
set_function_hook r1, GetNature_


set_nop_bl 0x811233a

.endif
5 changes: 5 additions & 0 deletions src/field_message_box.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,8 @@ void HideFieldMessageBoxInstant(void)
TextWindow_EraseDialogueFrame(&gFieldMessageBoxWindow);
sMessageBoxMode = FIELD_MESSAGE_BOX_HIDDEN;
}

void ShowFieldMessageInstantBuffer(void)
{
ShowFieldMessageInstant(gStringVar1);
}
6 changes: 6 additions & 0 deletions src/pokemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,9 @@ void CheckIfPartyHasMoveForElevator(void)
}
}
}

u8 GetNature_(struct Pokemon *mon)
{
if (mon->box.nature == 0) return GetNatureFromPersonality(GetMonData(mon, MON_DATA_PERSONALITY));
return mon->box.nature - 1;
}
Loading

0 comments on commit 3008001

Please sign in to comment.