1
0
Fork 0

(svn r19665) [1.0] -Backport from trunk:

- Fix: Crash of a dedicated server if the null blitter is overridden and (after a while) there is no company 0 on new year anymore [FS#3749] (r19664) 
- Fix: In rare cases, update of signals could be missed (r19663)
- Fix: Various improvements of command handling, missing error messages (r19658, r19657, r19656, r19655, r19654, r19637, r19633, r19621, r19616, r19605, r19604)
- Fix: Sorting industries by production was broken for NewGRF industries (r19538)
release/1.0
rubidium 2010-04-17 22:27:49 +00:00
parent 9f14d652a9
commit 1f1ad73073
51 changed files with 290 additions and 203 deletions

View File

@ -1,3 +1,50 @@
1.0.1-RC1 (2010-04-17)
------------------------------------------------------------------------
- Feature: [NewGRF] Support for extended text code 0x9A 11, print qword (r19570)
- Feature: Give more detailed error message when trying to build a too long bridge (r19561)
- Feature: Add rail speed limit to land area information window (r19556, r19434)
- Add: [NoAI] AIRail::GetMaxSpeed(RailType) to get the speed limit of railtypes (r19591)
- Change: Sync Debian packaging updates from Debian, but keep building a single package (r19572)
- Fix: Crash of a dedicated server if the null blitter is overridden and (after a while) there is no company 0 on new year anymore [FS#3749] (r19664)
- Fix: In rare cases, update of signals could be missed (r19663)
- Fix: Various improvements of command handling, missing error messages (r19658, r19657, r19656, r19655, r19654, r19637, r19633, r19621, r19616, r19605, r19604)
- Fix: Industry generation failed for large maps and lots of industry types (r19652, r19643)
- Fix: When a company is sold, move connected clients to spectators [FS#3745] (r19651)
- Fix: A client would not be properly moved when moved while joining, e.g. when entering a company's password. This caused the client to be in the wrong company (according to the rest of the clients) and the client being kicked on the first command [FS#3760] (r19648)
- Fix: Trains loaded above the original IDs did not have a default railtypelabel assigned to them, causing them to be unavailable. Could cause desyncs if the multiplayer game was not started from a savegame [FS#3768] (r19647)
- Fix: Do not allow building cacti outside of the desert or rain forest trees outside of the rain forest area. This to prevent people from thinking planting rain forest trees makes the rain forest bigger and thus adds more place to build a lumber mill [FS#3728] (r19644, r19635, r19634)
- Fix: Desync when taking over companies (r19636)
- Fix: Chat message caused glitch when rejoining a network game [FS#3757] (r19629)
- Fix: Desync when a command is received and in the queue while a client starts joining, i.e. save the game state. This can happen in two ways: with frame_freq > 1 a command received in a previous frame might not be executed yet or when a command is received in the same frame as the join but before the savegame is made. In both cases the joining client would not get all commands to get in-sync with the server (and the other clients) (r19620)
- Fix: Company related graphs were not updated correctly after changing the company colour [FS#3763] (r19615)
- Fix: Possible invalid read when server moves client to spectators before he finishes joining [FS#3755] (r19613)
- Fix: Crash when opening a savegame with a waypoint from around 0.4.0 [FS#3756] (r19612)
- Fix: Improve joining behaviour; kicking clients when entering passwords that was just cleared, 'connection lost' for people failing the password (r19610, r19609, r19608, r19607, r19606)
- Fix: Desync debugging; false positives in the cache validity checks and saving/loading the command stream (r19619, r19617, r19602, r19601, r19600, r19596, r19593, r19592, r19589, r19587, r19586)
- Fix: Presence of online content was not properly updated after download due to duplicate slashes in the path (r19600)
- Fix: [NewGRF] Setting industry prop 0x24 to 0 caused empty station names (r19590)
- Fix: Crash when pressing 'h' (non-stop) in the order window of a ship or aircraft [FS#3744] (r19584)
- Fix: Graphs were not properly updated when going toggling keys (i.e. companies) (r19574)
- Fix: The timetable button was not automatically raised [FS#3739] (r19571)
- Fix: [NewGRF] Possible buffer underflow in NewGRF string code (r19569)
- Fix: [NewGRF] Do not return a random colour for unowned industries in var 45; TTDPatch does not seem to set the colour data in that case either and it could lead to desyncs (r19566)
- Fix: Window::OnResize() was not always called while resizing a window causing incorrect windows [FS#3730] (r19563, r19558)
- Fix: Bridge build error message should not show the same message twice (r19560, r19559)
- Fix: [NewGRF] During NewGRF loading, store rail type labels in temporary data and process after loading has finished. This avoids deactivated rail vehicles being reactivated if the climate property is set after the rail type property (r19557, r19502)
- Fix: Improperly scaled cargo payment graph when having lots of cargo (r19550, 19543)
- Fix: [NewGRF] Properties set before property 08 (house, industry, industry tiles) should be ignored, not trigger the NewGRF to be disabled [FS#3725] (r19547)
- Fix: Sorting industries by production was broken for NewGRF industries (r19538)
- Fix: Vehicle details window did not resize correctly after refitting a road vehicle to a longer variant [FS#3720] (r19533)
- Fix: Prevent drawing industries disabled at the smallmap as land tiles when they are built on water (r19523)
- Fix: Tunnels, bridges and roadstops are build with only one roadtype (r19506)
- Fix: Remove same_industry_close setting did not do what it said and caused NewGRF trouble (r19499)
- Fix: Keep number padding intact when cloning vehicle names [FS#3710] (r19498)
- Fix: [NewGRF] Bytes and words get sign-extended for temporary/persistent storage (r19497)
- Fix: Stop reducing the size of the vehicle list after selecting a vehicle with a long description (r19480)
- Fix: Implement custom sound effect for helicopter take-off [FS#3668] (r19364)
- Update: Plural type of Slovak (r19452)
1.0.0 (2010-04-01)
------------------------------------------------------------------------
- Fix: Network clients would crash while connecting to a server with AIs (r19526)

View File

@ -3154,6 +3154,7 @@ showhelp() {
echo " --with-midi=midi define which midi-player to use"
echo " --with-midi-arg=arg define which args to use for the"
echo " midi-player"
echo " --with-libtimidity enables libtimidity support"
echo " --with-allegrol[=allegro-config]"
echo " enables Allegro video driver support"
echo " --with-cocoa enables COCOA video driver (OSX ONLY)"

View File

@ -1,6 +1,6 @@
OpenTTD's known bugs
Last updated: 2010-04-01
Release version: 1.0.0
Last updated: 2010-04-17
Release version: 1.0.1-RC1
------------------------------------------------------------------------
@ -34,8 +34,6 @@ that you can find at: http://bugs.openttd.org
If the bugs are closed but still listed here it means that the bug is fixed
and that the nightlies and next major release will not have that bug.
- 3725 [NewGRF] Incorrect handling of some house action0s
- 3720 When refitting to a vehicle with more trailers, the details view is not made bigger
- 3714 Some corrupted savegames can cause crashes
- 3695 Behaviour inconsistency building railway/road down towards water
- 3651 [OSX] Crash when selecting full screen

View File

@ -1,3 +1,9 @@
openttd (1.0.1~rc1-0) unstable; urgency=low
* New upstream release 1.0.1-RC1
-- Matthijs Kooijman <matthijs@stdin.nl> Sat, 17 Apr 2010 23:36:21 +0000
openttd (1.0.0-1) unstable; urgency=low
* [30a2162] New upstream release 1.0.0. (Closes: #570104)

View File

@ -1,9 +1,9 @@
# Version numbers to update
!define APPV_MAJOR 1
!define APPV_MINOR 0
!define APPV_MAINT 0
!define APPV_BUILD 7
!define APPV_EXTRA ""
!define APPV_MAINT 1
!define APPV_BUILD 0
!define APPV_EXTRA "-RC1"
!define APPNAME "OpenTTD" ; Define application name
!define APPVERSION "${APPV_MAJOR}.${APPV_MINOR}.${APPV_MAINT}${APPV_EXTRA}" ; Define application version

View File

@ -1,6 +1,6 @@
OpenTTD README
Last updated: 2010-04-01
Release version: 1.0.0
Last updated: 2010-04-17
Release version: 1.0.1-RC1
------------------------------------------------------------------------

View File

@ -77,10 +77,10 @@ static void _DoCommandReturnBuildTunnel1(class AIInstance *instance)
uint type = 0;
if (vehicle_type == AIVehicle::VT_ROAD) {
type |= (TRANSPORT_ROAD << 9);
type |= (TRANSPORT_ROAD << 8);
type |= ::RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType());
} else {
type |= (TRANSPORT_RAIL << 9);
type |= (TRANSPORT_RAIL << 8);
type |= AIRail::GetCurrentRailType();
}

View File

@ -237,9 +237,10 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height)
*/
CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (!IsEngineBuildable(p1, VEH_AIRCRAFT, _current_company)) return_cmd_error(STR_ERROR_AIRCRAFT_NOT_AVAILABLE);
EngineID eid = GB(p1, 0, 16);
if (!IsEngineBuildable(eid, VEH_AIRCRAFT, _current_company)) return_cmd_error(STR_ERROR_AIRCRAFT_NOT_AVAILABLE);
const Engine *e = Engine::Get(p1);
const Engine *e = Engine::Get(eid);
const AircraftVehicleInfo *avi = &e->u.air;
CommandCost value(EXPENSES_NEW_VEHICLES, e->GetCost());
@ -252,7 +253,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
if (!IsHangarTile(tile) || !IsTileOwner(tile, _current_company)) return CMD_ERROR;
/* Prevent building aircraft types at places which can't handle them */
if (!CanVehicleUseStation(p1, Station::GetByTile(tile))) return CMD_ERROR;
if (!CanVehicleUseStation(eid, Station::GetByTile(tile))) return CMD_ERROR;
/* We will need to allocate 2 or 3 vehicle structs, depending on type */
if (!Vehicle::CanAllocateItem(avi->subtype & AIR_CTOL ? 2 : 3)) {
@ -299,8 +300,8 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
v->max_speed = avi->max_speed;
v->acceleration = avi->acceleration;
v->engine_type = p1;
u->engine_type = p1;
v->engine_type = eid;
u->engine_type = eid;
v->subtype = (avi->subtype & AIR_CTOL ? AIR_AIRCRAFT : AIR_HELICOPTER);
v->UpdateDeltaXY(INVALID_DIR);
@ -362,7 +363,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
/* Aircraft with 3 vehicles (chopper)? */
if (v->subtype == AIR_HELICOPTER) {
Aircraft *w = new Aircraft();
w->engine_type = p1;
w->engine_type = eid;
w->direction = DIR_N;
w->owner = _current_company;
w->x_pos = v->x_pos;
@ -387,7 +388,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
if (IsLocalCompany())
InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Aircraft window
Company::Get(_current_company)->num_engines[p1]++;
Company::Get(_current_company)->num_engines[eid]++;
}
return value;

View File

@ -12,25 +12,16 @@
#ifndef CMD_HELPER_H
#define CMD_HELPER_H
#include "direction_type.h"
#include "road_type.h"
#include "core/enum_type.hpp"
template<uint N> static inline void ExtractValid();
template<> inline void ExtractValid<1>() {}
template<typename T> struct ExtractBits;
template<> struct ExtractBits<Axis> { static const uint Count = 1; };
template<> struct ExtractBits<DiagDirection> { static const uint Count = 2; };
template<> struct ExtractBits<RoadBits> { static const uint Count = 4; };
template<typename T, uint N, typename U> static inline T Extract(U v)
template<typename T, uint S, uint N, typename U> static inline T Extract(U v)
{
/* Check if there are enough bits in v */
ExtractValid<N + ExtractBits<T>::Count <= sizeof(U) * 8>();
return (T)GB(v, N, ExtractBits<T>::Count);
assert_tcompile(N == EnumPropsT<T>::num_bits);
assert_tcompile(S + N <= sizeof(U) * 8);
assert_tcompile(EnumPropsT<T>::end <= (1 << N));
U masked = GB(v, S, N);
return IsInsideMM(masked, EnumPropsT<T>::begin, EnumPropsT<T>::end) ? (T)masked : EnumPropsT<T>::invalid;
}
#endif

View File

@ -678,6 +678,9 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
/* If we're needing more money and we haven't done
* anything yet, ask for the money! */
if (_additional_cash_required != 0 && res2.GetCost() == 0) {
/* It could happen we removed rail, thus gained money, and deleted something else.
* So make sure the signal buffer is empty even in this case */
UpdateSignalsInBuffer();
SetDParam(0, _additional_cash_required);
return_dcpi(CommandCost(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY), false);
}

View File

@ -15,6 +15,7 @@
#include "company_gui.h"
#include "town.h"
#include "news_func.h"
#include "cmd_helper.h"
#include "command_func.h"
#include "network/network.h"
#include "network/network_func.h"
@ -894,14 +895,11 @@ CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32
*/
CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (p2 >= 16) return CMD_ERROR; // max 16 colours
Colours colour = (Colours)p2;
LiveryScheme scheme = (LiveryScheme)GB(p1, 0, 8);
Colours colour = Extract<Colours, 0, 4>(p2);
LiveryScheme scheme = Extract<LiveryScheme, 0, 8>(p1);
byte state = GB(p1, 8, 2);
if (scheme >= LS_END || state >= 3) return CMD_ERROR;
if (scheme >= LS_END || state >= 3 || colour == INVALID_COLOUR) return CMD_ERROR;
Company *c = Company::Get(_current_company);

View File

@ -58,14 +58,16 @@ template <typename Tenum_t> struct EnumPropsT;
* @param Tbegin first valid value from the contiguous range (i.e. TRACK_BEGIN)
* @param Tend one past the last valid value from the contiguous range (i.e. TRACK_END)
* @param Tinvalid value used as invalid value marker (i.e. INVALID_TRACK)
* @param Tnum_bits Number of bits for storing the enum in command parameters
*/
template <typename Tenum_t, typename Tstorage_t, Tenum_t Tbegin, Tenum_t Tend, Tenum_t Tinvalid>
template <typename Tenum_t, typename Tstorage_t, Tenum_t Tbegin, Tenum_t Tend, Tenum_t Tinvalid, uint Tnum_bits = 8 * sizeof(Tstorage_t)>
struct MakeEnumPropsT {
typedef Tenum_t type; ///< enum type (i.e. Trackdir)
typedef Tstorage_t storage; ///< storage type (i.e. byte)
static const Tenum_t begin = Tbegin; ///< lowest valid value (i.e. TRACKDIR_BEGIN)
static const Tenum_t end = Tend; ///< one after the last valid value (i.e. TRACKDIR_END)
static const Tenum_t invalid = Tinvalid; ///< what value is used as invalid value (i.e. INVALID_TRACKDIR)
static const uint num_bits = Tnum_bits; ///< Number of bits for storing the enum in command parameters
};

View File

@ -41,7 +41,7 @@ enum Direction {
DECLARE_POSTFIX_INCREMENT(Direction);
/** Define basic enum properties */
template <> struct EnumPropsT<Direction> : MakeEnumPropsT<Direction, byte, DIR_BEGIN, DIR_END, INVALID_DIR> {};
template <> struct EnumPropsT<Direction> : MakeEnumPropsT<Direction, byte, DIR_BEGIN, DIR_END, INVALID_DIR, 3> {};
typedef TinyEnumT<Direction> DirectionByte; // typedefing-enumification of Direction
@ -91,7 +91,7 @@ enum DiagDirection {
DECLARE_POSTFIX_INCREMENT(DiagDirection);
/** Define basic enum properties */
template <> struct EnumPropsT<DiagDirection> : MakeEnumPropsT<DiagDirection, byte, DIAGDIR_BEGIN, DIAGDIR_END, INVALID_DIAGDIR> {};
template <> struct EnumPropsT<DiagDirection> : MakeEnumPropsT<DiagDirection, byte, DIAGDIR_BEGIN, DIAGDIR_END, INVALID_DIAGDIR, 2> {};
typedef TinyEnumT<DiagDirection> DiagDirectionByte; // typedefing-enumification of DiagDirection
@ -130,5 +130,6 @@ enum Axis {
AXIS_END, ///< Used for iterations
INVALID_AXIS = 0xFF, ///< Flag for an invalid Axis
};
template <> struct EnumPropsT<Axis> : MakeEnumPropsT<Axis, byte, AXIS_X, AXIS_END, INVALID_AXIS, 1> {};
#endif /* DIRECTION_TYPE_H */

View File

@ -1488,12 +1488,12 @@ extern int GetAmountOwnedBy(const Company *c, Owner owner);
CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
CommandCost cost(EXPENSES_OTHER);
Company *c = Company::GetIfValid(p1);
CompanyID target_company = (CompanyID)p1;
Company *c = Company::GetIfValid(target_company);
/* Check if buying shares is allowed (protection against modified clients)
* Cannot buy own shares */
if (c == NULL || !_settings_game.economy.allow_shares || _current_company == (CompanyID)p1) return CMD_ERROR;
if (c == NULL || !_settings_game.economy.allow_shares || _current_company == target_company) return CMD_ERROR;
/* Protect new companies from hostile takeovers */
if (_cur_year - c->inaugurated_year < 6) return_cmd_error(STR_ERROR_PROTECTED);
@ -1519,7 +1519,7 @@ CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1,
break;
}
}
SetWindowDirty(WC_COMPANY, p1);
SetWindowDirty(WC_COMPANY, target_company);
}
return cost;
}
@ -1534,11 +1534,12 @@ CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1,
*/
CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
Company *c = Company::GetIfValid(p1);
CompanyID target_company = (CompanyID)p1;
Company *c = Company::GetIfValid(target_company);
/* Check if selling shares is allowed (protection against modified clients)
* Cannot sell own shares */
if (c == NULL || !_settings_game.economy.allow_shares || _current_company == (CompanyID)p1) return CMD_ERROR;
if (c == NULL || !_settings_game.economy.allow_shares || _current_company == target_company) return CMD_ERROR;
/* Those lines are here for network-protection (clients can be slow) */
if (GetAmountOwnedBy(c, _current_company) == 0) return CommandCost();
@ -1551,7 +1552,7 @@ CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1
OwnerByte *b = c->share_owners;
while (*b != _current_company) b++; // share owners is guaranteed to contain company
*b = COMPANY_SPECTATOR;
SetWindowDirty(WC_COMPANY, p1);
SetWindowDirty(WC_COMPANY, target_company);
}
return CommandCost(EXPENSES_OTHER, cost);
}
@ -1569,7 +1570,8 @@ CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1
*/
CommandCost CmdBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
Company *c = Company::GetIfValid(p1);
CompanyID target_company = (CompanyID)p1;
Company *c = Company::GetIfValid(target_company);
if (c == NULL) return CMD_ERROR;
/* Disable takeovers when not asked */
@ -1579,7 +1581,7 @@ CommandCost CmdBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
if (!_networking && _local_company == c->index) return CMD_ERROR;
/* Do not allow companies to take over themselves */
if ((CompanyID)p1 == _current_company) return CMD_ERROR;
if (target_company == _current_company) return CMD_ERROR;
/* Get the cost here as the company is deleted in DoAcquireCompany. */
CommandCost cost(EXPENSES_OTHER, c->bankrupt_value);

View File

@ -196,6 +196,7 @@ enum Colours {
COLOUR_END,
INVALID_COLOUR = 0xFF,
};
template <> struct EnumPropsT<Colours> : MakeEnumPropsT<Colours, byte, COLOUR_DARK_BLUE, COLOUR_END, INVALID_COLOUR, 4> {};
/** Colour of the strings, see _string_colourmap in table/palettes.h or docs/ottd-colourtext-palette.png */
enum TextColour {

View File

@ -10,6 +10,7 @@
/** @file group_cmd.cpp Handling of the engine groups */
#include "stdafx.h"
#include "cmd_helper.h"
#include "command_func.h"
#include "group.h"
#include "train.h"
@ -82,7 +83,7 @@ void InitializeGroup()
*/
CommandCost CmdCreateGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
VehicleType vt = (VehicleType)p1;
VehicleType vt = Extract<VehicleType, 0, 3>(p1);
if (!IsCompanyBuildableVehicleType(vt)) return CMD_ERROR;
if (!Group::CanAllocateItem()) return CMD_ERROR;
@ -258,13 +259,12 @@ CommandCost CmdAddVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, u
*/
CommandCost CmdAddSharedVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
VehicleType type = (VehicleType)p2;
if (!Group::IsValidID(p1) || !IsCompanyBuildableVehicleType(type)) return CMD_ERROR;
VehicleType type = Extract<VehicleType, 0, 3>(p2);
GroupID id_g = p1;
if (!Group::IsValidID(id_g) || !IsCompanyBuildableVehicleType(type)) return CMD_ERROR;
if (flags & DC_EXEC) {
Vehicle *v;
VehicleType type = (VehicleType)p2;
GroupID id_g = p1;
/* Find the first front engine which belong to the group id_g
* then add all shared vehicles of this front engine to the group id_g */
@ -298,13 +298,13 @@ CommandCost CmdAddSharedVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32
*/
CommandCost CmdRemoveAllVehiclesGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
Group *g = Group::GetIfValid(p1);
VehicleType type = (VehicleType)p2;
GroupID old_g = p1;
Group *g = Group::GetIfValid(old_g);
VehicleType type = Extract<VehicleType, 0, 3>(p2);
if (g == NULL || g->owner != _current_company || !IsCompanyBuildableVehicleType(type)) return CMD_ERROR;
if (flags & DC_EXEC) {
GroupID old_g = p1;
Vehicle *v;
/* Find each Vehicle that belongs to the group old_g and add it to the default group */

View File

@ -955,18 +955,14 @@ protected:
/** Sort industries by production and name */
static int CDECL IndustryProductionSorter(const Industry * const *a, const Industry * const *b)
{
int r = 0;
if ((*a)->produced_cargo[0] == CT_INVALID) {
if ((*b)->produced_cargo[0] != CT_INVALID) return -1;
} else {
if ((*b)->produced_cargo[0] == CT_INVALID) return 1;
r = ((*a)->last_month_production[0] + (*a)->last_month_production[1]) -
((*b)->last_month_production[0] + (*b)->last_month_production[1]);
uint prod_a = 0, prod_b = 0;
for (uint i = 0; i < lengthof((*a)->produced_cargo); i++) {
if ((*a)->produced_cargo[i] != CT_INVALID) prod_a += (*a)->last_month_production[i];
if ((*b)->produced_cargo[i] != CT_INVALID) prod_b += (*b)->last_month_production[i];
}
int r = prod_a - prod_b;
return (r == 0) ? IndustryNameSorter(a, b) : r;
return (r == 0) ? IndustryTypeSorter(a, b) : r;
}
/** Sort industries by transported cargo and name */

View File

@ -604,8 +604,8 @@ CommandCost CmdLandscapeClear(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
/** Clear a big piece of landscape
* @param tile end tile of area dragging
* @param p1 start tile of area dragging
* @param flags of operation to conduct
* @param p1 start tile of area dragging
* @param p2 unused
* @param text unused
* @return the cost of this operation or an error

View File

@ -55,6 +55,7 @@ enum LiveryScheme {
};
DECLARE_POSTFIX_INCREMENT(LiveryScheme);
template <> struct EnumPropsT<LiveryScheme> : MakeEnumPropsT<LiveryScheme, byte, LS_BEGIN, LS_END, LS_END, 8> {};
/* List of different livery classes, used only by the livery GUI. */
enum LiveryClass {

View File

@ -97,7 +97,7 @@ CommandCost CmdDecreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
loan -= loan % LOAN_INTERVAL;
break;
case 2: // Repay the given amount of loan
if ((p1 % LOAN_INTERVAL != 0) || ((int32)p1 < LOAN_INTERVAL)) return CMD_ERROR; // Invalid amount to loan
if (p1 % LOAN_INTERVAL != 0 || (int32)p1 < LOAN_INTERVAL || p1 > c->current_loan) return CMD_ERROR; // Invalid amount to loan
loan = p1;
break;
}

View File

@ -27,6 +27,7 @@ enum StationClassID {
STAT_CLASS_MAX = 32, ///< Maximum number of classes.
};
typedef SimpleTinyEnumT<StationClassID, byte> StationClassIDByte;
template <> struct EnumPropsT<StationClassID> : MakeEnumPropsT<StationClassID, byte, STAT_CLASS_BEGIN, STAT_CLASS_MAX, STAT_CLASS_MAX, 8> {};
/** Allow incrementing of StationClassID variables */
DECLARE_POSTFIX_INCREMENT(StationClassID);

View File

@ -797,7 +797,7 @@ static void MakeNewGameDone()
SettingsDisableElrail(_settings_game.vehicle.disable_elrails);
/* In a dedicated server, the server does not play */
if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() == 0) {
if (_network_dedicated || BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() == 0) {
SetLocalCompany(COMPANY_SPECTATOR);
IConsoleCmdExec("exec scripts/game_start.scr 0");
return;

View File

@ -11,6 +11,7 @@
#include "stdafx.h"
#include "debug.h"
#include "cmd_helper.h"
#include "command_func.h"
#include "company_func.h"
#include "news_func.h"
@ -468,7 +469,7 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
Order new_order(p2);
Vehicle *v = Vehicle::GetIfValid(veh);
if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
if (v == NULL || !v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
/* Check if the inserted order is to the correct destination (owner, type),
* and has the correct flags if any */
@ -547,8 +548,6 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
default: return CMD_ERROR;
}
}
} else {
if (!IsCompanyBuildableVehicleType(v)) return CMD_ERROR;
}
if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN && v->type != VEH_ROAD) return CMD_ERROR;
@ -729,7 +728,7 @@ CommandCost CmdDeleteOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
if (v == NULL || !v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
/* If we did not select an order, we maybe want to de-clone the orders */
if (sel_ord >= v->GetNumOrders())
@ -795,10 +794,7 @@ CommandCost CmdSkipToOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
Vehicle *v = Vehicle::GetIfValid(veh_id);
if (v == NULL || !CheckOwnership(v->owner) || sel_ord == v->cur_order_index ||
sel_ord >= v->GetNumOrders() || v->GetNumOrders() < 2) {
return CMD_ERROR;
}
if (v == NULL || !v->IsPrimaryVehicle() || !CheckOwnership(v->owner) || sel_ord == v->cur_order_index || sel_ord >= v->GetNumOrders() || v->GetNumOrders() < 2) return CMD_ERROR;
if (flags & DC_EXEC) {
v->cur_order_index = sel_ord;
@ -835,7 +831,7 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
VehicleOrderID target_order = GB(p2, 16, 16);
Vehicle *v = Vehicle::GetIfValid(veh);
if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
if (v == NULL || !v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
/* Don't make senseless movements */
if (moving_order >= v->GetNumOrders() || target_order >= v->GetNumOrders() ||
@ -910,13 +906,13 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
{
VehicleOrderID sel_ord = GB(p1, 16, 16); // XXX - automatically truncated to 8 bits.
VehicleID veh = GB(p1, 0, 16);
ModifyOrderFlags mof = (ModifyOrderFlags)GB(p2, 0, 4);
uint16 data = GB(p2, 4, 11);
ModifyOrderFlags mof = Extract<ModifyOrderFlags, 0, 4>(p2);
uint16 data = GB(p2, 4, 11);
if (mof >= MOF_END) return CMD_ERROR;
Vehicle *v = Vehicle::GetIfValid(veh);
if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
if (v == NULL || !v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
/* Is it a valid order? */
if (sel_ord >= v->GetNumOrders()) return CMD_ERROR;
@ -1139,17 +1135,14 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
VehicleID veh_dst = GB(p1, 0, 16);
Vehicle *dst = Vehicle::GetIfValid(veh_dst);
if (dst == NULL || !CheckOwnership(dst->owner)) return CMD_ERROR;
if (dst == NULL || !dst->IsPrimaryVehicle() || !CheckOwnership(dst->owner)) return CMD_ERROR;
switch (p2) {
case CO_SHARE: {
Vehicle *src = Vehicle::GetIfValid(veh_src);
/* Sanity checks */
if (src == NULL || !CheckOwnership(src->owner) || dst->type != src->type || dst == src) {
return CMD_ERROR;
}
if (src == NULL || !src->IsPrimaryVehicle() || !CheckOwnership(src->owner) || dst->type != src->type || dst == src) return CMD_ERROR;
/* Trucks can't share orders with busses (and visa versa) */
if (src->type == VEH_ROAD && RoadVehicle::From(src)->IsBus() != RoadVehicle::From(dst)->IsBus()) {
@ -1188,9 +1181,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
Vehicle *src = Vehicle::GetIfValid(veh_src);
/* Sanity checks */
if (src == NULL || !CheckOwnership(src->owner) || dst->type != src->type || dst == src) {
return CMD_ERROR;
}
if (src == NULL || !src->IsPrimaryVehicle() || !CheckOwnership(src->owner) || dst->type != src->type || dst == src) return CMD_ERROR;
/* Trucks can't copy all the orders from busses (and visa versa),
* and neither can helicopters and aircarft. */
@ -1263,8 +1254,10 @@ CommandCost CmdOrderRefit(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
CargoID cargo = GB(p2, 0, 8);
byte subtype = GB(p2, 8, 8);
if (cargo >= NUM_CARGO) return CMD_ERROR;
const Vehicle *v = Vehicle::GetIfValid(veh);
if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
if (v == NULL || !v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
Order *order = v->GetOrder(order_number);
if (order == NULL) return CMD_ERROR;
@ -1416,7 +1409,8 @@ CommandCost CmdRestoreOrderIndex(TileIndex tile, DoCommandFlag flags, uint32 p1,
Vehicle *v = Vehicle::GetIfValid(p1);
/* Check the vehicle type and ownership, and if the service interval and order are in range */
if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
if (v == NULL || !v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
if (serv_int != GetServiceIntervalClamped(serv_int, v->owner) || cur_ord >= v->GetNumOrders()) return CMD_ERROR;
if (flags & DC_EXEC) {

View File

@ -149,6 +149,7 @@ enum ModifyOrderFlags {
MOF_COND_DESTINATION,///< Change the destination of a conditional order.
MOF_END
};
template <> struct EnumPropsT<ModifyOrderFlags> : MakeEnumPropsT<ModifyOrderFlags, byte, MOF_NON_STOP, MOF_END, MOF_END, 4> {};
/**
* Depot action to switch to when doing a MOF_DEPOT_ACTION.

View File

@ -181,7 +181,7 @@ bool HasRailtypeAvail(const CompanyID company, const RailType railtype)
bool ValParamRailtype(const RailType rail)
{
return HasRailtypeAvail(_current_company, rail);
return rail < RAILTYPE_END && HasRailtypeAvail(_current_company, rail);
}
RailType GetBestRailtype(const CompanyID company)

View File

@ -369,8 +369,8 @@ static inline bool ValParamTrackOrientation(Track track) {return IsValidTrack(tr
*/
CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
RailType railtype = (RailType)p1;
Track track = (Track)p2;
RailType railtype = Extract<RailType, 0, 4>(p1);
Track track = Extract<Track, 0, 3>(p2);
CommandCost cost(EXPENSES_CONSTRUCTION);
if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
@ -509,11 +509,11 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u
*/
CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
Track track = (Track)p2;
Track track = Extract<Track, 0, 3>(p2);
CommandCost cost(EXPENSES_CONSTRUCTION);
bool crossing = false;
if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
if (!ValParamTrackOrientation(track)) return CMD_ERROR;
TrackBits trackbit = TrackToTrackBits(track);
/* Need to read tile owner now because it may change when the rail is removed
@ -743,9 +743,9 @@ static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileInd
static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
CommandCost ret, total_cost(EXPENSES_CONSTRUCTION);
Track track = (Track)GB(p2, 4, 3);
Track track = Extract<Track, 4, 3>(p2);
bool remove = HasBit(p2, 7);
RailType railtype = (RailType)GB(p2, 0, 4);
RailType railtype = Extract<RailType, 0, 4>(p2);
if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
if (p1 >= MapSize()) return CMD_ERROR;
@ -830,11 +830,12 @@ CommandCost CmdRemoveRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p
CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
/* check railtype and valid direction for depot (0 through 3), 4 in total */
if (!ValParamRailtype((RailType)p1)) return CMD_ERROR;
RailType railtype = Extract<RailType, 0, 4>(p1);
if (!ValParamRailtype(railtype)) return CMD_ERROR;
Slope tileh = GetTileSlope(tile, NULL);
DiagDirection dir = Extract<DiagDirection, 0>(p2);
DiagDirection dir = Extract<DiagDirection, 0, 2>(p2);
/* Prohibit construction if
* The tile is non-flat AND
@ -862,7 +863,7 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, u
Depot *d = new Depot(tile);
d->town_index = ClosestTownFromTile(tile, UINT_MAX)->index;
MakeRailDepot(tile, _current_company, d->index, dir, (RailType)p1);
MakeRailDepot(tile, _current_company, d->index, dir, railtype);
MarkTileDirtyByTile(tile);
AddSideToSignalBuffer(tile, INVALID_DIAGDIR, _current_company);
@ -895,16 +896,17 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, u
*/
CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
Track track = (Track)GB(p1, 0, 3);
Track track = Extract<Track, 0, 3>(p1);
bool ctrl_pressed = HasBit(p1, 3); // was the CTRL button pressed
SignalVariant sigvar = (ctrl_pressed ^ HasBit(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC; // the signal variant of the new signal
SignalType sigtype = (SignalType)GB(p1, 5, 3); // the signal type of the new signal
SignalType sigtype = Extract<SignalType, 5, 3>(p1); // the signal type of the new signal
bool convert_signal = HasBit(p1, 8); // convert button pressed
SignalType cycle_start = (SignalType)GB(p1, 9, 3);
SignalType cycle_stop = (SignalType)GB(p1, 12, 3);
SignalType cycle_start = Extract<SignalType, 9, 3>(p1);
SignalType cycle_stop = Extract<SignalType, 12, 3>(p1);
uint num_dir_cycle = GB(p1, 15, 2);
if (sigtype > SIGTYPE_LAST) return CMD_ERROR;
if (cycle_start > cycle_stop || cycle_stop > SIGTYPE_LAST) return CMD_ERROR;
/* You can only build signals on plain rail tiles, and the selected track must exist */
if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) ||
@ -1122,15 +1124,14 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin
bool err = true;
TileIndex start_tile = tile;
Track track = (Track)GB(p2, 0, 3);
Track track = Extract<Track, 0, 3>(p2);
bool mode = HasBit(p2, 3);
bool semaphores = HasBit(p2, 4);
bool remove = HasBit(p2, 5);
bool autofill = HasBit(p2, 6);
Trackdir trackdir = TrackToTrackdir(track);
byte signal_density = GB(p2, 24, 8);
if (p1 >= MapSize()) return CMD_ERROR;
if (p1 >= MapSize() || !ValParamTrackOrientation(track)) return CMD_ERROR;
TileIndex end_tile = p1;
if (signal_density == 0 || signal_density > 20) return CMD_ERROR;
@ -1140,6 +1141,7 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin
* since the original amount will be too dense (shorter tracks) */
signal_density *= 2;
Trackdir trackdir = TrackToTrackdir(track);
if (ValidateAutoDrag(&trackdir, tile, end_tile).Failed()) return CMD_ERROR;
track = TrackdirToTrack(trackdir); // trackdir might have changed, keep track in sync
@ -1261,7 +1263,7 @@ CommandCost CmdBuildSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1,
*/
CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
Track track = (Track)GB(p1, 0, 3);
Track track = Extract<Track, 0, 3>(p1);
if (!ValParamTrackOrientation(track) ||
!IsPlainRailTile(tile) ||
@ -1361,7 +1363,7 @@ static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data)
CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
CommandCost cost(EXPENSES_CONSTRUCTION);
RailType totype = (RailType)p2;
RailType totype = Extract<RailType, 0, 4>(p2);
if (!ValParamRailtype(totype)) return CMD_ERROR;
if (p1 >= MapSize()) return CMD_ERROR;

View File

@ -270,7 +270,7 @@ void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uin
static void PlaceRail_Tunnel(TileIndex tile)
{
DoCommandP(tile, _cur_railtype, 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel);
DoCommandP(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel);
}
static void PlaceRail_ConvertRail(TileIndex tile)
@ -814,7 +814,7 @@ struct BuildRailToolbarWindow : Window {
virtual void OnPlacePresize(Point pt, TileIndex tile)
{
DoCommand(tile, _cur_railtype, 0, DC_AUTO, CMD_BUILD_TUNNEL);
DoCommand(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL);
VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
}

View File

@ -43,7 +43,7 @@ enum RailType {
/** Allow incrementing of Track variables */
DECLARE_POSTFIX_INCREMENT(RailType);
/** Define basic enum properties */
template <> struct EnumPropsT<RailType> : MakeEnumPropsT<RailType, byte, RAILTYPE_BEGIN, RAILTYPE_END, INVALID_RAILTYPE> {};
template <> struct EnumPropsT<RailType> : MakeEnumPropsT<RailType, byte, RAILTYPE_BEGIN, RAILTYPE_END, INVALID_RAILTYPE, 4> {};
typedef TinyEnumT<RailType> RailTypeByte;
/**

View File

@ -455,15 +455,15 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
p2 = (town != NULL) ? town->index : (TownID)INVALID_TOWN;
}
RoadBits pieces = Extract<RoadBits, 0>(p1);
RoadBits pieces = Extract<RoadBits, 0, 4>(p1);
/* do not allow building 'zero' road bits, code wouldn't handle it */
if (pieces == ROAD_NONE) return CMD_ERROR;
RoadType rt = (RoadType)GB(p1, 4, 2);
RoadType rt = Extract<RoadType, 4, 2>(p1);
if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR;
DisallowedRoadDirections toggle_drd = (DisallowedRoadDirections)GB(p1, 6, 2);
DisallowedRoadDirections toggle_drd = Extract<DisallowedRoadDirections, 6, 2>(p1);
Slope tileh = GetTileSlope(tile, NULL);
@ -714,10 +714,10 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p
if (p1 >= MapSize()) return CMD_ERROR;
TileIndex end_tile = p1;
RoadType rt = (RoadType)GB(p2, 3, 2);
RoadType rt = Extract<RoadType, 3, 2>(p2);
if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR;
Axis axis = Extract<Axis, 2>(p2);
Axis axis = Extract<Axis, 2, 1>(p2);
/* Only drag in X or Y direction dictated by the direction variable */
if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
@ -801,10 +801,10 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32
if (p1 >= MapSize()) return CMD_ERROR;
TileIndex end_tile = p1;
RoadType rt = (RoadType)GB(p2, 3, 2);
RoadType rt = Extract<RoadType, 3, 2>(p2);
if (!IsValidRoadType(rt)) return CMD_ERROR;
Axis axis = Extract<Axis, 2>(p2);
Axis axis = Extract<Axis, 2, 1>(p2);
/* Only drag in X or Y direction dictated by the direction variable */
if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis
@ -864,8 +864,8 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32
*/
CommandCost CmdBuildRoadDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
DiagDirection dir = Extract<DiagDirection, 0>(p1);
RoadType rt = (RoadType)GB(p1, 2, 2);
DiagDirection dir = Extract<DiagDirection, 0, 2>(p1);
RoadType rt = Extract<RoadType, 2, 2>(p1);
if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR;

View File

@ -174,7 +174,7 @@ static const RoadTypeInfo _road_type_infos[] = {
static void PlaceRoad_Tunnel(TileIndex tile)
{
DoCommandP(tile, 0x200 | RoadTypeToRoadTypes(_cur_roadtype), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel);
DoCommandP(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel);
}
static void BuildRoadOutsideStation(TileIndex tile, DiagDirection direction)
@ -613,7 +613,7 @@ struct BuildRoadToolbarWindow : Window {
virtual void OnPlacePresize(Point pt, TileIndex tile)
{
DoCommand(tile, 0x200 | RoadTypeToRoadTypes(_cur_roadtype), 0, DC_AUTO, CMD_BUILD_TUNNEL);
DoCommand(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL);
VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
}

View File

@ -168,6 +168,7 @@ enum DisallowedRoadDirections {
DRD_END
};
DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections);
template <> struct EnumPropsT<DisallowedRoadDirections> : MakeEnumPropsT<DisallowedRoadDirections, byte, DRD_NONE, DRD_END, DRD_END, 2> {};
/**
* Gets the disallowed directions

View File

@ -27,6 +27,7 @@ enum RoadType {
INVALID_ROADTYPE = 0xFF ///< flag for invalid roadtype
};
DECLARE_POSTFIX_INCREMENT(RoadType);
template <> struct EnumPropsT<RoadType> : MakeEnumPropsT<RoadType, byte, ROADTYPE_BEGIN, ROADTYPE_END, INVALID_ROADTYPE, 2> {};
/**
* The different roadtypes we support, but then a bitmask of them
@ -41,6 +42,7 @@ enum RoadTypes {
INVALID_ROADTYPES = 0xFF ///< Invalid roadtypes
};
DECLARE_ENUM_AS_BIT_SET(RoadTypes);
template <> struct EnumPropsT<RoadTypes> : MakeEnumPropsT<RoadTypes, byte, ROADTYPES_NONE, ROADTYPES_END, INVALID_ROADTYPES, 2> {};
typedef SimpleTinyEnumT<RoadTypes, byte> RoadTypesByte;
@ -67,5 +69,6 @@ enum RoadBits {
ROAD_ALL = ROAD_X | ROAD_Y ///< Full 4-way crossing
};
DECLARE_ENUM_AS_BIT_SET(RoadBits);
template <> struct EnumPropsT<RoadBits> : MakeEnumPropsT<RoadBits, byte, ROAD_NONE, ROAD_ALL, ROAD_NONE, 4> {};
#endif /* ROAD_TYPE_H */

View File

@ -200,9 +200,10 @@ void RoadVehUpdateCache(RoadVehicle *v)
*/
CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (!IsEngineBuildable(p1, VEH_ROAD, _current_company)) return_cmd_error(STR_ERROR_ROAD_VEHICLE_NOT_AVAILABLE);
EngineID eid = GB(p1, 0, 16);
if (!IsEngineBuildable(eid, VEH_ROAD, _current_company)) return_cmd_error(STR_ERROR_ROAD_VEHICLE_NOT_AVAILABLE);
const Engine *e = Engine::Get(p1);
const Engine *e = Engine::Get(eid);
/* Engines without valid cargo should not be available */
if (e->GetDefaultCargoType() == CT_INVALID) return CMD_ERROR;
@ -216,7 +217,7 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
if (HasTileRoadType(tile, ROADTYPE_TRAM) != HasBit(e->info.misc_flags, EF_ROAD_TRAM)) return_cmd_error(STR_ERROR_DEPOT_WRONG_DEPOT_TYPE);
uint num_vehicles = 1 + CountArticulatedParts(p1, false);
uint num_vehicles = 1 + CountArticulatedParts(eid, false);
/* Allow for the front and the articulated parts */
if (!Vehicle::CanAllocateItem(num_vehicles)) {
@ -254,7 +255,7 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
v->last_station_visited = INVALID_STATION;
v->max_speed = rvi->max_speed;
v->engine_type = (EngineID)p1;
v->engine_type = eid;
v->rcache.first_engine = INVALID_ENGINE; // needs to be set before first callback
v->reliability = e->reliability;
@ -297,7 +298,7 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Road window
}
Company::Get(_current_company)->num_engines[p1]++;
Company::Get(_current_company)->num_engines[eid]++;
CheckConsistencyOfArticulatedVehicle(v);
}

View File

@ -611,11 +611,12 @@ bool Ship::Tick()
*/
CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
EngineID eid = GB(p1, 0, 16);
UnitID unit_num;
if (!IsEngineBuildable(p1, VEH_SHIP, _current_company)) return_cmd_error(STR_ERROR_SHIP_NOT_AVAILABLE);
if (!IsEngineBuildable(eid, VEH_SHIP, _current_company)) return_cmd_error(STR_ERROR_SHIP_NOT_AVAILABLE);
const Engine *e = Engine::Get(p1);
const Engine *e = Engine::Get(eid);
CommandCost value(EXPENSES_NEW_VEHICLES, e->GetCost());
/* Engines without valid cargo should not be available */
@ -660,7 +661,7 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
v->last_station_visited = INVALID_STATION;
v->max_speed = svi->max_speed;
v->engine_type = p1;
v->engine_type = eid;
v->reliability = e->reliability;
v->reliability_spd_dec = e->reliability_spd_dec;
@ -692,7 +693,7 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Ship window
}
Company::Get(_current_company)->num_engines[p1]++;
Company::Get(_current_company)->num_engines[eid]++;
}
return value;

View File

@ -27,9 +27,12 @@ enum SignalType {
SIGTYPE_COMBO = 3, ///< presignal inter-block
SIGTYPE_PBS = 4, ///< normal pbs signal
SIGTYPE_PBS_ONEWAY = 5, ///< no-entry signal
SIGTYPE_END,
SIGTYPE_LAST = SIGTYPE_PBS_ONEWAY,
SIGTYPE_LAST_NOPBS = SIGTYPE_COMBO
};
template <> struct EnumPropsT<SignalType> : MakeEnumPropsT<SignalType, byte, SIGTYPE_NORMAL, SIGTYPE_END, SIGTYPE_END, 3> {};
#endif /* SIGNAL_TYPE_H */

View File

@ -973,13 +973,13 @@ CommandCost FindJoiningWaypoint(StationID existing_waypoint, StationID waypoint_
CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
/* Unpack parameters */
RailType rt = (RailType)GB(p1, 0, 4);
Axis axis = Extract<Axis, 4>(p1);
RailType rt = Extract<RailType, 0, 4>(p1);
Axis axis = Extract<Axis, 4, 1>(p1);
byte numtracks = GB(p1, 8, 8);
byte plat_len = GB(p1, 16, 8);
bool adjacent = HasBit(p1, 24);
StationClassID spec_class = (StationClassID)GB(p2, 0, 8);
StationClassID spec_class = Extract<StationClassID, 0, 8>(p2);
byte spec_index = GB(p2, 8, 8);
StationID station_to_join = GB(p2, 16, 16);
@ -988,7 +988,7 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32
if (!ValParamRailtype(rt)) return CMD_ERROR;
/* Check if the given station class is valid */
if ((uint)spec_class >= GetNumStationClasses()) return CMD_ERROR;
if ((uint)spec_class >= GetNumStationClasses() || spec_class == STAT_CLASS_WAYP) return CMD_ERROR;
if (spec_index >= GetNumCustomStations(spec_class)) return CMD_ERROR;
if (plat_len == 0 || numtracks == 0) return CMD_ERROR;
@ -1524,7 +1524,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
bool type = HasBit(p2, 0);
bool is_drive_through = HasBit(p2, 1);
bool build_over_road = is_drive_through && IsNormalRoadTile(tile);
RoadTypes rts = (RoadTypes)GB(p2, 2, 2);
RoadTypes rts = Extract<RoadTypes, 2, 2>(p2);
StationID station_to_join = GB(p2, 16, 16);
bool reuse = (station_to_join != NEW_STATION);
if (!reuse) station_to_join = INVALID_STATION;

View File

@ -313,15 +313,20 @@ typedef unsigned char byte;
#define PERSONAL_DIR ""
#endif
/* Compile time assertions. Prefer c++0x static_assert() */
/* Compile time assertions. Prefer c++0x static_assert().
* Older compilers cannot evaluate some expressions at compile time,
* typically when templates are involved, try assert_tcompile() in those cases. */
#if defined(__STDCXX_VERSION__) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(static_assert)
/* __STDCXX_VERSION__ is c++0x feature macro, __GXX_EXPERIMENTAL_CXX0X__ is used by gcc, __GXX_EXPERIMENTAL_CPP0X__ by icc */
#define assert_compile(expr) static_assert(expr, #expr )
#define assert_tcompile(expr) assert_compile(expr)
#elif defined(__OS2__)
/* Disabled for OS/2 */
#define assert_compile(expr)
#define assert_tcompile(expr) assert_compile(expr)
#else
#define assert_compile(expr) typedef int __ct_assert__[1 - 2 * !(expr)]
#define assert_tcompile(expr) assert(expr)
#endif
/* Check if the types have the bitsizes like we are using them */

View File

@ -372,7 +372,7 @@ CommandCost CmdLevelLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
uint oldh = TileHeight(p1);
/* compute new height */
uint h = oldh + p2;
uint h = oldh + (int8)p2;
/* Check range of destination height */
if (h > MAX_TILE_HEIGHT) return_cmd_error((oldh == 0) ? STR_ERROR_ALREADY_AT_SEA_LEVEL : STR_ERROR_TOO_HIGH);

View File

@ -14,6 +14,7 @@
#include "road_cmd.h"
#include "landscape.h"
#include "viewport_func.h"
#include "cmd_helper.h"
#include "command_func.h"
#include "industry.h"
#include "station_base.h"
@ -1445,7 +1446,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize
t->larger_town = city;
int x = (int)size * 16 + 3;
if (size == TS_RANDOM) x = (Random() & 0xF) + 8;
if (size == TSZ_RANDOM) x = (Random() & 0xF) + 8;
/* Don't create huge cities when founding town in-game */
if (city && (!manual || _game_mode == GM_EDITOR)) x *= _settings_game.economy.initial_city_size;
@ -1518,20 +1519,20 @@ static bool IsUniqueTownName(const char *name)
*/
CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
TownSize size = (TownSize)GB(p1, 0, 2);
TownSize size = Extract<TownSize, 0, 2>(p1);
bool city = HasBit(p1, 2);
TownLayout layout = (TownLayout)GB(p1, 3, 3);
TownLayout layout = Extract<TownLayout, 3, 3>(p1);
TownNameParams par(_settings_game.game_creation.town_name);
bool random = HasBit(p1, 6);
uint32 townnameparts = p2;
if (size > TS_RANDOM) return CMD_ERROR;
if (size > TSZ_RANDOM) return CMD_ERROR;
if (layout > TL_RANDOM) return CMD_ERROR;
/* Some things are allowed only in the scenario editor */
if (_game_mode != GM_EDITOR) {
if (_settings_game.economy.found_town == TF_FORBIDDEN) return CMD_ERROR;
if (size == TS_LARGE) return CMD_ERROR;
if (size == TSZ_LARGE) return CMD_ERROR;
if (random) return CMD_ERROR;
if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT && layout != _settings_game.economy.town_layout) {
return CMD_ERROR;
@ -1555,7 +1556,7 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
if (ret.Failed()) return ret;
}
static const byte price_mult[][TS_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
static const byte price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
/* multidimensional arrays have to have defined length of non-first dimension */
assert_compile(lengthof(price_mult[0]) == 4);
@ -1782,7 +1783,7 @@ bool GenerateTowns(TownLayout layout)
/* Get a unique name for the town. */
if (!GenerateTownName(&townnameparts)) continue;
/* try 20 times to create a random-sized town for the first loop. */
if (CreateRandomTown(20, townnameparts, TS_RANDOM, city, layout) != NULL) num++; // if creation successfull, raise a flag
if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != NULL) num++; // If creation was successful, raise a flag.
} while (--n);
if (num != 0) return true;
@ -1790,7 +1791,7 @@ bool GenerateTowns(TownLayout layout)
/* If num is still zero at this point, it means that not a single town has been created.
* So give it a last try, but now more aggressive */
if (GenerateTownName(&townnameparts) &&
CreateRandomTown(10000, townnameparts, TS_RANDOM, _settings_game.economy.larger_towns != 0, layout) != NULL) {
CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != NULL) {
return true;
}

View File

@ -1053,7 +1053,7 @@ private:
public:
FoundTownWindow(const WindowDesc *desc, WindowNumber window_number) :
QueryStringBaseWindow(MAX_LENGTH_TOWN_NAME_BYTES),
town_size(TS_MEDIUM),
town_size(TSZ_MEDIUM),
town_layout(_settings_game.economy.town_layout),
params(_settings_game.game_creation.town_name)
{

View File

@ -19,11 +19,14 @@ struct Town;
/** Supported initial town sizes */
enum TownSize {
TS_SMALL, ///< small town
TS_MEDIUM, ///< medium town
TS_LARGE, ///< large town
TS_RANDOM, ///< random size, bigger than small, smaller than large
TSZ_SMALL, ///< Small town.
TSZ_MEDIUM, ///< Medium town.
TSZ_LARGE, ///< Large town.
TSZ_RANDOM, ///< Random size, bigger than small, smaller than large.
TSZ_END, ///< Number of available town sizes.
};
template <> struct EnumPropsT<TownSize> : MakeEnumPropsT<TownSize, byte, TSZ_SMALL, TSZ_END, TSZ_END, 2> {};
enum {
/* These refer to the maximums, so Appalling is -1000 to -400
@ -87,6 +90,7 @@ enum TownLayout {
NUM_TLS, ///< Number of town layouts
};
template <> struct EnumPropsT<TownLayout> : MakeEnumPropsT<TownLayout, byte, TL_BEGIN, NUM_TLS, NUM_TLS, 3> {};
/** It needs to be 8bits, because we save and load it as such */
typedef SimpleTinyEnumT<TownLayout, byte> TownLayoutByte; // typedefing-enumification of TownLayout

View File

@ -33,7 +33,7 @@ enum Track {
/** Allow incrementing of Track variables */
DECLARE_POSTFIX_INCREMENT(Track);
/** Define basic enum properties */
template <> struct EnumPropsT<Track> : MakeEnumPropsT<Track, byte, TRACK_BEGIN, TRACK_END, INVALID_TRACK> {};
template <> struct EnumPropsT<Track> : MakeEnumPropsT<Track, byte, TRACK_BEGIN, TRACK_END, INVALID_TRACK, 3> {};
typedef TinyEnumT<Track> TrackByte;
@ -94,7 +94,7 @@ enum Trackdir {
};
/** Define basic enum properties */
template <> struct EnumPropsT<Trackdir> : MakeEnumPropsT<Trackdir, byte, TRACKDIR_BEGIN, TRACKDIR_END, INVALID_TRACKDIR> {};
template <> struct EnumPropsT<Trackdir> : MakeEnumPropsT<Trackdir, byte, TRACKDIR_BEGIN, TRACKDIR_END, INVALID_TRACKDIR, 4> {};
typedef TinyEnumT<Trackdir> TrackdirByte;
/**

View File

@ -816,10 +816,11 @@ static void AddRearEngineToMultiheadedTrain(Train *v)
*/
CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
EngineID eid = GB(p1, 0, 16);
/* Check if the engine-type is valid (for the company) */
if (!IsEngineBuildable(p1, VEH_TRAIN, _current_company)) return_cmd_error(STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE);
if (!IsEngineBuildable(eid, VEH_TRAIN, _current_company)) return_cmd_error(STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE);
const Engine *e = Engine::Get(p1);
const Engine *e = Engine::Get(eid);
const RailVehicleInfo *rvi = &e->u.rail;
CommandCost value(EXPENSES_NEW_VEHICLES, e->GetCost());
@ -833,11 +834,11 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1,
if (!IsRailDepotTile(tile)) return CMD_ERROR;
if (!IsTileOwner(tile, _current_company)) return CMD_ERROR;
if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(eid, tile, flags);
uint num_vehicles =
(rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) +
CountArticulatedParts(p1, false);
CountArticulatedParts(eid, false);
/* Check if depot and new engine uses the same kind of tracks *
* We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
@ -875,7 +876,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1,
v->value = value.GetCost();
v->last_station_visited = INVALID_STATION;
v->engine_type = p1;
v->engine_type = eid;
v->tcache.first_engine = INVALID_ENGINE; // needs to be set before first callback
v->reliability = e->reliability;
@ -920,7 +921,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1,
InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Train window
}
Company::Get(_current_company)->num_engines[p1]++;
Company::Get(_current_company)->num_engines[eid]++;
CheckConsistencyOfArticulatedVehicle(v);
}

View File

@ -30,5 +30,6 @@ enum TransportType {
TRANSPORT_END,
INVALID_TRANSPORT = 0xff,
};
template <> struct EnumPropsT<TransportType> : MakeEnumPropsT<TransportType, byte, TRANSPORT_BEGIN, TRANSPORT_END, INVALID_TRANSPORT, 2> {};
#endif /* TRANSPORT_TYPE_H */

View File

@ -17,6 +17,7 @@
#include "landscape.h"
#include "unmovable_map.h"
#include "viewport_func.h"
#include "cmd_helper.h"
#include "command_func.h"
#include "town.h"
#include "variables.h"
@ -191,7 +192,7 @@ CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoC
* @param p1 packed start tile coords (~ dx)
* @param p2 various bitstuffed elements
* - p2 = (bit 0- 7) - bridge type (hi bh)
* - p2 = (bit 8-14) - rail type or road types.
* - p2 = (bit 8-11) - rail type or road types.
* - p2 = (bit 15-16) - transport type.
* @param text unused
* @return the cost of this operation or an error
@ -208,17 +209,17 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u
if (p1 >= MapSize()) return CMD_ERROR;
TransportType transport_type = (TransportType)GB(p2, 15, 2);
TransportType transport_type = Extract<TransportType, 15, 2>(p2);
/* type of bridge */
switch (transport_type) {
case TRANSPORT_ROAD:
roadtypes = (RoadTypes)GB(p2, 8, 2);
roadtypes = Extract<RoadTypes, 8, 2>(p2);
if (!HasExactlyOneBit(roadtypes) || !HasRoadTypesAvail(_current_company, roadtypes)) return CMD_ERROR;
break;
case TRANSPORT_RAIL:
railtype = (RailType)GB(p2, 8, 7);
railtype = Extract<RailType, 8, 4>(p2);
if (!ValParamRailtype(railtype)) return CMD_ERROR;
break;
@ -479,22 +480,32 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u
/** Build Tunnel.
* @param start_tile start tile of tunnel
* @param flags type of operation
* @param p1 railtype or roadtypes. bit 9 set means road tunnel
* @param p1 bit 0-3 railtype or roadtypes
* bit 8-9 transport type
* @param p2 unused
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
TransportType transport_type = (TransportType)GB(p1, 9, 1);
TransportType transport_type = Extract<TransportType, 8, 2>(p1);
CommandCost cost(EXPENSES_CONSTRUCTION);
RailType railtype = INVALID_RAILTYPE;
RoadTypes rts = ROADTYPES_NONE;
_build_tunnel_endtile = 0;
if (transport_type == TRANSPORT_RAIL) {
if (!ValParamRailtype((RailType)p1)) return CMD_ERROR;
} else {
const RoadTypes rts = (RoadTypes)GB(p1, 0, 2);
if (!HasExactlyOneBit(rts) || !HasRoadTypesAvail(_current_company, rts)) return CMD_ERROR;
switch (transport_type) {
case TRANSPORT_RAIL:
railtype = Extract<RailType, 0, 4>(p1);
if (!ValParamRailtype(railtype)) return CMD_ERROR;
break;
case TRANSPORT_ROAD:
rts = Extract<RoadTypes, 0, 2>(p1);
if (!HasExactlyOneBit(rts) || !HasRoadTypesAvail(_current_company, rts)) return CMD_ERROR;
break;
default: return CMD_ERROR;
}
uint start_z;
@ -581,13 +592,13 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1,
if (flags & DC_EXEC) {
if (transport_type == TRANSPORT_RAIL) {
MakeRailTunnel(start_tile, _current_company, direction, (RailType)GB(p1, 0, 4));
MakeRailTunnel(end_tile, _current_company, ReverseDiagDir(direction), (RailType)GB(p1, 0, 4));
MakeRailTunnel(start_tile, _current_company, direction, railtype);
MakeRailTunnel(end_tile, _current_company, ReverseDiagDir(direction), railtype);
AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, _current_company);
YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction));
} else {
MakeRoadTunnel(start_tile, _current_company, direction, (RoadTypes)GB(p1, 0, 2));
MakeRoadTunnel(end_tile, _current_company, ReverseDiagDir(direction), (RoadTypes)GB(p1, 0, 2));
MakeRoadTunnel(start_tile, _current_company, direction, rts);
MakeRoadTunnel(end_tile, _current_company, ReverseDiagDir(direction), rts);
}
}

View File

@ -13,6 +13,7 @@
#include "roadveh.h"
#include "news_func.h"
#include "airport.h"
#include "cmd_helper.h"
#include "command_func.h"
#include "company_func.h"
#include "vehicle_gui.h"
@ -123,22 +124,24 @@ CommandCost CmdStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1,
* - bit 0-4 Vehicle type
* - bit 5 false = start vehicles, true = stop vehicles
* - bit 6 if set, then it's a vehicle list window, not a depot and Tile is ignored in this case
* - bit 8-11 Vehicle List Window type (ignored unless bit 1 is set)
* - bit 8-11 Vehicle List Window type (ignored unless bit 6 is set)
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdMassStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
VehicleList list;
VehicleType vehicle_type = (VehicleType)GB(p2, 0, 5);
VehicleType vehicle_type = Extract<VehicleType, 0, 3>(p2);
bool start_stop = HasBit(p2, 5);
bool vehicle_list_window = HasBit(p2, 6);
if (!IsCompanyBuildableVehicleType(vehicle_type)) return CMD_ERROR;
if (vehicle_list_window) {
uint32 id = p1;
uint16 window_type = p2 & VLW_MASK;
GenerateVehicleSortList(&list, vehicle_type, _current_company, id, window_type);
if (!GenerateVehicleSortList(&list, vehicle_type, _current_company, id, window_type)) return CMD_ERROR;
} else {
/* Get the list of vehicles in the depot */
BuildDepotVehicleList(vehicle_type, tile, &list, NULL);
@ -177,9 +180,11 @@ CommandCost CmdDepotSellAllVehicles(TileIndex tile, DoCommandFlag flags, uint32
VehicleList list;
CommandCost cost(EXPENSES_NEW_VEHICLES);
VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
VehicleType vehicle_type = Extract<VehicleType, 0, 3>(p1);
uint sell_command = GetCmdSellVeh(vehicle_type);
if (!IsCompanyBuildableVehicleType(vehicle_type)) return CMD_ERROR;
/* Get the list of vehicles in the depot */
BuildDepotVehicleList(vehicle_type, tile, &list, &list);
@ -205,8 +210,9 @@ CommandCost CmdDepotMassAutoReplace(TileIndex tile, DoCommandFlag flags, uint32
{
VehicleList list;
CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES);
VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
VehicleType vehicle_type = Extract<VehicleType, 0, 3>(p1);
if (!IsCompanyBuildableVehicleType(vehicle_type)) return CMD_ERROR;
if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_company)) return CMD_ERROR;
/* Get the list of vehicles in the depot */
@ -395,7 +401,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
uint32 build_argument = 2;
Vehicle *v = Vehicle::GetIfValid(p1);
if (v == NULL) return CMD_ERROR;
if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR;
Vehicle *v_front = v;
Vehicle *w = NULL;
Vehicle *w_front = NULL;
@ -580,7 +586,7 @@ CommandCost SendAllVehiclesToDepot(VehicleType type, DoCommandFlag flags, bool s
{
VehicleList list;
GenerateVehicleSortList(&list, type, owner, id, vlw_flag);
if (!GenerateVehicleSortList(&list, type, owner, id, vlw_flag)) return CMD_ERROR;
/* Send all the vehicles to a depot */
for (uint i = 0; i < list.Length(); i++) {
@ -610,7 +616,7 @@ CommandCost SendAllVehiclesToDepot(VehicleType type, DoCommandFlag flags, bool s
CommandCost CmdRenameVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
Vehicle *v = Vehicle::GetIfValid(p1);
if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
if (v == NULL || !v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
bool reset = StrEmpty(text);
@ -641,7 +647,7 @@ CommandCost CmdRenameVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
CommandCost CmdChangeServiceInt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
Vehicle *v = Vehicle::GetIfValid(p1);
if (v == NULL || !CheckOwnership(v->owner)) return CMD_ERROR;
if (v == NULL || !v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
uint16 serv_int = GetServiceIntervalClamped(p2, v->owner); // Double check the service interval from the user-input
if (serv_int != p2) return CMD_ERROR;

View File

@ -28,6 +28,7 @@ enum VehicleType {
VEH_INVALID = 0xFF, ///< Non-existing type of vehicle.
};
DECLARE_POSTFIX_INCREMENT(VehicleType);
template <> struct EnumPropsT<VehicleType> : MakeEnumPropsT<VehicleType, byte, VEH_TRAIN, VEH_END, VEH_INVALID, 3> {};
/** It needs to be 8bits, because we save and load it as such */
typedef SimpleTinyEnumT<VehicleType, byte> VehicleTypeByte;

View File

@ -76,8 +76,9 @@ void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine
* <li>VLW_WAYPOINT_LIST: index of waypoint to generate a list for</li>
* </ul>
* @param window_type The type of window the list is for, using the VLW_ flags in vehicle_gui.h
* @return false if invalid list is requested
*/
void GenerateVehicleSortList(VehicleList *list, VehicleType type, Owner owner, uint32 index, uint16 window_type)
bool GenerateVehicleSortList(VehicleList *list, VehicleType type, Owner owner, uint32 index, uint16 window_type)
{
list->Clear();
@ -101,7 +102,10 @@ void GenerateVehicleSortList(VehicleList *list, VehicleType type, Owner owner, u
case VLW_SHARED_ORDERS:
/* Add all vehicles from this vehicle's shared order list */
for (v = Vehicle::Get(index); v != NULL; v = v->NextShared()) {
v = Vehicle::GetIfValid(index);
if (v == NULL || v->type != type || !v->IsPrimaryVehicle()) return false;
for (; v != NULL; v = v->NextShared()) {
*list->Append() = v;
}
break;
@ -153,8 +157,9 @@ void GenerateVehicleSortList(VehicleList *list, VehicleType type, Owner owner, u
}
break;
default: NOT_REACHED();
default: return false;
}
list->Compact();
return true;
}

View File

@ -19,7 +19,7 @@
typedef SmallVector<const Vehicle *, 32> VehicleList;
void GenerateVehicleSortList(VehicleList *list, VehicleType type, Owner owner, uint32 index, uint16 window_type);
bool GenerateVehicleSortList(VehicleList *list, VehicleType type, Owner owner, uint32 index, uint16 window_type);
void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine_list, VehicleList *wagon_list, bool individual_wagons = false);
#endif /* VEHICLELIST_H */

View File

@ -104,13 +104,9 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile)
*/
CommandCost CmdBuildShipDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
TileIndex tile2;
Axis axis = Extract<Axis, 0, 1>(p1);
CommandCost ret;
Axis axis = Extract<Axis, 0>(p1);
tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
TileIndex tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
if (!IsWaterTile(tile) || !IsWaterTile(tile2)) {
return_cmd_error(STR_ERROR_MUST_BE_BUILT_ON_WATER);
@ -125,7 +121,7 @@ CommandCost CmdBuildShipDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
WaterClass wc1 = GetWaterClass(tile);
WaterClass wc2 = GetWaterClass(tile2);
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (ret.Failed()) return CMD_ERROR;
ret = DoCommand(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (ret.Failed()) return CMD_ERROR;
@ -291,7 +287,7 @@ CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
{
CommandCost cost(EXPENSES_CONSTRUCTION);
if (p1 >= MapSize()) return CMD_ERROR;
if (p1 >= MapSize() || p2 > 2) return CMD_ERROR;
/* Outside of the editor you can only build canals, not oceans */
if (p2 != 0 && _game_mode != GM_EDITOR) return CMD_ERROR;

View File

@ -11,6 +11,7 @@
#include "stdafx.h"
#include "cmd_helper.h"
#include "command_func.h"
#include "landscape.h"
#include "bridge_map.h"
@ -214,12 +215,12 @@ extern bool CanExpandRailStation(const BaseStation *st, TileArea &new_ta, Axis a
CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
/* Unpack parameters */
Axis axis = (Axis)GB(p1, 4, 1);
Axis axis = Extract<Axis, 4, 1>(p1);
byte width = GB(p1, 8, 8);
byte height = GB(p1, 16, 8);
bool adjacent = HasBit(p1, 24);
StationClassID spec_class = (StationClassID)GB(p2, 0, 8);
StationClassID spec_class = Extract<StationClassID, 0, 8>(p2);
byte spec_index = GB(p2, 8, 8);
StationID station_to_join = GB(p2, 16, 16);