Skip to content

Commit eb66327

Browse files
committed
bath house bribes blunders
1 parent 64602fa commit eb66327

File tree

8 files changed

+112
-5
lines changed

8 files changed

+112
-5
lines changed

src/SUMMARY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
- [Ship Types](./basics/ships.md)
1212
- [Ship Artillery](./basics/ship-artillery.md)
1313
- [Operations](./operations.md)
14+
- [Bath House Bribe Success](./operations/0042-bath-house-bribe-success.md)
15+
- [Bath House Bribe Failure](./operations/0043-bath-house-bribe-failure.md)
1416
- [Tavern Interaction](./operations/0052-tavern-interaction.md)
1517
- [Scheduled Tasks](./scheduled-tasks/0000.md)
1618
- [Update Shipyard Experience](./scheduled-tasks/0006-update-shipyard-experience.md)
@@ -53,6 +55,7 @@
5355
- [Siege Beggar Satisfaction Bonus](./bugs/siege-beggar-satisfaction-bonus.md)
5456
- [Damage to Offside Ship Artillery](./bugs/damage-to-offside-ship-artillery.md)
5557
- [Invulnerable Ship Artillery Slots](./bugs/invulnerable-ship-artillery-slots.md)
58+
- [Bath House Bribes Blunders](./bugs/bath-house-bribes-blunders.md)
5659
- [Patches](./patches.md)
5760
- [High Res](./patches/high-res.md)
5861
- [Increase Alderman "Found Settlement" Mission Limit](./patches/increase-alderman-found-settlement-limit.md)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Bath House Bribes Blunders
2+
3+
## Summary
4+
The bath house bribes are affected by three different bugs:
5+
- If a merchant's offer is lower than the councillor's expectations and the councillor hasn't been bribed by anyone else, the councillor is bribed by the merchant with the index `1`.
6+
- Annoying a councillor in one town affects councillors in all towns.
7+
- Limits on the bribability don't have any effect.
8+
9+
## Details
10+
11+
### Attribution to Merchant `1`
12+
The `handle_operation_bath_house_bribe_failure` function at `0x0053AD10` sets the councillor's briber to `1`, if the councillor was not already bribed by anyone.
13+
14+
This also prevents you from getting the *"Are you there again?! Let me have my bath in peace, please."* line you are supposed to get with annoyed councillors.
15+
Instead you'll get the *"Ah! You're here as well, John Doe? I have only very recently spoken to one of your competitors."* line, since the councillor is now bribed by merchant `1`.
16+
17+
### Unforgiving Bath Houses
18+
The bath house remembers only the index of annoyed local councillors (0-3), and not to which town they belong.
19+
If you annoy the first councillor in one town, the first councillor in every town will stop talking to you, and so forth.
20+
21+
While the annoyed *"Are you there again?! Let me have my bath in peace, please."* line is unreachable in the correct town due to the attribution bug, you do get it if you encounter a councillor with the same index in a different town.
22+
23+
### Limitless Corruption
24+
The `handle_operation_bath_house_bribe_success` function at `0x0053AC50` applies the briber only if a particular value is smaller than 2:
25+
```c
26+
bribed_councillors = 0;
27+
previous_bribing_merchant = static_game_world.field_68_towns[town_index].field_6DC_councillor_bribes[this->args.unknown.arg1];
28+
v6 = 4;
29+
do
30+
{
31+
if (previous_bribing_merchant == merchant_index)
32+
++bribed_councillors;
33+
--v6;
34+
}
35+
while (v6);
36+
merchant = get_merchant(&static_game_world, merchant_index);
37+
old_recent_donations = merchant->field_4BC_recent_donations;
38+
merchant->field_0_money -= this->args.unknown.arg3;
39+
merchant->field_4BC_recent_donations = this->args.unknown.arg3 + old_recent_donations;
40+
merchant_bribe_success_increase_social_reputation(merchant, this->args.unknown.arg4, this->args.unknown.arg3);
41+
if (bribed_councillors < 2) {
42+
static_game_world.field_68_towns[this->args.unknown.arg4].field_6DC_councillor_bribes[this->args.unknown.arg1] = this->args.unknown.arg2;
43+
}
44+
```
45+
46+
Since neither `previous_bribing_merchant` nor `merchant_index` change during the loop, the final value of `bribed_councillors` is always either 0 or 4.
47+
This doesn't make any sense as it is, so it is assumed that `bribed_councillors` was intended to be the amount of already bribed councillors in that town, and that the comparison with 2 was intended to prevent a player from bribing the majority of councillors in one town.
48+
49+
## Fix
50+
All bugs are fixed by the [fox-bath-house-bribe-blunders](https://github.com/P3Modding/p3-lib/tree/master/mod-fix-bath-house-bribe-blunders) mod.
51+
52+
### Attribution to Merchant `1`
53+
The councillor's briber must be set to `-1` instead of `1` if the bribe fails and the councillor is not bribed by anyone else.
54+
The original instruction:
55+
```asm
56+
.text:0053AD85 mov byte ptr [ecx], 1
57+
```
58+
must be replaced with:
59+
```asm
60+
.text:0053AD85 mov byte ptr [ecx], -1
61+
```
62+
63+
### Unforgiving Bath Houses
64+
This cannot be properly fixed easily.
65+
However, resetting the annoyance when opening the bath house is just a small change.
66+
Since the annoyances are reset if the bath house is not opened for 256 ticks, one can replace the conditional jump around the reset code with nops:
67+
```asm
68+
.text:005B17B7 jbe short loc_5B17CC
69+
```
70+
71+
### Limitless Corruption
72+
This issue is fixed by moving the `previous_bribing_merchant` assignment into the loop and using the loop counter instead of the argument to index the bribes array.
73+
74+
## Footnotes
75+
Since the probability of each councillor appearing is just 7%, you can use the [debug bath house IDC script](https://github.com/P3Modding/p3_ida_scripts) to change it to 100%.

src/operations.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ The following operations have been identified:
8787
|0x37|Join Guild|
8888
|0x39|Bathe|
8989
|0x41|Form Militia Squad|
90+
|0x42|Bath House Bribe Success|
91+
|0x43|Bath House Bribe Failure|
9092
|0x52|Tavern Interaction|
9193
|0xc2|Autosave|
9294
|0xc4|Advance Time|
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Bath House Bribe Success
2+
The `handle_operation_bath_house_bribe_success` function at `0x0053AC50` applies the effects of a successful bribe.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Bath House Bribe Failure
2+
The `handle_operation_bath_house_bribe_failure` function at `0x0053AD10` applies the effects of a failed bribe.
3+
4+
The merchant's social reputation in the corresponding town is decreased by `2.0`.
5+
6+
**If the councillor was already successfully bribed by the merchant or not bribed by any merchant, he will now be bribed by the merchant with the index 1.
7+
This is wrong, as discussed in the Known Bugs chapter.**

src/ships/sea-battles/hitboxes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ The jump table at `0x0060AD69` maps intersections of the projectile's path with
5151
This defines the following line-to-location mapping:
5252
![](hitboxes_impact_location.png)
5353

54-
**The mapping is incorrect, as discussed in the Known Bugs chapter**.
54+
**The mapping is incorrect, as discussed in the Known Bugs chapter.**

src/towns/bath-house.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,29 @@ def calculate_bribe_result(amount: int, rank: int, already_bribed: bool):
5555
return BribeResult.FAILED
5656
```
5757

58+
### Result
5859
The result can be identified by the councillor's response:
5960

6061
|Result|Response|
6162
|-|-|
62-
|Ok|"Aha, a bribe eh! But all right, I'll take your gold. We'll see what I can do for you at the appointed time."|
63-
|Good|"Oh, that's a very enticing sum. You can be certain of my loyalty."|
64-
|Failed|"What am I supposed to do with this pittance? You ought to realise yourself, that a man in my position expects a little more from someone of your standing."|
63+
|Ok|*"Aha, a bribe eh! But all right, I'll take your gold. We'll see what I can do for you at the appointed time."*|
64+
|Good|*"Oh, that's a very enticing sum. You can be certain of my loyalty."*|
65+
|Failed|*"What am I supposed to do with this pittance? You ought to realise yourself, that a man in my position expects a little more from someone of your standing."*|
6566

66-
Both `Ok` and `Good` enqueue a *Bath House Bribe Success* operation, while `Failed` enqueues a *Bath House Bribe Failed* operation.
67+
Both `Ok` and `Good` enqueue a *Bath House Bribe Success* operation, while `Failed` enqueues a *Bath House Bribe Failure* operation.
68+
**The failure operation is bugged, as discussed in the Known Bugs chapter.**
69+
70+
### Status
71+
The current status of a councillor can be inferred by his lines:
72+
73+
|Status|Response|
74+
|-|-|
75+
|Bribed by merchant|*"So we meet again, John Doe. I can very well remember how pleasant our last meeting was."*|
76+
|Bribed by other merchant|*"Ah! You're here as well, John Doe? I have only very recently spoken to one of your competitors."*|
77+
|Not bribed by anyone, annoyed|*"Are you there again?! Let me have my bath in peace, please."*|
78+
79+
**The annoyance of the councillor with a given index is bugged and saved globally, as discussed in the Known Bugs chapter.**
80+
81+
### Limits
82+
The success operation has a check which probably should prevent a merchant from bribing more than 2 councillors in one town.
83+
**However, this check is bugged, as discussed in the Known Bugs chapter.**

src/towns/population.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ At `0x00672860` there is a table that contains the daily consumptions for 100 ci
3333
|Carbine|0|0|0|0|
3434

3535
If a town is not under siege and a ware is in oversupply, more of it is consumed.
36+
**TODO clarify**
3637
**TODO pitch consumption (sieged and unsieged), winter/famine/plague modifiers**
3738

3839
## Satisfaction

0 commit comments

Comments
 (0)