Skip to content

Commit

Permalink
Merge pull request #100 from savaughn/evolve-ui
Browse files Browse the repository at this point in the history
Evolve UI
  • Loading branch information
savaughn authored Nov 19, 2023
2 parents 78fdb8d + d6ac948 commit cfa9781
Show file tree
Hide file tree
Showing 14 changed files with 265 additions and 104 deletions.
Binary file modified .DS_Store
Binary file not shown.
3 changes: 2 additions & 1 deletion include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ typedef enum {
error_swap_pkmn,
error_update_save,
error_update_pokedex,
error_update_files
error_update_files,
error_evolve_pkmn,
} pksavhelper_error;

#endif // COMMON_H
1 change: 1 addition & 0 deletions include/pksavhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ enum eligible_evolution_status check_trade_evolution_gen2(PokemonSave *pkmn_save
void evolve_party_pokemon_at_index(PokemonSave *pkmn_save, uint8_t pkmn_party_index);
void generate_random_number_step(void);
void update_pkmn_DVs(PokemonSave *pkmn_save, uint8_t pkmn_party_index);
void update_pkmn_stats(PokemonSave *pkmn_save, uint8_t pkmn_party_index);
bool get_is_random_DVs_disabled(void);
void set_is_random_DVs_disabled(bool is_disabled);
bool get_is_item_required(void);
Expand Down
2 changes: 1 addition & 1 deletion include/raylibhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void draw_file_select(struct save_file_data *save_file_data, char *player1_save_
void draw_trade(PokemonSave *save_player1, PokemonSave *save_player2, char *player1_save_path, char *player2_save_path, struct TrainerSelection trainer_selection[2], struct trainer_info *trainer1, struct trainer_info *trainer2, bool *is_same_generation, GameScreen *current_screen, Texture2D *trade_texture);
void draw_file_select_single(struct save_file_data *save_file_data, PokemonSave *save_player1, char *player1_save_path, struct trainer_info *trainer1, struct TrainerSelection *trainer_selection, enum single_player_menu_types menu_type, GameScreen *current_screen);
void draw_bills_pc(PokemonSave *pkmn_save, char *save_path, struct trainer_info *trainer, struct TrainerSelection *trainerSelection, GameScreen *current_screen);
void draw_evolve(PokemonSave *pkmn_save, char *save_path, struct trainer_info *trainer, GameScreen *current_screen);
void draw_evolve(PokemonSave *pkmn_save, char *save_path, struct trainer_info *trainer, GameScreen *current_screen, Texture2D *evolve_texture);
void handle_list_scroll(int *y_offset, const int num_saves, const int corrupted_count, int *mouses_down_index, bool *is_moving_scroll, int *banner_position_offset);
void update_selected_indexes_with_selection(int *selected_saves_index, int *mouses_down_index, bool *is_moving_scroll);
void draw_no_save_files(char *save_path);
Expand Down
16 changes: 14 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Pokerom Trader - Pokémon Save File Trading GUI

![Pokerom Trader](https://user-images.githubusercontent.com/25937456/277514322-288a8da9-fb6f-4ae1-8adb-00ccaed6683d.gif)
![main_menu](https://github.com/savaughn/pokerom-trader/assets/25937456/78ef12ba-b04c-471d-a1b2-36bc55ab731e)

#
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/savaughn/pokerom-trader)](https://github.com/savaughn/pokerom-trader/releases) [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/savaughn/pokerom-trader/build-macos.yml?branch=main)](https://github.com/savaughn/pokerom-trader/actions) [![GitHub issues](https://img.shields.io/github/issues/savaughn/pokerom-trader)](https://github.com/savaughn/pokerom-trader/issues) [![GitHub](https://img.shields.io/github/license/savaughn/pokerom-trader)](https://github.com/savaughn/pokerom-trader/blob/main/LICENSE) [![GitHub all releases](https://img.shields.io/github/downloads/savaughn/pokerom-trader/total)](https://github.com/savaughn/pokerom-trader/releases)

Expand All @@ -16,7 +17,7 @@ There is no backup system implemented yet. Make backup saves before using this o
- Bill's PC - Allows a user to view and manage their Pokémon boxes and party (in progress)

### Settings
![settings menu](https://user-images.githubusercontent.com/25937456/277552973-c1d28185-c347-463c-bf33-b7b782f6f32e.png)
![settings menu](https://user-images.githubusercontent.com/25937456/284032112-e4d14a96-731e-4255-88a3-2acabdd73b94.png)
- Change save files folder with absolute path to folder
- Default is ~/Library/PokeromTrader/saves (MacOS)
- Default is ~/.pokeromtrader/ (Linux)
Expand Down Expand Up @@ -47,6 +48,7 @@ There is no backup system implemented yet. Make backup saves before using this o

## What's not working
- See [issues tab](https://github.com/savaughn/pokerom-trader/issues) for current bugs
- No JP Region support

## Discord
https://discord.gg/JUzzegS3AP
Expand Down Expand Up @@ -88,3 +90,13 @@ This project is licensed under the [MIT License](LICENSE).

## Disclaimer
Pokerom Trader is an unofficial application and is not affiliated with or endorsed by Nintendo, Game Freak, Creatures, The Pokémon Company, or any related entities. Pokémon and Pokémon character names are trademarks of Nintendo, Game Freak, Creatures, and The Pokémon Company. All trademarks, character names, and other intellectual property used in this application are used for identification and informational purposes only. The use of these names and marks is believed to qualify as fair use under trademark law. Pokerom Trader is not endorsed by or affiliated with any of the aforementioned entities. Pokerom Trader is provided "as is" without warranty of any kind, and the developers make no warranties, express or implied, regarding the accuracy or completeness of the content provided in this application.

## Demos
### Trade

![trade_demo](https://github.com/savaughn/pokerom-trader/assets/25937456/d33ebe5f-d3ab-4b58-b67e-9cc4a8c7633f)

### Evolve

![evolve_demo](https://github.com/savaughn/pokerom-trader/assets/25937456/4e97170c-d3ed-44ee-9fe5-19c5c25792ee)

Binary file added saves/Pokemon - Blue Evolve.sav
Binary file not shown.
Binary file added saves/Pokemon - Crystal Evolve.sav
Binary file not shown.
2 changes: 1 addition & 1 deletion src/components/TrainerInfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ void draw_trainer_info(struct trainer_info *trainer, int x, int y, struct Traine
if (current_trainer_index != -1 && trainer_selection[current_trainer_index].pkmn_party_index != -1 && is_panel_out)
{
// Name of the pokemon selected from list
static char selected_pokemon_nickname[PKMN_NAME_TEXT_MAX + 1] = "\0";
char selected_pokemon_nickname[PKMN_NAME_TEXT_MAX + 1] = "\0";
if (trainer_generation == SAVE_GENERATION_1)
{
pksav_gen1_import_text(trainer->pokemon_party.gen1_pokemon_party.nicknames[trainer_selection[current_trainer_index].pkmn_party_index], selected_pokemon_nickname, PKMN_NAME_TEXT_MAX);
Expand Down
62 changes: 25 additions & 37 deletions src/pksavhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,15 @@ pksavhelper_error update_seen_owned_pkmn(PokemonSave *pkmn_save, uint8_t pokemon
error_handler(pksav_error, "Error setting owned pokedex bit");
}
}
if (pksav_error != PKSAV_ERROR_NONE)
{
return error_update_pokedex;
}
return error_none;

return pksav_error == PKSAV_ERROR_NONE ? error_none : error_update_pokedex;
}

void swap_party_pkmn_at_indices(struct pksav_gen2_save *save, uint8_t pkmn_party_index1, uint8_t pkmn_party_index2)
{
// swap nickname
char tmp_nickname1[PKMN_NAME_TEXT_MAX + 1];
char tmp_nickname2[PKMN_NAME_TEXT_MAX + 1];
char tmp_nickname1[PKMN_NAME_TEXT_MAX + 1] = "\0";
char tmp_nickname2[PKMN_NAME_TEXT_MAX + 1] = "\0";
pksav_gen2_import_text(save->pokemon_storage.p_party->nicknames[pkmn_party_index1], tmp_nickname1, PKMN_NAME_TEXT_MAX);
pksav_gen2_import_text(save->pokemon_storage.p_party->nicknames[pkmn_party_index2], tmp_nickname2, PKMN_NAME_TEXT_MAX);
pksav_gen2_export_text(tmp_nickname2, save->pokemon_storage.p_party->nicknames[pkmn_party_index1], PKMN_NAME_TEXT_MAX);
Expand All @@ -82,8 +79,8 @@ void swap_party_pkmn_at_indices(struct pksav_gen2_save *save, uint8_t pkmn_party
save->pokemon_storage.p_party->species[pkmn_party_index2] = tmp_species;

// swap otnames
char tmp_otname1[TRAINER_NAME_TEXT_MAX + 1];
char tmp_otname2[TRAINER_NAME_TEXT_MAX + 1];
char tmp_otname1[TRAINER_NAME_TEXT_MAX + 1] = "\0";
char tmp_otname2[TRAINER_NAME_TEXT_MAX + 1] = "\0";
pksav_gen2_import_text(save->pokemon_storage.p_party->otnames[pkmn_party_index1], tmp_otname1, TRAINER_NAME_TEXT_MAX);
pksav_gen2_import_text(save->pokemon_storage.p_party->otnames[pkmn_party_index2], tmp_otname2, TRAINER_NAME_TEXT_MAX);
pksav_gen2_export_text(tmp_otname2, save->pokemon_storage.p_party->otnames[pkmn_party_index1], TRAINER_NAME_TEXT_MAX);
Expand All @@ -102,7 +99,7 @@ void create_trainer(PokemonSave *pkmn_save, struct trainer_info *trainer)
case SAVE_GENERATION_1:
{
// Trainer name
char trainer_name[TRAINER_NAME_TEXT_MAX + 1];
char trainer_name[TRAINER_NAME_TEXT_MAX + 1] = "\0";
pksav_gen1_import_text(pkmn_save->save.gen1_save.trainer_info.p_name, trainer_name, TRAINER_NAME_TEXT_MAX);

// Trainer Id
Expand All @@ -122,7 +119,7 @@ void create_trainer(PokemonSave *pkmn_save, struct trainer_info *trainer)
case SAVE_GENERATION_2:
{
// Trainer name
char trainer_name[TRAINER_NAME_TEXT_MAX + 1];
char trainer_name[TRAINER_NAME_TEXT_MAX + 1] = "\0";
pksav_gen2_import_text(pkmn_save->save.gen2_save.trainer_info.p_name, trainer_name, TRAINER_NAME_TEXT_MAX);

// Update the trainer struct
Expand Down Expand Up @@ -362,6 +359,7 @@ void update_pkmn_stats(PokemonSave *pkmn_save, uint8_t pkmn_party_index)
pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].party_data.spd = pksav_bigendian16(pkmn_stats[PKSAV_GEN1_STAT_SPEED]);
pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].party_data.spcl = pksav_bigendian16(pkmn_stats[PKSAV_GEN1_STAT_SPECIAL]);
pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].party_data.max_hp = pksav_bigendian16(pkmn_stats[PKSAV_GEN1_STAT_HP]);
pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].pc_data.current_hp = pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].party_data.max_hp;
}
else
{
Expand Down Expand Up @@ -453,9 +451,9 @@ enum eligible_trade_status check_trade_eligibility(struct trainer_info *trainer,

bool check_if_reds_pikachu(const PokemonSave *pkmn_save, const uint8_t pkmn_party_index)
{
char tmp_otname_pkmn[PKMN_NAME_TEXT_MAX + 1];
char tmp_otname_pkmn[PKMN_NAME_TEXT_MAX + 1] = "\0";
pksav_gen1_import_text(pkmn_save->save.gen1_save.pokemon_storage.p_party->otnames[pkmn_party_index], tmp_otname_pkmn, PKMN_NAME_TEXT_MAX);
char tmp_otname_trainer[PKMN_NAME_TEXT_MAX + 1];
char tmp_otname_trainer[PKMN_NAME_TEXT_MAX + 1] = "\0";
pksav_gen1_import_text(pkmn_save->save.gen1_save.trainer_info.p_name, tmp_otname_trainer, PKMN_NAME_TEXT_MAX);
return pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].pc_data.species == SI_PIKACHU && // Is a Pikachu
pkmn_save->save.gen1_save.save_type == PKSAV_GEN1_SAVE_TYPE_YELLOW && // Is from Yellow
Expand Down Expand Up @@ -487,8 +485,8 @@ pksavhelper_error swap_pkmn_at_index_between_saves_cross_gen(PokemonSave *player
}

// swap nickname
char tmp_nickname1[PKMN_NAME_TEXT_MAX + 1];
char tmp_nickname2[PKMN_NAME_TEXT_MAX + 1];
char tmp_nickname1[PKMN_NAME_TEXT_MAX + 1] = "\0";
char tmp_nickname2[PKMN_NAME_TEXT_MAX + 1] = "\0";
pksav_error = pksav_gen1_import_text(player_gen1->save.gen1_save.pokemon_storage.p_party->nicknames[pkmn_party_index1], tmp_nickname1, PKMN_NAME_TEXT_MAX);
if (pksav_error != PKSAV_ERROR_NONE)
{
Expand Down Expand Up @@ -610,8 +608,8 @@ pksavhelper_error swap_pkmn_at_index_between_saves_cross_gen(PokemonSave *player
player_gen2->save.gen2_save.pokemon_storage.p_party->species[pkmn_party_index2] = species_gen1_to_gen2[tmp_species_gen1];

// swap otnames
char tmp_otname_gen1[TRAINER_NAME_TEXT_MAX + 1];
char tmp_otname_gen2[TRAINER_NAME_TEXT_MAX + 1];
char tmp_otname_gen1[TRAINER_NAME_TEXT_MAX + 1] = "\0";
char tmp_otname_gen2[TRAINER_NAME_TEXT_MAX + 1] = "\0";
pksav_error = pksav_gen1_import_text(player_gen1->save.gen1_save.pokemon_storage.p_party->otnames[pkmn_party_index1], tmp_otname_gen1, TRAINER_NAME_TEXT_MAX);
if (pksav_error != PKSAV_ERROR_NONE)
{
Expand Down Expand Up @@ -654,8 +652,8 @@ pksavhelper_error swap_pkmn_at_index_between_saves(PokemonSave *player1_save, Po
enum pksav_error pksav_error;

// swap nickname
char tmp_nickname1[PKMN_NAME_TEXT_MAX + 1];
char tmp_nickname2[PKMN_NAME_TEXT_MAX + 1];
char tmp_nickname1[PKMN_NAME_TEXT_MAX + 1] = "\0";
char tmp_nickname2[PKMN_NAME_TEXT_MAX + 1] = "\0";
if (player1_save->save_generation_type == SAVE_GENERATION_1)
{
pksav_error = pksav_gen1_import_text(player1_save->save.gen1_save.pokemon_storage.p_party->nicknames[pkmn_party_index1], tmp_nickname1, PKMN_NAME_TEXT_MAX);
Expand Down Expand Up @@ -736,8 +734,8 @@ pksavhelper_error swap_pkmn_at_index_between_saves(PokemonSave *player1_save, Po
}

// swap otnames
char tmp_otname1[TRAINER_NAME_TEXT_MAX + 1];
char tmp_otname2[TRAINER_NAME_TEXT_MAX + 1];
char tmp_otname1[TRAINER_NAME_TEXT_MAX + 1] = "\0";
char tmp_otname2[TRAINER_NAME_TEXT_MAX + 1] = "\0";
if (player1_save->save_generation_type == SAVE_GENERATION_1)
{
pksav_error = pksav_gen1_import_text(player1_save->save.gen1_save.pokemon_storage.p_party->otnames[pkmn_party_index1], tmp_otname1, TRAINER_NAME_TEXT_MAX);
Expand Down Expand Up @@ -819,21 +817,18 @@ void evolve_party_pokemon_at_index(PokemonSave *pkmn_save, uint8_t pkmn_party_in
uint8_t pkmn_species_index = pkmn_save->save.gen1_save.pokemon_storage.p_party->species[pkmn_party_index];

// Get the data for the pokemon's evolution
char evolution_name[PKMN_NAME_TEXT_MAX + 1];
char evolution_name[PKMN_NAME_TEXT_MAX + 1] = "\0";
strcpy(evolution_name, pkmn_evolution_pairs_gen1[pkmn_species_index].evolution_name);
char species_name[PKMN_NAME_TEXT_MAX + 1];
char species_name[PKMN_NAME_TEXT_MAX + 1] = "\0";
strcpy(species_name, pkmn_evolution_pairs_gen1[pkmn_species_index].species_name);
uint8_t evolution_index = pkmn_evolution_pairs_gen1[pkmn_species_index].evolution_index;

// Update species index to evolution index to access evolution base stats
pkmn_save->save.gen1_save.pokemon_storage.p_party->species[pkmn_party_index] = evolution_index;
pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].pc_data.species = evolution_index;

// Calculates and updates stats
update_pkmn_stats(pkmn_save, pkmn_party_index);

// Get the pokemon's nickname
char pkmn_save_nickname[PKMN_NAME_TEXT_MAX + 1];
char pkmn_save_nickname[PKMN_NAME_TEXT_MAX + 1] = "\0";
pksav_gen1_import_text(pkmn_save->save.gen1_save.pokemon_storage.p_party->nicknames[pkmn_party_index], pkmn_save_nickname, PKMN_NAME_TEXT_MAX);

// Check if pokemon does not have custom nickname
Expand All @@ -854,8 +849,6 @@ void evolve_party_pokemon_at_index(PokemonSave *pkmn_save, uint8_t pkmn_party_in
pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].pc_data.catch_rate = pkmn_base_stats_gen1[evolution_index].catch_rate;
// Update condition to none
pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].pc_data.condition = PKSAV_GB_CONDITION_NONE;
// Update health to max hp
pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].pc_data.current_hp = pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].party_data.max_hp;
// TODO: Update moves based on learn set and level
// engine/pokemon/evos_moves.asm
// pkmn_save->save.gen1_save.pokemon_storage.p_party->party[pkmn_party_index].pc_data.moves;
Expand All @@ -865,21 +858,18 @@ void evolve_party_pokemon_at_index(PokemonSave *pkmn_save, uint8_t pkmn_party_in
// Get the species index of the pokemon being evolved
uint8_t pkmn_species_index = pkmn_save->save.gen2_save.pokemon_storage.p_party->species[pkmn_party_index];
// Get the data for the pokemon's evolution
char evolution_name[PKMN_NAME_TEXT_MAX + 1];
char evolution_name[PKMN_NAME_TEXT_MAX + 1] = "\0";
strcpy(evolution_name, pkmn_evolution_pairs_gen2[pkmn_species_index].evolution_name);
char species_name[PKMN_NAME_TEXT_MAX + 1];
char species_name[PKMN_NAME_TEXT_MAX + 1] = "\0";
strcpy(species_name, pkmn_evolution_pairs_gen2[pkmn_species_index].species_name);
uint8_t evolution_index = pkmn_evolution_pairs_gen2[pkmn_species_index].evolution_index;

// Update species index to evolution index to access evolution base stats
pkmn_save->save.gen2_save.pokemon_storage.p_party->species[pkmn_party_index] = evolution_index;
pkmn_save->save.gen2_save.pokemon_storage.p_party->party[pkmn_party_index].pc_data.species = evolution_index;

// Calculates and updates stats
update_pkmn_stats(pkmn_save, pkmn_party_index);

// Get the pokemon's nickname
char pkmn_save_nickname[PKMN_NAME_TEXT_MAX + 1];
char pkmn_save_nickname[PKMN_NAME_TEXT_MAX + 1] = "\0";
pksav_gen2_import_text(pkmn_save->save.gen2_save.pokemon_storage.p_party->nicknames[pkmn_party_index], pkmn_save_nickname, PKMN_NAME_TEXT_MAX);

// Check if pokemon does not have custom nickname
Expand All @@ -895,8 +885,6 @@ void evolve_party_pokemon_at_index(PokemonSave *pkmn_save, uint8_t pkmn_party_in

// Update condition to none
pkmn_save->save.gen2_save.pokemon_storage.p_party->party[pkmn_party_index].party_data.condition = PKSAV_CONDITION_NONE;
// Update health to max hp
pkmn_save->save.gen2_save.pokemon_storage.p_party->party[pkmn_party_index].party_data.current_hp = pkmn_save->save.gen2_save.pokemon_storage.p_party->party[pkmn_party_index].party_data.max_hp;
// TODO: Update moves based on learn set and level
// engine/pokemon/evos_moves.asm
// pkmn_save->save.gen2_save.pokemon_storage.p_party->party[pkmn_party_index].pc_data.moves;
Expand Down
11 changes: 6 additions & 5 deletions src/raylibhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,18 @@ void update_selected_indexes_with_selection(int *selected_saves_index, int *mous

void draw_no_save_files(char *save_path)
{
ClearBackground(RAYWHITE);
ClearBackground(RED);
DrawRectangle(20, 150, SCREEN_WIDTH - 40, SCREEN_HEIGHT - 300, (Color){0,0,0,50});
if (no_dir_err)
{
Vector2 text_center = SCREEN_CENTER("Save folder doesn't exist!", 20);
DrawText("Save folder doesn't exist!", text_center.x, text_center.y, 20, BLACK);
shadow_text("Save folder doesn't exist!", text_center.x, text_center.y, 20, WHITE);
}
else
{
DrawText("No save files found in save folder", 190, 200, 20, BLACK);
shadow_text("No save files found in save folder", 190, 200, 20, WHITE);
}
DrawText(TextFormat("%s", save_path), SCREEN_CENTER(save_path, 20).x, 275, 20, BLACK);
shadow_text(TextFormat("%s", save_path), SCREEN_CENTER(save_path, 20).x, 275, 20, WHITE);
}

void draw_top_banner(const char *text, const int *banner_position_offset)
Expand Down Expand Up @@ -307,7 +308,7 @@ void draw_raylib_screen_loop(
draw_file_select_single(save_file_data, pkmn_save_player1, player1_save_path, trainer1, &trainerSelection[0], SINGLE_PLAYER_MENU_TYPE_EVOLVE, &current_screen);
break;
case SCREEN_EVOLVE:
draw_evolve(pkmn_save_player1, player1_save_path, trainer1, &current_screen);
draw_evolve(pkmn_save_player1, player1_save_path, trainer1, &current_screen, &textures[T_EVOLVE]);
break;
case SCREEN_ABOUT:
draw_about(&current_screen, is_build_prerelease);
Expand Down
Loading

0 comments on commit cfa9781

Please sign in to comment.