mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r1323) Adding autoreplace feature
This feature works much like autorenew, but it will get you a new engine type instead of a new one of the same type. Once ordered, it will automatically replace the engines while they visits a depot. The GUI for setting this up have been added on the vehicle overview windows Note: autorenew is now autoreplace, but to the same engine type Nice new features, that was added to make this possible - windows can now have two independant vertical scrollbars - CMD_SHOW_NO_ERROR have been added as a flag for DoCommandP. It will make it do the action instead of showing the red box with estimated costs even if shift is pressed - fixed problem where enginetypes where not initialized when loading a game. It's now done in InitializeGame()
This commit is contained in:
parent
a11f46fed4
commit
29d8c5bb50
|
@ -406,29 +406,32 @@ int32 CmdChangeAircraftServiceInt(int x, int y, uint32 flags, uint32 p1, uint32
|
|||
}
|
||||
|
||||
// p1 = vehicle
|
||||
// p2 = new cargo type
|
||||
// p2 = new cargo type(0xFF)
|
||||
// p2 = skip check for stopped in hanger (0x0100)
|
||||
int32 CmdRefitAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
Vehicle *v,*u;
|
||||
int pass, mail;
|
||||
int32 cost;
|
||||
byte SkipStoppedInHangerCheck = (p2 & 0x100) >> 8; //excludes the cargo value
|
||||
byte new_cargo_type = p2 & 0xFF; //gets the cargo number
|
||||
|
||||
SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_RUN);
|
||||
|
||||
v = &_vehicles[p1];
|
||||
if (!CheckOwnership(v->owner) || !CheckStoppedInHangar(v))
|
||||
if (!CheckOwnership(v->owner) || (!CheckStoppedInHangar(v) && !(SkipStoppedInHangerCheck)))
|
||||
return CMD_ERROR;
|
||||
|
||||
pass = AircraftVehInfo(v->engine_type)->passanger_capacity;
|
||||
if (p2 != 0) {
|
||||
if (new_cargo_type != CT_PASSENGERS) {
|
||||
pass >>= 1;
|
||||
if (p2 != 5)
|
||||
if (new_cargo_type != CT_GOODS)
|
||||
pass >>= 1;
|
||||
}
|
||||
_aircraft_refit_capacity = pass;
|
||||
|
||||
cost = 0;
|
||||
if (IS_HUMAN_PLAYER(v->owner) && (byte)p2 != v->cargo_type) {
|
||||
if (IS_HUMAN_PLAYER(v->owner) && new_cargo_type != v->cargo_type) {
|
||||
cost = _price.aircraft_base >> 7;
|
||||
}
|
||||
|
||||
|
@ -437,12 +440,15 @@ int32 CmdRefitAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
u = v->next;
|
||||
mail = AircraftVehInfo(v->engine_type)->mail_capacity;
|
||||
if (p2 != 0) {
|
||||
if (new_cargo_type != CT_PASSENGERS) {
|
||||
mail = 0;
|
||||
}
|
||||
u->cargo_cap = mail;
|
||||
v->cargo_count = u->cargo_count = 0;
|
||||
v->cargo_type = (byte)p2;
|
||||
//autorefitted planes wants to keep the cargo
|
||||
//it will be checked if the cargo is valid in CmdReplaceVehicle
|
||||
if (!(SkipStoppedInHangerCheck))
|
||||
v->cargo_count = u->cargo_count = 0;
|
||||
v->cargo_type = new_cargo_type;
|
||||
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
||||
}
|
||||
|
||||
|
@ -1157,7 +1163,7 @@ static void AircraftEnterHangar(Vehicle *v)
|
|||
|
||||
ServiceAircraft(v);
|
||||
|
||||
MaybeRenewVehicle(v);
|
||||
MaybeReplaceVehicle(v);
|
||||
|
||||
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
||||
|
||||
|
|
|
@ -13,6 +13,26 @@
|
|||
#include "player.h"
|
||||
|
||||
|
||||
void Set_DPARAM_Aircraft_Build_Window(uint16 engine_number)
|
||||
{
|
||||
const AircraftVehicleInfo *avi = AircraftVehInfo(engine_number);
|
||||
Engine *e;
|
||||
YearMonthDay ymd;
|
||||
|
||||
SetDParam(0, avi->base_cost * (_price.aircraft_base>>3)>>5);
|
||||
SetDParam(1, avi->max_speed * 8);
|
||||
SetDParam(2, avi->passanger_capacity);
|
||||
SetDParam(3, avi->mail_capacity);
|
||||
SetDParam(4, avi->running_cost * _price.aircraft_running >> 8);
|
||||
|
||||
e = &_engines[engine_number];
|
||||
SetDParam(6, e->lifelength);
|
||||
SetDParam(7, e->reliability * 100 >> 16);
|
||||
ConvertDayToYMD(&ymd, e->intro_date);
|
||||
SetDParam(5, ymd.year + 1920);
|
||||
|
||||
}
|
||||
|
||||
static void DrawAircraftImage(Vehicle *v, int x, int y, VehicleID selection)
|
||||
{
|
||||
int image = GetAircraftImage(v, 6);
|
||||
|
@ -43,8 +63,6 @@ void CcBuildAircraft(bool success, uint tile, uint32 p1, uint32 p2)
|
|||
|
||||
static void NewAircraftWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
YearMonthDay ymd;
|
||||
|
||||
switch(e->event) {
|
||||
|
||||
case WE_PAINT: {
|
||||
|
@ -89,20 +107,7 @@ static void NewAircraftWndProc(Window *w, WindowEvent *e)
|
|||
WP(w,buildtrain_d).sel_engine = selected_id;
|
||||
|
||||
if (selected_id != -1) {
|
||||
const AircraftVehicleInfo *avi = AircraftVehInfo(selected_id);
|
||||
Engine *e;
|
||||
|
||||
SetDParam(0, avi->base_cost * (_price.aircraft_base>>3)>>5);
|
||||
SetDParam(1, avi->max_speed * 8);
|
||||
SetDParam(2, avi->passanger_capacity);
|
||||
SetDParam(3, avi->mail_capacity);
|
||||
SetDParam(4, avi->running_cost * _price.aircraft_running >> 8);
|
||||
|
||||
e = &_engines[selected_id];
|
||||
SetDParam(6, e->lifelength);
|
||||
SetDParam(7, e->reliability * 100 >> 16);
|
||||
ConvertDayToYMD(&ymd, e->intro_date);
|
||||
SetDParam(5, ymd.year + 1920);
|
||||
Set_DPARAM_Aircraft_Build_Window(selected_id);
|
||||
|
||||
DrawString(2, 111, STR_A007_COST_SPEED_CAPACITY_PASSENGERS, 0);
|
||||
}
|
||||
|
@ -899,7 +904,7 @@ static Widget _player_aircraft_widgets[] = {
|
|||
{ WWT_MATRIX, 14, 0, 248, 26, 169, 0x401, STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT},
|
||||
{ WWT_SCROLLBAR, 14, 249, 259, 26, 169, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_PUSHTXTBTN, 14, 0, 129, 170, 181, STR_A003_NEW_AIRCRAFT, STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES},
|
||||
{ WWT_PANEL, 14, 130, 259, 170, 181, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 14, 130, 259, 170, 181, STR_REPLACE_VEHICLES, STR_REPLACE_HELP},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
|
@ -1005,7 +1010,7 @@ static void PlayerAircraftWndProc(Window *w, WindowEvent *e)
|
|||
break;
|
||||
|
||||
case 4: case 5:/* Select sorting criteria dropdown menu */
|
||||
ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0);
|
||||
ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0, 0);
|
||||
return;
|
||||
|
||||
case 7: { /* Matrix to show vehicles */
|
||||
|
@ -1044,6 +1049,11 @@ static void PlayerAircraftWndProc(Window *w, WindowEvent *e)
|
|||
|
||||
ShowBuildAircraftWindow(0);
|
||||
} break;
|
||||
|
||||
case 10:
|
||||
ShowReplaceVehicleWindow(VEH_Aircraft);
|
||||
break;
|
||||
|
||||
}
|
||||
} break;
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@ DEF_COMMAND(CmdStartScenario);
|
|||
|
||||
DEF_COMMAND(CmdBuildManySignals);
|
||||
|
||||
DEF_COMMAND(CmdRenewVehicle);
|
||||
DEF_COMMAND(CmdReplaceVehicle);
|
||||
|
||||
/* The master command table */
|
||||
static CommandProc * const _command_proc_table[] = {
|
||||
|
@ -309,7 +309,7 @@ static CommandProc * const _command_proc_table[] = {
|
|||
CmdDestroyCompanyHQ, /* 111 */
|
||||
CmdGiveMoney, /* 112 */
|
||||
CmdChangePatchSetting, /* 113 */
|
||||
CmdRenewVehicle, /* 114 */
|
||||
CmdReplaceVehicle, /* 114 */
|
||||
};
|
||||
|
||||
int32 DoCommandByTile(TileIndex tile, uint32 p1, uint32 p2, uint32 flags, uint procc)
|
||||
|
@ -431,7 +431,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback,
|
|||
_docommand_recursive = 1;
|
||||
|
||||
// cost estimation only?
|
||||
if (_shift_pressed && _current_player == _local_player && !(cmd & CMD_NETWORK_COMMAND)) {
|
||||
if (_shift_pressed && _current_player == _local_player && !(cmd & (CMD_NETWORK_COMMAND | CMD_SHOW_NO_ERROR))) {
|
||||
// estimate the cost.
|
||||
res = proc(x, y, flags, p1, p2);
|
||||
if ((uint32)res >> 16 == 0x8000) {
|
||||
|
|
|
@ -149,7 +149,7 @@ enum {
|
|||
CMD_GIVE_MONEY = 112,
|
||||
CMD_CHANGE_PATCH_SETTING = 113,
|
||||
|
||||
CMD_RENEW_VEHICLE = 114,
|
||||
CMD_REPLACE_VEHICLE = 114,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -172,6 +172,7 @@ enum {
|
|||
CMD_NO_WATER = 0x400,
|
||||
CMD_NETWORK_COMMAND = 0x800, // execute the command without sending it on the network
|
||||
CMD_NO_TEST_IF_IN_NETWORK = 0x1000, // When enabled, the command will bypass the no-DC_EXEC round if in network
|
||||
CMD_SHOW_NO_ERROR = 0x2000,
|
||||
};
|
||||
|
||||
//#define return_cmd_error(errcode) do { _error_message=(errcode); return CMD_ERROR; } while(0)
|
||||
|
|
38
engine.c
38
engine.c
|
@ -115,6 +115,29 @@ static void CalcEngineReliability(Engine *e)
|
|||
}
|
||||
}
|
||||
|
||||
void AddTypeToEngines()
|
||||
{
|
||||
Engine *e;
|
||||
uint32 counter = 0;
|
||||
|
||||
for(e=_engines; e != endof(_engines); e++, counter++) {
|
||||
|
||||
e->type = VEH_Train;
|
||||
if (counter >= ROAD_ENGINES_INDEX) {
|
||||
e->type = VEH_Road;
|
||||
if (counter >= SHIP_ENGINES_INDEX) {
|
||||
e->type = VEH_Ship;
|
||||
if (counter >= AIRCRAFT_ENGINES_INDEX) {
|
||||
e->type = VEH_Aircraft;
|
||||
if (counter >= TOTAL_NUM_ENGINES) {
|
||||
e->type = VEH_Special;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StartupEngines()
|
||||
{
|
||||
Engine *e;
|
||||
|
@ -123,8 +146,8 @@ void StartupEngines()
|
|||
|
||||
SetupEngineNames();
|
||||
|
||||
|
||||
for(e=_engines, ei=_engine_info; e != endof(_engines); e++, ei++, counter++) {
|
||||
|
||||
e->age = 0;
|
||||
e->railtype = ei->railtype_climates >> 4;
|
||||
e->flags = 0;
|
||||
|
@ -170,19 +193,6 @@ void StartupEngines()
|
|||
It should hopefully be the same as when you ask a vehicle what it is
|
||||
but using this, you can ask what type an engine number is
|
||||
even if it is not a vehicle (yet)*/
|
||||
e->type = VEH_Train;
|
||||
if (counter >= ROAD_ENGINES_INDEX) {
|
||||
e->type = VEH_Road;
|
||||
if (counter >= SHIP_ENGINES_INDEX) {
|
||||
e->type = VEH_Ship;
|
||||
if (counter >= AIRCRAFT_ENGINES_INDEX) {
|
||||
e->type = VEH_Aircraft;
|
||||
if (counter >= TOTAL_NUM_ENGINES) {
|
||||
e->type = VEH_Special;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AdjustAvailAircraft();
|
||||
|
|
1
gui.h
1
gui.h
|
@ -85,6 +85,7 @@ void CheckRedrawStationCoverage(Window *w);
|
|||
void ShowSmallMap();
|
||||
void ShowExtraViewPortWindow();
|
||||
void SetVScrollCount(Window *w, int num);
|
||||
void SetVScroll2Count(Window *w, int num);
|
||||
void SetHScrollCount(Window *w, int num);
|
||||
int HandleEditBoxKey(Window *w, int wid, WindowEvent *we);
|
||||
|
||||
|
|
|
@ -2763,3 +2763,25 @@ STR_SCHEDULED_TRAINS_TIP :{BLACK}Show all trains which have this station on
|
|||
STR_SCHEDULED_ROAD_VEHICLES_TIP :{BLACK}Show all road vehicles which have this station on their schedule
|
||||
STR_SCHEDULED_AIRCRAFT_TIP :{BLACK}Show all aircraft which have this station on their schedule
|
||||
STR_SCHEDULED_SHIPS_TIP :{BLACK}Show all ships which have this station on their schedule
|
||||
|
||||
STR_REPLACE_VEHICLES :{BLACK}Replace Vehicles
|
||||
STR_REPLACE_VEHICLES_START :{BLACK}Start Replacing Vehicles
|
||||
STR_REPLACE_VEHICLES_STOP :{BLACK}Stop Replaing Vehicles
|
||||
STR_NOT_REPLACING :{BLACK}Not replacing
|
||||
STR_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}No vehicle selected
|
||||
STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Select a type of engine to replace{}Select an engine on the right side to replace to
|
||||
STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Select an engine to replace to{}It will replace the engines selected on the left side
|
||||
STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Press this button if you don't want to replace the engine, you selected on the left
|
||||
STR_REPLACE_HELP_START_BUTTON :{BLACK}Press this button if you want to replace the engine selected on the left with the one selected on the right
|
||||
STR_REPLACE_HELP_RAILTYPE :{BLACK}Select a railtype you want to select engines for
|
||||
STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}This displays what engine the selected engine on the left are being replaced to
|
||||
STR_REPLACE_HELP :{BLACK}This feature allows you to select an enginetype and replace that one with another one. This will then be done automatically when the vehicles enters a depot anyway
|
||||
|
||||
############ Lists rail types
|
||||
|
||||
STR_RAIL_VEHICLES :{BLACK}Rail Vehicles
|
||||
STR_MONORAIL_VEHICLES :{BLACK}Monorail Vehicles
|
||||
STR_MAGLEV_VEHICLES :{BLACK}Maglev Vehicles
|
||||
|
||||
############ End of list of rail types
|
||||
|
||||
|
|
8
misc.c
8
misc.c
|
@ -9,6 +9,7 @@
|
|||
#include "network.h"
|
||||
#include "network_data.h"
|
||||
#include "network_server.h"
|
||||
#include "engine.h"
|
||||
|
||||
extern void StartupEconomy();
|
||||
extern void InitNewsItemStructs();
|
||||
|
@ -182,6 +183,13 @@ void ConvertGroundTilesIntoWaterTiles();
|
|||
|
||||
void InitializeGame()
|
||||
{
|
||||
// Initialize the autoreplace array. Needs to be cleared between each game
|
||||
int i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
_autoreplace_array[i] = i;
|
||||
}
|
||||
AddTypeToEngines(); // make sure all engines have a type
|
||||
|
||||
SetObjectToPlace(1, 0, 0, 0);
|
||||
|
||||
_pause = 0;
|
||||
|
|
|
@ -692,6 +692,14 @@ void SetVScrollCount(Window *w, int num)
|
|||
if (num < w->vscroll.pos) w->vscroll.pos = num;
|
||||
}
|
||||
|
||||
void SetVScroll2Count(Window *w, int num)
|
||||
{
|
||||
w->vscroll2.count = num;
|
||||
num -= w->vscroll2.cap;
|
||||
if (num < 0) num = 0;
|
||||
if (num < w->vscroll2.pos) w->vscroll2.pos = num;
|
||||
}
|
||||
|
||||
void SetHScrollCount(Window *w, int num)
|
||||
{
|
||||
w->hscroll.count = num;
|
||||
|
@ -700,7 +708,6 @@ void SetHScrollCount(Window *w, int num)
|
|||
if (num < w->hscroll.pos) w->hscroll.pos = num;
|
||||
}
|
||||
|
||||
|
||||
int HandleEditBoxKey(Window *w, int wid, WindowEvent *we)
|
||||
{
|
||||
byte *p;
|
||||
|
|
|
@ -231,7 +231,7 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
|
|||
DeleteWindowById(WC_NETWORK_WINDOW, 0);
|
||||
break;
|
||||
case 4: case 5:
|
||||
ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, 5, 0); // do it for widget 5
|
||||
ShowDropDownMenu(w, _lan_internet_types_dropdown, _network_lan_internet, 5, 0, 0); // do it for widget 5
|
||||
break;
|
||||
case 10: { /* Matrix to show networkgames */
|
||||
uint32 id_v = (e->click.pt.y - NET_PRC__OFFSET_TOP_WIDGET) / NET_PRC__SIZE_OF_ROW;
|
||||
|
@ -540,13 +540,13 @@ static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
|
|||
SetWindowDirty(w);
|
||||
} break;
|
||||
case 7: case 8: /* Connection type */
|
||||
ShowDropDownMenu(w, _connection_types_dropdown, _network_advertise, 8, 0); // do it for widget 8
|
||||
ShowDropDownMenu(w, _connection_types_dropdown, _network_advertise, 8, 0, 0); // do it for widget 8
|
||||
break;
|
||||
case 9: case 10: /* Number of Players */
|
||||
ShowDropDownMenu(w, _players_dropdown, _network_game_info.clients_max - 2, 10, 0); // do it for widget 10
|
||||
ShowDropDownMenu(w, _players_dropdown, _network_game_info.clients_max - 2, 10, 0, 0); // do it for widget 10
|
||||
return;
|
||||
case 11: case 12: /* Language */
|
||||
ShowDropDownMenu(w, _language_dropdown, _network_game_info.server_lang, 12, 0); // do it for widget 12
|
||||
ShowDropDownMenu(w, _language_dropdown, _network_game_info.server_lang, 12, 0, 0); // do it for widget 12
|
||||
return;
|
||||
case 13: /* Start game */
|
||||
_is_network_server = true;
|
||||
|
|
|
@ -105,6 +105,8 @@ int32 EstimateRoadVehCost(byte engine_type)
|
|||
return ((_price.roadveh_base >> 3) * RoadVehInfo(engine_type)->base_cost) >> 5;
|
||||
}
|
||||
|
||||
// p1 = engine_type
|
||||
// p2 not used
|
||||
int32 CmdBuildRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
int32 cost;
|
||||
|
@ -211,6 +213,8 @@ int32 CmdStartStopRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// p1 = vehicle index in &_vehicles[]
|
||||
// p2 not used
|
||||
int32 CmdSellRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
Vehicle *v;
|
||||
|
@ -1379,7 +1383,7 @@ void RoadVehEnterDepot(Vehicle *v)
|
|||
|
||||
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
||||
|
||||
MaybeRenewVehicle(v);
|
||||
MaybeReplaceVehicle(v);
|
||||
|
||||
VehicleServiceInDepot(v);
|
||||
|
||||
|
|
|
@ -12,6 +12,25 @@
|
|||
#include "player.h"
|
||||
#include "engine.h"
|
||||
|
||||
void Set_DPARAM_Road_Veh_Build_Window(uint16 engine_number)
|
||||
{
|
||||
const RoadVehicleInfo *rvi = RoadVehInfo(engine_number);
|
||||
Engine *e;
|
||||
YearMonthDay ymd;
|
||||
|
||||
SetDParam(0, rvi->base_cost * (_price.roadveh_base>>3)>>5);
|
||||
SetDParam(1, rvi->max_speed * 10 >> 5);
|
||||
SetDParam(2, rvi->running_cost * _price.roadveh_running >> 8);
|
||||
SetDParam(4, rvi->capacity);
|
||||
SetDParam(3, _cargoc.names_long_p[rvi->cargo_type]);
|
||||
|
||||
e = &_engines[engine_number];
|
||||
SetDParam(6, e->lifelength);
|
||||
SetDParam(7, e->reliability * 100 >> 16);
|
||||
ConvertDayToYMD(&ymd, e->intro_date);
|
||||
SetDParam(5, ymd.year + 1920);
|
||||
}
|
||||
|
||||
static void DrawRoadVehImage(Vehicle *v, int x, int y, VehicleID selection)
|
||||
{
|
||||
int image = GetRoadVehImage(v, 6);
|
||||
|
@ -307,8 +326,6 @@ void ShowRoadVehViewWindow(Vehicle *v)
|
|||
|
||||
static void DrawNewRoadVehWindow(Window *w)
|
||||
{
|
||||
YearMonthDay ymd;
|
||||
|
||||
if (w->window_number == 0)
|
||||
w->disabled_state = 1 << 5;
|
||||
|
||||
|
@ -350,20 +367,7 @@ static void DrawNewRoadVehWindow(Window *w)
|
|||
|
||||
WP(w,buildtrain_d).sel_engine = selected_id;
|
||||
if (selected_id != -1) {
|
||||
const RoadVehicleInfo *rvi = RoadVehInfo(selected_id);
|
||||
Engine *e;
|
||||
|
||||
SetDParam(0, rvi->base_cost * (_price.roadveh_base>>3)>>5);
|
||||
SetDParam(1, rvi->max_speed * 10 >> 5);
|
||||
SetDParam(2, rvi->running_cost * _price.roadveh_running >> 8);
|
||||
SetDParam(4, rvi->capacity);
|
||||
SetDParam(3, _cargoc.names_long_p[rvi->cargo_type]);
|
||||
|
||||
e = &_engines[selected_id];
|
||||
SetDParam(6, e->lifelength);
|
||||
SetDParam(7, e->reliability * 100 >> 16);
|
||||
ConvertDayToYMD(&ymd, e->intro_date);
|
||||
SetDParam(5, ymd.year + 1920);
|
||||
Set_DPARAM_Road_Veh_Build_Window(selected_id);
|
||||
|
||||
DrawString(2, 127, STR_9008_COST_SPEED_RUNNING_COST, 0);
|
||||
}
|
||||
|
@ -714,7 +718,7 @@ static Widget _player_roadveh_widgets[] = {
|
|||
{ WWT_SCROLLBAR, 14, 249, 259, 26, 207, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
/* only for our road list, a 'Build Vehicle' button that opens the depot of the last built depot */
|
||||
{ WWT_PUSHTXTBTN, 14, 0, 129, 208, 219, STR_8815_NEW_VEHICLES, STR_901B_BUILD_NEW_ROAD_VEHICLES},
|
||||
{ WWT_PANEL, 14, 130, 259, 208, 219, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 14, 130, 259, 208, 219, STR_REPLACE_VEHICLES, STR_REPLACE_HELP},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
|
@ -818,7 +822,7 @@ static void PlayerRoadVehWndProc(Window *w, WindowEvent *e)
|
|||
break;
|
||||
|
||||
case 4: case 5:/* Select sorting criteria dropdown menu */
|
||||
ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0);
|
||||
ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0, 0);
|
||||
return;
|
||||
case 7: { /* Matrix to show vehicles */
|
||||
uint32 id_v = (e->click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / PLY_WND_PRC__SIZE_OF_ROW_SMALL;
|
||||
|
@ -856,6 +860,10 @@ static void PlayerRoadVehWndProc(Window *w, WindowEvent *e)
|
|||
|
||||
ShowBuildRoadVehWindow(0);
|
||||
} break;
|
||||
case 10: {
|
||||
ShowReplaceVehicleWindow(VEH_Road);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
|
|
|
@ -92,35 +92,35 @@ static void GameOptionsWndProc(Window *w, WindowEvent *e)
|
|||
case WE_CLICK:
|
||||
switch(e->click.widget) {
|
||||
case 5:
|
||||
ShowDropDownMenu(w, _currency_string_list, _opt_mod_ptr->currency, e->click.widget, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies());
|
||||
ShowDropDownMenu(w, _currency_string_list, _opt_mod_ptr->currency, e->click.widget, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0);
|
||||
return;
|
||||
case 8:
|
||||
ShowDropDownMenu(w, _distances_dropdown, _opt_mod_ptr->kilometers, e->click.widget, 0);
|
||||
ShowDropDownMenu(w, _distances_dropdown, _opt_mod_ptr->kilometers, e->click.widget, 0, 0);
|
||||
return;
|
||||
case 11: {
|
||||
int i = _opt_mod_ptr->road_side;
|
||||
ShowDropDownMenu(w, _driveside_dropdown, i, e->click.widget, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << i));
|
||||
ShowDropDownMenu(w, _driveside_dropdown, i, e->click.widget, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << i), 0);
|
||||
return;
|
||||
}
|
||||
case 14: {
|
||||
int i = _opt_mod_ptr->town_name;
|
||||
ShowDropDownMenu(w, BuildDynamicDropdown(STR_TOWNNAME_ORIGINAL_ENGLISH, SPECSTR_TOWNNAME_LAST - SPECSTR_TOWNNAME_START + 1), i, e->click.widget, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << i));
|
||||
ShowDropDownMenu(w, BuildDynamicDropdown(STR_TOWNNAME_ORIGINAL_ENGLISH, SPECSTR_TOWNNAME_LAST - SPECSTR_TOWNNAME_START + 1), i, e->click.widget, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << i), 0);
|
||||
return;
|
||||
}
|
||||
case 17:
|
||||
ShowDropDownMenu(w, _autosave_dropdown, _opt_mod_ptr->autosave, e->click.widget, 0);
|
||||
ShowDropDownMenu(w, _autosave_dropdown, _opt_mod_ptr->autosave, e->click.widget, 0, 0);
|
||||
return;
|
||||
case 20:
|
||||
ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names&1)?1:0, e->click.widget, (_vehicle_design_names&2)?0:2);
|
||||
ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names&1)?1:0, e->click.widget, (_vehicle_design_names&2)?0:2, 0);
|
||||
return;
|
||||
case 21:
|
||||
return;
|
||||
case 24:
|
||||
ShowDropDownMenu(w, _dynlang.dropdown, _dynlang.curr, e->click.widget, 0);
|
||||
ShowDropDownMenu(w, _dynlang.dropdown, _dynlang.curr, e->click.widget, 0, 0);
|
||||
return;
|
||||
case 27:
|
||||
// setup resolution dropdown
|
||||
ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), e->click.widget, 0);
|
||||
ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), e->click.widget, 0, 0);
|
||||
return;
|
||||
case 28: /* Click fullscreen on/off */
|
||||
(_fullscreen) ? CLRBIT(w->click_state, 28) : SETBIT(w->click_state, 28);
|
||||
|
@ -128,7 +128,7 @@ static void GameOptionsWndProc(Window *w, WindowEvent *e)
|
|||
SetWindowDirty(w);
|
||||
return;
|
||||
case 31: /* Setup screenshot format dropdown */
|
||||
ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, e->click.widget, 0);
|
||||
ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, e->click.widget, 0, 0);
|
||||
return;
|
||||
|
||||
}
|
||||
|
|
24
ship_cmd.c
24
ship_cmd.c
|
@ -400,7 +400,7 @@ static void ShipEnterDepot(Vehicle *v)
|
|||
|
||||
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
||||
|
||||
MaybeRenewVehicle(v);
|
||||
MaybeReplaceVehicle(v);
|
||||
|
||||
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
||||
|
||||
|
@ -975,30 +975,38 @@ int32 CmdChangeShipServiceInt(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
|
||||
// p1 = vehicle
|
||||
// p2 = new cargo
|
||||
// p2 = new cargo (0xFF)
|
||||
// p2 = skip check for stopped in hanger (0x0100)
|
||||
int32 CmdRefitShip(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
Vehicle *v;
|
||||
int32 cost;
|
||||
byte SkipStoppedInDepotCheck = (p2 & 0x100) >> 8; //excludes the cargo value
|
||||
|
||||
p2 = p2 & 0xFF;
|
||||
SET_EXPENSES_TYPE(EXPENSES_SHIP_RUN);
|
||||
|
||||
v = &_vehicles[p1];
|
||||
if (!CheckOwnership(v->owner))
|
||||
return CMD_ERROR;
|
||||
|
||||
if (!IsShipDepotTile(v->tile) ||
|
||||
!(v->vehstatus&VS_STOPPED) ||
|
||||
v->u.ship.state != 0x80)
|
||||
return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN);
|
||||
|
||||
if (!( SkipStoppedInDepotCheck )) {
|
||||
if (!IsShipDepotTile(v->tile) ||
|
||||
!(v->vehstatus&VS_STOPPED) ||
|
||||
v->u.ship.state != 0x80)
|
||||
return_cmd_error(STR_980B_SHIP_MUST_BE_STOPPED_IN);
|
||||
}
|
||||
|
||||
cost = 0;
|
||||
if (IS_HUMAN_PLAYER(v->owner) && (byte)p2 != v->cargo_type) {
|
||||
cost = _price.ship_base >> 7;
|
||||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
v->cargo_count = 0;
|
||||
//autorefitted ships wants to keep the cargo
|
||||
//it will be checked if the cargo is valid in CmdRenewVehicle
|
||||
if (!(SkipStoppedInDepotCheck))
|
||||
v->cargo_count = 0;
|
||||
v->cargo_type = (byte)p2;
|
||||
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
||||
}
|
||||
|
|
45
ship_gui.c
45
ship_gui.c
|
@ -12,6 +12,25 @@
|
|||
#include "player.h"
|
||||
#include "engine.h"
|
||||
|
||||
void Set_DPARAM_Ship_Build_Window(uint16 engine_number)
|
||||
{
|
||||
YearMonthDay ymd;
|
||||
const ShipVehicleInfo *svi = ShipVehInfo(engine_number);
|
||||
Engine *e;
|
||||
|
||||
SetDParam(0, svi->base_cost * (_price.ship_base>>3)>>5);
|
||||
SetDParam(1, svi->max_speed * 10 >> 5);
|
||||
SetDParam(2, _cargoc.names_long_p[svi->cargo_type]);
|
||||
SetDParam(3, svi->capacity);
|
||||
SetDParam(4, svi->refittable ? STR_9842_REFITTABLE : STR_EMPTY);
|
||||
SetDParam(5, svi->running_cost * _price.ship_running >> 8);
|
||||
|
||||
e = &_engines[engine_number];
|
||||
SetDParam(7, e->lifelength);
|
||||
SetDParam(8, e->reliability * 100 >> 16);
|
||||
ConvertDayToYMD(&ymd, e->intro_date);
|
||||
SetDParam(6, ymd.year + 1920);
|
||||
}
|
||||
|
||||
static void DrawShipImage(Vehicle *v, int x, int y, VehicleID selection);
|
||||
|
||||
|
@ -317,7 +336,6 @@ void CcBuildShip(bool success, uint tile, uint32 p1, uint32 p2)
|
|||
|
||||
static void NewShipWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
YearMonthDay ymd;
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
if (w->window_number == 0)
|
||||
|
@ -362,21 +380,7 @@ static void NewShipWndProc(Window *w, WindowEvent *e)
|
|||
WP(w,buildtrain_d).sel_engine = selected_id;
|
||||
|
||||
if (selected_id != -1) {
|
||||
const ShipVehicleInfo *svi = ShipVehInfo(selected_id);
|
||||
Engine *e;
|
||||
|
||||
SetDParam(0, svi->base_cost * (_price.ship_base>>3)>>5);
|
||||
SetDParam(1, svi->max_speed * 10 >> 5);
|
||||
SetDParam(2, _cargoc.names_long_p[svi->cargo_type]);
|
||||
SetDParam(3, svi->capacity);
|
||||
SetDParam(4, svi->refittable ? STR_9842_REFITTABLE : STR_EMPTY);
|
||||
SetDParam(5, svi->running_cost * _price.ship_running >> 8);
|
||||
|
||||
e = &_engines[selected_id];
|
||||
SetDParam(7, e->lifelength);
|
||||
SetDParam(8, e->reliability * 100 >> 16);
|
||||
ConvertDayToYMD(&ymd, e->intro_date);
|
||||
SetDParam(6, ymd.year + 1920);
|
||||
Set_DPARAM_Ship_Build_Window(selected_id);
|
||||
|
||||
DrawString(2, 111, STR_980A_COST_SPEED_CAPACITY_RUNNING, 0);
|
||||
}
|
||||
|
@ -881,7 +885,7 @@ static Widget _player_ships_widgets[] = {
|
|||
{ WWT_MATRIX, 14, 0, 248, 26, 169, 0x401, STR_9823_SHIPS_CLICK_ON_SHIP_FOR},
|
||||
{ WWT_SCROLLBAR, 14, 249, 259, 26, 169, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_PUSHTXTBTN, 14, 0, 129, 170, 181, STR_9804_NEW_SHIPS, STR_9824_BUILD_NEW_SHIPS_REQUIRES},
|
||||
{ WWT_PANEL, 14, 130, 259, 170, 181, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 14, 130, 259, 170, 181, STR_REPLACE_VEHICLES, STR_REPLACE_HELP},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
|
@ -986,7 +990,7 @@ static void PlayerShipsWndProc(Window *w, WindowEvent *e)
|
|||
SetWindowDirty(w);
|
||||
break;
|
||||
case 4: case 5:/* Select sorting criteria dropdown menu */
|
||||
ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0);
|
||||
ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0, 0);
|
||||
return;
|
||||
case 7: { /* Matrix to show vehicles */
|
||||
uint32 id_v = (e->click.pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / PLY_WND_PRC__SIZE_OF_ROW_BIG;
|
||||
|
@ -1024,7 +1028,12 @@ static void PlayerShipsWndProc(Window *w, WindowEvent *e)
|
|||
|
||||
ShowBuildShipWindow(0);
|
||||
} break;
|
||||
|
||||
case 10: {
|
||||
ShowReplaceVehicleWindow(VEH_Ship);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
|
||||
|
|
24
train_cmd.c
24
train_cmd.c
|
@ -1057,23 +1057,27 @@ int32 CmdForceTrainProceed(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||
}
|
||||
|
||||
// p1 = vehicle to refit
|
||||
// p2 = new cargo
|
||||
|
||||
// p2 = new cargo (0xFF)
|
||||
// p2 = skip check for stopped in hanger (0x0100)
|
||||
int32 CmdRefitRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
Vehicle *v;
|
||||
int32 cost;
|
||||
uint num;
|
||||
|
||||
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
|
||||
byte SkipStoppedInDepotCheck = (p2 & 0x100) >> 8;
|
||||
|
||||
p2 = p2 & 0xFF;
|
||||
|
||||
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
|
||||
|
||||
v = &_vehicles[p1];
|
||||
if (!CheckOwnership(v->owner) || CheckStoppedInDepot(v) < 0)
|
||||
if (!CheckOwnership(v->owner) || ((CheckStoppedInDepot(v) < 0) && !(SkipStoppedInDepotCheck)))
|
||||
return CMD_ERROR;
|
||||
|
||||
cost = 0;
|
||||
num = 0;
|
||||
|
||||
|
||||
do {
|
||||
/* XXX: We also refit all the attached wagons en-masse if they
|
||||
* can be refitted. This is how TTDPatch does it. TODO: Have
|
||||
|
@ -1084,12 +1088,16 @@ int32 CmdRefitRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||
cost += (_price.build_railvehicle >> 8);
|
||||
num += v->cargo_cap;
|
||||
if (flags & DC_EXEC) {
|
||||
v->cargo_count = 0;
|
||||
//autorefitted train cars wants to keep the cargo
|
||||
//it will be checked if the cargo is valid in CmdReplaceVehicle
|
||||
if (!(SkipStoppedInDepotCheck))
|
||||
v->cargo_count = 0;
|
||||
v->cargo_type = (byte)p2;
|
||||
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
||||
}
|
||||
}
|
||||
} while ( (v=v->next) != NULL);
|
||||
// SkipStoppedInDepotCheck is called by CmdReplace and it should only apply to the single car it is called for
|
||||
} while ( (v=v->next) != NULL || SkipStoppedInDepotCheck );
|
||||
|
||||
_returned_refit_amount = num;
|
||||
|
||||
|
@ -2618,7 +2626,7 @@ void TrainEnterDepot(Vehicle *v, uint tile)
|
|||
v->load_unload_time_rem = 0;
|
||||
v->cur_speed = 0;
|
||||
|
||||
MaybeRenewVehicle(v);
|
||||
MaybeReplaceVehicle(v);
|
||||
|
||||
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
||||
|
||||
|
|
80
train_gui.c
80
train_gui.c
|
@ -16,6 +16,44 @@
|
|||
|
||||
int _traininfo_vehicle_pitch = 0;
|
||||
|
||||
void Set_DPARAM_Train_Engine_Build_Window(uint16 engine_number)
|
||||
{
|
||||
const RailVehicleInfo *rvi = RailVehInfo(engine_number);
|
||||
Engine *e;
|
||||
int multihead = (rvi->flags&RVI_MULTIHEAD?1:0);
|
||||
YearMonthDay ymd;
|
||||
|
||||
|
||||
SetDParam(0, rvi->base_cost * (_price.build_railvehicle >> 3) >> 5);
|
||||
SetDParam(2, rvi->max_speed * 10 >> 4);
|
||||
SetDParam(3, rvi->power << multihead);
|
||||
SetDParam(1, rvi->weight << multihead);
|
||||
SetDParam(4, (rvi->running_cost_base * _price.running_rail[rvi->engclass] >> 8) << multihead);
|
||||
|
||||
SetDParam(5, STR_8838_N_A);
|
||||
if (rvi->capacity != 0) {
|
||||
SetDParam(6, rvi->capacity << multihead);
|
||||
SetDParam(5, _cargoc.names_long_p[rvi->cargo_type]);
|
||||
}
|
||||
|
||||
e = &_engines[engine_number];
|
||||
|
||||
SetDParam(8, e->lifelength);
|
||||
SetDParam(9, e->reliability * 100 >> 16);
|
||||
ConvertDayToYMD(&ymd, e->intro_date);
|
||||
SetDParam(7, ymd.year + 1920);
|
||||
}
|
||||
|
||||
void Set_DPARAM_Train_Car_Build_Window(Window *w, uint16 engine_number)
|
||||
{
|
||||
const RailVehicleInfo *rvi = RailVehInfo(engine_number);
|
||||
|
||||
SetDParam(0, DoCommandByTile(w->window_number, engine_number, 0, DC_QUERY_COST, CMD_BUILD_RAIL_VEHICLE) );
|
||||
SetDParam(4, rvi->capacity);
|
||||
SetDParam(1, rvi->weight);
|
||||
SetDParam(3, _cargoc.names_long_p[rvi->cargo_type]);
|
||||
SetDParam(2, (_cargoc.weights[rvi->cargo_type] * rvi->capacity >> 4) + rvi->weight);
|
||||
}
|
||||
|
||||
void CcBuildWagon(bool success, uint tile, uint32 p1, uint32 p2)
|
||||
{
|
||||
|
@ -131,43 +169,16 @@ static void NewRailVehicleWndProc(Window *w, WindowEvent *e)
|
|||
|
||||
if (selected_id != -1) {
|
||||
const RailVehicleInfo *rvi = RailVehInfo(selected_id);
|
||||
Engine *e;
|
||||
YearMonthDay ymd;
|
||||
|
||||
if (!(rvi->flags & RVI_WAGON)) {
|
||||
/* it's an engine */
|
||||
int multihead = (rvi->flags&RVI_MULTIHEAD?1:0);
|
||||
|
||||
SetDParam(0, rvi->base_cost * (_price.build_railvehicle >> 3) >> 5);
|
||||
SetDParam(2, rvi->max_speed * 10 >> 4);
|
||||
SetDParam(3, rvi->power << multihead);
|
||||
SetDParam(1, rvi->weight << multihead);
|
||||
SetDParam(4, (rvi->running_cost_base * _price.running_rail[rvi->engclass] >> 8) << multihead);
|
||||
|
||||
SetDParam(5, STR_8838_N_A);
|
||||
if (rvi->capacity != 0) {
|
||||
SetDParam(6, rvi->capacity << multihead);
|
||||
SetDParam(5, _cargoc.names_long_p[rvi->cargo_type]);
|
||||
}
|
||||
|
||||
e = &_engines[selected_id];
|
||||
|
||||
SetDParam(8, e->lifelength);
|
||||
SetDParam(9, e->reliability * 100 >> 16);
|
||||
ConvertDayToYMD(&ymd, e->intro_date);
|
||||
SetDParam(7, ymd.year + 1920);
|
||||
Set_DPARAM_Train_Engine_Build_Window(selected_id);
|
||||
|
||||
DrawString(2, 0x7F, STR_8817_COST_WEIGHT_T_SPEED_POWER, 0);
|
||||
} else {
|
||||
/* it's a wagon */
|
||||
|
||||
SetDParam(0,
|
||||
DoCommandByTile(w->window_number, selected_id, 0, DC_QUERY_COST, CMD_BUILD_RAIL_VEHICLE)
|
||||
);
|
||||
SetDParam(4, rvi->capacity);
|
||||
SetDParam(1, rvi->weight);
|
||||
SetDParam(3, _cargoc.names_long_p[rvi->cargo_type]);
|
||||
SetDParam(2, (_cargoc.weights[rvi->cargo_type] * rvi->capacity >> 4) + rvi->weight);
|
||||
Set_DPARAM_Train_Car_Build_Window(w, selected_id);
|
||||
|
||||
DrawString(2, 0x7F, STR_8821_COST_WEIGHT_T_T_CAPACITY, 0);
|
||||
}
|
||||
}
|
||||
|
@ -1183,7 +1194,7 @@ static Widget _player_trains_widgets[] = {
|
|||
{ WWT_MATRIX, 14, 0, 313, 26, 207, 0x701, STR_883D_TRAINS_CLICK_ON_TRAIN_FOR},
|
||||
{ WWT_SCROLLBAR, 14, 314, 324, 26, 207, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_PUSHTXTBTN, 14, 0, 161, 208, 219, STR_8815_NEW_VEHICLES, STR_883E_BUILD_NEW_TRAINS_REQUIRES},
|
||||
{ WWT_PANEL, 14, 162, 324, 208, 219, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 14, 162, 324, 208, 219, STR_REPLACE_VEHICLES, STR_REPLACE_HELP},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
|
@ -1289,7 +1300,7 @@ static void PlayerTrainsWndProc(Window *w, WindowEvent *e)
|
|||
break;
|
||||
|
||||
case 4: case 5:/* Select sorting criteria dropdown menu */
|
||||
ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0);
|
||||
ShowDropDownMenu(w, _vehicle_sort_listing, vl->sort_type, 5, 0, 0);
|
||||
return;
|
||||
|
||||
case 7: { /* Matrix to show vehicles */
|
||||
|
@ -1328,6 +1339,11 @@ static void PlayerTrainsWndProc(Window *w, WindowEvent *e)
|
|||
|
||||
ShowBuildTrainWindow(0);
|
||||
} break;
|
||||
case 10: {
|
||||
ShowReplaceVehicleWindow(VEH_Train);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
} break;
|
||||
|
||||
|
|
1
ttd.h
1
ttd.h
|
@ -439,6 +439,7 @@ enum {
|
|||
WC_CLIENT_LIST = 0x49,
|
||||
WC_NETWORK_STATUS_WINDOW = 0x4A,
|
||||
WC_CUSTOM_CURRENCY = 0x4B,
|
||||
WC_REPLACE_VEHICLE = 0x4C,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -431,6 +431,9 @@ VARDEF SignStruct *_new_sign_struct;
|
|||
/* tunnelbridge */
|
||||
#define MAX_BRIDGES 13
|
||||
|
||||
/* Autoreplace vehicle stuff*/
|
||||
VARDEF byte _autoreplace_array[255];
|
||||
|
||||
/* Debugging levels */
|
||||
VARDEF int _debug_spritecache_level;
|
||||
VARDEF int _debug_misc_level;
|
||||
|
|
178
vehicle.c
178
vehicle.c
|
@ -4,7 +4,6 @@
|
|||
#include "map.h"
|
||||
#include "vehicle.h"
|
||||
#include "gfx.h"
|
||||
//#include "station.h"
|
||||
#include "viewport.h"
|
||||
#include "news.h"
|
||||
#include "command.h"
|
||||
|
@ -1394,35 +1393,45 @@ extern int32 EstimateTrainCost(const RailVehicleInfo *rvi);
|
|||
extern int32 EstimateRoadVehCost(byte engine_type);
|
||||
extern int32 EstimateShipCost(uint16 engine_type);
|
||||
extern int32 EstimateAircraftCost(uint16 engine_type);
|
||||
extern int32 CmdRefitRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2);
|
||||
extern int32 CmdRefitShip(int x, int y, uint32 flags, uint32 p1, uint32 p2);
|
||||
extern int32 CmdRefitAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2);
|
||||
|
||||
/* Renews a vehicle
|
||||
/* Replaces a vehicle (used to be called autorenew)
|
||||
p1 - Index of vehicle
|
||||
p2 - Type of new engine */
|
||||
int32 CmdRenewVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
int32 CmdReplaceVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
byte new_engine_type = p2;
|
||||
/* makesvariables to inform about how much money the player wants to have left after replacing
|
||||
and which engine to replace with out of p2.
|
||||
the first 16 bit is the money. The last 5 digits (all 0) were removed when sent, so we add them again.
|
||||
This way the max is 6553 millions and it is more than the 32 bit that is stored in _patches
|
||||
This is a nice way to send 32 bit and only use 16 bit
|
||||
the last 8 bit is the engine. The 8 bits in front of the engine is free so it have room for 16 bit engine entries */
|
||||
uint16 new_engine_type = (uint16)(p2 & 0xFFFF);
|
||||
uint32 autorefit_money = (p2 >> 16) * 100000;
|
||||
Vehicle *v = DEREF_VEHICLE(p1);
|
||||
int cost, build_cost;
|
||||
|
||||
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
|
||||
|
||||
if (v->type != _engines[new_engine_type].type) return CMD_ERROR;
|
||||
|
||||
switch (v->type) {
|
||||
case VEH_Train: build_cost = EstimateTrainCost(RailVehInfo(v->engine_type)); break;
|
||||
case VEH_Road: build_cost = EstimateRoadVehCost(new_engine_type); break;
|
||||
case VEH_Ship: build_cost = EstimateShipCost(v->engine_type); break;
|
||||
case VEH_Aircraft: build_cost = EstimateAircraftCost(new_engine_type); break;
|
||||
case VEH_Train: build_cost = EstimateTrainCost(RailVehInfo(new_engine_type)); break;
|
||||
case VEH_Road: build_cost = EstimateRoadVehCost(new_engine_type); break;
|
||||
case VEH_Ship: build_cost = EstimateShipCost(new_engine_type); break;
|
||||
case VEH_Aircraft: build_cost = EstimateAircraftCost(new_engine_type); break;
|
||||
default: return CMD_ERROR;
|
||||
}
|
||||
|
||||
/* In a rare situation, when 2 clients are connected to 1 company and have the same
|
||||
settings, a vehicle can be replaced twice.. check if this is the situation here */
|
||||
if (v->age == 0)
|
||||
if (v->engine_type == new_engine_type && v->age == 0)
|
||||
return CMD_ERROR;
|
||||
|
||||
/* Check if there is money for the upgrade.. if not, give a nice news-item
|
||||
(that is needed, because this CMD is called automaticly) */
|
||||
if (DEREF_PLAYER(v->owner)->money64 < _patches.autorenew_money + build_cost - v->value) {
|
||||
if (_local_player == v->owner) {
|
||||
if ( DEREF_PLAYER(v->owner)->money64 < (int32)(autorefit_money + build_cost - v->value)) {
|
||||
if (( _local_player == v->owner ) && ( v->unitnumber != 0 )) { //v->unitnumber = 0 for train cars
|
||||
int message;
|
||||
SetDParam(0, v->unitnumber);
|
||||
switch (v->type) {
|
||||
|
@ -1439,21 +1448,106 @@ int32 CmdRenewVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
cost = build_cost - v->value;
|
||||
|
||||
if (flags & DC_QUERY_COST)
|
||||
return cost;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
Engine *e;
|
||||
e = &_engines[new_engine_type];
|
||||
|
||||
// TODO make it check if refit is possible before actually doing it
|
||||
|
||||
/* We do not really buy a new vehicle, we upgrade the old one */
|
||||
if (v->engine_type != new_engine_type) {
|
||||
/* XXX - We need to do some more stuff here, when we are going to upgrade
|
||||
to a new engine! */
|
||||
byte cargo_type = v->cargo_type;
|
||||
v->engine_type = new_engine_type;
|
||||
v->max_age = e->lifelength * 366;
|
||||
|
||||
/* Update limits of the vehicle (for when upgraded) */
|
||||
switch (v->type) {
|
||||
case VEH_Train:
|
||||
// using if (true) to declare the const
|
||||
{
|
||||
const RailVehicleInfo *rvi = RailVehInfo(new_engine_type);
|
||||
byte capacity = rvi->capacity;
|
||||
|
||||
v->spritenum = rvi->image_index;
|
||||
v->cargo_type = rvi->cargo_type;
|
||||
v->cargo_cap = rvi->capacity;
|
||||
v->max_speed = rvi->max_speed;
|
||||
|
||||
v->u.rail.railtype = e->railtype;
|
||||
|
||||
// 0x0100 means that we skip the check for being stopped inside the depot
|
||||
// since we do not stop it for autorefitting
|
||||
if (v->cargo_type != cargo_type && capacity) {
|
||||
// BUG: somehow v->index is not transfered properly
|
||||
//CmdRefitRailVehicle(v->x_pos, v->y_pos, DC_EXEC, v->index , cargo_type + 0x0100 );
|
||||
v->cargo_type = cargo_type; // workaround, but it do not check the refit table
|
||||
} else {
|
||||
v->cargo_type = rvi->cargo_type;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VEH_Road:
|
||||
// using if (true) to declare the const
|
||||
if (true) {
|
||||
const RoadVehicleInfo *rvi = RoadVehInfo(new_engine_type);
|
||||
|
||||
v->spritenum = rvi->image_index;
|
||||
v->cargo_type = rvi->cargo_type;
|
||||
v->cargo_cap = rvi->capacity;
|
||||
v->max_speed = rvi->max_speed;
|
||||
break;
|
||||
}
|
||||
case VEH_Ship:
|
||||
// using if (true) to declare the const
|
||||
if (true) {
|
||||
const ShipVehicleInfo *svi = ShipVehInfo(new_engine_type);
|
||||
|
||||
v->spritenum = svi->image_index;
|
||||
v->cargo_type = svi->cargo_type;
|
||||
v->cargo_cap = svi->capacity;
|
||||
v->max_speed = svi->max_speed;
|
||||
|
||||
// 0x0100 means that we skip the check for being stopped inside the depot
|
||||
// since we do not stop it for autorefitting
|
||||
if (v->cargo_type != cargo_type)
|
||||
CmdRefitShip(v->x_pos, v->y_pos, DC_EXEC, v->index , cargo_type + 0x0100 );
|
||||
break;
|
||||
}
|
||||
case VEH_Aircraft:
|
||||
// using if (true) to declare the const
|
||||
if (true) {
|
||||
const AircraftVehicleInfo *avi = AircraftVehInfo(new_engine_type);
|
||||
Vehicle *u;
|
||||
|
||||
v->max_speed = avi->max_speed;
|
||||
v->acceleration = avi->acceleration;
|
||||
v->spritenum = avi->image_index;
|
||||
|
||||
if ( cargo_type == CT_PASSENGERS ) {
|
||||
v->cargo_cap = avi->passanger_capacity;
|
||||
u = v->next;
|
||||
u->cargo_cap = avi->mail_capacity;
|
||||
} else {
|
||||
// 0x0100 means that we skip the check for being stopped inside the hangar
|
||||
// since we do not stop it for autorefitting
|
||||
CmdRefitAircraft(v->x_pos, v->y_pos, DC_EXEC, v->index , cargo_type + 0x0100 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: return CMD_ERROR;
|
||||
}
|
||||
// makes sure that the cargo is still valid compared to new capacity
|
||||
if (v->cargo_count != 0) {
|
||||
if ( v->cargo_type != cargo_type )
|
||||
v->cargo_count = 0;
|
||||
else if ( v->cargo_count > v->cargo_cap )
|
||||
v->cargo_count = v->cargo_cap;
|
||||
}
|
||||
}
|
||||
e = &_engines[new_engine_type];
|
||||
|
||||
v->reliability = e->reliability;
|
||||
v->reliability_spd_dec = e->reliability_spd_dec;
|
||||
v->age = 0;
|
||||
|
@ -1465,26 +1559,58 @@ int32 CmdRenewVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
||||
}
|
||||
//needs to be down here because refitting will change SET_EXPENSES_TYPE if called
|
||||
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
void MaybeRenewVehicle(Vehicle *v)
|
||||
void MaybeReplaceVehicle(Vehicle *v)
|
||||
{
|
||||
uint32 new_engine_and_autoreplace_money;
|
||||
|
||||
if (v->owner != _local_player)
|
||||
return;
|
||||
// uncomment next line if you want to see what engine type just entered a depot
|
||||
//printf("engine type: %d\n", v->engine_type);
|
||||
|
||||
// A vehicle is autorenewed when it it gets the amount of months
|
||||
// give by _patches.autorenew_months away for his max age.
|
||||
// Standard is -6, meaning 6 months before his max age
|
||||
// It can be any value between -12 and 12.
|
||||
if (!_patches.autorenew || v->age - v->max_age < (_patches.autorenew_months * 30))
|
||||
return;
|
||||
|
||||
// Here it also checks if the vehicles is listed for replacement
|
||||
if (!_patches.autorenew || v->age - v->max_age < (_patches.autorenew_months * 30)) { //replace if engine is too old
|
||||
if (_autoreplace_array[v->engine_type] == v->engine_type && v->type != VEH_Train) //updates to a new model
|
||||
return;
|
||||
}
|
||||
/* Now replace the vehicle */
|
||||
_current_player = v->owner;
|
||||
|
||||
/* Now renew the vehicle */
|
||||
DoCommandP(v->tile, v->index, v->engine_type, NULL, CMD_RENEW_VEHICLE);
|
||||
|
||||
/* makes the variable to inform about how much money the player wants to have left after replacing
|
||||
and which engine to replace with
|
||||
the first 16 bit is the money. Since we know the last 5 digits is 0, they are thrown away.
|
||||
This way the max is 6553 millions and it is more than the 32 bit that is stored in _patches
|
||||
This is a nice way to send 32 bit and only use 16 bit
|
||||
the last 8 bit is the engine. The 8 bits in front of the engine is free so it have room for 16 bit engine entries */
|
||||
new_engine_and_autoreplace_money = (((_patches.autorenew_money / 100000) & 0xFFFF) << 16)
|
||||
+ _autoreplace_array[v->engine_type];
|
||||
|
||||
assert(v->type == _engines[ _autoreplace_array[v->engine_type] ].type);
|
||||
|
||||
if ( v->type != VEH_Train ) {
|
||||
DoCommandP(v->tile, v->index, new_engine_and_autoreplace_money, NULL, CMD_REPLACE_VEHICLE | CMD_SHOW_NO_ERROR);
|
||||
} else {
|
||||
// checks if the front engine is outdated
|
||||
if (v->engine_type != _autoreplace_array[v->engine_type] )
|
||||
DoCommandP(v->tile, v->index, new_engine_and_autoreplace_money, NULL, CMD_REPLACE_VEHICLE | CMD_SHOW_NO_ERROR);
|
||||
//we will check all the cars and engines if they should be replaced
|
||||
while (v->next != NULL){
|
||||
v = v->next;
|
||||
if (v->engine_type != _autoreplace_array[v->engine_type] || v->age - v->max_age < (_patches.autorenew_months * 30))
|
||||
DoCommandP(v->tile, v->index, new_engine_and_autoreplace_money , NULL, CMD_REPLACE_VEHICLE | CMD_SHOW_NO_ERROR);
|
||||
}
|
||||
}
|
||||
_current_player = OWNER_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -361,7 +361,7 @@ Vehicle *CheckClickOnVehicle(ViewPort *vp, int x, int y);
|
|||
void DecreaseVehicleValue(Vehicle *v);
|
||||
void CheckVehicleBreakdown(Vehicle *v);
|
||||
void AgeVehicle(Vehicle *v);
|
||||
void MaybeRenewVehicle(Vehicle *v);
|
||||
void MaybeReplaceVehicle(Vehicle *v);
|
||||
|
||||
void DeleteCommandFromVehicleSchedule(Order cmd);
|
||||
|
||||
|
|
644
vehicle_gui.c
644
vehicle_gui.c
|
@ -3,6 +3,10 @@
|
|||
#include "table/strings.h"
|
||||
#include "vehicle.h"
|
||||
#include "window.h"
|
||||
#include "engine.h"
|
||||
#include "gui.h"
|
||||
#include "command.h"
|
||||
#include "gfx.h"
|
||||
|
||||
VehicleSortListingTypeFunctions * const _vehicle_sorter[] = {
|
||||
&VehicleUnsortedSorter,
|
||||
|
@ -29,6 +33,13 @@ const StringID _vehicle_sort_listing[] = {
|
|||
INVALID_STRING_ID
|
||||
};
|
||||
|
||||
const StringID _rail_types_list[] = {
|
||||
STR_RAIL_VEHICLES,
|
||||
STR_MONORAIL_VEHICLES,
|
||||
STR_MAGLEV_VEHICLES,
|
||||
INVALID_STRING_ID
|
||||
};
|
||||
|
||||
void RebuildVehicleLists(void)
|
||||
{
|
||||
Window *w;
|
||||
|
@ -294,3 +305,636 @@ int CDECL VehicleMaxSpeedSorter(const void *a, const void *b)
|
|||
|
||||
return (_internal_sort_order & 1) ? -r : r;
|
||||
}
|
||||
|
||||
// this define is to match engine.c, but engine.c keeps it to itself
|
||||
// ENGINE_AVAILABLE is used in ReplaceVehicleWndProc
|
||||
#define ENGINE_AVAILABLE ((e->flags & 1 && HASBIT(info->railtype_climates, _opt.landscape)) || HASBIT(e->player_avail, _local_player))
|
||||
|
||||
/* if show_outdated is selected, it do not sort psudo engines properly but it draws all engines
|
||||
* if used compined with show_cars set to false, it will work as intended. Replace window do it like that
|
||||
* this was a big hack even before show_outdated was added. Stupid newgrf :p */
|
||||
static void train_engine_drawing_loop(int *x, int *y, int *pos, int *sel, int *selected_id, byte railtype,
|
||||
uint8 lines_drawn, bool is_engine, bool show_cars, bool show_outdated)
|
||||
{
|
||||
int i;
|
||||
byte colour;
|
||||
|
||||
for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
|
||||
const Engine *e = DEREF_ENGINE(i);
|
||||
const RailVehicleInfo *rvi = RailVehInfo(i);
|
||||
const EngineInfo *info = &_engine_info[i];
|
||||
|
||||
if ( rvi->power == 0 && !(show_cars) ) // disables display of cars (works since they do not have power)
|
||||
continue;
|
||||
|
||||
if (*sel == 0) *selected_id = i;
|
||||
|
||||
|
||||
colour = *sel == 0 ? 0xC : 0x10;
|
||||
if (!(ENGINE_AVAILABLE && show_outdated && RailVehInfo(i)->power && e->railtype == railtype)) {
|
||||
if (e->railtype != railtype || !(rvi->flags & RVI_WAGON) != is_engine ||
|
||||
!HASBIT(e->player_avail, _local_player))
|
||||
continue;
|
||||
} /*else {
|
||||
// TODO find a nice red colour for vehicles being replaced
|
||||
if ( _autoreplace_array[i] != i )
|
||||
colour = *sel == 0 ? 0x44 : 0x45;
|
||||
} */
|
||||
|
||||
if (IS_INT_INSIDE(--*pos, -lines_drawn, 0)) {
|
||||
DrawString(*x + 59, *y + 2, GetCustomEngineName(i),
|
||||
colour);
|
||||
DrawTrainEngine(*x + 29, *y + 6, i,
|
||||
SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
|
||||
*y += 14;
|
||||
}
|
||||
--*sel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void SetupScrollStuffForReplaceWindow(Window *w)
|
||||
{
|
||||
byte railtype;
|
||||
int selected_id[2] = {-1,-1};
|
||||
int sel[2] = { WP(w,replaceveh_d).sel_index[0], WP(w,replaceveh_d).sel_index[1]};
|
||||
int count = 0;
|
||||
int count2 = 0;
|
||||
int engine_id;
|
||||
|
||||
switch (WP(w,replaceveh_d).vehicletype) {
|
||||
case VEH_Train: {
|
||||
railtype = WP(w,replaceveh_d).railtype;
|
||||
for (engine_id = 0; engine_id < NUM_TRAIN_ENGINES; engine_id++) {
|
||||
const Engine *e = DEREF_ENGINE(engine_id);
|
||||
const EngineInfo *info = &_engine_info[engine_id];
|
||||
|
||||
if (ENGINE_AVAILABLE && RailVehInfo(engine_id)->power && e->railtype == railtype) {
|
||||
count++;
|
||||
if (sel[0]==0) selected_id[0] = engine_id;
|
||||
sel[0]--;
|
||||
if (HASBIT(e->player_avail, _local_player)) {
|
||||
if (sel[1]==0) selected_id[1] = engine_id;
|
||||
count2++;
|
||||
sel[1]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VEH_Road: {
|
||||
int num = NUM_ROAD_ENGINES;
|
||||
Engine *e = &_engines[ROAD_ENGINES_INDEX];
|
||||
byte cargo;
|
||||
EngineInfo *info;
|
||||
engine_id = ROAD_ENGINES_INDEX;
|
||||
|
||||
do {
|
||||
info = &_engine_info[engine_id];
|
||||
if (ENGINE_AVAILABLE) {
|
||||
if (sel[0]==0) selected_id[0] = engine_id;
|
||||
count++;
|
||||
sel[0]--;
|
||||
}
|
||||
} while (++engine_id,++e,--num);
|
||||
|
||||
if ( selected_id[0] != -1 ) { // only draw right array if we have anything in the left one
|
||||
num = NUM_ROAD_ENGINES;
|
||||
engine_id = ROAD_ENGINES_INDEX;
|
||||
e = &_engines[ROAD_ENGINES_INDEX];
|
||||
cargo = RoadVehInfo(selected_id[0])->cargo_type;
|
||||
|
||||
do {
|
||||
if ( cargo == RoadVehInfo(engine_id)->cargo_type && HASBIT(e->player_avail, _local_player)) {
|
||||
count2++;
|
||||
if (sel[1]==0) selected_id[1] = engine_id;
|
||||
sel[1]--;
|
||||
}
|
||||
} while (++engine_id,++e,--num);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VEH_Ship: {
|
||||
int num = NUM_SHIP_ENGINES;
|
||||
Engine *e = &_engines[SHIP_ENGINES_INDEX];
|
||||
byte cargo;
|
||||
EngineInfo *info;
|
||||
engine_id = SHIP_ENGINES_INDEX;
|
||||
byte refittable;
|
||||
|
||||
do {
|
||||
info = &_engine_info[engine_id];
|
||||
if (ENGINE_AVAILABLE) {
|
||||
if ( sel[0] == 0 ) selected_id[0] = engine_id;
|
||||
count++;
|
||||
sel[0]--;
|
||||
}
|
||||
} while (++engine_id,++e,--num);
|
||||
|
||||
if ( selected_id[0] != -1 ) {
|
||||
num = NUM_SHIP_ENGINES;
|
||||
e = &_engines[SHIP_ENGINES_INDEX];
|
||||
engine_id = SHIP_ENGINES_INDEX;
|
||||
cargo = ShipVehInfo(selected_id[0])->cargo_type;
|
||||
refittable = ShipVehInfo(selected_id[0])->refittable;
|
||||
|
||||
do {
|
||||
if (HASBIT(e->player_avail, _local_player)
|
||||
&& ( cargo == ShipVehInfo(engine_id)->cargo_type || refittable & ShipVehInfo(engine_id)->refittable)) {
|
||||
|
||||
if ( sel[1]==0) selected_id[1] = engine_id;
|
||||
sel[1]--;
|
||||
count2++;
|
||||
}
|
||||
} while (++engine_id,++e,--num);
|
||||
}
|
||||
break;
|
||||
} //end of ship
|
||||
|
||||
case VEH_Aircraft:{
|
||||
int num = NUM_AIRCRAFT_ENGINES;
|
||||
Engine *e = &_engines[AIRCRAFT_ENGINES_INDEX];
|
||||
EngineInfo *info;
|
||||
engine_id = AIRCRAFT_ENGINES_INDEX;
|
||||
byte subtype;
|
||||
|
||||
do {
|
||||
info = &_engine_info[engine_id];
|
||||
if (ENGINE_AVAILABLE) {
|
||||
count++;
|
||||
if (sel[0]==0) selected_id[0] = engine_id;
|
||||
sel[0]--;
|
||||
}
|
||||
} while (++engine_id,++e,--num);
|
||||
|
||||
if ( selected_id[0] != -1 ) {
|
||||
num = NUM_AIRCRAFT_ENGINES;
|
||||
e = &_engines[AIRCRAFT_ENGINES_INDEX];
|
||||
subtype = AircraftVehInfo(selected_id[0])->subtype;
|
||||
engine_id = AIRCRAFT_ENGINES_INDEX;
|
||||
do {
|
||||
if (HASBIT(e->player_avail, _local_player)) {
|
||||
if ( (subtype && AircraftVehInfo(engine_id)->subtype) || (!(subtype) && !AircraftVehInfo(engine_id)->subtype) ) {
|
||||
count2++;
|
||||
if (sel[1]==0) selected_id[1] = engine_id;
|
||||
sel[1]--;
|
||||
}
|
||||
}
|
||||
} while (++engine_id,++e,--num);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// sets up the number of items in each list
|
||||
SetVScrollCount(w, count);
|
||||
SetVScroll2Count(w, count2);
|
||||
WP(w,replaceveh_d).sel_engine[0] = selected_id[0];
|
||||
WP(w,replaceveh_d).sel_engine[1] = selected_id[1];
|
||||
|
||||
WP(w,replaceveh_d).count[0] = count;
|
||||
WP(w,replaceveh_d).count[1] = count2;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void DrawEngineArrayInReplaceWindow(Window *w, int x, int y, int x2, int y2, int pos, int pos2,
|
||||
int sel1, int sel2, int selected_id1, int selected_id2)
|
||||
{
|
||||
int sel[2] = {sel1, sel2};
|
||||
int selected_id[2] = {selected_id1, selected_id2};
|
||||
switch (WP(w,replaceveh_d).vehicletype) {
|
||||
case VEH_Train: {
|
||||
byte railtype = WP(w,replaceveh_d).railtype;
|
||||
DrawString(157, 89 + (14 * w->vscroll.cap), _rail_types_list[railtype], 0x10);
|
||||
/* draw sorting criteria string */
|
||||
|
||||
/* Ensure that custom engines which substituted wagons
|
||||
* are sorted correctly.
|
||||
* XXX - DO NOT EVER DO THIS EVER AGAIN! GRRR hacking in wagons as
|
||||
* engines to get more types.. Stays here until we have our own format
|
||||
* then it is exit!!! */
|
||||
train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, true, false, true); // True engines
|
||||
train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, true, false, false); // True engines
|
||||
train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, false, false); // Feeble wagons
|
||||
break;
|
||||
}
|
||||
|
||||
case VEH_Road: {
|
||||
int num = NUM_ROAD_ENGINES;
|
||||
Engine *e = &_engines[ROAD_ENGINES_INDEX];
|
||||
int engine_id = ROAD_ENGINES_INDEX;
|
||||
byte cargo;
|
||||
EngineInfo *info;
|
||||
|
||||
if ( selected_id[0] >= ROAD_ENGINES_INDEX && selected_id[0] <= SHIP_ENGINES_INDEX )
|
||||
cargo = RoadVehInfo(selected_id[0])->cargo_type;
|
||||
|
||||
do {
|
||||
info = &_engine_info[engine_id];
|
||||
if (ENGINE_AVAILABLE) {
|
||||
if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
|
||||
DrawString(x+59, y+2, GetCustomEngineName(engine_id), sel[0]==0 ? 0xC : 0x10);
|
||||
DrawRoadVehEngine(x+29, y+6, engine_id, SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
|
||||
y += 14;
|
||||
}
|
||||
|
||||
if ( RoadVehInfo(engine_id)->cargo_type == cargo && HASBIT(e->player_avail, _local_player) ) {
|
||||
if (IS_INT_INSIDE(--pos2, -w->vscroll.cap, 0) && RoadVehInfo(engine_id)->cargo_type == cargo) {
|
||||
DrawString(x2+59, y2+2, GetCustomEngineName(engine_id), sel[1]==0 ? 0xC : 0x10);
|
||||
DrawRoadVehEngine(x2+29, y2+6, engine_id, SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
|
||||
y2 += 14;
|
||||
}
|
||||
sel[1]--;
|
||||
}
|
||||
sel[0]--;
|
||||
}
|
||||
} while (++engine_id, ++e,--num);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case VEH_Ship: {
|
||||
int num = NUM_SHIP_ENGINES;
|
||||
Engine *e = &_engines[SHIP_ENGINES_INDEX];
|
||||
int engine_id = SHIP_ENGINES_INDEX;
|
||||
byte cargo, refittable;
|
||||
EngineInfo *info;
|
||||
|
||||
if ( selected_id[0] != -1 ) {
|
||||
cargo = ShipVehInfo(selected_id[0])->cargo_type;
|
||||
refittable = ShipVehInfo(selected_id[0])->refittable;
|
||||
}
|
||||
|
||||
do {
|
||||
info = &_engine_info[engine_id];
|
||||
if (ENGINE_AVAILABLE) {
|
||||
if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
|
||||
DrawString(x+75, y+7, GetCustomEngineName(engine_id), sel[0]==0 ? 0xC : 0x10);
|
||||
DrawShipEngine(x+35, y+10, engine_id, SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
|
||||
y += 24;
|
||||
}
|
||||
if ( selected_id[0] != -1 ) {
|
||||
if (HASBIT(e->player_avail, _local_player) && ( cargo == ShipVehInfo(engine_id)->cargo_type || refittable & ShipVehInfo(engine_id)->refittable)) {
|
||||
if (IS_INT_INSIDE(--pos2, -w->vscroll.cap, 0)) {
|
||||
DrawString(x2+75, y2+7, GetCustomEngineName(engine_id), sel[1]==0 ? 0xC : 0x10);
|
||||
DrawShipEngine(x2+35, y2+10, engine_id, SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
|
||||
y2 += 24;
|
||||
}
|
||||
sel[1]--;
|
||||
}
|
||||
}
|
||||
sel[0]--;
|
||||
}
|
||||
} while (++engine_id, ++e,--num);
|
||||
break;
|
||||
} //end of ship
|
||||
|
||||
case VEH_Aircraft: {
|
||||
if ( selected_id[0] != -1 ) {
|
||||
int num = NUM_AIRCRAFT_ENGINES;
|
||||
Engine *e = &_engines[AIRCRAFT_ENGINES_INDEX];
|
||||
int engine_id = AIRCRAFT_ENGINES_INDEX;
|
||||
byte subtype = AircraftVehInfo(selected_id[0])->subtype;
|
||||
EngineInfo *info;
|
||||
|
||||
do {
|
||||
info = &_engine_info[engine_id];
|
||||
if (ENGINE_AVAILABLE) {
|
||||
if (sel[0]==0) selected_id[0] = engine_id;
|
||||
if (IS_INT_INSIDE(--pos, -w->vscroll.cap, 0)) {
|
||||
DrawString(x+62, y+7, GetCustomEngineName(engine_id), sel[0]==0 ? 0xC : 0x10);
|
||||
DrawAircraftEngine(x+29, y+10, engine_id, SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
|
||||
y += 24;
|
||||
}
|
||||
if ( ((subtype && AircraftVehInfo(engine_id)->subtype) || (!(subtype) && !AircraftVehInfo(engine_id)->subtype))
|
||||
&& HASBIT(e->player_avail, _local_player) ) {
|
||||
if (sel[1]==0) selected_id[1] = engine_id;
|
||||
if (IS_INT_INSIDE(--pos2, -w->vscroll.cap, 0)) {
|
||||
DrawString(x2+62, y2+7, GetCustomEngineName(engine_id), sel[1]==0 ? 0xC : 0x10);
|
||||
DrawAircraftEngine(x2+29, y2+10, engine_id, SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)));
|
||||
y2 += 24;
|
||||
}
|
||||
sel[1]--;
|
||||
}
|
||||
sel[0]--;
|
||||
}
|
||||
} while (++engine_id, ++e,--num);
|
||||
}
|
||||
break;
|
||||
} // end of aircraft
|
||||
}
|
||||
|
||||
}
|
||||
static void ReplaceVehicleWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
// these 3 variables is used if any of the lists is clicked
|
||||
uint16 click_scroll_pos = w->vscroll2.pos;
|
||||
uint16 click_scroll_cap = w->vscroll2.cap;
|
||||
byte click_side = 1;
|
||||
|
||||
switch(e->event) {
|
||||
case WE_PAINT:
|
||||
{
|
||||
int pos = w->vscroll.pos;
|
||||
int selected_id[2] = {-1,-1};
|
||||
int x = 1;
|
||||
int y = 15;
|
||||
int pos2 = w->vscroll2.pos;
|
||||
int x2 = 1 + 228;
|
||||
int y2 = 15;
|
||||
int sel[2] = { WP(w,replaceveh_d).sel_index[0], WP(w,replaceveh_d).sel_index[1]};
|
||||
|
||||
SetupScrollStuffForReplaceWindow(w);
|
||||
|
||||
selected_id[0] = WP(w,replaceveh_d).sel_engine[0];
|
||||
selected_id[1] = WP(w,replaceveh_d).sel_engine[1];
|
||||
|
||||
// sets the selected left item to the top one if it's greater than the number of vehicles in the left side
|
||||
|
||||
if ( WP(w,replaceveh_d).count[0] <= sel[0] ) {
|
||||
if (WP(w,replaceveh_d).count[0]) {
|
||||
sel[0] = 0;
|
||||
WP(w,replaceveh_d).sel_index[0] = 0;
|
||||
w->vscroll.pos = 0;
|
||||
// now we go back to set selected_id[1] properly
|
||||
SetWindowDirty(w);
|
||||
return;
|
||||
} else { //there are no vehicles in the left window
|
||||
selected_id[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( WP(w,replaceveh_d).count[1] <= sel[1] ) {
|
||||
if (WP(w,replaceveh_d).count[1]) {
|
||||
sel[1] = 0;
|
||||
WP(w,replaceveh_d).sel_index[1] = 0;
|
||||
w->vscroll2.pos = 0;
|
||||
// now we go back to set selected_id[1] properly
|
||||
SetWindowDirty(w);
|
||||
return;
|
||||
} else { //there are no vehicles in the right window
|
||||
selected_id[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( selected_id[0] == selected_id[1] || _autoreplace_array[selected_id[0]] == selected_id[1]
|
||||
|| selected_id[0] == -1 || selected_id[1] == -1 )
|
||||
SETBIT(w->disabled_state, 4);
|
||||
else
|
||||
CLRBIT(w->disabled_state, 4);
|
||||
|
||||
if ( _autoreplace_array[selected_id[0]] == selected_id[0] || selected_id[0] == -1 )
|
||||
SETBIT(w->disabled_state, 6);
|
||||
else
|
||||
CLRBIT(w->disabled_state, 6);
|
||||
|
||||
// now the actual drawing of the window itself takes place
|
||||
DrawWindowWidgets(w);
|
||||
|
||||
|
||||
|
||||
// sets up the string for the vehicle that is being replaced to
|
||||
if ( selected_id[0] != -1 ) {
|
||||
if ( selected_id[0] == _autoreplace_array[selected_id[0]] )
|
||||
SetDParam(0, STR_NOT_REPLACING);
|
||||
else
|
||||
SetDParam(0, GetCustomEngineName(_autoreplace_array[selected_id[0]]));
|
||||
} else {
|
||||
SetDParam(0, STR_NOT_REPLACING_VEHICLE_SELECTED);
|
||||
}
|
||||
|
||||
|
||||
DrawString(145, (WP(w,replaceveh_d).line_height == 24 ? 67 : 77 ) + ( WP(w,replaceveh_d).line_height * w->vscroll.cap), STR_02BD, 0x10);
|
||||
|
||||
|
||||
/* now we draw the two arrays according to what we just counted */
|
||||
DrawEngineArrayInReplaceWindow(w, x, y, x2, y2, pos, pos2, sel[0], sel[1], selected_id[0], selected_id[1]);
|
||||
|
||||
WP(w,replaceveh_d).sel_engine[0] = selected_id[0];
|
||||
WP(w,replaceveh_d).sel_engine[1] = selected_id[1];
|
||||
/* now we draw the info about the vehicles we selected */
|
||||
switch (WP(w,replaceveh_d).vehicletype) {
|
||||
case VEH_Train: {
|
||||
byte i = 0;
|
||||
int offset = 0;
|
||||
|
||||
for ( i = 0 ; i < 2 ; i++) {
|
||||
if ( i )
|
||||
offset = 228;
|
||||
if (selected_id[i] != -1) {
|
||||
if (!(RailVehInfo(selected_id[i])->flags & RVI_WAGON)) {
|
||||
/* it's an engine */
|
||||
Set_DPARAM_Train_Engine_Build_Window(selected_id[i]);
|
||||
DrawString(2 + offset, 15 + (14 * w->vscroll.cap), STR_8817_COST_WEIGHT_T_SPEED_POWER, 0);
|
||||
} else {
|
||||
/* it's a wagon. Train cars are not replaced with the current GUI, but this code is ready for newgrf if anybody adds that*/
|
||||
Set_DPARAM_Train_Car_Build_Window(w, selected_id[i]);
|
||||
DrawString(2 + offset, 15 + (14 * w->vscroll.cap), STR_8821_COST_WEIGHT_T_T_CAPACITY, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} //end if case VEH_Train
|
||||
|
||||
case VEH_Road: {
|
||||
if (selected_id[0] != -1) {
|
||||
Set_DPARAM_Road_Veh_Build_Window(selected_id[0]);
|
||||
DrawString(2, 15 + (14 * w->vscroll.cap), STR_9008_COST_SPEED_RUNNING_COST, 0);
|
||||
if (selected_id[1] != -1) {
|
||||
Set_DPARAM_Road_Veh_Build_Window(selected_id[1]);
|
||||
DrawString(2 + 228, 15 + (14 * w->vscroll.cap), STR_9008_COST_SPEED_RUNNING_COST, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} // end of VEH_Road
|
||||
|
||||
case VEH_Ship: {
|
||||
if (selected_id[0] != -1) {
|
||||
Set_DPARAM_Ship_Build_Window(selected_id[0]);
|
||||
DrawString(2, 15 + (24 * w->vscroll.cap), STR_980A_COST_SPEED_CAPACITY_RUNNING, 0);
|
||||
if (selected_id[1] != -1) {
|
||||
Set_DPARAM_Ship_Build_Window(selected_id[1]);
|
||||
DrawString(2 + 228, 15 + (24 * w->vscroll.cap), STR_980A_COST_SPEED_CAPACITY_RUNNING, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} // end of VEH_Ship
|
||||
|
||||
case VEH_Aircraft: {
|
||||
if (selected_id[0] != -1) {
|
||||
Set_DPARAM_Aircraft_Build_Window(selected_id[0]);
|
||||
DrawString(2, 15 + (24 * w->vscroll.cap), STR_A007_COST_SPEED_CAPACITY_PASSENGERS, 0);
|
||||
if (selected_id[1] != -1) {
|
||||
Set_DPARAM_Aircraft_Build_Window(selected_id[1]);
|
||||
DrawString(2 + 228, 15 + (24 * w->vscroll.cap), STR_A007_COST_SPEED_CAPACITY_PASSENGERS, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} // end of VEH_Aircraft
|
||||
}
|
||||
} // end of paint
|
||||
|
||||
case WE_CLICK: {
|
||||
switch(e->click.widget) {
|
||||
/*case 0:
|
||||
DeleteWindowById(WC_REPLACE_VEHICLE, WP(w,replaceveh_d).vehicletype );
|
||||
break;*/
|
||||
|
||||
case 14: case 15:/* Select sorting criteria dropdown menu */
|
||||
// finds mask for available engines
|
||||
{
|
||||
int engine_avail = 0;
|
||||
if ( !(HASBIT(_engines[NUM_NORMAL_RAIL_ENGINES + NUM_MONORAIL_ENGINES].player_avail, _local_player))) {
|
||||
engine_avail = 4;
|
||||
if ( !(HASBIT(_engines[NUM_NORMAL_RAIL_ENGINES].player_avail, _local_player)))
|
||||
engine_avail = 6;
|
||||
}
|
||||
ShowDropDownMenu(w, _rail_types_list, WP(w,replaceveh_d).railtype, 15, engine_avail, 1);
|
||||
return;
|
||||
}
|
||||
case 4: {
|
||||
_autoreplace_array[WP(w,replaceveh_d).sel_engine[0]] = WP(w,replaceveh_d).sel_engine[1];
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: {
|
||||
_autoreplace_array[WP(w,replaceveh_d).sel_engine[0]] = WP(w,replaceveh_d).sel_engine[0];
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
}
|
||||
|
||||
case 7:
|
||||
// sets up that the left one was clicked. The default values are for the right one (9)
|
||||
// this way, the code for 9 handles both sides
|
||||
click_scroll_pos = w->vscroll.pos;
|
||||
click_scroll_cap = w->vscroll.cap;
|
||||
click_side = 0;
|
||||
case 9: {
|
||||
uint i = (e->click.pt.y - 14) / WP(w,replaceveh_d).line_height;
|
||||
if (i < click_scroll_cap) {
|
||||
WP(w,replaceveh_d).sel_index[click_side] = i + click_scroll_pos;
|
||||
SetWindowDirty(w);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case WE_DROPDOWN_SELECT: { /* we have selected a dropdown item in the list */
|
||||
//potiential bug: railtypes needs to be activated 0, 1, 2... If one is skipped, it messes up
|
||||
WP(w,replaceveh_d).railtype = e->dropdown.index;
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _replace_rail_vehicle_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 14, 11, 443, 0, 13, STR_REPLACE_VEHICLES, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_STICKYBOX, 14, 444, 455, 0, 13, 0x0, STR_STICKY_BUTTON},
|
||||
{ WWT_PANEL, 14, 0, 227, 126, 187, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 14, 0, 138, 200, 211, STR_REPLACE_VEHICLES_START,STR_REPLACE_HELP_START_BUTTON},
|
||||
{ WWT_PANEL, 14, 139, 316, 188, 199, 0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB},
|
||||
{ WWT_PUSHTXTBTN, 14, 317, 455, 200, 211, STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON},
|
||||
{ WWT_MATRIX, 14, 0, 216, 14, 125, 0x801, STR_REPLACE_HELP_LEFT_ARRAY},
|
||||
{ WWT_SCROLLBAR, 14, 217, 227, 14, 125, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_MATRIX, 14, 228, 455, 14, 125, 0x801, STR_REPLACE_HELP_RIGHT_ARRAY},
|
||||
{ WWT_SCROLL2BAR, 14, 445, 455, 14, 125, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_PANEL, 14, 228, 455, 126, 187, 0x0, STR_NULL},
|
||||
// the rest are train specific stuff
|
||||
{ WWT_PANEL, 14, 0, 138, 188, 199, 0x0, STR_NULL},
|
||||
{ WWT_PANEL, 3, 139, 153, 200, 211, 0x0, STR_NULL},
|
||||
{ WWT_PANEL, 14, 154, 290, 200, 211, 0x0, STR_REPLACE_HELP_RAILTYPE},
|
||||
{ WWT_CLOSEBOX, 14, 291, 301, 200, 210, STR_0225, STR_REPLACE_HELP_RAILTYPE},
|
||||
{ WWT_PANEL, 3, 301, 316, 200, 211, 0x0, STR_NULL},
|
||||
{ WWT_PANEL, 14, 317, 455, 188, 199, 0x0, STR_NULL},
|
||||
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const Widget _replace_road_vehicle_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 14, 11, 443, 0, 13, STR_REPLACE_VEHICLES, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_STICKYBOX, 14, 444, 455, 0, 13, 0x0, STR_STICKY_BUTTON},
|
||||
{ WWT_PANEL, 14, 0, 227, 126, 187, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 14, 0, 138, 188, 199, STR_REPLACE_VEHICLES_START,STR_REPLACE_HELP_START_BUTTON},
|
||||
{ WWT_PANEL, 14, 139, 316, 188, 199, 0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB},
|
||||
{ WWT_PUSHTXTBTN, 14, 317, 455, 188, 199, STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON},
|
||||
{ WWT_MATRIX, 14, 0, 216, 14, 125, 0x801, STR_REPLACE_HELP_LEFT_ARRAY},
|
||||
{ WWT_SCROLLBAR, 14, 217, 227, 14, 125, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_MATRIX, 14, 228, 455, 14, 125, 0x801, STR_REPLACE_HELP_RIGHT_ARRAY},
|
||||
{ WWT_SCROLL2BAR, 14, 445, 455, 14, 125, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_PANEL, 14, 228, 455, 126, 187, 0x0, STR_NULL},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const Widget _replace_ship_aircraft_vehicle_widgets[] = {
|
||||
{ WWT_CLOSEBOX, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, 14, 11, 443, 0, 13, STR_REPLACE_VEHICLES, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_STICKYBOX, 14, 444, 455, 0, 13, 0x0, STR_STICKY_BUTTON},
|
||||
{ WWT_PANEL, 14, 0, 227, 110, 161, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, 14, 0, 138, 162, 173, STR_REPLACE_VEHICLES_START,STR_REPLACE_HELP_START_BUTTON},
|
||||
{ WWT_PANEL, 14, 139, 316, 162, 173, 0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB},
|
||||
{ WWT_PUSHTXTBTN, 14, 317, 455, 162, 173, STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON},
|
||||
{ WWT_MATRIX, 14, 0, 216, 14, 109, 0x401, STR_REPLACE_HELP_LEFT_ARRAY},
|
||||
{ WWT_SCROLLBAR, 14, 217, 227, 14, 109, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_MATRIX, 14, 228, 455, 14, 109, 0x401, STR_REPLACE_HELP_RIGHT_ARRAY},
|
||||
{ WWT_SCROLL2BAR, 14, 445, 455, 14, 109, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_PANEL, 14, 228, 455, 110, 161, 0x0, STR_NULL},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const WindowDesc _replace_rail_vehicle_desc = {
|
||||
-1, -1, 456, 212,
|
||||
WC_REPLACE_VEHICLE,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
|
||||
_replace_rail_vehicle_widgets,
|
||||
ReplaceVehicleWndProc
|
||||
};
|
||||
|
||||
static const WindowDesc _replace_road_vehicle_desc = {
|
||||
-1, -1, 456, 200,
|
||||
WC_REPLACE_VEHICLE,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
|
||||
_replace_road_vehicle_widgets,
|
||||
ReplaceVehicleWndProc
|
||||
};
|
||||
|
||||
static const WindowDesc _replace_ship_aircraft_vehicle_desc = {
|
||||
-1, -1, 456, 174,
|
||||
WC_REPLACE_VEHICLE,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON,
|
||||
_replace_ship_aircraft_vehicle_widgets,
|
||||
ReplaceVehicleWndProc
|
||||
};
|
||||
|
||||
|
||||
void ShowReplaceVehicleWindow(byte vehicletype)
|
||||
{
|
||||
Window *w;
|
||||
|
||||
DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype );
|
||||
|
||||
switch (vehicletype) {
|
||||
case VEH_Train:
|
||||
w = AllocateWindowDescFront(&_replace_rail_vehicle_desc, vehicletype);
|
||||
w->vscroll.cap = 8;
|
||||
WP(w,replaceveh_d).line_height = 14;
|
||||
break;
|
||||
case VEH_Road:
|
||||
w = AllocateWindowDescFront(&_replace_road_vehicle_desc, vehicletype);
|
||||
w->vscroll.cap = 8;
|
||||
WP(w,replaceveh_d).line_height = 14;
|
||||
break;
|
||||
case VEH_Ship: case VEH_Aircraft:
|
||||
w = AllocateWindowDescFront(&_replace_ship_aircraft_vehicle_desc, vehicletype);
|
||||
w->vscroll.cap = 4;
|
||||
WP(w,replaceveh_d).line_height = 24;
|
||||
break;
|
||||
}
|
||||
WP(w,replaceveh_d).vehicletype = vehicletype;
|
||||
w->vscroll2.cap = w->vscroll.cap; // these two are always the same
|
||||
}
|
||||
|
|
|
@ -42,12 +42,13 @@ typedef DEF_SORTER(VehicleSortListingTypeFunctions);
|
|||
#define SORT_BY_UNSORTED 0
|
||||
extern VehicleSortListingTypeFunctions * const _vehicle_sorter[];
|
||||
extern const StringID _vehicle_sort_listing[];
|
||||
extern const StringID _rail_types_list[];
|
||||
|
||||
enum VehicleSortTypes {
|
||||
VEHTRAIN = 0,
|
||||
VEHROAD = 1,
|
||||
VEHSHIP = 2,
|
||||
VEHAIRCRAFT = 3
|
||||
VEHAIRCRAFT = 3
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -56,4 +57,13 @@ enum {
|
|||
PLY_WND_PRC__SIZE_OF_ROW_BIG = 36,
|
||||
};
|
||||
|
||||
void ShowReplaceVehicleWindow(byte vehicletype);
|
||||
|
||||
void Set_DPARAM_Train_Engine_Build_Window(uint16 engine_number);
|
||||
void Set_DPARAM_Train_Car_Build_Window(Window *w, uint16 engine_number);
|
||||
void Set_DPARAM_Road_Veh_Build_Window(uint16 engine_number);
|
||||
void Set_DPARAM_Aircraft_Build_Window(uint16 engine_number);
|
||||
void Set_DPARAM_Ship_Build_Window(uint16 engine_number);
|
||||
|
||||
|
||||
#endif /* VEHICLE_GUI_H */
|
||||
|
|
248
widget.c
248
widget.c
|
@ -46,23 +46,37 @@ void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y)
|
|||
int mi, ma, pos;
|
||||
Scrollbar *sb;
|
||||
|
||||
if (wi->type == WWT_SCROLLBAR) {
|
||||
// vertical scroller
|
||||
w->flags4 &= ~WF_HSCROLL;
|
||||
mi = wi->top;
|
||||
ma = wi->bottom;
|
||||
pos = y;
|
||||
sb = &w->vscroll;
|
||||
} else {
|
||||
// horizontal scroller
|
||||
assert(wi->type == WWT_HSCROLLBAR);
|
||||
w->flags4 |= WF_HSCROLL;
|
||||
mi = wi->left;
|
||||
ma = wi->right;
|
||||
pos = x;
|
||||
sb = &w->hscroll;
|
||||
switch (wi->type) {
|
||||
case WWT_SCROLLBAR: {
|
||||
// vertical scroller
|
||||
w->flags4 &= ~WF_HSCROLL;
|
||||
w->flags4 &= ~WF_SCROLL2;
|
||||
mi = wi->top;
|
||||
ma = wi->bottom;
|
||||
pos = y;
|
||||
sb = &w->vscroll;
|
||||
break;
|
||||
}
|
||||
case WWT_SCROLL2BAR: {
|
||||
// 2nd vertical scroller
|
||||
w->flags4 &= ~WF_HSCROLL;
|
||||
w->flags4 |= WF_SCROLL2;
|
||||
mi = wi->top;
|
||||
ma = wi->bottom;
|
||||
pos = y;
|
||||
sb = &w->vscroll2;
|
||||
break;
|
||||
}
|
||||
case WWT_HSCROLLBAR: {
|
||||
// horizontal scroller
|
||||
assert(wi->type == WWT_HSCROLLBAR);
|
||||
w->flags4 |= WF_HSCROLL;
|
||||
mi = wi->left;
|
||||
ma = wi->right;
|
||||
pos = x;
|
||||
sb = &w->hscroll;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos <= mi+9) {
|
||||
// Pressing the upper button?
|
||||
if (!_demo_mode) {
|
||||
|
@ -258,8 +272,8 @@ void DrawWindowWidgets(Window *w)
|
|||
int c1,c2;
|
||||
|
||||
// draw up/down buttons
|
||||
DrawFrameRect(r.left, r.top, r.right, r.top+9, wi->color, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL)) == WF_SCROLL_UP ? 0x20 : 0);
|
||||
DrawFrameRect(r.left, r.bottom-9, r.right, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL)) == WF_SCROLL_DOWN ? 0x20 : 0);
|
||||
DrawFrameRect(r.left, r.top, r.right, r.top+9, wi->color, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_UP ? 0x20 : 0);
|
||||
DrawFrameRect(r.left, r.bottom-9, r.right, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_DOWN ? 0x20 : 0);
|
||||
|
||||
// draw icons in up/down buttons
|
||||
DoDrawString("\xA0", r.left+2, r.top, 0x10);
|
||||
|
@ -279,7 +293,36 @@ void DrawWindowWidgets(Window *w)
|
|||
GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2);
|
||||
|
||||
pt = HandleScrollbarHittest(&w->vscroll, r.top, r.bottom);
|
||||
DrawFrameRect(r.left, pt.x, r.right, pt.y, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL)) == WF_SCROLL_MIDDLE ? 0x20 : 0);
|
||||
DrawFrameRect(r.left, pt.x, r.right, pt.y, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == WF_SCROLL_MIDDLE ? 0x20 : 0);
|
||||
break;
|
||||
}
|
||||
case WWT_SCROLL2BAR: {
|
||||
Point pt;
|
||||
int c1,c2;
|
||||
|
||||
// draw up/down buttons
|
||||
DrawFrameRect(r.left, r.top, r.right, r.top+9, wi->color, (w->flags4 & (WF_SCROLL_UP | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_UP | WF_SCROLL2) ? 0x20 : 0);
|
||||
DrawFrameRect(r.left, r.bottom-9, r.right, r.bottom, wi->color, (w->flags4 & (WF_SCROLL_DOWN | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_DOWN | WF_SCROLL2) ? 0x20 : 0);
|
||||
|
||||
// draw icons in up/down buttons
|
||||
DoDrawString("\xA0", r.left+2, r.top, 0x10);
|
||||
DoDrawString("\xAA", r.left+2, r.bottom-9, 0x10);
|
||||
|
||||
c1 = _color_list[wi->color&0xF].window_color_1a;
|
||||
c2 = _color_list[wi->color&0xF].window_color_2;
|
||||
|
||||
// draw "shaded" background
|
||||
GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c2);
|
||||
GfxFillRect(r.left, r.top+10, r.right, r.bottom-10, c1 | 0x8000);
|
||||
|
||||
// draw shaded lines
|
||||
GfxFillRect(r.left+2, r.top+10, r.left+2, r.bottom-10, c1);
|
||||
GfxFillRect(r.left+3, r.top+10, r.left+3, r.bottom-10, c2);
|
||||
GfxFillRect(r.left+7, r.top+10, r.left+7, r.bottom-10, c1);
|
||||
GfxFillRect(r.left+8, r.top+10, r.left+8, r.bottom-10, c2);
|
||||
|
||||
pt = HandleScrollbarHittest(&w->vscroll2, r.top, r.bottom);
|
||||
DrawFrameRect(r.left, pt.x, r.right, pt.y, wi->color, (w->flags4 & (WF_SCROLL_MIDDLE | WF_HSCROLL | WF_SCROLL2)) == (WF_SCROLL_MIDDLE | WF_SCROLL2) ? 0x20 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -383,6 +426,7 @@ draw_default:;
|
|||
|
||||
static uint _dropdown_item_count;
|
||||
static uint32 _dropdown_disabled;
|
||||
static bool _dropdown_hide_disabled;
|
||||
static const StringID *_dropdown_items;
|
||||
static int _dropdown_selindex;
|
||||
static byte _dropdown_button;
|
||||
|
@ -421,95 +465,100 @@ void DropdownMenuWndProc(Window *w, WindowEvent *e)
|
|||
int item;
|
||||
|
||||
switch(e->event) {
|
||||
case WE_PAINT: {
|
||||
int x,y,i,sel;
|
||||
uint32 dis;
|
||||
case WE_PAINT: {
|
||||
int x,y,i,sel;
|
||||
uint32 dis;
|
||||
bool hidden;
|
||||
|
||||
DrawWindowWidgets(w);
|
||||
DrawWindowWidgets(w);
|
||||
|
||||
x = 1;
|
||||
y = 2;
|
||||
sel = _dropdown_selindex;
|
||||
dis = _dropdown_disabled;
|
||||
x = 1;
|
||||
y = 2;
|
||||
sel = _dropdown_selindex;
|
||||
dis = _dropdown_disabled;
|
||||
hidden = _dropdown_hide_disabled;
|
||||
|
||||
|
||||
for(i=0; _dropdown_items[i] != INVALID_STRING_ID; i++) {
|
||||
if (_dropdown_items[i] != 0) {
|
||||
if (sel == 0) {
|
||||
GfxFillRect(x+1, y, x+w->width-4, y + 9, 0);
|
||||
for(i=0; _dropdown_items[i] != INVALID_STRING_ID; i++) {
|
||||
if (!(hidden) | !(dis & 1)) {
|
||||
if (_dropdown_items[i] != 0) {
|
||||
if (sel == 0) {
|
||||
GfxFillRect(x+1, y, x+w->width-4, y + 9, 0);
|
||||
}
|
||||
DrawString(x+2, y, _dropdown_items[i], sel==0 ? 12 : 16);
|
||||
|
||||
if (dis & 1) {
|
||||
GfxFillRect(x, y, x+w->width-3, y + 9, 0x8000 +
|
||||
_color_list[_dropdown_menu_widgets[0].color].window_color_bga);
|
||||
}
|
||||
} else {
|
||||
int color_1 = _color_list[_dropdown_menu_widgets[0].color].window_color_1a;
|
||||
int color_2 = _color_list[_dropdown_menu_widgets[0].color].window_color_2;
|
||||
GfxFillRect(x+1, y+3, x+w->width-5, y+3, color_1);
|
||||
GfxFillRect(x+1, y+4, x+w->width-5, y+4, color_2);
|
||||
}
|
||||
y += 10;
|
||||
sel--;
|
||||
}
|
||||
DrawString(x+2, y, _dropdown_items[i], sel==0 ? 12 : 16);
|
||||
|
||||
if (dis & 1) {
|
||||
GfxFillRect(x, y, x+w->width-3, y + 9, 0x8000 +
|
||||
_color_list[_dropdown_menu_widgets[0].color].window_color_bga);
|
||||
}
|
||||
} else {
|
||||
int color_1 = _color_list[_dropdown_menu_widgets[0].color].window_color_1a;
|
||||
int color_2 = _color_list[_dropdown_menu_widgets[0].color].window_color_2;
|
||||
GfxFillRect(x+1, y+3, x+w->width-5, y+3, color_1);
|
||||
GfxFillRect(x+1, y+4, x+w->width-5, y+4, color_2);
|
||||
dis>>=1;
|
||||
}
|
||||
y += 10;
|
||||
sel--;
|
||||
dis>>=1;
|
||||
}
|
||||
} break;
|
||||
} break;
|
||||
|
||||
case WE_CLICK: {
|
||||
item = GetDropdownItem(w);
|
||||
if (item >= 0) {
|
||||
_dropdown_var1 = 4;
|
||||
_dropdown_selindex = item;
|
||||
SetWindowDirty(w);
|
||||
}
|
||||
} break;
|
||||
|
||||
case WE_MOUSELOOP: {
|
||||
Window *w2 = FindWindowById(_dropdown_windowclass, _dropdown_windownum);
|
||||
if (w2 == NULL) {
|
||||
DeleteWindow(w);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dropdown_var1 != 0 && --_dropdown_var1 == 0) {
|
||||
WindowEvent e;
|
||||
e.event = WE_DROPDOWN_SELECT;
|
||||
e.dropdown.button = _dropdown_button;
|
||||
e.dropdown.index = _dropdown_selindex;
|
||||
w2->wndproc(w2, &e);
|
||||
DeleteWindow(w);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dropdown_var2 != 0) {
|
||||
case WE_CLICK: {
|
||||
item = GetDropdownItem(w);
|
||||
if (item >= 0) {
|
||||
_dropdown_var1 = 4;
|
||||
_dropdown_selindex = item;
|
||||
SetWindowDirty(w);
|
||||
}
|
||||
} break;
|
||||
|
||||
if (!_left_button_clicked) {
|
||||
_dropdown_var2 = 0;
|
||||
if (item < 0)
|
||||
return;
|
||||
_dropdown_var1 = 2;
|
||||
} else {
|
||||
if (item < 0)
|
||||
return;
|
||||
case WE_MOUSELOOP: {
|
||||
Window *w2 = FindWindowById(_dropdown_windowclass, _dropdown_windownum);
|
||||
if (w2 == NULL) {
|
||||
DeleteWindow(w);
|
||||
return;
|
||||
}
|
||||
|
||||
_dropdown_selindex = item;
|
||||
SetWindowDirty(w);
|
||||
}
|
||||
} break;
|
||||
if (_dropdown_var1 != 0 && --_dropdown_var1 == 0) {
|
||||
WindowEvent e;
|
||||
e.event = WE_DROPDOWN_SELECT;
|
||||
e.dropdown.button = _dropdown_button;
|
||||
e.dropdown.index = _dropdown_selindex;
|
||||
w2->wndproc(w2, &e);
|
||||
DeleteWindow(w);
|
||||
return;
|
||||
}
|
||||
|
||||
case WE_DESTROY: {
|
||||
Window *w2 = FindWindowById(_dropdown_windowclass, _dropdown_windownum);
|
||||
if (w2 != NULL) {
|
||||
CLRBIT(w2->click_state, _dropdown_button);
|
||||
InvalidateWidget(w2, _dropdown_button);
|
||||
}
|
||||
} break;
|
||||
if (_dropdown_var2 != 0) {
|
||||
item = GetDropdownItem(w);
|
||||
|
||||
if (!_left_button_clicked) {
|
||||
_dropdown_var2 = 0;
|
||||
if (item < 0)
|
||||
return;
|
||||
_dropdown_var1 = 2;
|
||||
} else {
|
||||
if (item < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
_dropdown_selindex = item;
|
||||
SetWindowDirty(w);
|
||||
}
|
||||
} break;
|
||||
|
||||
case WE_DESTROY: {
|
||||
Window *w2 = FindWindowById(_dropdown_windowclass, _dropdown_windownum);
|
||||
if (w2 != NULL) {
|
||||
CLRBIT(w2->click_state, _dropdown_button);
|
||||
InvalidateWidget(w2, _dropdown_button);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask)
|
||||
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, bool remove_filtered_strings)
|
||||
{
|
||||
WindowNumber num;
|
||||
WindowClass cls;
|
||||
|
@ -519,6 +568,7 @@ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int butt
|
|||
uint32 old_click_state = w->click_state;
|
||||
|
||||
_dropdown_disabled = disabled_mask;
|
||||
_dropdown_hide_disabled = remove_filtered_strings;
|
||||
|
||||
cls = w->window_class;
|
||||
num = w->window_number;
|
||||
|
@ -549,6 +599,16 @@ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int butt
|
|||
|
||||
wi = &w->widget[button];
|
||||
|
||||
if ( remove_filtered_strings ) {
|
||||
int j;
|
||||
for(j=0; _dropdown_items[j] != INVALID_STRING_ID; j++) {
|
||||
if ( disabled_mask & ( 1 << j )) {
|
||||
_dropdown_item_count--;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_dropdown_menu_widgets[0].color = wi->color;
|
||||
|
||||
w2 = AllocateWindow(
|
||||
|
|
5
window.c
5
window.c
|
@ -44,7 +44,7 @@ void DispatchLeftClickEvent(Window *w, int x, int y) {
|
|||
case WWT_NODISTXTBTN:
|
||||
break;
|
||||
}
|
||||
} else if (wi->type == WWT_SCROLLBAR || wi->type == WWT_HSCROLLBAR) {
|
||||
} else if (wi->type == WWT_SCROLLBAR || wi->type == WWT_SCROLL2BAR || wi->type == WWT_HSCROLLBAR) {
|
||||
ScrollbarClickHandler(w, wi, e.click.pt.x, e.click.pt.y);
|
||||
}
|
||||
|
||||
|
@ -953,6 +953,9 @@ static bool HandleScrollbarScrolling()
|
|||
if (w->flags4 & WF_HSCROLL) {
|
||||
sb = &w->hscroll;
|
||||
i = _cursor.pos.x - _cursorpos_drag_start.x;
|
||||
} else if (w->flags4 & WF_SCROLL2){
|
||||
sb = &w->vscroll2;
|
||||
i = _cursor.pos.y - _cursorpos_drag_start.y;
|
||||
} else {
|
||||
sb = &w->vscroll;
|
||||
i = _cursor.pos.y - _cursorpos_drag_start.y;
|
||||
|
|
17
window.h
17
window.h
|
@ -200,7 +200,7 @@ struct Window {
|
|||
int left,top;
|
||||
int width,height;
|
||||
|
||||
Scrollbar hscroll, vscroll;
|
||||
Scrollbar hscroll, vscroll, vscroll2;
|
||||
|
||||
byte caption_color;
|
||||
|
||||
|
@ -254,6 +254,15 @@ typedef struct {
|
|||
int16 rename_engine;
|
||||
} buildtrain_d;
|
||||
|
||||
typedef struct {
|
||||
byte railtype;
|
||||
byte vehicletype;
|
||||
byte sel_index[2];
|
||||
int16 sel_engine[2];
|
||||
uint16 count[2];
|
||||
byte line_height;
|
||||
} replaceveh_d;
|
||||
|
||||
typedef struct {
|
||||
VehicleID sel;
|
||||
} traindepot_d;
|
||||
|
@ -358,7 +367,8 @@ enum WindowWidgetTypes {
|
|||
|
||||
WWT_HSCROLLBAR = 11,
|
||||
WWT_STICKYBOX = 12,
|
||||
WWT_LAST = 13, /* Last Item. use WIDGETS_END to fill up padding!! */
|
||||
WWT_SCROLL2BAR = 13, /* 2nd vertical scrollbar*/
|
||||
WWT_LAST = 14, /* Last Item. use WIDGETS_END to fill up padding!! */
|
||||
|
||||
WWT_MASK = 31,
|
||||
|
||||
|
@ -384,6 +394,7 @@ enum WindowFlags {
|
|||
|
||||
WF_WHITE_BORDER_ONE = 1 << 11,
|
||||
WF_WHITE_BORDER_MASK = 3 << 11,
|
||||
WF_SCROLL2 = 1 << 13,
|
||||
};
|
||||
|
||||
|
||||
|
@ -453,7 +464,7 @@ int PositionMainToolbar(Window *w);
|
|||
/* widget.c */
|
||||
int GetWidgetFromPos(Window *w, int x, int y);
|
||||
void DrawWindowWidgets(Window *w);
|
||||
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask);
|
||||
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, bool remove_filtered_strings);
|
||||
|
||||
void HandleButtonClick(Window *w, byte widget);
|
||||
|
||||
|
|
Loading…
Reference in New Issue