123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
-
-
-
- #include <game_engine.h>
- #include <pkmn_attributes.h>
- #include <agb_debug.h>
- #include <math.h>
- #include <config.h>
- #include <moves.h>
- #include <pokemon.h>
- #include <pkmn_types.h>
-
- #define EVO_NULL \
- { \
- 0, 0, 0, { false, 0 } \
- }
- #define MAX_EVOLUTIONS 5
- #define EVO_NO_EVO \
- (struct evo_result) { false, false, 0 }
-
- #define HAPPY_BOUND 219
- #define BEAUTY_BOUND 170
-
- #define GENDER_DC 0
- #define GENDER_MALE 1
- #define GENDER_FEMALE 2
-
- #define EVO_HAPPINESS 1
- #define EVO_LEVEL_UP 4
- #define EVO_TRADE 5
- #define EVO_TRADE_ITEM 6
- #define EVO_STONE 7
- #define EVO_ATK 8
- #define EVO_DEF 9
- #define EVO_ADEQU 10
- #define EVO_PERSO_HIGH 11
- #define EVO_PERSO_LOW 12
- #define EVO_SPAWN 13
- #define EVO_SPAWNED 14
- #define EVO_BEAUTY 15
- #define EVO_WEAR_ITEM 16
- #define EVO_WEAR_ITEM_NIGHT 17
- #define EVO_WEAR_ITEM_DAY 18
- #define EVO_LEVEL_NIGHT 19
- #define EVO_LEVEL_DAY 20
- #define EVO_LEVEL_VAR 21
- #define EVO_LEVEL_MOVE 22
- #define EVO_LEVEL_POKEMON 23
- #define EVO_LEVEL_TYPE 24
- #define EVO_LEVEL_MOVE_TYPE 25
- #define EVO_MEGA_ONE 26
- #define EVO_MEGA_TWO 27
- #define EVO_PROTO 28
-
- enum evo_source
- {
- LEVEL_UP,
- TRADE,
- STONE_EVOLUTION,
- STONE_REQUEST
- };
-
- struct evo_information
- {
- u16 method;
- u16 argument;
- u16 evolve_to;
- struct
- {
- u16 gender : 2;
- u16 versatile : 14;
- } argument_2;
- };
-
- struct evo_result
- {
- u8 can_evolve;
- u8 consume_item;
- u8 evolve_to;
- };
-
- struct evo_information evolutions[][MAX_EVOLUTIONS] = {
- {EVO_NULL, EVO_NULL, EVO_NULL, EVO_NULL, EVO_NULL},
- {{EVO_LEVEL_MOVE_TYPE, 7, 20, {GENDER_DC, TYPE_GRASS}}, EVO_NULL, EVO_NULL, EVO_NULL, EVO_NULL},
- {{EVO_LEVEL_UP, 32, 3, {GENDER_DC, 0}}, EVO_NULL, EVO_NULL, EVO_NULL, EVO_NULL},
- };
-
- struct evo_call_arguments
- {
- u16 item;
- u16 level;
- enum evo_source source;
- u16 stoneId;
- struct pokemon *poke;
- struct evo_information evolution;
- };
-
- typedef struct evo_result (*evolution_callback)(struct evo_call_arguments);
-
- struct evo_result evolve_by_level(struct evo_call_arguments arguments)
- {
- u8 gender = pokemon_get_gender(arguments.poke);
- u8 gender_arg = arguments.evolution.argument_2.gender;
- dprintf("A pokemon with gender value %d\n", gender);
- if (gender_arg == 1)
- {
- if (gender)
- return EVO_NO_EVO;
- }
- if (gender_arg == 2)
- {
- if (!gender)
- return EVO_NO_EVO;
- }
-
- if (arguments.evolution.argument <= arguments.level && arguments.source == LEVEL_UP)
- {
- return (struct evo_result){true, false, arguments.evolution.evolve_to};
- }
- else
- {
- return (struct evo_result){false, false, 0};
- }
- }
-
- struct evo_result evolve_by_trade_group(struct evo_call_arguments arguments)
- {
- if (arguments.source != TRADE)
- {
- return EVO_NO_EVO;
- }
- if (arguments.evolution.method == EVO_TRADE_ITEM)
- {
- if (arguments.item != arguments.evolution.argument)
- return (struct evo_result){false, false, 0};
- else
- return (struct evo_result){true, true, arguments.evolution.evolve_to};
- }
- else if (arguments.evolution.method == EVO_TRADE)
- {
- return (struct evo_result){true, false, arguments.evolution.evolve_to};
- }
- else
- {
- dprintf("An invalid trade group method was reached in \"evolve_by_trade_group\"\nmethod: %d", arguments.evolution.method);
- return (struct evo_result){false, false, 0};
- }
- }
-
- struct evo_result evolve_random(struct evo_call_arguments arguments)
- {
- if (arguments.source != LEVEL_UP)
- {
- return EVO_NO_EVO;
- }
- u32 pid = pokemon_get_attribute(arguments.poke, ATTR_PID, NULL);
- pid = pid & 0xFFFF;
- u8 mod = (pid % 10);
- dprintf("A pokemon tries to evolve at random: pid: %d, low: %d, mod: %d\n", pid, pid, mod);
- if (mod >= 5)
- {
- if (arguments.evolution.method == EVO_PERSO_HIGH)
- return (struct evo_result){true, false, arguments.evolution.evolve_to};
- else
- return EVO_NO_EVO;
- }
- else
- {
- if (arguments.evolution.method == EVO_PERSO_LOW)
- return (struct evo_result){true, false, arguments.evolution.evolve_to};
- else
- return EVO_NO_EVO;
- }
- }
-
- struct evo_result evolve_by_stone(struct evo_call_arguments arguments)
- {
- u8 gender = pokemon_get_gender(arguments.poke);
- u8 gender_arg = arguments.evolution.argument_2.gender;
-
- if (gender_arg == 1)
- {
- if (gender)
- return EVO_NO_EVO;
- }
- if (gender_arg == 2)
- {
- if (!gender)
- return EVO_NO_EVO;
- }
-
- if (arguments.source != STONE_EVOLUTION && arguments.source != STONE_REQUEST)
- {
- return (struct evo_result){false, false, 0};
- }
- if (arguments.stoneId == arguments.evolution.argument)
- {
- return (struct evo_result){true, false, arguments.evolution.evolve_to};
- }
- else
- {
- return (struct evo_result){false, false, 0};
- }
- }
-
- struct evo_result evolve_by_pokemon(struct evo_call_arguments arguments)
- {
- u8 has_required_pokemon = false;
- u16 species_required = arguments.evolution.argument_2.versatile;
- dprintf("Required: %d\n", species_required);
- for (int i = 0; i < 6; ++i)
- {
- u16 current_species = pokemon_get_attribute(&(pokemon_party_player[i]), ATTR_SPECIES, NULL);
- dprintf("Found pkmn: %d\n", current_species);
- if (current_species == species_required)
- {
- has_required_pokemon = true;
- break;
- }
- }
- if (!has_required_pokemon)
- return EVO_NO_EVO;
- return evolve_by_level(arguments);
- }
-
- struct evo_result evolve_by_atk_def(struct evo_call_arguments arguments)
- {
- u32 atk = pokemon_get_attribute(arguments.poke, ATTR_ATTACK, NULL);
-
- u32 def = pokemon_get_attribute(arguments.poke, ATTR_DEFENCE, NULL);
- dprintf("A pokemon wants to evolve by atk and def.\n");
- dprintf("Level required: %d, pkmn level: %d, pkmn atk: %d, pkmn def: %d\n", arguments.evolution.argument, arguments.level, atk, def);
- if (arguments.evolution.method == EVO_ATK)
- {
- if (atk > def)
- return evolve_by_level(arguments);
- else
- return EVO_NO_EVO;
- }
- if (arguments.evolution.method == EVO_DEF)
- {
- if (def > atk)
- return evolve_by_level(arguments);
- else
- return EVO_NO_EVO;
- }
- if (arguments.evolution.method == EVO_ADEQU)
- {
- if (atk == def)
- return evolve_by_level(arguments);
- else
- return EVO_NO_EVO;
- }
- dprintf("invalid atk and def evo code reached.\n");
- return EVO_NO_EVO;
- }
-
- struct evo_result evolve_by_type(struct evo_call_arguments arguments)
- {
- u8 has_required_pokemon = false;
- u16 type_required = arguments.evolution.argument_2.versatile;
- dprintf("Required: %d\n", type_required);
- for (int i = 0; i < 6; ++i)
- {
- u16 current_species = pokemon_get_attribute(&(pokemon_party_player[i]), ATTR_SPECIES, NULL);
- if (current_species == 0)
- continue;
- u8 type_one = pokemon_base_stats[current_species].type_one;
- u8 type_two = pokemon_base_stats[current_species].type_two;
- dprintf("Found type: %d/%d\n", type_one, type_two);
- if (type_one == type_required || type_two == type_required)
- {
- has_required_pokemon = true;
- break;
- }
- }
- if (!has_required_pokemon)
- return EVO_NO_EVO;
- return evolve_by_level(arguments);
- }
-
- struct evo_result evolve_by_happiness(struct evo_call_arguments arguments)
- {
- u32 happiness = pokemon_get_attribute(arguments.poke, ATTR_HAPPINESS, NULL);
- dprintf("A pokemon wants to evolve by happiness.\n");
- dprintf("Happiness value: %d; needed: %d\n", happiness, HAPPY_BOUND);
- if ((happiness > HAPPY_BOUND) && (arguments.source == LEVEL_UP))
- {
- return (struct evo_result){true, false, arguments.evolution.evolve_to};
- }
- else
- {
- return (struct evo_result){false, false, 0};
- }
- }
-
- struct evo_result evolve_by_special_place(struct evo_call_arguments arguments)
- {
- u16 value = var_get(EVO_VAR);
- dprintf("A pokemon tried to evolve using the var evo method: value: %d needed: %d\n", value, arguments.evolution.argument_2.versatile);
- if (arguments.evolution.argument_2.versatile != value)
- {
- return EVO_NO_EVO;
- }
- return evolve_by_level(arguments);
- }
-
- struct evo_result evolve_by_beauty(struct evo_call_arguments arguments)
- {
- u32 beauty = pokemon_get_attribute(arguments.poke, ATTR_BEAUTY, NULL);
- dprintf("A pokemon tires to evolve by beauty: value: %d; required: %d.\n", beauty, BEAUTY_BOUND);
- if (beauty > BEAUTY_BOUND && arguments.source == LEVEL_UP)
- return evolve_by_level(arguments);
- return EVO_NO_EVO;
- }
-
- struct evo_result evolve_by_worn_item(struct evo_call_arguments arguments)
- {
-
- struct evo_result level_result = evolve_by_level(arguments);
- if (!level_result.can_evolve)
- return EVO_NO_EVO;
- u16 item_to_wear = arguments.evolution.argument_2.versatile;
- dprintf("A pokemon tried to evolve by item. pkmn_item: %d; argument item: %d", arguments.item, item_to_wear);
- if (arguments.item != item_to_wear)
- return EVO_NO_EVO;
-
- return (struct evo_result){true, false, arguments.evolution.evolve_to};
- }
-
- struct evo_result evolve_by_worn_item_day(struct evo_call_arguments arguments)
- {
- dprintf("A pokemon tried to use the (not implmented) evolve_by_worn_item_day evo method.\n");
- return evolve_by_worn_item(arguments);
- }
-
- struct evo_result evolve_by_worn_item_night(struct evo_call_arguments arguments)
- {
- dprintf("A pokemon tried to use the (not implmented) evolve_by_worn_item_night evo method.\n");
- return evolve_by_worn_item(arguments);
- }
-
- struct evo_result evolve_by_move(struct evo_call_arguments arguments)
- {
- u16 move_one = pokemon_get_attribute(arguments.poke, ATTR_ATTACK_1, NULL);
- u16 move_two = pokemon_get_attribute(arguments.poke, ATTR_ATTACK_2, NULL);
- u16 move_three = pokemon_get_attribute(arguments.poke, ATTR_ATTACK_3, NULL);
- u16 move_four = pokemon_get_attribute(arguments.poke, ATTR_ATTACK_4, NULL);
- u16 move_needed = arguments.evolution.argument_2.versatile;
- dprintf("A pokemon tried to evolve using evolve_by_move: needed: %d, one: %d, two: %d, three: %d, four: %d\n", move_needed, move_one, move_two, move_three, move_four);
- if ((move_one == move_needed) || (move_two == move_needed) || (move_three == move_needed) || (move_four == move_needed))
- return evolve_by_level(arguments);
- else
- return EVO_NO_EVO;
- }
-
- struct evo_result evolve_by_move_type(struct evo_call_arguments arguments)
- {
- u16 needed_type = arguments.evolution.argument_2.versatile;
- u8 knows_required_move = false;
- for (int i = ATTR_ATTACK_1; i <= ATTR_ATTACK_4; ++i)
- {
- u16 current_move = pokemon_get_attribute(arguments.poke, i, NULL);
- if (current_move == 0)
- continue;
- u8 current_type = move_table[current_move].type;
- dprintf("found move type: %d on move %d\n", current_type, current_move);
- if (current_type == needed_type)
- {
- knows_required_move = true;
- break;
- }
- }
- if (knows_required_move)
- return evolve_by_level(arguments);
- else
- return EVO_NO_EVO;
- }
-
- struct evo_result evolve_no_method(struct evo_call_arguments arguments)
- {
-
- return EVO_NO_EVO;
- }
-
- struct evo_result evolve_invalid_method(struct evo_call_arguments arguments)
- {
- dprintf("A pokemon tried to execute an evolution method that is not yet implemented.\n");
- return (struct evo_result){false, false, 0};
- }
-
- static evolution_callback evolution_methods[] =
- {
- evolve_invalid_method,
- evolve_by_happiness,
- evolve_invalid_method,
- evolve_invalid_method,
- evolve_by_level,
- evolve_by_trade_group,
- evolve_by_trade_group,
- evolve_by_stone,
- evolve_by_atk_def,
- evolve_by_atk_def,
- evolve_by_atk_def,
- evolve_random,
- evolve_random,
- evolve_by_level,
- evolve_no_method,
- evolve_by_beauty,
- evolve_by_worn_item,
- evolve_by_worn_item_day,
- evolve_by_worn_item_night,
- evolve_invalid_method,
- evolve_invalid_method,
- evolve_by_special_place,
- evolve_by_move,
- evolve_by_pokemon,
- evolve_by_type,
- evolve_by_move_type,
- evolve_no_method,
- evolve_no_method,
- evolve_no_method,
- evolve_no_method,
- };
-
- u16 evolution_try_evolve(struct pokemon *pokemon, enum evo_source source, u16 stoneId)
- {
- u16 held_item = pokemon_get_attribute(pokemon, ATTR_HELD_ITEM, NULL);
- u16 species = pokemon_get_attribute(pokemon, ATTR_SPECIES, NULL);
- u16 level = pokemon_get_attribute(pokemon, ATTR_LEVEL, NULL);
- dprintf("Species %d tried to evolve.\n", species);
- dprintf("Cause: %d\n", source);
- if (species > 2)
- {
- dprintf("Currently no evolution possible due to short table!\n");
- return 0;
- }
- struct evo_information *current_evolution_structure = evolutions[species];
- struct evo_result result;
- for (int i = 0; i < MAX_EVOLUTIONS; ++i)
- {
- if (current_evolution_structure[i].method != 0)
- {
- dprintf("found valid evolution with method %d for species %d\n", current_evolution_structure[i].method, species);
- struct evo_call_arguments args = {held_item, level, source, stoneId, pokemon, current_evolution_structure[i]};
- result = evolution_methods[current_evolution_structure[i].method](args);
- if (result.can_evolve)
- break;
- }
- }
- if (result.can_evolve)
- {
- if (result.consume_item)
- {
- u16 zero = 0;
- pokemon_set_attribute(pokemon, ATTR_HELD_ITEM, &zero);
- }
- return result.evolve_to;
- }
- else
- return 0;
- }
|