Skip to content

Commit

Permalink
many balancing tweaks, see CHANGELOG.md
Browse files Browse the repository at this point in the history
  • Loading branch information
bratkartoffel committed Feb 14, 2023
1 parent 69b4153 commit 0e1903d
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 46 deletions.
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- (impressum) Fix broken de-obfuscation with some browsers
- many balancing tweaks, thanks u/schokoboy!
- Increase production for each plantage level:
- (plantage) increase `production_amount_per_level` `10 -> 30`
- (plantage) increase `production_amount_per_item_id` `30 -> 100`
- Reduce research duration per building level:
- (research_lab) increase `bonus_factor` `0.055 -> 0.10`
- Increase production per research level:
- (research_lab) increase `production_amount_per_level` `12 -> 30`
- (research_lab) increase `production_cost_per_level` `7 -> 25`
- (research_lab) increase `cost_item_id_factor` `100 -> 1000`
- Decrease building time for each building yard level:
- (building_yard) increase `bonus_factor` `0.061 -> 0.08`
- Decrease deposit amount of bank per building level:
- (bank) decrease `bonus_factor_upgrade` `1.75 -> 1.50`
- Level 0: `100.000`
- Level 1: `200.000 -> 150.000`
- Level 2: `350.000 -> 250.000`
- Level 3: `550.000 -> 350.000`
- Level 4: `950.000 -> 550.000`
- Level 5: `1.650.000 -> 800.000`
- Level 6: `2.900.000 -> 1.150.000`
- Level 7: `5.050.000 -> 1.750.000`
- (bank) increase `credit_limit` `-15000 -> -30000`
- Increase credit limit depending on bank building level
- Each level of the bank building will now increase the credit amount by a factor of `3`
- Level 0: `30.000`
- Level 1: `90.000`
- Level 2: `270.000`
- Level 3: `810.000`
- Level 4: `2.430.000`
- Level 5: `7.290.000`
- Level 6: `21.870.000`

### Security

Expand Down
5 changes: 3 additions & 2 deletions actions/bank.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
redirectTo('/?p=bank', 112, __LINE__);
}
$depositLimit = calculateDepositLimit($data['Gebaeude' . building_bank]);
$creditLimit = calculateCreditLimit($data['Gebaeude' . building_bank]);

switch ($art) {
// deposit money
Expand Down Expand Up @@ -59,7 +60,7 @@

// withdraw money
case 2:
if ($data['Bank'] - $betrag < Config::getInt(Config::SECTION_BANK, 'credit_limit')) {
if ($data['Bank'] - $betrag < $creditLimit) {
redirectTo(sprintf('/?p=bank&art=%d&betrag=%f', $art, $betrag), 109, __LINE__);
}

Expand All @@ -68,7 +69,7 @@
'Geld' => +$betrag,
'Bank' => -$betrag
), array(
'Bank + ' . abs(Config::getInt(Config::SECTION_BANK, 'credit_limit')) . ' >= :whr0' => $betrag
'Bank - ' . $betrag . ' >= :whr0' => $creditLimit
)) == 0) {
Database::getInstance()->rollBack();
redirectTo(sprintf('/?p=bank&art=%d&betrag=%f', $art, $betrag), 142, __LINE__);
Expand Down
22 changes: 12 additions & 10 deletions config/config-defaults.ini
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ production_base_amount = 350
; base production cost for all items
production_base_cost = 200
; bonus to production amount for each plantage level
production_amount_per_level = 10
production_amount_per_level = 30
; bonus to production amount for later items
production_amount_per_item_id = 30
production_amount_per_item_id = 100
; maximum duration of a single production (in hours)
production_hours_max = 12
; base income per item and level each cronjob interval (x kg per research level and cronjob run)
Expand All @@ -172,11 +172,11 @@ base_duration = 1900
factor_cost = 1.37
factor_duration = 1.23
; each level of research lab reduces research duration (1 = 100%, 0.5 = 50%, 0 = 0%)
bonus_factor = 0.055
bonus_factor = 0.10
; bonus to production amount for each research level
production_amount_per_level = 12
production_amount_per_level = 30
; malus to production cost for each research level
production_cost_per_level = 7
production_cost_per_level = 25
; base data for researches
research_base_cost = 230
research_base_duration = 2400
Expand All @@ -185,7 +185,7 @@ research_factor_duration = 1.19
; minimum duration of all researches (in seconds)
research_min_duration = 7200
; extra cost for later items
cost_item_id_factor = 100
cost_item_id_factor = 1000

[shop]
; building data for shop
Expand Down Expand Up @@ -226,7 +226,7 @@ base_duration = 2250
factor_cost = 1.40
factor_duration = 1.24
; each level of building yard reduces building duration (1 = 100%, 0.5 = 50%, 0 = 0%)
bonus_factor = 0.061
bonus_factor = 0.08

[school]
; building data for school
Expand Down Expand Up @@ -261,8 +261,8 @@ base_cost = 200000
base_duration = 86400
factor_cost = 1.85
factor_duration = 1.75
; each level of this building increases the deposit amount by that value
bonus_factor_upgrade = 1.75
; each level of this building increases the deposit amount by that factor
bonus_factor_upgrade = 1.5
; minimum interest rate (1 = 100%, 0.5 = 50%, 0 = 0%)
interest_debit_rate_min = 0.011
; maximum interest rate (1 = 100%, 0.5 = 50%, 0 = 0%)
Expand All @@ -275,7 +275,9 @@ interest_credit_rate_max = 0.023
; each level of the building doubles this amount
deposit_limit = 100000
; maximum amount a user may overdraw a bank account
credit_limit = -15000
credit_limit = -30000
; each level of this building increases the credit amount by that factor
credit_limit_factor = 3

[market]
; when retracting an offer from the market, return that amount of the item (1 = 100%, 0.5 = 50%, 0 = 0%)
Expand Down
7 changes: 5 additions & 2 deletions cronjobs/cron.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ function handleInterestRatesAndBaseIncome(Database $database): void

function handleResetDueToDispo(Database $database): void
{
$entries = $database->getAllPlayerIdAndNameBankSmallerEquals(calculateResetCreditLimit());
$entries = $database->getAllPlayerIdAndNameForDispoReset(
Config::getInt(Config::SECTION_BANK, 'credit_limit'),
Config::getFloat(Config::SECTION_BANK, 'credit_limit_factor')
);
foreach ($entries as $entry) {
error_log(sprintf('Resetting player %s/%s', $entry['ID'], $entry['Name']));
$database->begin();
Expand All @@ -90,7 +93,7 @@ function handleResetDueToDispo(Database $database): void
'Von' => 0,
'An' => $entry['ID'],
'Betreff' => 'Account zurückgesetzt',
'Nachricht' => "Nachdem Ihr Kontostand unter " . formatCurrency(calculateResetCreditLimit()) . " gefallen ist wurden Sie gezwungen, Insolvenz anzumelden. Sie haben sich an der Grenze zu Absurdistan einen neuen Pass geholt und versuchen Ihr Glück mit einer neuen Identität nochmal neu"
'Nachricht' => "Nachdem Ihr Kontostand unter " . formatCurrency(calculateResetCreditLimit($entry['Gebaeude' . building_bank])) . " gefallen ist wurden Sie gezwungen, Insolvenz anzumelden. Sie haben sich an der Grenze zu Absurdistan einen neuen Pass geholt und versuchen Ihr Glück mit einer neuen Identität nochmal neu"
)) != 1) {
$database->rollBack();
error_log(sprintf('Could create message after resetting player %d', $entry['ID']));
Expand Down
9 changes: 5 additions & 4 deletions include/database.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1310,18 +1310,19 @@ public function getMessageByIdAndAnOrVonEquals(int $id, int $blm_user): ?array

public function getAllPlayerIdAndBankAndBioladenAndDoenerstandAndBank(): ?array
{
return $this->executeAndExtractRows($this->prepare("SELECT ID, Bank, Gebaeude3, Gebaeude4, Gebaeude9 FROM " . self::TABLE_USERS . " WHERE ID > 0 AND EmailAct IS NULL"));
return $this->executeAndExtractRows($this->prepare("SELECT ID, Bank, Gebaeude" . building_shop . ", Gebaeude" . building_kebab_stand . ", Gebaeude" . building_bank . " FROM " . self::TABLE_USERS . " WHERE ID > 0 AND EmailAct IS NULL"));
}

public function getAllPlayerIdAndResearchLevels(): ?array
{
return $this->executeAndExtractRows($this->prepare("SELECT ID, " . getAllResearchFields() . " FROM " . self::TABLE_USERS . " WHERE ID > 0 AND EmailAct IS NULL"));
}

public function getAllPlayerIdAndNameBankSmallerEquals(float $amount): ?array
public function getAllPlayerIdAndNameForDispoReset(int $creditLimit, float $creditLimitFactor): ?array
{
$stmt = $this->prepare("SELECT ID, Name FROM " . self::TABLE_USERS . " WHERE Bank <= :amount AND ID > 0");
$stmt->bindParam('amount', $amount);
$stmt = $this->prepare("SELECT ID, Name, Gebaeude" . building_bank . " FROM " . self::TABLE_USERS . " WHERE Bank <= :amount * pow(:limitFactor, Gebaeude" . building_bank . ") AND ID > 0");
$stmt->bindParam('amount', $creditLimit);
$stmt->bindParam('limitFactor', $creditLimitFactor);
return $this->executeAndExtractRows($stmt);
}

Expand Down
9 changes: 7 additions & 2 deletions include/functions.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -1313,10 +1313,10 @@ function calculateInterestRates(): array
return $result;
}

