Skip to content

Commit

Permalink
Merge pull request #3295 from MakoInfused/ManiacControlBattle
Browse files Browse the repository at this point in the history
Implement Maniacs Command 3009: ControlBattle
  • Loading branch information
Ghabry authored Dec 21, 2024
2 parents 6a45364 + ed6e15b commit 3bd1298
Show file tree
Hide file tree
Showing 14 changed files with 513 additions and 11 deletions.
17 changes: 17 additions & 0 deletions src/game_battle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,28 @@ void Game_Battle::UpdateAtbGauges() {
const auto multiplier = std::max(1.0, static_cast<double>(275000 - cur_atb) / 55000.0);
increment = Utils::RoundTo<int>(multiplier * increment);
}

ManiacBattleHook(
Game_Interpreter_Battle::ManiacBattleHookType::AtbIncrement,
bat->GetType() == Game_Battler::Type_Enemy,
bat->GetPartyIndex(),
bat->GetAtbGauge(),
increment
);

bat->IncrementAtbGauge(increment);
}
}
}

bool Game_Battle::ManiacBattleHook(Game_Interpreter_Battle::ManiacBattleHookType hook_type, int var1, int var2, int var3, int var4, int var5, int var6) {
return interpreter->ManiacBattleHook(hook_type, var1, var2, var3, var4, var5, var6);
}

bool Game_Battle::ManiacProcessSubEvents() {
return interpreter->ProcessManiacSubEvents();
}

void Game_Battle::ChangeBackground(const std::string& name) {
background_name = name;
}
Expand Down
10 changes: 10 additions & 0 deletions src/game_battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <lcf/rpg/system.h>
#include <lcf/rpg/troop.h>
#include "teleport_target.h"
#include "game_interpreter_battle.h"
#include "utils.h"
#include "point.h"

Expand Down Expand Up @@ -109,6 +110,15 @@ namespace Game_Battle {
*/
void UpdateAtbGauges();

/**
* Convenience function to call a maniacs battle hook, which processes sub-events at any time.
*/
bool ManiacBattleHook(Game_Interpreter_Battle::ManiacBattleHookType hook_type, int var1, int var2, int var3, int var4 = 0, int var5 = 0, int var6 = 0);
/**
* Convenience function to process all maniacs sub-events, and return whether they're currently running
*/
bool ManiacProcessSubEvents();

void ChangeBackground(const std::string& name);

const std::string& GetBackground();
Expand Down
167 changes: 166 additions & 1 deletion src/game_battlealgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ Game_BattleAlgorithm::AlgorithmBase::AlgorithmBase(Type ty, Game_Battler* source
party_target = target;
}

int Game_BattleAlgorithm::AlgorithmBase::GetActionType() {
return -1;
}

int Game_BattleAlgorithm::AlgorithmBase::GetActionId() {
return -1;
}

void Game_BattleAlgorithm::AlgorithmBase::Reset() {
hp = 0;
sp = 0;
Expand Down Expand Up @@ -185,7 +193,20 @@ int Game_BattleAlgorithm::AlgorithmBase::ApplySpEffect() {
// Only absorb the sp that were left
source->ChangeSp(-sp);
}

if (Player::IsPatchManiac()) {
Game_Battle::ManiacBattleHook(
Game_Interpreter_Battle::ManiacBattleHookType::StatChange,
target->GetType() == Game_Battler::Type_Enemy,
target->GetPartyIndex(),
target->GetDisplayX(),
target->GetDisplayY(),
3,
sp
);
}
}

return sp;
}

