mirror of https://github.com/OpenTTD/OpenTTD
(svn r12924) -Feature: Introducing the so called 'engine pool' which primarily removes the fixed engine type limits and also happens to allow (with the patch option 'dynamic_engines') multiple NewGRF vehicle sets to coexist.
parent
1d01390fa6
commit
a00371c8db
Binary file not shown.
Binary file not shown.
|
@ -987,6 +987,10 @@
|
||||||
RelativePath=".\..\src\core\endian_func.hpp"
|
RelativePath=".\..\src\core\endian_func.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\..\src\engine_base.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\engine_func.h"
|
RelativePath=".\..\src\engine_func.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -984,6 +984,10 @@
|
||||||
RelativePath=".\..\src\core\endian_func.hpp"
|
RelativePath=".\..\src\core\endian_func.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\..\src\engine_base.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\engine_func.h"
|
RelativePath=".\..\src\engine_func.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -168,6 +168,7 @@ economy_type.h
|
||||||
effectvehicle_func.h
|
effectvehicle_func.h
|
||||||
effectvehicle_base.h
|
effectvehicle_base.h
|
||||||
core/endian_func.hpp
|
core/endian_func.hpp
|
||||||
|
engine_base.h
|
||||||
engine_func.h
|
engine_func.h
|
||||||
engine_type.h
|
engine_type.h
|
||||||
core/enum_type.hpp
|
core/enum_type.hpp
|
||||||
|
|
|
@ -137,11 +137,11 @@ static EngineID AiChooseTrainToBuild(RailType railtype, Money money, byte flag,
|
||||||
{
|
{
|
||||||
EngineID best_veh_index = INVALID_ENGINE;
|
EngineID best_veh_index = INVALID_ENGINE;
|
||||||
byte best_veh_score = 0;
|
byte best_veh_score = 0;
|
||||||
EngineID i;
|
const Engine *e;
|
||||||
|
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(i, VEH_TRAIN) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
|
||||||
const RailVehicleInfo *rvi = RailVehInfo(i);
|
EngineID i = e->index;
|
||||||
const Engine* e = GetEngine(i);
|
const RailVehicleInfo *rvi = &e->u.rail;
|
||||||
|
|
||||||
if (!IsCompatibleRail(rvi->railtype, railtype) ||
|
if (!IsCompatibleRail(rvi->railtype, railtype) ||
|
||||||
rvi->railveh_type == RAILVEH_WAGON ||
|
rvi->railveh_type == RAILVEH_WAGON ||
|
||||||
|
@ -168,11 +168,11 @@ static EngineID AiChooseRoadVehToBuild(CargoID cargo, Money money, TileIndex til
|
||||||
{
|
{
|
||||||
EngineID best_veh_index = INVALID_ENGINE;
|
EngineID best_veh_index = INVALID_ENGINE;
|
||||||
int32 best_veh_rating = 0;
|
int32 best_veh_rating = 0;
|
||||||
EngineID i;
|
const Engine *e;
|
||||||
|
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(i, VEH_ROAD) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
|
||||||
const RoadVehicleInfo *rvi = RoadVehInfo(i);
|
EngineID i = e->index;
|
||||||
const Engine* e = GetEngine(i);
|
const RoadVehicleInfo *rvi = &e->u.road;
|
||||||
|
|
||||||
if (!HasBit(e->player_avail, _current_player) || e->reliability < 0x8A3D) {
|
if (!HasBit(e->player_avail, _current_player) || e->reliability < 0x8A3D) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -209,16 +209,17 @@ static EngineID AiChooseAircraftToBuild(Money money, byte forbidden)
|
||||||
{
|
{
|
||||||
EngineID best_veh_index = INVALID_ENGINE;
|
EngineID best_veh_index = INVALID_ENGINE;
|
||||||
Money best_veh_cost = 0;
|
Money best_veh_cost = 0;
|
||||||
EngineID i;
|
const Engine *e;
|
||||||
|
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(i, VEH_AIRCRAFT) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_AIRCRAFT) {
|
||||||
const Engine* e = GetEngine(i);
|
EngineID i = e->index;
|
||||||
|
const AircraftVehicleInfo *avi = &e->u.air;
|
||||||
|
|
||||||
if (!HasBit(e->player_avail, _current_player) || e->reliability < 0x8A3D) {
|
if (!HasBit(e->player_avail, _current_player) || e->reliability < 0x8A3D) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((AircraftVehInfo(i)->subtype & forbidden) != 0) continue;
|
if ((avi->subtype & forbidden) != 0) continue;
|
||||||
|
|
||||||
CommandCost ret = DoCommand(0, i, 0, DC_QUERY_COST, CMD_BUILD_AIRCRAFT);
|
CommandCost ret = DoCommand(0, i, 0, DC_QUERY_COST, CMD_BUILD_AIRCRAFT);
|
||||||
if (CmdSucceeded(ret) && ret.GetCost() <= money && ret.GetCost() >= best_veh_cost) {
|
if (CmdSucceeded(ret) && ret.GetCost() <= money && ret.GetCost() >= best_veh_cost) {
|
||||||
|
@ -2445,14 +2446,14 @@ static StationID AiGetStationIdByDef(TileIndex tile, int id)
|
||||||
static EngineID AiFindBestWagon(CargoID cargo, RailType railtype)
|
static EngineID AiFindBestWagon(CargoID cargo, RailType railtype)
|
||||||
{
|
{
|
||||||
EngineID best_veh_index = INVALID_ENGINE;
|
EngineID best_veh_index = INVALID_ENGINE;
|
||||||
EngineID i;
|
|
||||||
uint16 best_capacity = 0;
|
uint16 best_capacity = 0;
|
||||||
uint16 best_speed = 0;
|
uint16 best_speed = 0;
|
||||||
uint speed;
|
uint speed;
|
||||||
|
const Engine *e;
|
||||||
|
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(i, VEH_TRAIN) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
|
||||||
const RailVehicleInfo *rvi = RailVehInfo(i);
|
EngineID i = e->index;
|
||||||
const Engine* e = GetEngine(i);
|
const RailVehicleInfo *rvi = &e->u.rail;
|
||||||
|
|
||||||
if (!IsCompatibleRail(rvi->railtype, railtype) ||
|
if (!IsCompatibleRail(rvi->railtype, railtype) ||
|
||||||
rvi->railveh_type != RAILVEH_WAGON ||
|
rvi->railveh_type != RAILVEH_WAGON ||
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "../../command_func.h"
|
#include "../../command_func.h"
|
||||||
#include "trolly.h"
|
#include "trolly.h"
|
||||||
#include "../../engine_func.h"
|
#include "../../engine_func.h"
|
||||||
|
#include "../../engine_base.h"
|
||||||
#include "../../variables.h"
|
#include "../../variables.h"
|
||||||
#include "../../bridge.h"
|
#include "../../bridge.h"
|
||||||
#include "../../vehicle_func.h"
|
#include "../../vehicle_func.h"
|
||||||
|
@ -235,12 +236,12 @@ EngineID AiNew_PickVehicle(Player *p)
|
||||||
} else {
|
} else {
|
||||||
EngineID best_veh_index = INVALID_ENGINE;
|
EngineID best_veh_index = INVALID_ENGINE;
|
||||||
int32 best_veh_rating = 0;
|
int32 best_veh_rating = 0;
|
||||||
EngineID i;
|
const Engine *e;
|
||||||
|
|
||||||
/* Loop through all road vehicles */
|
/* Loop through all road vehicles */
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(i, VEH_ROAD) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
|
||||||
const RoadVehicleInfo *rvi = RoadVehInfo(i);
|
EngineID i = e->index;
|
||||||
const Engine* e = GetEngine(i);
|
const RoadVehicleInfo *rvi = &e->u.road;
|
||||||
|
|
||||||
/* Skip vehicles which can't take our cargo type */
|
/* Skip vehicles which can't take our cargo type */
|
||||||
if (rvi->cargo_type != _players_ainew[p->index].cargo && !CanRefitTo(i, _players_ainew[p->index].cargo)) continue;
|
if (rvi->cargo_type != _players_ainew[p->index].cargo && !CanRefitTo(i, _players_ainew[p->index].cargo)) continue;
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "../../industry.h"
|
#include "../../industry.h"
|
||||||
#include "../../station_base.h"
|
#include "../../station_base.h"
|
||||||
#include "../../engine_func.h"
|
#include "../../engine_func.h"
|
||||||
|
#include "../../engine_base.h"
|
||||||
#include "../../gui.h"
|
#include "../../gui.h"
|
||||||
#include "../../depot_base.h"
|
#include "../../depot_base.h"
|
||||||
#include "../../vehicle_base.h"
|
#include "../../vehicle_base.h"
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "station_base.h"
|
#include "station_base.h"
|
||||||
#include "vehicle_base.h"
|
#include "vehicle_base.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
|
|
||||||
/** An aircraft can be one ot those types */
|
/** An aircraft can be one ot those types */
|
||||||
enum AircraftSubType {
|
enum AircraftSubType {
|
||||||
|
|
|
@ -168,7 +168,7 @@ SpriteID Aircraft::GetImage(Direction direction) const
|
||||||
SpriteID sprite = GetCustomVehicleSprite(this, direction);
|
SpriteID sprite = GetCustomVehicleSprite(this, direction);
|
||||||
if (sprite != 0) return sprite;
|
if (sprite != 0) return sprite;
|
||||||
|
|
||||||
spritenum = _orig_aircraft_vehicle_info[this->engine_type - AIRCRAFT_ENGINES_INDEX].image_index;
|
spritenum = GetEngine(this->engine_type)->image_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
return direction + _aircraft_sprite[spritenum];
|
return direction + _aircraft_sprite[spritenum];
|
||||||
|
@ -196,7 +196,7 @@ static SpriteID GetAircraftIcon(EngineID engine)
|
||||||
SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W);
|
SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W);
|
||||||
if (sprite != 0) return sprite;
|
if (sprite != 0) return sprite;
|
||||||
|
|
||||||
spritenum = _orig_aircraft_vehicle_info[engine - AIRCRAFT_ENGINES_INDEX].image_index;
|
spritenum = GetEngine(engine)->image_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 6 + _aircraft_sprite[spritenum];
|
return 6 + _aircraft_sprite[spritenum];
|
||||||
|
|
|
@ -11,6 +11,19 @@
|
||||||
#include "newgrf_engine.h"
|
#include "newgrf_engine.h"
|
||||||
#include "vehicle_func.h"
|
#include "vehicle_func.h"
|
||||||
|
|
||||||
|
static EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
|
||||||
|
{
|
||||||
|
const Engine *e = NULL;
|
||||||
|
FOR_ALL_ENGINES(e) {
|
||||||
|
if (e->grffile != file) continue;
|
||||||
|
if (e->type != type) continue;
|
||||||
|
if (e->internal_id != internal_id) continue;
|
||||||
|
|
||||||
|
return e->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
return INVALID_ENGINE;
|
||||||
|
}
|
||||||
|
|
||||||
uint CountArticulatedParts(EngineID engine_type, bool purchase_window)
|
uint CountArticulatedParts(EngineID engine_type, bool purchase_window)
|
||||||
{
|
{
|
||||||
|
@ -54,7 +67,7 @@ uint16 *GetCapacityOfArticulatedParts(EngineID engine, VehicleType type)
|
||||||
uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, engine, NULL);
|
uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, engine, NULL);
|
||||||
if (callback == CALLBACK_FAILED || GB(callback, 0, 8) == 0xFF) break;
|
if (callback == CALLBACK_FAILED || GB(callback, 0, 8) == 0xFF) break;
|
||||||
|
|
||||||
EngineID artic_engine = GetFirstEngineOfType(type) + GB(callback, 0, 7);
|
EngineID artic_engine = GetNewEngineID(GetEngineGRF(engine), type, GB(callback, 0, 7));
|
||||||
|
|
||||||
if (type == VEH_TRAIN) {
|
if (type == VEH_TRAIN) {
|
||||||
const RailVehicleInfo *rvi = RailVehInfo(artic_engine);
|
const RailVehicleInfo *rvi = RailVehInfo(artic_engine);
|
||||||
|
@ -88,7 +101,7 @@ void AddArticulatedParts(Vehicle **vl, VehicleType type)
|
||||||
Vehicle *previous = u;
|
Vehicle *previous = u;
|
||||||
u = u->Next();
|
u = u->Next();
|
||||||
|
|
||||||
EngineID engine_type = GetFirstEngineOfType(type) + GB(callback, 0, 7);
|
EngineID engine_type = GetNewEngineID(GetEngineGRF(v->engine_type), type, GB(callback, 0, 7));
|
||||||
bool flip_image = HasBit(callback, 7);
|
bool flip_image = HasBit(callback, 7);
|
||||||
|
|
||||||
/* get common values from first engine */
|
/* get common values from first engine */
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "player_func.h"
|
#include "player_func.h"
|
||||||
#include "widgets/dropdown_func.h"
|
#include "widgets/dropdown_func.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
|
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
@ -198,8 +199,9 @@ static void GenerateReplaceVehList(Window *w, bool draw_left)
|
||||||
EngineList *list = &WP(w, replaceveh_d).list[i];
|
EngineList *list = &WP(w, replaceveh_d).list[i];
|
||||||
EngList_RemoveAll(list);
|
EngList_RemoveAll(list);
|
||||||
|
|
||||||
EngineID eid;
|
const Engine *e;
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(eid, type) {
|
FOR_ALL_ENGINES_OF_TYPE(e, type) {
|
||||||
|
EngineID eid = e->index;
|
||||||
if (type == VEH_TRAIN && !GenerateReplaceRailList(eid, draw_left, WP(w, replaceveh_d).wagon_btnstate)) continue; // special rules for trains
|
if (type == VEH_TRAIN && !GenerateReplaceRailList(eid, draw_left, WP(w, replaceveh_d).wagon_btnstate)) continue; // special rules for trains
|
||||||
|
|
||||||
if (draw_left) {
|
if (draw_left) {
|
||||||
|
@ -214,7 +216,7 @@ static void GenerateReplaceVehList(Window *w, bool draw_left)
|
||||||
if (!EnginesGotCargoInCommon(eid, WP(w, replaceveh_d).sel_engine[0])) continue; // the engines needs to be able to carry the same cargo
|
if (!EnginesGotCargoInCommon(eid, WP(w, replaceveh_d).sel_engine[0])) continue; // the engines needs to be able to carry the same cargo
|
||||||
|
|
||||||
/* Road vehicles can't be replaced by trams and vice-versa */
|
/* Road vehicles can't be replaced by trams and vice-versa */
|
||||||
if (type == VEH_ROAD && HasBit(EngInfo(WP(w, replaceveh_d).sel_engine[0])->misc_flags, EF_ROAD_TRAM) != HasBit(EngInfo(eid)->misc_flags, EF_ROAD_TRAM)) continue;
|
if (type == VEH_ROAD && HasBit(EngInfo(WP(w, replaceveh_d).sel_engine[0])->misc_flags, EF_ROAD_TRAM) != HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue;
|
||||||
if (eid == WP(w, replaceveh_d).sel_engine[0]) continue; // we can't replace an engine into itself (that would be autorenew)
|
if (eid == WP(w, replaceveh_d).sel_engine[0]) continue; // we can't replace an engine into itself (that would be autorenew)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -800,9 +800,10 @@ static void GenerateBuildTrainList(Window *w)
|
||||||
* Also check to see if the previously selected engine is still available,
|
* Also check to see if the previously selected engine is still available,
|
||||||
* and if not, reset selection to INVALID_ENGINE. This could be the case
|
* and if not, reset selection to INVALID_ENGINE. This could be the case
|
||||||
* when engines become obsolete and are removed */
|
* when engines become obsolete and are removed */
|
||||||
EngineID eid;
|
const Engine *e;
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(eid, VEH_TRAIN) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
|
||||||
const RailVehicleInfo *rvi = RailVehInfo(eid);
|
EngineID eid = e->index;
|
||||||
|
const RailVehicleInfo *rvi = &e->u.rail;
|
||||||
|
|
||||||
if (bv->filter.railtype != RAILTYPE_END && !HasPowerOnRail(rvi->railtype, bv->filter.railtype)) continue;
|
if (bv->filter.railtype != RAILTYPE_END && !HasPowerOnRail(rvi->railtype, bv->filter.railtype)) continue;
|
||||||
if (!IsEngineBuildable(eid, VEH_TRAIN, _local_player)) continue;
|
if (!IsEngineBuildable(eid, VEH_TRAIN, _local_player)) continue;
|
||||||
|
@ -839,8 +840,9 @@ static void GenerateBuildRoadVehList(Window *w)
|
||||||
|
|
||||||
EngList_RemoveAll(&bv->eng_list);
|
EngList_RemoveAll(&bv->eng_list);
|
||||||
|
|
||||||
EngineID eid;
|
const Engine *e;
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(eid, VEH_ROAD) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
|
||||||
|
EngineID eid = e->index;
|
||||||
if (!IsEngineBuildable(eid, VEH_ROAD, _local_player)) continue;
|
if (!IsEngineBuildable(eid, VEH_ROAD, _local_player)) continue;
|
||||||
if (!HasBit(bv->filter.roadtypes, HasBit(EngInfo(eid)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD)) continue;
|
if (!HasBit(bv->filter.roadtypes, HasBit(EngInfo(eid)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD)) continue;
|
||||||
EngList_Add(&bv->eng_list, eid);
|
EngList_Add(&bv->eng_list, eid);
|
||||||
|
@ -858,8 +860,9 @@ static void GenerateBuildShipList(Window *w)
|
||||||
|
|
||||||
EngList_RemoveAll(&bv->eng_list);
|
EngList_RemoveAll(&bv->eng_list);
|
||||||
|
|
||||||
EngineID eid;
|
const Engine *e;
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(eid, VEH_SHIP) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_SHIP) {
|
||||||
|
EngineID eid = e->index;
|
||||||
if (!IsEngineBuildable(eid, VEH_SHIP, _local_player)) continue;
|
if (!IsEngineBuildable(eid, VEH_SHIP, _local_player)) continue;
|
||||||
EngList_Add(&bv->eng_list, eid);
|
EngList_Add(&bv->eng_list, eid);
|
||||||
|
|
||||||
|
@ -880,8 +883,9 @@ static void GenerateBuildAircraftList(Window *w)
|
||||||
* Also check to see if the previously selected plane is still available,
|
* Also check to see if the previously selected plane is still available,
|
||||||
* and if not, reset selection to INVALID_ENGINE. This could be the case
|
* and if not, reset selection to INVALID_ENGINE. This could be the case
|
||||||
* when planes become obsolete and are removed */
|
* when planes become obsolete and are removed */
|
||||||
EngineID eid;
|
const Engine *e;
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(eid, VEH_AIRCRAFT) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_AIRCRAFT) {
|
||||||
|
EngineID eid = e->index;
|
||||||
if (!IsEngineBuildable(eid, VEH_AIRCRAFT, _local_player)) continue;
|
if (!IsEngineBuildable(eid, VEH_AIRCRAFT, _local_player)) continue;
|
||||||
/* First VEH_END window_numbers are fake to allow a window open for all different types at once */
|
/* First VEH_END window_numbers are fake to allow a window open for all different types at once */
|
||||||
if (w->window_number > VEH_END && !CanAircraftUseStation(eid, w->window_number)) continue;
|
if (w->window_number > VEH_END && !CanAircraftUseStation(eid, w->window_number)) continue;
|
||||||
|
|
|
@ -656,8 +656,9 @@ static void ResizeDefaultWindowSize(VehicleType type)
|
||||||
uint max_width = 0;
|
uint max_width = 0;
|
||||||
uint max_height = 0;
|
uint max_height = 0;
|
||||||
|
|
||||||
EngineID eid;
|
const Engine *e;
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(eid, type) {
|
FOR_ALL_ENGINES_OF_TYPE(e, type) {
|
||||||
|
EngineID eid = e->index;
|
||||||
uint x, y;
|
uint x, y;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
#include "player_base.h"
|
#include "player_base.h"
|
||||||
#include "tunnelbridge.h"
|
#include "tunnelbridge.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
|
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
#include "table/elrail_data.h"
|
#include "table/elrail_data.h"
|
||||||
|
@ -480,9 +481,9 @@ int32 SettingsDisableElrail(int32 p1)
|
||||||
const RailType new_railtype = disable ? RAILTYPE_RAIL : RAILTYPE_ELECTRIC;
|
const RailType new_railtype = disable ? RAILTYPE_RAIL : RAILTYPE_ELECTRIC;
|
||||||
|
|
||||||
/* walk through all train engines */
|
/* walk through all train engines */
|
||||||
EngineID eid;
|
Engine *e;
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(eid, VEH_TRAIN) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
|
||||||
RailVehicleInfo *rv_info = &_rail_vehicle_info[eid];
|
RailVehicleInfo *rv_info = &e->u.rail;
|
||||||
/* if it is an electric rail engine and its railtype is the wrong one */
|
/* if it is an electric rail engine and its railtype is the wrong one */
|
||||||
if (rv_info->engclass == 2 && rv_info->railtype == old_railtype) {
|
if (rv_info->engclass == 2 && rv_info->railtype == old_railtype) {
|
||||||
/* change it to the proper one */
|
/* change it to the proper one */
|
||||||
|
|
206
src/engine.cpp
206
src/engine.cpp
|
@ -14,6 +14,7 @@
|
||||||
#include "train.h"
|
#include "train.h"
|
||||||
#include "aircraft.h"
|
#include "aircraft.h"
|
||||||
#include "newgrf_cargo.h"
|
#include "newgrf_cargo.h"
|
||||||
|
#include "newgrf_engine.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "strings_func.h"
|
#include "strings_func.h"
|
||||||
#include "gfx_func.h"
|
#include "gfx_func.h"
|
||||||
|
@ -25,43 +26,103 @@
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "oldpool_func.h"
|
#include "oldpool_func.h"
|
||||||
|
#include "core/alloc_func.hpp"
|
||||||
|
#include "map"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/engines.h"
|
#include "table/engines.h"
|
||||||
|
|
||||||
Engine _engines[TOTAL_NUM_ENGINES];
|
DEFINE_OLD_POOL_GENERIC(Engine, Engine)
|
||||||
EngineInfo _engine_info[TOTAL_NUM_ENGINES];
|
|
||||||
RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES];
|
|
||||||
ShipVehicleInfo _ship_vehicle_info[NUM_SHIP_ENGINES];
|
|
||||||
AircraftVehicleInfo _aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES];
|
|
||||||
RoadVehicleInfo _road_vehicle_info[NUM_ROAD_ENGINES];
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
YEAR_ENGINE_AGING_STOPS = 2050,
|
YEAR_ENGINE_AGING_STOPS = 2050,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Number of engines of each vehicle type in original engine data */
|
||||||
|
const uint8 _engine_counts[4] = {
|
||||||
|
lengthof(_orig_rail_vehicle_info),
|
||||||
|
lengthof(_orig_road_vehicle_info),
|
||||||
|
lengthof(_orig_ship_vehicle_info),
|
||||||
|
lengthof(_orig_aircraft_vehicle_info),
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Offset of the first engine of each vehicle type in original engine data */
|
||||||
|
const uint8 _engine_offsets[4] = {
|
||||||
|
0,
|
||||||
|
lengthof(_orig_rail_vehicle_info),
|
||||||
|
lengthof(_orig_rail_vehicle_info) + lengthof(_orig_road_vehicle_info),
|
||||||
|
lengthof(_orig_rail_vehicle_info) + lengthof(_orig_road_vehicle_info) + lengthof(_orig_ship_vehicle_info),
|
||||||
|
};
|
||||||
|
|
||||||
|
Engine::Engine() :
|
||||||
|
name(NULL),
|
||||||
|
overrides_count(0),
|
||||||
|
overrides(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine::Engine(VehicleType type, EngineID base)
|
||||||
|
{
|
||||||
|
this->type = type;
|
||||||
|
this->internal_id = base;
|
||||||
|
this->list_position = base;
|
||||||
|
|
||||||
|
/* Check if this base engine is within the original engine data range */
|
||||||
|
if (base >= _engine_counts[type]) {
|
||||||
|
/* Mark engine as valid anyway */
|
||||||
|
this->info.climates = 0x80;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the original engine info for this slot */
|
||||||
|
this->info = _orig_engine_info[_engine_offsets[type] + base];
|
||||||
|
|
||||||
|
/* Copy the original engine data for this slot */
|
||||||
|
switch (type) {
|
||||||
|
default: NOT_REACHED();
|
||||||
|
|
||||||
|
case VEH_TRAIN:
|
||||||
|
this->u.rail = _orig_rail_vehicle_info[base];
|
||||||
|
this->image_index = this->u.rail.image_index;
|
||||||
|
this->info.string_id = STR_8000_KIRBY_PAUL_TANK_STEAM + base;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VEH_ROAD:
|
||||||
|
this->u.road = _orig_road_vehicle_info[base];
|
||||||
|
this->image_index = this->u.road.image_index;
|
||||||
|
this->info.string_id = STR_8074_MPS_REGAL_BUS + base;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VEH_SHIP:
|
||||||
|
this->u.ship = _orig_ship_vehicle_info[base];
|
||||||
|
this->image_index = this->u.ship.image_index;
|
||||||
|
this->info.string_id = STR_80CC_MPS_OIL_TANKER + base;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VEH_AIRCRAFT:
|
||||||
|
this->u.air = _orig_aircraft_vehicle_info[base];
|
||||||
|
this->image_index = this->u.air.image_index;
|
||||||
|
this->info.string_id = STR_80D7_SAMPSON_U52 + base;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Engine::~Engine()
|
||||||
|
{
|
||||||
|
UnloadWagonOverrides(this);
|
||||||
|
free(this->name);
|
||||||
|
}
|
||||||
|
|
||||||
void SetupEngines()
|
void SetupEngines()
|
||||||
{
|
{
|
||||||
/* Copy original static engine data */
|
_Engine_pool.CleanPool();
|
||||||
memcpy(&_engine_info, &_orig_engine_info, sizeof(_orig_engine_info));
|
_Engine_pool.AddBlockToPool();
|
||||||
memcpy(&_rail_vehicle_info, &_orig_rail_vehicle_info, sizeof(_orig_rail_vehicle_info));
|
|
||||||
memcpy(&_ship_vehicle_info, &_orig_ship_vehicle_info, sizeof(_orig_ship_vehicle_info));
|
|
||||||
memcpy(&_aircraft_vehicle_info, &_orig_aircraft_vehicle_info, sizeof(_orig_aircraft_vehicle_info));
|
|
||||||
memcpy(&_road_vehicle_info, &_orig_road_vehicle_info, sizeof(_orig_road_vehicle_info));
|
|
||||||
|
|
||||||
/* Add type to engines */
|
for (uint i = 0; i < lengthof(_orig_rail_vehicle_info); i++) new Engine(VEH_TRAIN, i);
|
||||||
Engine* e = _engines;
|
for (uint i = 0; i < lengthof(_orig_road_vehicle_info); i++) new Engine(VEH_ROAD, i);
|
||||||
do e->type = VEH_TRAIN; while (++e < &_engines[ROAD_ENGINES_INDEX]);
|
for (uint i = 0; i < lengthof(_orig_ship_vehicle_info); i++) new Engine(VEH_SHIP, i);
|
||||||
do e->type = VEH_ROAD; while (++e < &_engines[SHIP_ENGINES_INDEX]);
|
for (uint i = 0; i < lengthof(_orig_aircraft_vehicle_info); i++) new Engine(VEH_AIRCRAFT, i);
|
||||||
do e->type = VEH_SHIP; while (++e < &_engines[AIRCRAFT_ENGINES_INDEX]);
|
|
||||||
do e->type = VEH_AIRCRAFT; while (++e < &_engines[TOTAL_NUM_ENGINES]);
|
|
||||||
|
|
||||||
/* Set up default engine names */
|
|
||||||
for (EngineID engine = 0; engine < TOTAL_NUM_ENGINES; engine++) {
|
|
||||||
EngineInfo *ei = &_engine_info[engine];
|
|
||||||
ei->string_id = STR_8000_KIRBY_PAUL_TANK_STEAM + engine;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,7 +151,7 @@ static void CalcEngineReliability(Engine *e)
|
||||||
|
|
||||||
/* Check for early retirement */
|
/* Check for early retirement */
|
||||||
if (e->player_avail != 0 && !_patches.never_expire_vehicles) {
|
if (e->player_avail != 0 && !_patches.never_expire_vehicles) {
|
||||||
int retire_early = EngInfo(e - _engines)->retire_early;
|
int retire_early = e->info.retire_early;
|
||||||
uint retire_early_max_age = max(0, e->duration_phase_1 + e->duration_phase_2 - retire_early * 12);
|
uint retire_early_max_age = max(0, e->duration_phase_1 + e->duration_phase_2 - retire_early * 12);
|
||||||
if (retire_early != 0 && age >= retire_early_max_age) {
|
if (retire_early != 0 && age >= retire_early_max_age) {
|
||||||
/* Early retirement is enabled and we're past the date... */
|
/* Early retirement is enabled and we're past the date... */
|
||||||
|
@ -124,11 +185,11 @@ static void CalcEngineReliability(Engine *e)
|
||||||
void StartupEngines()
|
void StartupEngines()
|
||||||
{
|
{
|
||||||
Engine *e;
|
Engine *e;
|
||||||
const EngineInfo *ei;
|
|
||||||
/* Aging of vehicles stops, so account for that when starting late */
|
/* Aging of vehicles stops, so account for that when starting late */
|
||||||
const Date aging_date = min(_date, ConvertYMDToDate(YEAR_ENGINE_AGING_STOPS, 0, 1));
|
const Date aging_date = min(_date, ConvertYMDToDate(YEAR_ENGINE_AGING_STOPS, 0, 1));
|
||||||
|
|
||||||
for (e = _engines, ei = _engine_info; e != endof(_engines); e++, ei++) {
|
FOR_ALL_ENGINES(e) {
|
||||||
|
const EngineInfo *ei = &e->info;
|
||||||
uint32 r;
|
uint32 r;
|
||||||
|
|
||||||
e->age = 0;
|
e->age = 0;
|
||||||
|
@ -224,13 +285,11 @@ static PlayerID GetBestPlayer(uint8 pp)
|
||||||
|
|
||||||
void EnginesDailyLoop()
|
void EnginesDailyLoop()
|
||||||
{
|
{
|
||||||
EngineID i;
|
|
||||||
|
|
||||||
if (_cur_year >= YEAR_ENGINE_AGING_STOPS) return;
|
if (_cur_year >= YEAR_ENGINE_AGING_STOPS) return;
|
||||||
|
|
||||||
for (i = 0; i != lengthof(_engines); i++) {
|
Engine *e;
|
||||||
Engine *e = &_engines[i];
|
FOR_ALL_ENGINES(e) {
|
||||||
|
EngineID i = e->index;
|
||||||
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) {
|
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) {
|
||||||
if (e->flags & ENGINE_OFFER_WINDOW_OPEN) {
|
if (e->flags & ENGINE_OFFER_WINDOW_OPEN) {
|
||||||
if (e->preview_player_rank != 0xFF && !--e->preview_wait) {
|
if (e->preview_player_rank != 0xFF && !--e->preview_wait) {
|
||||||
|
@ -282,14 +341,15 @@ CommandCost CmdWantEnginePreview(TileIndex tile, uint32 flags, uint32 p1, uint32
|
||||||
/* Determine if an engine type is a wagon (and not a loco) */
|
/* Determine if an engine type is a wagon (and not a loco) */
|
||||||
static bool IsWagon(EngineID index)
|
static bool IsWagon(EngineID index)
|
||||||
{
|
{
|
||||||
return index < NUM_TRAIN_ENGINES && RailVehInfo(index)->railveh_type == RAILVEH_WAGON;
|
const Engine *e = GetEngine(index);
|
||||||
|
return e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NewVehicleAvailable(Engine *e)
|
static void NewVehicleAvailable(Engine *e)
|
||||||
{
|
{
|
||||||
Vehicle *v;
|
Vehicle *v;
|
||||||
Player *p;
|
Player *p;
|
||||||
EngineID index = e - _engines;
|
EngineID index = e->index;
|
||||||
|
|
||||||
/* In case the player didn't build the vehicle during the intro period,
|
/* In case the player didn't build the vehicle during the intro period,
|
||||||
* prevent that player from getting future intro periods for a while. */
|
* prevent that player from getting future intro periods for a while. */
|
||||||
|
@ -326,7 +386,7 @@ static void NewVehicleAvailable(Engine *e)
|
||||||
|
|
||||||
if (e->type == VEH_TRAIN) {
|
if (e->type == VEH_TRAIN) {
|
||||||
/* maybe make another rail type available */
|
/* maybe make another rail type available */
|
||||||
RailType railtype = RailVehInfo(index)->railtype;
|
RailType railtype = e->u.rail.railtype;
|
||||||
assert(railtype < RAILTYPE_END);
|
assert(railtype < RAILTYPE_END);
|
||||||
FOR_ALL_PLAYERS(p) {
|
FOR_ALL_PLAYERS(p) {
|
||||||
if (p->is_active) SetBit(p->avail_railtypes, railtype);
|
if (p->is_active) SetBit(p->avail_railtypes, railtype);
|
||||||
|
@ -334,7 +394,7 @@ static void NewVehicleAvailable(Engine *e)
|
||||||
} else if (e->type == VEH_ROAD) {
|
} else if (e->type == VEH_ROAD) {
|
||||||
/* maybe make another road type available */
|
/* maybe make another road type available */
|
||||||
FOR_ALL_PLAYERS(p) {
|
FOR_ALL_PLAYERS(p) {
|
||||||
if (p->is_active) SetBit(p->avail_roadtypes, HasBit(EngInfo(index)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD);
|
if (p->is_active) SetBit(p->avail_roadtypes, HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AddNewsItem(index, NM_CALLBACK, NF_NONE, NT_NEW_VEHICLES, DNC_VEHICLEAVAIL, 0, 0);
|
AddNewsItem(index, NM_CALLBACK, NF_NONE, NT_NEW_VEHICLES, DNC_VEHICLEAVAIL, 0, 0);
|
||||||
|
@ -359,7 +419,7 @@ void EnginesMonthlyLoop()
|
||||||
e->flags |= ENGINE_EXCLUSIVE_PREVIEW;
|
e->flags |= ENGINE_EXCLUSIVE_PREVIEW;
|
||||||
|
|
||||||
/* Do not introduce new rail wagons */
|
/* Do not introduce new rail wagons */
|
||||||
if (!IsWagon(e - _engines))
|
if (!IsWagon(e->index))
|
||||||
e->preview_player_rank = 1; // Give to the player with the highest rating.
|
e->preview_player_rank = 1; // Give to the player with the highest rating.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -370,8 +430,9 @@ static bool IsUniqueEngineName(const char *name)
|
||||||
{
|
{
|
||||||
char buf[512];
|
char buf[512];
|
||||||
|
|
||||||
for (EngineID i = 0; i < TOTAL_NUM_ENGINES; i++) {
|
const Engine *e;
|
||||||
SetDParam(0, i);
|
FOR_ALL_ENGINES(e) {
|
||||||
|
SetDParam(0, e->index);
|
||||||
GetString(buf, STR_ENGINE_NAME, lastof(buf));
|
GetString(buf, STR_ENGINE_NAME, lastof(buf));
|
||||||
if (strcmp(buf, name) == 0) return false;
|
if (strcmp(buf, name) == 0) return false;
|
||||||
}
|
}
|
||||||
|
@ -620,32 +681,77 @@ static const SaveLoad _engine_desc[] = {
|
||||||
SLE_END()
|
SLE_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::map<EngineID, Engine> _temp_engine;
|
||||||
|
|
||||||
|
Engine *GetTempDataEngine(EngineID index)
|
||||||
|
{
|
||||||
|
return &_temp_engine[index];
|
||||||
|
}
|
||||||
|
|
||||||
static void Save_ENGN()
|
static void Save_ENGN()
|
||||||
{
|
{
|
||||||
uint i;
|
Engine *e;
|
||||||
|
FOR_ALL_ENGINES(e) {
|
||||||
for (i = 0; i != lengthof(_engines); i++) {
|
SlSetArrayIndex(e->index);
|
||||||
SlSetArrayIndex(i);
|
SlObject(e, _engine_desc);
|
||||||
SlObject(&_engines[i], _engine_desc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_ENGN()
|
static void Load_ENGN()
|
||||||
{
|
{
|
||||||
|
/* As engine data is loaded before engines are initialized we need to load
|
||||||
|
* this information into a temporary array. This is then copied into the
|
||||||
|
* engine pool after processing NewGRFs by CopyTempEngineData(). */
|
||||||
int index;
|
int index;
|
||||||
while ((index = SlIterateArray()) != -1) {
|
while ((index = SlIterateArray()) != -1) {
|
||||||
SlObject(GetEngine(index), _engine_desc);
|
Engine *e = GetTempDataEngine(index);
|
||||||
|
SlObject(e, _engine_desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy data from temporary engine array into the real engine pool.
|
||||||
|
*/
|
||||||
|
void CopyTempEngineData()
|
||||||
|
{
|
||||||
|
Engine *e;
|
||||||
|
FOR_ALL_ENGINES(e) {
|
||||||
|
if (e->index >= _temp_engine.size()) break;
|
||||||
|
|
||||||
|
const Engine *se = GetTempDataEngine(e->index);
|
||||||
|
e->intro_date = se->intro_date;
|
||||||
|
e->age = se->age;
|
||||||
|
e->reliability = se->reliability;
|
||||||
|
e->reliability_spd_dec = se->reliability_spd_dec;
|
||||||
|
e->reliability_start = se->reliability_start;
|
||||||
|
e->reliability_max = se->reliability_max;
|
||||||
|
e->reliability_final = se->reliability_final;
|
||||||
|
e->duration_phase_1 = se->duration_phase_1;
|
||||||
|
e->duration_phase_2 = se->duration_phase_2;
|
||||||
|
e->duration_phase_3 = se->duration_phase_3;
|
||||||
|
e->lifelength = se->lifelength;
|
||||||
|
e->flags = se->flags;
|
||||||
|
e->preview_player_rank = se->preview_player_rank;
|
||||||
|
e->preview_wait = se->preview_wait;
|
||||||
|
e->player_avail = se->player_avail;
|
||||||
|
if (se->name != NULL) e->name = strdup(se->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get rid of temporary data */
|
||||||
|
_temp_engine.clear();
|
||||||
|
}
|
||||||
|
|
||||||
static void Load_ENGS()
|
static void Load_ENGS()
|
||||||
{
|
{
|
||||||
StringID names[TOTAL_NUM_ENGINES];
|
/* Load old separate String ID list into a temporary array. This
|
||||||
|
* was always 256 entries. */
|
||||||
|
StringID names[256];
|
||||||
|
|
||||||
SlArray(names, lengthof(names), SLE_STRINGID);
|
SlArray(names, lengthof(names), SLE_STRINGID);
|
||||||
|
|
||||||
|
/* Copy each string into the temporary engine array. */
|
||||||
for (EngineID engine = 0; engine < lengthof(names); engine++) {
|
for (EngineID engine = 0; engine < lengthof(names); engine++) {
|
||||||
Engine *e = GetEngine(engine);
|
Engine *e = GetTempDataEngine(engine);
|
||||||
e->name = CopyFromOldName(names[engine]);
|
e->name = CopyFromOldName(names[engine]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -661,10 +767,4 @@ void InitializeEngines()
|
||||||
/* Clean the engine renew pool and create 1 block in it */
|
/* Clean the engine renew pool and create 1 block in it */
|
||||||
_EngineRenew_pool.CleanPool();
|
_EngineRenew_pool.CleanPool();
|
||||||
_EngineRenew_pool.AddBlockToPool();
|
_EngineRenew_pool.AddBlockToPool();
|
||||||
|
|
||||||
Engine *e;
|
|
||||||
FOR_ALL_ENGINES(e) {
|
|
||||||
free(e->name);
|
|
||||||
e->name = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/** @file engine_base.h Base class for engines. */
|
||||||
|
|
||||||
|
#ifndef ENGINE_BASE_H
|
||||||
|
#define ENGINE_BASE_H
|
||||||
|
|
||||||
|
#include "engine_type.h"
|
||||||
|
#include "oldpool.h"
|
||||||
|
|
||||||
|
DECLARE_OLD_POOL(Engine, Engine, 6, 10000)
|
||||||
|
|
||||||
|
struct Engine : PoolItem<Engine, EngineID, &_Engine_pool> {
|
||||||
|
char *name; ///< Custom name of engine
|
||||||
|
Date intro_date;
|
||||||
|
Date age;
|
||||||
|
uint16 reliability;
|
||||||
|
uint16 reliability_spd_dec;
|
||||||
|
uint16 reliability_start, reliability_max, reliability_final;
|
||||||
|
uint16 duration_phase_1, duration_phase_2, duration_phase_3;
|
||||||
|
byte lifelength;
|
||||||
|
byte flags;
|
||||||
|
uint8 preview_player_rank;
|
||||||
|
byte preview_wait;
|
||||||
|
byte player_avail;
|
||||||
|
uint8 image_index; ///< Original vehicle image index
|
||||||
|
VehicleType type; ///< type, ie VEH_ROAD, VEH_TRAIN, etc.
|
||||||
|
|
||||||
|
EngineInfo info;
|
||||||
|
|
||||||
|
union {
|
||||||
|
RailVehicleInfo rail;
|
||||||
|
RoadVehicleInfo road;
|
||||||
|
ShipVehicleInfo ship;
|
||||||
|
AircraftVehicleInfo air;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
/* NewGRF related data */
|
||||||
|
const struct GRFFile *grffile;
|
||||||
|
const struct SpriteGroup *group[NUM_CARGO + 2];
|
||||||
|
uint16 internal_id; ///< ID within the GRF file
|
||||||
|
uint16 overrides_count;
|
||||||
|
struct WagonOverride *overrides;
|
||||||
|
uint16 list_position;
|
||||||
|
|
||||||
|
Engine();
|
||||||
|
Engine(VehicleType type, EngineID base);
|
||||||
|
~Engine();
|
||||||
|
|
||||||
|
inline bool IsValid() const { return this->info.climates != 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool IsEngineIndex(uint index)
|
||||||
|
{
|
||||||
|
return index < GetEnginePoolSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FOR_ALL_ENGINES_FROM(e, start) for (e = GetEngine(start); e != NULL; e = (e->index + 1U < GetEnginePoolSize()) ? GetEngine(e->index + 1U) : NULL) if (e->IsValid())
|
||||||
|
#define FOR_ALL_ENGINES(e) FOR_ALL_ENGINES_FROM(e, 0)
|
||||||
|
|
||||||
|
#define FOR_ALL_ENGINES_OF_TYPE(e, engine_type) FOR_ALL_ENGINES(e) if (e->type == engine_type)
|
||||||
|
|
||||||
|
static inline const EngineInfo *EngInfo(EngineID e)
|
||||||
|
{
|
||||||
|
return &GetEngine(e)->info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const RailVehicleInfo *RailVehInfo(EngineID e)
|
||||||
|
{
|
||||||
|
return &GetEngine(e)->u.rail;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const RoadVehicleInfo *RoadVehInfo(EngineID e)
|
||||||
|
{
|
||||||
|
return &GetEngine(e)->u.road;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const ShipVehicleInfo *ShipVehInfo(EngineID e)
|
||||||
|
{
|
||||||
|
return &GetEngine(e)->u.ship;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const AircraftVehicleInfo *AircraftVehInfo(EngineID e)
|
||||||
|
{
|
||||||
|
return &GetEngine(e)->u.air;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ENGINE_TYPE_H */
|
|
@ -10,6 +10,12 @@
|
||||||
void SetupEngines();
|
void SetupEngines();
|
||||||
void StartupEngines();
|
void StartupEngines();
|
||||||
|
|
||||||
|
Engine *GetTempDataEngine(EngineID index);
|
||||||
|
void CopyTempEngineData();
|
||||||
|
|
||||||
|
/* Original engine data counts and offsets */
|
||||||
|
extern const uint8 _engine_counts[4];
|
||||||
|
extern const uint8 _engine_offsets[4];
|
||||||
|
|
||||||
void DrawTrainEngine(int x, int y, EngineID engine, SpriteID pal);
|
void DrawTrainEngine(int x, int y, EngineID engine, SpriteID pal);
|
||||||
void DrawRoadVehEngine(int x, int y, EngineID engine, SpriteID pal);
|
void DrawRoadVehEngine(int x, int y, EngineID engine, SpriteID pal);
|
||||||
|
@ -22,83 +28,6 @@ void DeleteCustomEngineNames();
|
||||||
bool IsEngineBuildable(EngineID engine, VehicleType type, PlayerID player);
|
bool IsEngineBuildable(EngineID engine, VehicleType type, PlayerID player);
|
||||||
CargoID GetEngineCargoType(EngineID engine);
|
CargoID GetEngineCargoType(EngineID engine);
|
||||||
|
|
||||||
static inline EngineID GetFirstEngineOfType(VehicleType type)
|
|
||||||
{
|
|
||||||
const EngineID start[] = {0, ROAD_ENGINES_INDEX, SHIP_ENGINES_INDEX, AIRCRAFT_ENGINES_INDEX};
|
|
||||||
|
|
||||||
return start[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline EngineID GetLastEngineOfType(VehicleType type)
|
|
||||||
{
|
|
||||||
const EngineID end[] = {
|
|
||||||
NUM_TRAIN_ENGINES,
|
|
||||||
ROAD_ENGINES_INDEX + NUM_ROAD_ENGINES,
|
|
||||||
SHIP_ENGINES_INDEX + NUM_SHIP_ENGINES,
|
|
||||||
AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES};
|
|
||||||
|
|
||||||
return end[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
extern Engine _engines[TOTAL_NUM_ENGINES];
|
|
||||||
#define FOR_ALL_ENGINES(e) for (e = _engines; e != endof(_engines); e++)
|
|
||||||
#define FOR_ALL_ENGINEIDS_OF_TYPE(e, type) for (e = GetFirstEngineOfType(type); e != GetLastEngineOfType(type); e++)
|
|
||||||
|
|
||||||
|
|
||||||
static inline Engine* GetEngine(EngineID i)
|
|
||||||
{
|
|
||||||
assert(i < lengthof(_engines));
|
|
||||||
return &_engines[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool IsEngineIndex(uint index)
|
|
||||||
{
|
|
||||||
return index < TOTAL_NUM_ENGINES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Access Vehicle Data */
|
|
||||||
extern const EngineInfo _orig_engine_info[TOTAL_NUM_ENGINES];
|
|
||||||
extern const RailVehicleInfo _orig_rail_vehicle_info[NUM_TRAIN_ENGINES];
|
|
||||||
extern const ShipVehicleInfo _orig_ship_vehicle_info[NUM_SHIP_ENGINES];
|
|
||||||
extern const AircraftVehicleInfo _orig_aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES];
|
|
||||||
extern const RoadVehicleInfo _orig_road_vehicle_info[NUM_ROAD_ENGINES];
|
|
||||||
|
|
||||||
extern EngineInfo _engine_info[TOTAL_NUM_ENGINES];
|
|
||||||
extern RailVehicleInfo _rail_vehicle_info[NUM_TRAIN_ENGINES];
|
|
||||||
extern ShipVehicleInfo _ship_vehicle_info[NUM_SHIP_ENGINES];
|
|
||||||
extern AircraftVehicleInfo _aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES];
|
|
||||||
extern RoadVehicleInfo _road_vehicle_info[NUM_ROAD_ENGINES];
|
|
||||||
|
|
||||||
static inline const EngineInfo *EngInfo(EngineID e)
|
|
||||||
{
|
|
||||||
assert(e < lengthof(_engine_info));
|
|
||||||
return &_engine_info[e];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const RailVehicleInfo* RailVehInfo(EngineID e)
|
|
||||||
{
|
|
||||||
assert(e < lengthof(_rail_vehicle_info));
|
|
||||||
return &_rail_vehicle_info[e];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const ShipVehicleInfo* ShipVehInfo(EngineID e)
|
|
||||||
{
|
|
||||||
assert(e >= SHIP_ENGINES_INDEX && e < SHIP_ENGINES_INDEX + lengthof(_ship_vehicle_info));
|
|
||||||
return &_ship_vehicle_info[e - SHIP_ENGINES_INDEX];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const AircraftVehicleInfo* AircraftVehInfo(EngineID e)
|
|
||||||
{
|
|
||||||
assert(e >= AIRCRAFT_ENGINES_INDEX && e < AIRCRAFT_ENGINES_INDEX + lengthof(_aircraft_vehicle_info));
|
|
||||||
return &_aircraft_vehicle_info[e - AIRCRAFT_ENGINES_INDEX];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const RoadVehicleInfo* RoadVehInfo(EngineID e)
|
|
||||||
{
|
|
||||||
assert(e >= ROAD_ENGINES_INDEX && e < ROAD_ENGINES_INDEX + lengthof(_road_vehicle_info));
|
|
||||||
return &_road_vehicle_info[e - ROAD_ENGINES_INDEX];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Engine list manipulators - current implementation is only C wrapper of CBlobT<EngineID> class (helpers.cpp) */
|
/* Engine list manipulators - current implementation is only C wrapper of CBlobT<EngineID> class (helpers.cpp) */
|
||||||
void EngList_Create(EngineList *el); ///< Creates engine list
|
void EngList_Create(EngineList *el); ///< Creates engine list
|
||||||
void EngList_Destroy(EngineList *el); ///< Deallocate and destroy engine list
|
void EngList_Destroy(EngineList *el); ///< Deallocate and destroy engine list
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "window_gui.h"
|
#include "window_gui.h"
|
||||||
#include "gfx_func.h"
|
#include "gfx_func.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "command_func.h"
|
#include "command_func.h"
|
||||||
#include "economy_func.h"
|
#include "economy_func.h"
|
||||||
#include "news_func.h"
|
#include "news_func.h"
|
||||||
|
|
|
@ -18,6 +18,8 @@ typedef uint16 EngineID;
|
||||||
typedef uint16 EngineRenewID;
|
typedef uint16 EngineRenewID;
|
||||||
typedef EngineID *EngineList; ///< engine list type placeholder acceptable for C code (see helpers.cpp)
|
typedef EngineID *EngineList; ///< engine list type placeholder acceptable for C code (see helpers.cpp)
|
||||||
|
|
||||||
|
struct Engine;
|
||||||
|
|
||||||
enum RailVehicleTypes {
|
enum RailVehicleTypes {
|
||||||
RAILVEH_SINGLEHEAD, ///< indicates a "standalone" locomotive
|
RAILVEH_SINGLEHEAD, ///< indicates a "standalone" locomotive
|
||||||
RAILVEH_MULTIHEAD, ///< indicates a combination of two locomotives
|
RAILVEH_MULTIHEAD, ///< indicates a combination of two locomotives
|
||||||
|
@ -119,22 +121,6 @@ struct EngineInfo {
|
||||||
StringID string_id; ///< Default name of engine
|
StringID string_id; ///< Default name of engine
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Engine {
|
|
||||||
char *name; ///< Custom name of engine
|
|
||||||
Date intro_date;
|
|
||||||
Date age;
|
|
||||||
uint16 reliability;
|
|
||||||
uint16 reliability_spd_dec;
|
|
||||||
uint16 reliability_start, reliability_max, reliability_final;
|
|
||||||
uint16 duration_phase_1, duration_phase_2, duration_phase_3;
|
|
||||||
byte lifelength;
|
|
||||||
byte flags;
|
|
||||||
uint8 preview_player_rank;
|
|
||||||
byte preview_wait;
|
|
||||||
byte player_avail;
|
|
||||||
VehicleType type; ///< type, ie VEH_ROAD, VEH_TRAIN, etc.
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EngineInfo.misc_flags is a bitmask, with the following values
|
* EngineInfo.misc_flags is a bitmask, with the following values
|
||||||
*/
|
*/
|
||||||
|
@ -160,18 +146,4 @@ enum {
|
||||||
|
|
||||||
static const EngineID INVALID_ENGINE = 0xFFFF;
|
static const EngineID INVALID_ENGINE = 0xFFFF;
|
||||||
|
|
||||||
enum {
|
|
||||||
NUM_NORMAL_RAIL_ENGINES = 54,
|
|
||||||
NUM_MONORAIL_ENGINES = 30,
|
|
||||||
NUM_MAGLEV_ENGINES = 32,
|
|
||||||
NUM_TRAIN_ENGINES = NUM_NORMAL_RAIL_ENGINES + NUM_MONORAIL_ENGINES + NUM_MAGLEV_ENGINES,
|
|
||||||
NUM_ROAD_ENGINES = 88,
|
|
||||||
NUM_SHIP_ENGINES = 11,
|
|
||||||
NUM_AIRCRAFT_ENGINES = 41,
|
|
||||||
TOTAL_NUM_ENGINES = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES + NUM_AIRCRAFT_ENGINES,
|
|
||||||
AIRCRAFT_ENGINES_INDEX = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES + NUM_SHIP_ENGINES,
|
|
||||||
SHIP_ENGINES_INDEX = NUM_TRAIN_ENGINES + NUM_ROAD_ENGINES,
|
|
||||||
ROAD_ENGINES_INDEX = NUM_TRAIN_ENGINES,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* ENGINE_TYPE_H */
|
#endif /* ENGINE_TYPE_H */
|
||||||
|
|
|
@ -21,7 +21,7 @@ struct Group : PoolItem<Group, GroupID, &_Group_pool> {
|
||||||
VehicleTypeByte vehicle_type; ///< Vehicle type of the group
|
VehicleTypeByte vehicle_type; ///< Vehicle type of the group
|
||||||
|
|
||||||
bool replace_protection; ///< If set to true, the global autoreplace have no effect on the group
|
bool replace_protection; ///< If set to true, the global autoreplace have no effect on the group
|
||||||
uint16 num_engines[TOTAL_NUM_ENGINES]; ///< Caches the number of engines of each type the player owns (no need to save this)
|
uint16 *num_engines; ///< Caches the number of engines of each type the player owns (no need to save this)
|
||||||
|
|
||||||
Group(PlayerID owner = INVALID_PLAYER);
|
Group(PlayerID owner = INVALID_PLAYER);
|
||||||
virtual ~Group();
|
virtual ~Group();
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "player_func.h"
|
#include "player_func.h"
|
||||||
#include "order_func.h"
|
#include "order_func.h"
|
||||||
#include "oldpool_func.h"
|
#include "oldpool_func.h"
|
||||||
|
#include "core/alloc_func.hpp"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
|
@ -50,12 +51,14 @@ DEFINE_OLD_POOL_GENERIC(Group, Group)
|
||||||
Group::Group(PlayerID owner)
|
Group::Group(PlayerID owner)
|
||||||
{
|
{
|
||||||
this->owner = owner;
|
this->owner = owner;
|
||||||
|
this->num_engines = CallocT<uint16>(GetEnginePoolSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
Group::~Group()
|
Group::~Group()
|
||||||
{
|
{
|
||||||
free(this->name);
|
free(this->name);
|
||||||
this->owner = INVALID_PLAYER;
|
this->owner = INVALID_PLAYER;
|
||||||
|
free(this->num_engines);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Group::IsValid() const
|
bool Group::IsValid() const
|
||||||
|
|
|
@ -1054,6 +1054,7 @@ STR_CONFIG_PATCHES_FREIGHT_TRAINS :{LTBLUE}Weight
|
||||||
STR_CONFIG_PATCHES_PLANE_SPEED :{LTBLUE}Plane speed factor: {ORANGE}1 / {STRING1}
|
STR_CONFIG_PATCHES_PLANE_SPEED :{LTBLUE}Plane speed factor: {ORANGE}1 / {STRING1}
|
||||||
STR_CONFIG_PATCHES_STOP_ON_TOWN_ROAD :{LTBLUE}Allow drive-through road stops on town owned roads: {ORANGE}{STRING}
|
STR_CONFIG_PATCHES_STOP_ON_TOWN_ROAD :{LTBLUE}Allow drive-through road stops on town owned roads: {ORANGE}{STRING}
|
||||||
STR_CONFIG_PATCHES_ADJACENT_STATIONS :{LTBLUE}Allow building adjacent stations: {ORANGE}{STRING}
|
STR_CONFIG_PATCHES_ADJACENT_STATIONS :{LTBLUE}Allow building adjacent stations: {ORANGE}{STRING}
|
||||||
|
STR_CONFIG_PATCHES_DYNAMIC_ENGINES :{LTBLUE}Enable multiple NewGRF engine sets: {ORANGE}{STRING}
|
||||||
|
|
||||||
STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Always allow small airports: {ORANGE}{STRING1}
|
STR_CONFIG_PATCHES_SMALL_AIRPORTS :{LTBLUE}Always allow small airports: {ORANGE}{STRING1}
|
||||||
|
|
||||||
|
|
258
src/newgrf.cpp
258
src/newgrf.cpp
|
@ -10,6 +10,7 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "spritecache.h"
|
#include "spritecache.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "newgrf.h"
|
#include "newgrf.h"
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
#include "player_base.h"
|
#include "player_base.h"
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "map_func.h"
|
#include "map_func.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -97,20 +99,6 @@ static GrfDataType _grf_data_type;
|
||||||
|
|
||||||
typedef void (*SpecialSpriteHandler)(byte *buf, int len);
|
typedef void (*SpecialSpriteHandler)(byte *buf, int len);
|
||||||
|
|
||||||
static const uint _vehcounts[4] = {
|
|
||||||
/* GSF_TRAIN */ NUM_TRAIN_ENGINES,
|
|
||||||
/* GSF_ROAD */ NUM_ROAD_ENGINES,
|
|
||||||
/* GSF_SHIP */ NUM_SHIP_ENGINES,
|
|
||||||
/* GSF_AIRCRAFT */ NUM_AIRCRAFT_ENGINES
|
|
||||||
};
|
|
||||||
|
|
||||||
static const uint _vehshifts[4] = {
|
|
||||||
/* GSF_TRAIN */ 0,
|
|
||||||
/* GSF_ROAD */ ROAD_ENGINES_INDEX,
|
|
||||||
/* GSF_SHIP */ SHIP_ENGINES_INDEX,
|
|
||||||
/* GSF_AIRCRAFT */ AIRCRAFT_ENGINES_INDEX,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MAX_STATIONS = 256,
|
MAX_STATIONS = 256,
|
||||||
};
|
};
|
||||||
|
@ -123,8 +111,10 @@ struct GRFTempEngineData {
|
||||||
|
|
||||||
static GRFTempEngineData *_gted;
|
static GRFTempEngineData *_gted;
|
||||||
|
|
||||||
/* Contains the GRF ID of the owner of a vehicle if it has been reserved */
|
/* Contains the GRF ID of the owner of a vehicle if it has been reserved.
|
||||||
static uint32 _grm_engines[TOTAL_NUM_ENGINES];
|
* GRM for vehicles is only used if dynamic engine allocation is disabled,
|
||||||
|
* so 256 is the number of original engines. */
|
||||||
|
static uint32 _grm_engines[256];
|
||||||
|
|
||||||
/* Contains the GRF ID of the owner of a cargo if it has been reserved */
|
/* Contains the GRF ID of the owner of a cargo if it has been reserved */
|
||||||
static uint32 _grm_cargos[NUM_CARGO * 2];
|
static uint32 _grm_cargos[NUM_CARGO * 2];
|
||||||
|
@ -310,6 +300,65 @@ static uint8 MapDOSColour(uint8 colour)
|
||||||
return colour;
|
return colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::map<uint32, uint32> _grf_id_overrides;
|
||||||
|
|
||||||
|
static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
|
||||||
|
{
|
||||||
|
_grf_id_overrides[source_grfid] = target_grfid;
|
||||||
|
grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id)
|
||||||
|
{
|
||||||
|
/* Hack for add-on GRFs that need to modify another GRF's engines. This lets
|
||||||
|
* them use the same engine slots. */
|
||||||
|
const GRFFile *grf_match = NULL;
|
||||||
|
if (_patches.dynamic_engines) {
|
||||||
|
uint32 override = _grf_id_overrides[file->grfid];
|
||||||
|
if (override != 0) {
|
||||||
|
grf_match = GetFileByGRFID(override);
|
||||||
|
if (grf_match == NULL) {
|
||||||
|
grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
|
||||||
|
} else {
|
||||||
|
grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this vehicle is already defined... */
|
||||||
|
Engine *e = NULL;
|
||||||
|
FOR_ALL_ENGINES(e) {
|
||||||
|
if (_patches.dynamic_engines && e->grffile != NULL && e->grffile != file && e->grffile != grf_match) continue;
|
||||||
|
if (e->type != type) continue;
|
||||||
|
if (e->internal_id != internal_id) continue;
|
||||||
|
|
||||||
|
if (e->grffile == NULL) {
|
||||||
|
e->grffile = file;
|
||||||
|
grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint engine_pool_size = GetEnginePoolSize();
|
||||||
|
|
||||||
|
/* ... it's not, so create a new one based off an existing engine */
|
||||||
|
e = new Engine(type, internal_id);
|
||||||
|
e->grffile = file;
|
||||||
|
|
||||||
|
if (engine_pool_size != GetEnginePoolSize()) {
|
||||||
|
/* Resize temporary engine data ... */
|
||||||
|
_gted = ReallocT(_gted, GetEnginePoolSize());
|
||||||
|
|
||||||
|
/* and blank the new block. */
|
||||||
|
size_t len = (GetEnginePoolSize() - engine_pool_size) * sizeof(*_gted);
|
||||||
|
memset(_gted + engine_pool_size, 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
/** Map the colour modifiers of TTDPatch to those that Open is using.
|
/** Map the colour modifiers of TTDPatch to those that Open is using.
|
||||||
* @param grf_sprite pointer to the structure been modified
|
* @param grf_sprite pointer to the structure been modified
|
||||||
*/
|
*/
|
||||||
|
@ -333,18 +382,15 @@ static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
|
||||||
|
|
||||||
typedef bool (*VCI_Handler)(uint engine, int numinfo, int prop, byte **buf, int len);
|
typedef bool (*VCI_Handler)(uint engine, int numinfo, int prop, byte **buf, int len);
|
||||||
|
|
||||||
static void dewagonize(int condition, int engine)
|
static void dewagonize(int condition, Engine *e)
|
||||||
{
|
{
|
||||||
EngineInfo *ei = &_engine_info[engine];
|
|
||||||
RailVehicleInfo *rvi = &_rail_vehicle_info[engine];
|
|
||||||
|
|
||||||
if (condition != 0) {
|
if (condition != 0) {
|
||||||
ei->unk2 &= ~0x80;
|
e->info.unk2 &= ~0x80;
|
||||||
if (rvi->railveh_type == RAILVEH_WAGON)
|
if (e->u.rail.railveh_type == RAILVEH_WAGON)
|
||||||
rvi->railveh_type = RAILVEH_SINGLEHEAD;
|
e->u.rail.railveh_type = RAILVEH_SINGLEHEAD;
|
||||||
} else {
|
} else {
|
||||||
ei->unk2 |= 0x80;
|
e->info.unk2 |= 0x80;
|
||||||
rvi->railveh_type = RAILVEH_WAGON;
|
e->u.rail.railveh_type = RAILVEH_WAGON;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,8 +400,9 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
for (int i = 0; i < numinfo; i++) {
|
for (int i = 0; i < numinfo; i++) {
|
||||||
EngineInfo *ei = &_engine_info[engine + i];
|
Engine *e = GetNewEngine(_cur_grffile, VEH_TRAIN, engine + i);
|
||||||
RailVehicleInfo *rvi = &_rail_vehicle_info[engine + i];
|
EngineInfo *ei = &e->info;
|
||||||
|
RailVehicleInfo *rvi = &e->u.rail;
|
||||||
|
|
||||||
switch (prop) {
|
switch (prop) {
|
||||||
case 0x05: { // Track type
|
case 0x05: { // Track type
|
||||||
|
@ -390,7 +437,7 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf
|
||||||
if (rvi->railveh_type == RAILVEH_MULTIHEAD) power /= 2;
|
if (rvi->railveh_type == RAILVEH_MULTIHEAD) power /= 2;
|
||||||
|
|
||||||
rvi->power = power;
|
rvi->power = power;
|
||||||
dewagonize(power, engine + i);
|
dewagonize(power, e);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 0x0D: { // Running cost factor
|
case 0x0D: { // Running cost factor
|
||||||
|
@ -505,15 +552,9 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf
|
||||||
rvi->engclass = engclass;
|
rvi->engclass = engclass;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 0x1A: { // Alter purchase list sort order
|
case 0x1A: // Alter purchase list sort order
|
||||||
EngineID pos = grf_load_byte(&buf);
|
AlterRailVehListOrder(e->index, grf_load_byte(&buf));
|
||||||
|
break;
|
||||||
if (pos < NUM_TRAIN_ENGINES) {
|
|
||||||
AlterRailVehListOrder(engine + i, pos);
|
|
||||||
} else {
|
|
||||||
grfmsg(2, "RailVehicleChangeInfo: Invalid train engine ID %d, ignoring", pos);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case 0x1B: // Powered wagons power bonus
|
case 0x1B: // Powered wagons power bonus
|
||||||
rvi->pow_wag_power = grf_load_word(&buf);
|
rvi->pow_wag_power = grf_load_word(&buf);
|
||||||
|
@ -578,11 +619,11 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x28: // Cargo classes allowed
|
case 0x28: // Cargo classes allowed
|
||||||
_gted[engine + i].cargo_allowed = grf_load_word(&buf);
|
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x29: // Cargo classes disallowed
|
case 0x29: // Cargo classes disallowed
|
||||||
_gted[engine + i].cargo_disallowed = grf_load_word(&buf);
|
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x2A: // Long format introduction date (days since year 0)
|
case 0x2A: // Long format introduction date (days since year 0)
|
||||||
|
@ -605,8 +646,9 @@ static bool RoadVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
for (int i = 0; i < numinfo; i++) {
|
for (int i = 0; i < numinfo; i++) {
|
||||||
EngineInfo *ei = &_engine_info[ROAD_ENGINES_INDEX + engine + i];
|
Engine *e = GetNewEngine(_cur_grffile, VEH_ROAD, engine + i);
|
||||||
RoadVehicleInfo *rvi = &_road_vehicle_info[engine + i];
|
EngineInfo *ei = &e->info;
|
||||||
|
RoadVehicleInfo *rvi = &e->u.road;
|
||||||
|
|
||||||
switch (prop) {
|
switch (prop) {
|
||||||
case 0x08: // Speed (1 unit is 0.5 kmh)
|
case 0x08: // Speed (1 unit is 0.5 kmh)
|
||||||
|
@ -708,11 +750,11 @@ static bool RoadVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1D: // Cargo classes allowed
|
case 0x1D: // Cargo classes allowed
|
||||||
_gted[ROAD_ENGINES_INDEX + engine + i].cargo_allowed = grf_load_word(&buf);
|
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1E: // Cargo classes disallowed
|
case 0x1E: // Cargo classes disallowed
|
||||||
_gted[ROAD_ENGINES_INDEX + engine + i].cargo_disallowed = grf_load_word(&buf);
|
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1F: // Long format introduction date (days since year 0)
|
case 0x1F: // Long format introduction date (days since year 0)
|
||||||
|
@ -735,8 +777,9 @@ static bool ShipVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
for (int i = 0; i < numinfo; i++) {
|
for (int i = 0; i < numinfo; i++) {
|
||||||
EngineInfo *ei = &_engine_info[SHIP_ENGINES_INDEX + engine + i];
|
Engine *e = GetNewEngine(_cur_grffile, VEH_SHIP, engine + i);
|
||||||
ShipVehicleInfo *svi = &_ship_vehicle_info[engine + i];
|
EngineInfo *ei = &e->info;
|
||||||
|
ShipVehicleInfo *svi = &e->u.ship;
|
||||||
|
|
||||||
switch (prop) {
|
switch (prop) {
|
||||||
case 0x08: { // Sprite ID
|
case 0x08: { // Sprite ID
|
||||||
|
@ -814,11 +857,11 @@ static bool ShipVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x18: // Cargo classes allowed
|
case 0x18: // Cargo classes allowed
|
||||||
_gted[SHIP_ENGINES_INDEX + engine + i].cargo_allowed = grf_load_word(&buf);
|
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x19: // Cargo classes disallowed
|
case 0x19: // Cargo classes disallowed
|
||||||
_gted[SHIP_ENGINES_INDEX + engine + i].cargo_disallowed = grf_load_word(&buf);
|
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1A: // Long format introduction date (days since year 0)
|
case 0x1A: // Long format introduction date (days since year 0)
|
||||||
|
@ -841,8 +884,9 @@ static bool AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, byte *
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
for (int i = 0; i < numinfo; i++) {
|
for (int i = 0; i < numinfo; i++) {
|
||||||
EngineInfo *ei = &_engine_info[AIRCRAFT_ENGINES_INDEX + engine + i];
|
Engine *e = GetNewEngine(_cur_grffile, VEH_AIRCRAFT, engine + i);
|
||||||
AircraftVehicleInfo *avi = &_aircraft_vehicle_info[engine + i];
|
EngineInfo *ei = &e->info;
|
||||||
|
AircraftVehicleInfo *avi = &e->u.air;
|
||||||
|
|
||||||
switch (prop) {
|
switch (prop) {
|
||||||
case 0x08: { // Sprite ID
|
case 0x08: { // Sprite ID
|
||||||
|
@ -918,11 +962,11 @@ static bool AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, byte *
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x18: // Cargo classes allowed
|
case 0x18: // Cargo classes allowed
|
||||||
_gted[AIRCRAFT_ENGINES_INDEX + engine + i].cargo_allowed = grf_load_word(&buf);
|
_gted[e->index].cargo_allowed = grf_load_word(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x19: // Cargo classes disallowed
|
case 0x19: // Cargo classes disallowed
|
||||||
_gted[AIRCRAFT_ENGINES_INDEX + engine + i].cargo_disallowed = grf_load_word(&buf);
|
_gted[e->index].cargo_disallowed = grf_load_word(&buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1A: // Long format introduction date (days since year 0)
|
case 0x1A: // Long format introduction date (days since year 0)
|
||||||
|
@ -1604,6 +1648,12 @@ static bool GlobalVarChangeInfo(uint gvid, int numinfo, int prop, byte **bufp, i
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x11: // GRF match for engine allocation
|
||||||
|
/* This is loaded during the reservation stage, so just skip it here. */
|
||||||
|
/* Each entry is 8 bytes. */
|
||||||
|
buf += 8;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = true;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
|
@ -2211,13 +2261,6 @@ static void FeatureChangeInfo(byte *buf, int len)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (feature <= GSF_AIRCRAFT) {
|
|
||||||
if (engine + numinfo > _vehcounts[feature]) {
|
|
||||||
grfmsg(0, "FeatureChangeInfo: Last engine ID %d out of bounds (max %d), skipping", engine + numinfo, _vehcounts[feature]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (numprops-- && buf < bufend) {
|
while (numprops-- && buf < bufend) {
|
||||||
uint8 prop = grf_load_byte(&buf);
|
uint8 prop = grf_load_byte(&buf);
|
||||||
bool ignoring = false;
|
bool ignoring = false;
|
||||||
|
@ -2230,7 +2273,8 @@ static void FeatureChangeInfo(byte *buf, int len)
|
||||||
bool handled = true;
|
bool handled = true;
|
||||||
|
|
||||||
for (uint i = 0; i < numinfo; i++) {
|
for (uint i = 0; i < numinfo; i++) {
|
||||||
EngineInfo *ei = &_engine_info[engine + _vehshifts[feature] + i];
|
Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, engine + i);
|
||||||
|
EngineInfo *ei = &e->info;
|
||||||
|
|
||||||
/* Common properties for vehicles */
|
/* Common properties for vehicles */
|
||||||
switch (prop) {
|
switch (prop) {
|
||||||
|
@ -2252,6 +2296,8 @@ static void FeatureChangeInfo(byte *buf, int len)
|
||||||
|
|
||||||
case 0x06: // Climates available
|
case 0x06: // Climates available
|
||||||
ei->climates = grf_load_byte(&buf);
|
ei->climates = grf_load_byte(&buf);
|
||||||
|
// XXX sometimes a grf wants hidden vehicles :o
|
||||||
|
if (ei->climates == 0) ei->climates = 0x80;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x07: // Loading speed
|
case 0x07: // Loading speed
|
||||||
|
@ -2345,6 +2391,14 @@ static void ReserveChangeInfo(byte *buf, int len)
|
||||||
_cur_grffile->cargo_list[i] = BSWAP32(cl);
|
_cur_grffile->cargo_list[i] = BSWAP32(cl);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x11: // GRF match for engine allocation
|
||||||
|
for (uint i = 0; i < numinfo; i++) {
|
||||||
|
uint32 s = grf_load_dword(&buf);
|
||||||
|
uint32 t = grf_load_dword(&buf);
|
||||||
|
SetNewGRFOverride(s, t);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2857,14 +2911,9 @@ static void VehicleMapSpriteGroup(byte *buf, byte feature, uint8 idcount, uint8
|
||||||
|
|
||||||
for (uint i = 0; i < idcount; i++) {
|
for (uint i = 0; i < idcount; i++) {
|
||||||
uint8 engine_id = buf[3 + i];
|
uint8 engine_id = buf[3 + i];
|
||||||
uint8 engine = engine_id + _vehshifts[feature];
|
EngineID engine = GetNewEngine(_cur_grffile, (VehicleType)feature, engine_id)->index;
|
||||||
byte *bp = &buf[4 + idcount];
|
byte *bp = &buf[4 + idcount];
|
||||||
|
|
||||||
if (engine_id > _vehcounts[feature]) {
|
|
||||||
grfmsg(0, "Id %u for feature 0x%02X is out of bounds", engine_id, feature);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
|
grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
|
||||||
|
|
||||||
for (uint c = 0; c < cidcount; c++) {
|
for (uint c = 0; c < cidcount; c++) {
|
||||||
|
@ -2897,7 +2946,7 @@ static void VehicleMapSpriteGroup(byte *buf, byte feature, uint8 idcount, uint8
|
||||||
grfmsg(8, "-- Default group id 0x%04X", groupid);
|
grfmsg(8, "-- Default group id 0x%04X", groupid);
|
||||||
|
|
||||||
for (uint i = 0; i < idcount; i++) {
|
for (uint i = 0; i < idcount; i++) {
|
||||||
uint8 engine = buf[3 + i] + _vehshifts[feature];
|
EngineID engine = GetNewEngine(_cur_grffile, (VehicleType)feature, buf[3 + i])->index;
|
||||||
|
|
||||||
/* Don't tell me you don't love duplicated code! */
|
/* Don't tell me you don't love duplicated code! */
|
||||||
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
|
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
|
||||||
|
@ -3213,9 +3262,6 @@ static void FeatureNewName(byte *buf, int len)
|
||||||
|
|
||||||
ClrBit(lang, 7);
|
ClrBit(lang, 7);
|
||||||
|
|
||||||
if (feature <= GSF_AIRCRAFT && id < _vehcounts[feature]) {
|
|
||||||
id += _vehshifts[feature];
|
|
||||||
}
|
|
||||||
uint16 endid = id + num;
|
uint16 endid = id + num;
|
||||||
|
|
||||||
grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
|
grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
|
||||||
|
@ -3236,10 +3282,10 @@ static void FeatureNewName(byte *buf, int len)
|
||||||
case GSF_ROAD:
|
case GSF_ROAD:
|
||||||
case GSF_SHIP:
|
case GSF_SHIP:
|
||||||
case GSF_AIRCRAFT:
|
case GSF_AIRCRAFT:
|
||||||
if (id < TOTAL_NUM_ENGINES) {
|
if (id < GetEnginePoolSize()) {
|
||||||
StringID string = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_8000_KIRBY_PAUL_TANK_STEAM + id);
|
Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, id);
|
||||||
EngineInfo *ei = &_engine_info[id];
|
StringID string = AddGRFString(_cur_grffile->grfid, e->index, lang, new_scheme, name, e->info.string_id);
|
||||||
ei->string_id = string;
|
e->info.string_id = string;
|
||||||
} else {
|
} else {
|
||||||
AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, id);
|
AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, id);
|
||||||
}
|
}
|
||||||
|
@ -4303,8 +4349,22 @@ static void ParamSet(byte *buf, int len)
|
||||||
case 0x01: // Road Vehicles
|
case 0x01: // Road Vehicles
|
||||||
case 0x02: // Ships
|
case 0x02: // Ships
|
||||||
case 0x03: // Aircraft
|
case 0x03: // Aircraft
|
||||||
src1 = PerformGRM(&_grm_engines[_vehshifts[feature]], _vehcounts[feature], count, op, target, "vehicles");
|
if (!_patches.dynamic_engines) {
|
||||||
if (_skip_sprites == -1) return;
|
src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
|
||||||
|
if (_skip_sprites == -1) return;
|
||||||
|
} else {
|
||||||
|
// GRM does not apply for dynamic engine allocation.
|
||||||
|
switch (op) {
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
src1 = _cur_grffile->param[target];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
src1 = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x08: // General sprites
|
case 0x08: // General sprites
|
||||||
|
@ -5068,6 +5128,7 @@ static void InitializeGRFSpecial()
|
||||||
| (0 << 0x15) // enhancetunnels
|
| (0 << 0x15) // enhancetunnels
|
||||||
| (1 << 0x16) // shortrvs
|
| (1 << 0x16) // shortrvs
|
||||||
| (1 << 0x17) // articulatedrvs
|
| (1 << 0x17) // articulatedrvs
|
||||||
|
| ((_patches.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
|
||||||
| (1 << 0x1E); // variablerunningcosts
|
| (1 << 0x1E); // variablerunningcosts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5224,17 +5285,12 @@ static void ResetNewGRFData()
|
||||||
ResetBridges();
|
ResetBridges();
|
||||||
|
|
||||||
/* Allocate temporary refit/cargo class data */
|
/* Allocate temporary refit/cargo class data */
|
||||||
_gted = CallocT<GRFTempEngineData>(TOTAL_NUM_ENGINES);
|
_gted = CallocT<GRFTempEngineData>(GetEnginePoolSize());
|
||||||
|
|
||||||
/* Reset GRM reservations */
|
/* Reset GRM reservations */
|
||||||
memset(&_grm_engines, 0, sizeof(_grm_engines));
|
memset(&_grm_engines, 0, sizeof(_grm_engines));
|
||||||
memset(&_grm_cargos, 0, sizeof(_grm_cargos));
|
memset(&_grm_cargos, 0, sizeof(_grm_cargos));
|
||||||
|
|
||||||
/* Unload sprite group data */
|
|
||||||
UnloadWagonOverrides();
|
|
||||||
UnloadCustomEngineSprites();
|
|
||||||
ResetEngineListOrder();
|
|
||||||
|
|
||||||
/* Reset generic feature callback lists */
|
/* Reset generic feature callback lists */
|
||||||
ResetGenericCallbacks();
|
ResetGenericCallbacks();
|
||||||
|
|
||||||
|
@ -5284,6 +5340,9 @@ static void ResetNewGRFData()
|
||||||
_loaded_newgrf_features.has_newindustries = false;
|
_loaded_newgrf_features.has_newindustries = false;
|
||||||
_loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
|
_loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
|
||||||
|
|
||||||
|
/* Clear all GRF overrides */
|
||||||
|
_grf_id_overrides.clear();
|
||||||
|
|
||||||
InitializeSoundPool();
|
InitializeSoundPool();
|
||||||
InitializeSpriteGroupPool();
|
InitializeSpriteGroupPool();
|
||||||
}
|
}
|
||||||
|
@ -5397,14 +5456,17 @@ static const CargoLabel *_default_refitmasks[] = {
|
||||||
*/
|
*/
|
||||||
static void CalculateRefitMasks()
|
static void CalculateRefitMasks()
|
||||||
{
|
{
|
||||||
for (EngineID engine = 0; engine < TOTAL_NUM_ENGINES; engine++) {
|
Engine *e;
|
||||||
EngineInfo *ei = &_engine_info[engine];
|
|
||||||
|
FOR_ALL_ENGINES(e) {
|
||||||
|
EngineID engine = e->index;
|
||||||
|
EngineInfo *ei = &e->info;
|
||||||
uint32 mask = 0;
|
uint32 mask = 0;
|
||||||
uint32 not_mask = 0;
|
uint32 not_mask = 0;
|
||||||
uint32 xor_mask = 0;
|
uint32 xor_mask = 0;
|
||||||
|
|
||||||
if (ei->refit_mask != 0) {
|
if (ei->refit_mask != 0) {
|
||||||
const GRFFile *file = GetEngineGRF(engine);
|
const GRFFile *file = e->grffile;
|
||||||
if (file != NULL && file->cargo_max != 0) {
|
if (file != NULL && file->cargo_max != 0) {
|
||||||
/* Apply cargo translation table to the refit mask */
|
/* Apply cargo translation table to the refit mask */
|
||||||
uint num_cargo = min(32, file->cargo_max);
|
uint num_cargo = min(32, file->cargo_max);
|
||||||
|
@ -5434,15 +5496,10 @@ static void CalculateRefitMasks()
|
||||||
if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, i);
|
if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, i);
|
||||||
if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, i);
|
if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, i);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (xor_mask == 0) {
|
||||||
/* Don't apply default refit mask to wagons or engines with no capacity */
|
/* Don't apply default refit mask to wagons or engines with no capacity */
|
||||||
if (xor_mask == 0 && (
|
if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
|
||||||
GetEngine(engine)->type != VEH_TRAIN || (
|
const CargoLabel *cl = _default_refitmasks[e->type];
|
||||||
RailVehInfo(engine)->capacity != 0 &&
|
|
||||||
RailVehInfo(engine)->railveh_type != RAILVEH_WAGON
|
|
||||||
)
|
|
||||||
)) {
|
|
||||||
const CargoLabel *cl = _default_refitmasks[GetEngine(engine)->type];
|
|
||||||
for (uint i = 0;; i++) {
|
for (uint i = 0;; i++) {
|
||||||
if (cl[i] == 0) break;
|
if (cl[i] == 0) break;
|
||||||
|
|
||||||
|
@ -5458,25 +5515,25 @@ static void CalculateRefitMasks()
|
||||||
|
|
||||||
/* Check if this engine's cargo type is valid. If not, set to the first refittable
|
/* Check if this engine's cargo type is valid. If not, set to the first refittable
|
||||||
* cargo type. Apparently cargo_type isn't a common property... */
|
* cargo type. Apparently cargo_type isn't a common property... */
|
||||||
switch (GetEngine(engine)->type) {
|
switch (e->type) {
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
case VEH_AIRCRAFT: break;
|
case VEH_AIRCRAFT: break;
|
||||||
case VEH_TRAIN: {
|
case VEH_TRAIN: {
|
||||||
RailVehicleInfo *rvi = &_rail_vehicle_info[engine];
|
RailVehicleInfo *rvi = &e->u.rail;
|
||||||
if (rvi->cargo_type == CT_INVALID) rvi->cargo_type = FindFirstRefittableCargo(engine);
|
if (rvi->cargo_type == CT_INVALID) rvi->cargo_type = FindFirstRefittableCargo(engine);
|
||||||
if (rvi->cargo_type == CT_INVALID) ei->climates = 0;
|
if (rvi->cargo_type == CT_INVALID) ei->climates = 0x80;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VEH_ROAD: {
|
case VEH_ROAD: {
|
||||||
RoadVehicleInfo *rvi = &_road_vehicle_info[engine - ROAD_ENGINES_INDEX];
|
RoadVehicleInfo *rvi = &e->u.road;
|
||||||
if (rvi->cargo_type == CT_INVALID) rvi->cargo_type = FindFirstRefittableCargo(engine);
|
if (rvi->cargo_type == CT_INVALID) rvi->cargo_type = FindFirstRefittableCargo(engine);
|
||||||
if (rvi->cargo_type == CT_INVALID) ei->climates = 0;
|
if (rvi->cargo_type == CT_INVALID) ei->climates = 0x80;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VEH_SHIP: {
|
case VEH_SHIP: {
|
||||||
ShipVehicleInfo *svi = &_ship_vehicle_info[engine - SHIP_ENGINES_INDEX];
|
ShipVehicleInfo *svi = &e->u.ship;
|
||||||
if (svi->cargo_type == CT_INVALID) svi->cargo_type = FindFirstRefittableCargo(engine);
|
if (svi->cargo_type == CT_INVALID) svi->cargo_type = FindFirstRefittableCargo(engine);
|
||||||
if (svi->cargo_type == CT_INVALID) ei->climates = 0;
|
if (svi->cargo_type == CT_INVALID) ei->climates = 0x80;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5851,6 +5908,9 @@ static void AfterLoadGRFs()
|
||||||
/* Update the townname generators list */
|
/* Update the townname generators list */
|
||||||
InitGRFTownGeneratorNames();
|
InitGRFTownGeneratorNames();
|
||||||
|
|
||||||
|
/* Run all queued vehicle list order changes */
|
||||||
|
CommitRailVehListOrderChanges();
|
||||||
|
|
||||||
/* Load old shore sprites in new position, if they were replaced by ActionA */
|
/* Load old shore sprites in new position, if they were replaced by ActionA */
|
||||||
ActivateOldShore();
|
ActivateOldShore();
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "train.h"
|
#include "train.h"
|
||||||
#include "player_func.h"
|
#include "player_func.h"
|
||||||
#include "player_base.h"
|
#include "player_base.h"
|
||||||
|
@ -25,6 +26,8 @@
|
||||||
#include "direction_func.h"
|
#include "direction_func.h"
|
||||||
#include "rail_map.h"
|
#include "rail_map.h"
|
||||||
#include "rail.h"
|
#include "rail.h"
|
||||||
|
#include "settings_type.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
int _traininfo_vehicle_pitch = 0;
|
int _traininfo_vehicle_pitch = 0;
|
||||||
|
@ -37,29 +40,17 @@ struct WagonOverride {
|
||||||
const SpriteGroup *group;
|
const SpriteGroup *group;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WagonOverrides {
|
|
||||||
uint overrides_count;
|
|
||||||
WagonOverride *overrides;
|
|
||||||
};
|
|
||||||
|
|
||||||
static WagonOverrides _engine_wagon_overrides[TOTAL_NUM_ENGINES];
|
|
||||||
|
|
||||||
void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const SpriteGroup *group, EngineID *train_id, uint trains)
|
void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const SpriteGroup *group, EngineID *train_id, uint trains)
|
||||||
{
|
{
|
||||||
WagonOverrides *wos;
|
Engine *e = GetEngine(engine);
|
||||||
WagonOverride *wo;
|
WagonOverride *wo;
|
||||||
|
|
||||||
assert(engine < TOTAL_NUM_ENGINES);
|
|
||||||
assert(cargo < NUM_CARGO + 2); // Include CT_DEFAULT and CT_PURCHASE pseudo cargos.
|
assert(cargo < NUM_CARGO + 2); // Include CT_DEFAULT and CT_PURCHASE pseudo cargos.
|
||||||
|
|
||||||
wos = &_engine_wagon_overrides[engine];
|
e->overrides_count++;
|
||||||
wos->overrides_count++;
|
e->overrides = ReallocT(e->overrides, e->overrides_count);
|
||||||
wos->overrides = ReallocT(wos->overrides, wos->overrides_count);
|
|
||||||
|
|
||||||
wo = &wos->overrides[wos->overrides_count - 1];
|
wo = &e->overrides[e->overrides_count - 1];
|
||||||
/* FIXME: If we are replacing an override, release original SpriteGroup
|
|
||||||
* to prevent leaks. But first we need to refcount the SpriteGroup.
|
|
||||||
* --pasky */
|
|
||||||
wo->group = group;
|
wo->group = group;
|
||||||
wo->cargo = cargo;
|
wo->cargo = cargo;
|
||||||
wo->trains = trains;
|
wo->trains = trains;
|
||||||
|
@ -69,15 +60,15 @@ void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const SpriteGroup *
|
||||||
|
|
||||||
const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, EngineID overriding_engine)
|
const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, EngineID overriding_engine)
|
||||||
{
|
{
|
||||||
const WagonOverrides *wos = &_engine_wagon_overrides[engine];
|
const Engine *e = GetEngine(engine);
|
||||||
|
|
||||||
/* XXX: This could turn out to be a timesink on profiles. We could
|
/* XXX: This could turn out to be a timesink on profiles. We could
|
||||||
* always just dedicate 65535 bytes for an [engine][train] trampoline
|
* always just dedicate 65535 bytes for an [engine][train] trampoline
|
||||||
* for O(1). Or O(logMlogN) and searching binary tree or smt. like
|
* for O(1). Or O(logMlogN) and searching binary tree or smt. like
|
||||||
* that. --pasky */
|
* that. --pasky */
|
||||||
|
|
||||||
for (uint i = 0; i < wos->overrides_count; i++) {
|
for (uint i = 0; i < e->overrides_count; i++) {
|
||||||
const WagonOverride *wo = &wos->overrides[i];
|
const WagonOverride *wo = &e->overrides[i];
|
||||||
|
|
||||||
if (wo->cargo != cargo && wo->cargo != CT_DEFAULT) continue;
|
if (wo->cargo != cargo && wo->cargo != CT_DEFAULT) continue;
|
||||||
|
|
||||||
|
@ -91,43 +82,29 @@ const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, Eng
|
||||||
/**
|
/**
|
||||||
* Unload all wagon override sprite groups.
|
* Unload all wagon override sprite groups.
|
||||||
*/
|
*/
|
||||||
void UnloadWagonOverrides()
|
void UnloadWagonOverrides(Engine *e)
|
||||||
{
|
{
|
||||||
for (EngineID engine = 0; engine < TOTAL_NUM_ENGINES; engine++) {
|
for (uint i = 0; i < e->overrides_count; i++) {
|
||||||
WagonOverrides *wos = &_engine_wagon_overrides[engine];
|
WagonOverride *wo = &e->overrides[i];
|
||||||
for (uint i = 0; i < wos->overrides_count; i++) {
|
free(wo->train_id);
|
||||||
WagonOverride *wo = &wos->overrides[i];
|
|
||||||
free(wo->train_id);
|
|
||||||
}
|
|
||||||
free(wos->overrides);
|
|
||||||
wos->overrides_count = 0;
|
|
||||||
wos->overrides = NULL;
|
|
||||||
}
|
}
|
||||||
|
free(e->overrides);
|
||||||
|
e->overrides_count = 0;
|
||||||
|
e->overrides = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Space for NUM_CARGO real cargos and 2 pseudo cargos, CT_DEFAULT and CT_PURCHASE */
|
|
||||||
static const SpriteGroup *_engine_custom_sprites[TOTAL_NUM_ENGINES][NUM_CARGO + 2];
|
|
||||||
static const GRFFile *_engine_grf[TOTAL_NUM_ENGINES];
|
|
||||||
|
|
||||||
void SetCustomEngineSprites(EngineID engine, byte cargo, const SpriteGroup *group)
|
void SetCustomEngineSprites(EngineID engine, byte cargo, const SpriteGroup *group)
|
||||||
{
|
{
|
||||||
assert(engine < lengthof(_engine_custom_sprites));
|
Engine *e = GetEngine(engine);
|
||||||
assert(cargo < lengthof(*_engine_custom_sprites));
|
assert(cargo < lengthof(e->group));
|
||||||
|
|
||||||
if (_engine_custom_sprites[engine][cargo] != NULL) {
|
if (e->group[cargo] != NULL) {
|
||||||
grfmsg(6, "SetCustomEngineSprites: engine %d cargo %d already has group -- replacing", engine, cargo);
|
grfmsg(6, "SetCustomEngineSprites: engine %d cargo %d already has group -- replacing", engine, cargo);
|
||||||
}
|
}
|
||||||
_engine_custom_sprites[engine][cargo] = group;
|
e->group[cargo] = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Unload all engine sprite groups.
|
|
||||||
*/
|
|
||||||
void UnloadCustomEngineSprites()
|
|
||||||
{
|
|
||||||
memset(_engine_custom_sprites, 0, sizeof(_engine_custom_sprites));
|
|
||||||
memset(_engine_grf, 0, sizeof(_engine_grf));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tie a GRFFile entry to an engine, to allow us to retrieve GRF parameters
|
* Tie a GRFFile entry to an engine, to allow us to retrieve GRF parameters
|
||||||
|
@ -137,8 +114,8 @@ void UnloadCustomEngineSprites()
|
||||||
*/
|
*/
|
||||||
void SetEngineGRF(EngineID engine, const GRFFile *file)
|
void SetEngineGRF(EngineID engine, const GRFFile *file)
|
||||||
{
|
{
|
||||||
assert(engine < TOTAL_NUM_ENGINES);
|
Engine *e = GetEngine(engine);
|
||||||
_engine_grf[engine] = file;
|
e->grffile = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,8 +126,7 @@ void SetEngineGRF(EngineID engine, const GRFFile *file)
|
||||||
*/
|
*/
|
||||||
const GRFFile *GetEngineGRF(EngineID engine)
|
const GRFFile *GetEngineGRF(EngineID engine)
|
||||||
{
|
{
|
||||||
assert(engine < TOTAL_NUM_ENGINES);
|
return GetEngine(engine)->grffile;
|
||||||
return _engine_grf[engine];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -161,8 +137,7 @@ const GRFFile *GetEngineGRF(EngineID engine)
|
||||||
*/
|
*/
|
||||||
uint32 GetEngineGRFID(EngineID engine)
|
uint32 GetEngineGRFID(EngineID engine)
|
||||||
{
|
{
|
||||||
assert(engine < TOTAL_NUM_ENGINES);
|
return GetEngineGRF(engine)->grfid;
|
||||||
return _engine_grf[engine]->grfid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -468,6 +443,7 @@ static uint32 GetGRFParameter(EngineID engine_type, byte parameter)
|
||||||
{
|
{
|
||||||
const GRFFile *file = GetEngineGRF(engine_type);
|
const GRFFile *file = GetEngineGRF(engine_type);
|
||||||
|
|
||||||
|
if (file == NULL) return 0;
|
||||||
if (parameter >= file->param_end) return 0;
|
if (parameter >= file->param_end) return 0;
|
||||||
return file->param[parameter];
|
return file->param[parameter];
|
||||||
}
|
}
|
||||||
|
@ -643,12 +619,13 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
|
||||||
|
|
||||||
/* Variables which use the parameter */
|
/* Variables which use the parameter */
|
||||||
case 0x60: // Count consist's engine ID occurance
|
case 0x60: // Count consist's engine ID occurance
|
||||||
if (v->type != VEH_TRAIN) return v->engine_type == parameter;
|
//EngineID engine = GetNewEngineID(GetEngineGRF(v->engine_type), v->type, parameter);
|
||||||
|
if (v->type != VEH_TRAIN) return GetEngine(v->engine_type)->internal_id == parameter;
|
||||||
|
|
||||||
{
|
{
|
||||||
uint count = 0;
|
uint count = 0;
|
||||||
for (; v != NULL; v = v->Next()) {
|
for (; v != NULL; v = v->Next()) {
|
||||||
if (v->engine_type == parameter) count++;
|
if (GetEngine(v->engine_type)->internal_id == parameter) count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -723,8 +700,8 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
|
||||||
case 0x43: return GB(v->max_age, 8, 8);
|
case 0x43: return GB(v->max_age, 8, 8);
|
||||||
case 0x44: return Clamp(v->build_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
|
case 0x44: return Clamp(v->build_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
|
||||||
case 0x45: return v->unitnumber;
|
case 0x45: return v->unitnumber;
|
||||||
case 0x46: return v->engine_type;
|
case 0x46: return GetEngine(v->engine_type)->internal_id;
|
||||||
case 0x47: return GB(v->engine_type, 8, 8);
|
case 0x47: return GB(GetEngine(v->engine_type)->internal_id, 8, 8);
|
||||||
case 0x48:
|
case 0x48:
|
||||||
if (v->type != VEH_TRAIN || v->spritenum != 0xFD) return v->spritenum;
|
if (v->type != VEH_TRAIN || v->spritenum != 0xFD) return v->spritenum;
|
||||||
return HasBit(v->u.rail.flags, VRF_REVERSE_DIRECTION) ? 0xFE : 0xFD;
|
return HasBit(v->u.rail.flags, VRF_REVERSE_DIRECTION) ? 0xFE : 0xFD;
|
||||||
|
@ -883,11 +860,13 @@ static const SpriteGroup *GetVehicleSpriteGroup(EngineID engine, const Vehicle *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group = _engine_custom_sprites[engine][cargo];
|
const Engine *e = GetEngine(engine);
|
||||||
|
|
||||||
|
group = e->group[cargo];
|
||||||
if (group != NULL) return group;
|
if (group != NULL) return group;
|
||||||
|
|
||||||
/* Fall back to the default set if the selected cargo type is not defined */
|
/* Fall back to the default set if the selected cargo type is not defined */
|
||||||
return _engine_custom_sprites[engine][CT_DEFAULT];
|
return e->group[CT_DEFAULT];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -907,14 +886,14 @@ SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction dire
|
||||||
|
|
||||||
SpriteID GetRotorOverrideSprite(EngineID engine, const Vehicle *v, bool info_view)
|
SpriteID GetRotorOverrideSprite(EngineID engine, const Vehicle *v, bool info_view)
|
||||||
{
|
{
|
||||||
|
const Engine *e = GetEngine(engine);
|
||||||
const SpriteGroup *group;
|
const SpriteGroup *group;
|
||||||
ResolverObject object;
|
ResolverObject object;
|
||||||
|
|
||||||
assert(engine >= AIRCRAFT_ENGINES_INDEX);
|
assert(e->type == VEH_AIRCRAFT);
|
||||||
assert(engine < AIRCRAFT_ENGINES_INDEX + NUM_AIRCRAFT_ENGINES);
|
|
||||||
|
|
||||||
/* Only valid for helicopters */
|
/* Only valid for helicopters */
|
||||||
assert(!(AircraftVehInfo(engine)->subtype & AIR_CTOL));
|
assert(!(e->u.air.subtype & AIR_CTOL));
|
||||||
|
|
||||||
NewVehicleResolver(&object, engine, v);
|
NewVehicleResolver(&object, engine, v);
|
||||||
|
|
||||||
|
@ -1090,18 +1069,6 @@ void TriggerVehicle(Vehicle *v, VehicleTrigger trigger)
|
||||||
|
|
||||||
/* Functions for changing the order of vehicle purchase lists
|
/* Functions for changing the order of vehicle purchase lists
|
||||||
* This is currently only implemented for rail vehicles. */
|
* This is currently only implemented for rail vehicles. */
|
||||||
static EngineID _engine_list_order[NUM_TRAIN_ENGINES];
|
|
||||||
static byte _engine_list_position[NUM_TRAIN_ENGINES];
|
|
||||||
|
|
||||||
void ResetEngineListOrder()
|
|
||||||
{
|
|
||||||
EngineID i;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
|
|
||||||
_engine_list_order[i] = i;
|
|
||||||
_engine_list_position[i] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list position of an engine.
|
* Get the list position of an engine.
|
||||||
|
@ -1109,36 +1076,72 @@ void ResetEngineListOrder()
|
||||||
* @param engine ID of the engine.
|
* @param engine ID of the engine.
|
||||||
* @return The list position of the engine.
|
* @return The list position of the engine.
|
||||||
*/
|
*/
|
||||||
uint16 ListPositionOfEngine(EngineID engine)
|
uint ListPositionOfEngine(EngineID engine)
|
||||||
{
|
{
|
||||||
if (engine < NUM_TRAIN_ENGINES) return _engine_list_position[engine];
|
const Engine *e = GetEngine(engine);
|
||||||
return engine;
|
if (e->grffile == NULL) return e->list_position;
|
||||||
|
|
||||||
|
/* Crude sorting to group by GRF ID */
|
||||||
|
return (e->grffile->grfid * 256) + e->list_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ListOrderChange {
|
||||||
|
EngineID engine;
|
||||||
|
EngineID target;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::list<ListOrderChange> _list_order_changes;
|
||||||
|
|
||||||
void AlterRailVehListOrder(EngineID engine, EngineID target)
|
void AlterRailVehListOrder(EngineID engine, EngineID target)
|
||||||
{
|
{
|
||||||
EngineID i;
|
/* Add the list order change to a queue */
|
||||||
bool moving = false;
|
ListOrderChange loc;
|
||||||
|
loc.engine = engine;
|
||||||
if (engine == target) return;
|
loc.target = target;
|
||||||
|
_list_order_changes.push_back(loc);
|
||||||
/* First, remove our ID from the list. */
|
}
|
||||||
for (i = 0; i < NUM_TRAIN_ENGINES - 1; i++) {
|
|
||||||
if (_engine_list_order[i] == engine) moving = true;
|
void CommitRailVehListOrderChanges()
|
||||||
if (moving) _engine_list_order[i] = _engine_list_order[i + 1];
|
{
|
||||||
}
|
/* List position to Engine map */
|
||||||
|
typedef std::map<uint16, Engine*> ListPositionMap;
|
||||||
/* Now, insert it again, before the target engine. */
|
ListPositionMap lptr_map;
|
||||||
for (i = NUM_TRAIN_ENGINES - 1; i > 0; i--) {
|
|
||||||
_engine_list_order[i] = _engine_list_order[i - 1];
|
std::list<ListOrderChange>::iterator it;
|
||||||
if (_engine_list_order[i] == target) {
|
for (it = _list_order_changes.begin(); it != _list_order_changes.end(); ++it) {
|
||||||
_engine_list_order[i - 1] = engine;
|
EngineID engine = it->engine;
|
||||||
break;
|
EngineID target = it->target;
|
||||||
}
|
|
||||||
}
|
if (engine == target) continue;
|
||||||
|
|
||||||
/* Update the engine list position (a reverse of engine list order) */
|
Engine *source_e = GetEngine(engine);
|
||||||
for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
|
Engine *target_e = NULL;
|
||||||
_engine_list_position[_engine_list_order[i]] = i;
|
|
||||||
}
|
/* Populate map with current list positions */
|
||||||
|
Engine *e;
|
||||||
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
|
||||||
|
if (!_patches.dynamic_engines || e->grffile == source_e->grffile) {
|
||||||
|
if (e->internal_id == target) target_e = e;
|
||||||
|
lptr_map[e->list_position] = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the target position, if it exists */
|
||||||
|
if (target_e != NULL) {
|
||||||
|
uint16 target_position = target_e->list_position;
|
||||||
|
|
||||||
|
bool moving = false;
|
||||||
|
for (ListPositionMap::iterator it = lptr_map.begin(); it != lptr_map.end(); ++it) {
|
||||||
|
if (it->first == target_position) moving = true;
|
||||||
|
if (moving) it->second->list_position++;
|
||||||
|
}
|
||||||
|
|
||||||
|
source_e->list_position = target_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
lptr_map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear out the queue */
|
||||||
|
_list_order_changes.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,11 +53,10 @@ enum VehicleTrigger {
|
||||||
};
|
};
|
||||||
void TriggerVehicle(Vehicle *veh, VehicleTrigger trigger);
|
void TriggerVehicle(Vehicle *veh, VehicleTrigger trigger);
|
||||||
|
|
||||||
void UnloadWagonOverrides();
|
void UnloadWagonOverrides(Engine *e);
|
||||||
void UnloadCustomEngineSprites();
|
|
||||||
|
|
||||||
void ResetEngineListOrder();
|
uint ListPositionOfEngine(EngineID engine);
|
||||||
uint16 ListPositionOfEngine(EngineID engine);
|
|
||||||
void AlterRailVehListOrder(EngineID engine, EngineID target);
|
void AlterRailVehListOrder(EngineID engine, EngineID target);
|
||||||
|
void CommitRailVehListOrderChanges();
|
||||||
|
|
||||||
#endif /* NEWGRF_ENGINE_H */
|
#endif /* NEWGRF_ENGINE_H */
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "openttd.h"
|
#include "openttd.h"
|
||||||
#include "oldpool.h"
|
#include "oldpool.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "newgrf_callbacks.h"
|
#include "newgrf_callbacks.h"
|
||||||
#include "newgrf_engine.h"
|
#include "newgrf_engine.h"
|
||||||
#include "newgrf_sound.h"
|
#include "newgrf_sound.h"
|
||||||
|
|
|
@ -1330,18 +1330,19 @@ static const OldChunks engine_chunk[] = {
|
||||||
|
|
||||||
static bool LoadOldEngine(LoadgameState *ls, int num)
|
static bool LoadOldEngine(LoadgameState *ls, int num)
|
||||||
{
|
{
|
||||||
if (!LoadChunk(ls, GetEngine(num), engine_chunk)) return false;
|
Engine *e = GetTempDataEngine(num);
|
||||||
|
if (!LoadChunk(ls, e, engine_chunk)) return false;
|
||||||
|
|
||||||
/* Make sure wagons are marked as do-not-age */
|
/* Make sure wagons are marked as do-not-age */
|
||||||
if ((num >= 27 && num < 54) || (num >= 57 && num < 84) || (num >= 89 && num < 116))
|
if ((num >= 27 && num < 54) || (num >= 57 && num < 84) || (num >= 89 && num < 116))
|
||||||
GetEngine(num)->age = 0xFFFF;
|
e->age = 0xFFFF;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadOldEngineName(LoadgameState *ls, int num)
|
static bool LoadOldEngineName(LoadgameState *ls, int num)
|
||||||
{
|
{
|
||||||
Engine *e = GetEngine(num);
|
Engine *e = GetTempDataEngine(num);
|
||||||
e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
|
e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,6 +305,7 @@ static void UnInitializeGame()
|
||||||
_Order_pool.CleanPool();
|
_Order_pool.CleanPool();
|
||||||
_Group_pool.CleanPool();
|
_Group_pool.CleanPool();
|
||||||
_CargoPacket_pool.CleanPool();
|
_CargoPacket_pool.CleanPool();
|
||||||
|
_Engine_pool.CleanPool();
|
||||||
|
|
||||||
free((void*)_town_sort);
|
free((void*)_town_sort);
|
||||||
free((void*)_industry_sort);
|
free((void*)_industry_sort);
|
||||||
|
@ -1332,6 +1333,8 @@ static bool InitializeWindowsAndCaches()
|
||||||
/* Recalculate */
|
/* Recalculate */
|
||||||
Group *g;
|
Group *g;
|
||||||
FOR_ALL_GROUPS(g) {
|
FOR_ALL_GROUPS(g) {
|
||||||
|
g->num_engines = CallocT<uint16>(GetEnginePoolSize());
|
||||||
|
|
||||||
const Vehicle *v;
|
const Vehicle *v;
|
||||||
FOR_ALL_VEHICLES(v) {
|
FOR_ALL_VEHICLES(v) {
|
||||||
if (!IsEngineCountable(v)) continue;
|
if (!IsEngineCountable(v)) continue;
|
||||||
|
@ -1354,6 +1357,9 @@ static bool InitializeWindowsAndCaches()
|
||||||
* thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */
|
* thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */
|
||||||
if (_file_to_saveload.filetype == FT_SCENARIO && players[i]->inaugurated_year != MIN_YEAR)
|
if (_file_to_saveload.filetype == FT_SCENARIO && players[i]->inaugurated_year != MIN_YEAR)
|
||||||
players[i]->inaugurated_year = _cur_year;
|
players[i]->inaugurated_year = _cur_year;
|
||||||
|
|
||||||
|
free(players[i]->num_engines);
|
||||||
|
players[i]->num_engines = CallocT<uint16>(GetEnginePoolSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
FOR_ALL_VEHICLES(v) {
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
@ -1444,10 +1450,16 @@ bool AfterLoadGame()
|
||||||
* must be done before loading sprites as some newgrfs check it */
|
* must be done before loading sprites as some newgrfs check it */
|
||||||
SetDate(_date);
|
SetDate(_date);
|
||||||
|
|
||||||
|
/* Force dynamic engines off when loading older savegames */
|
||||||
|
if (CheckSavegameVersion(95)) _patches.dynamic_engines = 0;
|
||||||
|
|
||||||
/* Load the sprites */
|
/* Load the sprites */
|
||||||
GfxLoadSprites();
|
GfxLoadSprites();
|
||||||
LoadStringWidthTable();
|
LoadStringWidthTable();
|
||||||
|
|
||||||
|
/* Copy temporary data to Engine pool */
|
||||||
|
CopyTempEngineData();
|
||||||
|
|
||||||
/* Connect front and rear engines of multiheaded trains and converts
|
/* Connect front and rear engines of multiheaded trains and converts
|
||||||
* subtype to the new format */
|
* subtype to the new format */
|
||||||
if (CheckSavegameVersionOldStyle(17, 1)) ConvertOldMultiheadToNew();
|
if (CheckSavegameVersionOldStyle(17, 1)) ConvertOldMultiheadToNew();
|
||||||
|
|
|
@ -70,7 +70,7 @@ struct Player {
|
||||||
bool renew_keep_length;
|
bool renew_keep_length;
|
||||||
int16 engine_renew_months;
|
int16 engine_renew_months;
|
||||||
uint32 engine_renew_money;
|
uint32 engine_renew_money;
|
||||||
uint16 num_engines[TOTAL_NUM_ENGINES]; ///< caches the number of engines of each type the player owns (no need to save this)
|
uint16 *num_engines; ///< caches the number of engines of each type the player owns (no need to save this)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerMoneyBackup {
|
struct PlayerMoneyBackup {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "openttd.h"
|
#include "openttd.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "player_func.h"
|
#include "player_func.h"
|
||||||
#include "player_gui.h"
|
#include "player_gui.h"
|
||||||
#include "town.h"
|
#include "town.h"
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include "date_func.h"
|
#include "date_func.h"
|
||||||
#include "vehicle_func.h"
|
#include "vehicle_func.h"
|
||||||
#include "sound_func.h"
|
#include "sound_func.h"
|
||||||
|
#include "core/alloc_func.hpp"
|
||||||
#include "autoreplace_func.h"
|
#include "autoreplace_func.h"
|
||||||
#include "autoreplace_gui.h"
|
#include "autoreplace_gui.h"
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
|
@ -548,7 +550,8 @@ Player *DoStartupNewPlayer(bool is_ai)
|
||||||
if (is_ai && (!_networking || _network_server) && _ai.enabled)
|
if (is_ai && (!_networking || _network_server) && _ai.enabled)
|
||||||
AI_StartNewAI(p->index);
|
AI_StartNewAI(p->index);
|
||||||
|
|
||||||
memset(p->num_engines, 0, sizeof(p->num_engines));
|
free(p->num_engines);
|
||||||
|
p->num_engines = CallocT<uint16>(GetEnginePoolSize());
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
10
src/rail.cpp
10
src/rail.cpp
|
@ -14,6 +14,7 @@
|
||||||
#include "player_func.h"
|
#include "player_func.h"
|
||||||
#include "player_base.h"
|
#include "player_base.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
|
|
||||||
|
|
||||||
/* XXX: Below 3 tables store duplicate data. Maybe remove some? */
|
/* XXX: Below 3 tables store duplicate data. Maybe remove some? */
|
||||||
|
@ -202,14 +203,13 @@ RailTypes GetPlayerRailtypes(PlayerID p)
|
||||||
{
|
{
|
||||||
RailTypes rt = RAILTYPES_NONE;
|
RailTypes rt = RAILTYPES_NONE;
|
||||||
|
|
||||||
EngineID eid;
|
Engine *e;
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(eid, VEH_TRAIN) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
|
||||||
const Engine* e = GetEngine(eid);
|
const EngineInfo *ei = &e->info;
|
||||||
const EngineInfo *ei = EngInfo(eid);
|
|
||||||
|
|
||||||
if (HasBit(ei->climates, _opt.landscape) &&
|
if (HasBit(ei->climates, _opt.landscape) &&
|
||||||
(HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
|
(HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
|
||||||
const RailVehicleInfo *rvi = RailVehInfo(eid);
|
const RailVehicleInfo *rvi = &e->u.rail;
|
||||||
|
|
||||||
if (rvi->railveh_type != RAILVEH_WAGON) {
|
if (rvi->railveh_type != RAILVEH_WAGON) {
|
||||||
assert(rvi->railtype < RAILTYPE_END);
|
assert(rvi->railtype < RAILTYPE_END);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "command_func.h"
|
#include "command_func.h"
|
||||||
#include "pathfind.h"
|
#include "pathfind.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "town.h"
|
#include "town.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "depot_base.h"
|
#include "depot_base.h"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "player_func.h"
|
#include "player_func.h"
|
||||||
#include "player_base.h"
|
#include "player_base.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "date_func.h"
|
#include "date_func.h"
|
||||||
|
|
||||||
|
@ -96,10 +97,9 @@ RoadTypes GetPlayerRoadtypes(PlayerID p)
|
||||||
{
|
{
|
||||||
RoadTypes rt = ROADTYPES_NONE;
|
RoadTypes rt = ROADTYPES_NONE;
|
||||||
|
|
||||||
EngineID eid;
|
Engine *e;
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(eid, VEH_ROAD) {
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
|
||||||
const Engine* e = GetEngine(eid);
|
const EngineInfo *ei = &e->info;
|
||||||
const EngineInfo *ei = EngInfo(eid);
|
|
||||||
|
|
||||||
if (HasBit(ei->climates, _opt.landscape) &&
|
if (HasBit(ei->climates, _opt.landscape) &&
|
||||||
(HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
|
(HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "vehicle_base.h"
|
#include "vehicle_base.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "economy_func.h"
|
#include "economy_func.h"
|
||||||
|
|
||||||
enum RoadVehicleSubType {
|
enum RoadVehicleSubType {
|
||||||
|
|
|
@ -102,7 +102,7 @@ static SpriteID GetRoadVehIcon(EngineID engine)
|
||||||
SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W);
|
SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W);
|
||||||
if (sprite != 0) return sprite;
|
if (sprite != 0) return sprite;
|
||||||
|
|
||||||
spritenum = _orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index;
|
spritenum = GetEngine(engine)->image_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 6 + _roadveh_images[spritenum];
|
return 6 + _roadveh_images[spritenum];
|
||||||
|
@ -117,7 +117,7 @@ SpriteID RoadVehicle::GetImage(Direction direction) const
|
||||||
sprite = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)));
|
sprite = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)));
|
||||||
if (sprite != 0) return sprite;
|
if (sprite != 0) return sprite;
|
||||||
|
|
||||||
spritenum = _orig_road_vehicle_info[this->engine_type - ROAD_ENGINES_INDEX].image_index;
|
spritenum = GetEngine(this->engine_type)->image_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite = direction + _roadveh_images[spritenum];
|
sprite = direction + _roadveh_images[spritenum];
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
extern const uint16 SAVEGAME_VERSION = 94;
|
extern const uint16 SAVEGAME_VERSION = 95;
|
||||||
uint16 _sl_version; ///< the major savegame version identifier
|
uint16 _sl_version; ///< the major savegame version identifier
|
||||||
byte _sl_minor_version; ///< the minor savegame version, DO NOT USE!
|
byte _sl_minor_version; ///< the minor savegame version, DO NOT USE!
|
||||||
|
|
||||||
|
|
|
@ -1459,6 +1459,7 @@ const SettingDesc _patch_settings[] = {
|
||||||
SDT_CONDVAR(Patches, freight_trains, SLE_UINT8, 39, SL_MAX_VERSION, 0,NN, 1, 1, 255, 1, STR_CONFIG_PATCHES_FREIGHT_TRAINS, NULL),
|
SDT_CONDVAR(Patches, freight_trains, SLE_UINT8, 39, SL_MAX_VERSION, 0,NN, 1, 1, 255, 1, STR_CONFIG_PATCHES_FREIGHT_TRAINS, NULL),
|
||||||
SDT_CONDBOOL(Patches, timetabling, 67, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_PATCHES_TIMETABLE_ALLOW, NULL),
|
SDT_CONDBOOL(Patches, timetabling, 67, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_PATCHES_TIMETABLE_ALLOW, NULL),
|
||||||
SDT_CONDVAR(Patches, plane_speed, SLE_UINT8, 90, SL_MAX_VERSION, 0, 0, 4, 1, 4, 0, STR_CONFIG_PATCHES_PLANE_SPEED, NULL),
|
SDT_CONDVAR(Patches, plane_speed, SLE_UINT8, 90, SL_MAX_VERSION, 0, 0, 4, 1, 4, 0, STR_CONFIG_PATCHES_PLANE_SPEED, NULL),
|
||||||
|
SDT_CONDBOOL(Patches, dynamic_engines, 95, SL_MAX_VERSION, 0,NN, false, STR_CONFIG_PATCHES_DYNAMIC_ENGINES, NULL),
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/* Station section of the GUI-configure patches window */
|
/* Station section of the GUI-configure patches window */
|
||||||
|
|
|
@ -819,6 +819,7 @@ static const char *_patches_vehicles[] = {
|
||||||
"freight_trains",
|
"freight_trains",
|
||||||
"plane_speed",
|
"plane_speed",
|
||||||
"timetabling",
|
"timetabling",
|
||||||
|
"dynamic_engines",
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PatchEntry {
|
struct PatchEntry {
|
||||||
|
|
|
@ -232,6 +232,8 @@ struct Patches {
|
||||||
bool give_money; ///< allow giving other players money
|
bool give_money; ///< allow giving other players money
|
||||||
|
|
||||||
bool enable_signal_gui; ///< Show the signal GUI when the signal button is pressed
|
bool enable_signal_gui; ///< Show the signal GUI when the signal button is pressed
|
||||||
|
|
||||||
|
bool dynamic_engines; ///< Enable dynamic allocation of engine data
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Patches _patches;
|
extern Patches _patches;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "vehicle_base.h"
|
#include "vehicle_base.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "economy_func.h"
|
#include "economy_func.h"
|
||||||
|
|
||||||
void CcBuildShip(bool success, TileIndex tile, uint32 p1, uint32 p2);
|
void CcBuildShip(bool success, TileIndex tile, uint32 p1, uint32 p2);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "station_base.h"
|
#include "station_base.h"
|
||||||
#include "news_func.h"
|
#include "news_func.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "player_func.h"
|
#include "player_func.h"
|
||||||
#include "player_base.h"
|
#include "player_base.h"
|
||||||
#include "npf.h"
|
#include "npf.h"
|
||||||
|
@ -65,7 +66,7 @@ static SpriteID GetShipIcon(EngineID engine)
|
||||||
SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W);
|
SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W);
|
||||||
if (sprite != 0) return sprite;
|
if (sprite != 0) return sprite;
|
||||||
|
|
||||||
spritenum = _orig_ship_vehicle_info[engine - SHIP_ENGINES_INDEX].image_index;
|
spritenum = GetEngine(engine)->image_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 6 + _ship_sprites[spritenum];
|
return 6 + _ship_sprites[spritenum];
|
||||||
|
@ -97,7 +98,7 @@ SpriteID Ship::GetImage(Direction direction) const
|
||||||
SpriteID sprite = GetCustomVehicleSprite(this, direction);
|
SpriteID sprite = GetCustomVehicleSprite(this, direction);
|
||||||
if (sprite != 0) return sprite;
|
if (sprite != 0) return sprite;
|
||||||
|
|
||||||
spritenum = _orig_ship_vehicle_info[this->engine_type - SHIP_ENGINES_INDEX].image_index;
|
spritenum = GetEngine(this->engine_type)->image_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _ship_sprites[spritenum] + direction;
|
return _ship_sprites[spritenum] + direction;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "video/video_driver.hpp"
|
#include "video/video_driver.hpp"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
@ -934,7 +935,7 @@ static char* FormatString(char* buff, const char* str, const int64* argv, uint c
|
||||||
if (e->name != NULL) {
|
if (e->name != NULL) {
|
||||||
buff = strecpy(buff, e->name, last);
|
buff = strecpy(buff, e->name, last);
|
||||||
} else {
|
} else {
|
||||||
buff = GetStringWithArgs(buff, EngInfo(engine)->string_id, NULL, last);
|
buff = GetStringWithArgs(buff, e->info.string_id, NULL, last);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ enum {
|
||||||
#define A 2
|
#define A 2
|
||||||
#define S 4
|
#define S 4
|
||||||
#define Y 8
|
#define Y 8
|
||||||
const EngineInfo _orig_engine_info[] = {
|
static const EngineInfo _orig_engine_info[] = {
|
||||||
MK( 1827, 20, 15, 30, T ), /* 0 Kirby Paul Tank (Steam) */
|
MK( 1827, 20, 15, 30, T ), /* 0 Kirby Paul Tank (Steam) */
|
||||||
MK( 12784, 20, 22, 30, A|S ), /* 1 MJS 250 (Diesel) */
|
MK( 12784, 20, 22, 30, A|S ), /* 1 MJS 250 (Diesel) */
|
||||||
MK( 9497, 20, 20, 50, Y), /* 2 Ploddyphut Choo-Choo */
|
MK( 9497, 20, 20, 50, Y), /* 2 Ploddyphut Choo-Choo */
|
||||||
|
@ -370,7 +370,7 @@ const EngineInfo _orig_engine_info[] = {
|
||||||
#define O RAILTYPE_MONO
|
#define O RAILTYPE_MONO
|
||||||
#define L RAILTYPE_MAGLEV
|
#define L RAILTYPE_MAGLEV
|
||||||
|
|
||||||
const RailVehicleInfo _orig_rail_vehicle_info[NUM_TRAIN_ENGINES] = {
|
static const RailVehicleInfo _orig_rail_vehicle_info[] = {
|
||||||
// image_index max_speed (kph) running_cost ai_rank
|
// image_index max_speed (kph) running_cost ai_rank
|
||||||
// | flags | power (hp) | running_cost_class | railtype
|
// | flags | power (hp) | running_cost_class | railtype
|
||||||
// | | base_cost | weight | | capacity | |
|
// | | base_cost | weight | | capacity | |
|
||||||
|
@ -519,7 +519,7 @@ const RailVehicleInfo _orig_rail_vehicle_info[NUM_TRAIN_ENGINES] = {
|
||||||
* @param h refittable
|
* @param h refittable
|
||||||
*/
|
*/
|
||||||
#define SVI(a, b, c, d, e, f, g, h) { a, b, c, d, e, f, {g}, h }
|
#define SVI(a, b, c, d, e, f, g, h) { a, b, c, d, e, f, {g}, h }
|
||||||
const ShipVehicleInfo _orig_ship_vehicle_info[NUM_SHIP_ENGINES] = {
|
static const ShipVehicleInfo _orig_ship_vehicle_info[] = {
|
||||||
// image_index cargo_type cargo_amount refittable
|
// image_index cargo_type cargo_amount refittable
|
||||||
// | base_cost | | running_cost |
|
// | base_cost | | running_cost |
|
||||||
// | | max_speed | | sfx |
|
// | | max_speed | | sfx |
|
||||||
|
@ -554,7 +554,7 @@ const ShipVehicleInfo _orig_ship_vehicle_info[NUM_SHIP_ENGINES] = {
|
||||||
#define H AIR_HELI
|
#define H AIR_HELI
|
||||||
#define P AIR_CTOL
|
#define P AIR_CTOL
|
||||||
#define J AIR_CTOL | AIR_FAST
|
#define J AIR_CTOL | AIR_FAST
|
||||||
const AircraftVehicleInfo _orig_aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES] = {
|
static const AircraftVehicleInfo _orig_aircraft_vehicle_info[] = {
|
||||||
// image_index sfx acceleration
|
// image_index sfx acceleration
|
||||||
// | base_cost | | max_speed
|
// | base_cost | | max_speed
|
||||||
// | | running_cost | | mail_capacity
|
// | | running_cost | | mail_capacity
|
||||||
|
@ -618,7 +618,7 @@ const AircraftVehicleInfo _orig_aircraft_vehicle_info[NUM_AIRCRAFT_ENGINES] = {
|
||||||
* @param g cargo_type
|
* @param g cargo_type
|
||||||
*/
|
*/
|
||||||
#define ROV(a, b, c, d, e, f, g) { a, b, c, RC_R, {d}, e, f, g }
|
#define ROV(a, b, c, d, e, f, g) { a, b, c, RC_R, {d}, e, f, g }
|
||||||
const RoadVehicleInfo _orig_road_vehicle_info[NUM_ROAD_ENGINES] = {
|
static const RoadVehicleInfo _orig_road_vehicle_info[] = {
|
||||||
// image_index sfx max_speed
|
// image_index sfx max_speed
|
||||||
// | base_cost | | capacity
|
// | base_cost | | capacity
|
||||||
// | | running_cost | | cargo_type
|
// | | running_cost | | cargo_type
|
||||||
|
|
|
@ -33,7 +33,7 @@ static FileList files_dos = {
|
||||||
{ "TRGT.GRF", {0xfc, 0xde, 0x1d, 0x7e, 0x8a, 0x74, 0x19, 0x7d, 0x72, 0xa6, 0x26, 0x95, 0x88, 0x4b, 0x90, 0x9e} }
|
{ "TRGT.GRF", {0xfc, 0xde, 0x1d, 0x7e, 0x8a, 0x74, 0x19, 0x7d, 0x72, 0xa6, 0x26, 0x95, 0x88, 0x4b, 0x90, 0x9e} }
|
||||||
},
|
},
|
||||||
{ "SAMPLE.CAT", {0x42, 0x2e, 0xa3, 0xdd, 0x07, 0x4d, 0x28, 0x59, 0xbb, 0x51, 0x63, 0x9a, 0x6e, 0x0e, 0x85, 0xda} },
|
{ "SAMPLE.CAT", {0x42, 0x2e, 0xa3, 0xdd, 0x07, 0x4d, 0x28, 0x59, 0xbb, 0x51, 0x63, 0x9a, 0x6e, 0x0e, 0x85, 0xda} },
|
||||||
{ "OPENTTDD.GRF", {0x32, 0xb4, 0xec, 0x0c, 0xc9, 0x5d, 0xa0, 0x14, 0x3a, 0x2f, 0xe1, 0xd4, 0x20, 0x63, 0x49, 0x74} }
|
{ "OPENTTDD.GRF", {0xb2, 0xbd, 0xd2, 0xa4, 0x1b, 0xfa, 0x2c, 0x60, 0x4f, 0xd5, 0x5e, 0x4c, 0xb5, 0xba, 0x37, 0x73} }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,5 +47,5 @@ static FileList files_win = {
|
||||||
{ "TRGTR.GRF", {0xde, 0x53, 0x65, 0x05, 0x17, 0xfe, 0x66, 0x1c, 0xea, 0xa3, 0x13, 0x8c, 0x6e, 0xdb, 0x0e, 0xb8} }
|
{ "TRGTR.GRF", {0xde, 0x53, 0x65, 0x05, 0x17, 0xfe, 0x66, 0x1c, 0xea, 0xa3, 0x13, 0x8c, 0x6e, 0xdb, 0x0e, 0xb8} }
|
||||||
},
|
},
|
||||||
{ "SAMPLE.CAT", {0x92, 0x12, 0xe8, 0x1e, 0x72, 0xba, 0xdd, 0x4b, 0xbe, 0x1e, 0xae, 0xae, 0x66, 0x45, 0x8e, 0x10} },
|
{ "SAMPLE.CAT", {0x92, 0x12, 0xe8, 0x1e, 0x72, 0xba, 0xdd, 0x4b, 0xbe, 0x1e, 0xae, 0xae, 0x66, 0x45, 0x8e, 0x10} },
|
||||||
{ "OPENTTDW.GRF", {0xc6, 0x1f, 0xcc, 0x4e, 0x83, 0x98, 0x5b, 0x67, 0xb7, 0x03, 0xa0, 0x31, 0x39, 0x2e, 0x75, 0xfc} }
|
{ "OPENTTDW.GRF", {0x3b, 0x1a, 0x0d, 0x8c, 0x2d, 0x01, 0x0e, 0xee, 0x47, 0x7f, 0x5d, 0x70, 0x8f, 0xb2, 0xe4, 0xfb} }
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "station_base.h"
|
#include "station_base.h"
|
||||||
#include "news_func.h"
|
#include "news_func.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "player_func.h"
|
#include "player_func.h"
|
||||||
#include "player_base.h"
|
#include "player_base.h"
|
||||||
#include "depot_base.h"
|
#include "depot_base.h"
|
||||||
|
@ -487,7 +488,7 @@ SpriteID Train::GetImage(Direction direction) const
|
||||||
sprite = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)));
|
sprite = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)));
|
||||||
if (sprite != 0) return sprite;
|
if (sprite != 0) return sprite;
|
||||||
|
|
||||||
spritenum = _orig_rail_vehicle_info[this->engine_type].image_index;
|
spritenum = GetEngine(this->engine_type)->image_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite = _engine_sprite_base[spritenum] + ((direction + _engine_sprite_add[spritenum]) & _engine_sprite_and[spritenum]);
|
sprite = _engine_sprite_base[spritenum] + ((direction + _engine_sprite_add[spritenum]) & _engine_sprite_and[spritenum]);
|
||||||
|
@ -509,7 +510,7 @@ static SpriteID GetRailIcon(EngineID engine, bool rear_head, int &y)
|
||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
spritenum = _orig_rail_vehicle_info[engine].image_index;
|
spritenum = GetEngine(engine)->image_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rear_head) spritenum++;
|
if (rear_head) spritenum++;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "order_func.h"
|
#include "order_func.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
|
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "tunnelbridge.h"
|
#include "tunnelbridge.h"
|
||||||
#include "player_base.h"
|
#include "player_base.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
|
#include "engine_base.h"
|
||||||
#include "economy_func.h"
|
#include "economy_func.h"
|
||||||
#include "rail.h"
|
#include "rail.h"
|
||||||
#include "cheat_func.h"
|
#include "cheat_func.h"
|
||||||
|
|
|
@ -1985,9 +1985,9 @@ bool CanBuildVehicleInfrastructure(VehicleType type)
|
||||||
/* We can build vehicle infrastructure when we may build the vehicle type */
|
/* We can build vehicle infrastructure when we may build the vehicle type */
|
||||||
if (max > 0) {
|
if (max > 0) {
|
||||||
/* Can we actually build the vehicle type? */
|
/* Can we actually build the vehicle type? */
|
||||||
EngineID eid;
|
const Engine *e;
|
||||||
FOR_ALL_ENGINEIDS_OF_TYPE(eid, type) {
|
FOR_ALL_ENGINES_OF_TYPE(e, type) {
|
||||||
if (HasBit(GetEngine(eid)->player_avail, _local_player)) return true;
|
if (HasBit(e->player_avail, _local_player)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue