Skip to content

Commit

Permalink
Merge pull request #1539 from fmatthew5876/battle_algo
Browse files Browse the repository at this point in the history
Battle Algorithm related fixes from battle 7
  • Loading branch information
fdelapena committed Dec 12, 2018
2 parents ffdee3b + f7f783f commit dba6dc0
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 56 deletions.
26 changes: 15 additions & 11 deletions src/game_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,20 @@
constexpr int max_level_2k = 50;
constexpr int max_level_2k3 = 99;

static int max_hp_value() {
static int max_exp_value() {
return Player::IsRPG2k() ? 999999 : 9999999;
}

int Game_Actor::MaxHpValue() const {
return Player::IsRPG2k() ? 999 : 9999;
}

static int max_other_stat_value() {
return 999;
int Game_Actor::MaxStatBattleValue() const {
return Player::IsRPG2k() ? 999 : 9999;
}

static int max_exp_value() {
return Player::IsRPG2k() ? 999999 : 9999999;
int Game_Actor::MaxStatBaseValue() const {
return 999;
}

Game_Actor::Game_Actor(int actor_id) :
Expand Down Expand Up @@ -355,7 +359,7 @@ int Game_Actor::GetBaseMaxHp(bool mod) const {
if (mod)
n += GetData().hp_mod;

return min(max(n, 1), max_hp_value());
return Utils::Clamp(n, 1, MaxHpValue());
}

int Game_Actor::GetBaseMaxHp() const {
Expand All @@ -373,7 +377,7 @@ int Game_Actor::GetBaseMaxSp(bool mod) const {
if (mod)
n += GetData().sp_mod;

return min(max(n, 0), max_other_stat_value());
return Utils::Clamp(n, 0, MaxStatBaseValue());
}

int Game_Actor::GetBaseMaxSp() const {
Expand Down Expand Up @@ -401,7 +405,7 @@ int Game_Actor::GetBaseAtk(bool mod, bool equip) const {
}
}

return min(max(n, 1), max_other_stat_value());
return Utils::Clamp(n, 1, MaxStatBaseValue());
}

int Game_Actor::GetBaseAtk() const {
Expand Down Expand Up @@ -429,7 +433,7 @@ int Game_Actor::GetBaseDef(bool mod, bool equip) const {
}
}

return min(max(n, 1), max_other_stat_value());
return Utils::Clamp(n, 1, MaxStatBaseValue());
}

int Game_Actor::GetBaseDef() const {
Expand Down Expand Up @@ -457,7 +461,7 @@ int Game_Actor::GetBaseSpi(bool mod, bool equip) const {
}
}

return min(max(n, 1), max_other_stat_value());
return Utils::Clamp(n, 1, MaxStatBaseValue());
}

int Game_Actor::GetBaseSpi() const {
Expand Down Expand Up @@ -485,7 +489,7 @@ int Game_Actor::GetBaseAgi(bool mod, bool equip) const {
}
}

return min(max(n, 1), max_other_stat_value());
return Utils::Clamp(n, 1, MaxStatBaseValue());
}

