Skip to content

Commit 6583092

Browse files
committed
add fix-bath-house-bribe-blunders mod
1 parent c0571b7 commit 6583092

File tree

10 files changed

+111
-1
lines changed

10 files changed

+111
-1
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jobs:
1414
- run: cargo build --release
1515
- run: |
1616
mkdir mods
17+
mv target/i686-pc-windows-msvc/release/fix_bath_house_bribe_blunders ./mods/
1718
mv target/i686-pc-windows-msvc/release/fix_damage_to_offside_ship_artillery.dll ./mods/
1819
mv target/i686-pc-windows-msvc/release/fix_invulnerable_ship_artillery_slots.dll ./mods/
1920
mv target/i686-pc-windows-msvc/release/fix_market_hall_production_town.dll ./mods/

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ resolver = "2"
44
members = [
55
"aimcli",
66
"cprcli",
7+
"mod-fix-bath-house-bribe-blunders",
78
"mod-fix-damage-to-offside-ship-artillery",
89
"mod-fix-invulnerable-ship-artillery-slots",
910
"mod-fix-market-hall-production-town",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "mod-fix-bath-house-bribe-blunders"
3+
edition = "2021"
4+
version.workspace = true
5+
6+
[lib]
7+
crate-type = ["cdylib"]
8+
name="fix_bath_house_bribe_blunders"
9+
10+
[dependencies]
11+
log = { workspace = true }
12+
p3-api = { path = "../p3-api" }
13+
hooklet = { workspace = true }
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use std::{arch::global_asm, ffi::c_void};
2+
3+
use hooklet::windows::x86::{deploy_rel32_raw, replace_slice_rwx, X86Rel32Type};
4+
use log::debug;
5+
use p3_api::{game_world::GAME_WORLD_PTR, mods};
6+
7+
const COUNT_BRIBED_COUNCILLORS_PATCH_ADDRESS: u32 = 0x0053AC99;
8+
static COUNT_BRIBED_COUNCILLORS_CONTINUATION: u32 = 0x0053ACA6;
9+
10+
#[no_mangle]
11+
pub unsafe extern "C" fn start() -> u32 {
12+
mods::init_mod();
13+
14+
debug!("Properly set the councillor's briber to -1 if the bribe failed");
15+
match replace_slice_rwx(0x0053AD85, &[0xc6, 0x01, 0xff]) {
16+
Ok(_) => {}
17+
Err(_) => return 1,
18+
}
19+
20+
debug!("Reset annoyed councillors when opening the bath house");
21+
match replace_slice_rwx(0x005B17B7, &[0x90, 0x90]) {
22+
Ok(_) => {}
23+
Err(_) => return 2,
24+
}
25+
26+
debug!("Fix the limit of 2 bribed councillors");
27+
match deploy_rel32_raw(
28+
COUNT_BRIBED_COUNCILLORS_PATCH_ADDRESS,
29+
(&count_bribed_councillors_detour) as *const _ as _,
30+
X86Rel32Type::Jump,
31+
) {
32+
Ok(_) => {}
33+
Err(_) => return 3,
34+
}
35+
36+
0
37+
}
38+
39+
#[no_mangle]
40+
unsafe extern "thiscall" fn count_bribed_councillors(merchant_index: u8, town_index: u8) -> i32 {
41+
debug!("count_bribed_councillors(merchant_index={merchant_index:#x}, town_index={town_index:#x})");
42+
let town = GAME_WORLD_PTR.get_town(town_index);
43+
let mut bribed = 0;
44+
let bribers = town.get_councillor_bribes();
45+
for briber in bribers {
46+
if briber == merchant_index {
47+
bribed += 1;
48+
}
49+
}
50+
51+
debug!("Found {bribed} local councillors already bribed by the merchant");
52+
bribed
53+
}
54+
55+
extern "C" {
56+
static count_bribed_councillors_detour: c_void;
57+
}
58+
59+
global_asm!("
60+
.global {count_bribed_councillors_detour}
61+
{count_bribed_councillors_detour}:
62+
# save regs except eax and edx (not read)
63+
push ecx
64+
65+
push [esi+0x10]
66+
call {count_bribed_councillors}
67+
mov edi, eax
68+
69+
# restore regs
70+
pop ecx
71+
72+
jmp [{continuation}]
73+
",
74+
count_bribed_councillors_detour = sym count_bribed_councillors_detour,
75+
count_bribed_councillors = sym count_bribed_councillors,
76+
continuation = sym COUNT_BRIBED_COUNCILLORS_CONTINUATION);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub(crate) mod ffi;

mod-trading-office-prices-synchronization/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub(crate) unsafe fn synchronize_autotrade_settings() {
4242
}
4343
let stock = stock[i];
4444
let price = setting_prices[i];
45-
45+
4646
OPERATIONS_PTR.enqueue_operation(Operation::OfficeAutotradeSettingChange {
4747
stock,
4848
price,

p3-api/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ num-traits = "0.2"
1313
num-derive = "0.3"
1414
strum = { version = "0.24", features = ["derive"] }
1515
csbindgen = { version = "1.7.0", optional = true }
16+
win_dbg_logger = { workspace = true }
1617

1718
[dev-dependencies]
1819
simple_logger = "4.1"

p3-api/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod facility;
88
pub mod game_world;
99
pub mod merchant;
1010
pub mod missions;
11+
pub mod mods;
1112
pub mod operation;
1213
pub mod operations;
1314
pub mod scheduled_tasks;

p3-api/src/mods.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use std::panic;
2+
3+
use log::error;
4+
5+
pub unsafe fn init_mod() {
6+
let _ = log::set_logger(&win_dbg_logger::DEBUGGER_LOGGER);
7+
log::set_max_level(log::LevelFilter::Trace);
8+
9+
panic::set_hook(Box::new(|p| {
10+
error!("{p}");
11+
}));
12+
}

p3-api/src/town/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ impl TownPtr {
4949
unsafe { self.get(0x670) }
5050
}
5151

52+
pub fn get_councillor_bribes(&self) -> [u8; 4] {
53+
unsafe { self.get(0x6dc) }
54+
}
55+
5256
pub unsafe fn get_first_office_index(&self) -> u16 {
5357
self.get(0x784)
5458
}

0 commit comments

Comments
 (0)