mirror of
https://github.com/pret/pokefirered.git
synced 2026-05-14 16:20:24 -05:00
Merge pull request #79 from cawtds/time-based-encounters
Add Time based encounters
This commit is contained in:
commit
9945f335f8
39
Makefile
39
Makefile
|
|
@ -175,8 +175,31 @@ MAPJSON := $(TOOLS_DIR)/mapjson/mapjson$(EXE)
|
|||
JSONPROC := $(TOOLS_DIR)/jsonproc/jsonproc$(EXE)
|
||||
TRAINERPROC := $(TOOLS_DIR)/trainerproc/trainerproc$(EXE)
|
||||
PATCHELF := $(TOOLS_DIR)/patchelf/patchelf$(EXE)
|
||||
ROMTEST ?= $(shell { command -v mgba-rom-test || command -v $(TOOLS_DIR)/mgba/mgba-rom-test$(EXE); } 2>/dev/null)
|
||||
ROMTESTHYDRA := $(TOOLS_DIR)/mgba-rom-test-hydra/mgba-rom-test-hydra$(EXE)
|
||||
ifeq ($(shell uname),Darwin)
|
||||
ROMTEST ?= $(shell command -v mgba-rom-test-mac 2>/dev/null || echo $(TOOLS_DIR)/mgba/mgba-rom-test-mac)
|
||||
ROMTESTHYDRA := $(shell command -v mgba-rom-test-hydra 2>/dev/null || echo $(TOOLS_DIR)/mgba-rom-test-hydra/mgba-rom-test-hydra)
|
||||
else ifeq ($(shell uname),Linux)
|
||||
ROMTEST ?= $(shell command -v mgba-rom-test 2>/dev/null || echo $(TOOLS_DIR)/mgba/mgba-rom-test)
|
||||
ROMTESTHYDRA := $(shell command -v mgba-rom-test-hydra 2>/dev/null || echo $(TOOLS_DIR)/mgba-rom-test-hydra/mgba-rom-test-hydra)
|
||||
else
|
||||
ROMTEST ?= $(TOOLS_DIR)/mgba/mgba-rom-test$(EXE)
|
||||
ROMTESTHYDRA := $(TOOLS_DIR)/mgba-rom-test-hydra/mgba-rom-test-hydra$(EXE)
|
||||
endif
|
||||
|
||||
# Learnset helper is a Python script
|
||||
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
|
||||
|
||||
# wild_encounters.h is generated by a Python script
|
||||
WILD_ENCOUNTERS_TOOL_DIR := $(TOOLS_DIR)/wild_encounters
|
||||
AUTO_GEN_TARGETS += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
||||
|
||||
$(DATA_SRC_SUBDIR)/wild_encounters.h: $(DATA_SRC_SUBDIR)/wild_encounters.json $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py $(INCLUDE_DIRS)/config/overworld.h
|
||||
python3 $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py > $@
|
||||
|
||||
$(C_BUILDDIR)/wild_encounter.o: c_dep += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
||||
|
||||
PERL := perl
|
||||
SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c
|
||||
|
|
@ -352,6 +375,7 @@ generated: $(AUTO_GEN_TARGETS)
|
|||
|
||||
clean-generated:
|
||||
-rm -f $(AUTO_GEN_TARGETS)
|
||||
-rm -f $(ALL_LEARNABLES_JSON)
|
||||
|
||||
COMPETITIVE_PARTY_SYNTAX := $(shell PATH="$(PATH)"; echo 'COMPETITIVE_PARTY_SYNTAX' | $(CPP) $(CPPFLAGS) -imacros include/gba/defines.h -imacros include/config/general.h | tail -n1)
|
||||
ifeq ($(COMPETITIVE_PARTY_SYNTAX),1)
|
||||
|
|
@ -441,11 +465,16 @@ $(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 > $@
|
||||
|
||||
MOVES_JSON_DIR := $(TOOLS_DIR)/learnset_helpers/porymoves_files
|
||||
TEACHABLE_DEPS := $(shell find data/ -type f -name '*.inc') $(INCLUDE_DIRS)/constants/tms_hms.h $(C_SUBDIR)/pokemon.c $(wildcard $(MOVES_JSON_DIR)/*.json)
|
||||
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
|
||||
|
||||
$(LEARNSET_HELPERS_BUILD_DIR):
|
||||
@mkdir -p $@
|
||||
|
||||
$(ALL_LEARNABLES_JSON): $(wildcard $(LEARNSET_HELPERS_DATA_DIR)/*.json) | $(LEARNSET_HELPERS_BUILD_DIR)
|
||||
python3 $(LEARNSET_HELPERS_DIR)/make_learnables.py $(LEARNSET_HELPERS_DATA_DIR) $@
|
||||
|
||||
$(DATA_SRC_SUBDIR)/pokemon/teachable_learnsets.h: $(TEACHABLE_DEPS)
|
||||
python3 $(TOOLS_DIR)/learnset_helpers/teachable.py
|
||||
python3 $(LEARNSET_HELPERS_DIR)/make_teachables.py $<
|
||||
|
||||
# Linker script
|
||||
LD_SCRIPT := ld_script_modern.ld
|
||||
|
|
|
|||
|
|
@ -100,8 +100,11 @@ enum TimeOfDay {
|
|||
TIME_DAY,
|
||||
TIME_EVENING,
|
||||
TIME_NIGHT,
|
||||
TIMES_OF_DAY_COUNT,
|
||||
};
|
||||
|
||||
#define TIME_OF_DAY_DEFAULT 0
|
||||
|
||||
enum Season {
|
||||
SEASON_SPRING,
|
||||
SEASON_SUMMER,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,16 @@
|
|||
#define GUARD_WILD_ENCOUNTER_H
|
||||
|
||||
#include "global.h"
|
||||
#include "rtc.h"
|
||||
|
||||
enum WildPokemonArea
|
||||
{
|
||||
WILD_AREA_LAND,
|
||||
WILD_AREA_WATER,
|
||||
WILD_AREA_ROCKS,
|
||||
WILD_AREA_FISHING,
|
||||
WILD_AREA_HIDDEN
|
||||
};
|
||||
|
||||
#define LAND_WILD_COUNT 12
|
||||
#define WATER_WILD_COUNT 5
|
||||
|
|
@ -27,15 +37,25 @@ struct WildPokemonInfo
|
|||
const struct WildPokemon *wildPokemon;
|
||||
};
|
||||
|
||||
struct WildEncounterTypes
|
||||
{
|
||||
const struct WildPokemonInfo *landMonsInfo;
|
||||
const struct WildPokemonInfo *waterMonsInfo;
|
||||
const struct WildPokemonInfo *rockSmashMonsInfo;
|
||||
const struct WildPokemonInfo *fishingMonsInfo;
|
||||
const struct WildPokemonInfo *hiddenMonsInfo;
|
||||
};
|
||||
|
||||
struct WildPokemonHeader
|
||||
{
|
||||
u8 mapGroup;
|
||||
u8 mapNum;
|
||||
const struct WildPokemonInfo *landMonsInfo;
|
||||
const struct WildPokemonInfo *waterMonsInfo;
|
||||
const struct WildPokemonInfo *rockSmashMonsInfo;
|
||||
const struct WildPokemonInfo *hiddenMonsInfo;
|
||||
const struct WildPokemonInfo *fishingMonsInfo;
|
||||
|
||||
#if OW_TIME_OF_DAY_ENCOUNTERS
|
||||
const struct WildEncounterTypes encounterTypes[TIMES_OF_DAY_COUNT];
|
||||
#else
|
||||
const struct WildEncounterTypes encounterTypes[1];
|
||||
#endif
|
||||
};
|
||||
|
||||
extern const struct WildPokemonHeader gWildMonHeaders[];
|
||||
|
|
@ -66,5 +86,6 @@ u8 ChooseWildMonIndex_Land(void);
|
|||
u8 ChooseWildMonIndex_WaterRock(void);
|
||||
u8 ChooseHiddenMonIndex(void);
|
||||
bool32 MapHasNoEncounterData(void);
|
||||
enum TimeOfDay GetTimeOfDayForEncounters(u32 headerId, enum WildPokemonArea area);
|
||||
|
||||
#endif // GUARD_WILD_ENCOUNTER_H
|
||||
|
|
|
|||
|
|
@ -1,12 +1,6 @@
|
|||
# JSON files are run through jsonproc, which is a tool that converts JSON data to an output file
|
||||
# based on an Inja template. https://github.com/pantor/inja
|
||||
|
||||
AUTO_GEN_TARGETS += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
||||
$(DATA_SRC_SUBDIR)/wild_encounters.h: $(DATA_SRC_SUBDIR)/wild_encounters.json $(DATA_SRC_SUBDIR)/wild_encounters.json.txt
|
||||
$(JSONPROC) $^ $@
|
||||
|
||||
$(C_BUILDDIR)/wild_encounter.o: c_dep += $(DATA_SRC_SUBDIR)/wild_encounters.h
|
||||
|
||||
AUTO_GEN_TARGETS += $(DATA_SRC_SUBDIR)/region_map/region_map_entries.h
|
||||
$(DATA_SRC_SUBDIR)/region_map/region_map_entries.h: $(DATA_SRC_SUBDIR)/region_map/region_map_sections.json $(DATA_SRC_SUBDIR)/region_map/region_map_sections.json.txt
|
||||
$(JSONPROC) $^ $@
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -97,11 +97,11 @@ const struct WildPokemonHeader {{ wild_encounter_group.label }}[] =
|
|||
{
|
||||
.mapGroup = {% if wild_encounter_group.for_maps %}MAP_GROUP({{ removePrefix(encounter.map, "MAP_") }}){% else %}0{% endif %},
|
||||
.mapNum = {% if wild_encounter_group.for_maps %}MAP_NUM({{ removePrefix(encounter.map, "MAP_") }}){% else %}{{ loop.index1 }}{% endif %},
|
||||
.landMonsInfo = {% if existsIn(encounter, "land_mons") %}&{{ encounter.base_label }}_LandMonsInfo{% else %}NULL{% endif %},
|
||||
.waterMonsInfo = {% if existsIn(encounter, "water_mons") %}&{{ encounter.base_label }}_WaterMonsInfo{% else %}NULL{% endif %},
|
||||
.rockSmashMonsInfo = {% if existsIn(encounter, "rock_smash_mons") %}&{{ encounter.base_label }}_RockSmashMonsInfo{% else %}NULL{% endif %},
|
||||
.fishingMonsInfo = {% if existsIn(encounter, "fishing_mons") %}&{{ encounter.base_label }}_FishingMonsInfo{% else %}NULL{% endif %},
|
||||
.hiddenMonsInfo = {% if existsIn(encounter, "hidden_mons") %}&{{ encounter.base_label }}_HiddenMonsInfo{% else %}NULL{% endif %},
|
||||
.encounterTypes[timeOfDay].landMonsInfo = {% if existsIn(encounter, "land_mons") %}&{{ encounter.base_label }}_LandMonsInfo{% else %}NULL{% endif %},
|
||||
.encounterTypes[timeOfDay].waterMonsInfo = {% if existsIn(encounter, "water_mons") %}&{{ encounter.base_label }}_WaterMonsInfo{% else %}NULL{% endif %},
|
||||
.encounterTypes[timeOfDay].rockSmashMonsInfo = {% if existsIn(encounter, "rock_smash_mons") %}&{{ encounter.base_label }}_RockSmashMonsInfo{% else %}NULL{% endif %},
|
||||
.encounterTypes[timeOfDay].fishingMonsInfo = {% if existsIn(encounter, "fishing_mons") %}&{{ encounter.base_label }}_FishingMonsInfo{% else %}NULL{% endif %},
|
||||
.encounterTypes[timeOfDay].hiddenMonsInfo = {% if existsIn(encounter, "hidden_mons") %}&{{ encounter.base_label }}_HiddenMonsInfo{% else %}NULL{% endif %},
|
||||
},
|
||||
{% if contains(encounter.base_label, "FireRed") or contains(encounter.base_label, "LeafGreen") %}
|
||||
#endif
|
||||
|
|
@ -110,11 +110,11 @@ const struct WildPokemonHeader {{ wild_encounter_group.label }}[] =
|
|||
{
|
||||
.mapGroup = MAP_GROUP(UNDEFINED),
|
||||
.mapNum = MAP_NUM(UNDEFINED),
|
||||
.landMonsInfo = NULL,
|
||||
.waterMonsInfo = NULL,
|
||||
.rockSmashMonsInfo = NULL,
|
||||
.fishingMonsInfo = NULL,
|
||||
.hiddenMonsInfo = NULL,
|
||||
.encounterTypes[timeOfDay].landMonsInfo = NULL,
|
||||
.encounterTypes[timeOfDay].waterMonsInfo = NULL,
|
||||
.encounterTypes[timeOfDay].rockSmashMonsInfo = NULL,
|
||||
.encounterTypes[timeOfDay].fishingMonsInfo = NULL,
|
||||
.encounterTypes[timeOfDay].hiddenMonsInfo = NULL,
|
||||
},
|
||||
};
|
||||
## endfor
|
||||
|
|
|
|||
40
src/dexnav.c
40
src/dexnav.c
|
|
@ -36,6 +36,7 @@
|
|||
#include "pokemon_summary_screen.h"
|
||||
#include "random.h"
|
||||
#include "region_map.h"
|
||||
#include "rtc.h"
|
||||
#include "scanline_effect.h"
|
||||
#include "script.h"
|
||||
#include "script_pokemon_util.h"
|
||||
|
|
@ -1516,9 +1517,7 @@ static u8 DexNavGeneratePotential(u8 searchLevel)
|
|||
static u8 GetEncounterLevelFromMapData(u16 species, u8 environment)
|
||||
{
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
const struct WildPokemonInfo *landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
|
||||
const struct WildPokemonInfo *waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||
const struct WildPokemonInfo *hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo;
|
||||
enum TimeOfDay timeOfDay;
|
||||
u8 min = 100;
|
||||
u8 max = 0;
|
||||
u8 i;
|
||||
|
|
@ -1526,6 +1525,9 @@ static u8 GetEncounterLevelFromMapData(u16 species, u8 environment)
|
|||
switch (environment)
|
||||
{
|
||||
case ENCOUNTER_TYPE_LAND: // grass
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
const struct WildPokemonInfo *landMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
|
||||
if (landMonsInfo == NULL)
|
||||
return MON_LEVEL_NONEXISTENT; //Hidden pokemon should only appear on walkable tiles or surf tiles
|
||||
|
||||
|
|
@ -1539,6 +1541,9 @@ static u8 GetEncounterLevelFromMapData(u16 species, u8 environment)
|
|||
}
|
||||
break;
|
||||
case ENCOUNTER_TYPE_WATER: //water
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
const struct WildPokemonInfo *waterMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
|
||||
if (waterMonsInfo == NULL)
|
||||
return MON_LEVEL_NONEXISTENT; //Hidden pokemon should only appear on walkable tiles or surf tiles
|
||||
|
||||
|
|
@ -1552,6 +1557,8 @@ static u8 GetEncounterLevelFromMapData(u16 species, u8 environment)
|
|||
}
|
||||
break;
|
||||
case ENCOUNTER_TYPE_HIDDEN:
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_HIDDEN);
|
||||
const struct WildPokemonInfo *hiddenMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
if (hiddenMonsInfo == NULL)
|
||||
return MON_LEVEL_NONEXISTENT;
|
||||
|
||||
|
|
@ -1728,7 +1735,8 @@ static bool8 CapturedAllLandMons(u16 headerId)
|
|||
{
|
||||
u16 i, species;
|
||||
int count = 0;
|
||||
const struct WildPokemonInfo* landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
const struct WildPokemonInfo* landMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
|
||||
if (landMonsInfo != NULL)
|
||||
{
|
||||
|
|
@ -1761,7 +1769,8 @@ static bool8 CapturedAllWaterMons(u16 headerId)
|
|||
u32 i;
|
||||
u16 species;
|
||||
u8 count = 0;
|
||||
const struct WildPokemonInfo* waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
const struct WildPokemonInfo* waterMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
|
||||
if (waterMonsInfo != NULL)
|
||||
{
|
||||
|
|
@ -1792,7 +1801,8 @@ static bool8 CapturedAllHiddenMons(u16 headerId)
|
|||
u32 i;
|
||||
u16 species;
|
||||
u8 count = 0;
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo;
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_HIDDEN);
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
|
||||
if (hiddenMonsInfo != NULL)
|
||||
{
|
||||
|
|
@ -1937,9 +1947,14 @@ static void DexNavLoadEncounterData(void)
|
|||
u16 species;
|
||||
u32 i;
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
const struct WildPokemonInfo* landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
|
||||
const struct WildPokemonInfo* waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo;
|
||||
enum TimeOfDay timeOfDay;
|
||||
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
const struct WildPokemonInfo* landMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
const struct WildPokemonInfo* waterMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_HIDDEN);
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
|
||||
// nop struct data
|
||||
memset(sDexNavUiDataPtr->landSpecies, 0, sizeof(sDexNavUiDataPtr->landSpecies));
|
||||
|
|
@ -2515,7 +2530,8 @@ bool8 TryFindHiddenPokemon(void)
|
|||
u16 species;
|
||||
u8 environment;
|
||||
u8 taskId;
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].hiddenMonsInfo;
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_HIDDEN);
|
||||
const struct WildPokemonInfo* hiddenMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
bool8 isHiddenMon = FALSE;
|
||||
|
||||
// while you can still technically find hidden pokemon if there are not hidden-only pokemon on a map,
|
||||
|
|
@ -2540,7 +2556,7 @@ bool8 TryFindHiddenPokemon(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
species = gWildMonHeaders[headerId].landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
|
||||
species = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
|
||||
environment = ENCOUNTER_TYPE_LAND;
|
||||
}
|
||||
break;
|
||||
|
|
@ -2558,7 +2574,7 @@ bool8 TryFindHiddenPokemon(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
species = gWildMonHeaders[headerId].waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
|
||||
species = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
|
||||
environment = ENCOUNTER_TYPE_WATER;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,9 +113,10 @@ void AdvanceScript(void)
|
|||
|
||||
u32 FakeRtc_GetSecondsRatio(void)
|
||||
{
|
||||
return (OW_ALTERED_TIME_RATIO == GEN_8_PLA) ? 60 :
|
||||
(OW_ALTERED_TIME_RATIO == GEN_9) ? 20 :
|
||||
1;
|
||||
return (OW_ALTERED_TIME_RATIO == GEN_8_PLA) ? 60 :
|
||||
(OW_ALTERED_TIME_RATIO == GEN_9) ? 20 :
|
||||
(OW_ALTERED_TIME_RATIO == TIME_DEBUG) ? 1 :
|
||||
1;
|
||||
}
|
||||
|
||||
STATIC_ASSERT((OW_FLAG_PAUSE_TIME == 0 || OW_USE_FAKE_RTC == TRUE), FakeRtcMustBeTrueToPauseTime);
|
||||
|
|
|
|||
|
|
@ -24,14 +24,6 @@
|
|||
|
||||
#define MAX_ENCOUNTER_RATE 1600
|
||||
|
||||
enum
|
||||
{
|
||||
WILD_AREA_LAND,
|
||||
WILD_AREA_WATER,
|
||||
WILD_AREA_ROCKS,
|
||||
WILD_AREA_FISHING,
|
||||
};
|
||||
|
||||
#define WILD_CHECK_REPEL 0x1
|
||||
#define WILD_CHECK_KEEN_EYE 0x2
|
||||
|
||||
|
|
@ -289,6 +281,40 @@ u16 GetCurrentMapWildMonHeaderId(void)
|
|||
return HEADER_NONE;
|
||||
}
|
||||
|
||||
enum TimeOfDay GetTimeOfDayForEncounters(u32 headerId, enum WildPokemonArea area)
|
||||
{
|
||||
const struct WildPokemonInfo *wildMonInfo;
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDay();
|
||||
|
||||
if (!OW_TIME_OF_DAY_ENCOUNTERS)
|
||||
return TIME_OF_DAY_DEFAULT;
|
||||
|
||||
switch (area)
|
||||
{
|
||||
default:
|
||||
case WILD_AREA_LAND:
|
||||
wildMonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_WATER:
|
||||
wildMonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_ROCKS:
|
||||
wildMonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].rockSmashMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_FISHING:
|
||||
wildMonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].fishingMonsInfo;
|
||||
break;
|
||||
case WILD_AREA_HIDDEN:
|
||||
wildMonInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].hiddenMonsInfo;
|
||||
break;
|
||||
}
|
||||
|
||||
if (wildMonInfo == NULL && !OW_TIME_OF_DAY_DISABLE_FALLBACK)
|
||||
return OW_TIME_OF_DAY_FALLBACK;
|
||||
else
|
||||
return timeOfDay;
|
||||
}
|
||||
|
||||
static bool8 UnlockedTanobyOrAreNotInTanoby(void)
|
||||
{
|
||||
if (FlagGet(FLAG_SYS_UNLOCKED_TANOBY_RUINS))
|
||||
|
|
@ -539,13 +565,14 @@ static bool8 DoGlobalWildEncounterDiceRoll(void)
|
|||
bool8 TryStandardWildLandEncounter(u16 headerId, u32 currMetatileAttrs, u16 previousMetatileBehavior)
|
||||
{
|
||||
struct Roamer * roamer;
|
||||
if (gWildMonHeaders[headerId].landMonsInfo == NULL)
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo == NULL)
|
||||
return FALSE;
|
||||
if (previousMetatileBehavior != ExtractMetatileAttribute(currMetatileAttrs, METATILE_ATTRIBUTE_BEHAVIOR) && !DoGlobalWildEncounterDiceRoll())
|
||||
return FALSE;
|
||||
if (DoWildEncounterRateTest(gWildMonHeaders[headerId].landMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
if (DoWildEncounterRateTest(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
{
|
||||
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].landMonsInfo->encounterRate);
|
||||
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate);
|
||||
return FALSE;
|
||||
}
|
||||
if (TryStartRoamerEncounter() == TRUE)
|
||||
|
|
@ -561,12 +588,12 @@ bool8 TryStandardWildLandEncounter(u16 headerId, u32 currMetatileAttrs, u16 prev
|
|||
}
|
||||
|
||||
// try a regular wild land encounter
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_REPEL) == TRUE)
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_REPEL) == TRUE)
|
||||
{
|
||||
if (TryDoDoubleWildBattle())
|
||||
{
|
||||
struct Pokemon mon1 = gEnemyParty[0];
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE);
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE);
|
||||
gEnemyParty[1] = mon1;
|
||||
StartDoubleWildBattle();
|
||||
}
|
||||
|
|
@ -576,20 +603,21 @@ bool8 TryStandardWildLandEncounter(u16 headerId, u32 currMetatileAttrs, u16 prev
|
|||
}
|
||||
return TRUE;
|
||||
}
|
||||
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].landMonsInfo->encounterRate);
|
||||
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 TryStandardWildSurfEncounter(u16 headerId, u32 currMetatileAttrs, u16 previousMetatileBehavior)
|
||||
{
|
||||
struct Roamer * roamer;
|
||||
if (gWildMonHeaders[headerId].waterMonsInfo == NULL)
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo == NULL)
|
||||
return FALSE;
|
||||
if (previousMetatileBehavior != ExtractMetatileAttribute(currMetatileAttrs, METATILE_ATTRIBUTE_BEHAVIOR) && !DoGlobalWildEncounterDiceRoll())
|
||||
return FALSE;
|
||||
if (DoWildEncounterRateTest(gWildMonHeaders[headerId].waterMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
if (DoWildEncounterRateTest(gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo->encounterRate, FALSE) != TRUE)
|
||||
{
|
||||
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].waterMonsInfo->encounterRate);
|
||||
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo->encounterRate);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -605,13 +633,13 @@ bool8 TryStandardWildSurfEncounter(u16 headerId, u32 currMetatileAttrs, u16 prev
|
|||
return TRUE;
|
||||
}
|
||||
// try a regular surfing encounter
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_REPEL) == TRUE)
|
||||
if (TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_REPEL) == TRUE)
|
||||
{
|
||||
gIsSurfingEncounter = TRUE;
|
||||
if (TryDoDoubleWildBattle())
|
||||
{
|
||||
struct Pokemon mon1 = gEnemyParty[0];
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_KEEN_EYE);
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_KEEN_EYE);
|
||||
gEnemyParty[1] = mon1;
|
||||
StartDoubleWildBattle();
|
||||
}
|
||||
|
|
@ -622,7 +650,7 @@ bool8 TryStandardWildSurfEncounter(u16 headerId, u32 currMetatileAttrs, u16 prev
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].waterMonsInfo->encounterRate);
|
||||
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo->encounterRate);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -648,14 +676,15 @@ bool8 StandardWildEncounter(u32 currMetatileAttrs, u16 previousMetatileBehavior)
|
|||
|
||||
void RockSmashWildEncounter(void)
|
||||
{
|
||||
u16 headerIdx = GetCurrentMapWildMonHeaderId();
|
||||
if (headerIdx == HEADER_NONE)
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_ROCKS);
|
||||
if (headerId == HEADER_NONE)
|
||||
gSpecialVar_Result = FALSE;
|
||||
else if (gWildMonHeaders[headerIdx].rockSmashMonsInfo == NULL)
|
||||
else if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].rockSmashMonsInfo == NULL)
|
||||
gSpecialVar_Result = FALSE;
|
||||
else if (DoWildEncounterRateTest(gWildMonHeaders[headerIdx].rockSmashMonsInfo->encounterRate, TRUE) != TRUE)
|
||||
else if (DoWildEncounterRateTest(gWildMonHeaders[headerId].encounterTypes[timeOfDay].rockSmashMonsInfo->encounterRate, TRUE) != TRUE)
|
||||
gSpecialVar_Result = FALSE;
|
||||
else if (TryGenerateWildMon(gWildMonHeaders[headerIdx].rockSmashMonsInfo, WILD_AREA_ROCKS, WILD_CHECK_REPEL) == TRUE)
|
||||
else if (TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].rockSmashMonsInfo, WILD_AREA_ROCKS, WILD_CHECK_REPEL) == TRUE)
|
||||
{
|
||||
StartWildBattle();
|
||||
gSpecialVar_Result = TRUE;
|
||||
|
|
@ -668,6 +697,7 @@ bool8 SweetScentWildEncounter(void)
|
|||
{
|
||||
s16 x, y;
|
||||
u16 headerId;
|
||||
enum TimeOfDay timeOfDay;
|
||||
|
||||
PlayerGetDestCoords(&x, &y);
|
||||
headerId = GetCurrentMapWildMonHeaderId();
|
||||
|
|
@ -682,11 +712,12 @@ bool8 SweetScentWildEncounter(void)
|
|||
StartRoamerBattle();
|
||||
return TRUE;
|
||||
}
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
|
||||
if (gWildMonHeaders[headerId].landMonsInfo == NULL)
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo == NULL)
|
||||
return FALSE;
|
||||
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, 0);
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo, WILD_AREA_LAND, 0);
|
||||
|
||||
StartWildBattle();
|
||||
return TRUE;
|
||||
|
|
@ -699,10 +730,11 @@ bool8 SweetScentWildEncounter(void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (gWildMonHeaders[headerId].waterMonsInfo == NULL)
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo == NULL)
|
||||
return FALSE;
|
||||
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, 0);
|
||||
TryGenerateWildMon(gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo, WILD_AREA_WATER, 0);
|
||||
StartWildBattle();
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -712,10 +744,12 @@ bool8 SweetScentWildEncounter(void)
|
|||
|
||||
bool8 DoesCurrentMapHaveFishingMons(void)
|
||||
{
|
||||
u16 headerIdx = GetCurrentMapWildMonHeaderId();
|
||||
if (headerIdx == HEADER_NONE)
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_FISHING);
|
||||
|
||||
if (headerId == HEADER_NONE)
|
||||
return FALSE;
|
||||
if (gWildMonHeaders[headerIdx].fishingMonsInfo == NULL)
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].fishingMonsInfo == NULL)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -738,15 +772,18 @@ static void UpdateChainFishingStreak()
|
|||
|
||||
void FishingWildEncounter(u8 rod)
|
||||
{
|
||||
u32 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_FISHING);
|
||||
gIsFishingEncounter = TRUE;
|
||||
GenerateFishingEncounter(gWildMonHeaders[GetCurrentMapWildMonHeaderId()].fishingMonsInfo, rod);
|
||||
GenerateFishingEncounter(gWildMonHeaders[headerId].encounterTypes[timeOfDay].fishingMonsInfo, rod);
|
||||
IncrementGameStat(GAME_STAT_FISHING_CAPTURES);
|
||||
StartWildBattle();
|
||||
}
|
||||
|
||||
u16 GetLocalWildMon(bool8 *isWaterMon)
|
||||
{
|
||||
u16 headerId;
|
||||
u32 headerId;
|
||||
enum TimeOfDay timeOfDay;
|
||||
const struct WildPokemonInfo *landMonsInfo;
|
||||
const struct WildPokemonInfo *waterMonsInfo;
|
||||
|
||||
|
|
@ -754,8 +791,11 @@ u16 GetLocalWildMon(bool8 *isWaterMon)
|
|||
headerId = GetCurrentMapWildMonHeaderId();
|
||||
if (headerId == HEADER_NONE)
|
||||
return SPECIES_NONE;
|
||||
landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
|
||||
waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
landMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo;
|
||||
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
waterMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
// Neither
|
||||
if (landMonsInfo == NULL && waterMonsInfo == NULL)
|
||||
return SPECIES_NONE;
|
||||
|
|
@ -783,10 +823,12 @@ u16 GetLocalWildMon(bool8 *isWaterMon)
|
|||
u16 GetLocalWaterMon(void)
|
||||
{
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay;
|
||||
|
||||
if (headerId != HEADER_NONE)
|
||||
{
|
||||
const struct WildPokemonInfo * waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
const struct WildPokemonInfo * waterMonsInfo = gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo;
|
||||
|
||||
if (waterMonsInfo)
|
||||
return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
|
||||
|
|
@ -982,28 +1024,31 @@ static u16 WildEncounterRandom(void)
|
|||
|
||||
static u8 GetMapBaseEncounterCooldown(u8 encounterType)
|
||||
{
|
||||
u16 headerIdx = GetCurrentMapWildMonHeaderId();
|
||||
if (headerIdx == HEADER_NONE)
|
||||
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||
enum TimeOfDay timeOfDay;
|
||||
if (headerId == HEADER_NONE)
|
||||
return 0xFF;
|
||||
if (encounterType == TILE_ENCOUNTER_LAND)
|
||||
{
|
||||
if (gWildMonHeaders[headerIdx].landMonsInfo == NULL)
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo == NULL)
|
||||
return 0xFF;
|
||||
if (gWildMonHeaders[headerIdx].landMonsInfo->encounterRate >= 80)
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate >= 80)
|
||||
return 0;
|
||||
if (gWildMonHeaders[headerIdx].landMonsInfo->encounterRate < 10)
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate < 10)
|
||||
return 8;
|
||||
return 8 - (gWildMonHeaders[headerIdx].landMonsInfo->encounterRate / 10);
|
||||
return 8 - (gWildMonHeaders[headerId].encounterTypes[timeOfDay].landMonsInfo->encounterRate / 10);
|
||||
}
|
||||
if (encounterType == TILE_ENCOUNTER_WATER)
|
||||
{
|
||||
if (gWildMonHeaders[headerIdx].waterMonsInfo == NULL)
|
||||
timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_WATER);
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo == NULL)
|
||||
return 0xFF;
|
||||
if (gWildMonHeaders[headerIdx].waterMonsInfo->encounterRate >= 80)
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo->encounterRate >= 80)
|
||||
return 0;
|
||||
if (gWildMonHeaders[headerIdx].waterMonsInfo->encounterRate < 10)
|
||||
if (gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo->encounterRate < 10)
|
||||
return 8;
|
||||
return 8 - (gWildMonHeaders[headerIdx].waterMonsInfo->encounterRate / 10);
|
||||
return 8 - (gWildMonHeaders[headerId].encounterTypes[timeOfDay].waterMonsInfo->encounterRate / 10);
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "overworld.h"
|
||||
#include "pokedex.h"
|
||||
#include "pokedex_area_markers.h"
|
||||
#include "rtc.h"
|
||||
#include "constants/region_map_sections.h"
|
||||
#include "constants/maps.h"
|
||||
|
||||
|
|
@ -17,7 +18,7 @@ struct RoamerPair
|
|||
|
||||
static s32 GetRoamerIndex(u16 species);
|
||||
static s32 GetRoamerPokedexAreaMarkers(u16 species, struct Subsprite * subsprites);
|
||||
static bool32 IsSpeciesOnMap(const struct WildPokemonHeader * data, s32 species);
|
||||
static bool32 IsSpeciesOnMap(const struct WildPokemonHeader * data, u32 headerId, s32 species);
|
||||
static bool32 IsSpeciesInEncounterTable(const struct WildPokemonInfo * pokemon, s32 species, s32 count);
|
||||
static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header);
|
||||
static bool32 FindDexAreaByMapSec(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p);
|
||||
|
|
@ -190,7 +191,7 @@ s32 GetSpeciesPokedexAreaMarkers(u16 species, struct Subsprite * subsprites)
|
|||
if (alteringCaveNum != alteringCaveCount - 1)
|
||||
continue;
|
||||
}
|
||||
if (IsSpeciesOnMap(&gWildMonHeaders[i], species))
|
||||
if (IsSpeciesOnMap(&gWildMonHeaders[i], i, species))
|
||||
{
|
||||
// Search for all dex areas associated with this MAPSEC.
|
||||
// In the vanilla game each MAPSEC only has at most one DEX_AREA.
|
||||
|
|
@ -259,21 +260,22 @@ static s32 GetRoamerPokedexAreaMarkers(u16 species, struct Subsprite * subsprite
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool32 IsSpeciesOnMap(const struct WildPokemonHeader * data, s32 species)
|
||||
static bool32 IsSpeciesOnMap(const struct WildPokemonHeader * data, u32 headerId, s32 species)
|
||||
{
|
||||
if (IsSpeciesInEncounterTable(data->landMonsInfo, species, LAND_WILD_COUNT))
|
||||
enum TimeOfDay timeOfDay = GetTimeOfDayForEncounters(headerId, WILD_AREA_LAND);
|
||||
if (IsSpeciesInEncounterTable(data->encounterTypes[timeOfDay].landMonsInfo, species, LAND_WILD_COUNT))
|
||||
return TRUE;
|
||||
if (IsSpeciesInEncounterTable(data->waterMonsInfo, species, WATER_WILD_COUNT))
|
||||
if (IsSpeciesInEncounterTable(data->encounterTypes[timeOfDay].waterMonsInfo, species, WATER_WILD_COUNT))
|
||||
return TRUE;
|
||||
// When searching the fishing encounters, this incorrectly uses the size of the land encounters.
|
||||
// As a result it's reading out of bounds of the fishing encounters tables.
|
||||
#ifdef BUGFIX
|
||||
if (IsSpeciesInEncounterTable(data->fishingMonsInfo, species, FISH_WILD_COUNT))
|
||||
if (IsSpeciesInEncounterTable(data->encounterTypes[timeOfDay].fishingMonsInfo, species, FISH_WILD_COUNT))
|
||||
#else
|
||||
if (IsSpeciesInEncounterTable(data->fishingMonsInfo, species, LAND_WILD_COUNT))
|
||||
if (IsSpeciesInEncounterTable(data->encounterTypes[timeOfDay].fishingMonsInfo, species, LAND_WILD_COUNT))
|
||||
#endif
|
||||
return TRUE;
|
||||
if (IsSpeciesInEncounterTable(data->rockSmashMonsInfo, species, ROCK_WILD_COUNT))
|
||||
if (IsSpeciesInEncounterTable(data->encounterTypes[timeOfDay].rockSmashMonsInfo, species, ROCK_WILD_COUNT))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -45,13 +45,6 @@ int main(int argc, char *argv[])
|
|||
return "//\n// DO NOT MODIFY THIS FILE! It is auto-generated from " + jsonfilepath +" and Inja template " + templateFilepath + "\n//\n";
|
||||
});
|
||||
|
||||
env.add_callback("contains", 2, [](Arguments& args) {
|
||||
string word = args.at(0)->get<string>();
|
||||
string check = args.at(1)->get<string>();
|
||||
|
||||
return word.find(check) != std::string::npos;
|
||||
});
|
||||
|
||||
env.add_callback("subtract", 2, [](Arguments& args) {
|
||||
int minuend = args.at(0)->get<int>();
|
||||
int subtrahend = args.at(1)->get<int>();
|
||||
|
|
|
|||
62
tools/learnset_helpers/make_learnables.py
Executable file
62
tools/learnset_helpers/make_learnables.py
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Usage: python3 make_learnables.py INPUTS_DIR OUTPUT_FILE
|
||||
|
||||
Build a primary store of learnable moves for each species based on input documents. This script
|
||||
is meant to be run to generate a pre-processed store of data that should not change very much;
|
||||
thus, it can safely be pre-computed in order to speed up incremental builds for end-users.
|
||||
"""
|
||||
|
||||
from functools import reduce
|
||||
|
||||
import json
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
|
||||
def from_single(fname: pathlib.Path) -> dict[str, set[str]]:
|
||||
with open(fname, "r") as fp:
|
||||
return {
|
||||
species: set([level_up["Move"] for level_up in by_method["LevelMoves"]])
|
||||
| set([move for move in by_method["TMMoves"]])
|
||||
| set([move for move in by_method["EggMoves"]])
|
||||
| set([move for move in by_method["TutorMoves"]])
|
||||
for species, by_method in json.load(fp).items()
|
||||
}
|
||||
|
||||
|
||||
def from_batch(dir: pathlib.Path) -> dict[str, set[str]]:
|
||||
return reduce(
|
||||
lambda acc, single: {
|
||||
species: acc.get(species, set()) | single.get(species, set())
|
||||
for species in acc.keys() | single.keys()
|
||||
},
|
||||
map(from_single, dir.glob("*.json")),
|
||||
{},
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print("Missing required arguments", file=sys.stderr)
|
||||
print(__doc__, file=sys.stderr)
|
||||
quit(1)
|
||||
|
||||
INPUTS_DIR = pathlib.Path(sys.argv[1])
|
||||
OUTPUT_FILE = pathlib.Path(sys.argv[2])
|
||||
|
||||
assert INPUTS_DIR.exists(), f"{INPUTS_DIR=} does not exist"
|
||||
assert INPUTS_DIR.is_dir(), f"{INPUTS_DIR=} is not a directory"
|
||||
assert OUTPUT_FILE.parent.exists(), f"parent of {OUTPUT_FILE=} does not exist"
|
||||
|
||||
batch = {
|
||||
species: list(sorted(learnables))
|
||||
for species, learnables in from_batch(INPUTS_DIR).items()
|
||||
}
|
||||
with open(OUTPUT_FILE, "w") as fp:
|
||||
json.dump(batch, fp, indent=2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
233
tools/learnset_helpers/make_teachables.py
Normal file
233
tools/learnset_helpers/make_teachables.py
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Usage: python3 make_teachable.py SOURCE_LEARNSETS_JSON
|
||||
|
||||
Build a C-header defining the set of teachable moves for each configured-on
|
||||
species-family based on the learnable moves defined in SOURCE_LEARNSETS_JSON.
|
||||
|
||||
A move is "teachable" if it is:
|
||||
1. Can be taught by some Move Tutor in the overworld, which is identified by
|
||||
using the ChooseMonForMoveTutor special in a script and setting VAR_0x8005
|
||||
to the offered MOVE constant. (e.g., MOVE_SWAGGER)
|
||||
2. Assigned to some TM or HM in include/constants/tms_hms.h using the
|
||||
FOREACH_TM macro.
|
||||
3. Not a universal move, as defined by sUniversalMoves in src/pokemon.c.
|
||||
|
||||
For a given species, a move is considered teachable to that species if:
|
||||
1. The species is not NONE -- which learns nothing -- nor MEW -- which
|
||||
learns everything.
|
||||
2. The species can learn the move via *any* method within any Expansion-
|
||||
supported game.
|
||||
"""
|
||||
|
||||
from itertools import chain
|
||||
from textwrap import dedent
|
||||
|
||||
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_.*)")
|
||||
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]*?};")
|
||||
SNAKIFY_PAT = re.compile(r"(?!^)([A-Z]+)")
|
||||
TUTOR_ARRAY_ENABLED_PAT = re.compile(r"#define\s+P_TUTOR_MOVES_ARRAY\s+(?P<cfg_val>[^ ]*)")
|
||||
|
||||
|
||||
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 extract_repo_tms() -> typing.Generator[str, None, None]:
|
||||
"""
|
||||
Yield MOVE constants assigned to a TM or HM in the user's repo.
|
||||
"""
|
||||
with open("./include/constants/tms_hms.h", "r") as tmshms_fp:
|
||||
tmshms = tmshms_fp.read()
|
||||
match_it = TMHM_MACRO_PAT.finditer(tmshms)
|
||||
if not match_it:
|
||||
return
|
||||
|
||||
for match in match_it:
|
||||
yield f"MOVE_{match.group(1)}"
|
||||
|
||||
|
||||
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 prepare_output(all_learnables: dict[str, set[str]], repo_teachables: set[str], header: str) -> str:
|
||||
"""
|
||||
Build the file content for teachable_learnsets.h.
|
||||
"""
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", "r") as teachables_fp:
|
||||
old = teachables_fp.read()
|
||||
|
||||
cursor = 0
|
||||
new = header + dedent("""
|
||||
static const u16 sNoneTeachableLearnset[] = {
|
||||
MOVE_UNAVAILABLE,
|
||||
};
|
||||
""")
|
||||
|
||||
joinpat = ",\n "
|
||||
for species in TEACHABLE_ARRAY_DECL_PAT.finditer(old):
|
||||
match_b, match_e = species.span()
|
||||
species_upper = SNAKIFY_PAT.sub(r"_\1", species.group("name")).upper()
|
||||
if species_upper == "NONE":
|
||||
# NONE is hard-coded to be at the start of the file to keep this code simple.
|
||||
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
|
||||
|
||||
repo_species_teachables = filter(lambda m: m in repo_teachables, all_learnables[species_upper])
|
||||
|
||||
new += old[cursor:match_b]
|
||||
new += "\n".join([
|
||||
f"{species.group('decl')} = {{",
|
||||
f" {joinpat.join(chain(repo_species_teachables, ('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:"
|
||||
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))
|
||||
|
||||
lines = [
|
||||
"//",
|
||||
"// DO NOT MODIFY THIS FILE! It is auto-generated by tools/learnset_helpers/make_teachables.py",
|
||||
"//",
|
||||
"",
|
||||
f"// {'*' * h_align} //",
|
||||
f"// {tmhm_title: >{h_align}} //",
|
||||
]
|
||||
lines.extend([f"// - {move: <{h_align - 2}} //" for move in tmshms])
|
||||
lines.extend([
|
||||
f"// {'*' * h_align} //",
|
||||
f"// {tutor_title: <{h_align}} //",
|
||||
])
|
||||
lines.extend([f"// - {move: <{h_align - 2}} //" for move in sorted(tutors)])
|
||||
lines.extend([
|
||||
f"// {'*' * h_align} //",
|
||||
f"// {universals_title: <{h_align}} //",
|
||||
])
|
||||
lines.extend([f"// - {move: <{h_align - 2}} //" for move in universals])
|
||||
lines.extend([
|
||||
f"// {'*' * h_align} //",
|
||||
"",
|
||||
])
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
SOURCE_LEARNSETS_JSON = pathlib.Path(sys.argv[1])
|
||||
|
||||
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()
|
||||
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)
|
||||
))
|
||||
|
||||
create_tutor_moves_array(repo_tutors)
|
||||
|
||||
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_LEARNSETS_JSON, "r") as source_fp:
|
||||
all_learnables = json.load(source_fp)
|
||||
|
||||
content = prepare_output(all_learnables, repo_teachables, header)
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", "w") as teachables_fp:
|
||||
teachables_fp.write(content)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -6536,7 +6536,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_COVET",
|
||||
|
|
@ -6687,7 +6687,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_COVET",
|
||||
|
|
@ -7754,7 +7754,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_POWER_TRICK",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -7890,7 +7890,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_POWER_TRICK",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -8033,7 +8033,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_POWER_TRICK",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -13164,7 +13164,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
],
|
||||
|
|
@ -25781,7 +25781,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -25930,7 +25930,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -31544,7 +31544,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BOUNCE",
|
||||
|
|
@ -31677,7 +31677,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BOUNCE",
|
||||
|
|
@ -31834,7 +31834,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BLAST_BURN",
|
||||
|
|
@ -35812,7 +35812,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -35943,7 +35943,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -36099,7 +36099,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -36155,7 +36155,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 25,
|
||||
|
|
@ -36301,7 +36301,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 27,
|
||||
|
|
@ -37260,7 +37260,7 @@
|
|||
"MOVE_HEAD_SMASH",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -37395,7 +37395,7 @@
|
|||
"MOVE_HEAD_SMASH",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -37551,7 +37551,7 @@
|
|||
"MOVE_HEAD_SMASH",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -40230,7 +40230,7 @@
|
|||
"MOVE_PSYCHO_CUT",
|
||||
"MOVE_RAPID_SPIN",
|
||||
"MOVE_ROLE_PLAY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WATER_PULSE",
|
||||
"MOVE_WISH"
|
||||
|
|
@ -40775,7 +40775,7 @@
|
|||
"MOVE_MAGICAL_LEAF",
|
||||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -40920,7 +40920,7 @@
|
|||
"MOVE_MAGICAL_LEAF",
|
||||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -55166,7 +55166,7 @@
|
|||
"MOVE_HEADBUTT",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -55321,7 +55321,7 @@
|
|||
"MOVE_HEADBUTT",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -56469,7 +56469,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
],
|
||||
|
|
@ -65266,7 +65266,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -65403,7 +65403,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -65544,7 +65544,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -76069,7 +76069,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -76215,7 +76215,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
|
|||
|
|
@ -5876,7 +5876,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": []
|
||||
},
|
||||
|
|
@ -6010,7 +6010,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": []
|
||||
},
|
||||
|
|
@ -6954,7 +6954,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_POWER_TRICK",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -7078,7 +7078,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_POWER_TRICK",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -7209,7 +7209,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_POWER_TRICK",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -11879,7 +11879,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
],
|
||||
|
|
@ -23106,7 +23106,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -23242,7 +23242,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -28253,7 +28253,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_FIRE_PLEDGE"
|
||||
|
|
@ -28379,7 +28379,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_FIRE_PLEDGE"
|
||||
|
|
@ -28526,7 +28526,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BLAST_BURN",
|
||||
|
|
@ -32107,7 +32107,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -32227,7 +32227,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -32371,7 +32371,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -32414,7 +32414,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 25,
|
||||
|
|
@ -32549,7 +32549,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 27,
|
||||
|
|
@ -33386,7 +33386,7 @@
|
|||
"MOVE_HEAD_SMASH",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -33512,7 +33512,7 @@
|
|||
"MOVE_HEAD_SMASH",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -33659,7 +33659,7 @@
|
|||
"MOVE_HEAD_SMASH",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -36075,7 +36075,7 @@
|
|||
"MOVE_PSYCHO_CUT",
|
||||
"MOVE_RAPID_SPIN",
|
||||
"MOVE_ROLE_PLAY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WATER_PULSE",
|
||||
"MOVE_WISH"
|
||||
|
|
@ -36505,7 +36505,7 @@
|
|||
"MOVE_MAGICAL_LEAF",
|
||||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -36636,7 +36636,7 @@
|
|||
"MOVE_MAGICAL_LEAF",
|
||||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -49431,7 +49431,7 @@
|
|||
"MOVE_HEADBUTT",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -49567,7 +49567,7 @@
|
|||
"MOVE_HEADBUTT",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -50591,7 +50591,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
],
|
||||
|
|
@ -58423,7 +58423,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -58548,7 +58548,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -58677,7 +58677,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -68196,7 +68196,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -68332,7 +68332,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
|
|||
|
|
@ -5745,7 +5745,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": []
|
||||
},
|
||||
|
|
@ -5873,7 +5873,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": []
|
||||
},
|
||||
|
|
@ -6789,7 +6789,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -6902,7 +6902,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -7018,7 +7018,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -11489,7 +11489,7 @@
|
|||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_MAGNITUDE",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SUBSTITUTE"
|
||||
],
|
||||
|
|
@ -22486,7 +22486,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_REFLECT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -22618,7 +22618,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_REFLECT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -27537,7 +27537,7 @@
|
|||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -27658,7 +27658,7 @@
|
|||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -27795,7 +27795,7 @@
|
|||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -31332,7 +31332,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
|
|
@ -31446,7 +31446,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
|
|
@ -31586,7 +31586,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
|
|
@ -31630,7 +31630,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 25,
|
||||
|
|
@ -31758,7 +31758,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 27,
|
||||
|
|
@ -32577,7 +32577,7 @@
|
|||
"MOVE_ENDEAVOR",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -32698,7 +32698,7 @@
|
|||
"MOVE_ENDEAVOR",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -32842,7 +32842,7 @@
|
|||
"MOVE_ENDEAVOR",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -35217,7 +35217,7 @@
|
|||
"MOVE_PSYCHO_CUT",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLE_PLAY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WISH"
|
||||
],
|
||||
|
|
@ -35649,7 +35649,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_MAGICAL_LEAF",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TEETER_DANCE"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -35782,7 +35782,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_MAGICAL_LEAF",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TEETER_DANCE"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -48274,7 +48274,7 @@
|
|||
"MOVE_HEADBUTT",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -48405,7 +48405,7 @@
|
|||
"MOVE_HEADBUTT",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -49430,7 +49430,7 @@
|
|||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_MAGNITUDE",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SUBSTITUTE"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -4694,7 +4694,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
|
|
@ -4807,7 +4807,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
|
|
@ -5582,7 +5582,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
|
|
@ -5685,7 +5685,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
|
|
@ -5789,7 +5789,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
|
|
@ -9379,7 +9379,7 @@
|
|||
"MOVE_CURSE",
|
||||
"MOVE_MAGNITUDE",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SUBSTITUTE"
|
||||
],
|
||||
|
|
@ -18107,7 +18107,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_REFLECT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -18212,7 +18212,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_REFLECT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -22086,7 +22086,7 @@
|
|||
"MOVE_ENDURE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -22195,7 +22195,7 @@
|
|||
"MOVE_ENDURE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -22315,7 +22315,7 @@
|
|||
"MOVE_ENDURE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -25387,7 +25387,7 @@
|
|||
],
|
||||
"EggMoves": [
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -25495,7 +25495,7 @@
|
|||
],
|
||||
"EggMoves": [
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -25609,7 +25609,7 @@
|
|||
],
|
||||
"EggMoves": [
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -25662,7 +25662,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 31,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 37,
|
||||
|
|
@ -25772,7 +25772,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 33,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 40,
|
||||
|
|
@ -26446,7 +26446,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -26550,7 +26550,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -26667,7 +26667,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -28659,7 +28659,7 @@
|
|||
"MOVE_DISABLE",
|
||||
"MOVE_ENCORE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WISH"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -6393,7 +6393,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_ENDEAVOR",
|
||||
|
|
@ -6539,7 +6539,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_ENDEAVOR",
|
||||
|
|
@ -7558,7 +7558,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -7684,7 +7684,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -7813,7 +7813,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -12749,7 +12749,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SUBSTITUTE"
|
||||
],
|
||||
|
|
@ -25059,7 +25059,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_REFLECT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -25203,7 +25203,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_REFLECT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -30728,7 +30728,7 @@
|
|||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -30859,7 +30859,7 @@
|
|||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -31011,7 +31011,7 @@
|
|||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -34988,7 +34988,7 @@
|
|||
"MOVE_ENDEAVOR",
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
|
|
@ -35114,7 +35114,7 @@
|
|||
"MOVE_ENDEAVOR",
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
|
|
@ -35268,7 +35268,7 @@
|
|||
"MOVE_ENDEAVOR",
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
|
|
@ -35325,7 +35325,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 25,
|
||||
|
|
@ -35468,7 +35468,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 27,
|
||||
|
|
@ -36406,7 +36406,7 @@
|
|||
"MOVE_HEAD_SMASH",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -36543,7 +36543,7 @@
|
|||
"MOVE_HEAD_SMASH",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -36704,7 +36704,7 @@
|
|||
"MOVE_HEAD_SMASH",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -39350,7 +39350,7 @@
|
|||
"MOVE_PSYCHO_CUT",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLE_PLAY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WISH"
|
||||
],
|
||||
|
|
@ -39836,7 +39836,7 @@
|
|||
"MOVE_MAGICAL_LEAF",
|
||||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TEETER_DANCE"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -39983,7 +39983,7 @@
|
|||
"MOVE_MAGICAL_LEAF",
|
||||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TEETER_DANCE"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -54014,7 +54014,7 @@
|
|||
"MOVE_HEADBUTT",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -54164,7 +54164,7 @@
|
|||
"MOVE_HEADBUTT",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -55299,7 +55299,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SUBSTITUTE"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -6941,7 +6941,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_COVET",
|
||||
|
|
@ -7101,7 +7101,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_COVET",
|
||||
|
|
@ -8220,7 +8220,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -8372,7 +8372,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -8531,7 +8531,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -13938,7 +13938,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
],
|
||||
|
|
@ -27315,7 +27315,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -27475,7 +27475,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -33468,7 +33468,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BOUNCE",
|
||||
|
|
@ -33608,7 +33608,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BOUNCE",
|
||||
|
|
@ -33777,7 +33777,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BLAST_BURN",
|
||||
|
|
@ -38135,7 +38135,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -38275,7 +38275,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -38448,7 +38448,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -38513,7 +38513,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 28,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 31,
|
||||
|
|
@ -38662,7 +38662,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 30,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 34,
|
||||
|
|
@ -39698,7 +39698,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -39846,7 +39846,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -40017,7 +40017,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -42918,7 +42918,7 @@
|
|||
"MOVE_PSYCHO_SHIFT",
|
||||
"MOVE_RAPID_SPIN",
|
||||
"MOVE_ROLE_PLAY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WATER_PULSE",
|
||||
"MOVE_WISH"
|
||||
|
|
@ -43493,7 +43493,7 @@
|
|||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_ROTOTILLER",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -43658,7 +43658,7 @@
|
|||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_ROTOTILLER",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -58895,7 +58895,7 @@
|
|||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -59058,7 +59058,7 @@
|
|||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -60269,7 +60269,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
],
|
||||
|
|
@ -69623,7 +69623,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -69763,7 +69763,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -69907,7 +69907,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -81039,7 +81039,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -81197,7 +81197,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
|
|||
|
|
@ -6231,7 +6231,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_ENDEAVOR",
|
||||
|
|
@ -6373,7 +6373,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_ENDEAVOR",
|
||||
|
|
@ -7363,7 +7363,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -7485,7 +7485,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -7610,7 +7610,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -12437,7 +12437,7 @@
|
|||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_MAGNITUDE",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SUBSTITUTE"
|
||||
],
|
||||
|
|
@ -24447,7 +24447,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_REFLECT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -24587,7 +24587,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_REFLECT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -29978,7 +29978,7 @@
|
|||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -30107,7 +30107,7 @@
|
|||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -30256,7 +30256,7 @@
|
|||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -34139,7 +34139,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
|
|
@ -34263,7 +34263,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
|
|
@ -34413,7 +34413,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
|
|
@ -34468,7 +34468,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 25,
|
||||
|
|
@ -34606,7 +34606,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 27,
|
||||
|
|
@ -35512,7 +35512,7 @@
|
|||
"MOVE_ENDEAVOR",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -35647,7 +35647,7 @@
|
|||
"MOVE_ENDEAVOR",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -35805,7 +35805,7 @@
|
|||
"MOVE_ENDEAVOR",
|
||||
"MOVE_IRON_HEAD",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -38387,7 +38387,7 @@
|
|||
"MOVE_PSYCHO_CUT",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLE_PLAY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WISH"
|
||||
],
|
||||
|
|
@ -38859,7 +38859,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_MAGICAL_LEAF",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TEETER_DANCE"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -39001,7 +39001,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_MAGICAL_LEAF",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TEETER_DANCE"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -52668,7 +52668,7 @@
|
|||
"MOVE_HEADBUTT",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -52813,7 +52813,7 @@
|
|||
"MOVE_HEADBUTT",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -53921,7 +53921,7 @@
|
|||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_MAGNITUDE",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SUBSTITUTE"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -5046,7 +5046,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
|
|
@ -5167,7 +5167,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
|
|
@ -6014,7 +6014,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
|
|
@ -6126,7 +6126,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
|
|
@ -6239,7 +6239,7 @@
|
|||
"MOVE_MEDITATE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
|
|
@ -10019,7 +10019,7 @@
|
|||
"MOVE_CURSE",
|
||||
"MOVE_MAGNITUDE",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SUBSTITUTE"
|
||||
],
|
||||
|
|
@ -19386,7 +19386,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_REFLECT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -19501,7 +19501,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_REFLECT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -23705,7 +23705,7 @@
|
|||
"MOVE_ENDURE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -23820,7 +23820,7 @@
|
|||
"MOVE_ENDURE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -23950,7 +23950,7 @@
|
|||
"MOVE_ENDURE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWAGGER"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -27284,7 +27284,7 @@
|
|||
],
|
||||
"EggMoves": [
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -27405,7 +27405,7 @@
|
|||
],
|
||||
"EggMoves": [
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -27532,7 +27532,7 @@
|
|||
],
|
||||
"EggMoves": [
|
||||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_SWAGGER",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -27598,7 +27598,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 31,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 37,
|
||||
|
|
@ -27717,7 +27717,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 33,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 40,
|
||||
|
|
@ -28461,7 +28461,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -28573,7 +28573,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -28698,7 +28698,7 @@
|
|||
"EggMoves": [
|
||||
"MOVE_BODY_SLAM",
|
||||
"MOVE_ENDEAVOR",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STOMP"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -30867,7 +30867,7 @@
|
|||
"MOVE_DISABLE",
|
||||
"MOVE_ENCORE",
|
||||
"MOVE_ROCK_SLIDE",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WISH"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -6229,7 +6229,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": []
|
||||
},
|
||||
|
|
@ -6382,7 +6382,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": []
|
||||
},
|
||||
|
|
@ -7355,7 +7355,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -7489,7 +7489,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -7638,7 +7638,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -12606,7 +12606,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
],
|
||||
|
|
@ -24581,7 +24581,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -24720,7 +24720,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -30061,7 +30061,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_FIRE_PLEDGE"
|
||||
|
|
@ -30192,7 +30192,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_FIRE_PLEDGE"
|
||||
|
|
@ -30349,7 +30349,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BLAST_BURN",
|
||||
|
|
@ -34270,7 +34270,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -34397,7 +34397,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -34558,7 +34558,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -34609,7 +34609,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 28,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 31,
|
||||
|
|
@ -34742,7 +34742,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 30,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 34,
|
||||
|
|
@ -35641,7 +35641,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -35769,7 +35769,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -35920,7 +35920,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -38534,7 +38534,7 @@
|
|||
"MOVE_PSYCHO_SHIFT",
|
||||
"MOVE_RAPID_SPIN",
|
||||
"MOVE_ROLE_PLAY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SPOTLIGHT",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WATER_PULSE",
|
||||
|
|
@ -39048,7 +39048,7 @@
|
|||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_ROTOTILLER",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -39198,7 +39198,7 @@
|
|||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_ROTOTILLER",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -52913,7 +52913,7 @@
|
|||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -53052,7 +53052,7 @@
|
|||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -54137,7 +54137,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
],
|
||||
|
|
@ -62422,7 +62422,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -62546,7 +62546,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -62674,7 +62674,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -72602,7 +72602,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -72745,7 +72745,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
|
|||
|
|
@ -60044,7 +60044,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 52,
|
||||
"Move": "MOVE_FOREST\u2019S_CURSE"
|
||||
"Move": "MOVE_FORESTS_CURSE"
|
||||
}
|
||||
],
|
||||
"PreEvoMoves": [],
|
||||
|
|
@ -60166,7 +60166,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 52,
|
||||
"Move": "MOVE_FOREST\u2019S_CURSE"
|
||||
"Move": "MOVE_FORESTS_CURSE"
|
||||
}
|
||||
],
|
||||
"PreEvoMoves": [],
|
||||
|
|
|
|||
|
|
@ -6867,7 +6867,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_COVET",
|
||||
|
|
@ -7039,7 +7039,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_COVET",
|
||||
|
|
@ -8149,7 +8149,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -8295,7 +8295,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -8457,7 +8457,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -13908,7 +13908,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THRASH",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
|
|
@ -27257,7 +27257,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -27411,7 +27411,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -33325,7 +33325,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BOUNCE",
|
||||
|
|
@ -33463,7 +33463,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BOUNCE",
|
||||
|
|
@ -33631,7 +33631,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BLAST_BURN",
|
||||
|
|
@ -37975,7 +37975,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN",
|
||||
|
|
@ -38115,7 +38115,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN",
|
||||
|
|
@ -38291,7 +38291,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN",
|
||||
|
|
@ -38358,7 +38358,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 28,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 31,
|
||||
|
|
@ -38502,7 +38502,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 30,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 34,
|
||||
|
|
@ -39511,7 +39511,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -39653,7 +39653,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -39819,7 +39819,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -42709,7 +42709,7 @@
|
|||
"MOVE_PSYCHO_SHIFT",
|
||||
"MOVE_RAPID_SPIN",
|
||||
"MOVE_ROLE_PLAY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SPOTLIGHT",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WATER_PULSE",
|
||||
|
|
@ -43284,7 +43284,7 @@
|
|||
"MOVE_POWER_UP_PUNCH",
|
||||
"MOVE_ROTOTILLER",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -43448,7 +43448,7 @@
|
|||
"MOVE_POWER_UP_PUNCH",
|
||||
"MOVE_ROTOTILLER",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -58660,7 +58660,7 @@
|
|||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -58817,7 +58817,7 @@
|
|||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -60013,7 +60013,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THRASH",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
|
|
@ -69340,7 +69340,7 @@
|
|||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_POWER_UP_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -69477,7 +69477,7 @@
|
|||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_POWER_UP_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -69618,7 +69618,7 @@
|
|||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_POWER_UP_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -80651,7 +80651,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
@ -80805,7 +80805,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": [
|
||||
|
|
|
|||
|
|
@ -6251,7 +6251,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": []
|
||||
},
|
||||
|
|
@ -6392,7 +6392,7 @@
|
|||
"MOVE_REVENGE",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": []
|
||||
},
|
||||
|
|
@ -7365,7 +7365,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -7492,7 +7492,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -7626,7 +7626,7 @@
|
|||
"MOVE_POWER_TRICK",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_ROLLING_KICK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_THUNDER_PUNCH",
|
||||
"MOVE_TICKLE"
|
||||
],
|
||||
|
|
@ -12530,7 +12530,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
],
|
||||
|
|
@ -24501,7 +24501,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -24645,7 +24645,7 @@
|
|||
"MOVE_METRONOME",
|
||||
"MOVE_MIMIC",
|
||||
"MOVE_PRESENT",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_THUNDER_FANG"
|
||||
],
|
||||
|
|
@ -30010,7 +30010,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_FIRE_PLEDGE"
|
||||
|
|
@ -30138,7 +30138,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_FIRE_PLEDGE"
|
||||
|
|
@ -30291,7 +30291,7 @@
|
|||
"MOVE_LOW_KICK",
|
||||
"MOVE_NIGHT_SLASH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT"
|
||||
"MOVE_SMELLING_SALTS"
|
||||
],
|
||||
"TutorMoves": [
|
||||
"MOVE_BLAST_BURN",
|
||||
|
|
@ -34074,7 +34074,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -34197,7 +34197,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -34352,7 +34352,7 @@
|
|||
"MOVE_EXTRASENSORY",
|
||||
"MOVE_FAKE_TEARS",
|
||||
"MOVE_HAMMER_ARM",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SMOKESCREEN",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_TAKE_DOWN"
|
||||
|
|
@ -34395,7 +34395,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 25,
|
||||
|
|
@ -34532,7 +34532,7 @@
|
|||
},
|
||||
{
|
||||
"Level": 22,
|
||||
"Move": "MOVE_SMELLING_SALT"
|
||||
"Move": "MOVE_SMELLING_SALTS"
|
||||
},
|
||||
{
|
||||
"Level": 27,
|
||||
|
|
@ -35457,7 +35457,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -35582,7 +35582,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -35730,7 +35730,7 @@
|
|||
"MOVE_IRON_HEAD",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SCREECH",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_STEALTH_ROCK",
|
||||
"MOVE_STOMP",
|
||||
"MOVE_SUPERPOWER"
|
||||
|
|
@ -38335,7 +38335,7 @@
|
|||
"MOVE_PSYCHO_SHIFT",
|
||||
"MOVE_RAPID_SPIN",
|
||||
"MOVE_ROLE_PLAY",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_TRICK",
|
||||
"MOVE_WATER_PULSE",
|
||||
"MOVE_WISH"
|
||||
|
|
@ -38856,7 +38856,7 @@
|
|||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_ROTOTILLER",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -38999,7 +38999,7 @@
|
|||
"MOVE_NASTY_PLOT",
|
||||
"MOVE_ROTOTILLER",
|
||||
"MOVE_SEED_BOMB",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SWITCHEROO",
|
||||
"MOVE_TEETER_DANCE",
|
||||
"MOVE_WORRY_SEED"
|
||||
|
|
@ -52626,7 +52626,7 @@
|
|||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -52770,7 +52770,7 @@
|
|||
"MOVE_ME_FIRST",
|
||||
"MOVE_MEDITATE",
|
||||
"MOVE_QUICK_GUARD",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VACUUM_WAVE",
|
||||
"MOVE_WAKE_UP_SLAP"
|
||||
],
|
||||
|
|
@ -53863,7 +53863,7 @@
|
|||
"MOVE_MAGNITUDE",
|
||||
"MOVE_MUDDY_WATER",
|
||||
"MOVE_SLEEP_TALK",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_SNORE",
|
||||
"MOVE_ZEN_HEADBUTT"
|
||||
],
|
||||
|
|
@ -62168,7 +62168,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -62295,7 +62295,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -62426,7 +62426,7 @@
|
|||
"MOVE_FORESIGHT",
|
||||
"MOVE_MACH_PUNCH",
|
||||
"MOVE_REVERSAL",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_WIDE_GUARD"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -72468,7 +72468,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
@ -72615,7 +72615,7 @@
|
|||
"MOVE_KNOCK_OFF",
|
||||
"MOVE_LOW_KICK",
|
||||
"MOVE_ME_FIRST",
|
||||
"MOVE_SMELLING_SALT",
|
||||
"MOVE_SMELLING_SALTS",
|
||||
"MOVE_VITAL_THROW"
|
||||
],
|
||||
"TutorMoves": []
|
||||
|
|
|
|||
|
|
@ -1,214 +0,0 @@
|
|||
import glob
|
||||
import re
|
||||
import json
|
||||
import os
|
||||
|
||||
# before all else, abort if the config is off
|
||||
with open("./include/config/pokemon.h", "r") as file:
|
||||
learnset_config = re.findall(r"#define P_LEARNSET_HELPER_TEACHABLE *([^ ]*)", file.read())
|
||||
if len(learnset_config) != 1:
|
||||
quit()
|
||||
if learnset_config[0] != "TRUE":
|
||||
quit()
|
||||
|
||||
def parse_mon_name(name):
|
||||
return re.sub(r'(?!^)([A-Z]+)', r'_\1', name).upper()
|
||||
|
||||
tm_moves = []
|
||||
tutor_moves = []
|
||||
|
||||
# scan incs
|
||||
incs_to_check = glob.glob('./data/scripts/*.inc') # all .incs in the script folder
|
||||
incs_to_check += glob.glob('./data/maps/*/scripts.inc') # all map scripts
|
||||
|
||||
if len(incs_to_check) == 0: # disabled if no jsons present
|
||||
quit()
|
||||
|
||||
for file in incs_to_check:
|
||||
with open(file, 'r') as f2:
|
||||
raw = f2.read()
|
||||
if 'special ChooseMonForMoveTutor' in raw:
|
||||
for x in re.findall(r'setvar VAR_0x8005, (MOVE_.*)', raw):
|
||||
if not x in tutor_moves:
|
||||
tutor_moves.append(x)
|
||||
|
||||
# scan TMs and HMs
|
||||
with open("./include/constants/tms_hms.h", 'r') as file:
|
||||
for x in re.findall(r'F\((.*)\)', file.read()):
|
||||
if not 'MOVE_' + x in tm_moves:
|
||||
tm_moves.append('MOVE_' + x)
|
||||
|
||||
# look up universal moves to exclude them
|
||||
universal_moves = []
|
||||
with open("./src/pokemon.c", "r") as file:
|
||||
for x in re.findall(r"static const u16 sUniversalMoves\[\] =(.|\n)*?{((.|\n)*?)};", file.read())[0]:
|
||||
x = x.replace("\n", "")
|
||||
for y in x.split(","):
|
||||
y = y.strip()
|
||||
if y == "":
|
||||
continue
|
||||
universal_moves.append(y)
|
||||
|
||||
# get compatibility from jsons
|
||||
def construct_compatibility_dict(force_custom_check):
|
||||
dict_out = {}
|
||||
for pth in glob.glob('./tools/learnset_helpers/porymoves_files/*.json'):
|
||||
f = open(pth, 'r')
|
||||
data = json.load(f)
|
||||
for mon in data.keys():
|
||||
if not mon in dict_out:
|
||||
dict_out[mon] = []
|
||||
for move in data[mon]['LevelMoves']:
|
||||
if not move['Move'] in dict_out[mon]:
|
||||
dict_out[mon].append(move['Move'])
|
||||
#for move in data[mon]['PreEvoMoves']:
|
||||
# if not move in dict_out[mon]:
|
||||
# dict_out[mon].append(move)
|
||||
for move in data[mon]['TMMoves']:
|
||||
if not move in dict_out[mon]:
|
||||
dict_out[mon].append(move)
|
||||
for move in data[mon]['EggMoves']:
|
||||
if not move in dict_out[mon]:
|
||||
dict_out[mon].append(move)
|
||||
for move in data[mon]['TutorMoves']:
|
||||
if not move in dict_out[mon]:
|
||||
dict_out[mon].append(move)
|
||||
|
||||
# if the file was not previously generated, check if there is custom data there that needs to be preserved
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", 'r') as file:
|
||||
raw = file.read()
|
||||
if not "// DO NOT MODIFY THIS FILE!" in raw and force_custom_check == True:
|
||||
custom_teachable_compatibilities = {}
|
||||
for entry in re.findall(r"static const u16 s(.*)TeachableLearnset\[\] = {\n((.|\n)*?)\n};", raw):
|
||||
monname = parse_mon_name(entry[0])
|
||||
if monname == "NONE":
|
||||
continue
|
||||
compatibility = entry[1].split("\n")
|
||||
if not monname in custom_teachable_compatibilities:
|
||||
custom_teachable_compatibilities[monname] = []
|
||||
if not monname in dict_out:
|
||||
# this mon is unknown, so all data needs to be preserved
|
||||
for move in compatibility:
|
||||
move = move.replace(",", "").strip()
|
||||
if move == "" or move == "MOVE_UNAVAILABLE":
|
||||
continue
|
||||
custom_teachable_compatibilities[monname].append(move)
|
||||
else:
|
||||
# this mon is known, so check if the moves in the old teachable_learnsets.h are not in the jsons
|
||||
for move in compatibility:
|
||||
move = move.replace(",", "").strip()
|
||||
if move == "" or move == "MOVE_UNAVAILABLE":
|
||||
continue
|
||||
if not move in dict_out[monname]:
|
||||
custom_teachable_compatibilities[monname].append(move)
|
||||
# actually store the data in custom.json
|
||||
if os.path.exists("./tools/learnset_helpers/porymoves_files/custom.json"):
|
||||
f2 = open("./tools/learnset_helpers/porymoves_files/custom.json", "r")
|
||||
custom_json = json.load(f2)
|
||||
f2.close()
|
||||
else:
|
||||
custom_json = {}
|
||||
for x in custom_teachable_compatibilities:
|
||||
if len(custom_teachable_compatibilities[x]) == 0:
|
||||
continue
|
||||
if not x in custom_json:
|
||||
custom_json[x] = {"LevelMoves": [], "PreEvoMoves": [], "TMMoves": [], "EggMoves": [], "TutorMoves": []}
|
||||
for move in custom_teachable_compatibilities[x]:
|
||||
custom_json[x]["TutorMoves"].append(move)
|
||||
f2 = open("./tools/learnset_helpers/porymoves_files/custom.json", "w")
|
||||
f2.write(json.dumps(custom_json, indent=2))
|
||||
f2.close()
|
||||
print("FIRST RUN: Updated custom.json with teachable_learnsets.h's data")
|
||||
# rerun the process
|
||||
dict_out = construct_compatibility_dict(False)
|
||||
return dict_out
|
||||
|
||||
compatibility_dict = construct_compatibility_dict(True)
|
||||
|
||||
# actually prepare the file
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", 'r') as file:
|
||||
out = file.read()
|
||||
list_of_mons = re.findall(r'static const u16 s(.*)TeachableLearnset', out)
|
||||
for mon in list_of_mons:
|
||||
mon_parsed = parse_mon_name(mon)
|
||||
tm_learnset = []
|
||||
tutor_learnset = []
|
||||
if mon_parsed == "NONE" or mon_parsed == "MEW":
|
||||
continue
|
||||
if not mon_parsed in compatibility_dict:
|
||||
print("Unable to find %s in json" % mon)
|
||||
continue
|
||||
for move in tm_moves:
|
||||
if move in universal_moves:
|
||||
continue
|
||||
if move in tm_learnset:
|
||||
continue
|
||||
if move in compatibility_dict[mon_parsed]:
|
||||
tm_learnset.append(move)
|
||||
continue
|
||||
for move in tutor_moves:
|
||||
if move in universal_moves:
|
||||
continue
|
||||
if move in tutor_learnset:
|
||||
continue
|
||||
if move in compatibility_dict[mon_parsed]:
|
||||
tutor_learnset.append(move)
|
||||
continue
|
||||
tm_learnset.sort()
|
||||
tutor_learnset.sort()
|
||||
tm_learnset += tutor_learnset
|
||||
repl = "static const u16 s%sTeachableLearnset[] = {\n " % mon
|
||||
if len(tm_learnset) > 0:
|
||||
repl += ",\n ".join(tm_learnset) + ",\n "
|
||||
repl += "MOVE_UNAVAILABLE,\n};"
|
||||
newout = re.sub(r'static const u16 s%sTeachableLearnset\[\] = {[\s\S]*?};' % mon, repl, out)
|
||||
if newout != out:
|
||||
out = newout
|
||||
print("Updated %s" % mon)
|
||||
|
||||
# add/update header
|
||||
header = "//\n// DO NOT MODIFY THIS FILE! It is auto-generated from tools/learnset_helpers/teachable.py\n//\n\n"
|
||||
longest_move_name = 0
|
||||
for move in tm_moves + tutor_moves:
|
||||
if len(move) > longest_move_name:
|
||||
longest_move_name = len(move)
|
||||
longest_move_name += 2 # + 2 for a hyphen and a space
|
||||
|
||||
universal_title = "Near-universal moves found in sUniversalMoves:"
|
||||
tmhm_title = "TM/HM moves found in \"include/constants/tms_hms.h\":"
|
||||
tutor_title = "Tutor moves found in map scripts:"
|
||||
|
||||
if longest_move_name < len(universal_title):
|
||||
longest_move_name = len(universal_title)
|
||||
if longest_move_name < len(tmhm_title):
|
||||
longest_move_name = len(tmhm_title)
|
||||
if longest_move_name < len(tutor_title):
|
||||
longest_move_name = len(tutor_title)
|
||||
|
||||
def header_print(str):
|
||||
global header
|
||||
header += "// " + str + " " * (longest_move_name - len(str)) + " //\n"
|
||||
|
||||
header += "// " + longest_move_name * "*" + " //\n"
|
||||
header_print(tmhm_title)
|
||||
for move in tm_moves:
|
||||
header_print("- " + move)
|
||||
header += "// " + longest_move_name * "*" + " //\n"
|
||||
header_print(tutor_title)
|
||||
tutor_moves.sort() # alphabetically sort tutor moves for easier referencing
|
||||
for move in tutor_moves:
|
||||
header_print("- " + move)
|
||||
header += "// " + longest_move_name * "*" + " //\n"
|
||||
header_print(universal_title)
|
||||
universal_moves.sort() # alphabetically sort near-universal moves for easier referencing
|
||||
for move in universal_moves:
|
||||
header_print("- " + move)
|
||||
header += "// " + longest_move_name * "*" + " //\n\n"
|
||||
|
||||
if not "// DO NOT MODIFY THIS FILE!" in out:
|
||||
out = header + out
|
||||
else:
|
||||
out = re.sub(r"\/\/\n\/\/ DO NOT MODIFY THIS FILE!(.|\n)*\* \/\/\n\n", header, out)
|
||||
|
||||
with open("./src/data/pokemon/teachable_learnsets.h", 'w') as file:
|
||||
file.write(out)
|
||||
687
tools/wild_encounters/wild_encounters_to_header.py
Normal file
687
tools/wild_encounters/wild_encounters_to_header.py
Normal file
|
|
@ -0,0 +1,687 @@
|
|||
import json
|
||||
import re
|
||||
import os
|
||||
|
||||
|
||||
IS_ENABLED = False
|
||||
|
||||
# C string vars
|
||||
define = "#define"
|
||||
ENCOUNTER_CHANCE = "ENCOUNTER_CHANCE"
|
||||
SLOT = "SLOT"
|
||||
TOTAL = "TOTAL"
|
||||
NULL = "NULL"
|
||||
UNDEFINED = "UNDEFINED"
|
||||
MAP_UNDEFINED = "MAP_UNDEFINED"
|
||||
|
||||
# encounter group header types, filled out programmatically
|
||||
MON_HEADERS = []
|
||||
|
||||
# mon encounter group types
|
||||
fieldData = []
|
||||
fieldInfoStrings = []
|
||||
fieldStrings = []
|
||||
|
||||
# time of day encounter data
|
||||
TIME_DEFAULT = ""
|
||||
TIME_DEFAULT_LABEL = "TIME_OF_DAY_DEFAULT"
|
||||
TIME_DEFAULT_INDEX = 0
|
||||
TIMES_OF_DAY_COUNT = TIME_DEFAULT_INDEX + 1
|
||||
|
||||
# struct building blocks
|
||||
baseStruct = "const struct WildPokemon"
|
||||
structLabel = ""
|
||||
structMonType = ""
|
||||
structTime = ""
|
||||
structMap = ""
|
||||
|
||||
structInfo = "Info"
|
||||
structHeader = "Header"
|
||||
structArrayAssign = "[] ="
|
||||
|
||||
baseStructLabel = ""
|
||||
baseStructContent = []
|
||||
infoStructString = ""
|
||||
infoStructRate = 0
|
||||
infoStructContent = []
|
||||
headerStructLabel = ""
|
||||
headerStructContent = {}
|
||||
headerStructTable = {}
|
||||
headerIndex = 0
|
||||
|
||||
# map header data variables
|
||||
hLabel = ""
|
||||
hForMaps = True
|
||||
headersArray = [headerIndex]
|
||||
|
||||
|
||||
|
||||
# debug output control
|
||||
mainSwitch = True
|
||||
printWarningAndInclude = mainSwitch
|
||||
printEncounterHeaders = mainSwitch
|
||||
printEncounterRateMacros = mainSwitch
|
||||
printEncounterStructsInfoString = mainSwitch
|
||||
printEncounterStructs = mainSwitch
|
||||
|
||||
|
||||
class TimeOfDay():
|
||||
def __init__(self):
|
||||
self.vals = []
|
||||
self.lvals = []
|
||||
self.fvals = []
|
||||
self.count = 0
|
||||
|
||||
def __len__(self):
|
||||
return self.count
|
||||
|
||||
# for debugging purposes
|
||||
def __str__(self):
|
||||
return str([self.vals, self.lvals, self.fvals, self.count])
|
||||
|
||||
def add(self, val):
|
||||
self.vals.append(val)
|
||||
self.lvals.append(val.lower())
|
||||
self.fvals.append(GetTimeLabelFromString(val).capitalize())
|
||||
self.count += 1
|
||||
|
||||
def indexOf(self, val):
|
||||
tempArr = [self.vals, self.lvals, self.fvals]
|
||||
|
||||
for tvals in tempArr:
|
||||
i = 0
|
||||
for time in tvals:
|
||||
if val in time:
|
||||
return i
|
||||
|
||||
i += 1
|
||||
# return -1 here so it returns a consistent type and can be checked against < 0
|
||||
return -1
|
||||
|
||||
|
||||
def ImportWildEncounterFile():
|
||||
# make sure we're in the right directory before anything else
|
||||
if not os.path.exists("Makefile"):
|
||||
print("Please run this script from the project's root folder.")
|
||||
quit()
|
||||
|
||||
global MON_HEADERS
|
||||
|
||||
global TIME_OF_DAY
|
||||
TIME_OF_DAY = SetupUserTimeEnum(TimeOfDay())
|
||||
|
||||
global IS_ENABLED
|
||||
global TIMES_OF_DAY_COUNT
|
||||
if IsConfigEnabled():
|
||||
IS_ENABLED = True
|
||||
TIMES_OF_DAY_COUNT = len(TIME_OF_DAY)
|
||||
|
||||
global fieldInfoStrings
|
||||
global fieldStrings
|
||||
global structLabel
|
||||
global structMonType
|
||||
global structTime
|
||||
global structMap
|
||||
global baseStructLabel
|
||||
global baseStructContent
|
||||
global infoStructString
|
||||
global infoStructRate
|
||||
global headerStructLabel
|
||||
global headerStructContent
|
||||
global hLabel
|
||||
global headersArray
|
||||
global encounterTotalCount
|
||||
global encounterCount
|
||||
global headerIndex
|
||||
global fieldData
|
||||
global tabStr
|
||||
tabStr = " "
|
||||
|
||||
wFile = open("src/data/wild_encounters.json")
|
||||
wData = json.load(wFile)
|
||||
|
||||
encounterTotalCount = []
|
||||
encounterCount = []
|
||||
groupCount = 0
|
||||
while groupCount < len(wData["wild_encounter_groups"]):
|
||||
encounterTotalCount.append(0)
|
||||
encounterCount.append(0)
|
||||
groupCount += 1
|
||||
|
||||
for data in wData["wild_encounter_groups"]:
|
||||
wEncounters = wData["wild_encounter_groups"][headerIndex]["encounters"]
|
||||
headerSuffix = structHeader + "s"
|
||||
|
||||
if data["label"]:
|
||||
hLabel = wData["wild_encounter_groups"][headerIndex]["label"]
|
||||
if headerSuffix in hLabel:
|
||||
hLabel = hLabel[:len(hLabel) - len(headerSuffix)]
|
||||
MON_HEADERS.append(hLabel)
|
||||
|
||||
if data["for_maps"]:
|
||||
hForMaps = wData["wild_encounter_groups"][headerIndex]["for_maps"]
|
||||
|
||||
# for the encounter rate macros, so we don't worry about hidden mons here
|
||||
if headerIndex == 0:
|
||||
wFields = wData["wild_encounter_groups"][headerIndex]["fields"]
|
||||
fieldCounter = 0
|
||||
for field in wFields:
|
||||
fieldData.append({})
|
||||
fieldData[fieldCounter]["name"] = field["type"]
|
||||
fieldData[fieldCounter]["pascalName"] = GetPascalCase(field["type"])
|
||||
fieldData[fieldCounter]["snakeName"] = GetSnakeCase(field["type"])
|
||||
fieldData[fieldCounter]["encounter_rates"] = field["encounter_rates"]
|
||||
|
||||
if "groups" in field:
|
||||
fieldData[fieldCounter]["groups"] = field["groups"]
|
||||
|
||||
if fieldCounter == len(wFields) - 1:
|
||||
fieldData.append({})
|
||||
fieldData[fieldCounter + 1]["name"] = "hidden_mons"
|
||||
fieldData[fieldCounter + 1]["pascalName"] = GetPascalCase("hidden_mons")
|
||||
fieldData[fieldCounter + 1]["snakeName"] = GetSnakeCase("hidden_mons")
|
||||
|
||||
fieldCounter += 1
|
||||
|
||||
if printWarningAndInclude:
|
||||
PrintGeneratedWarningText()
|
||||
print('#include "rtc.h"')
|
||||
print("\n")
|
||||
|
||||
PrintEncounterRateMacros()
|
||||
|
||||
for encounter in wEncounters:
|
||||
if "map" in encounter:
|
||||
structMap = encounter["map"]
|
||||
else:
|
||||
structMap = encounter["base_label"]
|
||||
|
||||
structLabel = encounter["base_label"]
|
||||
|
||||
if encounterTotalCount[headerIndex] != len(wEncounters):
|
||||
encounterTotalCount[headerIndex] = len(wEncounters)
|
||||
|
||||
encounterCount[headerIndex] += 1
|
||||
headersArray = []
|
||||
|
||||
structTime = TIME_DEFAULT_INDEX
|
||||
if IS_ENABLED:
|
||||
timeCounter = 0
|
||||
while timeCounter < TIMES_OF_DAY_COUNT:
|
||||
tempfTime = f"_{TIME_OF_DAY.fvals[timeCounter]}"
|
||||
tempTime = TIME_OF_DAY.vals[timeCounter]
|
||||
if tempfTime in structLabel or tempTime in structLabel:
|
||||
structTime = timeCounter
|
||||
|
||||
timeCounter += 1
|
||||
|
||||
fieldCounter = 0
|
||||
fieldInfoStrings = []
|
||||
while fieldCounter < len(fieldData):
|
||||
fieldInfoStrings.append("")
|
||||
fieldStrings.append("")
|
||||
fieldCounter += 1
|
||||
|
||||
fieldCounter = 0
|
||||
while fieldCounter < len(fieldData):
|
||||
for areaTable in encounter:
|
||||
if fieldData[fieldCounter]["name"] in areaTable:
|
||||
structMonType = fieldData[fieldCounter]["pascalName"]
|
||||
if f"_{TIME_OF_DAY.fvals[structTime]}" in structLabel:
|
||||
fieldInfoStrings[fieldCounter] = f"{structLabel}_{structMonType}{structInfo}"
|
||||
fieldStrings[fieldCounter] = f"{structLabel}_{structMonType}"
|
||||
else:
|
||||
fieldInfoStrings[fieldCounter] = f"{structLabel}_{TIME_OF_DAY.fvals[structTime]}_{structMonType}{structInfo}"
|
||||
fieldStrings[fieldCounter] = f"{structLabel}_{TIME_OF_DAY.fvals[structTime]}_{structMonType}"
|
||||
else:
|
||||
structMonType = ""
|
||||
continue
|
||||
|
||||
baseStructContent = []
|
||||
for group in encounter[areaTable]:
|
||||
if "mons" in group:
|
||||
for mon in encounter[areaTable][group]:
|
||||
baseStructContent.append(list(mon.values()))
|
||||
|
||||
if "encounter_rate" in group:
|
||||
infoStructRate = encounter[areaTable][group]
|
||||
|
||||
baseStructLabel = f"{baseStruct} {fieldStrings[fieldCounter]}{structArrayAssign}"
|
||||
if printEncounterStructs:
|
||||
print()
|
||||
print(baseStructLabel)
|
||||
print("{")
|
||||
PrintStructContent(baseStructContent)
|
||||
print("};")
|
||||
|
||||
if printEncounterStructsInfoString:
|
||||
infoStructString = f"{baseStruct}{structInfo} {fieldInfoStrings[fieldCounter]} = {{ {infoStructRate}, {fieldStrings[fieldCounter]} }};"
|
||||
print(infoStructString)
|
||||
|
||||
fieldCounter += 1
|
||||
AssembleMonHeaderContent()
|
||||
headerIndex += 1
|
||||
PrintWildMonHeadersContent()
|
||||
|
||||
|
||||
def PrintStructContent(contentList):
|
||||
for monList in contentList:
|
||||
print(f"{tabStr}{{ {monList[0]}, {monList[1]}, {monList[2]} }},")
|
||||
return
|
||||
|
||||
|
||||
def GetStructLabelWithoutTime(label):
|
||||
labelLength = len(label)
|
||||
timeLength = 0
|
||||
|
||||
if not IS_ENABLED:
|
||||
return label
|
||||
|
||||
timeCounter = 0
|
||||
while timeCounter < TIMES_OF_DAY_COUNT:
|
||||
tempTime = TIME_OF_DAY.fvals[timeCounter]
|
||||
if tempTime in label:
|
||||
timeLength = len(tempTime)
|
||||
return label[:(labelLength - (timeLength + 1))]
|
||||
|
||||
timeCounter += 1
|
||||
return label
|
||||
|
||||
|
||||
def GetStructTimeWithoutLabel(label):
|
||||
if not IS_ENABLED:
|
||||
return TIME_DEFAULT_INDEX
|
||||
|
||||
timeCounter = 0
|
||||
while timeCounter < TIMES_OF_DAY_COUNT:
|
||||
tempTime = f"_{TIME_OF_DAY.fvals[timeCounter]}"
|
||||
if tempTime in label:
|
||||
return timeCounter
|
||||
|
||||
timeCounter += 1
|
||||
return TIME_DEFAULT_INDEX
|
||||
|
||||
|
||||
def AssembleMonHeaderContent():
|
||||
SetupMonInfoVars()
|
||||
|
||||
tempHeaderLabel = GetWildMonHeadersLabel()
|
||||
tempHeaderTimeIndex = GetStructTimeWithoutLabel(structLabel)
|
||||
structLabelNoTime = GetStructLabelWithoutTime(structLabel)
|
||||
|
||||
if tempHeaderLabel not in headerStructTable:
|
||||
headerStructTable[tempHeaderLabel] = {}
|
||||
headerStructTable[tempHeaderLabel]["groupNum"] = headerIndex
|
||||
|
||||
if structLabelNoTime not in headerStructTable[tempHeaderLabel]:
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime] = {}
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["headerType"] = GetWildMonHeadersLabel()
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["mapGroup"] = structMap
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["mapNum"] = structMap
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounterTotalCount"] = encounterTotalCount[headerIndex]
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounter_types"] = []
|
||||
|
||||
timeCounter = 0
|
||||
while timeCounter < TIMES_OF_DAY_COUNT:
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounter_types"].append([])
|
||||
timeCounter += 1
|
||||
|
||||
fieldCounter = 0
|
||||
while fieldCounter < len(fieldData):
|
||||
headerStructTable[tempHeaderLabel][structLabelNoTime]["encounter_types"][tempHeaderTimeIndex].append(fieldInfoStrings[fieldCounter])
|
||||
fieldCounter += 1
|
||||
|
||||
|
||||
def SetupMonInfoVars():
|
||||
i = 0
|
||||
while i < len(fieldData):
|
||||
fieldData[i]["infoStringBase"] = "." + fieldData[i]["snakeName"] + structInfo
|
||||
if CheckEmpty(fieldInfoStrings[i]):
|
||||
fieldInfoStrings[i] = NULL
|
||||
else:
|
||||
fieldInfoStrings[i] = "&" + fieldInfoStrings[i]
|
||||
|
||||
i += 1
|
||||
|
||||
|
||||
def PrintWildMonHeadersContent():
|
||||
groupCount = 0
|
||||
for group in headerStructTable:
|
||||
labelCount = 0
|
||||
for label in headerStructTable[group]:
|
||||
if label != "groupNum":
|
||||
if labelCount == 0:
|
||||
PrintEncounterHeaders("\n")
|
||||
PrintEncounterHeaders(headerStructTable[group][label]["headerType"])
|
||||
|
||||
PrintEncounterHeaders(tabStr + "{")
|
||||
|
||||
for stat in headerStructTable[group][label]:
|
||||
mapData = headerStructTable[group][label][stat]
|
||||
|
||||
if stat == "mapGroup":
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.mapGroup = {GetMapGroupEnum(mapData)},")
|
||||
elif stat == "mapNum":
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.mapNum = {GetMapGroupEnum(mapData, labelCount + 1)},")
|
||||
|
||||
if type(headerStructTable[group][label][stat]) == list:
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.encounterTypes =")
|
||||
PrintEncounterHeaders(TabStr(2) + "{")
|
||||
|
||||
timeCounter = 0
|
||||
while timeCounter < TIMES_OF_DAY_COUNT:
|
||||
monInfo = headerStructTable[group][label][stat][timeCounter]
|
||||
PrintEncounterHeaders(f"{TabStr(3)}[{TIME_OF_DAY.vals[timeCounter]}] = ")
|
||||
|
||||
infoIndex = 0
|
||||
while infoIndex < len(fieldData):
|
||||
if infoIndex == 0:
|
||||
PrintEncounterHeaders(TabStr(3) + "{")
|
||||
|
||||
if len(monInfo) == 0:
|
||||
PrintEncounterHeaders(f"{TabStr(4)}{GetIMonInfoStringFromIndex(infoIndex)} = NULL,")
|
||||
else:
|
||||
PrintEncounterHeaders(f"{TabStr(4)}{GetIMonInfoStringFromIndex(infoIndex)} = {monInfo[infoIndex]},")
|
||||
|
||||
if infoIndex == len(fieldData) - 1:
|
||||
PrintEncounterHeaders(TabStr(3) + "},")
|
||||
|
||||
infoIndex += 1
|
||||
timeCounter += 1
|
||||
PrintEncounterHeaders(TabStr(2) + "},")
|
||||
PrintEncounterHeaders(tabStr + "},")
|
||||
|
||||
if labelCount + 1 == headerStructTable[group][label]["encounterTotalCount"]:
|
||||
PrintEncounterHeaders(tabStr + "{")
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.mapGroup = {GetMapGroupEnum(MAP_UNDEFINED)},")
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.mapNum = {GetMapGroupEnum(MAP_UNDEFINED, labelCount + 1)},")
|
||||
|
||||
nullCount = 0
|
||||
while nullCount < TIMES_OF_DAY_COUNT:
|
||||
if nullCount == 0:
|
||||
PrintEncounterHeaders(f"{TabStr(2)}.encounterTypes =")
|
||||
PrintEncounterHeaders(TabStr(2)+ "{")
|
||||
|
||||
PrintEncounterHeaders(f"{TabStr(3)}[{TIME_OF_DAY.vals[nullCount]}] = ")
|
||||
|
||||
nullIndex = 0
|
||||
while nullIndex <= len(fieldData) - 1:
|
||||
if nullIndex == 0:
|
||||
PrintEncounterHeaders(TabStr(3) + "{")
|
||||
|
||||
PrintEncounterHeaders(f"{TabStr(4)}{GetIMonInfoStringFromIndex(nullIndex)} = NULL,")
|
||||
|
||||
if nullIndex == len(fieldData) - 1:
|
||||
PrintEncounterHeaders(TabStr(3) + "},")
|
||||
|
||||
nullIndex += 1
|
||||
nullCount += 1
|
||||
PrintEncounterHeaders(TabStr(2) + "},")
|
||||
PrintEncounterHeaders(tabStr + "},")
|
||||
labelCount += 1
|
||||
groupCount += 1
|
||||
PrintEncounterHeaders("};")
|
||||
|
||||
|
||||
def GetWildMonHeadersLabel():
|
||||
return f"{baseStruct}{structHeader} {MON_HEADERS[headerIndex]}{structHeader}s{structArrayAssign}" + "\n{"
|
||||
|
||||
|
||||
def PrintEncounterHeaders(content):
|
||||
if printEncounterHeaders:
|
||||
print(content)
|
||||
|
||||
|
||||
def PrintEncounterRateMacros():
|
||||
if not printEncounterRateMacros:
|
||||
return
|
||||
|
||||
fieldCounter = 0
|
||||
# len(fieldData) - 1 here so we skip hidden_mons
|
||||
while fieldCounter < len(fieldData) - 1:
|
||||
tempName = fieldData[fieldCounter]["name"].upper()
|
||||
if "groups" not in fieldData[fieldCounter]:
|
||||
rateCount = 0
|
||||
for percent in fieldData[fieldCounter]["encounter_rates"]:
|
||||
if rateCount == 0:
|
||||
print(f"{define} {ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount} {percent}")
|
||||
else:
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount} {ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount - 1} + {percent}"
|
||||
)
|
||||
|
||||
if rateCount + 1 == len(fieldData[fieldCounter]["encounter_rates"]):
|
||||
print(
|
||||
f"{define} {ENCOUNTER_CHANCE}_{tempName}_{TOTAL} ({ENCOUNTER_CHANCE}_{tempName}_{SLOT}_{rateCount})"
|
||||
)
|
||||
|
||||
rateCount += 1
|
||||
else:
|
||||
rates = fieldData[fieldCounter]["encounter_rates"]
|
||||
groups = fieldData[fieldCounter]["groups"]
|
||||
|
||||
for method in groups:
|
||||
method_indices = groups[method]
|
||||
if not method_indices:
|
||||
continue
|
||||
|
||||
for i, methodPercentIndex in enumerate(method_indices):
|
||||
if methodPercentIndex < 0 or methodPercentIndex >= len(rates):
|
||||
print(f"#error Invalid fishing encounter rate index {methodPercentIndex} for {method.upper()}")
|
||||
continue
|
||||
|
||||
rate_value = rates[methodPercentIndex]
|
||||
if i == 0:
|
||||
print(f"{define} {ENCOUNTER_CHANCE}_{tempName}_{method.upper()}_{SLOT}_{methodPercentIndex} {rate_value}")
|
||||
else:
|
||||
previous_method_index = method_indices[i - 1]
|
||||
print(f"{define} {ENCOUNTER_CHANCE}_{tempName}_{method.upper()}_{SLOT}_{methodPercentIndex} {ENCOUNTER_CHANCE}_{tempName}_{method.upper()}_{SLOT}_{previous_method_index} + {rate_value}")
|
||||
|
||||
if i == len(method_indices) - 1:
|
||||
print(f"{define} {ENCOUNTER_CHANCE}_{tempName}_{method.upper()}_{TOTAL} ({ENCOUNTER_CHANCE}_{tempName}_{method.upper()}_{SLOT}_{methodPercentIndex})")
|
||||
|
||||
fieldCounter += 1
|
||||
print()
|
||||
|
||||
|
||||
def GetTimeLabelFromString(string):
|
||||
time = "TIME"
|
||||
time_ = "TIME_"
|
||||
|
||||
if string == "TIMES_OF_DAY_COUNT":
|
||||
return string
|
||||
|
||||
if time_ in string.upper():
|
||||
return string[len(time_):len(string)]
|
||||
elif time in string.upper():
|
||||
return string[len(time):len(string)]
|
||||
return string
|
||||
|
||||
|
||||
def GetIMonInfoStringFromIndex(index):
|
||||
return fieldData[index]["infoStringBase"]
|
||||
|
||||
|
||||
def GetMapGroupEnum(string, index = 0):
|
||||
if "MAP_" in string and index == 0:
|
||||
return "MAP_GROUP(" + string[4:len(string)] + ")"
|
||||
elif "MAP_" in string and index != 0:
|
||||
return "MAP_NUM(" + string[4:len(string)] + ")"
|
||||
return index
|
||||
|
||||
|
||||
"""
|
||||
get copied lhea :^ )
|
||||
- next three functions copied almost verbatim from @lhearachel's python scripts in tools/learnset_helpers
|
||||
"""
|
||||
def PrintGeneratedWarningText():
|
||||
print("//")
|
||||
print("// DO NOT MODIFY THIS FILE! It is auto-generated by tools/wild_encounters/wild_encounters_to_header.py")
|
||||
print("//")
|
||||
print("\n")
|
||||
|
||||
|
||||
def IsConfigEnabled():
|
||||
CONFIG_ENABLED_PAT = re.compile(r"#define OW_TIME_OF_DAY_ENCOUNTERS\s+(?P<cfg_val>[^ ]*)")
|
||||
|
||||
with open("./include/config/overworld.h", "r") as overworld_config_file:
|
||||
config_overworld = overworld_config_file.read()
|
||||
config_setting = CONFIG_ENABLED_PAT.search(config_overworld)
|
||||
return config_setting is not None and config_setting.group("cfg_val") in ("TRUE", "1")
|
||||
|
||||
|
||||
def GetTimeEnum():
|
||||
DEFAULT_TIME_PAT = re.compile(r"enum\s+TimeOfDay\s*\{(?P<rtc_val>[\s*\w+,\=\d*]+)\s*\}\s*\;")
|
||||
|
||||
with open("./include/rtc.h", "r") as rtc_include_file:
|
||||
include_rtc = rtc_include_file.read()
|
||||
include_enum = DEFAULT_TIME_PAT.search(include_rtc)
|
||||
return include_enum.group("rtc_val")
|
||||
|
||||
|
||||
def CheckEmpty(string):
|
||||
return string == "" or string.isspace() or string == "\n"
|
||||
|
||||
|
||||
def SetupUserTimeEnum(timeOfDay):
|
||||
enum_string = GetTimeEnum()
|
||||
enum_string = enum_string.split(",")
|
||||
|
||||
# check for extra element from trailing comma
|
||||
if CheckEmpty(enum_string[-1]):
|
||||
enum_string.pop(-1)
|
||||
|
||||
# we don't need the `TIMES_OF_DAY_COUNT` value, so - 1 from the value of len(enum_string)
|
||||
strCount = 0
|
||||
while strCount < len(enum_string) - 1:
|
||||
tempStr = enum_string[strCount].strip("\n ")
|
||||
|
||||
"""
|
||||
we need to ignore any value assignments, as the times will need to correspond
|
||||
with the elements in the array.
|
||||
"""
|
||||
if "=" in tempStr:
|
||||
tempStr = tempStr[0:tempStr.index("=")]
|
||||
tempStr = tempStr.strip(" ")
|
||||
|
||||
#double check we didn't catch any empty values
|
||||
if not CheckEmpty(enum_string[strCount]):
|
||||
timeOfDay.add(tempStr)
|
||||
|
||||
strCount += 1
|
||||
return timeOfDay
|
||||
|
||||
|
||||
def TabStr(amount):
|
||||
return tabStr * amount
|
||||
|
||||
|
||||
def GetPascalCase(string):
|
||||
stringArray = string.split("_")
|
||||
pascalString = ""
|
||||
|
||||
for string in stringArray:
|
||||
pascalString += string.capitalize()
|
||||
return pascalString
|
||||
|
||||
|
||||
def GetSnakeCase(string):
|
||||
stringArray = string.split("_")
|
||||
snakeString = ""
|
||||
|
||||
i = 0
|
||||
for string in stringArray:
|
||||
if i == 0:
|
||||
snakeString += string
|
||||
else:
|
||||
snakeString += string.capitalize()
|
||||
|
||||
i += 1
|
||||
return snakeString
|
||||
|
||||
|
||||
def main():
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ImportWildEncounterFile()
|
||||
|
||||
|
||||
"""
|
||||
!!!! EXAMPLE OUTPUT !!!!
|
||||
- when OW_TIME_OF DAY_ENCOUNTERS is FALSE in configoverworld.h
|
||||
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_0 20
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_1 ENCOUNTER_CHANCE_LAND_MONS_SLOT_0 + 20
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_2 ENCOUNTER_CHANCE_LAND_MONS_SLOT_1 + 10
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_3 ENCOUNTER_CHANCE_LAND_MONS_SLOT_2 + 10
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_4 ENCOUNTER_CHANCE_LAND_MONS_SLOT_3 + 10
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_5 ENCOUNTER_CHANCE_LAND_MONS_SLOT_4 + 10
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_6 ENCOUNTER_CHANCE_LAND_MONS_SLOT_5 + 5
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_7 ENCOUNTER_CHANCE_LAND_MONS_SLOT_6 + 5
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_8 ENCOUNTER_CHANCE_LAND_MONS_SLOT_7 + 4
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_9 ENCOUNTER_CHANCE_LAND_MONS_SLOT_8 + 4
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_10 ENCOUNTER_CHANCE_LAND_MONS_SLOT_9 + 1
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_SLOT_11 ENCOUNTER_CHANCE_LAND_MONS_SLOT_10 + 1
|
||||
#define ENCOUNTER_CHANCE_LAND_MONS_TOTAL (ENCOUNTER_CHANCE_LAND_MONS_SLOT_11)
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_SLOT_0 60
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_SLOT_1 ENCOUNTER_CHANCE_WATER_MONS_SLOT_0 + 30
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_SLOT_2 ENCOUNTER_CHANCE_WATER_MONS_SLOT_1 + 5
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_SLOT_3 ENCOUNTER_CHANCE_WATER_MONS_SLOT_2 + 4
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_SLOT_4 ENCOUNTER_CHANCE_WATER_MONS_SLOT_3 + 1
|
||||
#define ENCOUNTER_CHANCE_WATER_MONS_TOTAL (ENCOUNTER_CHANCE_WATER_MONS_SLOT_4)
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_0 60
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_1 ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_0 + 30
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_2 ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_1 + 5
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_3 ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_2 + 4
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_4 ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_3 + 1
|
||||
#define ENCOUNTER_CHANCE_ROCK_SMASH_MONS_TOTAL (ENCOUNTER_CHANCE_ROCK_SMASH_MONS_SLOT_4)
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_2 60
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_3 ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_2 + 20
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_4 ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_3 + 20
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_TOTAL (ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_4)
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_SLOT_0 70
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_SLOT_1 ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_SLOT_0 + 30
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_TOTAL (ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_SLOT_1)
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_5 40
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_6 ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_5 + 40
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_7 ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_6 + 15
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_8 ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_7 + 4
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_9 ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_8 + 1
|
||||
#define ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_TOTAL (ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_9)
|
||||
|
||||
const struct WildPokemon gRoute101_LandMons_Day[] =
|
||||
{
|
||||
{ 2, 2, SPECIES_WURMPLE },
|
||||
{ 2, 2, SPECIES_POOCHYENA },
|
||||
{ 2, 2, SPECIES_WURMPLE },
|
||||
{ 3, 3, SPECIES_WURMPLE },
|
||||
{ 3, 3, SPECIES_POOCHYENA },
|
||||
{ 3, 3, SPECIES_POOCHYENA },
|
||||
{ 3, 3, SPECIES_WURMPLE },
|
||||
{ 3, 3, SPECIES_POOCHYENA },
|
||||
{ 2, 2, SPECIES_ZIGZAGOON },
|
||||
{ 2, 2, SPECIES_ZIGZAGOON },
|
||||
{ 3, 3, SPECIES_ZIGZAGOON },
|
||||
{ 3, 3, SPECIES_ZIGZAGOON },
|
||||
};
|
||||
|
||||
const struct WildPokemonInfo gRoute101_Day_LandMonsInfo= { 20, gRoute101_Day_LandMons };
|
||||
const struct WildPokemonHeader gWildMonHeaders[] =
|
||||
{
|
||||
{
|
||||
.mapGroup = MAP(ROUTE101),
|
||||
.mapNum = MAP_NUM(ROUTE101),
|
||||
.encounterTypes =
|
||||
[OW_TIME_OF_DAY_DEFAULT] =
|
||||
{
|
||||
.encounterTypes[timeOfDay].landMonsInfo = &gRoute101_LandMonsInfo,
|
||||
.encounterTypes[timeOfDay].waterMonsInfo = NULL,
|
||||
.encounterTypes[timeOfDay].rockSmashMonsInfo = NULL,
|
||||
.encounterTypes[timeOfDay].fishingMonsInfo = NULL,
|
||||
.encounterTypes[timeOfDay].hiddenMonsInfo = NULL,
|
||||
}
|
||||
},
|
||||
}
|
||||
"""
|
||||
Loading…
Reference in New Issue
Block a user