Permalink
Browse files

Merge pull request #815 from Tondorian/mergeRequest

Conditions in Battles
  • Loading branch information...
Ghabry committed Mar 14, 2016
2 parents 9f32bd8 + 95e8532 commit 118e900d0522348e2332628402eeba4451e5bab9
Showing with 145 additions and 30 deletions.
  1. +17 −2 src/game_battlealgorithm.cpp
  2. +56 −0 src/game_battler.cpp
  3. +7 −0 src/game_battler.h
  4. +41 −21 src/scene_battle_rpg2k.cpp
  5. +24 −7 src/scene_battle_rpg2k3.cpp
@@ -457,7 +457,6 @@ bool Game_BattleAlgorithm::Normal::Execute() {
Reset();
int to_hit;
if (source->GetType() == Game_Battler::Type_Ally) {
Game_Actor* ally = static_cast<Game_Actor*>(source);
int hit_chance = source->GetHitChance();
@@ -483,12 +482,17 @@ bool Game_BattleAlgorithm::Normal::Execute() {
}
int effect = (source->GetAtk() / 2 - (*current_target)->GetDef() / 4);
if (effect < 0)
effect = 0;
int act_perc = (rand() % 40) - 20;
// Change rounded up
int change = (int)(std::ceil(effect * act_perc / 100.0));
effect += change;
if(effect < 0) {
effect = 0;
}
this->hp = (effect * (critical_hit ? 3 : 1) * (source->IsCharged() ? 2 : 1)) / ((*current_target)->IsDefending() ? 2 : 1);
if ((*current_target)->GetHp() - this->hp <= 0) {
@@ -614,9 +618,15 @@ bool Game_BattleAlgorithm::Skill::Execute() {
// TODO: Phys/Magic attribute: Phys.Attribute /100 x Magic.Attribute /100
// see #480
if(effect < 0) {
effect = 0;
}
effect += rand() % (((effect * skill.variance / 10) + 1) - (effect * skill.variance / 20));
if (effect < 0)
effect = 0;
if (skill.affect_hp) {
this->hp = effect / ((*current_target)->IsDefending() ? 2 : 1);
@@ -644,7 +654,7 @@ bool Game_BattleAlgorithm::Skill::Execute() {
for (int i = 0; i < (int) skill.state_effects.size(); i++) {
if (!skill.state_effects[i])
continue;
if (!healing || rand() % 100 >= skill.hit)
if (!healing && rand() % 100 >= skill.hit)
continue;
this->success = true;
@@ -977,13 +987,18 @@ bool Game_BattleAlgorithm::SelfDestruct::Execute() {
// Like a normal attack, but with double damage and always hitting
// Never crits, ignores charge
int effect = source->GetAtk() - (*current_target)->GetDef() / 2;
if (effect < 0)
effect = 0;
// up to 20% stronger/weaker
int act_perc = (rand() % 40) - 20;
int change = (int)(std::ceil(effect * act_perc / 100.0));
effect += change;
if (effect < 0)
effect = 0;
this->hp = effect / ((*current_target)->IsDefending() ? 2 : 1);;
if ((*current_target)->GetHp() - this->hp <= 0) {
View
@@ -18,6 +18,7 @@
// Headers
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include "player.h"
#include "game_battler.h"
@@ -327,6 +328,61 @@ static bool non_permanent(int state_id) {
return Data::states[state_id - 1].type == RPG::State::Persistence_ends;
}
int Game_Battler::ApplyConditions()
{
int damageTaken = 0;
for (int16_t inflicted : GetInflictedStates()) {
RPG::State state = Data::states[inflicted - 1];
int hp = state.hp_change_val + (int)(std::ceil(GetMaxHp() * state.hp_change_max / 100.0));
int sp = state.sp_change_val + (int)(std::ceil(GetMaxHp() * state.sp_change_max / 100.0));
int source_hp = this->GetHp();
int source_sp = this->GetSp();
int src_hp = 0;
int src_sp = 0;
if (state.hp_change_type == state.ChangeType_lose) {
src_hp = -std::min(source_hp - 1, hp);
if(src_hp > 0) {
src_hp = 0;
}
}
else if(state.hp_change_type == state.ChangeType_gain) {
src_hp = std::min(source_hp, hp);
if(src_hp < 0) {
src_hp = 0;
}
}
else {
src_hp = 0;
}
if (state.sp_change_type == state.ChangeType_lose) {
src_sp = -std::min(source_sp, sp);
if(src_sp > 0) {
src_sp = 0;
}
}
else if(state.sp_change_type == state.ChangeType_gain) {
src_sp = std::min(source_sp, sp);
if(src_sp < 0 ) {
src_sp = 0;
}
}
else {
src_sp = 0;
}
this->ChangeHp(src_hp);
this->ChangeSp(src_sp);
damageTaken += src_hp;
}
if(damageTaken < 0) {
return -damageTaken;
}
else {
return damageTaken;
}
}
void Game_Battler::RemoveBattleStates() {
std::vector<int16_t>& states = GetStates();
View
@@ -58,6 +58,13 @@ class Game_Battler {
*/
std::vector<int16_t> GetInflictedStates() const;
/**
* Apply effects of Conditions to Battler
*
* @return Damage taken to Battler from conditions
*/
int ApplyConditions();
/**
* Gets battler states.
* This returns the raw state list with not inflected states set to 0 and
View
@@ -36,8 +36,8 @@
#include "scene_gameover.h"
Scene_Battle_Rpg2k::Scene_Battle_Rpg2k() : Scene_Battle(),
battle_action_wait(30),
battle_action_state(BattleActionState_Start)
battle_action_wait(0),
battle_action_state(BattleActionState_ConditionHeal)
{
}
@@ -313,6 +313,10 @@ bool Scene_Battle_Rpg2k::ProcessBattleAction(Game_BattleAlgorithm::AlgorithmBase
switch (battle_action_state) {
case BattleActionState_Start:
if (battle_action_wait--) {
return false;
}
battle_action_wait = 30;
battle_message_window->Clear();
if (!action->IsTargetValid()) {
@@ -358,31 +362,47 @@ bool Scene_Battle_Rpg2k::ProcessBattleAction(Game_BattleAlgorithm::AlgorithmBase
Game_System::SePlay(*action->GetStartSe());
}
battle_action_state = BattleActionState_ConditionHeal;
battle_action_state = BattleActionState_Result;
break;
case BattleActionState_ConditionHeal:
if (battle_action_wait--) {
return false;
}
battle_action_wait = 0;
case BattleActionState_ConditionHeal:
if (action->IsFirstAttack()) {
std::vector<int16_t> states = action->GetSource()->NextBattleTurn();
if (!states.empty()) {
std::vector<int16_t> states_to_heal = action->GetSource()->NextBattleTurn();
std::vector<int16_t> states_remaining = action->GetSource()->GetInflictedStates();
action->GetSource()->ApplyConditions();
bool message_to_show = false;
if (!states_to_heal.empty() || !states_remaining.empty()) {
battle_message_window->Clear();
for (std::vector<int16_t>::iterator it = states.begin(); it != states.end(); ++it) {
battle_message_window->Push(action->GetSource()->GetName() + Data::states[(*it) - 1].message_recovery);
for (auto state : states_to_heal) {
if (!Data::states[state - 1].message_recovery.empty()) {
battle_message_window->Push(action->GetSource()->GetName() + Data::states[state- 1].message_recovery);
message_to_show = true;
}
}
for (auto state : states_remaining) {
if (!Data::states[state - 1].message_affected.empty()) {
battle_message_window->Push(action->GetSource()->GetName() + Data::states[state- 1].message_affected);
message_to_show = true;
}
}
if (message_to_show) {
battle_action_wait = 30;
}
else {
battle_action_wait = 0;
}
battle_action_wait = 30;
}
else {
battle_action_wait = 0;
}
}
if (!action->GetTarget()) {
battle_action_state = BattleActionState_Finished;
}
else {
battle_action_state = BattleActionState_Result;
battle_action_state = BattleActionState_Start;
}
break;
@@ -450,12 +470,12 @@ bool Scene_Battle_Rpg2k::ProcessBattleAction(Game_BattleAlgorithm::AlgorithmBase
}
if (action->TargetNext()) {
battle_action_state = BattleActionState_Start;
battle_action_state = BattleActionState_ConditionHeal;
return false;
}
// Reset variables
battle_action_state = BattleActionState_Start;
battle_action_state = BattleActionState_ConditionHeal;
return true;
}
@@ -792,11 +812,11 @@ bool Scene_Battle_Rpg2k::CheckWin() {
std::stringstream ss;
ss << exp << Data::terms.exp_received;
Game_Message::texts.push_back(ss.str());
ss.str("");
ss << Data::terms.gold_recieved_a << " " << money << Data::terms.gold << Data::terms.gold_recieved_b;
Game_Message::texts.push_back(ss.str());
if (money > 0) {
ss.str("");
ss << Data::terms.gold_recieved_a << " " << money << Data::terms.gold << Data::terms.gold_recieved_b;
Game_Message::texts.push_back(ss.str());
}
for (std::vector<int>::iterator it = drops.begin(); it != drops.end(); ++it) {
ss.str("");
ss << Data::items[*it - 1].name << Data::terms.item_recieved;
@@ -530,8 +530,25 @@ bool Scene_Battle_Rpg2k3::ProcessBattleAction(Game_BattleAlgorithm::AlgorithmBas
Sprite_Battler::LoopState_DefaultAnimationAfterFinish);
}
if (action->IsFirstAttack() && action->GetStartSe()) {
Game_System::SePlay(*action->GetStartSe());
if (action->IsFirstAttack()) {
std::vector<Game_Battler*> battlers;
Main_Data::game_party->GetActiveBattlers(battlers);
Main_Data::game_enemyparty->GetActiveBattlers(battlers);
for (auto& b : battlers) {
int damageTaken = b->ApplyConditions();
if (damageTaken != 0) {
DrawFloatText(
b->GetBattleX(),
b->GetBattleY(),
0,
boost::lexical_cast<std::string>(damageTaken),
30);
}
}
if (action->GetStartSe()) {
Game_System::SePlay(*action->GetStartSe());
}
}
battle_action_state = BattleActionState_Result;
@@ -834,11 +851,11 @@ bool Scene_Battle_Rpg2k3::CheckWin() {
std::stringstream ss;
ss << exp << Data::terms.exp_received << "\f";
Game_Message::texts.push_back(ss.str());
ss.str("");
ss << Data::terms.gold_recieved_a << " " << money << Data::terms.gold << Data::terms.gold_recieved_b << "\f";
Game_Message::texts.push_back(ss.str());
if (money > 0) {
ss.str("");
ss << Data::terms.gold_recieved_a << " " << money << Data::terms.gold << Data::terms.gold_recieved_b << "\f";
Game_Message::texts.push_back(ss.str());
}
for(std::vector<int>::iterator it = drops.begin(); it != drops.end(); ++it) {
ss.str("");
ss << Data::items[*it - 1].name << Data::terms.item_recieved << "\f";

0 comments on commit 118e900

Please sign in to comment.