/****************************************************************************
* 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 . *
****************************************************************************/
/**
* @file entry_hazards.c
* @author Sturmvogel
* @date 15 dec 2016
* @brief Handle entry hazards
*/
/* === INCLUDE === */
#include
#include
#include
#include
#include
#include
#include
/* === EXTERN STATICS === */
extern void* bs_stealth_rock;
extern void* bs_toxic_spikes;
extern void* bs_toxic_spikes_bad;
extern void* bs_sticky_web;
extern void* bs_toxic_resolve;
extern void* bs_spikes_lain;
extern void* bs_rocks_lain;
extern void* bs_toxic_lain;
extern void* bs_sticky_lain;
extern void* bs_lunar_dance_exec;
extern void* str_lunardance_executed_ref;
/* === PROTOTYPES === */
/**
* @brief execute entry hazards scripts if they are lain
* @return true if there was an effect, false otherwise
*/
u8 execute_entry_hazards();
/**
* @brief execute a lay script for entry hazards
* @return true
*/
u8 lay_entry_hazards();
/* === IMPLEMENTATIONS === */
u8 execute_entry_hazards() {
u8 active_side = get_side_from_bank(battle_active_bank);
u8 has_effect = 0;
struct side_affecting* active_side_affecting = &custom_battle_elements.ptr->side_affecting[active_side];
if (active_side_affecting->lunardance && !(active_side_affecting->lunardance_done)) {
battle_damage_store = ((s32)battle_participants[battle_active_bank].max_hp - (s32)battle_participants[battle_active_bank].current_hp) * -1;
active_side_affecting->lunardance = 0;
battle_participants[battle_active_bank].status.int_status = 0;
prepare_setattributes_in_battle(0, REQUEST_STATUS_BATTLE, 0, 4, &battle_participants[battle_active_bank].status);
mark_buffer_bank_for_execution(battle_active_bank);
battle_script_push();
battle_string_chooser = str_lunardance_executed_ref;
battlescript_cursor = bs_lunar_dance_exec;
has_effect = 1;
} else if (side_affecting_halfword[active_side].spikes_on && !(side_affecting_halfword[active_side].spikes_damage_done)) {
//spikes lay down, deal spiky damage
u32 damage = (battle_participants[battle_active_bank].max_hp) / ((5 - battle_side_timers[active_side].spikes_amount) * 2);
if (damage == 0)
damage = 1;
battle_damage_store = damage;
side_affecting_halfword[active_side].spikes_damage_done = 1;
battle_script_push();
battlescript_cursor = (void*) (0x081D8CBE);
has_effect = 1;
} else if (active_side_affecting->stealth_rock && !(active_side_affecting->stealth_rock_done)) {
active_side_affecting->stealth_rock_done = 1;
//check for magic guard here
u32 damage = battle_participants[battle_active_bank].max_hp;
switch (battle_type_effectiveness_calc(MOVE_STEALTH_ROCK, TYPE_ROCK, battle_active_bank^1, battle_active_bank, 0) >> 4) {
case 1:
damage = damage >> 5;
break;
case 2:
damage = damage >> 4;
break;
case 4:
damage = damage >> 3;
break;
case 8:
damage = damage >> 2;
break;
case 16:
damage = damage >> 1;
break;
}
if (damage == 0)
damage = 1;
battle_damage_store = damage;
battle_script_push();
battlescript_cursor = bs_stealth_rock;
has_effect = 1;
} else if (active_side_affecting->toxic_spikes_psn && !(active_side_affecting->toxic_spikes_done)) {
active_side_affecting->toxic_spikes_done = 1;
if (battle_bank_has_type(battle_active_bank, TYPE_POISON)) {
has_effect = 1;
active_side_affecting->toxic_spikes_psn = 0;
active_side_affecting->toxic_spikes_badpsn = 0;
battle_script_push();
battlescript_cursor = bs_toxic_resolve;
} else if (!battle_bank_is_poison_resistant(battle_active_bank, 0)) {
if (active_side_affecting->toxic_spikes_badpsn) {
battle_participants[battle_active_bank].status.flags.toxic_poison = 1;
battle_script_push();
battlescript_cursor = bs_toxic_spikes_bad;
} else {
battle_participants[battle_active_bank].status.flags.poison = 1;
battle_script_push();
battlescript_cursor = bs_toxic_spikes;
}
prepare_setattributes_in_battle(0, REQUEST_STATUS_BATTLE, 0, 4, &battle_participants[battle_active_bank].status.flags);
mark_buffer_bank_for_execution(battle_active_bank);
has_effect = 1;
}
} else if (active_side_affecting->sticky_web && !(active_side_affecting->sticky_web_done) && battle_participants[battle_active_bank].spd_buff != 0) {
active_side_affecting->sticky_web_done = 1;
battle_script_push();
battlescript_cursor = bs_sticky_web;
battle_stat_changer = 0x93;
has_effect = 1;
}
if (has_effect) {
custom_battle_elements.ptr->various.var1 = battle_active_bank;
battle_participants[battle_active_bank].status2.destinny_bond = 0;
battle_hitmarker &= 0xFFFFFFBF;
}
return has_effect;
}
u8 lay_entry_hazards() {
u8 target_side = get_side_from_bank(battle_defender_bank);
u8 fail = 0;
struct side_affecting* target_side_struct = &custom_battle_elements.ptr->side_affecting[target_side];
switch (battle_executed_move) {
case MOVE_SPIKES:
if (battle_side_timers[target_side].spikes_amount < 3) {
battle_side_timers[target_side].spikes_amount++;
side_affecting_halfword[target_side].spikes_on = 1;
battlescript_cursor = bs_spikes_lain;
} else {
fail = 1;
}
break;
case MOVE_STEALTH_ROCK:
if (target_side_struct->stealth_rock == 0) {
target_side_struct->stealth_rock = 1;
battlescript_cursor = bs_rocks_lain;
} else
fail = 1;
break;
case MOVE_TOXIC_SPIKES:
if (target_side_struct->toxic_spikes_psn == 0) {
target_side_struct->toxic_spikes_psn = 1;
battlescript_cursor = bs_toxic_lain;
} else if (target_side_struct->toxic_spikes_badpsn == 0) {
target_side_struct->toxic_spikes_badpsn = 1;
battlescript_cursor = bs_toxic_lain;
} else
fail = 1;
break;
case MOVE_STICKY_WEB:
if (target_side_struct->sticky_web == 0) {
target_side_struct->sticky_web = 1;
battlescript_cursor = bs_sticky_lain;
} else
fail = 1;
break;
default:
fail = 1;
break;
}
if (fail) {
//failed execution
battlescript_cursor = (void*) (0x081D7DF0);
}
return 1;
}