mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-01-13 23:23:43 +01:00
merge w be
This commit is contained in:
commit
e4bf99d777
19
INSTALL.md
19
INSTALL.md
@ -451,13 +451,6 @@ Replace `<output of nproc>` with the number that the `nproc` command returned.
|
||||
|
||||
`nproc` is not available on macOS. The alternative is `sysctl -n hw.ncpu` ([relevant Stack Overflow thread](https://stackoverflow.com/questions/1715580)).
|
||||
|
||||
## Debug info
|
||||
|
||||
To build **pokeemerald.elf** with enhanced debug info:
|
||||
```bash
|
||||
make DINFO=1
|
||||
```
|
||||
|
||||
## devkitARM's C compiler
|
||||
|
||||
This project supports the `arm-none-eabi-gcc` compiler included with devkitARM. If devkitARM (a.k.a. gba-dev) has already been installed as part of the platform-specific instructions, simply run:
|
||||
@ -534,7 +527,7 @@ devkitARM is now installed.
|
||||
|
||||
devkitARM is now installed.
|
||||
|
||||
## Installing devkitARM on Arch Linux
|
||||
### Installing devkitARM on Arch Linux
|
||||
|
||||
1. Follow [devkitPro's instructions](https://devkitpro.org/wiki/devkitPro_pacman#Customising_Existing_Pacman_Install) to configure `pacman` to download devkitPro packages.
|
||||
2. Install `gba-dev`: run the following command as root.
|
||||
@ -552,7 +545,7 @@ devkitARM is now installed.
|
||||
|
||||
devkitARM is now installed.
|
||||
|
||||
## Other toolchains
|
||||
### Other toolchains
|
||||
|
||||
To build using a toolchain other than devkitARM, override the `TOOLCHAIN` environment variable with the path to your toolchain, which must contain the subdirectory `bin`.
|
||||
```bash
|
||||
@ -564,6 +557,14 @@ make TOOLCHAIN="/usr/local/arm-none-eabi"
|
||||
```
|
||||
To compile the `modern` target with this toolchain, the subdirectories `lib`, `include`, and `arm-none-eabi` must also be present.
|
||||
|
||||
### Building with debug info under a modern toolchain
|
||||
|
||||
To build **pokeemerald.elf** with debug symbols under a modern toolchain:
|
||||
```bash
|
||||
make modern DINFO=1
|
||||
```
|
||||
Note that this is not necessary for a non-modern build since those are built with debug symbols by default.
|
||||
|
||||
# Useful additional tools
|
||||
|
||||
* [porymap](https://github.com/huderlem/porymap) for viewing and editing maps
|
||||
|
2
Makefile
2
Makefile
@ -107,7 +107,7 @@ LIBPATH := -L ../../tools/agbcc/lib
|
||||
LIB := $(LIBPATH) -lgcc -lc -L../../libagbsyscall -lagbsyscall
|
||||
else
|
||||
CC1 = $(shell $(PATH_MODERNCC) --print-prog-name=cc1) -quiet
|
||||
override CFLAGS += -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast -g
|
||||
override CFLAGS += -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast
|
||||
ROM := $(MODERN_ROM_NAME)
|
||||
OBJ_DIR := $(MODERN_OBJ_DIR_NAME)
|
||||
LIBPATH := -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libgcc.a))" -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libnosys.a))" -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libc.a))"
|
||||
|
@ -100,9 +100,9 @@
|
||||
special CallTrainerHillFunction
|
||||
.endm
|
||||
|
||||
@ Set the challenge mode to HILL_TAG_* (Normal, Variety, Unique, or Expert)
|
||||
.macro trainerhill_settag tag:req
|
||||
setvar VAR_0x8004, TRAINER_HILL_FUNC_SET_TAG
|
||||
copyvar VAR_0x8005, \tag
|
||||
@ Set the challenge mode to HILL_MODE_* (Normal, Variety, Unique, or Expert)
|
||||
.macro trainerhill_setmode mode:req
|
||||
setvar VAR_0x8004, TRAINER_HILL_FUNC_SET_MODE
|
||||
copyvar VAR_0x8005, \mode
|
||||
special CallTrainerHillFunction
|
||||
.endm
|
||||
|
@ -14193,7 +14193,42 @@ Move_LASH_OUT::
|
||||
end @to do:
|
||||
|
||||
Move_POLTERGEIST::
|
||||
end @to do:
|
||||
loadspritegfx ANIM_TAG_EYE_SPARKLE
|
||||
loadspritegfx ANIM_TAG_WHITE_SHADOW @Destiny Bond
|
||||
loadspritegfx ANIM_TAG_QUICK_GUARD_HAND @Black Colour
|
||||
loadspritegfx ANIM_TAG_IMPACT
|
||||
loadspritegfx ANIM_TAG_POLTERGEIST
|
||||
fadetobg BG_NIGHTMARE
|
||||
waitbgfadein
|
||||
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 2, 0, 0, 16, RGB_BLACK
|
||||
waitforvisualfinish
|
||||
createsprite gEyeSparkleSpriteTemplate, ANIM_ATTACKER, 0, -16, -8
|
||||
createsprite gEyeSparkleSpriteTemplate, ANIM_ATTACKER, 0, 16, -8
|
||||
playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER
|
||||
waitforvisualfinish
|
||||
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 2, 0, 16, 0, RGB_BLACK
|
||||
playsewithpan SE_M_FAINT_ATTACK, SOUND_PAN_ATTACKER
|
||||
delay 0x1
|
||||
launchtask AnimTask_DestinyBondWhiteShadow 0x5 0x2 0x0 0x24
|
||||
delay 0x30
|
||||
playsewithpan SE_M_SAND_ATTACK, SOUND_PAN_TARGET
|
||||
createvisualtask AnimTask_PoltergeistItem, 2
|
||||
waitforvisualfinish
|
||||
setalpha 12, 8
|
||||
launchtemplate gBasicHitSplatSpriteTemplate 0x2 0x4 0x0 0x0 0x1 0x1
|
||||
launchtask AnimTask_ShakeMon 0x5 0x5 0x1 0x0 0x5 0x5 0x1
|
||||
launchtemplate gComplexPaletteBlendSpriteTemplate 0x2 0x7 0x7 0x5 0x1 0x0 0xa 0x0 0x0
|
||||
playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET
|
||||
waitforvisualfinish
|
||||
launchtask AnimTask_NightmareClone 0x2 0x0
|
||||
launchtask AnimTask_ShakeMon 0x2 0x5 0x1 0x3 0x0 0x28 0x1
|
||||
playsewithpan SE_M_NIGHTMARE, SOUND_PAN_TARGET
|
||||
waitforvisualfinish
|
||||
restorebg
|
||||
waitbgfadein
|
||||
clearmonbg 0x3
|
||||
blendoff
|
||||
end
|
||||
|
||||
Move_CORROSIVE_GAS::
|
||||
end @to do:
|
||||
|
@ -2390,7 +2390,7 @@ BattleScript_EffectPsychicTerrain:
|
||||
waitanimation
|
||||
printfromtable gTerrainStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
playanimation BS_SCRIPTING, B_ANIM_RESTORE_BG
|
||||
playanimation BS_ATTACKER, B_ANIM_RESTORE_BG
|
||||
call BattleScript_TerrainSeedLoop
|
||||
jumpifabilitypresent ABILITY_MIMICRY, BattleScript_ApplyMimicry
|
||||
goto BattleScript_MoveEnd
|
||||
@ -6264,12 +6264,30 @@ BattleScript_LocalBattleLost::
|
||||
jumpifbattletype BATTLE_TYPE_EREADER_TRAINER, BattleScript_LocalBattleLostEnd
|
||||
jumpifhalfword CMP_EQUAL, gTrainerBattleOpponent_A, TRAINER_SECRET_BASE, BattleScript_LocalBattleLostEnd
|
||||
BattleScript_LocalBattleLostPrintWhiteOut::
|
||||
.if B_WHITEOUT_MONEY >= GEN_4
|
||||
jumpifbattletype BATTLE_TYPE_TRAINER, BattleScript_LocalBattleLostEnd
|
||||
printstring STRINGID_PLAYERWHITEOUT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
getmoneyreward
|
||||
printstring STRINGID_PLAYERWHITEOUT2
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
BattleScript_LocalBattleLostEnd::
|
||||
printstring STRINGID_PLAYERLOSTTOENEMYTRAINER
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
getmoneyreward
|
||||
printstring STRINGID_PLAYERPAIDPRIZEMONEY
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
.else
|
||||
printstring STRINGID_PLAYERWHITEOUT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
printstring STRINGID_PLAYERWHITEOUT2
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_LocalBattleLostEnd::
|
||||
end2
|
||||
.endif
|
||||
|
||||
BattleScript_CheckDomeDrew::
|
||||
jumpifbyte CMP_EQUAL, gBattleOutcome, B_OUTCOME_DREW, BattleScript_LocalBattleLostEnd_
|
||||
BattleScript_LocalBattleLostPrintTrainersWinText::
|
||||
|
@ -157,7 +157,7 @@ TrainerHill_Entrance_EventScript_ChooseChallenge::
|
||||
switch VAR_RESULT
|
||||
case 4, TrainerHill_Entrance_EventScript_CancelEntry
|
||||
case MULTI_B_PRESSED, TrainerHill_Entrance_EventScript_CancelEntry
|
||||
trainerhill_settag VAR_RESULT
|
||||
trainerhill_setmode VAR_RESULT
|
||||
setvar VAR_TRAINER_HILL_IS_ACTIVE, 1
|
||||
setvar VAR_TEMP_5, 0
|
||||
special HealPlayerParty
|
||||
|
19
graphics/battle_anims/sprites/new/poltergeist.pal
Normal file
19
graphics/battle_anims/sprites/new/poltergeist.pal
Normal file
@ -0,0 +1,19 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
246 246 246
|
||||
246 246 246
|
||||
213 197 230
|
||||
213 197 230
|
||||
180 148 213
|
||||
180 148 213
|
||||
180 148 213
|
||||
148 98 197
|
||||
115 65 164
|
||||
82 32 131
|
||||
82 32 131
|
||||
82 32 131
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
BIN
graphics/trainer_hill/maps_expert/floor_0/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_expert/floor_0/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_expert/floor_0/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_expert/floor_0/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;;;9989:;;;1;;;;;,99:;;;;;1;;;;isMMMMŃMMMMis@;UUUUŃUUUU1AiAĹŮŮŮšŮŮŮĆAsi;ÔŰ›sss›ŰĚ1si;Í›ssDss›Ő1si;ÔŰ›sss›ŰĚ1siAŃŰŰŰ›ŰŰŰŰAs@;ÇÇŰŰŰÇÇ1Ai;MMggŰŰŰggMM1si;UU××ŃŰŰ××UU1si;9999:;;9999:sissssssssssssss
|
BIN
graphics/trainer_hill/maps_expert/floor_1/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_expert/floor_1/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_expert/floor_1/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_expert/floor_1/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;;;9989:;;;‘FFFFFFFFFFFFFx‘F›|›››}›|›{›z›‘F}FFFFFFFFFFFF‘F›~›››}›~›ł›››‘FFFFFFFFFFFFF›‘F›}›|›{›z›|›››‘F›FFFFFFFFFFFF‘F›|›}›~›››}›~›‘FFFFFFFFFFFFFł‘Ö–››–ÖŰÖ–››–Ö›Ö–››–ÖŰŰŰÖ–››–Ö–››–ÖŰŰŰŰŰÖ–››–Ö–››–ÖŰŰŰÖ–››–Ö‘Ö–››–ÖŰÖ–››–Ö›
|
1
graphics/trainer_hill/maps_expert/floor_2/collision.bin
Executable file
1
graphics/trainer_hill/maps_expert/floor_2/collision.bin
Executable file
@ -0,0 +1 @@
|
||||
<EFBFBD>áñù>ù>}~=x½=x}~y>ù>ñá
|
1
graphics/trainer_hill/maps_expert/floor_2/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_expert/floor_2/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
ムロロロルル<15>圀屁ムロロロユユテ<EFBE95>歯屁屁ムロロユヒヒヒ絜給副屁ムロユヒヒヒヒ絜給虚屁ムロヒヒヒヒヒ絜給給屁ムユヒヒヒヒヒ綷給給副ムヒヒヒヒフフ驎結給魚ムフフフフ顥顥絜給魚ムユユユユ隯隯絜給魚ムヒヒヒヒ<EFBE8B>驎<EFBFBD>給魚ムフヒヒヒヒヒ驎給給憲ムロヒヒヒヒヒ顥給給屁ムロフヒヒヒヒ絜給旧屁ムロロフヒヒヒ絜給憲屁ムロロロフフヒ綷血屁屁ムロロロロロフ蕙屁屁屁
|
BIN
graphics/trainer_hill/maps_expert/floor_3/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_expert/floor_3/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_expert/floor_3/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_expert/floor_3/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;;;9999:;;;<08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>F<EFBFBD><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>F<EFBFBD><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD>FF<46>FF<46><46><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD>F66<36>66F<36><46><EFBFBD><EFBFBD><08><><EFBFBD>F<EFBFBD>FF<46>FF<46>F<EFBFBD><46><EFBFBD><08><>F6F<36><46><EFBFBD>ۛF6F<36><46><08><>F6<46><36><EFBFBD><EFBFBD><EFBFBD>ۛ6F<36><46><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֖<EFBFBD><D696>ۛ<EFBFBD><DB9B><EFBFBD><08><>F6<46><36><EFBFBD><EFBFBD><EFBFBD>ۛ6F<36><46><08><>F6F<36><46><EFBFBD>ۛF6F<36><46><08><><EFBFBD>F<EFBFBD>FF<46>FF<46>F<EFBFBD><46><EFBFBD><08><><EFBFBD><EFBFBD>F66<36>66F<36><46><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD>FF<46>FF<46><46><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>F<EFBFBD><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>F<EFBFBD><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
1
graphics/trainer_hill/maps_jp/floor_0/collision.bin
Executable file
1
graphics/trainer_hill/maps_jp/floor_0/collision.bin
Executable file
@ -0,0 +1 @@
|
||||
<EFBFBD>ÁoAcA`ADAUAUÁÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
|
1
graphics/trainer_hill/maps_jp/floor_0/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_jp/floor_0/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
155;&&%9:;;;1++;44++43????;1++;;;44;3???;;1++55555;3???;?1+444+44;,???;;1+;5;+;5;5;???;1+;+;+;+;+;???;14;+;4;+5+;;?;;1;;4;;;444?;;;?
|
BIN
graphics/trainer_hill/maps_jp/floor_1/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_jp/floor_1/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_jp/floor_1/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_jp/floor_1/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;5;9&%9:;5;1;+;;+++++;;;+;1;+;;+++++>>;+;1;+;;+++++;;;+;?;+;;+++++;>>+;1;+;;++,++;;;+;1?+;;,,;,,>>;+;1;+5555;55555+;?;,,,,,;,,,,,,;1;??;55;55555551???;++5+++++++1??;;++++++++++1;;;?,,,,,,,,,,
|
1
graphics/trainer_hill/maps_normal/floor_0/collision.bin
Executable file
1
graphics/trainer_hill/maps_normal/floor_0/collision.bin
Executable file
@ -0,0 +1 @@
|
||||
<EFBFBD>ĺ?í˝%„˝ß!~A } ÷Aůy˙˙
|
1
graphics/trainer_hill/maps_normal/floor_0/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_normal/floor_0/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;55&&%&:;5;1;,,,+$$$$,;;,;-;;;;+;;;;5;55;3;2!0+;2!0+;,+;35;;;,5;;;+;;+;4,;2!0+20;+20,;15;;5;,;;5,;;551,20+205;+2!0,,15;;+;;+;,;5;;;1,20+20+;20+20;1555+;;+;;5+;551+,,,20+20,,;,,1+;;5;;+;;5;;;;1,20+;;,20,20;51;;;,;;;;;;;;;,
|
1
graphics/trainer_hill/maps_normal/floor_1/collision.bin
Executable file
1
graphics/trainer_hill/maps_normal/floor_1/collision.bin
Executable file
@ -0,0 +1 @@
|
||||
<EFBFBD><03>s@@<40>Q<EFBFBD>S<EFBFBD>Q<EFBFBD>Q<EFBFBD>Q<EFBFBD>Q<EFBFBD>QPP<10><>
|
1
graphics/trainer_hill/maps_normal/floor_1/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_normal/floor_1/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
ムユユユルルナニホユロユムヒトトロロトトトフフフヒロヒムヒロロロロロロロヒロヒムヒロユユユユユ゚ヒロヒムヒロヒヒヒトトロヒロヒムヒロヒロロトヒピユユヒロヒムヒロヒロロロヒヒロトトヒロヒムヒロヒロロロヒヒユユ゚ヒロヒムヒロヒロロロヒヒトトロヒロヒムヒロヒロロロヒピユユヒロヒムヒロヒロロロトトロトトトロヒムヒロヒ屁屁屁ロユユユヒムトロヒロロロロロ巒ヒヒヒヒムロロヒロロロロロ巒ヒヒヒヒムロロトロロロロロ巒トトトト
|
BIN
graphics/trainer_hill/maps_normal/floor_2/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_normal/floor_2/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_normal/floor_2/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_normal/floor_2/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1555&&8&.55;icddddqqqrdddcsicssssssssssscsicssssssssssscsicCA@ABAAJBAAcsicsssssssdssscsicACKCCABB@A@csicssdsssssssscsicA@BBAABJBABcsicsssssssdssscsicABACKAAA@CAcsicssssdsssssscsicA@CABBAJBABcsidsssssssdsssdsiCCABBACAA@BABsiBsssssssssssBs
|
BIN
graphics/trainer_hill/maps_normal/floor_3/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_normal/floor_3/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_normal/floor_3/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_normal/floor_3/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;;;9&%9:;;;+$$$+;;;;;3+;;;+55;553+;;;+,,;,,3+;;;+4,+;;;,,;;;;;;;3+;;;54+;;;+,;;++;;;+,,+;;;+;;3+;;;+;+;3+555+;,;4,,,,,
|
BIN
graphics/trainer_hill/maps_unique/floor_0/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_unique/floor_0/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_unique/floor_0/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_unique/floor_0/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><15><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۛ<EFBFBD><DB9B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
BIN
graphics/trainer_hill/maps_unique/floor_1/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_unique/floor_1/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_unique/floor_1/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_unique/floor_1/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;;;9&%9:;;;-;;;5,#$#,5;;;;<08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
BIN
graphics/trainer_hill/maps_unique/floor_2/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_unique/floor_2/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_unique/floor_2/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_unique/floor_2/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;;;9989:;;;iFFFFFFFFFFFF|FiFzsssysss}sssFiFsFFFFFFFFFFFFiFss{s|s{szsssFiFFFFFFFFFFFFzFiFsssss}|s|s{sFiFFFFFF|FFFFFFF詮屁妲;;;F屁屁F詮屁妲;;;F屁屁F詮屁妲;;;F屁屁F<08>FFFFFxFFFFFFF<08>驎驎驎z驎驎礰<08>FFFFFFFFFFFF<46>|硺硤硎﨤礼神礼
|
BIN
graphics/trainer_hill/maps_unique/floor_3/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_unique/floor_3/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_unique/floor_3/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_unique/floor_3/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
ّ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>منَ<D986><D98E><EFBFBD>ٍ<><D98D><EFBFBD><EFBFBD><EFBFBD>ًٌٌٌٌٌٌ<D98C><D98C><08>ٌٌٌ<D98C><D98C><EFBFBD><EFBFBD><EFBFBD>ً<EFBFBD><D98B><EFBFBD><EFBFBD><EFBFBD>ّ<><D991><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ً<EFBFBD><D98B><EFBFBD><EFBFBD><EFBFBD>ًًٌٌٌٌٌّ<D98C>ٌ<EFBFBD>ًٌٌٌٌّ<D991><D98B><EFBFBD>ً<EFBFBD><D98B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ًّ<D991><D98B><EFBFBD>ً<EFBFBD>ً<EFBFBD>ً<EFBFBD><D98B><EFBFBD><EFBFBD><EFBFBD>ًّ<D991>ً<EFBFBD>ً<EFBFBD>ً<EFBFBD>ًٌٌٌ<D98C><D98C>ًّ<D991>ً<EFBFBD>ً<EFBFBD>ً<EFBFBD>ً<EFBFBD><D98B><EFBFBD><EFBFBD><EFBFBD>ًّ<D991>ً<EFBFBD>ً<EFBFBD>ً<EFBFBD>ً<EFBFBD>ًٌٌٌٌّ<D991>ً<EFBFBD>ً<EFBFBD>ً<EFBFBD>ً<EFBFBD><D98B><EFBFBD><EFBFBD><EFBFBD>ًّ<D991>ً<EFBFBD>ً<EFBFBD>ً<EFBFBD>ً<EFBFBD><D98B><EFBFBD><EFBFBD><EFBFBD>ٌّ<D991>ً<EFBFBD>ٌ<EFBFBD>ً<EFBFBD>ٌٌٌٌٌ<D98C>ّ<><D991>ً<EFBFBD><D98B><EFBFBD>ً<EFBFBD><D98B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ّ<><D991>ٌ<EFBFBD><D98C><EFBFBD>ٌ<EFBFBD><D98C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
BIN
graphics/trainer_hill/maps_variety/floor_0/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_variety/floor_0/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_variety/floor_0/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_variety/floor_0/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;;;9989:;;;@AAAAABCCCCC@AA@ûCAAAB@CABBBûA@AûAAAB@CACCû@A@AAûCAB@CCCûA@A@AAABBB@CCCAA@A@AAAþþþûþþþAA@A@AAAþþþûþþþAA@A@ABAþûûûûûþAA@A@AAAþþþûþþþAA@A@AAAþþþûþþþAA@A@BACCCA@BBBBA@A@@AûAAAAAAAûA@A@@ûCCAAABBBBû@A@ûCCAACCCCCCCûA@BBBBBBBBBBBBBB
|
BIN
graphics/trainer_hill/maps_variety/floor_1/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_variety/floor_1/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_variety/floor_1/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_variety/floor_1/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;;;9989:;;;<08><><EFBFBD><EFBFBD>@@<40><><EFBFBD>@@<40><><EFBFBD><EFBFBD><08><><EFBFBD>@<40><>@<40>@<40><>B<EFBFBD><42><EFBFBD><08><>@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><42><08>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><08>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><08>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><08>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><08>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><08><>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><42><08><><EFBFBD>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><42><EFBFBD><08><><EFBFBD><EFBFBD>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><42><EFBFBD><EFBFBD><08><><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41><EFBFBD>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD>֖<><D696><EFBFBD><EFBFBD>A<EFBFBD>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><08>֖<EFBFBD><D696><EFBFBD><EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD>֜
|
BIN
graphics/trainer_hill/maps_variety/floor_2/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_variety/floor_2/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_variety/floor_2/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_variety/floor_2/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;;;9989:;;;<08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><17><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><17><><17><17><17><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><17><><17><17><17><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><17><><17><17><17><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><17><><17><17><17><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><17><><17><17><17><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><17><><17><17><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><17><><17><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><17><>
|
BIN
graphics/trainer_hill/maps_variety/floor_3/collision.bin
Executable file
BIN
graphics/trainer_hill/maps_variety/floor_3/collision.bin
Executable file
Binary file not shown.
1
graphics/trainer_hill/maps_variety/floor_3/metatiles.bin
Executable file
1
graphics/trainer_hill/maps_variety/floor_3/metatiles.bin
Executable file
@ -0,0 +1 @@
|
||||
1;;;9989:;;;i@mAsA^AqBEEEEECsdsCsdsAsEEEEEe@sBmBsBmBEEEEElsAsds@sds@sBsAi@mAs@mCsCmBsBm@sdsCsdsAsdsAsdeBsBmAs@mBsAmBslsAsdsBsdsBsdsBi@mAsAmBsCmAsCm@sdsCsdsCsdsBsdeBsBmCsBmBsAm@sls@sdsAsdsBsdsBi@mBsBmCs@mAs@m@sds@sds@sdsCsd
|
@ -621,7 +621,7 @@ struct BattleStruct
|
||||
#define TARGET_TURN_DAMAGED ((gSpecialStatuses[gBattlerTarget].physicalDmg != 0 || gSpecialStatuses[gBattlerTarget].specialDmg != 0))
|
||||
#define BATTLER_DAMAGED(battlerId) ((gSpecialStatuses[battlerId].physicalDmg != 0 || gSpecialStatuses[battlerId].specialDmg != 0))
|
||||
|
||||
#define IS_BATTLER_OF_TYPE(battlerId, type)((gBattleMons[battlerId].type1 == type || gBattleMons[battlerId].type2 == type || gBattleMons[battlerId].type3 == type))
|
||||
#define IS_BATTLER_OF_TYPE(battlerId, type)((gBattleMons[battlerId].type1 == type || gBattleMons[battlerId].type2 == type || (gBattleMons[battlerId].type3 != TYPE_MYSTERY && gBattleMons[battlerId].type3 == type)))
|
||||
#define SET_BATTLER_TYPE(battlerId, type) \
|
||||
{ \
|
||||
gBattleMons[battlerId].type1 = type; \
|
||||
|
@ -86,7 +86,7 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *effectiveness);
|
||||
u8 GetMoveDamageResult(u16 move);
|
||||
u32 GetCurrDamageHpPercent(u8 battlerAtk, u8 battlerDef);
|
||||
u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
|
||||
u8 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
|
||||
u32 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
|
||||
u16 *GetMovesArray(u32 battler);
|
||||
bool32 IsConfusionMoveEffect(u16 moveEffect);
|
||||
bool32 HasMove(u32 battlerId, u32 move);
|
||||
|
@ -15,11 +15,13 @@
|
||||
#define AI_TYPE_MOVE 4
|
||||
|
||||
// type effectiveness
|
||||
#define AI_EFFECTIVENESS_x8 320
|
||||
#define AI_EFFECTIVENESS_x4 160
|
||||
#define AI_EFFECTIVENESS_x2 80
|
||||
#define AI_EFFECTIVENESS_x1 40
|
||||
#define AI_EFFECTIVENESS_x0_5 20
|
||||
#define AI_EFFECTIVENESS_x0_25 10
|
||||
#define AI_EFFECTIVENESS_x0_125 5
|
||||
#define AI_EFFECTIVENESS_x0 0
|
||||
|
||||
// ai weather
|
||||
|
@ -395,6 +395,7 @@
|
||||
#define ANIM_TAG_OMEGA_SYMBOL (ANIM_SPRITES_START + 383)
|
||||
#define ANIM_TAG_PRIMAL_PARTICLES (ANIM_SPRITES_START + 384)
|
||||
#define ANIM_TAG_STEEL_BEAM (ANIM_SPRITES_START + 385)
|
||||
#define ANIM_TAG_POLTERGEIST (ANIM_SPRITES_START + 386)
|
||||
|
||||
// battlers
|
||||
#define ANIM_ATTACKER 0
|
||||
|
@ -104,6 +104,7 @@
|
||||
#define B_PARALYSIS_SPEED GEN_7 // In Gen7+, Speed is decreased by 50% instead of 75%.
|
||||
#define B_CONFUSION_SELF_DMG_CHANCE GEN_7 // In Gen7+, confusion has a 33.3% of self-damage, instead of 50%.
|
||||
#define B_MULTI_HIT_CHANCE GEN_7 // In Gen5+, multi-hit moves have different %. See Cmd_setmultihitcounter for values.
|
||||
#define B_WHITEOUT_MONEY GEN_7 // In Gen4+, the amount of money lost by losing a battle is determined by the amount of badges earned. Previously, it would cut the current money by half. (While this change was also in FRLG, for the sake of simplicity, setting this to GEN_3 will result in RSE behavior.)
|
||||
|
||||
// Exp and stat settings
|
||||
#define B_EXP_CATCH GEN_7 // In Gen6+, Pokémon get experience from catching.
|
||||
|
@ -613,8 +613,10 @@
|
||||
#define STRINGID_METEORBEAMCHARGING 611
|
||||
#define STRINGID_HEATUPBEAK 612
|
||||
#define STRINGID_COURTCHANGE 613
|
||||
#define STRINGID_PLAYERLOSTTOENEMYTRAINER 614
|
||||
#define STRINGID_PLAYERPAIDPRIZEMONEY 615
|
||||
|
||||
#define BATTLESTRINGS_COUNT 614
|
||||
#define BATTLESTRINGS_COUNT 616
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
@ -872,4 +874,16 @@
|
||||
#define B_MSG_TERRAINPREVENTS_ELECTRIC 1
|
||||
#define B_MSG_TERRAINPREVENTS_PSYCHIC 2
|
||||
|
||||
// gWrappedStringIds
|
||||
#define B_MSG_WRAPPED_BIND 0
|
||||
#define B_MSG_WRAPPED_WRAP 1
|
||||
#define B_MSG_WRAPPED_FIRE_SPIN 2
|
||||
#define B_MSG_WRAPPED_CLAMP 3
|
||||
#define B_MSG_WRAPPED_WHIRLPOOL 4
|
||||
#define B_MSG_WRAPPED_SAND_TOMB 5
|
||||
#define B_MSG_WRAPPED_MAGMA_STORM 6
|
||||
#define B_MSG_WRAPPED_INFESTATION 7
|
||||
#define B_MSG_WRAPPED_SNAP_TRAP 8
|
||||
#define TRAPPING_MOVES_COUNT 9
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H
|
||||
|
@ -8,6 +8,12 @@
|
||||
#define TRAINER_HILL_ROOF 5
|
||||
#define TRAINER_HILL_ENTRANCE 6
|
||||
|
||||
#define HILL_MODE_NORMAL 0
|
||||
#define HILL_MODE_VARIETY 1
|
||||
#define HILL_MODE_UNIQUE 2
|
||||
#define HILL_MODE_EXPERT 3
|
||||
#define NUM_TRAINER_HILL_MODES 4
|
||||
|
||||
#define NUM_TRAINER_HILL_FLOORS 4
|
||||
#define NUM_TRAINER_HILL_FLOORS_JP 2
|
||||
|
||||
@ -30,20 +36,33 @@
|
||||
#define TRAINER_HILL_FUNC_SET_GAME_SAVED 14
|
||||
#define TRAINER_HILL_FUNC_CLEAR_GAME_SAVED 15
|
||||
#define TRAINER_HILL_FUNC_GET_WON 16
|
||||
#define TRAINER_HILL_FUNC_SET_TAG 17
|
||||
#define TRAINER_HILL_FUNC_SET_MODE 17
|
||||
|
||||
#define TRAINER_HILL_TEXT_INTRO 2
|
||||
#define TRAINER_HILL_TEXT_PLAYER_LOST 3
|
||||
#define TRAINER_HILL_TEXT_PLAYER_WON 4
|
||||
#define TRAINER_HILL_TEXT_AFTER 5
|
||||
|
||||
#define TRAINER_HILL_TRAINERS_PER_FLOOR 2
|
||||
#define NUM_TRAINER_HILL_TRAINERS (NUM_TRAINER_HILL_FLOORS * TRAINER_HILL_TRAINERS_PER_FLOOR)
|
||||
#define NUM_TRAINER_HILL_TRAINERS_JP (NUM_TRAINER_HILL_FLOORS_JP * TRAINER_HILL_TRAINERS_PER_FLOOR)
|
||||
#define HILL_TRAINERS_PER_FLOOR 2
|
||||
#define NUM_TRAINER_HILL_TRAINERS (NUM_TRAINER_HILL_FLOORS * HILL_TRAINERS_PER_FLOOR)
|
||||
#define NUM_TRAINER_HILL_TRAINERS_JP (NUM_TRAINER_HILL_FLOORS_JP * HILL_TRAINERS_PER_FLOOR)
|
||||
|
||||
// Values returned by TrainerHillGetChallengeStatus
|
||||
#define TRAINER_HILL_PLAYER_STATUS_LOST 0
|
||||
#define TRAINER_HILL_PLAYER_STATUS_ECARD_SCANNED 1
|
||||
#define TRAINER_HILL_PLAYER_STATUS_NORMAL 2
|
||||
|
||||
#define HILL_TRAINER_NAME_LENGTH 11
|
||||
|
||||
#define TRAINER_HILL_OTID 0x10000000
|
||||
|
||||
// The full map of each Trainer Hill floor is 16x21.
|
||||
// The first 5x21 at the top is the entrance/exit area,
|
||||
// and the remaining 16x16 is the randomized portion of
|
||||
// the room where the trainers are.
|
||||
#define HILL_FLOOR_WIDTH 16
|
||||
#define HILL_FLOOR_HEIGHT_MAIN 16
|
||||
#define HILL_FLOOR_HEIGHT_MARGIN 5
|
||||
#define HILL_FLOOR_HEIGHT (HILL_FLOOR_HEIGHT_MAIN + HILL_FLOOR_HEIGHT_MARGIN)
|
||||
|
||||
#endif
|
||||
|
@ -35,7 +35,7 @@ struct EReaderTrainerHillTrainer
|
||||
{
|
||||
u8 trainerNum;
|
||||
struct TrainerHillTrainer trainer;
|
||||
struct TrHillDisplay display;
|
||||
struct TrainerHillFloorMap map;
|
||||
u32 checksum;
|
||||
}; // size=0x274
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "constants/maps.h"
|
||||
#include "constants/pokemon.h"
|
||||
#include "constants/easy_chat.h"
|
||||
#include "constants/trainer_hill.h"
|
||||
#include "constants/expansion_branches.h"
|
||||
|
||||
// Prevent cross-jump optimization.
|
||||
@ -286,8 +287,6 @@ struct BattleTowerPokemon
|
||||
u8 friendship;
|
||||
};
|
||||
|
||||
#define NULL_BATTLE_TOWER_POKEMON { .nickname = __("$$$$$$$$$$$") }
|
||||
|
||||
struct EmeraldBattleTowerRecord
|
||||
{
|
||||
/*0x00*/ u8 lvlMode; // 0 = level 50, 1 = level 100
|
||||
@ -815,7 +814,7 @@ struct TrainerNameRecord
|
||||
u8 trainerName[PLAYER_NAME_LENGTH + 1];
|
||||
};
|
||||
|
||||
struct SaveTrainerHill
|
||||
struct TrainerHillSave
|
||||
{
|
||||
/*0x3D64*/ u32 timer;
|
||||
/*0x3D68*/ u32 bestTime;
|
||||
@ -827,7 +826,7 @@ struct SaveTrainerHill
|
||||
/*0x3D6E*/ u16 hasLost:1;
|
||||
/*0x3D6E*/ u16 maybeECardScanDuringChallenge:1;
|
||||
/*0x3D6E*/ u16 field_3D6E_0f:1;
|
||||
/*0x3D6E*/ u16 tag:2;
|
||||
/*0x3D6E*/ u16 mode:2; // HILL_MODE_*
|
||||
};
|
||||
|
||||
struct WonderNewsMetadata
|
||||
@ -1010,7 +1009,7 @@ struct SaveBlock1
|
||||
/*0x31F8*/ struct EnigmaBerry enigmaBerry;
|
||||
/*0x322C*/ struct MysteryGiftSave mysteryGift;
|
||||
/*0x3598*/ u8 unused_3598[0x180];
|
||||
/*0x3718*/ u32 trainerHillTimes[4];
|
||||
/*0x3718*/ u32 trainerHillTimes[NUM_TRAINER_HILL_MODES];
|
||||
/*0x3728*/ struct RamScript ramScript;
|
||||
/*0x3B14*/ struct RecordMixingGift recordMixingGift;
|
||||
/*0x3B24*/ u8 seen2[NUM_DEX_FLAG_BYTES];
|
||||
@ -1018,7 +1017,7 @@ struct SaveBlock1
|
||||
/*0x3B98*/ struct TrainerNameRecord trainerNameRecords[20];
|
||||
/*0x3C88*/ u8 registeredTexts[UNION_ROOM_KB_ROW_COUNT][21];
|
||||
/*0x3D5A*/ u8 unused_3D5A[10];
|
||||
/*0x3D64*/ struct SaveTrainerHill trainerHill;
|
||||
/*0x3D64*/ struct TrainerHillSave trainerHill;
|
||||
/*0x3D70*/ struct WaldaPhrase waldaPhrase;
|
||||
// sizeof: 0x3D88
|
||||
};
|
||||
|
@ -4906,6 +4906,7 @@ extern const u32 gBattleAnimSpriteGfx_StonePillar[];
|
||||
extern const u32 gBattleAnimSpritePal_StonePillar[];
|
||||
extern const u32 gBattleAnimSpriteGfx_StraightBeam[];
|
||||
extern const u32 gBattleAnimSpritePal_StraightBeam[];
|
||||
extern const u32 gBattleAnimSpritePal_Poltergeist[];
|
||||
extern const u32 gBattleAnimSpriteGfx_SubstituteBack[];
|
||||
extern const u32 gBattleAnimSpriteGfx_SubstituteFront[];
|
||||
extern const u32 gBattleAnimSpritePal_SubstituteFront[];
|
||||
|
@ -1,13 +1,13 @@
|
||||
#ifndef GUARD_TRAINER_HILL_H
|
||||
#define GUARD_TRAINER_HILL_H
|
||||
|
||||
#define HILL_TRAINER_NAME_LENGTH 11
|
||||
#define DUMMY_HILL_MON { .nickname = __("$$$$$$$$$$$") }
|
||||
|
||||
struct TrainerHillTrainer
|
||||
{
|
||||
u8 name[HILL_TRAINER_NAME_LENGTH];
|
||||
u8 facilityClass;
|
||||
u32 unused;
|
||||
bool32 unused; // Set to TRUE on JP trainers
|
||||
u16 speechBefore[EASY_CHAT_BATTLE_WORDS_COUNT];
|
||||
u16 speechWin[EASY_CHAT_BATTLE_WORDS_COUNT];
|
||||
u16 speechLose[EASY_CHAT_BATTLE_WORDS_COUNT];
|
||||
@ -15,44 +15,30 @@ struct TrainerHillTrainer
|
||||
struct BattleTowerPokemon mons[PARTY_SIZE];
|
||||
};
|
||||
|
||||
struct TrHillRoomTrainers
|
||||
struct TrainerHillFloorMap
|
||||
{
|
||||
u8 name[2][HILL_TRAINER_NAME_LENGTH];
|
||||
u8 facilityClass[2];
|
||||
u8 metatileData[HILL_FLOOR_WIDTH * HILL_FLOOR_HEIGHT_MAIN]; // Add NUM_METATILES_IN_PRIMARY to the values in this array to get metatile ids.
|
||||
u16 collisionData[HILL_FLOOR_WIDTH]; // One bit for each tile in column-major order, so every array entry is one row. 1 = impassable, 0 = passable
|
||||
u8 trainerCoords[HILL_TRAINERS_PER_FLOOR]; // Starting at (0,6). Format is 0bYYYYXXXX.
|
||||
u8 trainerDirections; // DIR_* - 1, 4 bits per trainer
|
||||
u8 trainerRanges; // 4 bits per trainer
|
||||
};
|
||||
|
||||
struct TrHillDisplay
|
||||
{
|
||||
// Metatile data. Add 0x200 to the values in this array to get metatiles.
|
||||
// This data then overwrites the metatiles in the map starting at (0,5)
|
||||
u8 metatileData[0x100];
|
||||
// Collision data. One bit for each tile in column-major order,
|
||||
// so every array entry is one row. 1 = impassable, 0 = passable
|
||||
u16 collisionData[16];
|
||||
// Trainer coordinates, starting at (0,6). Format is 0bYYYYXXXX.
|
||||
u8 coords[2];
|
||||
// Trainer facing directions. Same as (DIR_* - 1).
|
||||
// Effectively an array of nibbles, one for each trainer.
|
||||
u8 direction;
|
||||
// Trainer sight ranges. Effectively an array of nibbles, one for each trainer.
|
||||
u8 range;
|
||||
};
|
||||
|
||||
struct TrHillFloor
|
||||
struct TrainerHillFloor
|
||||
{
|
||||
u8 trainerNum1;
|
||||
u8 trainerNum2;
|
||||
struct TrainerHillTrainer trainers[2];
|
||||
struct TrHillDisplay display;
|
||||
struct TrainerHillTrainer trainers[HILL_TRAINERS_PER_FLOOR];
|
||||
struct TrainerHillFloorMap map;
|
||||
};
|
||||
|
||||
struct TrHillTag
|
||||
struct TrainerHillChallenge
|
||||
{
|
||||
u8 numTrainers;
|
||||
u8 unused1;
|
||||
u8 numFloors;
|
||||
u32 checksum;
|
||||
struct TrHillFloor floors[0];
|
||||
u32 checksum; // A byte array sum of the floor data
|
||||
struct TrainerHillFloor floors[0]; // Floor data is assumed to follow, so this will be intentionally read out of bounds
|
||||
};
|
||||
|
||||
extern u32 *gTrainerHillVBlankCounter;
|
||||
|
@ -20,7 +20,9 @@ SECTIONS {
|
||||
. = 0x1C000;
|
||||
|
||||
INCLUDE "sym_ewram.ld"
|
||||
|
||||
*libc.a:impure.o(.data);
|
||||
*libc.a:locale.o(.data);
|
||||
*libc.a:mallocr.o(.data);
|
||||
. = 0x40000;
|
||||
}
|
||||
|
||||
@ -464,6 +466,7 @@ SECTIONS {
|
||||
src/mystery_gift_server.o(.rodata);
|
||||
src/mystery_gift_client.o(.rodata);
|
||||
src/mystery_gift_scripts.o(.rodata);
|
||||
src/wonder_news.o(.rodata);
|
||||
src/union_room_chat.o(.rodata);
|
||||
src/berry_crush.o(.rodata);
|
||||
src/berry_powder.o(.rodata);
|
||||
@ -1250,9 +1253,43 @@ SECTIONS {
|
||||
src/librfu_sio32id.o(.rodata);
|
||||
*libgcc.a:_divdi3.o(.rodata);
|
||||
*libgcc.a:_udivdi3.o(.rodata);
|
||||
*libc.a(.rodata);
|
||||
*libc.a(.data);
|
||||
*libc.a:memcpy.o(.rodata);
|
||||
*libc.a:memset.o(.rodata);
|
||||
*libc.a:strcmp.o(.rodata);
|
||||
*libc.a:strcpy.o(.rodata);
|
||||
*libc.a:impure.o(.rodata);
|
||||
*libc.a:vsprintf.o(.rodata);
|
||||
*libc.a:vfprintf.o(.rodata);
|
||||
*libc.a:wsetup.o(.rodata);
|
||||
*libc.a:dtoa.o(.rodata);
|
||||
*libc.a:fflush.o(.rodata);
|
||||
*libc.a:findfp.o(.rodata);
|
||||
*libc.a:freer.o(.rodata);
|
||||
*libc.a:mtrim.o(.rodata);
|
||||
*libc.a:fvwrite.o(.rodata);
|
||||
*libc.a:fwalk.o(.rodata);
|
||||
*libc.a:locale.o(.rodata);
|
||||
*libc.a:makebuf.o(.rodata);
|
||||
*libc.a:mallocr.o(.rodata);
|
||||
*libc.a:mbtowc_r.o(.rodata);
|
||||
*libc.a:memchr.o(.rodata);
|
||||
*libc.a:memmove.o(.rodata);
|
||||
*libc.a:mlock.o(.rodata);
|
||||
*libc.a:mprec.o(.rodata);
|
||||
*libc.a:s_isinf.o(.rodata);
|
||||
*libc.a:s_isnan.o(.rodata);
|
||||
*libc.a:sbrkr.o(.rodata);
|
||||
*libc.a:stdio.o(.rodata);
|
||||
*libc.a:strlen.o(.rodata);
|
||||
*libc.a:syscalls.o(.rodata);
|
||||
*libc.a:writer.o(.rodata);
|
||||
*libc.a:callocr.o(.rodata);
|
||||
*libc.a:closer.o(.rodata);
|
||||
*libc.a:errno.o(.rodata);
|
||||
*libc.a:fstatr.o(.rodata);
|
||||
*libc.a:libcfunc.o(.rodata);
|
||||
*libc.a:lseekr.o(.rodata);
|
||||
*libc.a:readr.o(.rodata);
|
||||
src/libisagbprn.o(.rodata);
|
||||
} =0
|
||||
|
||||
|
@ -580,7 +580,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
s32 moveType;
|
||||
u16 moveTarget = AI_GetBattlerMoveTargetType(battlerAtk, move);
|
||||
u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, move);
|
||||
u8 effectiveness = AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex];
|
||||
u32 effectiveness = AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex];
|
||||
bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk);
|
||||
u32 i;
|
||||
u16 predictedMove = AI_DATA->predictedMoves[battlerDef];
|
||||
@ -625,6 +625,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
case AI_EFFECTIVENESS_x0:
|
||||
RETURN_SCORE_MINUS(20);
|
||||
break;
|
||||
case AI_EFFECTIVENESS_x0_125:
|
||||
case AI_EFFECTIVENESS_x0_25:
|
||||
RETURN_SCORE_MINUS(10);
|
||||
break;
|
||||
@ -667,7 +668,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
RETURN_SCORE_MINUS(20);
|
||||
break;
|
||||
case ABILITY_WONDER_GUARD:
|
||||
if (effectiveness != AI_EFFECTIVENESS_x2 && effectiveness != AI_EFFECTIVENESS_x4)
|
||||
if (effectiveness < AI_EFFECTIVENESS_x2)
|
||||
return 0;
|
||||
break;
|
||||
case ABILITY_SAP_SIPPER:
|
||||
@ -2545,33 +2546,17 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
|
||||
switch (AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex])
|
||||
{
|
||||
case AI_EFFECTIVENESS_x8:
|
||||
score += 8;
|
||||
break;
|
||||
case AI_EFFECTIVENESS_x4:
|
||||
if (WEATHER_HAS_EFFECT
|
||||
&& gBattleWeather & B_WEATHER_STRONG_WINDS
|
||||
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING))
|
||||
{
|
||||
if (AI_RandLessThan(176)) //Consider it supereffective instead of hypereffective.
|
||||
score += 2;
|
||||
else
|
||||
score++;
|
||||
}
|
||||
else
|
||||
score += 4;
|
||||
score += 4;
|
||||
break;
|
||||
case AI_EFFECTIVENESS_x2:
|
||||
if (WEATHER_HAS_EFFECT
|
||||
&& gBattleWeather & B_WEATHER_STRONG_WINDS
|
||||
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING))
|
||||
{
|
||||
break; // Don't increase score, consider it neutral.
|
||||
}
|
||||
if (AI_RandLessThan(176))
|
||||
score += 2;
|
||||
else
|
||||
{
|
||||
if (AI_RandLessThan(176))
|
||||
score += 2;
|
||||
else
|
||||
score++;
|
||||
}
|
||||
score++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2983,7 +2968,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
{
|
||||
// move data
|
||||
u16 moveEffect = gBattleMoves[move].effect;
|
||||
u8 effectiveness = AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex];
|
||||
u32 effectiveness = AI_DATA->effectiveness[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex];
|
||||
u8 atkPriority = GetMovePriority(battlerAtk, move);
|
||||
u16 predictedMove = AI_DATA->predictedMoves[battlerDef];
|
||||
bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk);
|
||||
|
@ -604,39 +604,39 @@ static u32 GetBestMonBatonPass(struct Pokemon *party, int firstId, int lastId, u
|
||||
return PARTY_SIZE;
|
||||
}
|
||||
|
||||
static u32 GestBestMonOffensive(struct Pokemon *party, int firstId, int lastId, u8 invalidMons, u32 opposingBattler)
|
||||
static u32 GetBestMonTypeMatchup(struct Pokemon *party, int firstId, int lastId, u8 invalidMons, u32 opposingBattler)
|
||||
{
|
||||
int i, bits = 0;
|
||||
|
||||
while (bits != 0x3F) // All mons were checked.
|
||||
{
|
||||
int bestDmg = 0;
|
||||
u32 bestResist = UQ_4_12(1.0);
|
||||
int bestMonId = PARTY_SIZE;
|
||||
// Find the mon whose type is the most suitable offensively.
|
||||
// Find the mon whose type is the most suitable defensively.
|
||||
for (i = firstId; i < lastId; i++)
|
||||
{
|
||||
if (!(gBitTable[i] & invalidMons) && !(gBitTable[i] & bits))
|
||||
{
|
||||
u16 species = GetMonData(&party[i], MON_DATA_SPECIES);
|
||||
u32 typeDmg = UQ_4_12(1.0);
|
||||
u32 typeEffectiveness = UQ_4_12(1.0);
|
||||
|
||||
u8 atkType1 = gBaseStats[species].type1;
|
||||
u8 atkType2 = gBaseStats[species].type2;
|
||||
u8 defType1 = gBattleMons[opposingBattler].type1;
|
||||
u8 defType2 = gBattleMons[opposingBattler].type2;
|
||||
u8 atkType1 = gBattleMons[opposingBattler].type1;
|
||||
u8 atkType2 = gBattleMons[opposingBattler].type2;
|
||||
u8 defType1 = gBaseStats[species].type1;
|
||||
u8 defType2 = gBaseStats[species].type2;
|
||||
|
||||
typeDmg *= GetTypeModifier(atkType1, defType1);
|
||||
typeEffectiveness *= GetTypeModifier(atkType1, defType1);
|
||||
if (atkType2 != atkType1)
|
||||
typeDmg *= GetTypeModifier(atkType2, defType1);
|
||||
typeEffectiveness *= GetTypeModifier(atkType2, defType1);
|
||||
if (defType2 != defType1)
|
||||
{
|
||||
typeDmg *= GetTypeModifier(atkType1, defType2);
|
||||
typeEffectiveness *= GetTypeModifier(atkType1, defType2);
|
||||
if (atkType2 != atkType1)
|
||||
typeDmg *= GetTypeModifier(atkType2, defType2);
|
||||
typeEffectiveness *= GetTypeModifier(atkType2, defType2);
|
||||
}
|
||||
if (bestDmg < typeDmg)
|
||||
if (typeEffectiveness < bestResist)
|
||||
{
|
||||
bestDmg = typeDmg;
|
||||
bestResist = typeEffectiveness;
|
||||
bestMonId = i;
|
||||
}
|
||||
}
|
||||
@ -700,7 +700,6 @@ static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 inva
|
||||
u8 GetMostSuitableMonToSwitchInto(void)
|
||||
{
|
||||
u32 opposingBattler = 0;
|
||||
u32 bestDmg = 0;
|
||||
u32 bestMonId = 0;
|
||||
u8 battlerIn1 = 0, battlerIn2 = 0;
|
||||
s32 firstId = 0;
|
||||
@ -759,7 +758,7 @@ u8 GetMostSuitableMonToSwitchInto(void)
|
||||
if (bestMonId != PARTY_SIZE)
|
||||
return bestMonId;
|
||||
|
||||
bestMonId = GestBestMonOffensive(party, firstId, lastId, invalidMons, opposingBattler);
|
||||
bestMonId = GetBestMonTypeMatchup(party, firstId, lastId, invalidMons, opposingBattler);
|
||||
if (bestMonId != PARTY_SIZE)
|
||||
return bestMonId;
|
||||
|
||||
|
@ -961,29 +961,33 @@ u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
return typeEffectiveness;
|
||||
}
|
||||
|
||||
u8 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
u32 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
{
|
||||
gMoveResultFlags = 0;
|
||||
return AI_GetEffectiveness(AI_GetTypeEffectiveness(move, battlerAtk, battlerDef));
|
||||
}
|
||||
|
||||
static u8 AI_GetEffectiveness(u16 multiplier)
|
||||
static u32 AI_GetEffectiveness(u16 multiplier)
|
||||
{
|
||||
switch (multiplier)
|
||||
{
|
||||
case UQ_4_12(0.0):
|
||||
default:
|
||||
return AI_EFFECTIVENESS_x0;
|
||||
case UQ_4_12(0.125):
|
||||
return AI_EFFECTIVENESS_x0_125;
|
||||
case UQ_4_12(0.25):
|
||||
return AI_EFFECTIVENESS_x0_25;
|
||||
case UQ_4_12(0.5):
|
||||
return AI_EFFECTIVENESS_x0_5;
|
||||
case UQ_4_12(1.0):
|
||||
default:
|
||||
return AI_EFFECTIVENESS_x1;
|
||||
case UQ_4_12(2.0):
|
||||
return AI_EFFECTIVENESS_x2;
|
||||
case UQ_4_12(4.0):
|
||||
return AI_EFFECTIVENESS_x4;
|
||||
case UQ_4_12(8.0):
|
||||
return AI_EFFECTIVENESS_x8;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "battle.h"
|
||||
#include "battle_anim.h"
|
||||
#include "gpu_regs.h"
|
||||
#include "item_icon.h"
|
||||
#include "palette.h"
|
||||
#include "constants/rgb.h"
|
||||
#include "scanline_effect.h"
|
||||
@ -39,6 +40,7 @@ static void AnimGhostStatusSprite_Step(struct Sprite *);
|
||||
static void AnimGrudgeFlame(struct Sprite *);
|
||||
static void AnimMonMoveCircular(struct Sprite *);
|
||||
static void AnimMonMoveCircular_Step(struct Sprite *);
|
||||
static void AnimPoltergeistItem(struct Sprite *);
|
||||
|
||||
static const union AffineAnimCmd sAffineAnim_ConfuseRayBallBounce[] =
|
||||
{
|
||||
@ -270,6 +272,17 @@ const struct SpriteTemplate gFlashCannonBallMovementTemplate =
|
||||
.callback = AnimShadowBall
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gPoltergeistEffectTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_POLTERGEIST,
|
||||
.paletteTag = ANIM_TAG_POLTERGEIST,
|
||||
.oam = &gOamData_AffineNormal_ObjNormal_32x32,
|
||||
.anims = gDummySpriteAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gAffineAnims_ShadowBall,
|
||||
.callback = AnimPoltergeistItem,
|
||||
};
|
||||
|
||||
static void AnimConfuseRayBallBounce(struct Sprite *sprite)
|
||||
{
|
||||
InitSpritePosToAnimAttacker(sprite, TRUE);
|
||||
@ -870,7 +883,8 @@ void AnimTask_DestinyBondWhiteShadow(u8 taskId)
|
||||
&& battler != (gBattleAnimAttacker ^ 2)
|
||||
&& IsBattlerSpriteVisible(battler))
|
||||
{
|
||||
if (gAnimMoveIndex == MOVE_DARK_VOID)
|
||||
if (gAnimMoveIndex == MOVE_DARK_VOID
|
||||
|| gAnimMoveIndex == MOVE_POLTERGEIST)
|
||||
spriteId = CreateSprite(&gDarkVoidBlackHoleTemplate, baseX, baseY, 55); //dark void
|
||||
else
|
||||
spriteId = CreateSprite(&gDestinyBondWhiteShadowSpriteTemplate, baseX, baseY, 55); //destiny bond
|
||||
@ -1395,3 +1409,36 @@ static void AnimMonMoveCircular_Step(struct Sprite *sprite)
|
||||
sprite->callback = DestroySpriteAndMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
void AnimTask_PoltergeistItem(u8 taskId)
|
||||
{
|
||||
struct Task *task = &gTasks[taskId];
|
||||
u8 x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
|
||||
u8 y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + (GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_HEIGHT) / 2);
|
||||
|
||||
task->data[0] = AddItemIconSprite(ANIM_TAG_ITEM_BAG, ANIM_TAG_ITEM_BAG, gLastUsedItem);
|
||||
gSprites[task->data[0]].x = x + 4;
|
||||
gSprites[task->data[0]].y = y + 4;
|
||||
gSprites[task->data[0]].data[0] = x + 4;
|
||||
gSprites[task->data[0]].data[1] = y + 4;
|
||||
gSprites[task->data[0]].callback = AnimPoltergeistItem;
|
||||
|
||||
task->data[1] = CreateSprite(&gPoltergeistEffectTemplate, x, y, 1);
|
||||
gSprites[task->data[1]].data[0] = x;
|
||||
gSprites[task->data[1]].data[1] = y;
|
||||
|
||||
gAnimVisualTaskCount += 2;
|
||||
|
||||
DestroyAnimVisualTask(taskId);
|
||||
}
|
||||
|
||||
static void AnimPoltergeistItem(struct Sprite *sprite)
|
||||
{
|
||||
sprite->data[2] += 4;
|
||||
|
||||
sprite->x = sprite->data[0] + Sin(sprite->data[2], 24);
|
||||
sprite->y = sprite->data[1] + (Cos(sprite->data[2], 24) - 24);
|
||||
|
||||
if (sprite->data[2] == 256)
|
||||
DestroyAnimSprite(sprite);
|
||||
}
|
||||
|
@ -77,8 +77,14 @@ static const u8 sText_ItDoesntAffect[] = _("It doesn't affect\n{B_DEF_NAME_WITH_
|
||||
static const u8 sText_AttackerFainted[] = _("{B_ATK_NAME_WITH_PREFIX}\nfainted!\p");
|
||||
static const u8 sText_TargetFainted[] = _("{B_DEF_NAME_WITH_PREFIX}\nfainted!\p");
|
||||
static const u8 sText_PlayerGotMoney[] = _("{B_PLAYER_NAME} got ¥{B_BUFF1}\nfor winning!\p");
|
||||
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}");
|
||||
static const u8 sText_PlayerWhiteout[] = _("{B_PLAYER_NAME} is out of\nusable POKéMON!\p");
|
||||
#if B_WHITEOUT_MONEY >= GEN_4
|
||||
static const u8 sText_PlayerWhiteout2[] = _("{B_PLAYER_NAME} panicked and lost ¥{B_BUFF1}…\p… … … …\p{B_PLAYER_NAME} whited out!{PAUSE_UNTIL_PRESS}");
|
||||
#else
|
||||
static const u8 sText_PlayerWhiteout2[] = _("{B_PLAYER_NAME} whited out!{PAUSE_UNTIL_PRESS}");
|
||||
#endif
|
||||
static const u8 sText_PreventsEscape[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} prevents\nescape with {B_SCR_ACTIVE_ABILITY}!\p");
|
||||
static const u8 sText_CantEscape2[] = _("Can't escape!\p");
|
||||
static const u8 sText_AttackerCantEscape[] = _("{B_ATK_NAME_WITH_PREFIX} can't escape!");
|
||||
@ -741,6 +747,8 @@ static const u8 sText_CourtChange[] = _("{B_ATK_NAME_WITH_PREFIX} swapped the ba
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_PLAYERLOSTTOENEMYTRAINER - BATTLESTRINGS_TABLE_START] = sText_PlayerLostToEnemyTrainer,
|
||||
[STRINGID_PLAYERPAIDPRIZEMONEY - BATTLESTRINGS_TABLE_START] = sText_PlayerPaidPrizeMoney,
|
||||
[STRINGID_COURTCHANGE - BATTLESTRINGS_TABLE_START] = sText_CourtChange,
|
||||
[STRINGID_HEATUPBEAK - BATTLESTRINGS_TABLE_START] = sText_HeatingUpBeak,
|
||||
[STRINGID_METEORBEAMCHARGING - BATTLESTRINGS_TABLE_START] = sText_MeteorBeamCharging,
|
||||
@ -1562,17 +1570,17 @@ const u16 gFirstTurnOfTwoStringIds[] =
|
||||
};
|
||||
|
||||
// Index copied from move's index in sTrappingMoves
|
||||
const u16 gWrappedStringIds[] =
|
||||
const u16 gWrappedStringIds[TRAPPING_MOVES_COUNT] =
|
||||
{
|
||||
STRINGID_PKMNSQUEEZEDBYBIND, // MOVE_BIND
|
||||
STRINGID_PKMNWRAPPEDBY, // MOVE_WRAP
|
||||
STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_FIRE_SPIN
|
||||
STRINGID_PKMNCLAMPED, // MOVE_CLAMP
|
||||
STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_WHIRLPOOL
|
||||
STRINGID_PKMNTRAPPEDBYSANDTOMB, // MOVE_SAND_TOMB
|
||||
STRINGID_TRAPPEDBYSWIRLINGMAGMA, // MOVE_MAGMA_STORM
|
||||
STRINGID_INFESTATION, // MOVE_INFESTATION
|
||||
STRINGID_PKMNINSNAPTRAP, // MOVE_SNAPTRAP
|
||||
[B_MSG_WRAPPED_BIND] = STRINGID_PKMNSQUEEZEDBYBIND, // MOVE_BIND
|
||||
[B_MSG_WRAPPED_WRAP] = STRINGID_PKMNWRAPPEDBY, // MOVE_WRAP
|
||||
[B_MSG_WRAPPED_FIRE_SPIN] = STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_FIRE_SPIN
|
||||
[B_MSG_WRAPPED_CLAMP] = STRINGID_PKMNCLAMPED, // MOVE_CLAMP
|
||||
[B_MSG_WRAPPED_WHIRLPOOL] = STRINGID_PKMNTRAPPEDINVORTEX, // MOVE_WHIRLPOOL
|
||||
[B_MSG_WRAPPED_SAND_TOMB] = STRINGID_PKMNTRAPPEDBYSANDTOMB, // MOVE_SAND_TOMB
|
||||
[B_MSG_WRAPPED_MAGMA_STORM] = STRINGID_TRAPPEDBYSWIRLINGMAGMA, // MOVE_MAGMA_STORM
|
||||
[B_MSG_WRAPPED_INFESTATION] = STRINGID_INFESTATION, // MOVE_INFESTATION
|
||||
[B_MSG_WRAPPED_SNAP_TRAP] = STRINGID_PKMNINSNAPTRAP, // MOVE_SNAP_TRAP
|
||||
};
|
||||
|
||||
const u16 gMistUsedStringIds[] =
|
||||
|
@ -279,11 +279,18 @@ static const s32 sExperienceScalingFactors[] =
|
||||
159767,
|
||||
};
|
||||
|
||||
static const u16 sTrappingMoves[] =
|
||||
static const u16 sTrappingMoves[TRAPPING_MOVES_COUNT] =
|
||||
{
|
||||
MOVE_BIND, MOVE_WRAP, MOVE_FIRE_SPIN, MOVE_CLAMP, MOVE_WHIRLPOOL, MOVE_SAND_TOMB, MOVE_MAGMA_STORM, MOVE_INFESTATION, MOVE_SNAP_TRAP, 0xFFFF
|
||||
MOVE_BIND, MOVE_WRAP, MOVE_FIRE_SPIN, MOVE_CLAMP, MOVE_WHIRLPOOL, MOVE_SAND_TOMB, MOVE_MAGMA_STORM, MOVE_INFESTATION, MOVE_SNAP_TRAP,
|
||||
};
|
||||
|
||||
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, 64, 80, 100, 120 };
|
||||
|
||||
#define STAT_CHANGE_WORKED 0
|
||||
#define STAT_CHANGE_DIDNT_WORK 1
|
||||
|
||||
@ -3032,10 +3039,8 @@ void SetMoveEffect(bool32 primary, u32 certain)
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleScripting.moveEffect];
|
||||
|
||||
for (gBattleCommunication[MULTISTRING_CHOOSER] = 0; ; gBattleCommunication[MULTISTRING_CHOOSER]++)
|
||||
for (gBattleCommunication[MULTISTRING_CHOOSER] = 0; gBattleCommunication[MULTISTRING_CHOOSER] < TRAPPING_MOVES_COUNT; gBattleCommunication[MULTISTRING_CHOOSER]++)
|
||||
{
|
||||
if (gBattleCommunication[MULTISTRING_CHOOSER] > ARRAY_COUNT(sTrappingMoves) - 1)
|
||||
break;
|
||||
if (sTrappingMoves[gBattleCommunication[MULTISTRING_CHOOSER]] == gCurrentMove)
|
||||
break;
|
||||
}
|
||||
@ -6777,13 +6782,38 @@ static u32 GetTrainerMoneyToGive(u16 trainerId)
|
||||
|
||||
static void Cmd_getmoneyreward(void)
|
||||
{
|
||||
u32 moneyReward = GetTrainerMoneyToGive(gTrainerBattleOpponent_A);
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
|
||||
moneyReward += GetTrainerMoneyToGive(gTrainerBattleOpponent_B);
|
||||
u32 money;
|
||||
u8 sPartyLevel = 1;
|
||||
|
||||
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) > sPartyLevel)
|
||||
sPartyLevel = 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] * sPartyLevel;
|
||||
RemoveMoney(&gSaveBlock1Ptr->money, money);
|
||||
}
|
||||
|
||||
PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff1, 5, money);
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
|
||||
@ -9443,6 +9473,7 @@ static void Cmd_various(void)
|
||||
else
|
||||
{
|
||||
PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].item);
|
||||
gLastUsedItem = gBattleMons[gActiveBattler].item;
|
||||
gBattlescriptCurrInstr += 7;
|
||||
}
|
||||
return;
|
||||
|
@ -1704,6 +1704,7 @@ bool32 IsHealBlockPreventingMove(u32 battler, u32 move)
|
||||
case EFFECT_HEALING_WISH:
|
||||
case EFFECT_WISH:
|
||||
case EFFECT_HEAL_PULSE:
|
||||
case EFFECT_JUNGLE_HEALING:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
@ -7770,33 +7771,35 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
bool32 IsBattlerGrounded(u8 battlerId)
|
||||
// Only called directly when calculating damage type effectiveness
|
||||
static bool32 IsBattlerGrounded2(u8 battlerId, bool32 considerInverse)
|
||||
{
|
||||
if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_IRON_BALL)
|
||||
return TRUE;
|
||||
else if (gFieldStatuses & STATUS_FIELD_GRAVITY)
|
||||
if (gFieldStatuses & STATUS_FIELD_GRAVITY)
|
||||
return TRUE;
|
||||
#if B_ROOTED_GROUNDING >= GEN_4
|
||||
else if (gStatuses3[battlerId] & STATUS3_ROOTED)
|
||||
if (gStatuses3[battlerId] & STATUS3_ROOTED)
|
||||
return TRUE;
|
||||
#endif
|
||||
else if (gStatuses3[battlerId] & STATUS3_SMACKED_DOWN)
|
||||
if (gStatuses3[battlerId] & STATUS3_SMACKED_DOWN)
|
||||
return TRUE;
|
||||
if (gStatuses3[battlerId] & STATUS3_TELEKINESIS)
|
||||
return FALSE;
|
||||
if (gStatuses3[battlerId] & STATUS3_MAGNET_RISE)
|
||||
return FALSE;
|
||||
if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_AIR_BALLOON)
|
||||
return FALSE;
|
||||
if (GetBattlerAbility(battlerId) == ABILITY_LEVITATE)
|
||||
return FALSE;
|
||||
if (IS_BATTLER_OF_TYPE(battlerId, TYPE_FLYING) && (!considerInverse || !FlagGet(B_FLAG_INVERSE_BATTLE)))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
else if (gStatuses3[battlerId] & STATUS3_TELEKINESIS)
|
||||
return FALSE;
|
||||
else if (gStatuses3[battlerId] & STATUS3_MAGNET_RISE)
|
||||
return FALSE;
|
||||
else if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_AIR_BALLOON)
|
||||
return FALSE;
|
||||
else if (GetBattlerAbility(battlerId) == ABILITY_LEVITATE)
|
||||
return FALSE;
|
||||
else if (IS_BATTLER_OF_TYPE(battlerId, TYPE_FLYING))
|
||||
return FALSE;
|
||||
|
||||
else
|
||||
return TRUE;
|
||||
bool32 IsBattlerGrounded(u8 battlerId)
|
||||
{
|
||||
IsBattlerGrounded2(battlerId, FALSE);
|
||||
}
|
||||
|
||||
bool32 IsBattlerAlive(u8 battlerId)
|
||||
@ -8942,7 +8945,7 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
|
||||
}
|
||||
|
||||
// check stab
|
||||
if (IS_BATTLER_OF_TYPE(battlerAtk, moveType) && move != MOVE_STRUGGLE)
|
||||
if (IS_BATTLER_OF_TYPE(battlerAtk, moveType) && move != MOVE_STRUGGLE && move != MOVE_NONE)
|
||||
{
|
||||
if (abilityAtk == ABILITY_ADAPTABILITY)
|
||||
MulModifier(&finalModifier, UQ_4_12(2.0));
|
||||
@ -9183,7 +9186,7 @@ static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 bat
|
||||
&& gBattleMons[battlerDef].type3 != gBattleMons[battlerDef].type1)
|
||||
MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type3, battlerAtk, recordAbilities);
|
||||
|
||||
if (moveType == TYPE_GROUND && !IsBattlerGrounded(battlerDef) && !(gBattleMoves[move].flags & FLAG_DMG_UNGROUNDED_IGNORE_TYPE_IF_FLYING))
|
||||
if (moveType == TYPE_GROUND && !IsBattlerGrounded2(battlerDef, TRUE) && !(gBattleMoves[move].flags & FLAG_DMG_UNGROUNDED_IGNORE_TYPE_IF_FLYING))
|
||||
{
|
||||
modifier = UQ_4_12(0.0);
|
||||
if (recordAbilities && defAbility == ABILITY_LEVITATE)
|
||||
|
@ -1188,9 +1188,9 @@ static void SetBerrySpriteData(struct Sprite* sprite, s16 x, s16 y, s16 bounceSp
|
||||
#undef sXSpeed
|
||||
#undef sYDownSpeed
|
||||
|
||||
static void CreateBerrySprite(u16 a0, u8 playerId)
|
||||
static void CreateBerrySprite(u16 itemId, u8 playerId)
|
||||
{
|
||||
u8 spriteId = CreateSpinningBerrySprite(a0 + FIRST_BERRY_INDEX - 10, 0, 80, playerId & 1);
|
||||
u8 spriteId = CreateSpinningBerrySprite(ITEM_TO_BERRY(itemId) - 1, 0, 80, playerId & 1);
|
||||
SetBerrySpriteData(&gSprites[spriteId],
|
||||
sBerrySpriteData[playerId][0],
|
||||
sBerrySpriteData[playerId][1],
|
||||
|
@ -1451,6 +1451,7 @@ const struct CompressedSpriteSheet gBattleAnimPicTable[] =
|
||||
{gBattleAnimSpriteGfx_OmegaSymbol, 0x0200, ANIM_TAG_OMEGA_SYMBOL},
|
||||
{gBattleAnimSpriteGfx_PrimalParticles, 0x0180, ANIM_TAG_PRIMAL_PARTICLES},
|
||||
{gBattleAnimSpriteGfx_Orbs, 0x0180, ANIM_TAG_STEEL_BEAM},
|
||||
{gBattleAnimSpriteGfx_AuraSphere, 0x200, ANIM_TAG_POLTERGEIST},
|
||||
};
|
||||
|
||||
const struct CompressedSpritePalette gBattleAnimPaletteTable[] =
|
||||
@ -1902,6 +1903,7 @@ const struct CompressedSpritePalette gBattleAnimPaletteTable[] =
|
||||
{gBattleAnimSpritePal_OmegaSymbol, ANIM_TAG_OMEGA_SYMBOL},
|
||||
{gBattleAnimSpritePal_PrimalParticles, ANIM_TAG_PRIMAL_PARTICLES},
|
||||
{gBattleAnimSpritePal_SteelBeam, ANIM_TAG_STEEL_BEAM},
|
||||
{gBattleAnimSpritePal_Poltergeist, ANIM_TAG_POLTERGEIST},
|
||||
};
|
||||
|
||||
const struct BattleAnimBackground gBattleAnimBackgroundTable[] =
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -57,22 +57,20 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.speechLose = { EC_WORD_TO_HER, EC_WORD_WIN, EC_WORD_JOKING, EC_WORD_HIGHS, EC_WORD_SCARY, EC_WORD_ELLIPSIS_EXCL },
|
||||
.speechAfter = { EC_WORD_IGNORANT, EC_WORD_SO, EC_WORD_TODAY, EC_WORD_NIGHTTIME, EC_WORD_YOU_RE, EC_WORD_ELLIPSIS_ELLIPSIS_ELLIPSIS },
|
||||
.mons = {
|
||||
[0] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[1] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[2] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[0] = DUMMY_HILL_MON,
|
||||
[1] = DUMMY_HILL_MON,
|
||||
[2] = DUMMY_HILL_MON,
|
||||
[3] = {
|
||||
.species = SPECIES_SWALOT,
|
||||
.heldItem = ITEM_SHELL_BELL,
|
||||
.moves = { MOVE_SLUDGE_BOMB, MOVE_SHADOW_BALL, MOVE_PAIN_SPLIT, MOVE_YAWN },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 55,
|
||||
.attackEV = 255,
|
||||
.defenseEV = 100,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 0,
|
||||
.spDefenseEV = 100,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -82,21 +80,19 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 1,
|
||||
.personality = 0x80,
|
||||
.nickname = __("マルノーム$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
[4] = {
|
||||
.species = SPECIES_DUSTOX,
|
||||
.heldItem = ITEM_BRIGHT_POWDER,
|
||||
.moves = { MOVE_SILVER_WIND, MOVE_SLUDGE_BOMB, MOVE_SHADOW_BALL, MOVE_GIGA_DRAIN },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 0,
|
||||
.attackEV = 255,
|
||||
.defenseEV = 0,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 255,
|
||||
.spDefenseEV = 0,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -106,21 +102,19 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 0,
|
||||
.personality = 0x6,
|
||||
.nickname = __("ドクケイル$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
[5] = {
|
||||
.species = SPECIES_RELICANTH,
|
||||
.heldItem = ITEM_QUICK_CLAW,
|
||||
.moves = { MOVE_ANCIENT_POWER, MOVE_SURF, MOVE_EARTHQUAKE, MOVE_AMNESIA },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 100,
|
||||
.attackEV = 0,
|
||||
.defenseEV = 0,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 155,
|
||||
.spDefenseEV = 255,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -130,7 +124,7 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 0,
|
||||
.personality = 0x2f,
|
||||
.nickname = __("ジーランス$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -143,22 +137,20 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.speechLose = { EC_MOVE2(MINIMIZE), EC_WORD_AS_MUCH_AS, EC_EMPTY_WORD, EC_WORD_THEY_RE, EC_WORD_SAD, EC_WORD_EXCL },
|
||||
.speechAfter = { EC_MOVE(BITE), EC_WORD_AS_MUCH_AS, EC_EMPTY_WORD, EC_WORD_THEY_RE, EC_WORD_ANGRY, EC_WORD_EXCL },
|
||||
.mons = {
|
||||
[0] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[1] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[2] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[0] = DUMMY_HILL_MON,
|
||||
[1] = DUMMY_HILL_MON,
|
||||
[2] = DUMMY_HILL_MON,
|
||||
[3] = {
|
||||
.species = SPECIES_CACTURNE,
|
||||
.heldItem = ITEM_QUICK_CLAW,
|
||||
.moves = { MOVE_GIGA_DRAIN, MOVE_FEINT_ATTACK, MOVE_THUNDER_PUNCH, MOVE_GROWTH },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 55,
|
||||
.attackEV = 0,
|
||||
.defenseEV = 100,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 255,
|
||||
.spDefenseEV = 100,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -168,21 +160,19 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 0,
|
||||
.personality = 0x8c,
|
||||
.nickname = __("ノクタス$$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
[4] = {
|
||||
.species = SPECIES_SWELLOW,
|
||||
.heldItem = ITEM_BRIGHT_POWDER,
|
||||
.moves = { MOVE_FACADE, MOVE_AERIAL_ACE, MOVE_QUICK_ATTACK, MOVE_DOUBLE_TEAM },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 255,
|
||||
.attackEV = 255,
|
||||
.defenseEV = 0,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 0,
|
||||
.spDefenseEV = 0,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -192,21 +182,19 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 0,
|
||||
.personality = 0x80,
|
||||
.nickname = __("オオスバメ$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
[5] = {
|
||||
.species = SPECIES_WHISCASH,
|
||||
.heldItem = ITEM_CHESTO_BERRY,
|
||||
.moves = { MOVE_SURF, MOVE_EARTHQUAKE, MOVE_AMNESIA, MOVE_REST },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 0,
|
||||
.attackEV = 255,
|
||||
.defenseEV = 0,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 255,
|
||||
.spDefenseEV = 0,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -216,7 +204,7 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 0,
|
||||
.personality = 0x0,
|
||||
.nickname = __("ナマズン$$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -229,22 +217,20 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.speechLose = { EC_WORD_THAT, EC_WORD_ABOVE, EC_WORD_LOST, EC_WORD_STORES, EC_WORD_JOKING, EC_WORD_ELLIPSIS_ELLIPSIS_ELLIPSIS },
|
||||
.speechAfter = { EC_WORD_ENTERTAINING, EC_WORD_NONE, EC_WORD_HEY_QUES, EC_WORD_ALMOST, EC_WORD_EXCL, EC_EMPTY_WORD },
|
||||
.mons = {
|
||||
[0] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[1] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[2] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[0] = DUMMY_HILL_MON,
|
||||
[1] = DUMMY_HILL_MON,
|
||||
[2] = DUMMY_HILL_MON,
|
||||
[3] = {
|
||||
.species = SPECIES_DELCATTY,
|
||||
.heldItem = ITEM_LUM_BERRY,
|
||||
.moves = { MOVE_SING, MOVE_BODY_SLAM, MOVE_SHADOW_BALL, MOVE_IRON_TAIL },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 0,
|
||||
.attackEV = 255,
|
||||
.defenseEV = 0,
|
||||
.speedEV = 255,
|
||||
.spAttackEV = 0,
|
||||
.spDefenseEV = 0,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -254,21 +240,19 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 0,
|
||||
.personality = 0x3,
|
||||
.nickname = __("エネコロロ$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
[4] = {
|
||||
.species = SPECIES_ROSELIA,
|
||||
.heldItem = ITEM_LEFTOVERS,
|
||||
.moves = { MOVE_GIGA_DRAIN, MOVE_GRASS_WHISTLE, MOVE_TOXIC, MOVE_LEECH_SEED },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 255,
|
||||
.attackEV = 0,
|
||||
.defenseEV = 0,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 255,
|
||||
.spDefenseEV = 0,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -278,21 +262,19 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 1,
|
||||
.personality = 0x6,
|
||||
.nickname = __("ロゼリア$$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
[5] = {
|
||||
.species = SPECIES_BEAUTIFLY,
|
||||
.heldItem = ITEM_BRIGHT_POWDER,
|
||||
.moves = { MOVE_SILVER_WIND, MOVE_AERIAL_ACE, MOVE_ATTRACT, MOVE_PSYCHIC },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 100,
|
||||
.attackEV = 200,
|
||||
.defenseEV = 0,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 200,
|
||||
.spDefenseEV = 0,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -302,7 +284,7 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 0,
|
||||
.personality = 0x6,
|
||||
.nickname = __("アゲハント$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -315,22 +297,20 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.speechLose = { EC_WORD_OUTSIDE, EC_WORD_UNCLE, EC_WORD_SURPRISE, EC_WORD_THESE, EC_WORD_HEY_QUES, EC_WORD_ELLIPSIS_EXCL },
|
||||
.speechAfter = { EC_WORD_HE_S, EC_WORD_NO_1, EC_WORD_STRONG, EC_WORD_CHILDREN, EC_WORD_CAN_T, EC_WORD_EXCL_EXCL },
|
||||
.mons = {
|
||||
[0] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[1] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[2] = NULL_BATTLE_TOWER_POKEMON,
|
||||
[0] = DUMMY_HILL_MON,
|
||||
[1] = DUMMY_HILL_MON,
|
||||
[2] = DUMMY_HILL_MON,
|
||||
[3] = {
|
||||
.species = SPECIES_MAWILE,
|
||||
.heldItem = ITEM_BRIGHT_POWDER,
|
||||
.moves = { MOVE_CRUNCH, MOVE_FLAMETHROWER, MOVE_THUNDER_PUNCH, MOVE_COMET_PUNCH },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 0,
|
||||
.attackEV = 0,
|
||||
.defenseEV = 100,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 255,
|
||||
.spDefenseEV = 155,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -340,21 +320,19 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 1,
|
||||
.personality = 0x0,
|
||||
.nickname = __("クチート$$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
[4] = {
|
||||
.species = SPECIES_SHARPEDO,
|
||||
.heldItem = ITEM_SCOPE_LENS,
|
||||
.moves = { MOVE_SURF, MOVE_CRUNCH, MOVE_DOUBLE_EDGE, MOVE_EARTHQUAKE },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 255,
|
||||
.attackEV = 0,
|
||||
.defenseEV = 0,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 255,
|
||||
.spDefenseEV = 0,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -364,21 +342,19 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 0,
|
||||
.personality = 0x96,
|
||||
.nickname = __("サメハダー$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
[5] = {
|
||||
.species = SPECIES_BANETTE,
|
||||
.heldItem = ITEM_LUM_BERRY,
|
||||
.moves = { MOVE_PSYCHIC, MOVE_SHADOW_BALL, MOVE_THUNDERBOLT, MOVE_WILL_O_WISP },
|
||||
.level = 0,
|
||||
.ppBonuses = 0x0,
|
||||
.hpEV = 255,
|
||||
.attackEV = 0,
|
||||
.defenseEV = 0,
|
||||
.speedEV = 0,
|
||||
.spAttackEV = 255,
|
||||
.spDefenseEV = 0,
|
||||
.otId = 0x10000000,
|
||||
.otId = TRAINER_HILL_OTID,
|
||||
.hpIV = 5,
|
||||
.attackIV = 5,
|
||||
.defenseIV = 5,
|
||||
@ -388,7 +364,7 @@ static const struct TrainerHillTrainer sTrainerHillTrainerTemplates_JP[] = {
|
||||
.abilityNum = 0,
|
||||
.personality = 0x96,
|
||||
.nickname = __("ジュペッタ$$$$$$"),
|
||||
.friendship = 255
|
||||
.friendship = MAX_FRIENDSHIP
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -447,40 +423,40 @@ static bool32 ValidateTrainerHillChecksum(struct EReaderTrainerHillSet *hillSet)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool32 TryWriteTrainerHill_Internal(struct EReaderTrainerHillSet * hillSet, struct TrHillTag * hillTag)
|
||||
static bool32 TryWriteTrainerHill_Internal(struct EReaderTrainerHillSet * hillSet, struct TrainerHillChallenge * challenge)
|
||||
{
|
||||
int i;
|
||||
|
||||
AGB_ASSERT_EX(hillSet->dummy == 0, "cereader_tool.c", 450);
|
||||
AGB_ASSERT_EX(hillSet->id == 0, "cereader_tool.c", 452);
|
||||
|
||||
memset(hillTag, 0, SECTOR_SIZE);
|
||||
hillTag->numTrainers = hillSet->numTrainers;
|
||||
hillTag->unused1 = GetTrainerHillUnkVal();
|
||||
hillTag->numFloors = (hillSet->numTrainers + 1) / TRAINER_HILL_TRAINERS_PER_FLOOR;
|
||||
memset(challenge, 0, SECTOR_SIZE);
|
||||
challenge->numTrainers = hillSet->numTrainers;
|
||||
challenge->unused1 = GetTrainerHillUnkVal();
|
||||
challenge->numFloors = (hillSet->numTrainers + 1) / HILL_TRAINERS_PER_FLOOR;
|
||||
|
||||
for (i = 0; i < hillSet->numTrainers; i++)
|
||||
{
|
||||
if (!(i & 1))
|
||||
{
|
||||
hillTag->floors[i / TRAINER_HILL_TRAINERS_PER_FLOOR].trainerNum1 = hillSet->trainers[i].trainerNum;
|
||||
hillTag->floors[i / TRAINER_HILL_TRAINERS_PER_FLOOR].display = hillSet->trainers[i].display;
|
||||
hillTag->floors[i / TRAINER_HILL_TRAINERS_PER_FLOOR].trainers[0] = hillSet->trainers[i].trainer;
|
||||
challenge->floors[i / HILL_TRAINERS_PER_FLOOR].trainerNum1 = hillSet->trainers[i].trainerNum;
|
||||
challenge->floors[i / HILL_TRAINERS_PER_FLOOR].map = hillSet->trainers[i].map;
|
||||
challenge->floors[i / HILL_TRAINERS_PER_FLOOR].trainers[0] = hillSet->trainers[i].trainer;
|
||||
}
|
||||
else
|
||||
{
|
||||
hillTag->floors[i / TRAINER_HILL_TRAINERS_PER_FLOOR].trainerNum2 = hillSet->trainers[i].trainerNum;
|
||||
hillTag->floors[i / TRAINER_HILL_TRAINERS_PER_FLOOR].trainers[1] = hillSet->trainers[i].trainer;
|
||||
challenge->floors[i / HILL_TRAINERS_PER_FLOOR].trainerNum2 = hillSet->trainers[i].trainerNum;
|
||||
challenge->floors[i / HILL_TRAINERS_PER_FLOOR].trainers[1] = hillSet->trainers[i].trainer;
|
||||
}
|
||||
}
|
||||
|
||||
if (i & 1)
|
||||
{
|
||||
hillTag->floors[i / TRAINER_HILL_TRAINERS_PER_FLOOR].trainers[1] = sTrainerHillTrainerTemplates_JP[i / TRAINER_HILL_TRAINERS_PER_FLOOR];
|
||||
challenge->floors[i / HILL_TRAINERS_PER_FLOOR].trainers[1] = sTrainerHillTrainerTemplates_JP[i / HILL_TRAINERS_PER_FLOOR];
|
||||
}
|
||||
|
||||
hillTag->checksum = CalcByteArraySum((u8 *)hillTag->floors, NUM_TRAINER_HILL_FLOORS * sizeof(struct TrHillFloor));
|
||||
if (TryWriteSpecialSaveSector(SECTOR_ID_TRAINER_HILL, (u8 *)hillTag) != SAVE_STATUS_OK)
|
||||
challenge->checksum = CalcByteArraySum((u8 *)challenge->floors, NUM_TRAINER_HILL_FLOORS * sizeof(struct TrainerHillFloor));
|
||||
if (TryWriteSpecialSaveSector(SECTOR_ID_TRAINER_HILL, (u8 *)challenge) != SAVE_STATUS_OK)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -269,6 +269,8 @@ const u32 gBattleAnimSpritePal_Steamroller[] = INCBIN_U32("graphics/battle_anims
|
||||
const u32 gBattleAnimSpriteGfx_StonePillar[] = INCBIN_U32("graphics/battle_anims/sprites/new/stone_pillar.4bpp.lz");
|
||||
const u32 gBattleAnimSpritePal_StonePillar[] = INCBIN_U32("graphics/battle_anims/sprites/new/stone_pillar.gbapal.lz");
|
||||
|
||||
const u32 gBattleAnimSpritePal_Poltergeist[] = INCBIN_U32("graphics/battle_anims/sprites/new/poltergeist.gbapal.lz");
|
||||
|
||||
const u32 gBattleAnimSpriteGfx_StraightBeam[] = INCBIN_U32("graphics/battle_anims/sprites/new/straight_beam.4bpp.lz");
|
||||
const u32 gBattleAnimSpritePal_StraightBeam[] = INCBIN_U32("graphics/battle_anims/sprites/new/straight_beam.gbapal.lz");
|
||||
|
||||
|
@ -31,7 +31,7 @@ void AGBPrintFlush1Block(void);
|
||||
void AGBPrintInit(void)
|
||||
{
|
||||
volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
|
||||
u16 *pWSCNT = ®_WAITCNT;
|
||||
vu16 *pWSCNT = ®_WAITCNT;
|
||||
u16 *pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR;
|
||||
u16 nOldWSCNT = *pWSCNT;
|
||||
*pWSCNT = WSCNT_DATA;
|
||||
@ -57,7 +57,7 @@ static void AGBPutcInternal(const char cChr)
|
||||
|
||||
void AGBPutc(const char cChr)
|
||||
{
|
||||
u16 *pWSCNT = ®_WAITCNT;
|
||||
vu16 *pWSCNT = ®_WAITCNT;
|
||||
u16 nOldWSCNT = *pWSCNT;
|
||||
volatile struct AGBPrintStruct *pPrint;
|
||||
*pWSCNT = WSCNT_DATA;
|
||||
@ -71,7 +71,7 @@ void AGBPutc(const char cChr)
|
||||
void AGBPrint(const char *pBuf)
|
||||
{
|
||||
volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
|
||||
u16 *pWSCNT = ®_WAITCNT;
|
||||
vu16 *pWSCNT = ®_WAITCNT;
|
||||
u16 nOldWSCNT = *pWSCNT;
|
||||
*pWSCNT = WSCNT_DATA;
|
||||
while (*pBuf)
|
||||
@ -95,9 +95,9 @@ void AGBPrintf(const char *pBuf, ...)
|
||||
static void AGBPrintTransferDataInternal(u32 bAllData)
|
||||
{
|
||||
LPFN_PRINT_FLUSH lpfnFuncFlush;
|
||||
u16 *pIME;
|
||||
vu16 *pIME;
|
||||
u16 nIME;
|
||||
u16 *pWSCNT;
|
||||
vu16 *pWSCNT;
|
||||
u16 nOldWSCNT;
|
||||
u16 *pProtect;
|
||||
volatile struct AGBPrintStruct *pPrint;
|
||||
|
@ -506,9 +506,13 @@ static void IncrementCardStat(u32 statType)
|
||||
}
|
||||
|
||||
if (stat == NULL)
|
||||
{
|
||||
AGB_ASSERT(0);
|
||||
}
|
||||
else if (++(*stat) > MAX_WONDER_CARD_STAT)
|
||||
{
|
||||
*stat = MAX_WONDER_CARD_STAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -361,7 +361,9 @@ static void (*const gMovementStatusHandler[])(struct LinkPlayerObjectEvent *, st
|
||||
void DoWhiteOut(void)
|
||||
{
|
||||
ScriptContext2_RunNewScript(EventScript_WhiteOut);
|
||||
#if B_WHITEOUT_MONEY == GEN_3
|
||||
SetMoney(&gSaveBlock1Ptr->money, GetMoney(&gSaveBlock1Ptr->money) / 2);
|
||||
#endif
|
||||
HealPlayerParty();
|
||||
Overworld_ResetStateAfterWhiteOut();
|
||||
SetWarpDestinationToLastHealLocation();
|
||||
|
@ -32,23 +32,21 @@
|
||||
#include "constants/trainer_hill.h"
|
||||
#include "constants/trainer_types.h"
|
||||
|
||||
#define HILL_TAG_NORMAL 0
|
||||
#define HILL_TAG_VARIETY 1
|
||||
#define HILL_TAG_UNIQUE 2
|
||||
#define HILL_TAG_EXPERT 3
|
||||
|
||||
#define HILL_MAX_TIME 215999 // 60 * 60 * 60 - 1
|
||||
|
||||
// EWRAM
|
||||
struct TrHillStruct2
|
||||
struct FloorTrainers
|
||||
{
|
||||
u8 floorId;
|
||||
struct TrHillTag tag;
|
||||
struct TrHillFloor floors[NUM_TRAINER_HILL_FLOORS];
|
||||
u8 name[HILL_TRAINERS_PER_FLOOR][HILL_TRAINER_NAME_LENGTH];
|
||||
u8 facilityClass[HILL_TRAINERS_PER_FLOOR];
|
||||
};
|
||||
|
||||
static EWRAM_DATA struct TrHillStruct2 *sHillData = NULL;
|
||||
static EWRAM_DATA struct TrHillRoomTrainers *sRoomTrainers = NULL;
|
||||
static EWRAM_DATA struct {
|
||||
u8 floorId;
|
||||
struct TrainerHillChallenge challenge;
|
||||
struct TrainerHillFloor floors[NUM_TRAINER_HILL_FLOORS];
|
||||
} *sHillData = NULL;
|
||||
|
||||
static EWRAM_DATA struct FloorTrainers *sFloorTrainers = NULL;
|
||||
EWRAM_DATA u32 *gTrainerHillVBlankCounter = NULL;
|
||||
|
||||
// This file's functions.
|
||||
@ -69,7 +67,7 @@ static void GetGameSaved(void);
|
||||
static void SetGameSaved(void);
|
||||
static void ClearGameSaved(void);
|
||||
static void GetChallengeWon(void);
|
||||
static void TrainerHillSetTag(void);
|
||||
static void TrainerHillSetMode(void);
|
||||
static void SetUpDataStruct(void);
|
||||
static void FreeDataStruct(void);
|
||||
static void TrainerHillDummy(void);
|
||||
@ -202,12 +200,12 @@ static const u16 *const *const sPrizeListSets[] =
|
||||
static const u16 sEReader_Pal[] = INCBIN_U16("graphics/trainer_hill/ereader.gbapal");
|
||||
static const u8 sRecordWinColors[] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY};
|
||||
|
||||
static const struct TrHillTag *const sDataPerTag[] =
|
||||
static const struct TrainerHillChallenge *const sChallengeData[NUM_TRAINER_HILL_MODES] =
|
||||
{
|
||||
&sDataTagNormal,
|
||||
&sDataTagVariety,
|
||||
&sDataTagUnique,
|
||||
&sDataTagExpert,
|
||||
[HILL_MODE_NORMAL] = &sChallenge_Normal,
|
||||
[HILL_MODE_VARIETY] = &sChallenge_Variety,
|
||||
[HILL_MODE_UNIQUE] = &sChallenge_Unique,
|
||||
[HILL_MODE_EXPERT] = &sChallenge_Expert,
|
||||
};
|
||||
|
||||
// Unused.
|
||||
@ -238,15 +236,15 @@ static void (* const sHillFunctions[])(void) =
|
||||
[TRAINER_HILL_FUNC_SET_GAME_SAVED] = SetGameSaved,
|
||||
[TRAINER_HILL_FUNC_CLEAR_GAME_SAVED] = ClearGameSaved,
|
||||
[TRAINER_HILL_FUNC_GET_WON] = GetChallengeWon,
|
||||
[TRAINER_HILL_FUNC_SET_TAG] = TrainerHillSetTag,
|
||||
[TRAINER_HILL_FUNC_SET_MODE] = TrainerHillSetMode,
|
||||
};
|
||||
|
||||
static const u8 *const sTagMatchStrings[] =
|
||||
static const u8 *const sModeStrings[NUM_TRAINER_HILL_MODES] =
|
||||
{
|
||||
gText_NormalTagMatch,
|
||||
gText_VarietyTagMatch,
|
||||
gText_UniqueTagMatch,
|
||||
gText_ExpertTagMatch,
|
||||
[HILL_MODE_NORMAL] = gText_NormalTagMatch,
|
||||
[HILL_MODE_VARIETY] = gText_VarietyTagMatch,
|
||||
[HILL_MODE_UNIQUE] = gText_UniqueTagMatch,
|
||||
[HILL_MODE_EXPERT] = gText_ExpertTagMatch,
|
||||
};
|
||||
|
||||
static const struct ObjectEventTemplate sTrainerObjectEventTemplate =
|
||||
@ -261,18 +259,17 @@ static const struct ObjectEventTemplate sTrainerObjectEventTemplate =
|
||||
|
||||
static const u32 sNextFloorMapNum[NUM_TRAINER_HILL_FLOORS] =
|
||||
{
|
||||
MAP_NUM(TRAINER_HILL_2F),
|
||||
MAP_NUM(TRAINER_HILL_3F),
|
||||
MAP_NUM(TRAINER_HILL_4F),
|
||||
MAP_NUM(TRAINER_HILL_ROOF)
|
||||
[TRAINER_HILL_1F - 1] = MAP_NUM(TRAINER_HILL_2F),
|
||||
[TRAINER_HILL_2F - 1] = MAP_NUM(TRAINER_HILL_3F),
|
||||
[TRAINER_HILL_3F - 1] = MAP_NUM(TRAINER_HILL_4F),
|
||||
[TRAINER_HILL_4F - 1] = MAP_NUM(TRAINER_HILL_ROOF)
|
||||
};
|
||||
static const u8 sTrainerPartySlots[][PARTY_SIZE / 2] =
|
||||
static const u8 sTrainerPartySlots[HILL_TRAINERS_PER_FLOOR][PARTY_SIZE / 2] =
|
||||
{
|
||||
{0, 1, 2},
|
||||
{3, 4, 5}
|
||||
};
|
||||
|
||||
// code
|
||||
void CallTrainerHillFunction(void)
|
||||
{
|
||||
SetUpDataStruct();
|
||||
@ -287,7 +284,7 @@ void ResetTrainerHillResults(void)
|
||||
gSaveBlock2Ptr->frontier.savedGame = 0;
|
||||
gSaveBlock2Ptr->frontier.unk_EF9 = 0;
|
||||
gSaveBlock1Ptr->trainerHill.bestTime = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < NUM_TRAINER_HILL_MODES; i++)
|
||||
SetTimerValue(&gSaveBlock1Ptr->trainerHillTimes[i], HILL_MAX_TIME);
|
||||
}
|
||||
|
||||
@ -300,7 +297,7 @@ u8 GetTrainerHillOpponentClass(u16 trainerId)
|
||||
{
|
||||
u8 id = trainerId - 1;
|
||||
|
||||
return gFacilityClassToTrainerClass[sRoomTrainers->facilityClass[id]];
|
||||
return gFacilityClassToTrainerClass[sFloorTrainers->facilityClass[id]];
|
||||
}
|
||||
|
||||
void GetTrainerHillTrainerName(u8 *dst, u16 trainerId)
|
||||
@ -309,7 +306,7 @@ void GetTrainerHillTrainerName(u8 *dst, u16 trainerId)
|
||||
u8 id = trainerId - 1;
|
||||
|
||||
for (i = 0; i < HILL_TRAINER_NAME_LENGTH; i++)
|
||||
dst[i] = sRoomTrainers->name[id][i];
|
||||
dst[i] = sFloorTrainers->name[id][i];
|
||||
}
|
||||
|
||||
u8 GetTrainerHillTrainerFrontSpriteId(u16 trainerId)
|
||||
@ -329,15 +326,14 @@ void InitTrainerHillBattleStruct(void)
|
||||
s32 i, j;
|
||||
|
||||
SetUpDataStruct();
|
||||
sRoomTrainers = AllocZeroed(sizeof(*sRoomTrainers));
|
||||
sFloorTrainers = AllocZeroed(sizeof(*sFloorTrainers));
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
for (i = 0; i < HILL_TRAINERS_PER_FLOOR; i++)
|
||||
{
|
||||
for (j = 0; j < HILL_TRAINER_NAME_LENGTH; j++)
|
||||
{
|
||||
sRoomTrainers->name[i][j] = sHillData->floors[sHillData->floorId].trainers[i].name[j];
|
||||
}
|
||||
sRoomTrainers->facilityClass[i] = sHillData->floors[sHillData->floorId].trainers[i].facilityClass;
|
||||
sFloorTrainers->name[i][j] = sHillData->floors[sHillData->floorId].trainers[i].name[j];
|
||||
|
||||
sFloorTrainers->facilityClass[i] = sHillData->floors[sHillData->floorId].trainers[i].facilityClass;
|
||||
}
|
||||
SetTrainerHillVBlankCounter(&gSaveBlock1Ptr->trainerHill.timer);
|
||||
FreeDataStruct();
|
||||
@ -345,8 +341,7 @@ void InitTrainerHillBattleStruct(void)
|
||||
|
||||
void FreeTrainerHillBattleStruct(void)
|
||||
{
|
||||
if (sRoomTrainers != NULL)
|
||||
FREE_AND_SET_NULL(sRoomTrainers);
|
||||
TRY_FREE_AND_SET_NULL(sFloorTrainers);
|
||||
}
|
||||
|
||||
static void SetUpDataStruct(void)
|
||||
@ -355,15 +350,20 @@ static void SetUpDataStruct(void)
|
||||
{
|
||||
sHillData = AllocZeroed(sizeof(*sHillData));
|
||||
sHillData->floorId = gMapHeader.mapLayoutId - LAYOUT_TRAINER_HILL_1F;
|
||||
CpuCopy32(sDataPerTag[gSaveBlock1Ptr->trainerHill.tag], &sHillData->tag, sizeof(sHillData->tag) + 4 * sizeof(struct TrHillFloor));
|
||||
|
||||
// This copy depends on the floor data for each challenge being directly after the
|
||||
// challenge header data, and for the field 'floors' in sHillData to come directly
|
||||
// after the field 'challenge'.
|
||||
// e.g. for HILL_MODE_NORMAL, it will copy sChallenge_Normal to sHillData->challenge and
|
||||
// it will copy sFloors_Normal to sHillData->floors
|
||||
CpuCopy32(sChallengeData[gSaveBlock1Ptr->trainerHill.mode], &sHillData->challenge, sizeof(sHillData->challenge) + sizeof(sHillData->floors));
|
||||
TrainerHillDummy();
|
||||
}
|
||||
}
|
||||
|
||||
static void FreeDataStruct(void)
|
||||
{
|
||||
if (sHillData != NULL)
|
||||
FREE_AND_SET_NULL(sHillData);
|
||||
TRY_FREE_AND_SET_NULL(sHillData);
|
||||
}
|
||||
|
||||
void CopyTrainerHillTrainerText(u8 which, u16 trainerId)
|
||||
@ -428,7 +428,7 @@ static void GiveChallengePrize(void)
|
||||
{
|
||||
u16 itemId = GetPrizeItemId();
|
||||
|
||||
if (sHillData->tag.numFloors != NUM_TRAINER_HILL_FLOORS || gSaveBlock1Ptr->trainerHill.receivedPrize)
|
||||
if (sHillData->challenge.numFloors != NUM_TRAINER_HILL_FLOORS || gSaveBlock1Ptr->trainerHill.receivedPrize)
|
||||
{
|
||||
gSpecialVar_Result = 2;
|
||||
}
|
||||
@ -456,7 +456,7 @@ static void CheckFinalTime(void)
|
||||
else if (GetTimerValue(&gSaveBlock1Ptr->trainerHill.bestTime) > gSaveBlock1Ptr->trainerHill.timer)
|
||||
{
|
||||
SetTimerValue(&gSaveBlock1Ptr->trainerHill.bestTime, gSaveBlock1Ptr->trainerHill.timer);
|
||||
gSaveBlock1Ptr->trainerHillTimes[gSaveBlock1Ptr->trainerHill.tag] = gSaveBlock1Ptr->trainerHill.bestTime;
|
||||
gSaveBlock1Ptr->trainerHillTimes[gSaveBlock1Ptr->trainerHill.mode] = gSaveBlock1Ptr->trainerHill.bestTime;
|
||||
gSpecialVar_Result = 0;
|
||||
}
|
||||
else
|
||||
@ -529,9 +529,9 @@ static void BufferChallengeTime(void)
|
||||
static void GetAllFloorsUsed(void)
|
||||
{
|
||||
SetUpDataStruct();
|
||||
if (sHillData->tag.numFloors != NUM_TRAINER_HILL_FLOORS)
|
||||
if (sHillData->challenge.numFloors != NUM_TRAINER_HILL_FLOORS)
|
||||
{
|
||||
ConvertIntToDecimalStringN(gStringVar1, sHillData->tag.numFloors, STR_CONV_MODE_LEFT_ALIGN, 1);
|
||||
ConvertIntToDecimalStringN(gStringVar1, sHillData->challenge.numFloors, STR_CONV_MODE_LEFT_ALIGN, 1);
|
||||
gSpecialVar_Result = FALSE;
|
||||
}
|
||||
else
|
||||
@ -592,9 +592,9 @@ void PrintOnTrainerHillRecordsWindow(void)
|
||||
AddTextPrinterParameterized3(0, FONT_NORMAL, x, 2, sRecordWinColors, TEXT_SKIP_DRAW, gText_TimeBoard);
|
||||
|
||||
y = 18;
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < NUM_TRAINER_HILL_MODES; i++)
|
||||
{
|
||||
AddTextPrinterParameterized3(0, FONT_NORMAL, 0, y, sRecordWinColors, TEXT_SKIP_DRAW, sTagMatchStrings[i]);
|
||||
AddTextPrinterParameterized3(0, FONT_NORMAL, 0, y, sRecordWinColors, TEXT_SKIP_DRAW, sModeStrings[i]);
|
||||
y += 15;
|
||||
total = GetTimerValue(&gSaveBlock1Ptr->trainerHillTimes[i]);
|
||||
minutes = total / (60 * 60);
|
||||
@ -637,23 +637,23 @@ void LoadTrainerHillObjectEventTemplates(void)
|
||||
return;
|
||||
|
||||
SetUpDataStruct();
|
||||
for (i = 0; i < 2; i++)
|
||||
for (i = 0; i < HILL_TRAINERS_PER_FLOOR; i++)
|
||||
gSaveBlock2Ptr->frontier.trainerIds[i] = 0xFFFF;
|
||||
CpuFill32(0, gSaveBlock1Ptr->objectEventTemplates, sizeof(gSaveBlock1Ptr->objectEventTemplates));
|
||||
|
||||
floorId = GetFloorId();
|
||||
for (i = 0; i < 2; i++)
|
||||
for (i = 0; i < HILL_TRAINERS_PER_FLOOR; i++)
|
||||
{
|
||||
u8 bits;
|
||||
|
||||
eventTemplates[i] = sTrainerObjectEventTemplate;
|
||||
eventTemplates[i].localId = i + 1;
|
||||
eventTemplates[i].graphicsId = FacilityClassToGraphicsId(sHillData->floors[floorId].trainers[i].facilityClass);
|
||||
eventTemplates[i].x = sHillData->floors[floorId].display.coords[i] & 0xF;
|
||||
eventTemplates[i].y = ((sHillData->floors[floorId].display.coords[i] >> 4) & 0xF) + 5;
|
||||
eventTemplates[i].x = sHillData->floors[floorId].map.trainerCoords[i] & 0xF;
|
||||
eventTemplates[i].y = ((sHillData->floors[floorId].map.trainerCoords[i] >> 4) & 0xF) + 5;
|
||||
bits = i << 2;
|
||||
eventTemplates[i].movementType = ((sHillData->floors[floorId].display.direction >> bits) & 0xF) + MOVEMENT_TYPE_FACE_UP;
|
||||
eventTemplates[i].trainerRange_berryTreeId = (sHillData->floors[floorId].display.range >> bits) & 0xF;
|
||||
eventTemplates[i].movementType = ((sHillData->floors[floorId].map.trainerDirections >> bits) & 0xF) + MOVEMENT_TYPE_FACE_UP;
|
||||
eventTemplates[i].trainerRange_berryTreeId = (sHillData->floors[floorId].map.trainerRanges >> bits) & 0xF;
|
||||
eventTemplates[i].script = TrainerHill_EventScript_TrainerBattle;
|
||||
gSaveBlock2Ptr->frontier.trainerIds[i] = i + 1;
|
||||
}
|
||||
@ -669,14 +669,14 @@ bool32 LoadTrainerHillFloorObjectEventScripts(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static u16 GetMetatileForFloor(u8 floorId, u32 x, u32 y, u32 stride) // stride is always 16
|
||||
static u16 GetMetatileForFloor(u8 floorId, u32 x, u32 y, u32 floorWidth) // floorWidth is always 16
|
||||
{
|
||||
bool8 impassable;
|
||||
u16 metatile;
|
||||
u16 elevation;
|
||||
|
||||
impassable = (sHillData->floors[floorId].display.collisionData[y] >> (15 - x) & 1);
|
||||
metatile = sHillData->floors[floorId].display.metatileData[stride * y + x] + NUM_METATILES_IN_PRIMARY;
|
||||
impassable = (sHillData->floors[floorId].map.collisionData[y] >> (15 - x) & 1);
|
||||
metatile = sHillData->floors[floorId].map.metatileData[floorWidth * y + x] + NUM_METATILES_IN_PRIMARY;
|
||||
elevation = 3 << MAPGRID_ELEVATION_SHIFT;
|
||||
|
||||
return ((impassable << MAPGRID_COLLISION_SHIFT) & MAPGRID_COLLISION_MASK) | elevation | (metatile & MAPGRID_METATILE_ID_MASK);
|
||||
@ -684,7 +684,7 @@ static u16 GetMetatileForFloor(u8 floorId, u32 x, u32 y, u32 stride) // stride i
|
||||
|
||||
void GenerateTrainerHillFloorLayout(u16 *mapArg)
|
||||
{
|
||||
s32 i, j;
|
||||
s32 y, x;
|
||||
u16 *src, *dst;
|
||||
u8 mapId = GetCurrentTrainerHillMapId();
|
||||
|
||||
@ -705,24 +705,25 @@ void GenerateTrainerHillFloorLayout(u16 *mapArg)
|
||||
mapId = GetFloorId();
|
||||
src = gMapHeader.mapLayout->map;
|
||||
gBackupMapLayout.map = mapArg;
|
||||
gBackupMapLayout.width = 31;
|
||||
gBackupMapLayout.height = 35;
|
||||
// Dimensions include border area loaded beyond map
|
||||
gBackupMapLayout.width = HILL_FLOOR_WIDTH + 15;
|
||||
gBackupMapLayout.height = HILL_FLOOR_HEIGHT + 14;
|
||||
dst = mapArg + 224;
|
||||
|
||||
// First 5 rows of the map (Entrance / Exit) are always the same
|
||||
for (i = 0; i < 5; i++)
|
||||
for (y = 0; y < HILL_FLOOR_HEIGHT_MARGIN; y++)
|
||||
{
|
||||
for (j = 0; j < 16; j++)
|
||||
dst[j] = src[j];
|
||||
for (x = 0; x < HILL_FLOOR_WIDTH; x++)
|
||||
dst[x] = src[x];
|
||||
dst += 31;
|
||||
src += 16;
|
||||
}
|
||||
|
||||
// Load the 16x16 floor-specific layout
|
||||
for (i = 0; i < 16; i++)
|
||||
for (y = 0; y < HILL_FLOOR_HEIGHT_MAIN; y++)
|
||||
{
|
||||
for (j = 0; j < 16; j++)
|
||||
dst[j] = GetMetatileForFloor(mapId, j, i, 16);
|
||||
for (x = 0; x < HILL_FLOOR_WIDTH; x++)
|
||||
dst[x] = GetMetatileForFloor(mapId, x, y, HILL_FLOOR_WIDTH);
|
||||
dst += 31;
|
||||
}
|
||||
|
||||
@ -812,8 +813,8 @@ u16 LocalIdToHillTrainerId(u8 localId)
|
||||
|
||||
bool8 GetHillTrainerFlag(u8 objectEventId)
|
||||
{
|
||||
u32 floorId = GetFloorId() * 2;
|
||||
u8 bitId = gObjectEvents[objectEventId].localId - 1 + floorId;
|
||||
u32 trainerIndexStart = GetFloorId() * HILL_TRAINERS_PER_FLOOR;
|
||||
u8 bitId = gObjectEvents[objectEventId].localId - 1 + trainerIndexStart;
|
||||
|
||||
return gSaveBlock2Ptr->frontier.trainerFlags & gBitTable[bitId];
|
||||
}
|
||||
@ -821,24 +822,24 @@ bool8 GetHillTrainerFlag(u8 objectEventId)
|
||||
void SetHillTrainerFlag(void)
|
||||
{
|
||||
u8 i;
|
||||
u8 floorId = GetFloorId() * 2;
|
||||
u8 trainerIndexStart = GetFloorId() * HILL_TRAINERS_PER_FLOOR;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
for (i = 0; i < HILL_TRAINERS_PER_FLOOR; i++)
|
||||
{
|
||||
if (gSaveBlock2Ptr->frontier.trainerIds[i] == gTrainerBattleOpponent_A)
|
||||
{
|
||||
gSaveBlock2Ptr->frontier.trainerFlags |= gBitTable[floorId + i];
|
||||
gSaveBlock2Ptr->frontier.trainerFlags |= gBitTable[trainerIndexStart + i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
|
||||
{
|
||||
for (i = 0; i < 2; i++)
|
||||
for (i = 0; i < HILL_TRAINERS_PER_FLOOR; i++)
|
||||
{
|
||||
if (gSaveBlock2Ptr->frontier.trainerIds[i] == gTrainerBattleOpponent_B)
|
||||
{
|
||||
gSaveBlock2Ptr->frontier.trainerFlags |= gBitTable[floorId + i];
|
||||
gSaveBlock2Ptr->frontier.trainerFlags |= gBitTable[trainerIndexStart + i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -861,14 +862,14 @@ static void CreateNPCTrainerHillParty(u16 trainerId, u8 firstMonId)
|
||||
u8 trId, level;
|
||||
s32 i, floorId, partySlot;
|
||||
|
||||
if (trainerId == 0 || trainerId > 2)
|
||||
if (trainerId == 0 || trainerId > HILL_TRAINERS_PER_FLOOR)
|
||||
return;
|
||||
|
||||
trId = trainerId - 1;
|
||||
SetUpDataStruct();
|
||||
level = GetHighestLevelInPlayerParty();
|
||||
floorId = GetFloorId();
|
||||
for (i = firstMonId, partySlot = 0; i < firstMonId + 3; i++, partySlot++)
|
||||
for (i = firstMonId, partySlot = 0; i < firstMonId + PARTY_SIZE / 2; i++, partySlot++)
|
||||
{
|
||||
u8 id = sTrainerPartySlots[trId][partySlot];
|
||||
struct Pokemon *mon = &gEnemyParty[i];
|
||||
@ -890,7 +891,7 @@ void FillHillTrainersParties(void)
|
||||
{
|
||||
ZeroEnemyPartyMons();
|
||||
CreateNPCTrainerHillParty(gTrainerBattleOpponent_A, 0);
|
||||
CreateNPCTrainerHillParty(gTrainerBattleOpponent_B, 3);
|
||||
CreateNPCTrainerHillParty(gTrainerBattleOpponent_B, PARTY_SIZE / 2);
|
||||
}
|
||||
|
||||
// This function is unused, but my best guess is
|
||||
@ -935,7 +936,7 @@ u8 GetNumFloorsInTrainerHillChallenge(void)
|
||||
u8 floors;
|
||||
|
||||
SetUpDataStruct();
|
||||
floors = sHillData->tag.numFloors;
|
||||
floors = sHillData->challenge.numFloors;
|
||||
FreeDataStruct();
|
||||
|
||||
return floors;
|
||||
@ -989,16 +990,20 @@ static void GetChallengeWon(void)
|
||||
gSpecialVar_Result = TRUE;
|
||||
}
|
||||
|
||||
static void TrainerHillSetTag(void)
|
||||
static void TrainerHillSetMode(void)
|
||||
{
|
||||
gSaveBlock1Ptr->trainerHill.tag = gSpecialVar_0x8005;
|
||||
gSaveBlock1Ptr->trainerHill.mode = gSpecialVar_0x8005;
|
||||
gSaveBlock1Ptr->trainerHill.bestTime = gSaveBlock1Ptr->trainerHillTimes[gSpecialVar_0x8005];
|
||||
}
|
||||
|
||||
static u8 GetPrizeListId(bool8 maxTrainers)
|
||||
// Determines which prize list to use from the set of prize lists.
|
||||
static u8 GetPrizeListId(bool8 allowTMs)
|
||||
{
|
||||
u8 prizeListId, i, modBy;
|
||||
|
||||
// The initial selection depends on the trainer numbers for the completed challenge.
|
||||
// These don't change with the available challenge modes, so Normal/Unique will always
|
||||
// have a prizeListId of 8, and Variety/Expert will have a prizeListId of 24.
|
||||
prizeListId = 0;
|
||||
for (i = 0; i < NUM_TRAINER_HILL_FLOORS; i++)
|
||||
{
|
||||
@ -1006,8 +1011,10 @@ static u8 GetPrizeListId(bool8 maxTrainers)
|
||||
prizeListId ^= sHillData->floors[i].trainerNum2 & 0x1F;
|
||||
}
|
||||
|
||||
// Not possible to win TMs with fewer than 8 trainers
|
||||
if (maxTrainers)
|
||||
// In practice, the conditional below is always true.
|
||||
// The 2nd half of the lists in both sets of lists all have a TM as the "grand prize", while the 1st half do not,
|
||||
// so taking the mod of the (total / 2) ensures that a prize list without a TM will be used.
|
||||
if (allowTMs)
|
||||
modBy = NUM_TRAINER_HILL_PRIZE_LISTS;
|
||||
else
|
||||
modBy = NUM_TRAINER_HILL_PRIZE_LISTS / 2;
|
||||
@ -1020,38 +1027,64 @@ static u16 GetPrizeItemId(void)
|
||||
{
|
||||
u8 i;
|
||||
const u16 *prizeList;
|
||||
s32 var = 0, prizeListSetId, minutes, id;
|
||||
s32 trainerNumSum = 0, prizeListSetId, minutes, id;
|
||||
|
||||
// First determine which set of prize lists to use. The sets of lists only differ in
|
||||
// what TMs they can offer as the "grand prize" for a time under 12 minutes.
|
||||
// Which set of lists gets used is based on the sum of all the trainer numbers for that
|
||||
// challenge. These don't change with the available challenge modes, so Normal will always
|
||||
// have a prizeListSetId of 0, and Unique/Variety/Expert will have a prizeListSetId of 1.
|
||||
for (i = 0; i < NUM_TRAINER_HILL_FLOORS; i++)
|
||||
{
|
||||
var += sHillData->floors[i].trainerNum1;
|
||||
var += sHillData->floors[i].trainerNum2;
|
||||
trainerNumSum += sHillData->floors[i].trainerNum1;
|
||||
trainerNumSum += sHillData->floors[i].trainerNum2;
|
||||
}
|
||||
prizeListSetId = trainerNumSum / 256;
|
||||
prizeListSetId %= (int)ARRAY_COUNT(sPrizeListSets);
|
||||
|
||||
prizeListSetId = var / 256;
|
||||
prizeListSetId %= 2;
|
||||
if (FlagGet(FLAG_SYS_GAME_CLEAR) && sHillData->tag.numTrainers == NUM_TRAINER_HILL_TRAINERS)
|
||||
// Now get which prize list to use from the set. See GetPrizeListId for details.
|
||||
// The below conditional will always be true, because a Trainer Hill challenge can't be entered
|
||||
// until the player has entered the Hall of Fame (FLAG_SYS_GAME_CLEAR is set) and because all
|
||||
// of the available challenge modes have the full 8 trainers (NUM_TRAINER_HILL_TRAINERS).
|
||||
if (FlagGet(FLAG_SYS_GAME_CLEAR) && sHillData->challenge.numTrainers == NUM_TRAINER_HILL_TRAINERS)
|
||||
i = GetPrizeListId(TRUE);
|
||||
else
|
||||
i = GetPrizeListId(FALSE);
|
||||
|
||||
if (gSaveBlock1Ptr->trainerHill.tag == HILL_TAG_EXPERT)
|
||||
// 1 is added to Expert mode's prize list selection because otherwise it has the same prizes as Variety
|
||||
if (gSaveBlock1Ptr->trainerHill.mode == HILL_MODE_EXPERT)
|
||||
i = (i + 1) % NUM_TRAINER_HILL_PRIZE_LISTS;
|
||||
|
||||
// After the above (non-random) calculations, the following are the possible prize list selections:
|
||||
// sPrizeListSets[0][8] (Normal)
|
||||
// sPrizeListSets[1][4] (Variety)
|
||||
// sPrizeListSets[1][8] (Unique)
|
||||
// sPrizeListSets[1][5] (Expert)
|
||||
prizeList = sPrizeListSets[prizeListSetId][i];
|
||||
|
||||
// Which prize is given from the list depends on the time scored.
|
||||
// The prize for any time after 12 minutes is the same in every list.
|
||||
// The prizes for a time under 12 minutes are:
|
||||
// - ITEM_TM11_SUNNY_DAY (Normal)
|
||||
// - ITEM_ELIXIR (Variety)
|
||||
// - ITEM_TM19_GIGA_DRAIN (Unique)
|
||||
// - ITEM_TM31_BRICK_BREAK (Expert)
|
||||
// As an additional note, if players were allowed to enter a Trainer Hill challenge before
|
||||
// entering the Hall of Fame, there would be 1 additional prize possibility (ITEM_MAX_ETHER)
|
||||
// as Normal / Unique modes would use sPrizeListSets[0][3] / sPrizeListSets[1][3] respectively.
|
||||
minutes = (signed)(gSaveBlock1Ptr->trainerHill.timer) / (60 * 60);
|
||||
if (minutes < 12)
|
||||
id = 0;
|
||||
id = 0; // Depends on list
|
||||
else if (minutes < 13)
|
||||
id = 1;
|
||||
id = 1; // ITEM_ETHER
|
||||
else if (minutes < 14)
|
||||
id = 2;
|
||||
id = 2; // ITEM_MAX_POTION
|
||||
else if (minutes < 16)
|
||||
id = 3;
|
||||
id = 3; // ITEM_REVIVE
|
||||
else if (minutes < 18)
|
||||
id = 4;
|
||||
id = 4; // ITEM_FLUFFY_TAIL
|
||||
else
|
||||
id = 5;
|
||||
id = 5; // ITEM_GREAT_BALL
|
||||
|
||||
return prizeList[id];
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
CC = gcc
|
||||
|
||||
CFLAGS = -Wall -Wextra -Werror -Wno-sign-compare -std=c11 -O2 -DPNG_SKIP_SETJMP_CHECK
|
||||
CFLAGS += $(shell pkg-config --cflags libpng)
|
||||
|
||||
LIBS = -lpng -lz
|
||||
LDFLAGS += $(shell pkg-config --libs-only-L libpng)
|
||||
|
||||
SRCS = main.c convert_png.c gfx.c jasc_pal.c lz.c rl.c util.c font.c huff.c
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
CC ?= gcc
|
||||
|
||||
CFLAGS = -Wall -Wextra -Werror -std=c11 -O2 -DPNG_SKIP_SETJMP_CHECK
|
||||
CFLAGS += $(shell pkg-config --cflags libpng)
|
||||
|
||||
LIBS = -lpng -lz
|
||||
LDFLAGS += $(shell pkg-config --libs-only-L libpng)
|
||||
|
||||
SRCS = main.c convert_png.c util.c font.c
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user