mirror of https://github.com/OpenTTD/OpenTTD.git
Feature: Infinite money mode (#11902)
This commit is contained in:
parent
7acf78964f
commit
5a88027a19
|
@ -161,21 +161,6 @@ bool IsCommandAllowedWhilePaused(Commands cmd)
|
|||
return _game_mode == GM_EDITOR || command_type_lookup[_command_proc_table[cmd].type] <= _settings_game.construction.command_pause_level;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This functions returns the money which can be used to execute a command.
|
||||
* This is either the money of the current company or INT64_MAX if there
|
||||
* is no such a company "at the moment" like the server itself.
|
||||
*
|
||||
* @return The available money of a company or INT64_MAX
|
||||
*/
|
||||
Money GetAvailableMoneyForCommand()
|
||||
{
|
||||
CompanyID company = _current_company;
|
||||
if (!Company::IsValidID(company)) return INT64_MAX;
|
||||
return Company::Get(company)->money;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare for calling a command proc.
|
||||
* @param top_level Top level of command execution, i.e. command from a command.
|
||||
|
|
|
@ -42,7 +42,6 @@ void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *cal
|
|||
bool IsValidCommand(Commands cmd);
|
||||
CommandFlags GetCommandFlags(Commands cmd);
|
||||
const char *GetCommandName(Commands cmd);
|
||||
Money GetAvailableMoneyForCommand();
|
||||
bool IsCommandAllowedWhilePaused(Commands cmd);
|
||||
|
||||
template <Commands Tcmd>
|
||||
|
|
|
@ -193,21 +193,49 @@ void InvalidateCompanyWindows(const Company *company)
|
|||
SetWindowDirty(WC_FINANCES, cid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of money that a company has available, or INT64_MAX
|
||||
* if there is no such valid company.
|
||||
*
|
||||
* @param company Company to check
|
||||
* @return The available money of the company or INT64_MAX
|
||||
*/
|
||||
Money GetAvailableMoney(CompanyID company)
|
||||
{
|
||||
if (_settings_game.difficulty.infinite_money) return INT64_MAX;
|
||||
if (!Company::IsValidID(company)) return INT64_MAX;
|
||||
return Company::Get(company)->money;
|
||||
}
|
||||
|
||||
/**
|
||||
* This functions returns the money which can be used to execute a command.
|
||||
* This is either the money of the current company, or INT64_MAX if infinite money
|
||||
* is enabled or there is no such a company "at the moment" like the server itself.
|
||||
*
|
||||
* @return The available money of the current company or INT64_MAX
|
||||
*/
|
||||
Money GetAvailableMoneyForCommand()
|
||||
{
|
||||
return GetAvailableMoney(_current_company);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify whether the company can pay the bill.
|
||||
* @param[in,out] cost Money to pay, is changed to an error if the company does not have enough money.
|
||||
* @return Function returns \c true if the company has enough money, else it returns \c false.
|
||||
* @return Function returns \c true if the company has enough money or infinite money is enabled,
|
||||
* else it returns \c false.
|
||||
*/
|
||||
bool CheckCompanyHasMoney(CommandCost &cost)
|
||||
{
|
||||
if (cost.GetCost() > 0) {
|
||||
if (cost.GetCost() <= 0) return true;
|
||||
if (_settings_game.difficulty.infinite_money) return true;
|
||||
|
||||
const Company *c = Company::GetIfValid(_current_company);
|
||||
if (c != nullptr && cost.GetCost() > c->money) {
|
||||
SetDParam(0, cost.GetCost());
|
||||
cost.MakeError(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ void CompanyAdminBankrupt(CompanyID company_id);
|
|||
void UpdateLandscapingLimits();
|
||||
void UpdateCompanyLiveries(Company *c);
|
||||
|
||||
Money GetAvailableMoney(CompanyID company);
|
||||
Money GetAvailableMoneyForCommand();
|
||||
bool CheckCompanyHasMoney(CommandCost &cost);
|
||||
void SubtractMoneyFromCompany(const CommandCost &cost);
|
||||
void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost &cost);
|
||||
|
|
|
@ -568,6 +568,9 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
|
|||
*/
|
||||
static void CompanyCheckBankrupt(Company *c)
|
||||
{
|
||||
/* If "Infinite money" setting is on, companies should not go bankrupt. */
|
||||
if (_settings_game.difficulty.infinite_money) return;
|
||||
|
||||
/* If the company has money again, it does not go bankrupt */
|
||||
if (c->money - c->current_loan >= -_economy.max_loan) {
|
||||
int previous_months_of_bankruptcy = CeilDiv(c->months_of_bankruptcy, 3);
|
||||
|
|
|
@ -835,6 +835,7 @@ STR_STATUSBAR_AUTOSAVE :{RED}AUTOSAVE
|
|||
STR_STATUSBAR_SAVING_GAME :{RED}* * SAVING GAME * *
|
||||
|
||||
STR_STATUSBAR_SPECTATOR :{WHITE}(spectator)
|
||||
STR_STATUSBAR_INFINITE_MONEY :{WHITE}(infinite money)
|
||||
|
||||
# News message history
|
||||
STR_MESSAGE_HISTORY :{WHITE}Message History
|
||||
|
@ -1287,6 +1288,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Right
|
|||
|
||||
STR_CONFIG_SETTING_SECONDS_VALUE :{COMMA}{NBSP}second{P 0 "" s}
|
||||
|
||||
STR_CONFIG_SETTING_INFINITE_MONEY :Infinite money: {STRING2}
|
||||
STR_CONFIG_SETTING_INFINITE_MONEY_HELPTEXT :Allow unlimited spending and disable bankruptcy of companies
|
||||
|
||||
STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximum initial loan: {STRING2}
|
||||
STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximum amount a company can loan (without taking inflation into account)
|
||||
STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "landscape.h"
|
||||
#include "command_func.h"
|
||||
#include "company_func.h"
|
||||
#include "viewport_func.h"
|
||||
#include "company_base.h"
|
||||
#include "town.h"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "road_internal.h"
|
||||
#include "viewport_func.h"
|
||||
#include "command_func.h"
|
||||
#include "company_func.h"
|
||||
#include "pathfinder/yapf/yapf_cache.h"
|
||||
#include "depot_base.h"
|
||||
#include "newgrf.h"
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
company = ResolveCompanyID(company);
|
||||
if (company == COMPANY_INVALID) return -1;
|
||||
|
||||
return ::Company::Get(company)->money;
|
||||
return GetAvailableMoney((::CompanyID)company);
|
||||
}
|
||||
|
||||
/* static */ Money ScriptCompany::GetLoanAmount()
|
||||
|
|
|
@ -2084,6 +2084,7 @@ static SettingsContainer &GetSettingsTree()
|
|||
|
||||
SettingsPage *accounting = main->Add(new SettingsPage(STR_CONFIG_SETTING_ACCOUNTING));
|
||||
{
|
||||
accounting->Add(new SettingEntry("difficulty.infinite_money"));
|
||||
accounting->Add(new SettingEntry("economy.inflation"));
|
||||
accounting->Add(new SettingEntry("difficulty.initial_interest"));
|
||||
accounting->Add(new SettingEntry("difficulty.max_loan"));
|
||||
|
|
|
@ -114,6 +114,7 @@ struct DifficultySettings {
|
|||
bool line_reverse_mode; ///< reversing at stations or not
|
||||
bool disasters; ///< are disasters enabled
|
||||
byte town_council_tolerance; ///< minimum required town ratings to be allowed to demolish stuff
|
||||
bool infinite_money; ///< whether spending money despite negative balance is allowed
|
||||
};
|
||||
|
||||
/** Settings relating to viewport/smallmap scrolling. */
|
||||
|
|
|
@ -123,6 +123,8 @@ struct StatusBarWindow : Window {
|
|||
case WID_S_RIGHT: {
|
||||
if (_local_company == COMPANY_SPECTATOR) {
|
||||
DrawString(tr, STR_STATUSBAR_SPECTATOR, TC_FROMSTRING, SA_HOR_CENTER);
|
||||
} else if (_settings_game.difficulty.infinite_money) {
|
||||
DrawString(tr, STR_STATUSBAR_INFINITE_MONEY, TC_FROMSTRING, SA_HOR_CENTER);
|
||||
} else {
|
||||
/* Draw company money, if any */
|
||||
const Company *c = Company::GetIfValid(_local_company);
|
||||
|
|
|
@ -298,3 +298,11 @@ min = 0
|
|||
max = 3
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDT_BOOL]
|
||||
var = difficulty.infinite_money
|
||||
def = false
|
||||
str = STR_CONFIG_SETTING_INFINITE_MONEY
|
||||
strhelp = STR_CONFIG_SETTING_INFINITE_MONEY_HELPTEXT
|
||||
cat = SC_BASIC
|
||||
post_cb = [](auto) { SetWindowDirty(WC_STATUS_BAR, 0); }
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "viewport_func.h"
|
||||
#include "viewport_kdtree.h"
|
||||
#include "command_func.h"
|
||||
#include "company_func.h"
|
||||
#include "industry.h"
|
||||
#include "station_base.h"
|
||||
#include "waypoint_base.h"
|
||||
|
|
|
@ -220,7 +220,7 @@ bool Vehicle::NeedsServicing() const
|
|||
* There are a lot more reasons for autoreplace to fail than we can test here reasonably. */
|
||||
bool pending_replace = false;
|
||||
Money needed_money = c->settings.engine_renew_money;
|
||||
if (needed_money > c->money) return false;
|
||||
if (needed_money > GetAvailableMoney(c->index)) return false;
|
||||
|
||||
for (const Vehicle *v = this; v != nullptr; v = (v->type == VEH_TRAIN) ? Train::From(v)->GetNextUnit() : nullptr) {
|
||||
bool replace_when_old = false;
|
||||
|
@ -258,7 +258,7 @@ bool Vehicle::NeedsServicing() const
|
|||
* We want 2*(the price of the new vehicle) without looking at the value of the vehicle we are going to sell. */
|
||||
pending_replace = true;
|
||||
needed_money += 2 * Engine::Get(new_engine)->GetCost();
|
||||
if (needed_money > c->money) return false;
|
||||
if (needed_money > GetAvailableMoney(c->index)) return false;
|
||||
}
|
||||
|
||||
return pending_replace;
|
||||
|
|
Loading…
Reference in New Issue