Expand All @@ -198,6 +219,18 @@ int Game_BattleAlgorithm::AlgorithmBase::ApplyAtkEffect() {
if (IsAbsorbAtk()) {
source->ChangeAtkModifier(-atk);
}

if (Player::IsPatchManiac()) {
Game_Battle::ManiacBattleHook(
Game_Interpreter_Battle::ManiacBattleHookType::StatChange,
target->GetType() == Game_Battler::Type_Enemy,
target->GetPartyIndex(),
target->GetDisplayX(),
target->GetDisplayY(),
4,
atk
);
}
}
return atk;
}
Expand All @@ -211,6 +244,18 @@ int Game_BattleAlgorithm::AlgorithmBase::ApplyDefEffect() {
if (IsAbsorbDef()) {
source->ChangeDefModifier(-def);
}

if (Player::IsPatchManiac()) {
Game_Battle::ManiacBattleHook(
Game_Interpreter_Battle::ManiacBattleHookType::StatChange,
target->GetType() == Game_Battler::Type_Enemy,
target->GetPartyIndex(),
target->GetDisplayX(),
target->GetDisplayY(),
5,
def
);
}
}
return def;
}
Expand All @@ -224,6 +269,18 @@ int Game_BattleAlgorithm::AlgorithmBase::ApplySpiEffect() {
if (IsAbsorbSpi()) {
source->ChangeSpiModifier(-spi);
}

if (Player::IsPatchManiac()) {
Game_Battle::ManiacBattleHook(
Game_Interpreter_Battle::ManiacBattleHookType::StatChange,
target->GetType() == Game_Battler::Type_Enemy,
target->GetPartyIndex(),
target->GetDisplayX(),
target->GetDisplayY(),
6,
spi
);
}
}
return spi;
}
Expand All @@ -237,6 +294,18 @@ int Game_BattleAlgorithm::AlgorithmBase::ApplyAgiEffect() {
if (IsAbsorbAgi()) {
source->ChangeAgiModifier(-agi);
}

if (Player::IsPatchManiac()) {
Game_Battle::ManiacBattleHook(
Game_Interpreter_Battle::ManiacBattleHookType::StatChange,
target->GetType() == Game_Battler::Type_Enemy,
target->GetPartyIndex(),
target->GetDisplayX(),
target->GetDisplayY(),
7,
agi
);
}
}
return agi;
}
Expand Down Expand Up @@ -532,6 +601,26 @@ AlgorithmBase(Type::None, source, source) {
// no-op
}

int Game_BattleAlgorithm::None::GetActionId() {
return lcf::rpg::EnemyAction::Basic_nothing;
}

int Game_BattleAlgorithm::None::GetActionType() {
return lcf::rpg::EnemyAction::Kind_basic;
}

int Game_BattleAlgorithm::Normal::GetActionId() {
if (IsDualAttack()) {
return lcf::rpg::EnemyAction::Basic_dual_attack;
}

return lcf::rpg::EnemyAction::Basic_attack;
}

int Game_BattleAlgorithm::Normal::GetActionType() {
return lcf::rpg::EnemyAction::Kind_basic;
}

