Files @ r21584:561d516cfa45
Branch filter:

Location: cpp/openttd-patchpack/source/src/misc_cmd.cpp - annotation

rubidium
(svn r26708) -Codechange: replace C preprocessor with all kinds of options to prevent adding certain things to the result and the sed script to remove everything that shouldn't be in the resulting nfo file but came out of the C preprocessor by a small-ish awk program. This means no more breaking if a C preprocessor decides to add more data to the processed file (like GCC's inclusion of stdc-predef.h when not passing -nostdinc). It furthermore more than halfs the time needed for the assemble step of the extra GRF compilation
r5584:545d748cc681
r5584:545d748cc681
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r9111:983de9c5a848
r6201:2e76eb9a1d7a
r5584:545d748cc681
r8116:df67d3c5e4fd
r8116:df67d3c5e4fd
r20745:b1ebcc10c74a
r8107:82461791b7a2
r8107:82461791b7a2
r5584:545d748cc681
r13521:8a785d107381
r8114:866ed489ed98
r10208:ef8fcc3dc4ca
r10208:ef8fcc3dc4ca
r14174:6999d5f69ce1
r15269:8b901e9e0694
r5584:545d748cc681
r8264:d493cb51fe8a
r8264:d493cb51fe8a
r21383:942c32fb8b0e
r21383:942c32fb8b0e
r15610:623a23fb6560
r15610:623a23fb6560
r5584:545d748cc681
r6481:534c9f0317ec
r10696:8dfe83e30d01
r6909:8484192a9653
r6909:8484192a9653
r10696:8dfe83e30d01
r13057:58af81fcdcf8
r13057:58af81fcdcf8
r5584:545d748cc681
r11090:9276cea703d4
r5584:545d748cc681
r11917:612c11f7ab47
r5584:545d748cc681
r10207:a1fc2f2a33db
r7002:201ff6832d3a
r11725:57bc99fdc1bc
r5584:545d748cc681
r5584:545d748cc681
r6953:acd98f6a2bb8
r6909:8484192a9653
r6909:8484192a9653
r6909:8484192a9653
r10696:8dfe83e30d01
r6909:8484192a9653
r6909:8484192a9653
r10207:a1fc2f2a33db
r6909:8484192a9653
r10696:8dfe83e30d01
r14877:8260fce9fd4a
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r6909:8484192a9653
r6909:8484192a9653
r6957:88dc5fc7fccd
r10207:a1fc2f2a33db
r6957:88dc5fc7fccd
r5584:545d748cc681
r10207:a1fc2f2a33db
r10207:a1fc2f2a33db
r10207:a1fc2f2a33db
r5584:545d748cc681
r5584:545d748cc681
r8230:33d57fce0ec2
r5584:545d748cc681
r5584:545d748cc681
r15610:623a23fb6560
r15610:623a23fb6560
r5584:545d748cc681
r6481:534c9f0317ec
r10696:8dfe83e30d01
r6909:8484192a9653
r6909:8484192a9653
r10696:8dfe83e30d01
r13057:58af81fcdcf8
r13057:58af81fcdcf8
r5584:545d748cc681
r11090:9276cea703d4
r5584:545d748cc681
r11917:612c11f7ab47
r5584:545d748cc681
r11725:57bc99fdc1bc
r5584:545d748cc681
r6957:88dc5fc7fccd
r6909:8484192a9653
r6909:8484192a9653
r6909:8484192a9653
r10696:8dfe83e30d01
r6909:8484192a9653
r6909:8484192a9653
r10207:a1fc2f2a33db
r6909:8484192a9653
r6909:8484192a9653
r10696:8dfe83e30d01
r15031:cef0205b33f5
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r5584:545d748cc681
r5584:545d748cc681
r10207:a1fc2f2a33db
r7002:201ff6832d3a
r11725:57bc99fdc1bc
r5584:545d748cc681
r5584:545d748cc681
r5584:545d748cc681
r10207:a1fc2f2a33db
r10207:a1fc2f2a33db
r10207:a1fc2f2a33db
r5584:545d748cc681
r6950:1a54b1afb12a
r5584:545d748cc681
r5584:545d748cc681
r8013:0e71243088a7
r8013:0e71243088a7
r8013:0e71243088a7
r8013:0e71243088a7
r8013:0e71243088a7
r8013:0e71243088a7
r8013:0e71243088a7
r8013:0e71243088a7
r17820:911c0dc851f5
r17820:911c0dc851f5
r17820:911c0dc851f5
r8013:0e71243088a7
r8013:0e71243088a7
r13521:8a785d107381
r13521:8a785d107381
r13521:8a785d107381
r13521:8a785d107381
r13521:8a785d107381
r5584:545d748cc681
r6481:534c9f0317ec
r11847:235c011992a8
r11847:235c011992a8
r13057:58af81fcdcf8
r13057:58af81fcdcf8
r5584:545d748cc681
r11090:9276cea703d4
r5584:545d748cc681
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r18760:babf79514cd5
r11847:235c011992a8
r8013:0e71243088a7
r13519:c2a8bbec9a15
r13519:c2a8bbec9a15
r13520:b28b2da3bc7b
r13519:c2a8bbec9a15
r13519:c2a8bbec9a15
r13521:8a785d107381
r13519:c2a8bbec9a15
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r13521:8a785d107381
r13521:8a785d107381
r13521:8a785d107381
r13521:8a785d107381
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r11847:235c011992a8
r13521:8a785d107381
r13521:8a785d107381
r13521:8a785d107381
r13521:8a785d107381
r8013:0e71243088a7
r8013:0e71243088a7
r13024:48c81d0b078a
r13024:48c81d0b078a
r5584:545d748cc681
r6950:1a54b1afb12a
r5584:545d748cc681
r5584:545d748cc681
r15610:623a23fb6560
r15610:623a23fb6560
r5584:545d748cc681
r6481:534c9f0317ec
r20744:c2d633f529e4
r5584:545d748cc681
r13057:58af81fcdcf8
r13057:58af81fcdcf8
r5584:545d748cc681
r11090:9276cea703d4
r5584:545d748cc681
r8715:d1fd9abcb279
r5584:545d748cc681
r5584:545d748cc681
r15610:623a23fb6560
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r20745:b1ebcc10c74a
r15610:623a23fb6560
r5584:545d748cc681
r19944:25a78576fb5e
r5584:545d748cc681
r5584:545d748cc681
r6481:534c9f0317ec
r5584:545d748cc681
r10207:a1fc2f2a33db
r13057:58af81fcdcf8
r13057:58af81fcdcf8
r5584:545d748cc681
r11090:9276cea703d4
r5584:545d748cc681
r9413:fcf267325763
r7657:0608e862fd36
r11917:612c11f7ab47
r8230:33d57fce0ec2
r15281:67f5f7a17ea3
r5584:545d748cc681
r5584:545d748cc681
r15051:f68242dc392e
r15281:67f5f7a17ea3
r5584:545d748cc681
r5584:545d748cc681
r10207:a1fc2f2a33db
r15282:8e9c51163c93
r10207:a1fc2f2a33db
r15269:8b901e9e0694
r5584:545d748cc681
r5584:545d748cc681
r10207:a1fc2f2a33db
r5584:545d748cc681
r5584:545d748cc681
/* $Id$ */

