Make .party files use "enum Pokeball" instead of "enum Item" (#9159)

This commit is contained in:
FosterProgramming 2026-02-19 11:20:47 +01:00 committed by GitHub
parent ccfb1b6e09
commit 150241913a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 119 additions and 18 deletions

View File

@ -0,0 +1,85 @@
import re
import os
import shutil
item_to_ball = {
"ITEM_STRANGE_BALL": "Strange",
"ITEM_POKE_BALL": "Poke",
"ITEM_GREAT_BALL": "Great",
"ITEM_ULTRA_BALL": "Ultra",
"ITEM_MASTER_BALL": "Master",
"ITEM_PREMIER_BALL": "Premier",
"ITEM_HEAL_BALL": "Heal",
"ITEM_NET_BALL": "Net",
"ITEM_NEST_BALL": "Nest",
"ITEM_DIVE_BALL": "Dive",
"ITEM_DUSK_BALL": "Dusk",
"ITEM_TIMER_BALL": "Timer",
"ITEM_QUICK_BALL": "Quick",
"ITEM_REPEAT_BALL": "Repeat",
"ITEM_LUXURY_BALL": "Luxury",
"ITEM_LEVEL_BALL": "Level",
"ITEM_LURE_BALL": "Lure",
"ITEM_MOON_BALL": "Moon",
"ITEM_FRIEND_BALL": "Friend",
"ITEM_LOVE_BALL": "Love",
"ITEM_FAST_BALL": "Fast",
"ITEM_HEAVY_BALL": "Heavy",
"ITEM_DREAM_BALL": "Dream",
"ITEM_SAFARI_BALL": "Safari",
"ITEM_SPORT_BALL": "Sport",
"ITEM_PARK_BALL": "Park",
"ITEM_BEAST_BALL": "Beast",
"ITEM_CHERISH_BALL": "Cherish",
}
def make_backup_files(files):
for file in files:
backup = os.path.basename(file) + ".backup"
if not os.path.isfile(backup):
print("Creating backup for " + file)
shutil.copy2(file, backup, follow_symlinks=True)
def parse_ball(line):
line = line.removeprefix("Ball:").strip()
item = "ITEM_"
for c in line:
if ('A' <= c and c <= 'Z') or ('0' <= c and c <= '9'):
item += c
elif 'a' <= c and c <= 'z':
item += c.upper()
elif c == '\'':
pass
else:
item += "_"
if item not in item_to_ball:
print("unrecognized pattern:" + item)
quit()
return ("Ball: " + item_to_ball[item] + "\n")
def parse_and_change(filepath):
backup = os.path.basename(filepath) + ".backup"
allLines = list()
with open(backup, 'r', encoding='UTF-8') as file:
while line:=file.readline():
if "Ball:" in line:
allLines.append(parse_ball(line))
else:
allLines.append(line)
with open(filepath, 'w+', encoding='UTF-8') as file:
for line in allLines:
file.write(line)
if not os.path.exists("Makefile"):
print("Please run this script from your root folder.")
quit()
files = ["src/data/battle_partners.party", "src/data/trainers.party"]
make_backup_files(files)
for file in files:
parse_and_change(file)
print("Migration complete. You can delete battle_partners.party.backup and trainers.party.backup if things are working properly")

View File

@ -2009,7 +2009,7 @@ u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer
}
SetMonData(&party[i], MON_DATA_ABILITY_NUM, &abilityNum);
SetMonData(&party[i], MON_DATA_FRIENDSHIP, &(partyData[monIndex].friendship));
if (partyData[monIndex].ball != ITEM_NONE)
if (partyData[monIndex].ball < POKEBALL_COUNT)
{
ball = partyData[monIndex].ball;
SetMonData(&party[i], MON_DATA_POKEBALL, &ball);

View File

@ -28,7 +28,6 @@ void FillPartnerParty(u16 trainerId)
u16 monId;
u32 otID;
u8 trainerName[(PLAYER_NAME_LENGTH * 3) + 1];
s32 ball = -1;
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(trainerId);
SetFacilityPtrsGetLevel();
@ -100,10 +99,9 @@ void FillPartnerParty(u16 trainerId)
SetMonData(&gPlayerParty[i + 3], MON_DATA_ABILITY_NUM, &j);
}
SetMonData(&gPlayerParty[i + 3], MON_DATA_FRIENDSHIP, &(partyData[i].friendship));
if (partyData[i].ball != ITEM_NONE)
if (partyData[i].ball < POKEBALL_COUNT)
{
ball = partyData[i].ball;
SetMonData(&gPlayerParty[i + 3], MON_DATA_POKEBALL, &ball);
SetMonData(&gPlayerParty[i + 3], MON_DATA_POKEBALL, &partyData[i].ball);
}
if (partyData[i].nickname != NULL)
{

View File

@ -12,7 +12,7 @@
#include "constants/trainers.h"
#include "constants/battle.h"
#define NUM_TEST_TRAINERS 11
#define NUM_TEST_TRAINERS 12
static const struct Trainer sTestTrainers[DIFFICULTY_COUNT][NUM_TEST_TRAINERS] =
{
@ -160,22 +160,15 @@ static const struct TrainerMon sTestParty2[] =
},
};
static const struct Trainer sTestTrainer2 =
{
.trainerName = _("Test2"),
.trainerClass = TRAINER_CLASS_BLACK_BELT,
.party = TRAINER_PARTY(sTestParty2),
};
TEST("Trainer Class Balls apply to the entire party")
{
ASSUME(B_TRAINER_CLASS_POKE_BALLS >= GEN_8);
u32 j;
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainer2, TRUE, BATTLE_TYPE_TRAINER);
u32 j;
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[DIFFICULTY_NORMAL][11], TRUE, BATTLE_TYPE_TRAINER);
for(j = 0; j < 6; j++)
{
EXPECT(GetMonData(&testParty[j], MON_DATA_POKEBALL, 0) == gTrainerClasses[sTestTrainer2.trainerClass].ball);
EXPECT(GetMonData(&testParty[j], MON_DATA_POKEBALL, 0) == gTrainerClasses[sTestTrainers[DIFFICULTY_NORMAL][11].trainerClass].ball);
}
Free(testParty);
}

View File

@ -14,7 +14,7 @@ IVs: 25 HP / 26 Atk / 27 Def / 29 SpA / 30 SpD / 28 Spe
EVs: 252 HP / 4 SpA / 252 Spe
Happiness: 42
Shiny: Yes
Ball: Master Ball
Ball: Master
Dynamax Level: 5
- Air Slash
- Barrier
@ -239,3 +239,24 @@ Party Size: 2
Wynaut
Wobbuffet
=== 11 ===
Name: Test11
Class: Black Belt
Pic: Red
Gender: Male
Music: Male
Battle Type: Singles
Party Size: 6
Wynaut
Wobbuffet
Eevee
Mew
Oddish
Aron

View File

@ -2044,9 +2044,13 @@ static void fprint_trainers(const char *output_path, FILE *f, struct Parsed *par
{
fprintf(f, "#line %d\n", pokemon->ball_line);
fprintf(f, " .ball = ");
fprint_constant(f, "ITEM", pokemon->ball);
fprint_constant(f, "BALL", pokemon->ball);
fprintf(f, ",\n");
}
else
{
fprintf(f, " .ball = POKEBALL_COUNT,\n");
}
if (pokemon->friendship_line)
{