mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-03-21 18:04:50 -05:00
Make movelist calculations happen during compilation instead of runtime (#7967)
This commit is contained in:
parent
786859b6bb
commit
eac5da89ad
10
Makefile
10
Makefile
|
|
@ -212,6 +212,7 @@ LEARNSET_HELPERS_DIR := $(TOOLS_DIR)/learnset_helpers
|
|||
LEARNSET_HELPERS_DATA_DIR := $(LEARNSET_HELPERS_DIR)/porymoves_files
|
||||
LEARNSET_HELPERS_BUILD_DIR := $(LEARNSET_HELPERS_DIR)/build
|
||||
ALL_LEARNABLES_JSON := $(LEARNSET_HELPERS_BUILD_DIR)/all_learnables.json
|
||||
ALL_TUTORS_JSON := $(LEARNSET_HELPERS_BUILD_DIR)/all_tutors.json
|
||||
|
||||
# wild_encounters.h is generated by a Python script
|
||||
WILD_ENCOUNTERS_TOOL_DIR := $(TOOLS_DIR)/wild_encounters
|
||||
|
|
@ -411,6 +412,8 @@ clean-generated:
|
|||
@echo "rm -f <AUTO_GEN_TARGETS>"
|
||||
@rm -f $(ALL_LEARNABLES_JSON)
|
||||
@echo "rm -f <ALL_LEARNABLES_JSON>"
|
||||
@rm -f $(ALL_TUTORS_JSON)
|
||||
@echo "rm -f <ALL_TUTORS_JSON>"
|
||||
|
||||
$(C_BUILDDIR)/librfu_intr.o: CFLAGS := -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast
|
||||
$(C_BUILDDIR)/berry_crush.o: override CFLAGS += -Wno-address-of-packed-member
|
||||
|
|
@ -500,7 +503,7 @@ $(OBJ_DIR)/sym_common.ld: sym_common.txt $(C_OBJS) $(wildcard common_syms/*.txt)
|
|||
$(OBJ_DIR)/sym_ewram.ld: sym_ewram.txt
|
||||
$(RAMSCRGEN) ewram_data $< ENGLISH > $@
|
||||
|
||||
TEACHABLE_DEPS := $(ALL_LEARNABLES_JSON) $(shell find data/ -type f -name '*.inc') $(INCLUDE_DIRS)/constants/tms_hms.h $(INCLUDE_DIRS)/config/pokemon.h $(C_SUBDIR)/pokemon.c
|
||||
TEACHABLE_DEPS := $(ALL_LEARNABLES_JSON) $(ALL_TUTORS_JSON) $(INCLUDE_DIRS)/constants/tms_hms.h $(INCLUDE_DIRS)/config/pokemon.h $(INCLUDE_DIRS)/config/pokedex_plus_hgss.h $(LEARNSET_HELPERS_DIR)/make_teachables.py
|
||||
|
||||
$(LEARNSET_HELPERS_BUILD_DIR):
|
||||
@mkdir -p $@
|
||||
|
|
@ -508,8 +511,11 @@ $(LEARNSET_HELPERS_BUILD_DIR):
|
|||
$(ALL_LEARNABLES_JSON): $(wildcard $(LEARNSET_HELPERS_DATA_DIR)/*.json) | $(LEARNSET_HELPERS_BUILD_DIR)
|
||||
python3 $(LEARNSET_HELPERS_DIR)/make_learnables.py $(LEARNSET_HELPERS_DATA_DIR) $@
|
||||
|
||||
$(ALL_TUTORS_JSON): $(shell find data/ -type f -name '*.inc') $(LEARNSET_HELPERS_DIR)/make_tutors.py
|
||||
python3 $(LEARNSET_HELPERS_DIR)/make_tutors.py $@
|
||||
|
||||
$(DATA_SRC_SUBDIR)/pokemon/teachable_learnsets.h: $(TEACHABLE_DEPS)
|
||||
python3 $(LEARNSET_HELPERS_DIR)/make_teachables.py $<
|
||||
python3 $(LEARNSET_HELPERS_DIR)/make_teachables.py $< $(ALL_TUTORS_JSON)
|
||||
|
||||
# Linker script
|
||||
LD_SCRIPT := ld_script_modern.ld
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@
|
|||
|
||||
// Learnset helper toggles
|
||||
#define P_LEARNSET_HELPER_TEACHABLE TRUE // If TRUE, teachable_learnsets.h will be populated by tools/learnset_helpers/make_teachables.py using the included JSON files based on available TMs and tutors.
|
||||
#define P_TUTOR_MOVES_ARRAY FALSE // If TRUE, generates a gTutorMoves array automatically using make_teachables.py. (generally not needed, but the HGSS Pokedex has an optional use for it)
|
||||
|
||||
// Flag settings
|
||||
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.
|
||||
|
|
|
|||
34
include/constants/teaching_types.h
Normal file
34
include/constants/teaching_types.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef GUARD_CONSTANTS_TEACHING_TYPES_H
|
||||
#define GUARD_CONSTANTS_TEACHING_TYPES_H
|
||||
|
||||
/*
|
||||
Teaching Types are not used directly by the ROM but they are used by
|
||||
make_teachables.py to generate teachable learnsets. To save ROM space, the info is
|
||||
stored in 1 bit and the python script reads the name of the define.
|
||||
This means we can have multiple "modes" that define to 1.
|
||||
You can add additional teaching types but they would need to be described in the
|
||||
python script.
|
||||
*/
|
||||
|
||||
|
||||
/* DEFAULT_LEARNING
|
||||
Vanilla uses: most pokemon
|
||||
Allow a pokemon to learn all universal moves
|
||||
*/
|
||||
#define DEFAULT_LEARNING 0
|
||||
|
||||
/* TM_ILLITERATE
|
||||
Vanilla uses: pokemon with "gimmick" moveset (Ditto, Smeargle, Magikarp, ...)
|
||||
Pokemon can't learn any universal moves (unless it was added to their teachable learnset)
|
||||
*/
|
||||
#define TM_ILLITERATE 1
|
||||
|
||||
/* ALL_TEACHABLES
|
||||
Vanilla uses: Mew
|
||||
Allows a pokemon to learn almost every teachable move (whether from TM or tutors)
|
||||
Some moves are excluded, they are listed in SignatureTeachables
|
||||
*/
|
||||
#define ALL_TEACHABLES 1
|
||||
|
||||
|
||||
#endif // GUARD_CONSTANTS_TEACHING_TYPES_H
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef GUARD_POKEDEX_PLUS_HGSS_H
|
||||
#define GUARD_POKEDEX_PLUS_HGSS_H
|
||||
|
||||
extern const u16 gTutorMoves[];
|
||||
|
||||
void CB2_OpenPokedexPlusHGSS(void);
|
||||
void Task_DisplayCaughtMonDexPageHGSS(u8);
|
||||
|
||||
|
|
|
|||
|
|
@ -505,7 +505,7 @@ struct SpeciesInfo /*0xC4*/
|
|||
u32 cannotBeTraded:1;
|
||||
u32 perfectIVCount:3; // This species will always generate with the specified amount of perfect IVs.
|
||||
u32 dexForceRequired:1; // This species will be taken into account for Pokédex ratings even if they have the "isMythical" flag set.
|
||||
u32 tmIlliterate:1; // This species will be unable to learn the universal moves.
|
||||
u32 teachingType:1; // Not used in the ROM but used in compilation (check constants/teaching_types.h for explanations)
|
||||
u32 isFrontierBanned:1; // This species is not allowed to participate in Battle Frontier facilities.
|
||||
u32 padding4:11;
|
||||
// Shadow settings
|
||||
|
|
@ -700,9 +700,8 @@ extern const struct SpriteTemplate gBattlerSpriteTemplates[];
|
|||
extern const u32 sExpCandyExperienceTable[];
|
||||
extern const struct AbilityInfo gAbilitiesInfo[];
|
||||
extern const struct NatureInfo gNaturesInfo[];
|
||||
#if P_TUTOR_MOVES_ARRAY
|
||||
|
||||
extern const u16 gTutorMoves[];
|
||||
#endif // P_TUTOR_MOVES_ARRAY
|
||||
|
||||
void ZeroBoxMonData(struct BoxPokemon *boxMon);
|
||||
void ZeroMonData(struct Pokemon *mon);
|
||||
|
|
|
|||
33
src/data/pokemon/special_movesets.json
Normal file
33
src/data/pokemon/special_movesets.json
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"universalMoves":
|
||||
[
|
||||
"MOVE_BIDE",
|
||||
"MOVE_FRUSTRATION",
|
||||
"MOVE_HIDDEN_POWER",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_NATURAL_GIFT",
|
||||
"MOVE_RAGE",
|
||||
"MOVE_RETURN",
|
||||
"MOVE_SECRET_POWER",
|
||||
"MOVE_SUBSTITUTE",
|
||||
"MOVE_TERA_BLAST"
|
||||
],
|
||||
"signatureTeachables":
|
||||
[
|
||||
"MOVE_BADDY_BAD",
|
||||
"MOVE_BOUNCY_BUBBLE",
|
||||
"MOVE_BUZZY_BUZZ",
|
||||
"MOVE_DRAGON_ASCENT",
|
||||
"MOVE_FLOATY_FALL",
|
||||
"MOVE_FREEZY_FROST",
|
||||
"MOVE_GLITZY_GLOW",
|
||||
"MOVE_RELIC_SONG",
|
||||
"MOVE_SAPPY_SEED",
|
||||
"MOVE_SECRET_SWORD",
|
||||
"MOVE_SIZZLY_SLIDE",
|
||||
"MOVE_SPARKLY_SWIRL",
|
||||
"MOVE_SPLISHY_SPLASH",
|
||||
"MOVE_VOLT_TACKLE",
|
||||
"MOVE_ZIPPY_ZAP"
|
||||
]
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include "constants/abilities.h"
|
||||
#include "constants/teaching_types.h"
|
||||
#include "species_info/shared_dex_text.h"
|
||||
#include "species_info/shared_front_pic_anims.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1188,7 +1188,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
|||
gOverworldPalette_Caterpie,
|
||||
gShinyOverworldPalette_Caterpie
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sCaterpieLevelUpLearnset,
|
||||
.teachableLearnset = sCaterpieTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 7, SPECIES_METAPOD}),
|
||||
|
|
@ -1256,7 +1256,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
|||
gOverworldPalette_Metapod,
|
||||
gShinyOverworldPalette_Metapod
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sMetapodLevelUpLearnset,
|
||||
.teachableLearnset = sMetapodTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 10, SPECIES_BUTTERFREE}),
|
||||
|
|
@ -1499,7 +1499,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
|||
gOverworldPalette_Weedle,
|
||||
gShinyOverworldPalette_Weedle
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sWeedleLevelUpLearnset,
|
||||
.teachableLearnset = sWeedleTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 7, SPECIES_KAKUNA}),
|
||||
|
|
@ -1577,7 +1577,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
|||
gOverworldPalette_Kakuna,
|
||||
gShinyOverworldPalette_Kakuna
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sKakunaLevelUpLearnset,
|
||||
.teachableLearnset = sKakunaTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 10, SPECIES_BEEDRILL}),
|
||||
|
|
@ -17203,7 +17203,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
|||
TRACKS_SPOT,
|
||||
sAnimTable_Following
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sMagikarpLevelUpLearnset,
|
||||
.teachableLearnset = sMagikarpTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 20, SPECIES_GYARADOS}),
|
||||
|
|
@ -17565,7 +17565,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
|||
gOverworldPalette_Ditto,
|
||||
gShinyOverworldPalette_Ditto
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sDittoLevelUpLearnset,
|
||||
.teachableLearnset = sDittoTeachableLearnset,
|
||||
},
|
||||
|
|
@ -20239,6 +20239,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
|||
.isMythical = TRUE,
|
||||
.isFrontierBanned = TRUE,
|
||||
.perfectIVCount = LEGENDARY_PERFECT_IV_COUNT,
|
||||
.teachingType = ALL_TEACHABLES,
|
||||
.levelUpLearnset = sMewLevelUpLearnset,
|
||||
.teachableLearnset = sMewTeachableLearnset,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3970,9 +3970,9 @@ const struct SpeciesInfo gSpeciesInfoGen2[] =
|
|||
gOverworldPalette_Unown, \
|
||||
gShinyOverworldPalette_Unown, \
|
||||
) \
|
||||
.teachingType = TM_ILLITERATE, \
|
||||
.levelUpLearnset = sUnownLevelUpLearnset, \
|
||||
.teachableLearnset = sUnownTeachableLearnset, \
|
||||
.tmIlliterate = TRUE, \
|
||||
.formSpeciesIdTable = sUnownFormSpeciesIdTable, \
|
||||
}
|
||||
|
||||
|
|
@ -4074,7 +4074,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] =
|
|||
gOverworldPalette_Wynaut,
|
||||
gShinyOverworldPalette_Wynaut
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sWynautLevelUpLearnset,
|
||||
.teachableLearnset = sWynautTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 15, SPECIES_WOBBUFFET}),
|
||||
|
|
@ -4163,7 +4163,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] =
|
|||
TRACKS_FOOT,
|
||||
sAnimTable_Following
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sWobbuffetLevelUpLearnset,
|
||||
.teachableLearnset = sWobbuffetTeachableLearnset,
|
||||
},
|
||||
|
|
@ -7697,7 +7697,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] =
|
|||
gOverworldPalette_Smeargle,
|
||||
gShinyOverworldPalette_Smeargle
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sSmeargleLevelUpLearnset,
|
||||
.teachableLearnset = sSmeargleTeachableLearnset,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1501,7 +1501,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] =
|
|||
gOverworldPalette_Wurmple,
|
||||
gShinyOverworldPalette_Wurmple
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sWurmpleLevelUpLearnset,
|
||||
.teachableLearnset = sWurmpleTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 7, SPECIES_SILCOON, CONDITIONS({IF_PID_UPPER_MODULO_10_GT, 4})},
|
||||
|
|
@ -1571,7 +1571,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] =
|
|||
gOverworldPalette_Silcoon,
|
||||
gShinyOverworldPalette_Silcoon
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sSilcoonLevelUpLearnset,
|
||||
.teachableLearnset = sSilcoonTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 10, SPECIES_BEAUTIFLY}),
|
||||
|
|
@ -1744,7 +1744,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] =
|
|||
gOverworldPalette_Cascoon,
|
||||
gShinyOverworldPalette_Cascoon
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sCascoonLevelUpLearnset,
|
||||
.teachableLearnset = sCascoonTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 10, SPECIES_DUSTOX}),
|
||||
|
|
@ -11668,7 +11668,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] =
|
|||
gOverworldPalette_Beldum,
|
||||
gShinyOverworldPalette_Beldum
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sBeldumLevelUpLearnset,
|
||||
.teachableLearnset = sBeldumTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 20, SPECIES_METANG}),
|
||||
|
|
|
|||
|
|
@ -1183,7 +1183,7 @@ const struct SpeciesInfo gSpeciesInfoGen4[] =
|
|||
TRACKS_FOOT,
|
||||
sAnimTable_Following
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sKricketotLevelUpLearnset,
|
||||
.teachableLearnset = sKricketotTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 10, SPECIES_KRICKETUNE}),
|
||||
|
|
@ -1865,7 +1865,7 @@ const struct SpeciesInfo gSpeciesInfoGen4[] =
|
|||
gOverworldPalette_BurmyPlant,
|
||||
gShinyOverworldPalette_BurmyPlant
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sBurmyLevelUpLearnset,
|
||||
.teachableLearnset = sBurmyTeachableLearnset,
|
||||
.formSpeciesIdTable = sBurmyFormSpeciesIdTable,
|
||||
|
|
@ -1934,7 +1934,7 @@ const struct SpeciesInfo gSpeciesInfoGen4[] =
|
|||
gOverworldPalette_BurmySandy,
|
||||
gShinyOverworldPalette_BurmySandy
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sBurmyLevelUpLearnset,
|
||||
.teachableLearnset = sBurmyTeachableLearnset,
|
||||
.formSpeciesIdTable = sBurmyFormSpeciesIdTable,
|
||||
|
|
@ -2003,7 +2003,7 @@ const struct SpeciesInfo gSpeciesInfoGen4[] =
|
|||
gOverworldPalette_BurmyTrash,
|
||||
gShinyOverworldPalette_BurmyTrash
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sBurmyLevelUpLearnset,
|
||||
.teachableLearnset = sBurmyTeachableLearnset,
|
||||
.formSpeciesIdTable = sBurmyFormSpeciesIdTable,
|
||||
|
|
@ -2360,7 +2360,7 @@ const struct SpeciesInfo gSpeciesInfoGen4[] =
|
|||
TRACKS_FOOT,
|
||||
sAnimTable_Following
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sCombeeLevelUpLearnset,
|
||||
.teachableLearnset = sCombeeTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 21, SPECIES_VESPIQUEN, CONDITIONS({IF_GENDER, MON_FEMALE})}),
|
||||
|
|
|
|||
|
|
@ -9394,7 +9394,7 @@ const struct SpeciesInfo gSpeciesInfoGen5[] =
|
|||
gOverworldPalette_Tynamo,
|
||||
gShinyOverworldPalette_Tynamo
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sTynamoLevelUpLearnset,
|
||||
.teachableLearnset = sTynamoTeachableLearnset,
|
||||
.evolutions = EVOLUTION({EVO_LEVEL, 39, SPECIES_EELEKTRIK}),
|
||||
|
|
|
|||
|
|
@ -1169,7 +1169,7 @@ const struct SpeciesInfo gSpeciesInfoGen6[] =
|
|||
gOverworldPalette_Scatterbug, \
|
||||
gShinyOverworldPalette_Scatterbug \
|
||||
) \
|
||||
.tmIlliterate = TRUE, \
|
||||
.teachingType = TM_ILLITERATE, \
|
||||
.levelUpLearnset = sScatterbugLevelUpLearnset, \
|
||||
.teachableLearnset = sScatterbugTeachableLearnset, \
|
||||
.eggMoveLearnset = sScatterbugEggMoveLearnset, \
|
||||
|
|
@ -1253,7 +1253,7 @@ const struct SpeciesInfo gSpeciesInfoGen6[] =
|
|||
gOverworldPalette_Spewpa, \
|
||||
gShinyOverworldPalette_Spewpa \
|
||||
) \
|
||||
.tmIlliterate = TRUE, \
|
||||
.teachingType = TM_ILLITERATE, \
|
||||
.levelUpLearnset = sSpewpaLevelUpLearnset, \
|
||||
.teachableLearnset = sSpewpaTeachableLearnset, \
|
||||
.formSpeciesIdTable = sSpewpaFormSpeciesIdTable, \
|
||||
|
|
|
|||
|
|
@ -4291,6 +4291,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] =
|
|||
gOverworldPalette_Pyukumuku,
|
||||
gShinyOverworldPalette_Pyukumuku
|
||||
)
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sPyukumukuLevelUpLearnset,
|
||||
.teachableLearnset = sPyukumukuTeachableLearnset,
|
||||
.eggMoveLearnset = sPyukumukuEggMoveLearnset,
|
||||
|
|
@ -5900,7 +5901,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] =
|
|||
gShinyOverworldPalette_Cosmog
|
||||
)
|
||||
.isLegendary = TRUE,
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.isFrontierBanned = TRUE,
|
||||
.perfectIVCount = LEGENDARY_PERFECT_IV_COUNT,
|
||||
.levelUpLearnset = sCosmogLevelUpLearnset,
|
||||
|
|
@ -5970,7 +5971,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] =
|
|||
gShinyOverworldPalette_Cosmoem
|
||||
)
|
||||
.isLegendary = TRUE,
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.isFrontierBanned = TRUE,
|
||||
.perfectIVCount = LEGENDARY_PERFECT_IV_COUNT,
|
||||
.levelUpLearnset = sCosmoemLevelUpLearnset,
|
||||
|
|
|
|||
|
|
@ -1230,7 +1230,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] =
|
|||
gOverworldPalette_Blipbug,
|
||||
gShinyOverworldPalette_Blipbug
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sBlipbugLevelUpLearnset,
|
||||
.teachableLearnset = sBlipbugTeachableLearnset,
|
||||
.eggMoveLearnset = sBlipbugEggMoveLearnset,
|
||||
|
|
@ -2461,7 +2461,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] =
|
|||
gOverworldPalette_Applin,
|
||||
gShinyOverworldPalette_Applin
|
||||
)
|
||||
.tmIlliterate = TRUE,
|
||||
.teachingType = TM_ILLITERATE,
|
||||
.levelUpLearnset = sApplinLevelUpLearnset,
|
||||
.teachableLearnset = sApplinTeachableLearnset,
|
||||
.eggMoveLearnset = sApplinEggMoveLearnset,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -290,9 +290,6 @@ static EWRAM_DATA u16 sLastSelectedPokemon = 0;
|
|||
static EWRAM_DATA u8 sPokeBallRotation = 0;
|
||||
static EWRAM_DATA struct PokedexListItem *sPokedexListItem = NULL;
|
||||
//Pokedex Plus HGSS_Ui
|
||||
#define MOVES_COUNT_TOTAL (EGG_MOVES_ARRAY_COUNT + MAX_LEVEL_UP_MOVES + NUM_ALL_MACHINES)
|
||||
EWRAM_DATA static u16 sStatsMoves[MOVES_COUNT_TOTAL] = {0};
|
||||
EWRAM_DATA static u16 sStatsMovesTMHM_ID[NUM_ALL_MACHINES] = {0};
|
||||
|
||||
|
||||
struct SearchOptionText
|
||||
|
|
@ -409,8 +406,7 @@ struct PokedexView
|
|||
u8 categoryIconSpriteId; //Physical/Special/Status category
|
||||
u8 numEggMoves;
|
||||
u8 numLevelUpMoves;
|
||||
u8 numTMHMMoves;
|
||||
u8 numTutorMoves;
|
||||
u8 numTeachableMoves;
|
||||
u8 numPreEvolutions;
|
||||
struct PokemonStats sPokemonStats;
|
||||
struct EvoScreenData sEvoScreenData;
|
||||
|
|
@ -4871,7 +4867,7 @@ static void Task_LoadStatsScreen(u8 taskId)
|
|||
sPokedexView->movesTotal = 0;
|
||||
sPokedexView->numEggMoves = 0;
|
||||
sPokedexView->numLevelUpMoves = 0;
|
||||
sPokedexView->numTMHMMoves = 0;
|
||||
sPokedexView->numTeachableMoves = 0;
|
||||
if (CalculateMoves())
|
||||
gMain.state++;
|
||||
break;
|
||||
|
|
@ -5059,87 +5055,15 @@ static void PrintStatsScreen_DestroyMoveItemIcon(u8 taskId)
|
|||
DestroySprite(&gSprites[gTasks[taskId].data[3]]); //Destroy item icon
|
||||
}
|
||||
|
||||
static u16 AddTMTutorMoves(u16 species, u16 movesTotal, u8 *numTMHMMoves, u8 *numTutorMoves)
|
||||
{
|
||||
u16 i, move;
|
||||
bool8 isTMMove[MOVES_COUNT] = {0};
|
||||
const u16 *teachableLearnset = GetSpeciesTeachableLearnset(species);
|
||||
|
||||
// TM Moves
|
||||
if (HGSS_SORT_TMS_BY_NUM)
|
||||
{
|
||||
for (i = 0; i < NUM_ALL_MACHINES; i++)
|
||||
{
|
||||
move = GetTMHMMoveId(i + 1);
|
||||
if (move != MOVE_NONE && CanLearnTeachableMove(species, move))
|
||||
{
|
||||
isTMMove[move] = TRUE;
|
||||
sStatsMovesTMHM_ID[*numTMHMMoves] = GetTMHMItemId(i + 1);
|
||||
(*numTMHMMoves)++;
|
||||
sStatsMoves[movesTotal] = move;
|
||||
movesTotal++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; teachableLearnset[i] != MOVE_UNAVAILABLE; i++)
|
||||
{
|
||||
move = teachableLearnset[i];
|
||||
for (u16 j = 0; j < NUM_ALL_MACHINES; j++)
|
||||
{
|
||||
if (GetTMHMMoveId(j + 1) == move)
|
||||
{
|
||||
isTMMove[move] = TRUE;
|
||||
sStatsMovesTMHM_ID[*numTMHMMoves] = GetTMHMItemId(j + 1);
|
||||
(*numTMHMMoves)++;
|
||||
sStatsMoves[movesTotal] = move;
|
||||
movesTotal++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tutor Moves
|
||||
#if P_TUTOR_MOVES_ARRAY
|
||||
for (i = 0; gTutorMoves[i] != MOVE_UNAVAILABLE; i++)
|
||||
{
|
||||
move = gTutorMoves[i];
|
||||
if (!isTMMove[move] && CanLearnTeachableMove(species, move))
|
||||
{
|
||||
sStatsMoves[movesTotal] = move;
|
||||
movesTotal++;
|
||||
(*numTutorMoves)++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; teachableLearnset[i] != MOVE_UNAVAILABLE; i++)
|
||||
{
|
||||
move = teachableLearnset[i];
|
||||
if (!isTMMove[move] && CanLearnTeachableMove(species, move))
|
||||
{
|
||||
sStatsMoves[movesTotal] = move;
|
||||
movesTotal++;
|
||||
(*numTutorMoves)++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return movesTotal;
|
||||
}
|
||||
|
||||
static bool8 CalculateMoves(void)
|
||||
{
|
||||
u16 species = NationalPokedexNumToSpeciesHGSS(sPokedexListItem->dexNum);
|
||||
|
||||
u16 statsMovesEgg[EGG_MOVES_ARRAY_COUNT] = {0};
|
||||
u16 statsMovesLevelUp[MAX_LEVEL_UP_MOVES] = {0};
|
||||
|
||||
u8 numEggMoves = 0;
|
||||
u8 numLevelUpMoves = 0;
|
||||
u8 numTMHMMoves = 0;
|
||||
u8 numTutorMoves = 0;
|
||||
u16 movesTotal = 0;
|
||||
u8 numTeachableMoves = 0;
|
||||
u8 i;
|
||||
|
||||
// Mega and Gmax Pokémon don't have distinct learnsets from their base form; so use base species for calculation
|
||||
|
|
@ -5161,57 +5085,91 @@ static bool8 CalculateMoves(void)
|
|||
numEggMoves = GetEggMovesBySpecies(species, statsMovesEgg);
|
||||
}
|
||||
|
||||
for (i = 0; i < numEggMoves; i++)
|
||||
{
|
||||
sStatsMoves[movesTotal] = statsMovesEgg[i];
|
||||
movesTotal++;
|
||||
}
|
||||
|
||||
// Level up moves
|
||||
numLevelUpMoves = GetLevelUpMovesBySpecies(species, statsMovesLevelUp);
|
||||
for (i = 0; i < numLevelUpMoves; i++)
|
||||
{
|
||||
sStatsMoves[movesTotal] = statsMovesLevelUp[i];
|
||||
movesTotal++;
|
||||
}
|
||||
const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species);
|
||||
for (i = 0; i < MAX_LEVEL_UP_MOVES && learnset[i].move != LEVEL_UP_MOVE_END; i++)
|
||||
numLevelUpMoves++;
|
||||
|
||||
// TM and Tutor moves
|
||||
movesTotal = AddTMTutorMoves(species, movesTotal, &numTMHMMoves, &numTutorMoves);
|
||||
const u16 *teachableLearnset = GetSpeciesTeachableLearnset(species);
|
||||
for (i = 0; teachableLearnset[i] != MOVE_UNAVAILABLE; i++)
|
||||
numTeachableMoves++;
|
||||
|
||||
sPokedexView->numEggMoves = numEggMoves;
|
||||
sPokedexView->numLevelUpMoves = numLevelUpMoves;
|
||||
sPokedexView->numTMHMMoves = numTMHMMoves;
|
||||
sPokedexView->numTutorMoves = numTutorMoves;
|
||||
sPokedexView->movesTotal = movesTotal;
|
||||
sPokedexView->numTeachableMoves = numTeachableMoves;
|
||||
sPokedexView->movesTotal = (numEggMoves + numLevelUpMoves + numTeachableMoves);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static u16 GetSelectedMove(u32 species, u32 selected)
|
||||
{
|
||||
if (selected < sPokedexView->numEggMoves)
|
||||
return GetSpeciesEggMoves(species)[selected];
|
||||
selected -= sPokedexView->numEggMoves;
|
||||
if (selected < sPokedexView->numLevelUpMoves)
|
||||
return GetSpeciesLevelUpLearnset(species)[selected].move;
|
||||
selected -= sPokedexView->numLevelUpMoves;
|
||||
if (selected < sPokedexView->numTeachableMoves)
|
||||
return GetSpeciesTeachableLearnset(species)[selected];
|
||||
return MOVE_NONE; //It should never get here but it allows us to visually see errors
|
||||
}
|
||||
|
||||
static void PrintStatsScreen_Moves_Top(u8 taskId)
|
||||
{
|
||||
u8 numEggMoves = sPokedexView->numEggMoves;
|
||||
u8 numLevelUpMoves = sPokedexView->numLevelUpMoves;
|
||||
u8 numTMHMMoves = sPokedexView->numTMHMMoves;
|
||||
u8 numTutorMoves = sPokedexView->numTutorMoves;
|
||||
u16 movesTotal = sPokedexView->movesTotal;
|
||||
u16 selected = sPokedexView->moveSelected;
|
||||
u8 level;
|
||||
u8 moves_x = 5;
|
||||
u8 moves_y = 3;
|
||||
u16 move;
|
||||
u16 item;
|
||||
|
||||
u16 species = NationalPokedexNumToSpeciesHGSS(sPokedexListItem->dexNum);
|
||||
|
||||
//Move
|
||||
move = sStatsMoves[selected];
|
||||
|
||||
u32 item = ITEM_MASTER_BALL;
|
||||
u32 species = NationalPokedexNumToSpeciesHGSS(sPokedexListItem->dexNum);
|
||||
u32 selected = sPokedexView->moveSelected;
|
||||
u32 move = GetSelectedMove(species, selected);
|
||||
//Moves selected from move max
|
||||
ConvertIntToDecimalStringN(gStringVar1, (selected+1), STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
ConvertIntToDecimalStringN(gStringVar2, movesTotal, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
ConvertIntToDecimalStringN(gStringVar2, sPokedexView->movesTotal, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
StringExpandPlaceholders(gStringVar1, sText_Stats_MoveSelectedMax);
|
||||
PrintStatsScreenTextSmallWhite(WIN_STATS_MOVES_TOP, gStringVar1, moves_x-1, moves_y+1);
|
||||
|
||||
//Calculate and retrieve correct move from the arrays
|
||||
if (selected < sPokedexView->numEggMoves)
|
||||
{
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_TOP, gText_ThreeDashes, moves_x + 113, moves_y + 9);
|
||||
item = ITEM_LUCKY_EGG;
|
||||
}
|
||||
else if (selected < (sPokedexView->numLevelUpMoves + sPokedexView->numEggMoves))
|
||||
{
|
||||
u32 level = GetSpeciesLevelUpLearnset(species)[selected - sPokedexView->numEggMoves].level;
|
||||
ConvertIntToDecimalStringN(gStringVar1, level, STR_CONV_MODE_LEFT_ALIGN, 3); //Move learn lvl
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_TOP, sText_Stats_MoveLevel, moves_x + 113, moves_y + 3); //Level text
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_TOP, gStringVar1, moves_x + 113, moves_y + 14); //Print level
|
||||
item = ITEM_RARE_CANDY;
|
||||
}
|
||||
else if (move)
|
||||
{
|
||||
u32 TMHMItemId = ITEM_NONE;
|
||||
for (u32 i = 0; i < NUM_ALL_MACHINES; i++)
|
||||
{
|
||||
if (move == GetTMHMMoveId(i + 1))
|
||||
TMHMItemId = GetTMHMItemId(i + 1);
|
||||
}
|
||||
if (TMHMItemId)
|
||||
{
|
||||
CopyItemName(TMHMItemId, gStringVar1); //TM name
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_TOP, gStringVar1, moves_x + 113, moves_y + 9);
|
||||
item = TMHMItemId;
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_TOP, gText_ThreeDashes, moves_x + 113, moves_y + 9);
|
||||
item = ITEM_TEACHY_TV;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StringCopy(gStringVar4, gText_CommunicationError);
|
||||
}
|
||||
|
||||
//Move name
|
||||
StringCopy(gStringVar3, GetMoveName(move));
|
||||
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 20);
|
||||
|
|
@ -5229,37 +5187,6 @@ static void PrintStatsScreen_Moves_Top(u8 taskId)
|
|||
SetSpriteInvisibility(0, TRUE);
|
||||
}
|
||||
|
||||
//Calculate and retrieve correct move from the arrays
|
||||
if (selected < numEggMoves)
|
||||
{
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_TOP, gText_ThreeDashes, moves_x + 113, moves_y + 9);
|
||||
item = ITEM_LUCKY_EGG;
|
||||
}
|
||||
else if (selected < (numEggMoves + numLevelUpMoves))
|
||||
{
|
||||
level = GetSpeciesLevelUpLearnset(species)[(selected-numEggMoves)].level;
|
||||
ConvertIntToDecimalStringN(gStringVar1, level, STR_CONV_MODE_LEFT_ALIGN, 3); //Move learn lvl
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_TOP, sText_Stats_MoveLevel, moves_x + 113, moves_y + 3); //Level text
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_TOP, gStringVar1, moves_x + 113, moves_y + 14); //Print level
|
||||
item = ITEM_RARE_CANDY;
|
||||
}
|
||||
else if (selected < (numEggMoves + numLevelUpMoves + numTMHMMoves))
|
||||
{
|
||||
CopyItemName(sStatsMovesTMHM_ID[(selected-numEggMoves-numLevelUpMoves)], gStringVar1); //TM name
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_TOP, gStringVar1, moves_x + 113, moves_y + 9);
|
||||
item = sStatsMovesTMHM_ID[(selected-numEggMoves-numLevelUpMoves)];
|
||||
}
|
||||
else if (selected < (numEggMoves + numLevelUpMoves + numTMHMMoves + numTutorMoves))
|
||||
{
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_TOP, gText_ThreeDashes, moves_x + 113, moves_y + 9);
|
||||
item = ITEM_TEACHY_TV;
|
||||
}
|
||||
else
|
||||
{
|
||||
StringCopy(gStringVar4, gText_CommunicationError);
|
||||
item = ITEM_MASTER_BALL;
|
||||
}
|
||||
|
||||
//Egg/TM/Level/Tutor Item Icon
|
||||
gTasks[taskId].data[3] = AddItemIconSprite(ITEM_TAG, ITEM_TAG, item);
|
||||
gSprites[gTasks[taskId].data[3]].x2 = 203;
|
||||
|
|
@ -5270,13 +5197,11 @@ static void PrintStatsScreen_Moves_Top(u8 taskId)
|
|||
|
||||
static void PrintStatsScreen_Moves_Description(u8 taskId)
|
||||
{
|
||||
u16 selected = sPokedexView->moveSelected;
|
||||
u16 move;
|
||||
u8 moves_x = 5;
|
||||
u8 moves_y = 5;
|
||||
|
||||
//Move
|
||||
move = sStatsMoves[selected];
|
||||
u32 species = NationalPokedexNumToSpeciesHGSS(sPokedexListItem->dexNum);
|
||||
u32 move = GetSelectedMove(species, sPokedexView->moveSelected);
|
||||
|
||||
//Move description
|
||||
if (gTasks[taskId].data[5] == 0)
|
||||
|
|
@ -5295,6 +5220,7 @@ static void PrintStatsScreen_Moves_BottomText(u8 taskId)
|
|||
{
|
||||
u8 moves_x = 8;
|
||||
u8 moves_y = 3;
|
||||
|
||||
if (gTasks[taskId].data[5] == 0)
|
||||
{
|
||||
PrintStatsScreenTextSmall(WIN_STATS_MOVES_BOTTOM, gText_Power, moves_x, moves_y);
|
||||
|
|
@ -5311,15 +5237,14 @@ static void PrintStatsScreen_Moves_Bottom(u8 taskId)
|
|||
{
|
||||
u8 moves_x = 8;
|
||||
u8 moves_y = 3;
|
||||
u8 selected = sPokedexView->moveSelected;
|
||||
u16 move;
|
||||
|
||||
//Contest
|
||||
u8 contest_effectValue;
|
||||
u8 contest_appeal = 0;
|
||||
u8 contest_jam = 0;
|
||||
|
||||
//Move
|
||||
move = sStatsMoves[selected];
|
||||
u32 species = NationalPokedexNumToSpeciesHGSS(sPokedexListItem->dexNum);
|
||||
u32 move = GetSelectedMove(species, sPokedexView->moveSelected);
|
||||
|
||||
//Power + Accuracy
|
||||
if (gTasks[taskId].data[5] == 0)
|
||||
|
|
|
|||
|
|
@ -95,9 +95,6 @@ EWRAM_DATA static u8 sTriedEvolving = 0;
|
|||
EWRAM_DATA u16 gFollowerSteps = 0;
|
||||
|
||||
#include "data/abilities.h"
|
||||
#if P_TUTOR_MOVES_ARRAY
|
||||
#include "data/tutor_moves.h"
|
||||
#endif // P_TUTOR_MOVES_ARRAY
|
||||
|
||||
// Used in an unreferenced function in RS.
|
||||
// Unreferenced here and in FRLG.
|
||||
|
|
@ -5581,89 +5578,17 @@ bool8 TryIncrementMonLevel(struct Pokemon *mon)
|
|||
}
|
||||
}
|
||||
|
||||
static const u16 sUniversalMoves[] =
|
||||
{
|
||||
MOVE_BIDE,
|
||||
MOVE_FRUSTRATION,
|
||||
MOVE_HIDDEN_POWER,
|
||||
MOVE_MIMIC,
|
||||
MOVE_NATURAL_GIFT,
|
||||
MOVE_RAGE,
|
||||
MOVE_RETURN,
|
||||
MOVE_SECRET_POWER,
|
||||
MOVE_SUBSTITUTE,
|
||||
MOVE_TERA_BLAST,
|
||||
};
|
||||
|
||||
u8 CanLearnTeachableMove(u16 species, u16 move)
|
||||
{
|
||||
const u16 *teachableLearnset = GetSpeciesTeachableLearnset(species);
|
||||
if (species == SPECIES_EGG)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else if (species == SPECIES_MEW)
|
||||
for (u32 i = 0; teachableLearnset[i] != MOVE_UNAVAILABLE; i++)
|
||||
{
|
||||
switch (move)
|
||||
{
|
||||
case MOVE_BADDY_BAD:
|
||||
case MOVE_BOUNCY_BUBBLE:
|
||||
case MOVE_BUZZY_BUZZ:
|
||||
case MOVE_DRAGON_ASCENT:
|
||||
case MOVE_FLOATY_FALL:
|
||||
case MOVE_FREEZY_FROST:
|
||||
case MOVE_GLITZY_GLOW:
|
||||
case MOVE_RELIC_SONG:
|
||||
case MOVE_SAPPY_SEED:
|
||||
case MOVE_SECRET_SWORD:
|
||||
case MOVE_SIZZLY_SLIDE:
|
||||
case MOVE_SPARKLY_SWIRL:
|
||||
case MOVE_SPLISHY_SPLASH:
|
||||
case MOVE_VOLT_TACKLE:
|
||||
case MOVE_ZIPPY_ZAP:
|
||||
return FALSE;
|
||||
default:
|
||||
if (teachableLearnset[i] == move)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 i, j;
|
||||
const u16 *teachableLearnset = GetSpeciesTeachableLearnset(species);
|
||||
for (i = 0; i < ARRAY_COUNT(sUniversalMoves); i++)
|
||||
{
|
||||
if (sUniversalMoves[i] == move)
|
||||
{
|
||||
if (!gSpeciesInfo[species].tmIlliterate)
|
||||
{
|
||||
if (move == MOVE_TERA_BLAST && GET_BASE_SPECIES_ID(species) == SPECIES_TERAPAGOS)
|
||||
return FALSE;
|
||||
if (GET_BASE_SPECIES_ID(species) == SPECIES_PYUKUMUKU && (move == MOVE_HIDDEN_POWER || move == MOVE_RETURN || move == MOVE_FRUSTRATION))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species);
|
||||
|
||||
if (P_TM_LITERACY < GEN_6)
|
||||
return FALSE;
|
||||
|
||||
for (j = 0; j < MAX_LEVEL_UP_MOVES && learnset[j].move != LEVEL_UP_MOVE_END; j++)
|
||||
{
|
||||
if (learnset[j].move == move)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; teachableLearnset[i] != MOVE_UNAVAILABLE; i++)
|
||||
{
|
||||
if (teachableLearnset[i] == move)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u8 GetMoveRelearnerMoves(struct Pokemon *mon, u16 *moves)
|
||||
|
|
|
|||
|
|
@ -33,14 +33,14 @@ import typing
|
|||
|
||||
|
||||
CONFIG_ENABLED_PAT = re.compile(r"#define P_LEARNSET_HELPER_TEACHABLE\s+(?P<cfg_val>[^ ]*)")
|
||||
INCFILE_HAS_TUTOR_PAT = re.compile(r"special ChooseMonForMoveTutor")
|
||||
INCFILE_MOVE_PAT = re.compile(r"setvar VAR_0x8005, (MOVE_.*)")
|
||||
ALPHABETICAL_ORDER_ENABLED_PAT = re.compile(r"#define HGSS_SORT_TMS_BY_NUM\s+(?P<cfg_val>[^ ]*)")
|
||||
TM_LITTERACY_PAT = re.compile(r"#define P_TM_LITERACY\s+GEN_(?P<cfg_val>[^ ]*)")
|
||||
TMHM_MACRO_PAT = re.compile(r"F\((\w+)\)")
|
||||
UNIVERSAL_MOVES_PAT = re.compile(r"static const u16 sUniversalMoves\[\]\s*=\s*{((.|\n)*?)\n};")
|
||||
TEACHABLE_ARRAY_DECL_PAT = re.compile(r"(?P<decl>static const u16 s(?P<name>\w+)TeachableLearnset\[\]) = {[\s\S]*?};")
|
||||
MOVE_TUTOR_ARRAY_DECL_PAT = re.compile(r"(?P<decl>const u16 gTutorMoves\[\] = {)[\s\S]*? MOVE_UNAVAILABLE,")
|
||||
SNAKIFY_PAT = re.compile(r"(?!^)([A-Z]+)")
|
||||
TUTOR_ARRAY_ENABLED_PAT = re.compile(r"#define\s+P_TUTOR_MOVES_ARRAY\s+(?P<cfg_val>[^ ]*)")
|
||||
|
||||
TUTOR_ARRAY_ENABLED_PAT = re.compile(r"#define\s+POKEDEX_PLUS_HGSS\s+(?P<cfg_val>[^ ]*)")
|
||||
POKEMON_TEACHING_TYPE_PAT = re.compile(r"\{[\s\S]*?(.teachingType\s*=\s*(?P<teaching_type>[A-Z_]+),[\s\S]*?)?\.teachableLearnset\s*=\s*s(?P<name>\w+?)TeachableLearnset[\s\S]*?\}")
|
||||
|
||||
def enabled() -> bool:
|
||||
"""
|
||||
|
|
@ -51,22 +51,6 @@ def enabled() -> bool:
|
|||
cfg_defined = CONFIG_ENABLED_PAT.search(cfg_pokemon)
|
||||
return cfg_defined is not None and cfg_defined.group("cfg_val") in ("TRUE", "1")
|
||||
|
||||
|
||||
def extract_repo_tutors() -> typing.Generator[str, None, None]:
|
||||
"""
|
||||
Yield MOVE constants which are *likely* assigned to a move tutor. This isn't
|
||||
foolproof, but it's suitable.
|
||||
"""
|
||||
for inc_fname in chain(glob.glob("./data/scripts/*.inc"), glob.glob("./data/maps/*/scripts.inc")):
|
||||
with open(inc_fname, "r") as inc_fp:
|
||||
incfile = inc_fp.read()
|
||||
if not INCFILE_HAS_TUTOR_PAT.search(incfile):
|
||||
continue
|
||||
|
||||
for move in INCFILE_MOVE_PAT.finditer(incfile):
|
||||
yield move.group(1)
|
||||
|
||||
|
||||
def extract_repo_tms() -> typing.Generator[str, None, None]:
|
||||
"""
|
||||
Yield MOVE constants assigned to a TM or HM in the user's repo.
|
||||
|
|
@ -80,22 +64,37 @@ def extract_repo_tms() -> typing.Generator[str, None, None]:
|
|||
for match in match_it:
|
||||
yield f"MOVE_{match.group(1)}"
|
||||
|
||||
def extract_repo_teaching_types() -> dict[str, str]:
|
||||
species_teaching_types = {}
|
||||
for families_fname in sorted(glob.glob("src/data/pokemon/species_info/gen_*_families.h")):
|
||||
with open(families_fname, "r") as family_fp:
|
||||
family_file = family_fp.read()
|
||||
for pokemon in POKEMON_TEACHING_TYPE_PAT.finditer(family_file):
|
||||
if pokemon.group("teaching_type"):
|
||||
species_teaching_types[pokemon.group("name")] = pokemon.group("teaching_type")
|
||||
else:
|
||||
species_teaching_types[pokemon.group("name")] = "DEFAULT_LEARNING"
|
||||
return species_teaching_types
|
||||
|
||||
def extract_repo_universals() -> list[str]:
|
||||
"""
|
||||
Return a list of MOVE constants which are deemed to be universal and can
|
||||
thus be learned by any species.
|
||||
"""
|
||||
with open("./src/pokemon.c", "r") as pokemon_fp:
|
||||
if match := UNIVERSAL_MOVES_PAT.search(pokemon_fp.read()):
|
||||
return list(filter(lambda s: s, map(lambda s: s.strip(), match.group(1).split(','))))
|
||||
return list()
|
||||
def extract_tm_litteracy_config() -> bool:
|
||||
config = False
|
||||
with open("./include/config/pokemon.h", "r") as cfg_pokemon_fp:
|
||||
cfg_pokemon = cfg_pokemon_fp.read()
|
||||
cfg_defined = TM_LITTERACY_PAT.search(cfg_pokemon)
|
||||
if cfg_defined:
|
||||
cfg_val = cfg_defined.group("cfg_val")
|
||||
if ((cfg_val == "LATEST") or (int(cfg_val) > 6)):
|
||||
config = True
|
||||
return config
|
||||
|
||||
|
||||
def prepare_output(all_learnables: dict[str, set[str]], repo_teachables: set[str], header: str) -> str:
|
||||
def prepare_output(all_learnables: dict[str, set[str]], tms: list[str], tutors: list[str], special_movesets, header: str) -> str:
|
||||
"""
|
||||
Build the file content for teachable_learnsets.h.
|
||||
"""
|
||||
|
||||
repo_teaching_types = extract_repo_teaching_types()
|
||||
tm_litteracy_config = extract_tm_litteracy_config()
|
||||
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", "r") as teachables_fp:
|
||||
old = teachables_fp.read()
|
||||
|
||||
|
|
@ -115,13 +114,22 @@ def prepare_output(all_learnables: dict[str, set[str]], repo_teachables: set[str
|
|||
cursor = match_e + 1
|
||||
continue
|
||||
|
||||
if species_upper == "MEW":
|
||||
new += old[cursor:match_e + 1] # copy the original content and skip.
|
||||
cursor = match_e + 1
|
||||
continue
|
||||
if repo_teaching_types[species.group("name")] == "ALL_TEACHABLES":
|
||||
learnables = filter(lambda m: m not in special_movesets["signatureTeachables"], tms + tutors)
|
||||
elif repo_teaching_types[species.group("name")] == "TM_ILLITERATE":
|
||||
learnables = all_learnables[species_upper]
|
||||
if not tm_litteracy_config:
|
||||
learnables = filter(lambda m: m not in special_movesets["universalMoves"], learnables)
|
||||
else:
|
||||
learnables = all_learnables[species_upper] + special_movesets["universalMoves"]
|
||||
|
||||
repo_species_teachables = filter(lambda m: m in repo_teachables, all_learnables[species_upper])
|
||||
part1 = list(filter(lambda m: m in learnables, tms))
|
||||
part2 = list(filter(lambda m: m in learnables, tutors))
|
||||
repo_species_teachables = part1 + part2
|
||||
if species_upper == "TERAPAGOS":
|
||||
repo_species_teachables = filter(lambda m: m != "MOVE_TERA_BLAST", repo_species_teachables)
|
||||
|
||||
repo_species_teachables = list(dict.fromkeys(repo_species_teachables))
|
||||
new += old[cursor:match_b]
|
||||
new += "\n".join([
|
||||
f"{species.group('decl')} = {{",
|
||||
|
|
@ -130,39 +138,23 @@ def prepare_output(all_learnables: dict[str, set[str]], repo_teachables: set[str
|
|||
])
|
||||
cursor = match_e + 1
|
||||
|
||||
tutors_array = MOVE_TUTOR_ARRAY_DECL_PAT.search(old)
|
||||
match_b, match_e = tutors_array.span()
|
||||
new += old[cursor:match_b]
|
||||
new += "\n".join([
|
||||
f"{tutors_array.group('decl')}",
|
||||
f" {joinpat.join(chain(sorted(tutors)))},"
|
||||
f"\n MOVE_UNAVAILABLE,\n"
|
||||
])
|
||||
cursor = match_e + 1
|
||||
|
||||
new += old[cursor:]
|
||||
|
||||
return new
|
||||
|
||||
|
||||
def create_tutor_moves_array(tutors: list[str]) -> None:
|
||||
"""
|
||||
Generate gTutorMoves[] if P_TUTOR_MOVES_ARRAY is enabled.
|
||||
"""
|
||||
# Check if the config is enabled
|
||||
with open("./include/config/pokemon.h", "r") as cfg_pokemon_fp:
|
||||
cfg_pokemon = cfg_pokemon_fp.read()
|
||||
cfg_defined = TUTOR_ARRAY_ENABLED_PAT.search(cfg_pokemon)
|
||||
if not (cfg_defined and cfg_defined.group("cfg_val") in ("TRUE", "1")):
|
||||
return
|
||||
|
||||
# If enabled, generate the tutor moves array
|
||||
header = dedent("""\
|
||||
// DO NOT MODIFY THIS FILE! It is auto-generated by tools/learnset_helpers/make_teachables.py
|
||||
// Set the config P_TUTOR_MOVES_ARRAY in include/config/pokemon.h to TRUE to enable this array!
|
||||
|
||||
const u16 gTutorMoves[] = {
|
||||
""")
|
||||
|
||||
lines = [f" {move}," for move in sorted(tutors)]
|
||||
lines.append(" MOVE_UNAVAILABLE\n};\n")
|
||||
|
||||
with open("./src/data/tutor_moves.h", "w") as f:
|
||||
f.write(header + "\n".join(lines))
|
||||
|
||||
|
||||
def prepare_header(h_align: int, tmshms: list[str], tutors: list[str], universals: list[str]) -> str:
|
||||
universals_title = "Near-universal moves found from sUniversalMoves:"
|
||||
universals_title = "Near-universal moves found in data/special_movesets.json:"
|
||||
tmhm_title = "TM/HM moves found in \"include/constants/tms_hms.h\":"
|
||||
tutor_title = "Tutor moves found from map scripts:"
|
||||
h_align = max(h_align, len(universals_title), len(tmhm_title), len(tutor_title))
|
||||
|
|
@ -204,30 +196,38 @@ def main():
|
|||
quit(1)
|
||||
|
||||
SOURCE_LEARNSETS_JSON = pathlib.Path(sys.argv[1])
|
||||
SOURCE_TUTORS_JSON = pathlib.Path(sys.argv[2])
|
||||
|
||||
assert SOURCE_LEARNSETS_JSON.exists(), f"{SOURCE_LEARNSETS_JSON=} does not exist"
|
||||
assert SOURCE_LEARNSETS_JSON.is_file(), f"{SOURCE_LEARNSETS_JSON=} is not a file"
|
||||
|
||||
repo_universals = extract_repo_universals()
|
||||
assert SOURCE_TUTORS_JSON.exists(), f"{SOURCE_TUTORS_JSON=} does not exist"
|
||||
assert SOURCE_TUTORS_JSON.is_file(), f"{SOURCE_TUTORS_JSON=} is not a file"
|
||||
|
||||
repo_tms = list(extract_repo_tms())
|
||||
repo_tutors = list(extract_repo_tutors())
|
||||
repo_teachables = set(filter(
|
||||
lambda move: move not in set(repo_universals),
|
||||
chain(repo_tms, repo_tutors)
|
||||
))
|
||||
order_alphabetically = False
|
||||
|
||||
create_tutor_moves_array(repo_tutors)
|
||||
with open("./include/config/pokedex_plus_hgss.h", "r") as cfg_pokemon_fp:
|
||||
cfg_pokemon = cfg_pokemon_fp.read()
|
||||
cfg_defined = ALPHABETICAL_ORDER_ENABLED_PAT.search(cfg_pokemon)
|
||||
if cfg_defined is None or cfg_defined.group("cfg_val") in ("FALSE", "0"):
|
||||
repo_tms = sorted(repo_tms)
|
||||
|
||||
h_align = max(map(lambda move: len(move), chain(repo_universals, repo_teachables))) + 2
|
||||
header = prepare_header(h_align, repo_tms, repo_tutors, repo_universals)
|
||||
with open(SOURCE_TUTORS_JSON, "r") as fp:
|
||||
repo_tutors = json.load(fp)
|
||||
|
||||
with open("src/data/pokemon/special_movesets.json", "r") as file:
|
||||
special_movesets = json.load(file)
|
||||
|
||||
h_align = max(map(lambda move: len(move), chain(special_movesets["universalMoves"], repo_tms, repo_tutors))) + 2
|
||||
header = prepare_header(h_align, repo_tms, repo_tutors, special_movesets["universalMoves"])
|
||||
|
||||
with open(SOURCE_LEARNSETS_JSON, "r") as source_fp:
|
||||
all_learnables = json.load(source_fp)
|
||||
|
||||
content = prepare_output(all_learnables, repo_teachables, header)
|
||||
content = prepare_output(all_learnables, repo_tms, repo_tutors, special_movesets, header)
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", "w") as teachables_fp:
|
||||
teachables_fp.write(content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
68
tools/learnset_helpers/make_tutors.py
Normal file
68
tools/learnset_helpers/make_tutors.py
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
from itertools import chain
|
||||
|
||||
import glob
|
||||
import json
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
import typing
|
||||
|
||||
CONFIG_ENABLED_PAT = re.compile(r"#define P_LEARNSET_HELPER_TEACHABLE\s+(?P<cfg_val>[^ ]*)")
|
||||
INCFILE_HAS_TUTOR_PAT = re.compile(r"special ChooseMonForMoveTutor")
|
||||
INCFILE_MOVE_PAT = re.compile(r"setvar VAR_0x8005, (MOVE_.*)")
|
||||
|
||||
def enabled() -> bool:
|
||||
"""
|
||||
Check if the user has explicitly enabled this opt-in helper.
|
||||
"""
|
||||
with open("./include/config/pokemon.h", "r") as cfg_pokemon_fp:
|
||||
cfg_pokemon = cfg_pokemon_fp.read()
|
||||
cfg_defined = CONFIG_ENABLED_PAT.search(cfg_pokemon)
|
||||
return cfg_defined is not None and cfg_defined.group("cfg_val") in ("TRUE", "1")
|
||||
|
||||
def extract_repo_tutors() -> typing.Generator[str, None, None]:
|
||||
"""
|
||||
Yield MOVE constants which are *likely* assigned to a move tutor. This isn't
|
||||
foolproof, but it's suitable.
|
||||
"""
|
||||
for inc_fname in chain(glob.glob("./data/scripts/*.inc"), glob.glob("./data/maps/*/scripts.inc")):
|
||||
with open(inc_fname, "r") as inc_fp:
|
||||
incfile = inc_fp.read()
|
||||
if not INCFILE_HAS_TUTOR_PAT.search(incfile):
|
||||
continue
|
||||
|
||||
for move in INCFILE_MOVE_PAT.finditer(incfile):
|
||||
yield move.group(1)
|
||||
|
||||
|
||||
def dump_output(file, data):
|
||||
with open(file, "w") as fp:
|
||||
fp.write(data)
|
||||
|
||||
def main():
|
||||
if not enabled():
|
||||
quit()
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("Missing required arguments", file=sys.stderr)
|
||||
print(__doc__, file=sys.stderr)
|
||||
quit(1)
|
||||
|
||||
OUTPUT_FILE = pathlib.Path(sys.argv[1])
|
||||
|
||||
assert OUTPUT_FILE.parent.exists(), f"parent of {OUTPUT_FILE=} does not exist"
|
||||
|
||||
new_tutors = json.dumps(sorted(list(extract_repo_tutors())), indent=2)
|
||||
if OUTPUT_FILE.exists() and OUTPUT_FILE.is_file():
|
||||
with open(OUTPUT_FILE, "r") as fp:
|
||||
old_tutors = fp.read()
|
||||
else:
|
||||
dump_output(OUTPUT_FILE, new_tutors)
|
||||
return
|
||||
|
||||
if new_tutors != old_tutors:
|
||||
dump_output(OUTPUT_FILE, new_tutors)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in New Issue
Block a user