/****************************************************************************
* Copyright (C) 2015-2017 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 flag_manipulation.c
* @author Sturmvogel
* @date 25 may 2017
* @brief functions for preserving flags and reusing difficulty
*/
#include
#include
#define TRAINER_FLAG_SPACE_START 0x1000
extern u16 tb_modify_flag_id(u16 flag_id);
u16 trainerflag_fix_difficulty(u16 flag_id);
u16 load_hword(void *ptr) {
u8 *to_load = (u8 *)ptr;
u16 result = *to_load;
u16 result2 = *(to_load + 1) << 8;
return result | result2;
}
u8 load_byte(void *ptr) { return (u8)(*((u8 *)ptr)); }
u16 trainerflag_fix_difficulty(u16 flag_id) {
u16 new_flag = ((flag_id - TRAINER_FLAG_SPACE_START + 1) / 3) + TRAINER_FLAG_SPACE_START;
dprintf("trainerflag_fix_difficulty;; flag_id: 0x%x, reduced: 0x%x, status: %s\n", flag_id, new_flag,
flag_check(new_flag) ? "true" : "false");
return new_flag;
}
bool trainer_check_flag_on_spot(u8 npc_id) {
void *script = npc_get_script_by_npc_id(npc_id);
/* probably inject some script execution here */
u16 flag = tb_modify_flag_id(load_hword(script + 2));
/* check for line of sight */
u8 hit_result = npc_trainer_and_raycast_hit(&npc_states[npc_id]);
if (hit_result == 0)
return false;
if (flag_check(trainerflag_fix_difficulty(flag + TRAINER_FLAG_SPACE_START)))
return false;
if ((load_byte(script + 1) == 4) && (player_cant_double_battle() > 0))
return false;
spot_trainer_8080334(npc_id, script);
spot_trainer_8081E68(&npc_states[npc_id], hit_result - 1);
return true;
}
u8 trainerflag_read_fix(void *script_location) {
script_location += 2;
u16 flag = load_hword(script_location);
// dprintf("trainerflag_read_fix: 0x%x", flag);
flag = trainerflag_fix_difficulty(flag + TRAINER_FLAG_SPACE_START);
return flag_check(flag);
}
volatile u8 test;
u16 trainerflag_opponent_fix(void) {
return trainerflag_fix_difficulty(trainerbattle_flag_id + TRAINER_FLAG_SPACE_START);
}
bool trainerflag_check_fix(u16 flag) { return flag_check(trainerflag_fix_difficulty(flag + TRAINER_FLAG_SPACE_START)); }
void trainerflag_set_fix(u16 flag) { flag_set(trainerflag_fix_difficulty(flag + TRAINER_FLAG_SPACE_START)); }
void trainerflag_clear_fix(u16 flag) { flag_clear(trainerflag_fix_difficulty(flag + TRAINER_FLAG_SPACE_START)); }
void flag_set_hack(u16 flag) {
u8 *addr = flag_byte_access(flag);
if (addr != NULL) {
dprintf("flag 0x%x was set\n", flag);
*addr |= 1 << (flag & 7);
}
}
u16 var_get_hack(u16 var) {
u16 *ptr = var_access(var);
if (ptr != NULL)
return *ptr;
return var;
}
bool var_set_hack(u16 var, u16 val) {
u16 *ptr = var_access(var);
if (ptr != NULL) {
dprintf("variable 0x%x was set to 0x%x (Address: 0x%x)\n", var, val, ptr);
*ptr = val;
return true;
}
return false;
}
bool var_set_script_hack(struct ScriptEnvironment *env) {
u16 var = script_read_halfword(env);
u16 val = script_read_halfword(env);
var_set_hack(var, val);
return 0;
}