Game_BattleAlgorithm::Normal::Normal(Game_Battler* source, Game_Battler* target, int hits_multiplier, Style style) :
AlgorithmBase(Type::Normal, source, target), hits_multiplier(hits_multiplier)
{
Expand Down Expand Up @@ -740,12 +829,16 @@ bool Game_BattleAlgorithm::Normal::vExecute() {
return SetIsSuccess();
}

bool Game_BattleAlgorithm::Normal::IsDualAttack() const {
return GetSource()->GetType() == Game_Battler::Type_Enemy && hits_multiplier == 2;
}

std::string Game_BattleAlgorithm::Normal::GetStartMessage(int line) const {
if (line == 0) {
if (Feature::HasRpg2kBattleSystem()) {
return BattleMessage::GetNormalAttackStartMessage2k(*GetSource());
}
if (GetSource()->GetType() == Game_Battler::Type_Enemy && hits_multiplier == 2) {
if (IsDualAttack()) {
return BattleMessage::GetDoubleAttackStartMessage2k3(*GetSource());
}
}
Expand Down Expand Up @@ -849,6 +942,14 @@ Game_BattleAlgorithm::Skill::Skill(Game_Battler* source, const lcf::rpg::Skill&
{
}

int Game_BattleAlgorithm::Skill::GetActionType() {
return lcf::rpg::EnemyAction::Kind_skill;
}

int Game_BattleAlgorithm::Skill::GetActionId() {
return skill.ID;
}

void Game_BattleAlgorithm::Skill::Init() {
}

Expand Down Expand Up @@ -1236,6 +1337,14 @@ Game_BattleAlgorithm::Item::Item(Game_Battler* source, Game_Party_Base* target,
// no-op
}

int Game_BattleAlgorithm::Item::GetActionType() {
return 3;
}

int Game_BattleAlgorithm::Item::GetActionId() {
return item.ID;
}

bool Game_BattleAlgorithm::Item::vStart() {
Main_Data::game_party->ConsumeItemUse(item.ID);
return true;
Expand Down Expand Up @@ -1340,6 +1449,14 @@ Game_BattleAlgorithm::Defend::Defend(Game_Battler* source) :
source->SetIsDefending(true);
}

int Game_BattleAlgorithm::Defend::GetActionType() {
return lcf::rpg::EnemyAction::Kind_basic;
}

int Game_BattleAlgorithm::Defend::GetActionId() {
return lcf::rpg::EnemyAction::Basic_defense;
}

std::string Game_BattleAlgorithm::Defend::GetStartMessage(int line) const {
if (line == 0) {
if (Feature::HasRpg2kBattleSystem()) {
Expand All @@ -1360,6 +1477,14 @@ AlgorithmBase(Type::Observe, source, source) {
// no-op
}

int Game_BattleAlgorithm::Observe::GetActionType() {
return lcf::rpg::EnemyAction::Kind_basic;
}

int Game_BattleAlgorithm::Observe::GetActionId() {
return lcf::rpg::EnemyAction::Basic_observe;
}

std::string Game_BattleAlgorithm::Observe::GetStartMessage(int line) const {
if (line == 0) {
if (Feature::HasRpg2kBattleSystem()) {
Expand All @@ -1376,6 +1501,14 @@ AlgorithmBase(Type::Charge, source, source) {
// no-op
}

int Game_BattleAlgorithm::Charge::GetActionType() {
return lcf::rpg::EnemyAction::Kind_basic;
}

int Game_BattleAlgorithm::Charge::GetActionId() {
return lcf::rpg::EnemyAction::Basic_charge;
}

std::string Game_BattleAlgorithm::Charge::GetStartMessage(int line) const {
if (line == 0) {
if (Feature::HasRpg2kBattleSystem()) {
Expand All @@ -1396,6 +1529,14 @@ AlgorithmBase(Type::SelfDestruct, source, target) {
// no-op
}

int Game_BattleAlgorithm::SelfDestruct::GetActionType() {
return lcf::rpg::EnemyAction::Kind_basic;
}

int Game_BattleAlgorithm::SelfDestruct::GetActionId() {
return lcf::rpg::EnemyAction::Basic_autodestruction;
}

std::string Game_BattleAlgorithm::SelfDestruct::GetStartMessage(int line) const {
if (line == 0) {
if (Feature::HasRpg2kBattleSystem()) {
Expand Down Expand Up @@ -1450,6 +1591,14 @@ Game_BattleAlgorithm::Escape::Escape(Game_Battler* source) :
// no-op
}

int Game_BattleAlgorithm::Escape::GetActionType() {
return lcf::rpg::EnemyAction::Kind_basic;
}

int Game_BattleAlgorithm::Escape::GetActionId() {
return lcf::rpg::EnemyAction::Basic_escape;
}

std::string Game_BattleAlgorithm::Escape::GetStartMessage(int line) const {
if (line == 0) {
if (Feature::HasRpg2kBattleSystem()) {
Expand Down Expand Up @@ -1487,6 +1636,14 @@ AlgorithmBase(Type::Transform, source, source), new_monster_id(new_monster_id) {
// no-op
}

int Game_BattleAlgorithm::Transform::GetActionType() {
return lcf::rpg::EnemyAction::Kind_transformation;
}

int Game_BattleAlgorithm::Transform::GetActionId() {
return new_monster_id;
}

std::string Game_BattleAlgorithm::Transform::GetStartMessage(int line) const {
if (line == 0 && Feature::HasRpg2kBattleSystem()) {
auto* enemy = lcf::ReaderUtil::GetElement(lcf::Data::enemies, new_monster_id);
Expand All @@ -1509,3 +1666,11 @@ AlgorithmBase(Type::DoNothing, source, source) {
// no-op
}

int Game_BattleAlgorithm::DoNothing::GetActionType() {
return lcf::rpg::EnemyAction::Kind_basic;
}

int Game_BattleAlgorithm::DoNothing::GetActionId() {
return lcf::rpg::EnemyAction::Basic_nothing;
}

Loading

0 comments on commit 3bd1298

Please sign in to comment.