int Game_Actor::GetBaseAgi() const {
Expand Down
6 changes: 6 additions & 0 deletions src/game_actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ class Game_Actor : public Game_Battler {
*/
Game_Actor(int actor_id);

int MaxHpValue() const override;

int MaxStatBattleValue() const override;

int MaxStatBaseValue() const override;

/**
* Sets up the game actor
* This is automatically called in the constructor.
Expand Down
80 changes: 43 additions & 37 deletions src/game_battlealgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
#include "sprite_battler.h"
#include "utils.h"

static inline int MaxDamageValue() {
return Player::IsRPG2k() ? 999 : 9999;
}

static inline int ToHitPhysical(Game_Battler *source, Game_Battler *target, int to_hit) {
// If target has Restriction "do_nothing", the attack always hits
if (target->GetSignificantRestriction() == RPG::State::Restriction_do_nothing) {
Expand Down Expand Up @@ -681,7 +685,7 @@ void Game_BattleAlgorithm::AlgorithmBase::Apply() {
int atk = GetAffectedAttack();
GetTarget()->ChangeAtkModifier(IsPositive() ? atk : -atk);
if (IsAbsorb()) {
atk = std::max<int>(0, std::min<int>(atk, std::min<int>(999, source->GetBaseAtk() * 2) - source->GetAtk()));
atk = std::max<int>(0, std::min<int>(atk, std::min<int>(source->MaxStatBattleValue(), source->GetBaseAtk() * 2) - source->GetAtk()));
source->ChangeAtkModifier(atk);
}
}
Expand All @@ -690,7 +694,7 @@ void Game_BattleAlgorithm::AlgorithmBase::Apply() {
int def = GetAffectedDefense();
GetTarget()->ChangeDefModifier(IsPositive() ? def : -def);
if (IsAbsorb()) {
def = std::max<int>(0, std::min<int>(def, std::min<int>(999, source->GetBaseAtk() * 2) - source->GetAtk()));
def = std::max<int>(0, std::min<int>(def, std::min<int>(source->MaxStatBattleValue(), source->GetBaseAtk() * 2) - source->GetAtk()));
source->ChangeDefModifier(def);
}
}
Expand All @@ -699,7 +703,7 @@ void Game_BattleAlgorithm::AlgorithmBase::Apply() {
int spi = GetAffectedSpirit();
GetTarget()->ChangeSpiModifier(IsPositive() ? spi : -spi);
if (IsAbsorb()) {
spi = std::max<int>(0, std::min<int>(spi, std::min<int>(999, source->GetBaseAtk() * 2) - source->GetAtk()));
spi = std::max<int>(0, std::min<int>(spi, std::min<int>(source->MaxStatBattleValue(), source->GetBaseAtk() * 2) - source->GetAtk()));
source->ChangeSpiModifier(spi);
}
}
Expand All @@ -708,7 +712,7 @@ void Game_BattleAlgorithm::AlgorithmBase::Apply() {
int agi = GetAffectedAgility();
GetTarget()->ChangeAgiModifier(IsPositive() ? agi : -agi);
if (IsAbsorb()) {
agi = std::max<int>(0, std::min<int>(agi, std::min<int>(999, source->GetBaseAtk() * 2) - source->GetAtk()));
agi = std::max<int>(0, std::min<int>(agi, std::min<int>(source->MaxStatBattleValue(), source->GetBaseAtk() * 2) - source->GetAtk()));
source->ChangeAgiModifier(agi);
}
}
Expand Down Expand Up @@ -915,21 +919,21 @@ bool Game_BattleAlgorithm::Normal::Execute() {
int change = (int)(std::ceil(effect * act_perc / 100.0));
effect += change;
effect *= multiplier;
if(effect < 0) {
effect = 0;
}
if (critical_hit) {
effect *= 3;
} else if(source->IsCharged()) {
effect *= 2;
}
if (GetTarget()->IsDefending()) {
if (GetTarget()->HasStrongDefense()) {
effect /= 3;
effect /= 4;
} else {
effect /= 2;
}
}

effect = Utils::Clamp(effect, 0, MaxDamageValue());

this->hp = effect;

if (GetTarget()->GetHp() - this->hp <= 0) {
Expand Down Expand Up @@ -1075,7 +1079,6 @@ bool Game_BattleAlgorithm::Skill::Execute() {

absorb = false;
this->success = false;
int effect = skill.power;

this->healing =
skill.scope == RPG::Skill::Scope_ally ||
Expand All @@ -1098,25 +1101,30 @@ bool Game_BattleAlgorithm::Skill::Execute() {
}

if (this->healing) {
float mul = GetTarget()->GetAttributeMultiplier(skill.attribute_effects);

effect +=
int effect = skill.power +
source->GetAtk() * skill.physical_rate / 20 +
source->GetSpi() * skill.magical_rate / 40;
effect *= mul;

effect *= GetTarget()->GetAttributeMultiplier(skill.attribute_effects);

effect += (effect * Utils::GetRandomNumber(-skill.variance, skill.variance) / 10);

effect = Utils::Clamp(effect, 0, MaxDamageValue());

if (skill.affect_hp)
this->hp = std::max<int>(0, std::min<int>(effect, GetTarget()->GetMaxHp() - GetTarget()->GetHp()));
if (skill.affect_sp)
this->sp = std::max<int>(0, std::min<int>(effect, GetTarget()->GetMaxSp() - GetTarget()->GetSp()));
if (skill.affect_sp) {
int sp_cost = GetSource() == GetTarget() ? source->CalculateSkillCost(skill.ID) : 0;
this->sp = std::max<int>(0, std::min<int>(effect, GetTarget()->GetMaxSp() - GetTarget()->GetSp() + sp_cost));
}
if (skill.affect_attack)
this->attack = std::max<int>(0, std::min<int>(effect, std::min<int>(999, GetTarget()->GetBaseAtk() * 2) - GetTarget()->GetAtk()));
this->attack = std::max<int>(0, std::min<int>(effect, std::min<int>(GetTarget()->MaxStatBattleValue(), GetTarget()->GetBaseAtk() * 2) - GetTarget()->GetAtk()));
if (skill.affect_defense)
this->defense = std::max<int>(0, std::min<int>(effect, std::min<int>(999, GetTarget()->GetBaseDef() * 2) - GetTarget()->GetDef()));
this->defense = std::max<int>(0, std::min<int>(effect, std::min<int>(GetTarget()->MaxStatBattleValue(), GetTarget()->GetBaseDef() * 2) - GetTarget()->GetDef()));
if (skill.affect_spirit)
this->spirit = std::max<int>(0, std::min<int>(effect, std::min<int>(999, GetTarget()->GetBaseSpi() * 2) - GetTarget()->GetSpi()));
this->spirit = std::max<int>(0, std::min<int>(effect, std::min<int>(GetTarget()->MaxStatBattleValue(), GetTarget()->GetBaseSpi() * 2) - GetTarget()->GetSpi()));
if (skill.affect_agility)
this->agility = std::max<int>(0, std::min<int>(effect, std::min<int>(999, GetTarget()->GetBaseAgi() * 2) - GetTarget()->GetAgi()));
this->agility = std::max<int>(0, std::min<int>(effect, std::min<int>(GetTarget()->MaxStatBattleValue(), GetTarget()->GetBaseAgi() * 2) - GetTarget()->GetAgi()));

this->success = GetAffectedHp() != -1 || GetAffectedSp() != -1 || GetAffectedAttack() > 0
|| GetAffectedDefense() > 0 || GetAffectedSpirit() > 0 || GetAffectedAgility() > 0;
Expand All @@ -1128,30 +1136,26 @@ bool Game_BattleAlgorithm::Skill::Execute() {
this->success = true;
}
}
else if (Utils::PercentChance(to_hit)) {
if (!healing && Utils::PercentChance(to_hit)) {
absorb = skill.absorb_damage;

effect +=
int effect = skill.power +
source->GetAtk() * skill.physical_rate / 20 +
source->GetSpi() * skill.magical_rate / 40;

if (!skill.ignore_defense) {
effect -= GetTarget()->GetDef() * skill.physical_rate / 40;
effect -= GetTarget()->GetSpi() * skill.magical_rate / 80;
}
effect *= GetTarget()->GetAttributeMultiplier(skill.attribute_effects);

if (effect < 0) {
effect = 0;
}

effect += Utils::GetRandomNumber(0, (((effect * skill.variance / 10) + 1) - (effect * skill.variance / 20)) - 1);
effect += (effect * Utils::GetRandomNumber(-skill.variance, skill.variance) / 10);

if (effect < 0)
effect = 0;
effect = Utils::Clamp(effect, 0, MaxDamageValue());

if (skill.affect_hp) {
this->hp = effect /
(GetTarget()->IsDefending() ? GetTarget()->HasStrongDefense() ? 3 : 2 : 1);
(GetTarget()->IsDefending() ? GetTarget()->HasStrongDefense() ? 4 : 2 : 1);

if (IsAbsorb())
this->hp = std::min<int>(hp, GetTarget()->GetHp());
Expand All @@ -1178,7 +1182,9 @@ bool Game_BattleAlgorithm::Skill::Execute() {
this->success = (GetAffectedHp() != -1 && !IsAbsorb()) || (GetAffectedHp() > 0 && IsAbsorb()) || GetAffectedSp() > 0 || GetAffectedAttack() > 0
|| GetAffectedDefense() > 0 || GetAffectedSpirit() > 0 || GetAffectedAgility() > 0;

if (IsAbsorb() && !success)
if (!success &&
((IsAbsorb() && ((GetAffectedHp() == 0 && GetAffectedSp() <= 0) || (GetAffectedHp() <= 0 && GetAffectedSp() == 0))) ||
(!IsAbsorb() && GetAffectedSp() == 0 && GetAffectedHp() == -1)))
return this->success;
}

Expand Down Expand Up @@ -1222,8 +1228,6 @@ bool Game_BattleAlgorithm::Skill::Execute() {
}

void Game_BattleAlgorithm::Skill::Apply() {
AlgorithmBase::Apply();

if (IsFirstAttack()) {
if (item) {
Main_Data::game_party->ConsumeItemUse(item->ID);
Expand All @@ -1233,6 +1237,8 @@ void Game_BattleAlgorithm::Skill::Apply() {
}
}

AlgorithmBase::Apply();

for (auto& sa: shift_attributes) {
GetTarget()->ShiftAttributeRate(sa, healing ? 1 : -1);
}
Expand Down Expand Up @@ -1695,11 +1701,11 @@ bool Game_BattleAlgorithm::SelfDestruct::Execute() {
int change = (int)(std::ceil(effect * act_perc / 100.0));
effect += change;

if (effect < 0)
effect = 0;
effect /= GetTarget()->IsDefending() ? GetTarget()->HasStrongDefense() ? 4 : 2 : 1;

effect = Utils::Clamp(effect, 0, MaxDamageValue());

this->hp = effect / (
GetTarget()->IsDefending() ? GetTarget()->HasStrongDefense() ? 3 : 2 : 1);
this->hp = effect;

if (GetTarget()->GetHp() - this->hp <= 0) {
// Death state
Expand Down Expand Up @@ -1783,7 +1789,7 @@ bool Game_BattleAlgorithm::Escape::Execute() {
float to_hit = std::max(0.0f, 1.5f - ((float)enemy_agi / ally_agi));

// Every failed escape is worth 10% higher escape chance
to_hit += to_hit * Game_Battle::escape_fail_count * 0.1f;
to_hit += Game_Battle::escape_fail_count * 0.1f;

to_hit *= 100;
this->success = Utils::GetRandomNumber(0, 99) < (int)to_hit;
Expand Down
16 changes: 8 additions & 8 deletions src/game_battler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ static int AffectParameter(const int type, const int val) {

int Game_Battler::GetAtk() const {
int base_atk = GetBaseAtk();
int n = min(max(base_atk, 1), 999);
int n = Utils::Clamp(base_atk, 1, MaxStatBaseValue());

for (int16_t i : GetInflictedStates()) {
// States are guaranteed to be valid
Expand All @@ -662,14 +662,14 @@ int Game_Battler::GetAtk() const {

n += atk_modifier;

n = min(max(n, 1), 999);
n = Utils::Clamp(n, 1, MaxStatBattleValue());

return n;
}

int Game_Battler::GetDef() const {
int base_def = GetBaseDef();
int n = min(max(base_def, 1), 999);
int n = Utils::Clamp(base_def, 1, MaxStatBaseValue());

for (int16_t i : GetInflictedStates()) {
// States are guaranteed to be valid
Expand All @@ -682,14 +682,14 @@ int Game_Battler::GetDef() const {

n += def_modifier;

n = min(max(n, 1), 999);
n = Utils::Clamp(n, 1, MaxStatBattleValue());

return n;
}

int Game_Battler::GetSpi() const {
int base_spi = GetBaseSpi();
int n = min(max(base_spi, 1), 999);
int n = Utils::Clamp(base_spi, 1, MaxStatBaseValue());

for (int16_t i : GetInflictedStates()) {
// States are guaranteed to be valid
Expand All @@ -702,14 +702,14 @@ int Game_Battler::GetSpi() const {

n += spi_modifier;

n = min(max(n, 1), 999);
n = Utils::Clamp(n, 1, MaxStatBattleValue());

return n;
}

int Game_Battler::GetAgi() const {
int base_agi = GetBaseAgi();
int n = min(max(base_agi, 1), 999);
int n = Utils::Clamp(base_agi, 1, MaxStatBaseValue());

for (int16_t i : GetInflictedStates()) {
// States are guaranteed to be valid
Expand All @@ -722,7 +722,7 @@ int Game_Battler::GetAgi() const {

n += agi_modifier;

n = min(max(n, 1), 999);
n = Utils::Clamp(n, 1, MaxStatBattleValue());

return n;
}
Expand Down
6 changes: 6 additions & 0 deletions src/game_battler.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ class Game_Battler {
*/
Game_Battler();

virtual int MaxHpValue() const = 0;

virtual int MaxStatBattleValue() const = 0;

virtual int MaxStatBaseValue() const = 0;

/**
* Gets if battler has a state.
*
Expand Down
Loading

0 comments on commit dba6dc0

Please sign in to comment.