diff --git a/newgrf.c b/newgrf.c index 109ab68e2c..c8f2798d49 100644 --- a/newgrf.c +++ b/newgrf.c @@ -365,6 +365,18 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf rvi[i].engclass = engclass; } } break; + case 0x1A: // Alter purchase list sort order. + FOR_EACH_OBJECT { + EngineID pos = grf_load_byte(&buf); + + if (pos < NUM_TRAIN_ENGINES) { + AlterRailVehListOrder(engine + i, pos); + } else { + grfmsg(GMS_NOTICE, "RailVehicleChangeInfo: Invalid train engine ID %d, ignoring.", pos); + } + } + break; + case 0x1B: { /* Powered wagons power bonus */ FOR_EACH_OBJECT { uint16 wag_power = grf_load_word(&buf); @@ -431,7 +443,6 @@ static bool RailVehicleChangeInfo(uint engine, int numinfo, int prop, byte **buf } break; /* TODO */ /* Fall-through for unimplemented one byte long properties. */ - case 0x1A: /* Sort order */ case 0x1C: /* Refit cost */ case 0x1F: /* Tractive effort */ case 0x20: /* Air drag */ @@ -2499,6 +2510,7 @@ static void ResetNewGRFData(void) UnloadWagonOverrides(); UnloadCustomEngineSprites(); UnloadCustomEngineNames(); + ResetEngineListOrder(); // Reset price base data ResetPriceBaseMultipliers(); diff --git a/newgrf_engine.c b/newgrf_engine.c index 8270142257..ebaa15c1d7 100644 --- a/newgrf_engine.c +++ b/newgrf_engine.c @@ -591,3 +591,44 @@ StringID GetCustomEngineName(EngineID engine) return STR_SPEC_USERSTRING; } +// Functions for changing the order of vehicle purchase lists +// This is currently only implemented for rail vehicles. +static EngineID engine_list_order[NUM_TRAIN_ENGINES]; + +void ResetEngineListOrder(void) +{ + EngineID i; + + for (i = 0; i < NUM_TRAIN_ENGINES; i++) + engine_list_order[i] = i; +} + +EngineID GetRailVehAtPosition(EngineID pos) +{ + return engine_list_order[pos]; +} + +void AlterRailVehListOrder(EngineID engine, EngineID target) +{ + EngineID i; + bool moving = false; + + if (engine == target) return; + + // First, remove our ID from the list. + for (i = 0; i < NUM_TRAIN_ENGINES - 1; i++) { + if (engine_list_order[i] == engine) + moving = true; + if (moving) + engine_list_order[i] = engine_list_order[i + 1]; + } + + // Now, insert it again, before the target engine. + for (i = NUM_TRAIN_ENGINES - 1; i > 0; i--) { + engine_list_order[i] = engine_list_order[i - 1]; + if (engine_list_order[i] == target) { + engine_list_order[i - 1] = engine; + break; + } + } +} diff --git a/newgrf_engine.h b/newgrf_engine.h index 1812bff9b4..5eca617ea5 100644 --- a/newgrf_engine.h +++ b/newgrf_engine.h @@ -70,4 +70,8 @@ void UnloadWagonOverrides(void); void UnloadCustomEngineSprites(void); void UnloadCustomEngineNames(void); +void ResetEngineListOrder(void); +EngineID GetRailVehAtPosition(EngineID pos); +void AlterRailVehListOrder(EngineID engine, EngineID target); + #endif /* NEWGRF_ENGINE_H */ diff --git a/train_gui.c b/train_gui.c index f71339092b..ede95848cc 100644 --- a/train_gui.c +++ b/train_gui.c @@ -170,9 +170,10 @@ void CcCloneTrain(bool success, uint tile, uint32 p1, uint32 p2) static void engine_drawing_loop(int *x, int *y, int *pos, int *sel, EngineID* selected_id, RailType railtype, byte show_max, bool is_engine) { - EngineID i; + EngineID j; - for (i = 0; i < NUM_TRAIN_ENGINES; i++) { + for (j = 0; j < NUM_TRAIN_ENGINES; j++) { + EngineID i = GetRailVehAtPosition(j); const Engine *e = GetEngine(i); const RailVehicleInfo *rvi = RailVehInfo(i); diff --git a/vehicle_gui.c b/vehicle_gui.c index 0b2f773878..4072873987 100644 --- a/vehicle_gui.c +++ b/vehicle_gui.c @@ -453,11 +453,12 @@ static int CDECL VehicleValueSorter(const void *a, const void *b) static void train_engine_drawing_loop(int *x, int *y, int *pos, int *sel, EngineID *selected_id, RailType railtype, uint8 lines_drawn, bool is_engine, bool show_cars, bool show_outdated) { - EngineID i; + EngineID j; byte colour; const Player *p = GetPlayer(_local_player); - for (i = 0; i < NUM_TRAIN_ENGINES; i++) { + for (j = 0; j < NUM_TRAIN_ENGINES; j++) { + EngineID i = GetRailVehAtPosition(j); const Engine *e = GetEngine(i); const RailVehicleInfo *rvi = RailVehInfo(i); const EngineInfo *info = &_engine_info[i]; @@ -467,7 +468,7 @@ static void train_engine_drawing_loop(int *x, int *y, int *pos, int *sel, Engine if ((rvi->power == 0 && !show_cars) || (rvi->power != 0 && show_cars)) // show wagons or engines (works since wagons do not have power) continue; - if (*sel == 0) *selected_id = i; + if (*sel == 0) *selected_id = j; colour = *sel == 0 ? 0xC : 0x10; @@ -513,10 +514,12 @@ static void SetupScrollStuffForReplaceWindow(Window *w) switch (WP(w,replaceveh_d).vehicletype) { case VEH_Train: { + EngineID i; railtype = _railtype_selected_in_replace_gui; w->widget[13].color = _player_colors[_local_player]; // sets the colour of that art thing w->widget[16].color = _player_colors[_local_player]; // sets the colour of that art thing - for (engine_id = 0; engine_id < NUM_TRAIN_ENGINES; engine_id++) { + for (i = 0; i < NUM_TRAIN_ENGINES; i++) { + EngineID engine_id = GetRailVehAtPosition(i); const Engine *e = GetEngine(engine_id); const EngineInfo *info = &_engine_info[engine_id];