|
| 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%. |
0 commit comments