Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Battle2k: Always allow escape when first strike + unusable skills fix #1830

Merged
merged 3 commits into from
Jul 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/game_battlealgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1846,8 +1846,8 @@ void Game_BattleAlgorithm::SelfDestruct::Apply() {
}
}

Game_BattleAlgorithm::Escape::Escape(Game_Battler* source) :
AlgorithmBase(Type::Escape, source) {
Game_BattleAlgorithm::Escape::Escape(Game_Battler* source, bool always_succeed) :
AlgorithmBase(Type::Escape, source), always_succeed(always_succeed) {
// no-op
}

Expand Down Expand Up @@ -1893,9 +1893,7 @@ bool Game_BattleAlgorithm::Escape::Execute() {
// Monsters always escape
this->success = true;

// TODO: Preemptive attack has 100% escape ratio

if (source->GetType() == Game_Battler::Type_Ally) {
if (source->GetType() == Game_Battler::Type_Ally && !always_succeed) {
int ally_agi = Main_Data::game_party->GetAverageAgility();
int enemy_agi = Main_Data::game_enemyparty->GetAverageAgility();

Expand Down
4 changes: 3 additions & 1 deletion src/game_battlealgorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -602,13 +602,15 @@ class SelfDestruct : public AlgorithmBase {

class Escape : public AlgorithmBase {
public:
Escape(Game_Battler* source);
Escape(Game_Battler* source, bool always_succeed = false);

std::string GetStartMessage() const override;
int GetSourceAnimationState() const override;
const RPG::Sound* GetStartSe() const override;
bool Execute() override;
void Apply() override;
private:
bool always_succeed = false;
};

class Transform : public AlgorithmBase {
Expand Down
18 changes: 18 additions & 0 deletions src/game_battler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include "game_party_base.h"
#include "game_switches.h"
#include "game_system.h"
#include "game_temp.h"
#include "game_targets.h"
#include "util_macro.h"
#include "main_data.h"
#include "utils.h"
Expand Down Expand Up @@ -172,6 +174,22 @@ bool Game_Battler::IsSkillUsable(int skill_id) const {
return false;
}

if (skill->type == RPG::Skill::Type_escape) {
return !Game_Temp::battle_running && Game_System::GetAllowEscape() && Game_Targets::HasEscapeTarget();
}

if (skill->type == RPG::Skill::Type_teleport) {
return !Game_Temp::battle_running && Game_System::GetAllowTeleport() && Game_Targets::HasTeleportTarget();
}

if (skill->type == RPG::Skill::Type_switch) {
if (Game_Temp::battle_running) {
return skill->occasion_battle;
} else {
return skill->occasion_field;
}
}

// > 10 makes any skill usable
int32_t smallest_physical_rate = 11;
int32_t smallest_magical_rate = 11;
Expand Down
18 changes: 5 additions & 13 deletions src/scene_battle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ void Scene_Battle::Start() {
SetState(State_Start);
}

void Scene_Battle::Continue(SceneType prev_scene) {
// Debug scene / other scene could have changed party status.
status_window->Refresh();
}

void Scene_Battle::TransitionIn(SceneType prev_scene) {
if (prev_scene == Scene::Debug) {
Scene::TransitionIn(prev_scene);
Expand Down Expand Up @@ -563,19 +568,6 @@ void Scene_Battle::CreateEnemyActionSkill(Game_Enemy* enemy, const RPG::EnemyAct
return;
}


switch (skill->type) {
case RPG::Skill::Type_teleport:
case RPG::Skill::Type_escape:
// FIXME: Can enemy use this?
return;
case RPG::Skill::Type_switch:
case RPG::Skill::Type_normal:
case RPG::Skill::Type_subskill:
default:
break;
}

switch (skill->scope) {
case RPG::Skill::Scope_enemy:
enemy->SetBattleAlgorithm(std::make_shared<Game_BattleAlgorithm::Skill>(enemy, Main_Data::game_party->GetRandomActiveBattler(), *skill));
Expand Down
1 change: 1 addition & 0 deletions src/scene_battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Scene_Battle : public Scene {
void Start() override;
void Update() override;

void Continue(SceneType prev_scene) override;
void TransitionIn(SceneType prev_scene) override;
void TransitionOut(SceneType next_scene) override;
void DrawBackground() override;
Expand Down
22 changes: 15 additions & 7 deletions src/scene_battle_rpg2k.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

Scene_Battle_Rpg2k::Scene_Battle_Rpg2k() : Scene_Battle()
{
first_strike = Game_Temp::battle_first_strike;
}

Scene_Battle_Rpg2k::~Scene_Battle_Rpg2k() {
Expand Down Expand Up @@ -328,6 +329,10 @@ void Scene_Battle_Rpg2k::ProcessActions() {
// Everybody acted
actor_index = 0;

if (Game_Battle::GetTurn() > 0) {
first_strike = false;
}

// Go right into next turn if no actors controllable.
if (!Main_Data::game_party->IsAnyControllable()) {
SelectNextActor();
Expand Down Expand Up @@ -1170,7 +1175,7 @@ void Scene_Battle_Rpg2k::Escape() {
if (battle_action_substate == eBegin) {
battle_message_window->Clear();

Game_BattleAlgorithm::Escape escape_alg = Game_BattleAlgorithm::Escape(&(*Main_Data::game_party)[0]);
Game_BattleAlgorithm::Escape escape_alg = Game_BattleAlgorithm::Escape(&(*Main_Data::game_party)[0], first_strike);

auto next_ss = escape_alg.Execute()
? eSuccess
Expand Down Expand Up @@ -1218,9 +1223,7 @@ void Scene_Battle_Rpg2k::SelectNextActor() {
SetState(State_Battle);
NextTurn();

if (!Game_Temp::battle_first_strike || Game_Battle::GetTurn() > 1) {
CreateEnemyActions();
}
CreateEnemyActions();
CreateExecutionOrder();
Game_Battle::RefreshEvents();

Expand Down Expand Up @@ -1322,6 +1325,9 @@ void Scene_Battle_Rpg2k::CreateExecutionOrder() {
}

void Scene_Battle_Rpg2k::CreateEnemyActions() {
if (first_strike) {
return;
}
std::vector<Game_Battler*> enemies;
Main_Data::game_enemyparty->GetActiveBattlers(enemies);

Expand All @@ -1335,8 +1341,10 @@ void Scene_Battle_Rpg2k::CreateEnemyActions() {
const RPG::EnemyAction* action = static_cast<Game_Enemy*>(battler)->ChooseRandomAction();
if (action) {
CreateEnemyAction(static_cast<Game_Enemy*>(battler), action);
} else {
// Enemies with no action list get Null callback
}

if (battler->GetBattleAlgorithm() == nullptr) {
// Enemies with no valid actions get Null action so that their states still process.
battler->SetBattleAlgorithm(std::make_shared<Game_BattleAlgorithm::Null>(battler));
ActionSelectedCallback(battler);
}
Expand Down Expand Up @@ -1415,7 +1423,7 @@ bool Scene_Battle_Rpg2k::DisplayMonstersInMessageWindow() {

if (battle_result_messages_it == battle_result_messages.end()) {
battle_message_window->Clear();
if (Game_Temp::battle_first_strike && !encounter_message_first_strike) {
if (first_strike && !encounter_message_first_strike) {
battle_message_window->Push(Data::terms.special_combat);
encounter_message_first_strike = true;
SetWait(30, 70);
Expand Down
6 changes: 3 additions & 3 deletions src/scene_battle_rpg2k.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,16 +216,16 @@ class Scene_Battle_Rpg2k : public Scene_Battle {
int battle_action_substate_index = 0;

int select_target_flash_count = 0;
bool encounter_message_first_monster = true;
bool encounter_message_first_strike = false;

int battle_action_wait = 0;
int battle_action_min_wait = 0;

bool encounter_message_first_monster = true;
bool encounter_message_first_strike = false;
bool message_box_got_visible = false;
bool move_screen = false;
bool first_strike = false;

int last_turn_check = -1;
};

#endif
4 changes: 3 additions & 1 deletion src/scene_battle_rpg2k3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ void Scene_Battle_Rpg2k3::Update() {
if (action) {
CreateEnemyAction(enemy, action);
}
//FIXME: Do we need to handle invalid actions or empty action list here?
}
}
}
Expand Down Expand Up @@ -1016,7 +1017,8 @@ void Scene_Battle_Rpg2k3::SpecialSelected() {

void Scene_Battle_Rpg2k3::Escape() {

Game_BattleAlgorithm::Escape escape_alg = Game_BattleAlgorithm::Escape(active_actor);
//FIXME: Handle first strike etc.. here.
Game_BattleAlgorithm::Escape escape_alg = Game_BattleAlgorithm::Escape(active_actor, false);
active_actor->SetGauge(0);

bool escape_success = escape_alg.Execute();
Expand Down