123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /****************************************************************************
- * Copyright (C) 2015-2016 by the SotS Team *
- * *
- * This file is part of Sovereign of the Skies. *
- * *
- * Sovereign of the Skies is free software: you can redistribute it *
- * and/or modify it *
- * under the terms of the GNU Lesser General Public License as published *
- * by the Free Software Foundation, either version 3 of the License, or *
- * (at your option) any later version provided you include a copy of the *
- * licence and this header. *
- * *
- * Sovereign of the Skies is distributed in the hope that it will be *
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with Sovereign of the Skies. *
- * If not, see <http://www.gnu.org/licenses/>. *
- ****************************************************************************/
-
- /**
- * @file battle_help.c
- * @author Sturmvogel
- * @date 15 dec 2016
- * @brief Some general helper methods for battle
- */
-
- /* === INCLUDE === */
-
- #include <battle_common.h>
- #include <battle_custom_structs.h>
- #include <battle_help.h>
- #include <battle_locations.h>
- #include <game_engine.h>
- #include <pkmn_abilities.h>
- #include <pkmn_attributes.h>
- #include <pkmn_item_effects.h>
- #include <pkmn_items.h>
- #include <pkmn_types.h>
-
- /* === STATICS === */
-
- /* from kds emerald battle engine upgrade */
- u8 type_effectiveness_table[TYPE_FAIRY - 0x4][TYPE_FAIRY - 0x4] = {
- {10, 10, 10, 10, 10, 05, 10, 00, 05, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, // normal
- {20, 10, 05, 05, 10, 20, 05, 00, 20, 10, 10, 10, 10, 10, 05, 20, 10, 20, 05}, // fight
- {10, 20, 10, 10, 10, 05, 20, 10, 05, 10, 10, 10, 20, 05, 10, 10, 10, 10, 10}, // flying
- {10, 10, 10, 05, 05, 05, 10, 05, 00, 10, 10, 10, 20, 10, 10, 10, 10, 10, 20}, // poison
- {10, 10, 00, 20, 10, 20, 05, 10, 20, 10, 20, 10, 05, 20, 10, 10, 10, 10, 10}, // ground
- {10, 05, 20, 10, 05, 10, 20, 10, 05, 10, 20, 10, 10, 10, 10, 20, 10, 10, 10}, // rock
- {10, 05, 05, 05, 10, 10, 10, 05, 05, 10, 05, 10, 20, 10, 20, 10, 10, 20, 05}, // bug
- {00, 10, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 20, 10, 10, 05, 10}, // ghost
- {10, 10, 10, 10, 10, 20, 10, 10, 05, 10, 05, 05, 10, 05, 10, 20, 10, 10, 20}, // steel
- {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}, // egg
- {10, 10, 10, 10, 10, 05, 20, 10, 20, 10, 05, 05, 20, 10, 10, 20, 05, 10, 10}, // fire
- {10, 10, 10, 10, 20, 20, 10, 10, 10, 10, 20, 05, 05, 10, 10, 10, 05, 10, 10}, // water
- {10, 10, 05, 05, 20, 20, 05, 10, 05, 10, 05, 20, 05, 10, 10, 10, 05, 10, 10}, // grass
- {10, 10, 20, 10, 00, 10, 10, 10, 10, 10, 10, 20, 05, 05, 10, 10, 05, 10, 10}, // electric
- {10, 20, 10, 20, 10, 10, 10, 10, 05, 10, 10, 10, 10, 10, 05, 10, 10, 00, 10}, // psychic
- {10, 10, 20, 10, 20, 10, 10, 10, 05, 10, 05, 05, 20, 10, 10, 05, 20, 10, 10}, // ice
- {10, 10, 10, 10, 10, 10, 10, 10, 05, 10, 10, 10, 10, 10, 10, 10, 20, 10, 00}, // dragon
- {10, 05, 10, 10, 10, 10, 10, 20, 10, 10, 10, 10, 10, 10, 20, 10, 10, 05, 05}, // dark
- {10, 20, 10, 05, 10, 10, 10, 10, 05, 10, 05, 10, 10, 10, 10, 10, 20, 20, 10} // fairy
- };
-
- /* === IMPLEMENTATIONS === */
- u16 battle_damage_type_effectiveness_update(u8 attacking_type, u8 defending_type, u8 atk_bank, u8 def_bank,
- u16 chained_effect, u8 airstatus) {
- u8 effect, atype = attacking_type, dtype = defending_type;
- if (!chained_effect || atype == TYPE_EGG || dtype == TYPE_EGG)
- return chained_effect;
-
- if (atype >= TYPE_FAIRY)
- atype = atype - 5;
-
- if (dtype >= TYPE_FAIRY)
- dtype = dtype - 5;
- effect = type_effectiveness_table[atype][dtype];
-
- if (custom_battle_elements.ptr->various.inverse_battle) {
- if (effect == 20) {
- effect = 5;
- } else if (effect == 5 || effect == 0) {
- effect = 20;
- }
- }
- /* handle normal / fighting on ghost */
- if ((((attacking_type == TYPE_NORMAL || attacking_type == TYPE_FIGHTING) && defending_type == TYPE_GHOST &&
- ((battle_participants[def_bank].status2.foresight))) ||
- battle_participants[atk_bank].ability_id == ABILITY_SCRAPPY) &&
- effect == 0) {
- effect = 10;
- }
- /* handle other effectiveness changers here */
-
- switch (effect) {
- case 0:
- chained_effect = 0;
- break;
- case 5:
- chained_effect = chained_effect >> 1;
- break;
- case 20:
- chained_effect = chained_effect << 1;
- break;
- }
- return chained_effect;
- }
-
- u16 battle_apply_type_effectiveness(u16 chained_effect, u8 move_type, u8 target_bank, u8 atk_bank, u8 airstatus) {
- u8 defender_type1 = battle_participants[target_bank].type1;
- u8 defender_type2 = battle_participants[target_bank].type2;
- /* set different types */
- if (defender_type2 == defender_type1)
- defender_type2 = TYPE_EGG;
- chained_effect = battle_damage_type_effectiveness_update(move_type, defender_type1, atk_bank, target_bank,
- chained_effect, airstatus);
- chained_effect = battle_damage_type_effectiveness_update(move_type, defender_type2, atk_bank, target_bank,
- chained_effect, airstatus);
- return chained_effect;
- }
-
- u16 battle_type_effectiveness_calc(u16 move, u8 move_type, u8 atk_bank, u8 def_bank,
- u8 effects_handling_and_recording) {
- u16 chained_effect = 64;
- // TODO: double_type moves
- // TODO: get air status
- chained_effect = battle_apply_type_effectiveness(chained_effect, move_type, def_bank, atk_bank, 2);
- // TODO: save into structs
- // TODO: effect_handling_and_recording
- return chained_effect;
- }
-
- u8 battle_bank_has_type(u8 bank, u8 type) {
- return battle_participants[bank].type1 == type || battle_participants[bank].type2 == type;
- }
-
- u8 battle_item_get_effect(u8 bank, u8 check_negating_effects) {
- if (check_negating_effects) {
- if (battle_participants[bank].ability_id == ABILITY_KLUTZ ||
- custom_battle_elements.ptr->bank_affecting[bank].embargo)
- return ITEM_EFFECT_NOEFFECT;
- }
- if (battle_participants[bank].held_item == ITEM_ENIGMABERRY) {
- return battle_enigma_berry[bank].battle_effect_x12;
- } else {
- return item_get_x12(battle_participants[bank].held_item);
- }
- }
-
- u8 battle_bank_is_poison_resistant(u8 bank, u8 self_inflicted) { // 0 == can poison
- // 1 == is already poisoned
- // 2 == has other major condition
- // 3 == type doesn't allow it
- // 4 == ability doesn't allow it
- // 5 == safeguard protection
- // 8 == misty terrain doesn't allow it !TODO!
- if (battle_participants[bank].status.flags.poison || battle_participants[bank].status.flags.toxic_poison)
- return 1;
- if (battle_participants[bank].status.int_status)
- return 2;
- if (battle_bank_has_type(bank, TYPE_POISON) || battle_bank_has_type(bank, TYPE_STEEL))
- return 3;
- if (((battle_participants[bank].ability_id == ABILITY_IMMUNITY ||
- (battle_participants[bank].ability_id == ABILITY_LEAF_GUARD &&
- (battle_weather.flags.sun || battle_weather.flags.permament_sun || battle_weather.flags.harsh_sun)))))
- return 4;
- if (side_affecting_halfword[get_side_from_bank(bank)].safeguard_on && !self_inflicted)
- return 5;
- return 0;
- }
-
- u8 battle_count_party_pokemon(u8 bank) {
- struct pokemon *poke;
- if (get_side_from_bank(bank))
- poke = &party_opponent[0];
- else
- poke = &party_player[0];
- u8 usable_pokes = 0;
- for (u8 i = 0; i < 6; i++) {
- if (pokemon_get_attribute(&poke[i], ATTR_CURRENT_HP, 0) != 0 &&
- pokemon_get_attribute(&poke[i], ATTR_IS_EGG, 0) != 1 &&
- pokemon_get_attribute(&poke[i], ATTR_SPECIES, 0) != 0)
- usable_pokes++;
- }
- return usable_pokes;
- }
|