diff --git a/src/game_battler.h b/src/game_battler.h index a2c392c124..48ce45d179 100644 --- a/src/game_battler.h +++ b/src/game_battler.h @@ -445,6 +445,11 @@ class Game_Battler { bool IsHidden() const; virtual bool IsImmortal() const; + int GetAtkModifier() const; + int GetDefModifier() const; + int GetSpiModifier() const; + int GetAgiModifier() const; + /** @return true if this battler is in it's party */ virtual bool IsInParty() const = 0; @@ -1049,6 +1054,22 @@ inline bool Game_Battler::IsImmortal() const { return false; } +inline int Game_Battler::GetAtkModifier() const { + return atk_modifier; +} + +inline int Game_Battler::GetDefModifier() const { + return def_modifier; +} + +inline int Game_Battler::GetSpiModifier() const { + return spi_modifier; +} + +inline int Game_Battler::GetAgiModifier() const { + return agi_modifier; +} + constexpr int Game_Battler::GetMaxAtbGauge() { return 300000; } diff --git a/src/game_interpreter_battle.cpp b/src/game_interpreter_battle.cpp index e678e5e10f..a8c4180856 100644 --- a/src/game_interpreter_battle.cpp +++ b/src/game_interpreter_battle.cpp @@ -732,12 +732,125 @@ bool Game_Interpreter_Battle::CommandManiacChangeBattleCommandEx(lcf::rpg::Event return true; } -bool Game_Interpreter_Battle::CommandManiacGetBattleInfo(lcf::rpg::EventCommand const&) { +bool Game_Interpreter_Battle::CommandManiacGetBattleInfo(lcf::rpg::EventCommand const& com) { if (!Player::IsPatchManiac()) { return true; } - Output::Warning("Maniac Patch: Command GetBattleInfo not supported"); + int target_flags = com.parameters[0]; + int target_reference_flags = com.parameters[2]; + int target_reference_identifier = com.parameters[3]; + int information_flags = com.parameters[1]; + int information_identifier = com.parameters[4]; + + int target_id = ValueOrVariable(target_reference_flags, target_reference_identifier); + + auto executeOperationSingle = [information_flags, information_identifier, target_id](Game_Battler* battler, TargetType battler_type) { + if (!battler) { + MissingTargetWarning("CommandManiacGetBattleInfo", battler_type, target_id); + return; + } + + switch (information_flags) + { + case 0: + // parameter buffs: attack, defense, mind, agility + Main_Data::game_variables->Set(information_identifier, battler->GetAtkModifier()); + Main_Data::game_variables->Set(information_identifier + 1, battler->GetDefModifier()); + Main_Data::game_variables->Set(information_identifier + 2, battler->GetSpiModifier()); + Main_Data::game_variables->Set(information_identifier + 3, battler->GetAgiModifier()); + break; + case 1: + { + // states: size, [...state_id] + auto states = lcf::Data::states.size(); + Main_Data::game_variables->Set(information_identifier, states); + for (size_t i = 0; i < states; i++) + { + Main_Data::game_variables->Set(information_identifier + i + 1, battler->HasState(lcf::Data::states.at(i).ID)); + } + break; + } + case 2: + { + // elements: size, [...element_id] + auto elements = lcf::Data::attributes.size(); + Main_Data::game_variables->Set(information_identifier, elements); + for (size_t i = 0; i < elements; i++) + { + Main_Data::game_variables->Set(information_identifier + i + 1, battler->GetAttributeRateShift(lcf::Data::attributes.at(i).ID) + 1); + } + break; + break; + } + case 3: + // others: x, y, can move, defending, charging, appeared + Main_Data::game_variables->Set(information_identifier, battler->GetBattlePosition().x); + Main_Data::game_variables->Set(information_identifier + 1, battler->GetBattlePosition().y); + Main_Data::game_variables->Set(information_identifier + 2, battler->CanAct()); + Main_Data::game_variables->Set(information_identifier + 3, battler->IsDefending()); + Main_Data::game_variables->Set(information_identifier + 4, battler->IsCharged()); + Main_Data::game_variables->Set(information_identifier + 5, !battler->IsHidden()); + break; + } + }; + + auto executeOperationMany = [information_flags](Game_Battler* battler) { + switch (information_flags) + { + case 0: + // list of members + return true; + case 1: + // list of members alive + return !battler->IsDead(); + case 2: + // list of members who can move + return battler->CanAct(); + } + + return false; + }; + + switch (target_flags) { + case 0: + // actor + if (target_id > 0) { + executeOperationSingle(Main_Data::game_actors->GetActor(target_id), Actor); + } + break; + case 1: + // party member + executeOperationSingle(Main_Data::game_party->GetActor(target_id), Member); + break; + case 2: + { + // entire party + auto count = 0; + for (Game_Battler* member : Main_Data::game_party->GetActors()) { + count += executeOperationMany(member); + } + Main_Data::game_variables->Set(information_identifier, count); + break; + } + case 3: + // troop member + if (target_id > 0) { + executeOperationSingle(Main_Data::game_enemyparty->GetEnemy(target_id), Enemy); + } + break; + case 4: + { + // entire troop + auto count = 0; + for (Game_Battler* member : Main_Data::game_enemyparty->GetEnemies()) { + count += executeOperationMany(member); + } + Main_Data::game_variables->Set(information_identifier, count); + break; + } + } + return true; }