function calculateResetCreditLimit(): int
function calculateResetCreditLimit(int $bankLevel): int
{
$resetMedianRates = (Config::getFloat(Config::SECTION_BANK, 'interest_credit_rate_min') + Config::getFloat(Config::SECTION_BANK, 'interest_credit_rate_max')) / 2;
$resetCreditLimit = (int)(Config::getInt(Config::SECTION_BANK, 'credit_limit') * pow(1 + $resetMedianRates, 96));
$resetCreditLimit = (int)(calculateCreditLimit($bankLevel) * pow(1 + $resetMedianRates, 96));
$resetCreditLimit -= 10000 + ($resetCreditLimit % 10000);
return $resetCreditLimit;
}
Expand Down Expand Up @@ -1644,6 +1644,11 @@ function calculateDepositLimit(int $bankLevel): float
return ceil($limit / 50000) * 50000;
}

function calculateCreditLimit(int $bankLevel): float
{
return pow(Config::getFloat(Config::SECTION_BANK, 'credit_limit_factor'), $bankLevel) * Config::getInt(Config::SECTION_BANK, 'credit_limit');
}

function trimAndRemoveControlChars(string $string): string
{
// remove all control characters and trim spaces
Expand Down
4 changes: 2 additions & 2 deletions pages/bank.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
$depositLimit = calculateDepositLimit($data['Gebaeude' . building_bank]);

$resetMedianRates = (Config::getFloat(Config::SECTION_BANK, 'interest_credit_rate_min') + Config::getFloat(Config::SECTION_BANK, 'interest_credit_rate_max')) / 2;
$resetCreditLimit = calculateResetCreditLimit();
$resetCreditLimit = calculateResetCreditLimit($data['Gebaeude' . building_bank]);

?>
<div id="SeitenUeberschrift">
Expand All @@ -31,7 +31,7 @@
alle <?= Config::getInt(Config::SECTION_BASE, 'cron_interval'); ?> Minuten. Die
maximale Summe, die Sie anlegen können,
sind <?= formatCurrency($depositLimit); ?>, Ihr Kreditlimit sind
<span class="red"><?= formatCurrency(Config::getInt(Config::SECTION_BANK, 'credit_limit')); ?></span>.
<span class="red"><?= formatCurrency(calculateCreditLimit($data['Gebaeude' . building_bank])); ?></span>.
</p>
<p>
<span class="red">Wichtig! Falls der Kontostand unter <?= formatCurrency($resetCreditLimit); ?> fällt, wird Ihr Account automatisch resettet!
Expand Down
6 changes: 3 additions & 3 deletions pages/hilfe.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@
Sie haben von Anfang an ein Bankkonto mit ' . formatCurrency(Config::getSection(Config::SECTION_STARTING_VALUES)['Bank']) . ' Startguthaben.
Die maximale Summe, welche Sie zu Beginn einzahlen können liegt bei ' . formatCurrency(Config::getInt(Config::SECTION_BANK, 'deposit_limit')) . '
(Bitte beachten: Bei diesem Betrag bekommen Sie auch keine Zinsen mehr!), die maximale Kreditsumme beträgt ' . formatCurrency(Config::getInt(Config::SECTION_BANK, 'credit_limit')) . '.
(Bitte beachten: Bei diesem Betrag bekommen Sie auch keine Zinsen mehr!), die maximale Kreditsumme beträgt ' . formatCurrency(Config::getInt(Config::SECTION_BANK, 'credit_limit')) . ', steigt jedoch mit jeder Stufe des Bankschliessfaches.
Die Zinsen werden alle ' . Config::getInt(Config::SECTION_BASE, 'cron_interval') . ' Minuten abgerechnet.
Das Geld auf der Bank kann nicht (im Gegensatz zum Bargeld) von anderen Spielern geklaut werden.
Die Kapazität der Bank kann mit Hilfe des Bankschliessfaches je Stufe verdoppelt werden.
Die Kapazität der Bank kann mit Hilfe des Bankschliessfaches je Stufe um den Faktor ' . formatCurrency(Config::getFloat(Config::SECTION_BANK, 'bonus_factor_upgrade'), false) . ' erhöht werden.
[color=red]Wichtig: Falls Ihr Kontostand unter ' . formatCurrency(calculateResetCreditLimit()) . ' fällt, wird Ihr Account automatisch resettet![/color]'
[color=red]Wichtig: Falls Ihr Kontostand unter das Dispo-Limit fällt, wird Ihr Account automatisch resettet![/color]'
),
110 => array(
'Verträge',
Expand Down
12 changes: 6 additions & 6 deletions tests/src/test/java/eu/fraho/blm2/st/BankTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,13 @@ void testWithdrawCreditLimit() {
driver.findElement(By.id("link_bank")).click();

driver.findElement(By.id("auszahlen")).click();
setValue(By.id("betrag"), "65000.01");
setValue(By.id("betrag"), "80000.01");
driver.findElement(By.id("do_transaction")).click();
assertElementPresent(By.id("meldung_109"));

// check new balance
assertText(By.id("cur_bank_account"), "Ihr Kontostand: 50,000.00 €");
assertValue(By.id("betrag"), new BigDecimal("65000.01"));
assertValue(By.id("betrag"), new BigDecimal("80000.01"));
assertText(By.id("stat_money"), "100,000.00 €");
assertText(By.id("stat_bank"), "50,000.00 €");
}
Expand Down Expand Up @@ -217,15 +217,15 @@ void testDepositWithBankSafe() {
driver.findElement(By.id("link_bank")).click();

driver.findElement(By.id("einzahlen")).click();
assertValue(By.id("betrag"), new BigDecimal("130000.00"));
assertValue(By.id("betrag"), new BigDecimal("80000.00"));

driver.findElement(By.id("do_transaction")).click();
assertElementPresent(By.id("meldung_207"));

assertText(By.id("cur_bank_account"), "Ihr Kontostand: 200,000.00 €");
assertText(By.id("cur_bank_account"), "Ihr Kontostand: 150,000.00 €");
assertValue(By.id("betrag"), new BigDecimal("0.00"));
assertText(By.id("stat_money"), "70,000.00 €");
assertText(By.id("stat_bank"), "200,000.00 €");
assertText(By.id("stat_money"), "120,000.00 €");
assertText(By.id("stat_bank"), "150,000.00 €");
}

@Test
Expand Down
20 changes: 10 additions & 10 deletions tests/src/test/java/eu/fraho/blm2/st/PlantageTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ void testPlantAll2Hours() {

driver.findElement(By.id("link_plantage")).click();
setValue(By.id("stunden"), "2");
assertText(By.id("pr_ko_all"), "Kosten: 1,592.00 €");
assertText(By.id("pr_ko_all"), "Kosten: 2,600.00 €");
driver.findElement(By.id("plant_all")).submit();
assertElementPresent(By.id("meldung_207"));
assertElementPresent(By.id("abort_1"));
assertElementPresent(By.id("abort_2"));
assertText(By.id("stat_money"), "13,408.00 €");
assertText(By.id("stat_money"), "12,400.00 €");

driver.findElement(By.id("link_buero")).click();
assertText(By.id("b_s_3"), "1,592.00 €");
assertText(By.id("b_s_3"), "2,600.00 €");
}

@Test
Expand All @@ -46,7 +46,7 @@ void testPlantAll13Hours() {

driver.findElement(By.id("link_plantage")).click();
setValue(By.id("stunden"), "13");
assertText(By.id("pr_ko_all"), "Kosten: 10,348.00 €");
assertText(By.id("pr_ko_all"), "Kosten: 16,900.00 €");
driver.findElement(By.id("plant_all")).submit();
assertElementPresent(By.id("meldung_133"));
}
Expand All @@ -56,20 +56,20 @@ void testPlant12HoursManualAmount() {
WebDriver driver = getDriver();

driver.findElement(By.id("link_plantage")).click();
setValue(By.id("amount_1"), "8448");
setValue(By.id("amount_1"), "16920");
driver.findElement(By.id("plant_1")).submit();
assertElementPresent(By.id("meldung_207"));
assertElementPresent(By.id("abort_1"));
assertElementPresent(By.id("plant_2"));
assertText(By.id("stat_money"), "12,432.00 €");
assertText(By.id("stat_money"), "12,000.00 €");
}

@Test
void testPlantAmountOver12Hours() {
WebDriver driver = getDriver();

driver.findElement(By.id("link_plantage")).click();
setValue(By.id("amount_1"), "8449");
setValue(By.id("amount_1"), "16921");
driver.findElement(By.id("plant_1")).submit();
assertElementPresent(By.id("meldung_125"));
assertElementPresent(By.id("plant_1"));
Expand All @@ -85,15 +85,15 @@ void testPlantAndCancelAfter1Kg() throws InterruptedException {
setValue(By.id("amount_15"), "3");
driver.findElement(By.id("plant_15")).submit();
assertElementPresent(By.id("meldung_207"));
assertText(By.id("stat_money"), "14,999.20 €");
assertText(By.id("stat_money"), "14,999.29 €");
assertElementPresent(By.id("plant_1"));
assertElementPresent(By.id("abort_15"));
Thread.sleep(TimeUnit.SECONDS.toMillis(3));
Thread.sleep(TimeUnit.SECONDS.toMillis(1));
driver.findElement(By.id("abort_15")).click();
driver.switchTo().alert().accept();
assertElementPresent(By.id("meldung_222"));
assertElementPresent(By.id("plant_15"));
assertText(By.id("stat_money"), "14,999.20 €");
assertText(By.id("stat_money"), "14,999.29 €");

driver.findElement(By.id("link_bioladen")).click();
assertText(By.id("cur_amount_15"), "1 kg");
Expand Down
6 changes: 3 additions & 3 deletions tests/src/test/java/eu/fraho/blm2/st/ResearchTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ void testResearchAndCancel() {
assertElementPresent(By.id("meldung_207"));
assertElementPresent(By.id("abort_1"));

assertText(By.id("stat_money"), "4,517.26 €");
assertText(By.id("stat_money"), "3,617.26 €");
driver.findElement(By.id("abort_1")).click();
driver.switchTo().alert().accept();
assertElementPresent(By.id("meldung_222"));

assertElementPresent(By.id("research_1"));
assertText(By.id("stat_money"), "4,879.32 €");
assertText(By.id("stat_money"), "4,654.32 €");

driver.findElement(By.id("link_buero")).click();
assertText(By.id("b_s_2"), "120.68 €");
assertText(By.id("b_s_2"), "345.68 €");
}
}
4 changes: 2 additions & 2 deletions tests/src/test/resources/test-reset-player.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@
Database::getInstance()->updateTableEntry(Database::TABLE_USERS, $id, array('Bank' => 99900, 'Gebaeude9' => 1));
}
if ($testMethod === 'testResetAfterDispoLimit') {
Database::getInstance()->updateTableEntry(Database::TABLE_USERS, $id, array('Bank' => -109000));
Database::getInstance()->updateTableEntry(Database::TABLE_USERS, $id, array('Bank' => -210000));
}
break;

case 'BuildingTests':
Database::getInstance()->updateTableEntry(Database::TABLE_USERS, $id, array(
'Gebaeude' . building_plantage => 8,
'Gebaeude' . building_building_yard => 120,
'Gebaeude' . building_building_yard => 80,
));
break;

Expand Down

0 comments on commit 0e1903d

Please sign in to comment.