/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file misc_cmd.cpp Some misc functions that are better fitted in other files, but never got moved there... */

#include "stdafx.h"
#include "command_func.h"
#include "economy_func.h"
#include "cmd_helper.h"
#include "window_func.h"
#include "textbuf_gui.h"
#include "network/network.h"
#include "network/network_func.h"
#include "strings_func.h"
#include "company_func.h"
#include "company_gui.h"
#include "company_base.h"
#include "core/backup_type.hpp"

#include "table/strings.h"

#include "safeguards.h"

/**
 * Increase the loan of your company.
 * @param tile unused
 * @param flags operation to perform
 * @param p1 amount to increase the loan with, multitude of LOAN_INTERVAL. Only used when p2 == 2.
 * @param p2 when 0: loans LOAN_INTERVAL
 *           when 1: loans the maximum loan permitting money (press CTRL),
 *           when 2: loans the amount specified in p1
 * @param text unused
 * @return the cost of this operation or an error
 */
CommandCost CmdIncreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	Company *c = Company::Get(_current_company);

	if (c->current_loan >= _economy.max_loan) {
		SetDParam(0, _economy.max_loan);
		return_cmd_error(STR_ERROR_MAXIMUM_PERMITTED_LOAN);
	}

	Money loan;
	switch (p2) {
		default: return CMD_ERROR; // Invalid method
		case 0: // Take some extra loan
			loan = LOAN_INTERVAL;
			break;
		case 1: // Take a loan as big as possible
			loan = _economy.max_loan - c->current_loan;
			break;
		case 2: // Take the given amount of loan
			if ((int32)p1 < LOAN_INTERVAL || c->current_loan + (int32)p1 > _economy.max_loan || p1 % LOAN_INTERVAL != 0) return CMD_ERROR;
			loan = p1;
			break;
	}

	/* Overflow protection */
	if (c->money + c->current_loan + loan < c->money) return CMD_ERROR;

	if (flags & DC_EXEC) {
		c->money        += loan;
		c->current_loan += loan;
		InvalidateCompanyWindows(c);
	}

	return CommandCost(EXPENSES_OTHER);
}

