mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-08 23:19:40 +00:00
(svn r6679) -Feature: [train build window] added filter for wagons, engines or both in the display
-Codechange: [train build window] to get rid of a really ugly hack, the train build list is now generated in one loop and stored in an array
This commit is contained in:
parent
5df4e234e0
commit
db66567799
@ -2557,6 +2557,12 @@ STR_8840_BUILD_NEW_TRAIN_VEHICLE :{BLACK}Build ne
|
||||
STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE :{BLACK}Drag train vehicle to here to sell it
|
||||
STR_8842_CENTER_MAIN_VIEW_ON_TRAIN :{BLACK}Centre main view on train depot location
|
||||
STR_8843_TRAIN_VEHICLE_SELECTION :{BLACK}Train vehicle selection list - click on vehicle for information
|
||||
STR_BLACK_ENGINES :{BLACK}Engines
|
||||
STR_BLACK_WAGONS :{BLACK}Wagons
|
||||
STR_BLACK_BOTH :{BLACK}Both
|
||||
STR_BUILD_TRAIN_ENGINES_TIP :{BLACK}Click to see engines only
|
||||
STR_BUILD_TRAIN_WAGONS_TIP :{BLACK}Click to see wagons only
|
||||
STR_BUILD_TRAIN_BOTH_TIP :{BLACK}Click to see both engines and wagons
|
||||
STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN :{BLACK}Build the highlighted train vehicle
|
||||
STR_8845_RENAME_TRAIN_VEHICLE_TYPE :{BLACK}Rename train vehicle type
|
||||
STR_8846_CURRENT_TRAIN_ACTION_CLICK :{BLACK}Current train action - click here to stop/start train
|
||||
|
237
train_gui.c
237
train_gui.c
@ -29,11 +29,29 @@ typedef enum BuildTrainWidgets {
|
||||
BUILD_TRAIN_WIDGET_LIST,
|
||||
BUILD_TRAIN_WIDGET_SCROLLBAR,
|
||||
BUILD_TRAIN_WIDGET_PANEL,
|
||||
BUILD_TRAIN_WIDGET_ENGINES,
|
||||
BUILD_TRAIN_WIDGET_WAGONS,
|
||||
BUILD_TRAIN_WIDGET_BOTH,
|
||||
BUILD_TRAIN_WIDGET_BUILD,
|
||||
BUILD_TRAIN_WIDGET_RENAME,
|
||||
BUILD_TRAIN_WIDGET_RESIZE,
|
||||
} BuildTrainWidget;
|
||||
|
||||
static const Widget _new_rail_vehicle_widgets[] = {
|
||||
{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, RESIZE_NONE, 14, 11, 227, 0, 13, STR_JUST_STRING, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 215, 14, 125, 0x801, STR_8843_TRAIN_VEHICLE_SELECTION},
|
||||
{ WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 216, 227, 14, 125, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_PANEL, RESIZE_TB, 14, 0, 227, 126, 197, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 76, 198, 209, STR_BLACK_ENGINES, STR_BUILD_TRAIN_ENGINES_TIP},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 77, 151, 198, 209, STR_BLACK_WAGONS, STR_BUILD_TRAIN_WAGONS_TIP},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 152, 227, 198, 209, STR_BLACK_BOTH, STR_BUILD_TRAIN_BOTH_TIP},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 107, 210, 221, STR_881F_BUILD_VEHICLE, STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 108, 215, 210, 221, STR_8820_RENAME, STR_8845_RENAME_TRAIN_VEHICLE_TYPE},
|
||||
{ WWT_RESIZEBOX, RESIZE_TB, 14, 216, 227, 210, 221, 0x0, STR_RESIZE_BUTTON},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw the purchase info details of train engine at a given location.
|
||||
@ -187,99 +205,170 @@ void CcCloneTrain(bool success, TileIndex tile, uint32 p1, uint32 p2)
|
||||
{
|
||||
if (success) ShowTrainViewWindow(GetVehicle(_new_vehicle_id));
|
||||
}
|
||||
|
||||
static void engine_drawing_loop(int *x, int *y, int *pos, int *sel,
|
||||
EngineID *selected_id, RailType railtype, byte show_max, bool is_engine)
|
||||
static void engine_drawing_loop(const EngineID *engines, const uint16 engine_count,
|
||||
const int x, int *y, const EngineID sel, EngineID *position, const int16 show_max)
|
||||
{
|
||||
for (; (*position) < min(engine_count, show_max); (*position)++) {
|
||||
EngineID i = engines[*position];
|
||||
|
||||
DrawString(x + 59, *y + 2, GetCustomEngineName(i), sel == i ? 0xC : 0x10);
|
||||
DrawTrainEngine(x + 29, *y + 6, i, GetEnginePalette(i, _local_player));
|
||||
*y += 14;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ExtendEngineListSize(const EngineID **engine_list, uint16 *engine_list_length, uint16 step_size)
|
||||
{
|
||||
*engine_list_length = min(*engine_list_length + step_size, NUM_TRAIN_ENGINES);
|
||||
*engine_list = realloc((void*)*engine_list, (*engine_list_length) * sizeof((*engine_list)[0]));
|
||||
}
|
||||
|
||||
static void GenerateBuildList(EngineID **engines, uint16 *num_engines, EngineID **wagons, uint16 *num_wagons, RailType railtype)
|
||||
{
|
||||
uint16 engine_length = *num_engines;
|
||||
uint16 wagon_length = *num_wagons;
|
||||
EngineID j;
|
||||
|
||||
(*num_engines) = 0;
|
||||
(*num_wagons) = 0;
|
||||
|
||||
if (engines == NULL) ExtendEngineListSize((const EngineID**)engines, &engine_length, 25);
|
||||
if (wagons == NULL) ExtendEngineListSize((const EngineID**)wagons, &wagon_length, 25);
|
||||
|
||||
for (j = 0; j < NUM_TRAIN_ENGINES; j++) {
|
||||
EngineID i = GetRailVehAtPosition(j);
|
||||
const Engine *e = GetEngine(i);
|
||||
const RailVehicleInfo *rvi = RailVehInfo(i);
|
||||
|
||||
if (!HasPowerOnRail(e->railtype, railtype) || !(rvi->flags & RVI_WAGON) != is_engine ||
|
||||
!HASBIT(e->player_avail, _local_player))
|
||||
continue;
|
||||
if (!HasPowerOnRail(e->railtype, railtype)) continue;
|
||||
if (!IsEngineBuildable(i, VEH_Train)) continue;
|
||||
|
||||
if (*sel == 0) *selected_id = i;
|
||||
|
||||
if (IS_INT_INSIDE(--*pos, -show_max, 0)) {
|
||||
DrawString(*x + 59, *y + 2, GetCustomEngineName(i), *sel == 0 ? 0xC : 0x10);
|
||||
DrawTrainEngine(*x + 29, *y + 6, i, GetEnginePalette(i, _local_player));
|
||||
*y += 14;
|
||||
if (rvi->flags & RVI_WAGON) {
|
||||
if (*num_wagons == wagon_length) ExtendEngineListSize((const EngineID**)wagons, &wagon_length, 5);
|
||||
(*wagons)[(*num_wagons)++] = i;
|
||||
} else {
|
||||
if (*num_engines == engine_length) ExtendEngineListSize((const EngineID**)engines, &engine_length, 5);
|
||||
(*engines)[(*num_engines)++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reduce array sizes if they are too big */
|
||||
if (*num_engines == engine_length) *engines = realloc((void*)*engines, (*num_engines) * sizeof((*engines)[0]));
|
||||
if (*num_wagons == wagon_length) *wagons = realloc((void*)*wagons, (*num_wagons) * sizeof((*wagons)[0]));
|
||||
}
|
||||
|
||||
static void DrawTrainBuildWindow(Window *w)
|
||||
{
|
||||
int x = 1;
|
||||
int y = 15;
|
||||
EngineID position = w->vscroll.pos;
|
||||
EngineID selected_id = WP(w,buildtrain_d).sel_engine;
|
||||
int max = w->vscroll.pos + w->vscroll.cap;
|
||||
uint16 scrollcount = 0;
|
||||
|
||||
SetWindowWidgetDisabledState(w, BUILD_TRAIN_WIDGET_BUILD, w->window_number == 0); // Disable unless we got a depot to build in
|
||||
|
||||
/* Draw the clicked engine/wagon/both button pressed and unpress the other two */
|
||||
SetWindowWidgetLoweredState(w, BUILD_TRAIN_WIDGET_ENGINES, WP(w,buildtrain_d).show_engine_wagon == 1);
|
||||
SetWindowWidgetLoweredState(w, BUILD_TRAIN_WIDGET_WAGONS, WP(w,buildtrain_d).show_engine_wagon == 2);
|
||||
SetWindowWidgetLoweredState(w, BUILD_TRAIN_WIDGET_BOTH, WP(w,buildtrain_d).show_engine_wagon == 3);
|
||||
|
||||
GenerateBuildList(&WP(w,buildtrain_d).engines, &WP(w,buildtrain_d).num_engines, &WP(w,buildtrain_d).wagons, &WP(w,buildtrain_d).num_wagons, WP(w,buildtrain_d).railtype);
|
||||
|
||||
if (HASBIT(WP(w,buildtrain_d).show_engine_wagon, 0)) scrollcount += WP(w,buildtrain_d).num_engines;
|
||||
if (HASBIT(WP(w,buildtrain_d).show_engine_wagon, 1)) scrollcount += WP(w,buildtrain_d).num_wagons;
|
||||
|
||||
SetVScrollCount(w, scrollcount);
|
||||
SetDParam(0, WP(w,buildtrain_d).railtype + STR_881C_NEW_RAIL_VEHICLES);
|
||||
DrawWindowWidgets(w);
|
||||
|
||||
if (selected_id == INVALID_ENGINE && scrollcount != 0) {
|
||||
if (HASBIT(WP(w,buildtrain_d).show_engine_wagon, 0) && WP(w,buildtrain_d).num_engines != 0) {
|
||||
selected_id = WP(w,buildtrain_d).engines[0];
|
||||
} else {
|
||||
selected_id = WP(w,buildtrain_d).wagons[0];
|
||||
}
|
||||
WP(w,buildtrain_d).sel_engine = selected_id;
|
||||
}
|
||||
|
||||
/* Draw the engines */
|
||||
if (HASBIT(WP(w,buildtrain_d).show_engine_wagon, 0)) {
|
||||
engine_drawing_loop(WP(w,buildtrain_d).engines, WP(w,buildtrain_d).num_engines, x, &y, selected_id, &position, max);
|
||||
|
||||
/* Magically set the number 0 line to the one right after the last engine
|
||||
* This way the line numbers fit the indexes in the wagon array */
|
||||
position -= WP(w,buildtrain_d).num_engines;
|
||||
max -= WP(w,buildtrain_d).num_engines;
|
||||
}
|
||||
|
||||
/* Draw the wagons */
|
||||
if (HASBIT(WP(w,buildtrain_d).show_engine_wagon, 1)) {
|
||||
engine_drawing_loop(WP(w,buildtrain_d).wagons, WP(w,buildtrain_d).num_wagons, x, &y, selected_id, &position, max);
|
||||
}
|
||||
|
||||
if (selected_id != INVALID_ENGINE) {
|
||||
const RailVehicleInfo *rvi = RailVehInfo(selected_id);
|
||||
|
||||
if (rvi->flags & RVI_WAGON) {
|
||||
DrawTrainWagonPurchaseInfo(2, w->widget[BUILD_TRAIN_WIDGET_PANEL].top + 1, selected_id);
|
||||
} else {
|
||||
DrawTrainEnginePurchaseInfo(2, w->widget[BUILD_TRAIN_WIDGET_PANEL].top + 1, selected_id);
|
||||
}
|
||||
--*sel;
|
||||
}
|
||||
}
|
||||
|
||||
static void NewRailVehicleWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
switch (e->event) {
|
||||
case WE_CREATE:
|
||||
WP(w,buildtrain_d).num_engines = 0;
|
||||
WP(w,buildtrain_d).num_wagons = 0;
|
||||
WP(w,buildtrain_d).engines = NULL;
|
||||
WP(w,buildtrain_d).wagons = NULL;
|
||||
WP(w,buildtrain_d).show_engine_wagon = 3;
|
||||
break;
|
||||
|
||||
case WE_DESTROY:
|
||||
free((void*)WP(w,buildtrain_d).engines);
|
||||
free((void*)WP(w,buildtrain_d).wagons);
|
||||
break;
|
||||
|
||||
case WE_PAINT:
|
||||
DrawTrainBuildWindow(w);
|
||||
break;
|
||||
|
||||
SetWindowWidgetDisabledState(w, BUILD_TRAIN_WIDGET_BUILD, w->window_number == 0);
|
||||
|
||||
{
|
||||
int count = 0;
|
||||
RailType railtype = WP(w,buildtrain_d).railtype;
|
||||
EngineID i;
|
||||
|
||||
for (i = 0; i < NUM_TRAIN_ENGINES; i++) {
|
||||
const Engine *e = GetEngine(i);
|
||||
if (HasPowerOnRail(e->railtype, railtype) &&
|
||||
HASBIT(e->player_avail, _local_player)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
SetVScrollCount(w, count);
|
||||
}
|
||||
|
||||
SetDParam(0, WP(w,buildtrain_d).railtype + STR_881C_NEW_RAIL_VEHICLES);
|
||||
DrawWindowWidgets(w);
|
||||
|
||||
{
|
||||
RailType railtype = WP(w,buildtrain_d).railtype;
|
||||
int sel = WP(w,buildtrain_d).sel_index;
|
||||
int pos = w->vscroll.pos;
|
||||
int x = 1;
|
||||
int y = 15;
|
||||
EngineID selected_id = INVALID_ENGINE;
|
||||
|
||||
/* 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!!! */
|
||||
engine_drawing_loop(&x, &y, &pos, &sel, &selected_id, railtype, w->vscroll.cap, true); // True engines
|
||||
engine_drawing_loop(&x, &y, &pos, &sel, &selected_id, railtype, w->vscroll.cap, false); // Feeble wagons
|
||||
|
||||
WP(w,buildtrain_d).sel_engine = selected_id;
|
||||
|
||||
if (selected_id != INVALID_ENGINE) {
|
||||
const RailVehicleInfo *rvi = RailVehInfo(selected_id);
|
||||
|
||||
if (!(rvi->flags & RVI_WAGON)) {
|
||||
/* it's an engine */
|
||||
DrawTrainEnginePurchaseInfo(2, w->widget[BUILD_TRAIN_WIDGET_PANEL].top + 1,selected_id);
|
||||
} else {
|
||||
/* it's a wagon */
|
||||
DrawTrainWagonPurchaseInfo(2, w->widget[BUILD_TRAIN_WIDGET_PANEL].top + 1, selected_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WE_CLICK: {
|
||||
switch (e->we.click.widget) {
|
||||
case BUILD_TRAIN_WIDGET_LIST: {
|
||||
uint i = (e->we.click.pt.y - 14) / 14;
|
||||
if (i < w->vscroll.cap) {
|
||||
WP(w,buildtrain_d).sel_index = i + w->vscroll.pos;
|
||||
uint i = ((e->we.click.pt.y - 14) / 14) + w->vscroll.pos;
|
||||
if (i < WP(w,buildtrain_d).num_engines + WP(w,buildtrain_d).num_wagons) {
|
||||
if (i < WP(w,buildtrain_d).num_engines && HASBIT(WP(w,buildtrain_d).show_engine_wagon, 0)) {
|
||||
WP(w,buildtrain_d).sel_engine = WP(w,buildtrain_d).engines[i];
|
||||
} else {
|
||||
WP(w,buildtrain_d).sel_engine = WP(w,buildtrain_d).wagons[i - (HASBIT(WP(w,buildtrain_d).show_engine_wagon, 0) ? WP(w,buildtrain_d).num_engines : 0)];
|
||||
}
|
||||
SetWindowDirty(w);
|
||||
}
|
||||
} break;
|
||||
|
||||
case BUILD_TRAIN_WIDGET_ENGINES:
|
||||
case BUILD_TRAIN_WIDGET_WAGONS:
|
||||
case BUILD_TRAIN_WIDGET_BOTH: {
|
||||
/* First we need to figure out the new show_engine_wagon setting
|
||||
* Because the button widgets are ordered as they are (in a row), we can calculate as following:
|
||||
* engines = bit 0 (1 for set), wagons bit 1 (2 for set), both (2 | 1 = 3)
|
||||
* Those numbers are the same as the clicked button - BUILD_TRAIN_WIDGET_ENGINES + 1 */
|
||||
|
||||
byte click_state = e->we.click.widget - BUILD_TRAIN_WIDGET_ENGINES + 1;
|
||||
if (WP(w,buildtrain_d).show_engine_wagon == click_state) break; // We clicked the pressed button
|
||||
WP(w,buildtrain_d).sel_engine = INVALID_ENGINE;
|
||||
WP(w,buildtrain_d).show_engine_wagon = click_state;
|
||||
w->vscroll.pos = 0;
|
||||
SetWindowDirty(w);
|
||||
}
|
||||
break;
|
||||
|
||||
case BUILD_TRAIN_WIDGET_BUILD: {
|
||||
EngineID sel_eng = WP(w,buildtrain_d).sel_engine;
|
||||
if (sel_eng != INVALID_ENGINE)
|
||||
@ -314,20 +403,8 @@ static void NewRailVehicleWndProc(Window *w, WindowEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _new_rail_vehicle_widgets[] = {
|
||||
{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, RESIZE_NONE, 14, 11, 227, 0, 13, STR_JUST_STRING, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_MATRIX, RESIZE_BOTTOM, 14, 0, 215, 14, 125, 0x801, STR_8843_TRAIN_VEHICLE_SELECTION},
|
||||
{ WWT_SCROLLBAR, RESIZE_BOTTOM, 14, 216, 227, 14, 125, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_PANEL, RESIZE_TB, 14, 0, 227, 126, 197, 0x0, STR_NULL},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 107, 198, 209, STR_881F_BUILD_VEHICLE, STR_8844_BUILD_THE_HIGHLIGHTED_TRAIN},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 108, 215, 198, 209, STR_8820_RENAME, STR_8845_RENAME_TRAIN_VEHICLE_TYPE},
|
||||
{ WWT_RESIZEBOX, RESIZE_TB, 14, 216, 227, 198, 209, 0x0, STR_RESIZE_BUTTON},
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
static const WindowDesc _new_rail_vehicle_desc = {
|
||||
-1, -1, 228, 210,
|
||||
-1, -1, 228, 222,
|
||||
WC_BUILD_VEHICLE,0,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_RESIZABLE,
|
||||
_new_rail_vehicle_widgets,
|
||||
|
5
window.h
5
window.h
@ -393,8 +393,13 @@ assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tooltips_d));
|
||||
typedef struct {
|
||||
byte railtype;
|
||||
byte sel_index;
|
||||
byte show_engine_wagon;
|
||||
EngineID sel_engine;
|
||||
EngineID rename_engine;
|
||||
EngineID *engines;
|
||||
EngineID *wagons;
|
||||
uint16 num_engines;
|
||||
uint16 num_wagons;
|
||||
} buildtrain_d;
|
||||
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(buildtrain_d));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user