Skip to content

Commit 291a41e

Browse files
authored
Merge pull request #3378 from florianessl/compat/BattlePatches
Support for runtime patches: MonSca, EncounterRandomnessAlert, EXPlus, GuardRevamp
2 parents 2fa4e22 + c9058cf commit 291a41e

16 files changed

Lines changed: 806 additions & 138 deletions

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ add_library(${PROJECT_NAME} OBJECT
204204
src/game_pictures.h
205205
src/game_player.cpp
206206
src/game_player.h
207+
src/game_runtime_patches.cpp
208+
src/game_runtime_patches.h
207209
src/game_quit.cpp
208210
src/game_quit.h
209211
src/game_screen.cpp

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ libeasyrpg_player_a_SOURCES = \
178178
src/game_pictures.h \
179179
src/game_player.cpp \
180180
src/game_player.h \
181+
src/game_runtime_patches.cpp \
182+
src/game_runtime_patches.h \
181183
src/game_screen.cpp \
182184
src/game_screen.h \
183185
src/game_strings.cpp \

src/algo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ int VarianceAdjustEffect(int base, int var) {
171171
}
172172

173173
int AdjustDamageForDefend(int dmg, const Game_Battler& target) {
174+
if (RuntimePatches::GuardRevamp::OverrideDamageAdjustment(dmg, target)) {
175+
return dmg;
176+
}
174177
if (target.IsDefending()) {
175178
dmg /= 2;
176179
if (target.HasStrongDefense()) {

src/game_config_game.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
#include "game_config_game.h"
19+
#include "game_runtime_patches.h"
1920
#include "cmdline_parser.h"
2021
#include "directory_tree.h"
2122
#include "filefinder.h"
@@ -24,8 +25,8 @@
2425
#include "player.h"
2526
#include <cstring>
2627

27-
Game_ConfigGame Game_ConfigGame::Create(CmdlineParser& cp) {
28-
Game_ConfigGame cfg;
28+
void Game_ConfigGame::Initialize(CmdlineParser& cp) {
29+
Game_ConfigGame& cfg = *this;
2930

3031
auto cli_config = FileFinder::Game().OpenFile(EASYRPG_INI_NAME);
3132
if (cli_config) {
@@ -56,8 +57,6 @@ Game_ConfigGame Game_ConfigGame::Create(CmdlineParser& cp) {
5657
cfg.engine = Player::EngineRpg2k3 | Player::EngineMajorUpdated | Player::EngineEnglish;
5758
}
5859
}
59-
60-
return cfg;
6160
}
6261

6362
void Game_ConfigGame::LoadFromArgs(CmdlineParser& cp) {
@@ -88,6 +87,8 @@ void Game_ConfigGame::LoadFromArgs(CmdlineParser& cp) {
8887
patch_rpg2k3_commands.Lock(false);
8988
patch_anti_lag_switch.Lock(0);
9089
patch_direct_menu.Lock(0);
90+
91+
RuntimePatches::LockPatchesAsDiabled();
9192
patch_override = true;
9293
continue;
9394
}
@@ -155,6 +156,10 @@ void Game_ConfigGame::LoadFromArgs(CmdlineParser& cp) {
155156
}
156157
continue;
157158
}
159+
if (RuntimePatches::ParseFromCommandLine(cp)) {
160+
patch_override = true;
161+
continue;
162+
}
158163
if (cp.ParseNext(arg, 6, "--patch")) {
159164
// For backwards compatibility only
160165
for (int i = 0; i < arg.NumValues(); ++i) {
@@ -229,6 +234,10 @@ void Game_ConfigGame::LoadFromStream(Filesystem_Stream::InputStream& is) {
229234
if (patch_direct_menu.FromIni(ini)) {
230235
patch_override = true;
231236
}
237+
238+
if (RuntimePatches::ParseFromIni(ini)) {
239+
patch_override = true;
240+
}
232241
}
233242

234243
void Game_ConfigGame::PrintActivePatches() {
@@ -258,6 +267,8 @@ void Game_ConfigGame::PrintActivePatches() {
258267
add_int(patch_anti_lag_switch);
259268
add_int(patch_direct_menu);
260269

270+
RuntimePatches::DetermineActivePatches(patches);
271+
261272
if (patches.empty()) {
262273
Output::Debug("Patch configuration: None");
263274
} else {

src/game_config_game.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,28 @@ struct Game_ConfigGame {
4949
ConfigParam<int> patch_anti_lag_switch{ "Anti-Lag Switch", "Disable event page refreshes when switch is set", "Patch", "AntiLagSwitch", 0 };
5050
ConfigParam<int> patch_direct_menu{ "Direct Menu", " Allows direct access to subscreens of the default menu", "Patch", "DirectMenu", 0 };
5151

52+
ConfigParam<int> patch_encounter_random_alert_sw{ "Encounter Randomness Alert", "Set troop id to a variable, activate a switch and skip random battle", "Patch", "EncounterAlert.Switch", 0 };
53+
ConfigParam<int> patch_encounter_random_alert_var{ "Encounter Randomness Alert", "Set troop id to a variable, activate a switch and skip random battle", "Patch", "EncounterAlert.Var", 0 };
54+
55+
ConfigParam<int> patch_monsca_maxhp{ "MonSca", "Scales enemy battle stats by variable value. (MaxHP)", "Patch", "MonSca.MaxHP", 0 };
56+
ConfigParam<int> patch_monsca_maxsp{ "MonSca", "Scales enemy battle stats by variable value. (MaxSP)", "Patch", "MonSca.MaxSP", 0 };
57+
ConfigParam<int> patch_monsca_atk{ "MonSca", "Scales enemy battle stats by variable value. (Attack)", "Patch", "MonSca.Attack", 0 };
58+
ConfigParam<int> patch_monsca_def{ "MonSca", "Scales enemy battle stats by variable value. (Defense)", "Patch", "MonSca.Defense", 0 };
59+
ConfigParam<int> patch_monsca_spi{ "MonSca", "Scales enemy battle stats by variable value. (Spirit)", "Patch", "MonSca.Spirit", 0 };
60+
ConfigParam<int> patch_monsca_agi{ "MonSca", "Scales enemy battle stats by variable value. (Agility)", "Patch", "MonSca.Agility", 0 };
61+
ConfigParam<int> patch_monsca_exp{ "MonSca", "Scales enemy battle stats by variable value. (Gained EXP)", "Patch", "MonSca.Experience", 0 };
62+
ConfigParam<int> patch_monsca_gold{ "MonSca", "Scales enemy battle stats by variable value. (Gained Money)", "Patch", "MonSca.Money", 0 };
63+
ConfigParam<int> patch_monsca_item{ "MonSca", "Scales enemy battle stats by variable value. (Gained Item)", "Patch", "MonSca.ItemId", 0 };
64+
ConfigParam<int> patch_monsca_droprate{ "MonSca", "Scales enemy battle stats by variable value. (Item Drop Rate)", "Patch", "MonSca.ItemDropRate", 0 };
65+
ConfigParam<int> patch_monsca_levelscaling{ "MonSca", "Scales enemy battle stats by variable value. (Alternate formula)", "Patch", "MonSca.LevelScaling", 0 };
66+
ConfigParam<int> patch_monsca_plus{ "MonSca", "Scale enemies individually based on troop index", "Patch", "MonSca.Plus", 0 };
67+
68+
ConfigParam<int> patch_explus_var{ "EXPlus", "Boosts party EXP by set percentages", "Patch", "EXPlus.VarExpBoost", 0 };
69+
ConfigParam<int> patch_explusplus_var{ "EXPlus", "Allows for setting party index of given actors to a variable", "Patch", "EXPlus.VarActorInParty", 0 };
70+
71+
ConfigParam<int> patch_guardrevamp_normal{ "GuardRevamp", "Changes damage calculation for defense situations (Normal)", "Patch", "GuardRevamp.NormalDefense", 0 };
72+
ConfigParam<int> patch_guardrevamp_strong{ "GuardRevamp", "Changes damage calculation for defense situations (Strong)", "Patch", "GuardRevamp.StrongDefense", 0 };
73+
5274
// Command line only
5375
BoolConfigParam patch_support{ "Support patches", "When OFF all patch support is disabled", "", "", true };
5476

@@ -58,9 +80,9 @@ struct Game_ConfigGame {
5880
int engine = 0;
5981

6082
/**
61-
* Create a game config from the config file in the game directory, then loads command line arguments.
83+
* Initializes a game config from the config file in the game directory, then loads command line arguments.
6284
*/
63-
static Game_ConfigGame Create(CmdlineParser& cp);
85+
void Initialize(CmdlineParser& cp);
6486

6587
/**
6688
* Load configuration values from a stream;

src/game_enemy.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
// Headers
2222
#include "game_battler.h"
23+
#include "game_runtime_patches.h"
2324
#include "sprite_enemy.h"
2425
#include "player.h"
2526
#include <lcf/rpg/enemy.h>
@@ -327,27 +328,39 @@ inline int Game_Enemy::GetTroopMemberId() const {
327328
}
328329

329330
inline int Game_Enemy::GetBaseMaxHp() const {
330-
return enemy->max_hp;
331+
auto max_hp = enemy->max_hp;
332+
RuntimePatches::MonSca::ModifyMaxHp(*this, max_hp);
333+
return max_hp;
331334
}
332335

333336
inline int Game_Enemy::GetBaseMaxSp() const {
334-
return enemy->max_sp;
337+
auto max_sp = enemy->max_sp;
338+
RuntimePatches::MonSca::ModifyMaxSp(*this, max_sp);
339+
return max_sp;
335340
}
336341

337342
inline int Game_Enemy::GetBaseAtk(Weapon) const {
338-
return enemy->attack;
343+
auto attack = enemy->attack;
344+
RuntimePatches::MonSca::ModifyAtk(*this, attack);
345+
return attack;
339346
}
340347

341348
inline int Game_Enemy::GetBaseDef(Weapon) const {
342-
return enemy->defense;
349+
auto defense = enemy->defense;
350+
RuntimePatches::MonSca::ModifyDef(*this, defense);
351+
return defense;
343352
}
344353

345354
inline int Game_Enemy::GetBaseSpi(Weapon) const {
346-
return enemy->spirit;
355+
auto spirit = enemy->spirit;
356+
RuntimePatches::MonSca::ModifySpi(*this, spirit);
357+
return spirit;
347358
}
348359

349360
inline int Game_Enemy::GetBaseAgi(Weapon) const {
350-
return enemy->agility;
361+
auto agility = enemy->agility;
362+
RuntimePatches::MonSca::ModifyAgi(*this, agility);
363+
return agility;
351364
}
352365

353366
inline int Game_Enemy::GetHp() const {

src/game_enemyparty.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <algorithm>
2121
#include "game_interpreter.h"
2222
#include "game_enemyparty.h"
23+
#include "game_runtime_patches.h"
2324
#include "main_data.h"
2425
#include <lcf/reader_util.h>
2526
#include "utils.h"
@@ -102,7 +103,10 @@ int Game_EnemyParty::GetExp() const {
102103
int sum = 0;
103104
for (auto& enemy: enemies) {
104105
if (enemy.IsDead()) {
105-
sum += enemy.GetExp();
106+
auto exp = enemy.GetExp();
107+
RuntimePatches::MonSca::ModifyExpGained(enemy, exp);
108+
109+
sum += exp;
106110
}
107111
}
108112
return sum;
@@ -112,7 +116,10 @@ int Game_EnemyParty::GetMoney() const {
112116
int sum = 0;
113117
for (auto& enemy: enemies) {
114118
if (enemy.IsDead()) {
115-
sum += enemy.GetMoney();
119+
auto money = enemy.GetMoney();
120+
RuntimePatches::MonSca::ModifyMoneyGained(enemy, money);
121+
122+
sum += money;
116123
}
117124
}
118125
return sum;
@@ -121,10 +128,16 @@ int Game_EnemyParty::GetMoney() const {
121128
void Game_EnemyParty::GenerateDrops(std::vector<int>& out) const {
122129
for (auto& enemy: enemies) {
123130
if (enemy.IsDead()) {
131+
auto drop_id = enemy.GetDropId();
132+
RuntimePatches::MonSca::ModifyItemGained(enemy, drop_id);
133+
124134
// Only roll if the enemy has something to drop
125-
if (enemy.GetDropId() != 0) {
126-
if (Rand::ChanceOf(enemy.GetDropProbability(), 100)) {
127-
out.push_back(enemy.GetDropId());
135+
if (drop_id > 0) {
136+
auto drop_rate = enemy.GetDropProbability();
137+
RuntimePatches::MonSca::ModifyItemDropRate(enemy, drop_rate);
138+
139+
if (Rand::ChanceOf(drop_rate, 100)) {
140+
out.push_back(drop_id);
128141
}
129142
}
130143
}

src/game_interpreter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3566,6 +3566,7 @@ bool Game_Interpreter::CommandConditionalBranch(lcf::rpg::EventCommand const& co
35663566
case 0:
35673567
// Is actor in party
35683568
result = Main_Data::game_party->IsActorInParty(actor_id);
3569+
RuntimePatches::EXPlus::StoreActorPosition(actor_id);
35693570
break;
35703571
case 1:
35713572
// Name
@@ -4847,7 +4848,11 @@ bool Game_Interpreter::CommandManiacKeyInputProcEx(lcf::rpg::EventCommand const&
48474848
}
48484849
} else if (operation == 2) {
48494850
int key_id = ValueOrVariable(com.parameters[2], com.parameters[3]);
4850-
bool key_state = ManiacPatch::GetKeyState(key_id);
4851+
auto key = RuntimePatches::VirtualKeys::VirtualKeyToInputKey(key_id);
4852+
if (key == Input::Keys::NONE) {
4853+
Output::Debug("Maniac KeyInputProcEx: Unsupported keycode {}", key_id);
4854+
}
4855+
bool key_state = Input::IsRawKeyPressed(key);
48514856
Main_Data::game_variables->Set(start_var_id, key_state ? 1 : 0);
48524857
} else {
48534858
Output::Warning("Maniac KeyInputProcEx: Joypad not supported");

src/game_map.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "game_message.h"
3939
#include "game_screen.h"
4040
#include "game_pictures.h"
41+
#include "game_variables.h"
4142
#include "scene_battle.h"
4243
#include "scene_map.h"
4344
#include <lcf/lmu/reader.h>
@@ -1636,6 +1637,11 @@ bool Game_Map::PrepareEncounter(BattleArgs& args) {
16361637

16371638
args.troop_id = encounters[Rand::GetRandomNumber(0, encounters.size() - 1)];
16381639

1640+
if (RuntimePatches::EncounterRandomnessAlert::HandleEncounter(args.troop_id)) {
1641+
//Cancel the battle setup
1642+
return false;
1643+
}
1644+
16391645
if (Feature::HasRpg2kBattleSystem()) {
16401646
if (Rand::ChanceOf(1, 32)) {
16411647
args.first_strike = true;

0 commit comments

Comments
 (0)