/**
 * Decrease the loan of your company.
 * @param tile unused
 * @param flags operation to perform
 * @param p1 amount to decrease the loan with, multitude of LOAN_INTERVAL. Only used when p2 == 2.
 * @param p2 when 0: pays back LOAN_INTERVAL
 *           when 1: pays back the maximum loan permitting money (press CTRL),
 *           when 2: pays back the amount specified in p1
 * @param text unused
 * @return the cost of this operation or an error
 */
CommandCost CmdDecreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	Company *c = Company::Get(_current_company);

	if (c->current_loan == 0) return_cmd_error(STR_ERROR_LOAN_ALREADY_REPAYED);

	Money loan;
	switch (p2) {
		default: return CMD_ERROR; // Invalid method
		case 0: // Pay back one step
			loan = min(c->current_loan, (Money)LOAN_INTERVAL);
			break;
		case 1: // Pay back as much as possible
			loan = max(min(c->current_loan, c->money), (Money)LOAN_INTERVAL);
			loan -= loan % LOAN_INTERVAL;
			break;
		case 2: // Repay the given amount of loan
			if (p1 % LOAN_INTERVAL != 0 || (int32)p1 < LOAN_INTERVAL || p1 > c->current_loan) return CMD_ERROR; // Invalid amount to loan
			loan = p1;
			break;
	}

	if (c->money < loan) {
		SetDParam(0, loan);
		return_cmd_error(STR_ERROR_CURRENCY_REQUIRED);
	}

	if (flags & DC_EXEC) {
		c->money        -= loan;
		c->current_loan -= loan;
		InvalidateCompanyWindows(c);
	}
	return CommandCost();
}

/**
 * In case of an unsafe unpause, we want the
 * user to confirm that it might crash.
 * @param w         unused
 * @param confirmed whether the user confirms his/her action
 */
static void AskUnsafeUnpauseCallback(Window *w, bool confirmed)
{
	if (confirmed) {
		DoCommandP(0, PM_PAUSED_ERROR, 0, CMD_PAUSE);
	}
}

/**
 * Pause/Unpause the game (server-only).
 * Set or unset a bit in the pause mode. If pause mode is zero the game is
 * unpaused. A bitset is used instead of a boolean value/counter to have
 * more control over the game when saving/loading, etc.
 * @param tile unused
 * @param flags operation to perform
 * @param p1 the pause mode to change
 * @param p2 1 pauses, 0 unpauses this mode
 * @param text unused
 * @return the cost of this operation or an error
 */
CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	switch (p1) {
		case PM_PAUSED_SAVELOAD:
		case PM_PAUSED_ERROR:
		case PM_PAUSED_NORMAL:
		case PM_PAUSED_GAME_SCRIPT:
			break;

#ifdef ENABLE_NETWORK
		case PM_PAUSED_JOIN:
		case PM_PAUSED_ACTIVE_CLIENTS:
			if (!_networking) return CMD_ERROR;
			break;
#endif /* ENABLE_NETWORK */

		default: return CMD_ERROR;
	}
	if (flags & DC_EXEC) {
		if (p1 == PM_PAUSED_NORMAL && _pause_mode & PM_PAUSED_ERROR) {
			ShowQuery(
				STR_NEWGRF_UNPAUSE_WARNING_TITLE,
				STR_NEWGRF_UNPAUSE_WARNING,
				NULL,
				AskUnsafeUnpauseCallback
			);
		} else {
#ifdef ENABLE_NETWORK
			PauseMode prev_mode = _pause_mode;
#endif /* ENABLE_NETWORK */

			if (p2 == 0) {
				_pause_mode = _pause_mode & ~p1;
			} else {
				_pause_mode = _pause_mode | p1;
			}

#ifdef ENABLE_NETWORK
			NetworkHandlePauseChange(prev_mode, (PauseMode)p1);
#endif /* ENABLE_NETWORK */
		}

		SetWindowDirty(WC_STATUS_BAR, 0);
		SetWindowDirty(WC_MAIN_TOOLBAR, 0);
	}
	return CommandCost();
}

/**
 * Change the financial flow of your company.
 * @param tile unused
 * @param flags operation to perform
 * @param p1 the amount of money to receive (if positive), or spend (if negative)
 * @param p2 unused
 * @param text unused
 * @return the cost of this operation or an error
 */
CommandCost CmdMoneyCheat(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	return CommandCost(EXPENSES_OTHER, -(int32)p1);
}

/**
 * Change the bank bank balance of a company by inserting or removing money without affecting the loan.
 * @param tile unused
 * @param flags operation to perform
 * @param p1 the amount of money to receive (if positive), or spend (if negative)
 * @param p2 (bit 0-7)  - the company ID.
 *           (bit 8-15) - the expenses type which should register the cost/income @see ExpensesType.
 * @param text unused
 * @return zero cost or an error
 */
CommandCost CmdChangeBankBalance(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	int32 delta = (int32)p1;
	CompanyID company = (CompanyID) GB(p2, 0, 8);
	ExpensesType expenses_type = Extract<ExpensesType, 8, 8>(p2);

	if (!Company::IsValidID(company)) return CMD_ERROR;
	if (expenses_type >= EXPENSES_END) return CMD_ERROR;
	if (_current_company != OWNER_DEITY) return CMD_ERROR;

	if (flags & DC_EXEC) {
		/* Change company bank balance of company. */
		Backup<CompanyByte> cur_company(_current_company, company, FILE_LINE);
		SubtractMoneyFromCompany(CommandCost(expenses_type, -delta));
		cur_company.Restore();
	}

	/* This command doesn't cost anyting for deity. */
	CommandCost zero_cost(expenses_type, 0);
	return zero_cost;
}

/**
 * Transfer funds (money) from one company to another.
 * To prevent abuse in multiplayer games you can only send money to other
 * companies if you have paid off your loan (either explicitly, or implicitly
 * given the fact that you have more money than loan).
 * @param tile unused
 * @param flags operation to perform
 * @param p1 the amount of money to transfer; max 20.000.000
 * @param p2 the company to transfer the money to
 * @param text unused
 * @return the cost of this operation or an error
 */
CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	if (!_settings_game.economy.give_money) return CMD_ERROR;

	const Company *c = Company::Get(_current_company);
	CommandCost amount(EXPENSES_OTHER, min((Money)p1, (Money)20000000LL));
	CompanyID dest_company = (CompanyID)p2;

	/* You can only transfer funds that is in excess of your loan */
	if (c->money - c->current_loan < amount.GetCost() || amount.GetCost() < 0) return CMD_ERROR;
	if (!_networking || !Company::IsValidID(dest_company)) return CMD_ERROR;

	if (flags & DC_EXEC) {
		/* Add money to company */
		Backup<CompanyByte> cur_company(_current_company, dest_company, FILE_LINE);
		SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost()));
		cur_company.Restore();
	}

	/* Subtract money from local-company */
	return amount;
}