|
| 1 | +# Bath House |
| 2 | + |
| 3 | +## Bribes |
| 4 | +Every town with a bathhouse has 4 councillors which can be bribed. |
| 5 | + |
| 6 | +### Attendance |
| 7 | +Between 0 and 4 bribable councillors are present in the bath house. |
| 8 | +The bath house panel has an array of attendance selection timestamps at offset `0xd4`, whose entries denote when the attendance in a given town will be updated. |
| 9 | +These timestamps are updated to `now + 0x100` when |
| 10 | +- the bath house window is closed. |
| 11 | +- fast forward is activated. |
| 12 | +- the options screen is opened. |
| 13 | +- any window is opened after the bath house window has just been closed. |
| 14 | + |
| 15 | +Therefore, continuously opening an individual bath house locks the current attendance. |
| 16 | + |
| 17 | +Attendance is decided as follows: |
| 18 | +```python |
| 19 | +def will_attend(rand: int): |
| 20 | + return rand % 100 < 7 |
| 21 | +``` |
| 22 | +so each councillor has a 7% chance to attend. |
| 23 | + |
| 24 | +### Price Formula |
| 25 | +The `town_calculate_expected_bribe` function at `0x00529E20` determines the amount of money the merchant needs to offer for the bribe to be successful. |
| 26 | + |
| 27 | +It defines the following *bribe base factors* for each rank: |
| 28 | + |
| 29 | +|Rank|Bribe Base Factor| |
| 30 | +|-|-| |
| 31 | +|Shopkeeper|0| |
| 32 | +|Trader|1| |
| 33 | +|Merchant|2| |
| 34 | +|Travelling Merchant|3| |
| 35 | +|Councillor|5| |
| 36 | +|Patrician|7| |
| 37 | +|Mayor|10| |
| 38 | +|Alderman|15| |
| 39 | + |
| 40 | +The bribe result is calculated as follows: |
| 41 | +```python |
| 42 | +def calculate_expected_bribe(rank: int, already_bribed: bool): |
| 43 | + price = 500 * (rand % 11 + 4 * BRIBE_BASE_FACTORS[rank] + 16) |
| 44 | + if already_bribed: |
| 45 | + price *= 2 |
| 46 | + return price |
| 47 | + |
| 48 | +def calculate_bribe_result(amount: int, rank: int, already_bribed: bool): |
| 49 | + price = calculcate_expected_bribe(rank, already_bribed) |
| 50 | + if amount < price: |
| 51 | + return BribeResult.OK |
| 52 | + elif amount >= price * 1.5: |
| 53 | + return BribeResult.GOOD |
| 54 | + else: |
| 55 | + return BribeResult.FAILED |
| 56 | +``` |
| 57 | + |
| 58 | +The result can be identified by the councillor's response: |
| 59 | + |
| 60 | +|Result|Response| |
| 61 | +|-|-| |
| 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."| |
| 65 | + |
| 66 | +Both `Ok` and `Good` enqueue a *Bath House Bribe Success* operation, while `Failed` enqueues a *Bath House Bribe Failed* operation. |
0 commit comments