Merge branch 'tracerestrict-sx' into jgrpp
# Conflicts: # src/command.cpp # src/group_gui.cpp # src/lang/english.txt # src/saveload/extended_ver_sl.cpp # src/settings_gui.cpp # src/tracerestrict.cpp # src/tracerestrict.h # src/tracerestrict_gui.cpp # src/vehicle_gui.cpp # src/vehicle_gui_base.h # src/vehiclelist.cpp # src/window_type.h
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
#include "autoreplace_func.h"
|
#include "autoreplace_func.h"
|
||||||
#include "autoreplace_gui.h"
|
#include "autoreplace_gui.h"
|
||||||
#include "articulated_vehicles.h"
|
#include "articulated_vehicles.h"
|
||||||
|
#include "tracerestrict.h"
|
||||||
#include "core/random_func.hpp"
|
#include "core/random_func.hpp"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
@@ -567,6 +568,11 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
|||||||
/* Success ! */
|
/* Success ! */
|
||||||
if ((flags & DC_EXEC) != 0 && new_head != old_head) {
|
if ((flags & DC_EXEC) != 0 && new_head != old_head) {
|
||||||
*chain = new_head;
|
*chain = new_head;
|
||||||
|
if (HasBit(Train::From(old_head)->flags, VRF_HAVE_SLOT)) {
|
||||||
|
TraceRestrictTransferVehicleOccupantInAllSlots(old_head->index, new_head->index);
|
||||||
|
ClrBit(Train::From(old_head)->flags, VRF_HAVE_SLOT);
|
||||||
|
SetBit(Train::From(new_head)->flags, VRF_HAVE_SLOT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transfer cargo of old vehicles and sell them */
|
/* Transfer cargo of old vehicles and sell them */
|
||||||
|
@@ -228,6 +228,11 @@ CommandProc CmdSetTimetableStart;
|
|||||||
CommandProc CmdOpenCloseAirport;
|
CommandProc CmdOpenCloseAirport;
|
||||||
|
|
||||||
CommandProc CmdProgramSignalTraceRestrict;
|
CommandProc CmdProgramSignalTraceRestrict;
|
||||||
|
CommandProc CmdCreateTraceRestrictSlot;
|
||||||
|
CommandProc CmdAlterTraceRestrictSlot;
|
||||||
|
CommandProc CmdDeleteTraceRestrictSlot;
|
||||||
|
CommandProc CmdAddVehicleTraceRestrictSlot;
|
||||||
|
CommandProc CmdRemoveVehicleTraceRestrictSlot;
|
||||||
|
|
||||||
CommandProc CmdInsertSignalInstruction;
|
CommandProc CmdInsertSignalInstruction;
|
||||||
CommandProc CmdModifySignalInstruction;
|
CommandProc CmdModifySignalInstruction;
|
||||||
@@ -427,6 +432,11 @@ static const Command _command_proc_table[] = {
|
|||||||
DEF_CMD(CmdOpenCloseAirport, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_OPEN_CLOSE_AIRPORT
|
DEF_CMD(CmdOpenCloseAirport, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_OPEN_CLOSE_AIRPORT
|
||||||
|
|
||||||
DEF_CMD(CmdProgramSignalTraceRestrict, 0, CMDT_OTHER_MANAGEMENT ), // CMD_PROGRAM_TRACERESTRICT_SIGNAL
|
DEF_CMD(CmdProgramSignalTraceRestrict, 0, CMDT_OTHER_MANAGEMENT ), // CMD_PROGRAM_TRACERESTRICT_SIGNAL
|
||||||
|
DEF_CMD(CmdCreateTraceRestrictSlot, 0, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_TRACERESTRICT_SLOT
|
||||||
|
DEF_CMD(CmdAlterTraceRestrictSlot, 0, CMDT_OTHER_MANAGEMENT ), // CMD_ALTER_TRACERESTRICT_SLOT
|
||||||
|
DEF_CMD(CmdDeleteTraceRestrictSlot, 0, CMDT_OTHER_MANAGEMENT ), // CMD_DELETE_TRACERESTRICT_SLOT
|
||||||
|
DEF_CMD(CmdAddVehicleTraceRestrictSlot, 0, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_VEHICLE_TRACERESTRICT_SLOT
|
||||||
|
DEF_CMD(CmdRemoveVehicleTraceRestrictSlot, 0, CMDT_OTHER_MANAGEMENT ), // CMD_REMOVE_VEHICLE_TRACERESTRICT_SLOT
|
||||||
|
|
||||||
DEF_CMD(CmdInsertSignalInstruction, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_INSERT_SIGNAL_INSTRUCTION
|
DEF_CMD(CmdInsertSignalInstruction, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_INSERT_SIGNAL_INSTRUCTION
|
||||||
DEF_CMD(CmdModifySignalInstruction, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_MODIFY_SIGNAL_INSTRUCTION
|
DEF_CMD(CmdModifySignalInstruction, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_MODIFY_SIGNAL_INSTRUCTION
|
||||||
|
@@ -371,6 +371,11 @@ enum Commands {
|
|||||||
CMD_OPEN_CLOSE_AIRPORT, ///< open/close an airport to incoming aircraft
|
CMD_OPEN_CLOSE_AIRPORT, ///< open/close an airport to incoming aircraft
|
||||||
|
|
||||||
CMD_PROGRAM_TRACERESTRICT_SIGNAL, ///< modify a signal tracerestrict program
|
CMD_PROGRAM_TRACERESTRICT_SIGNAL, ///< modify a signal tracerestrict program
|
||||||
|
CMD_CREATE_TRACERESTRICT_SLOT, ///< create a tracerestrict slot
|
||||||
|
CMD_ALTER_TRACERESTRICT_SLOT, ///< alter a tracerestrict slot
|
||||||
|
CMD_DELETE_TRACERESTRICT_SLOT, ///< delete a tracerestrict slot
|
||||||
|
CMD_ADD_VEHICLE_TRACERESTRICT_SLOT, ///< add a vehicle to a tracerestrict slot
|
||||||
|
CMD_REMOVE_VEHICLE_TRACERESTRICT_SLOT, ///< remove a vehicle from a tracerestrict slot
|
||||||
|
|
||||||
CMD_INSERT_SIGNAL_INSTRUCTION, ///< insert a signal instruction
|
CMD_INSERT_SIGNAL_INSTRUCTION, ///< insert a signal instruction
|
||||||
CMD_MODIFY_SIGNAL_INSTRUCTION, ///< modifies a signal instruction
|
CMD_MODIFY_SIGNAL_INSTRUCTION, ///< modifies a signal instruction
|
||||||
|
@@ -531,16 +531,16 @@ public:
|
|||||||
this->vscroll->SetCount(this->vehicles.Length());
|
this->vscroll->SetCount(this->vehicles.Length());
|
||||||
|
|
||||||
/* The drop down menu is out, *but* it may not be used, retract it. */
|
/* The drop down menu is out, *but* it may not be used, retract it. */
|
||||||
if (this->vehicles.Length() == 0 && this->IsWidgetLowered(WID_GL_MANAGE_VEHICLES_DROPDOWN)) {
|
if (!this->ShouldShowActionDropdownList() && this->IsWidgetLowered(WID_GL_MANAGE_VEHICLES_DROPDOWN)) {
|
||||||
this->RaiseWidget(WID_GL_MANAGE_VEHICLES_DROPDOWN);
|
this->RaiseWidget(WID_GL_MANAGE_VEHICLES_DROPDOWN);
|
||||||
HideDropDownMenu(this);
|
HideDropDownMenu(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable all lists management button when the list is empty */
|
/* Disable all lists management button when the list is empty */
|
||||||
|
this->SetWidgetDisabledState(WID_GL_MANAGE_VEHICLES_DROPDOWN, !this->ShouldShowActionDropdownList() || _local_company != this->vli.company);
|
||||||
this->SetWidgetsDisabledState(this->vehicles.Length() == 0 || _local_company != this->vli.company,
|
this->SetWidgetsDisabledState(this->vehicles.Length() == 0 || _local_company != this->vli.company,
|
||||||
WID_GL_STOP_ALL,
|
WID_GL_STOP_ALL,
|
||||||
WID_GL_START_ALL,
|
WID_GL_START_ALL,
|
||||||
WID_GL_MANAGE_VEHICLES_DROPDOWN,
|
|
||||||
WIDGET_LIST_END);
|
WIDGET_LIST_END);
|
||||||
|
|
||||||
/* Disable the group specific function when we select the default group or all vehicles */
|
/* Disable the group specific function when we select the default group or all vehicles */
|
||||||
@@ -802,7 +802,7 @@ public:
|
|||||||
|
|
||||||
case WID_GL_MANAGE_VEHICLES_DROPDOWN: {
|
case WID_GL_MANAGE_VEHICLES_DROPDOWN: {
|
||||||
DropDownList *list = this->BuildActionDropdownList(true, Group::IsValidID(this->vli.index), this->vli.vtype == VEH_TRAIN);
|
DropDownList *list = this->BuildActionDropdownList(true, Group::IsValidID(this->vli.index), this->vli.vtype == VEH_TRAIN);
|
||||||
ShowDropDownList(this, list, 0, WID_GL_MANAGE_VEHICLES_DROPDOWN);
|
ShowDropDownList(this, list, -1, WID_GL_MANAGE_VEHICLES_DROPDOWN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -928,7 +928,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WID_GL_MANAGE_VEHICLES_DROPDOWN:
|
case WID_GL_MANAGE_VEHICLES_DROPDOWN:
|
||||||
assert(this->vehicles.Length() != 0);
|
assert(this->ShouldShowActionDropdownList());
|
||||||
|
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case ADI_TEMPLATE_REPLACE: // TemplateReplace Window
|
case ADI_TEMPLATE_REPLACE: // TemplateReplace Window
|
||||||
@@ -955,6 +955,13 @@ public:
|
|||||||
|
|
||||||
DoCommandP(0, this->vli.index, 0, CMD_REMOVE_ALL_VEHICLES_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES));
|
DoCommandP(0, this->vli.index, 0, CMD_REMOVE_ALL_VEHICLES_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ADI_TRACERESTRICT_SLOT_MGMT: {
|
||||||
|
extern void ShowTraceRestrictSlotWindow(CompanyID company);
|
||||||
|
ShowTraceRestrictSlotWindow(this->owner);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -1314,6 +1314,8 @@ STR_CONFIG_SETTING_SHOW_TRAIN_WEIGHT_RATIOS_IN_DETAILS :Show train weig
|
|||||||
STR_CONFIG_SETTING_SHOW_TRAIN_WEIGHT_RATIOS_IN_DETAILS_HELPTEXT :Show train weight ratios in the vehicle details window
|
STR_CONFIG_SETTING_SHOW_TRAIN_WEIGHT_RATIOS_IN_DETAILS_HELPTEXT :Show train weight ratios in the vehicle details window
|
||||||
STR_CONFIG_SETTING_SHOW_RESTRICTED_SIG_DEF :Show restricted electric signals using default graphics: {STRING2}
|
STR_CONFIG_SETTING_SHOW_RESTRICTED_SIG_DEF :Show restricted electric signals using default graphics: {STRING2}
|
||||||
STR_CONFIG_SETTING_SHOW_RESTRICTED_SIG_DEF_HELPTEXT :Show electric signals with routing restriction programs using the default signal graphics with a blue signal post, instead of using any NewGRF signal graphics. This is to make it easier to visually distinguish restricted signals.
|
STR_CONFIG_SETTING_SHOW_RESTRICTED_SIG_DEF_HELPTEXT :Show electric signals with routing restriction programs using the default signal graphics with a blue signal post, instead of using any NewGRF signal graphics. This is to make it easier to visually distinguish restricted signals.
|
||||||
|
STR_CONFIG_SETTING_SHOW_ADV_TRACE_RESTRICT_FEATURES :Show advanced routing restriction features: {STRING2}
|
||||||
|
STR_CONFIG_SETTING_SHOW_ADV_TRACE_RESTRICT_FEATURES_HELPTEXT :Show advanced routing restriction features. When disabled, some advanced features are not shown in the UI, but are still available to all players.
|
||||||
|
|
||||||
STR_CONFIG_SETTING_LANDSCAPE :Landscape: {STRING2}
|
STR_CONFIG_SETTING_LANDSCAPE :Landscape: {STRING2}
|
||||||
STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landscapes define basic gameplay scenarios with different cargos and town growth requirements. NewGRF and Game Scripts allow finer control though
|
STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landscapes define basic gameplay scenarios with different cargos and town growth requirements. NewGRF and Game Scripts allow finer control though
|
||||||
@@ -2554,6 +2556,7 @@ STR_TRACE_RESTRICT_VARIABLE_ENTRY_DIRECTION :entry direction
|
|||||||
STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL :PBS entry signal
|
STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL :PBS entry signal
|
||||||
STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL_LONG :entered signal of PBS block
|
STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL_LONG :entered signal of PBS block
|
||||||
STR_TRACE_RESTRICT_VARIABLE_TRAIN_GROUP :train group
|
STR_TRACE_RESTRICT_VARIABLE_TRAIN_GROUP :train group
|
||||||
|
STR_TRACE_RESTRICT_VARIABLE_TRAIN_SLOT :slot
|
||||||
STR_TRACE_RESTRICT_VARIABLE_TRAIN_WEIGHT :weight
|
STR_TRACE_RESTRICT_VARIABLE_TRAIN_WEIGHT :weight
|
||||||
STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER :power
|
STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER :power
|
||||||
STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE :max T.E.
|
STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE :max T.E.
|
||||||
@@ -2579,6 +2582,8 @@ STR_TRACE_RESTRICT_CONDITIONAL_TILE_INDEX :{STRING} {STRIN
|
|||||||
STR_TRACE_RESTRICT_CONDITIONAL_GROUP :{STRING} train {STRING} in group: {GROUP} then
|
STR_TRACE_RESTRICT_CONDITIONAL_GROUP :{STRING} train {STRING} in group: {GROUP} then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_GROUP_STR :{STRING} train {STRING} in group: {STRING} {BLACK}{STRING}then
|
STR_TRACE_RESTRICT_CONDITIONAL_GROUP_STR :{STRING} train {STRING} in group: {STRING} {BLACK}{STRING}then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_OWNER :{STRING} {STRING} {STRING} {COMPANY} {COMPANY_NUM} then
|
STR_TRACE_RESTRICT_CONDITIONAL_OWNER :{STRING} {STRING} {STRING} {COMPANY} {COMPANY_NUM} then
|
||||||
|
STR_TRACE_RESTRICT_CONDITIONAL_SLOT :{STRING} train {STRING} in slot: {TRSLOT} then
|
||||||
|
STR_TRACE_RESTRICT_CONDITIONAL_SLOT_STR :{STRING} train {STRING} in slot: {STRING} {BLACK}{STRING}then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_UNDEFINED :{STRING} {STRING} {STRING} {RED}undefined {BLACK}{STRING}then
|
STR_TRACE_RESTRICT_CONDITIONAL_UNDEFINED :{STRING} {STRING} {STRING} {RED}undefined {BLACK}{STRING}then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_UNDEFINED :{STRING} {RED}undefined {BLACK}{STRING}then
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_UNDEFINED :{STRING} {RED}undefined {BLACK}{STRING}then
|
||||||
STR_TRACE_RESTRICT_PF_PENALTY_ITEM :Add pathfinder penalty: {COMMA}
|
STR_TRACE_RESTRICT_PF_PENALTY_ITEM :Add pathfinder penalty: {COMMA}
|
||||||
@@ -2593,6 +2598,8 @@ STR_TRACE_RESTRICT_RESERVE_THROUGH :Reserve through
|
|||||||
STR_TRACE_RESTRICT_RESERVE_THROUGH_CANCEL :Cancel reserve through
|
STR_TRACE_RESTRICT_RESERVE_THROUGH_CANCEL :Cancel reserve through
|
||||||
STR_TRACE_RESTRICT_LONG_RESERVE :Long reserve
|
STR_TRACE_RESTRICT_LONG_RESERVE :Long reserve
|
||||||
STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL :Cancel long reserve
|
STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL :Cancel long reserve
|
||||||
|
STR_TRACE_RESTRICT_WAIT_AT_PBS :Wait at PBS signal
|
||||||
|
STR_TRACE_RESTRICT_WAIT_AT_PBS_CANCEL :Cancel wait at PBS signal
|
||||||
STR_TRACE_RESTRICT_PF_PENALTY :Penalty
|
STR_TRACE_RESTRICT_PF_PENALTY :Penalty
|
||||||
STR_TRACE_RESTRICT_PF_VALUE_SMALL :small
|
STR_TRACE_RESTRICT_PF_VALUE_SMALL :small
|
||||||
STR_TRACE_RESTRICT_PF_VALUE_MEDIUM :medium
|
STR_TRACE_RESTRICT_PF_VALUE_MEDIUM :medium
|
||||||
@@ -2606,6 +2613,18 @@ STR_TRACE_RESTRICT_DIRECTION_SW :south-west
|
|||||||
STR_TRACE_RESTRICT_DIRECTION_NW :north-west
|
STR_TRACE_RESTRICT_DIRECTION_NW :north-west
|
||||||
STR_TRACE_RESTRICT_COMPANY :Company
|
STR_TRACE_RESTRICT_COMPANY :Company
|
||||||
STR_TRACE_RESTRICT_UNDEFINED_COMPANY :Undefined company
|
STR_TRACE_RESTRICT_UNDEFINED_COMPANY :Undefined company
|
||||||
|
STR_TRACE_RESTRICT_SLOT_OP :Slot operation
|
||||||
|
STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT :Acquire or wait
|
||||||
|
STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE :Try to acquire
|
||||||
|
STR_TRACE_RESTRICT_SLOT_RELEASE_FRONT :Release (front)
|
||||||
|
STR_TRACE_RESTRICT_SLOT_RELEASE_BACK :Release (back)
|
||||||
|
STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT_ITEM :Acquire slot: {STRING1}{BLACK}{STRING}, or wait at PBS signal
|
||||||
|
STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE_ITEM :Try to acquire slot: {STRING1}{BLACK}{STRING}, or continue anyway
|
||||||
|
STR_TRACE_RESTRICT_SLOT_RELEASE_FRONT_ITEM :Release slot: {STRING1}{BLACK}{STRING} (front of train)
|
||||||
|
STR_TRACE_RESTRICT_SLOT_RELEASE_BACK_ITEM :Release slot: {STRING1}{BLACK}{STRING} (back of train)
|
||||||
|
STR_TRACE_RESTRICT_SLOT_NAME :{TRSLOT}
|
||||||
|
STR_TRACE_RESTRICT_SLOT_LIST_HEADER :{BLACK}Slot{CONSUME_ARG}{P "" s}: {LTBLUE}
|
||||||
|
STR_TRACE_RESTRICT_SLOT_LIST_SEPARATOR :{BLACK}, {LTBLUE}
|
||||||
STR_TRACE_RESTRICT_VALUE_CAPTION :{WHITE}Value
|
STR_TRACE_RESTRICT_VALUE_CAPTION :{WHITE}Value
|
||||||
STR_TRACE_RESTRICT_CAPTION :{WHITE}Routefinding restriction
|
STR_TRACE_RESTRICT_CAPTION :{WHITE}Routefinding restriction
|
||||||
STR_TRACE_RESTRICT_CAPTION_SHARED :{WHITE}Routefinding restriction - shared by {COMMA} signals
|
STR_TRACE_RESTRICT_CAPTION_SHARED :{WHITE}Routefinding restriction - shared by {COMMA} signals
|
||||||
@@ -2616,6 +2635,20 @@ STR_TRACE_RESTRICT_COND_COMPARATOR_TOOLTIP :{BLACK}Comparis
|
|||||||
STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP :{BLACK}Value
|
STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP :{BLACK}Value
|
||||||
STR_TRACE_RESTRICT_CONDFLAGS_TOOLTIP :{BLACK}Condition type
|
STR_TRACE_RESTRICT_CONDFLAGS_TOOLTIP :{BLACK}Condition type
|
||||||
STR_TRACE_RESTRICT_GOTO_SIGNAL_TOOLTIP :{BLACK}Go to signal
|
STR_TRACE_RESTRICT_GOTO_SIGNAL_TOOLTIP :{BLACK}Go to signal
|
||||||
|
STR_TRACE_RESTRICT_SLOT_OP_TOOLTIP :{BLACK}Slot operation type
|
||||||
|
STR_TRACE_RESTRICT_SLOT_GUI_LIST_TOOLTIP :{BLACK}Slots - click on a slot to list all vehicles of this slot.
|
||||||
|
STR_TRACE_RESTRICT_SLOT_CREATE_TOOLTIP :{BLACK}Click to create a slot
|
||||||
|
STR_TRACE_RESTRICT_SLOT_DELETE_TOOLTIP :{BLACK}Delete the selected slot
|
||||||
|
STR_TRACE_RESTRICT_SLOT_RENAME_TOOLTIP :{BLACK}Rename the selected slot
|
||||||
|
STR_TRACE_RESTRICT_SLOT_SET_MAX_OCCUPANCY_TOOLTIP :{BLACK}Set the maximum occupancy of the selected slot
|
||||||
|
STR_TRACE_RESTRICT_SLOT_CAPTION :{WHITE}Routing Restrictions - Slot Management
|
||||||
|
STR_TRACE_RESTRICT_SLOT_MANAGE :Manage slots
|
||||||
|
STR_TRACE_RESTRICT_SLOT_MAX_OCCUPANCY :{TINY_FONT}{COMMA} / {COMMA}
|
||||||
|
STR_TRACE_RESTRICT_SLOT_RENAME_CAPTION :{BLACK}Rename a slot
|
||||||
|
STR_TRACE_RESTRICT_SLOT_CREATE_CAPTION :{BLACK}Create a slot
|
||||||
|
STR_TRACE_RESTRICT_SLOT_SET_MAX_OCCUPANCY_CAPTION :{BLACK}Set maximum occupancy of a slot
|
||||||
|
STR_TRACE_RESTRICT_SLOT_QUERY_DELETE_CAPTION :{WHITE}Delete Slot
|
||||||
|
STR_TRACE_RESTRICT_SLOT_DELETE_QUERY_TEXT :{WHITE}Are you sure you want to delete this slot?
|
||||||
STR_TRACE_RESTRICT_INSERT :{BLACK}Insert
|
STR_TRACE_RESTRICT_INSERT :{BLACK}Insert
|
||||||
STR_TRACE_RESTRICT_REMOVE :{BLACK}Remove
|
STR_TRACE_RESTRICT_REMOVE :{BLACK}Remove
|
||||||
STR_TRACE_RESTRICT_RESET :{BLACK}Reset
|
STR_TRACE_RESTRICT_RESET :{BLACK}Reset
|
||||||
@@ -2652,6 +2685,12 @@ STR_TRACE_RESTRICT_ERROR_CAN_T_RESET_SIGNAL :{WHITE}Can't re
|
|||||||
STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_PROGRAM :{WHITE}Can't copy program
|
STR_TRACE_RESTRICT_ERROR_CAN_T_COPY_PROGRAM :{WHITE}Can't copy program
|
||||||
STR_TRACE_RESTRICT_ERROR_CAN_T_SHARE_PROGRAM :{WHITE}Can't share program
|
STR_TRACE_RESTRICT_ERROR_CAN_T_SHARE_PROGRAM :{WHITE}Can't share program
|
||||||
STR_TRACE_RESTRICT_ERROR_CAN_T_UNSHARE_PROGRAM :{WHITE}Can't unshare program
|
STR_TRACE_RESTRICT_ERROR_CAN_T_UNSHARE_PROGRAM :{WHITE}Can't unshare program
|
||||||
|
STR_TRACE_RESTRICT_ERROR_SLOT_CAN_T_CREATE :{WHITE}Can't create slot...
|
||||||
|
STR_TRACE_RESTRICT_ERROR_SLOT_CAN_T_DELETE :{WHITE}Can't delete this slot...
|
||||||
|
STR_TRACE_RESTRICT_ERROR_SLOT_CAN_T_RENAME :{WHITE}Can't rename slot...
|
||||||
|
STR_TRACE_RESTRICT_ERROR_SLOT_CAN_T_ADD_VEHICLE :{WHITE}Can't add the vehicle to this slot...
|
||||||
|
STR_TRACE_RESTRICT_ERROR_SLOT_CAN_T_REMOVE_VEHICLE :{WHITE}Can't remove the vehicle from this slot...
|
||||||
|
STR_TRACE_RESTRICT_ERROR_SLOT_CAN_T_SET_MAX_OCCUPANCY :{WHITE}Can't set maximum occupancy of this slot...
|
||||||
|
|
||||||
# Programmable Signals
|
# Programmable Signals
|
||||||
STR_PROGRAM_SIGNAL_TOOLTIP :{BLACK}Program signal
|
STR_PROGRAM_SIGNAL_TOOLTIP :{BLACK}Program signal
|
||||||
@@ -4161,6 +4200,7 @@ STR_VEHICLE_STATUS_BROKEN_DOWN_VEL_SHORT :{RED}Broken dow
|
|||||||
STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL :{RED}Stopping, {VELOCITY}
|
STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL :{RED}Stopping, {VELOCITY}
|
||||||
STR_VEHICLE_STATUS_TRAIN_NO_POWER :{RED}No power
|
STR_VEHICLE_STATUS_TRAIN_NO_POWER :{RED}No power
|
||||||
STR_VEHICLE_STATUS_TRAIN_STUCK :{ORANGE}Waiting for free path
|
STR_VEHICLE_STATUS_TRAIN_STUCK :{ORANGE}Waiting for free path
|
||||||
|
STR_VEHICLE_STATUS_TRAIN_STUCK_WAIT_RESTRICTION :{ORANGE}Waiting due to routing restriction
|
||||||
STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR :{ORANGE}Too far to next destination
|
STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR :{ORANGE}Too far to next destination
|
||||||
|
|
||||||
STR_BREAKDOWN_TYPE_CRITICAL :Mechanical failure
|
STR_BREAKDOWN_TYPE_CRITICAL :Mechanical failure
|
||||||
|
@@ -47,7 +47,7 @@ std::vector<uint32> _sl_xv_discardable_chunk_ids; ///< list of chunks
|
|||||||
static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version os SLXI chunk
|
static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version os SLXI chunk
|
||||||
|
|
||||||
const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||||
{ XSLFI_TRACE_RESTRICT, XSCF_NULL, 6, 6, "tracerestrict", NULL, NULL, "TRRM,TRRP" },
|
{ XSLFI_TRACE_RESTRICT, XSCF_NULL, 7, 7, "tracerestrict", NULL, NULL, "TRRM,TRRP,TRRS" },
|
||||||
{ XSLFI_TRACE_RESTRICT_OWNER, XSCF_NULL, 1, 1, "tracerestrict_owner", NULL, NULL, NULL },
|
{ XSLFI_TRACE_RESTRICT_OWNER, XSCF_NULL, 1, 1, "tracerestrict_owner", NULL, NULL, NULL },
|
||||||
{ XSLFI_PROG_SIGS, XSCF_NULL, 1, 1, "programmable_signals", NULL, NULL, "SPRG" },
|
{ XSLFI_PROG_SIGS, XSCF_NULL, 1, 1, "programmable_signals", NULL, NULL, "SPRG" },
|
||||||
{ XSLFI_ADJACENT_CROSSINGS, XSCF_NULL, 1, 1, "adjacent_crossings", NULL, NULL, NULL },
|
{ XSLFI_ADJACENT_CROSSINGS, XSCF_NULL, 1, 1, "adjacent_crossings", NULL, NULL, NULL },
|
||||||
@@ -178,6 +178,12 @@ void SlXvCheckSpecialSavegameVersions()
|
|||||||
_sl_is_faked_ext = true;
|
_sl_is_faked_ext = true;
|
||||||
_sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 6;
|
_sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 6;
|
||||||
}
|
}
|
||||||
|
if (_sl_version == 2002) {
|
||||||
|
DEBUG(sl, 1, "Loading a trace restrict patch savegame version %d as version 196", _sl_version);
|
||||||
|
_sl_version = 196;
|
||||||
|
_sl_is_faked_ext = true;
|
||||||
|
_sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 6;
|
||||||
|
}
|
||||||
|
|
||||||
if (_sl_version == 220) { /* SL_SPRING_2013_v2_0_102 */
|
if (_sl_version == 220) { /* SL_SPRING_2013_v2_0_102 */
|
||||||
DEBUG(sl, 1, "Loading a SpringPP 2013 v2.0.102 savegame version %d as version 187", _sl_version);
|
DEBUG(sl, 1, "Loading a SpringPP 2013 v2.0.102 savegame version %d as version 187", _sl_version);
|
||||||
|
@@ -108,6 +108,65 @@ static void Save_TRRP()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** program length save header struct */
|
||||||
|
struct TraceRestrictSlotStub {
|
||||||
|
uint32 length;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const SaveLoad _trace_restrict_slot_stub_desc[] = {
|
||||||
|
SLE_VAR(TraceRestrictSlotStub, length, SLE_UINT32),
|
||||||
|
SLE_END()
|
||||||
|
};
|
||||||
|
|
||||||
|
static const SaveLoad _trace_restrict_slot_desc[] = {
|
||||||
|
SLE_VAR(TraceRestrictSlot, max_occupancy, SLE_UINT32),
|
||||||
|
SLE_STDSTR(TraceRestrictSlot, name, SLF_ALLOW_CONTROL),
|
||||||
|
SLE_VAR(TraceRestrictSlot, owner, SLE_UINT8),
|
||||||
|
SLE_END()
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load slot pool
|
||||||
|
*/
|
||||||
|
static void Load_TRRS()
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
TraceRestrictSlotStub stub;
|
||||||
|
while ((index = SlIterateArray()) != -1) {
|
||||||
|
TraceRestrictSlot *slot = new (index) TraceRestrictSlot();
|
||||||
|
SlObject(slot, _trace_restrict_slot_desc);
|
||||||
|
SlObject(&stub, _trace_restrict_slot_stub_desc);
|
||||||
|
slot->occupants.resize(stub.length);
|
||||||
|
if (stub.length) SlArray(&(slot->occupants[0]), stub.length, SLE_UINT32);
|
||||||
|
}
|
||||||
|
TraceRestrictSlot::RebuildVehicleIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save a slot, used by SlAutolength
|
||||||
|
*/
|
||||||
|
static void RealSave_TRRS(TraceRestrictSlot *slot)
|
||||||
|
{
|
||||||
|
SlObject(slot, _trace_restrict_slot_desc);
|
||||||
|
TraceRestrictSlotStub stub;
|
||||||
|
stub.length = slot->occupants.size();
|
||||||
|
SlObject(&stub, _trace_restrict_slot_stub_desc);
|
||||||
|
if (stub.length) SlArray(&(slot->occupants[0]), stub.length, SLE_UINT32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save slot pool
|
||||||
|
*/
|
||||||
|
static void Save_TRRS()
|
||||||
|
{
|
||||||
|
TraceRestrictSlot *slot;
|
||||||
|
|
||||||
|
FOR_ALL_TRACE_RESTRICT_SLOTS(slot) {
|
||||||
|
SlSetArrayIndex(slot->index);
|
||||||
|
SlAutolength((AutolengthProc*) RealSave_TRRS, slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update program reference counts from just-loaded mapping
|
* Update program reference counts from just-loaded mapping
|
||||||
*/
|
*/
|
||||||
@@ -121,5 +180,6 @@ void AfterLoadTraceRestrict()
|
|||||||
|
|
||||||
extern const ChunkHandler _trace_restrict_chunk_handlers[] = {
|
extern const ChunkHandler _trace_restrict_chunk_handlers[] = {
|
||||||
{ 'TRRM', Save_TRRM, Load_TRRM, NULL, NULL, CH_SPARSE_ARRAY}, // Trace Restrict Mapping chunk
|
{ 'TRRM', Save_TRRM, Load_TRRM, NULL, NULL, CH_SPARSE_ARRAY}, // Trace Restrict Mapping chunk
|
||||||
{ 'TRRP', Save_TRRP, Load_TRRP, NULL, NULL, CH_ARRAY | CH_LAST}, // Trace Restrict Mapping Program Pool chunk
|
{ 'TRRP', Save_TRRP, Load_TRRP, NULL, NULL, CH_ARRAY}, // Trace Restrict Mapping Program Pool chunk
|
||||||
|
{ 'TRRS', Save_TRRS, Load_TRRS, NULL, NULL, CH_ARRAY | CH_LAST}, // Trace Restrict Slot Pool chunk
|
||||||
};
|
};
|
||||||
|
@@ -1598,6 +1598,7 @@ static SettingsContainer &GetSettingsTree()
|
|||||||
interface->Add(new SettingEntry("gui.show_train_weight_ratios_in_details"));
|
interface->Add(new SettingEntry("gui.show_train_weight_ratios_in_details"));
|
||||||
interface->Add(new SettingEntry("gui.show_vehicle_group_in_details"));
|
interface->Add(new SettingEntry("gui.show_vehicle_group_in_details"));
|
||||||
interface->Add(new SettingEntry("gui.show_vehicle_list_company_colour"));
|
interface->Add(new SettingEntry("gui.show_vehicle_list_company_colour"));
|
||||||
|
interface->Add(new SettingEntry("gui.show_adv_tracerestrict_features"));
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsPage *advisors = main->Add(new SettingsPage(STR_CONFIG_SETTING_ADVISORS));
|
SettingsPage *advisors = main->Add(new SettingsPage(STR_CONFIG_SETTING_ADVISORS));
|
||||||
|
@@ -172,6 +172,7 @@ struct GUISettings {
|
|||||||
bool show_train_weight_ratios_in_details; ///< show train weight ratios in vehicle details window top widget
|
bool show_train_weight_ratios_in_details; ///< show train weight ratios in vehicle details window top widget
|
||||||
bool show_vehicle_group_in_details; ///< show vehicle group in vehicle details window top widget
|
bool show_vehicle_group_in_details; ///< show vehicle group in vehicle details window top widget
|
||||||
bool show_restricted_signal_default; ///< Show restricted electric signals using the default sprite
|
bool show_restricted_signal_default; ///< Show restricted electric signals using the default sprite
|
||||||
|
bool show_adv_tracerestrict_features; ///< Show advanced trace restrict features in UI
|
||||||
uint8 osk_activation; ///< Mouse gesture to trigger the OSK.
|
uint8 osk_activation; ///< Mouse gesture to trigger the OSK.
|
||||||
bool show_vehicle_route_steps; ///< when a window related to a specific vehicle is focused, show route steps
|
bool show_vehicle_route_steps; ///< when a window related to a specific vehicle is focused, show route steps
|
||||||
bool show_vehicle_list_company_colour; ///< show the company colour of vehicles which have an owner different to the owner of the vehicle list
|
bool show_vehicle_list_company_colour; ///< show the company colour of vehicles which have an owner different to the owner of the vehicle list
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "window_func.h"
|
#include "window_func.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "unit_conversion.h"
|
#include "unit_conversion.h"
|
||||||
|
#include "tracerestrict.h"
|
||||||
#include "game/game_text.hpp"
|
#include "game/game_text.hpp"
|
||||||
#ifdef ENABLE_NETWORK
|
#ifdef ENABLE_NETWORK
|
||||||
# include "network/network_content_gui.h"
|
# include "network/network_content_gui.h"
|
||||||
@@ -1742,11 +1743,24 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SCC_TR_SLOT_NAME: { // {TRSLOT}
|
||||||
|
const TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(args->GetInt32(SCC_TR_SLOT_NAME));
|
||||||
|
if (slot == NULL) break;
|
||||||
|
int64 args_array[] = {(int64)(size_t)slot->name.c_str()};
|
||||||
|
StringParameters tmp_params(args_array);
|
||||||
|
buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SCC_STATION_FEATURES: { // {STATIONFEATURES}
|
case SCC_STATION_FEATURES: { // {STATIONFEATURES}
|
||||||
buff = StationGetSpecialString(buff, args->GetInt32(SCC_STATION_FEATURES), last);
|
buff = StationGetSpecialString(buff, args->GetInt32(SCC_STATION_FEATURES), last);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SCC_CONSUME_ARG:
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (buff + Utf8CharLen(b) < last) buff += Utf8Encode(buff, b);
|
if (buff + Utf8CharLen(b) < last) buff += Utf8Encode(buff, b);
|
||||||
break;
|
break;
|
||||||
|
@@ -45,6 +45,7 @@ enum StringControlCode {
|
|||||||
SCC_COMPANY_NAME,
|
SCC_COMPANY_NAME,
|
||||||
SCC_PRESIDENT_NAME,
|
SCC_PRESIDENT_NAME,
|
||||||
SCC_ENGINE_NAME,
|
SCC_ENGINE_NAME,
|
||||||
|
SCC_TR_SLOT_NAME,
|
||||||
|
|
||||||
SCC_CURRENCY_SHORT,
|
SCC_CURRENCY_SHORT,
|
||||||
SCC_CURRENCY_LONG,
|
SCC_CURRENCY_LONG,
|
||||||
@@ -121,6 +122,8 @@ enum StringControlCode {
|
|||||||
SCC_BLACK,
|
SCC_BLACK,
|
||||||
SCC_PREVIOUS_COLOUR,
|
SCC_PREVIOUS_COLOUR,
|
||||||
|
|
||||||
|
SCC_CONSUME_ARG,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The next variables are part of a NewGRF subsystem for creating text strings.
|
* The next variables are part of a NewGRF subsystem for creating text strings.
|
||||||
* It uses a "stack" of bytes and reads from there.
|
* It uses a "stack" of bytes and reads from there.
|
||||||
|
@@ -4029,6 +4029,15 @@ str = STR_CONFIG_SETTING_SHOW_RESTRICTED_SIG_DEF
|
|||||||
strhelp = STR_CONFIG_SETTING_SHOW_RESTRICTED_SIG_DEF_HELPTEXT
|
strhelp = STR_CONFIG_SETTING_SHOW_RESTRICTED_SIG_DEF_HELPTEXT
|
||||||
proc = RedrawScreen
|
proc = RedrawScreen
|
||||||
|
|
||||||
|
[SDTC_BOOL]
|
||||||
|
var = gui.show_adv_tracerestrict_features
|
||||||
|
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
|
||||||
|
def = false
|
||||||
|
str = STR_CONFIG_SETTING_SHOW_ADV_TRACE_RESTRICT_FEATURES
|
||||||
|
strhelp = STR_CONFIG_SETTING_SHOW_ADV_TRACE_RESTRICT_FEATURES_HELPTEXT
|
||||||
|
proc = RedrawScreen
|
||||||
|
cat = SC_EXPERT
|
||||||
|
|
||||||
; For the dedicated build we'll enable dates in logs by default.
|
; For the dedicated build we'll enable dates in logs by default.
|
||||||
[SDTC_BOOL]
|
[SDTC_BOOL]
|
||||||
ifdef = DEDICATED
|
ifdef = DEDICATED
|
||||||
|
@@ -124,6 +124,7 @@ static const CmdStruct _cmd_structs[] = {
|
|||||||
{"COMPANY", EmitSingleChar, SCC_COMPANY_NAME, 1, -1, C_NONE | C_GENDER},
|
{"COMPANY", EmitSingleChar, SCC_COMPANY_NAME, 1, -1, C_NONE | C_GENDER},
|
||||||
{"COMPANY_NUM", EmitSingleChar, SCC_COMPANY_NUM, 1, -1, C_NONE},
|
{"COMPANY_NUM", EmitSingleChar, SCC_COMPANY_NUM, 1, -1, C_NONE},
|
||||||
{"PRESIDENT_NAME", EmitSingleChar, SCC_PRESIDENT_NAME, 1, -1, C_NONE | C_GENDER},
|
{"PRESIDENT_NAME", EmitSingleChar, SCC_PRESIDENT_NAME, 1, -1, C_NONE | C_GENDER},
|
||||||
|
{"TRSLOT", EmitSingleChar, SCC_TR_SLOT_NAME, 1, -1, C_NONE | C_GENDER},
|
||||||
|
|
||||||
{"", EmitSingleChar, '\n', 0, -1, C_DONTCOUNT},
|
{"", EmitSingleChar, '\n', 0, -1, C_DONTCOUNT},
|
||||||
{"{", EmitSingleChar, '{', 0, -1, C_DONTCOUNT},
|
{"{", EmitSingleChar, '{', 0, -1, C_DONTCOUNT},
|
||||||
@@ -144,6 +145,8 @@ static const CmdStruct _cmd_structs[] = {
|
|||||||
{"SMALL_LEFT_ARROW", EmitSingleChar, SCC_LESS_THAN, 0, -1, C_DONTCOUNT},
|
{"SMALL_LEFT_ARROW", EmitSingleChar, SCC_LESS_THAN, 0, -1, C_DONTCOUNT},
|
||||||
{"SMALL_RIGHT_ARROW", EmitSingleChar, SCC_GREATER_THAN, 0, -1, C_DONTCOUNT},
|
{"SMALL_RIGHT_ARROW", EmitSingleChar, SCC_GREATER_THAN, 0, -1, C_DONTCOUNT},
|
||||||
|
|
||||||
|
{"CONSUME_ARG", EmitSingleChar, SCC_CONSUME_ARG, 1, 0, C_NONE},
|
||||||
|
|
||||||
/* The following are directional formatting codes used to get the RTL strings right:
|
/* The following are directional formatting codes used to get the RTL strings right:
|
||||||
* http://www.unicode.org/unicode/reports/tr9/#Directional_Formatting_Codes */
|
* http://www.unicode.org/unicode/reports/tr9/#Directional_Formatting_Codes */
|
||||||
{"LRM", EmitSingleChar, CHAR_TD_LRM, 0, -1, C_DONTCOUNT},
|
{"LRM", EmitSingleChar, CHAR_TD_LRM, 0, -1, C_DONTCOUNT},
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "order_base.h"
|
#include "order_base.h"
|
||||||
#include "cargotype.h"
|
#include "cargotype.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
|
#include "string_func.h"
|
||||||
#include "pathfinder/yapf/yapf_cache.h"
|
#include "pathfinder/yapf/yapf_cache.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -60,6 +61,9 @@
|
|||||||
TraceRestrictProgramPool _tracerestrictprogram_pool("TraceRestrictProgram");
|
TraceRestrictProgramPool _tracerestrictprogram_pool("TraceRestrictProgram");
|
||||||
INSTANTIATE_POOL_METHODS(TraceRestrictProgram)
|
INSTANTIATE_POOL_METHODS(TraceRestrictProgram)
|
||||||
|
|
||||||
|
TraceRestrictSlotPool _tracerestrictslot_pool("TraceRestrictSlot");
|
||||||
|
INSTANTIATE_POOL_METHODS(TraceRestrictSlot)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TraceRestrictRefId --> TraceRestrictProgramID (Pool ID) mapping
|
* TraceRestrictRefId --> TraceRestrictProgramID (Pool ID) mapping
|
||||||
* The indirection is mainly to enable shared programs
|
* The indirection is mainly to enable shared programs
|
||||||
@@ -350,6 +354,12 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TRIT_COND_SLOT: {
|
||||||
|
const TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(GetTraceRestrictValue(item));
|
||||||
|
result = TestBinaryConditionCommon(item, slot != NULL && slot->IsOccupant(v->index));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TRIT_COND_PHYS_PROP: {
|
case TRIT_COND_PHYS_PROP: {
|
||||||
switch (static_cast<TraceRestrictPhysPropCondAuxField>(GetTraceRestrictAuxField(item))) {
|
switch (static_cast<TraceRestrictPhysPropCondAuxField>(GetTraceRestrictAuxField(item))) {
|
||||||
case TRPPCAF_WEIGHT:
|
case TRPPCAF_WEIGHT:
|
||||||
@@ -443,6 +453,44 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRIT_WAIT_AT_PBS:
|
||||||
|
if (GetTraceRestrictValue(item)) {
|
||||||
|
out.flags &= ~TRPRF_WAIT_AT_PBS;
|
||||||
|
} else {
|
||||||
|
out.flags |= TRPRF_WAIT_AT_PBS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRIT_SLOT: {
|
||||||
|
if (!input.permitted_slot_operations) break;
|
||||||
|
TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(GetTraceRestrictValue(item));
|
||||||
|
if (slot == NULL) break;
|
||||||
|
switch (static_cast<TraceRestrictSlotCondOpField>(GetTraceRestrictCondOp(item))) {
|
||||||
|
case TRSCOF_ACQUIRE_WAIT:
|
||||||
|
if (input.permitted_slot_operations & TRPISP_ACQUIRE) {
|
||||||
|
if (!slot->Occupy(v->index)) out.flags |= TRPRF_WAIT_AT_PBS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRSCOF_ACQUIRE_TRY:
|
||||||
|
if (input.permitted_slot_operations & TRPISP_ACQUIRE) slot->Occupy(v->index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRSCOF_RELEASE_BACK:
|
||||||
|
if (input.permitted_slot_operations & TRPISP_RELEASE_BACK) slot->Vacate(v->index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRSCOF_RELEASE_FRONT:
|
||||||
|
if (input.permitted_slot_operations & TRPISP_RELEASE_FRONT) slot->Vacate(v->index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NOT_REACHED();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
@@ -530,6 +578,7 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
|
|||||||
case TRIT_COND_ENTRY_DIRECTION:
|
case TRIT_COND_ENTRY_DIRECTION:
|
||||||
case TRIT_COND_PBS_ENTRY_SIGNAL:
|
case TRIT_COND_PBS_ENTRY_SIGNAL:
|
||||||
case TRIT_COND_TRAIN_GROUP:
|
case TRIT_COND_TRAIN_GROUP:
|
||||||
|
case TRIT_COND_SLOT:
|
||||||
case TRIT_COND_PHYS_PROP:
|
case TRIT_COND_PHYS_PROP:
|
||||||
case TRIT_COND_PHYS_RATIO:
|
case TRIT_COND_PHYS_RATIO:
|
||||||
case TRIT_COND_TRAIN_OWNER:
|
case TRIT_COND_TRAIN_OWNER:
|
||||||
@@ -553,6 +602,34 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
|
|||||||
actions_used_flags |= TRPAUF_LONG_RESERVE;
|
actions_used_flags |= TRPAUF_LONG_RESERVE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRIT_WAIT_AT_PBS:
|
||||||
|
actions_used_flags |= TRPAUF_WAIT_AT_PBS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRIT_SLOT:
|
||||||
|
switch (static_cast<TraceRestrictSlotCondOpField>(GetTraceRestrictCondOp(item))) {
|
||||||
|
case TRSCOF_ACQUIRE_WAIT:
|
||||||
|
actions_used_flags |= TRPAUF_SLOT_ACQUIRE | TRPAUF_WAIT_AT_PBS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRSCOF_ACQUIRE_TRY:
|
||||||
|
actions_used_flags |= TRPAUF_SLOT_ACQUIRE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRSCOF_RELEASE_BACK:
|
||||||
|
actions_used_flags |= TRPAUF_SLOT_RELEASE_BACK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TRSCOF_RELEASE_FRONT:
|
||||||
|
actions_used_flags |= TRPAUF_SLOT_RELEASE_FRONT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NOT_REACHED();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return_cmd_error(STR_TRACE_RESTRICT_ERROR_VALIDATE_UNKNOWN_INSTRUCTION);
|
return_cmd_error(STR_TRACE_RESTRICT_ERROR_VALIDATE_UNKNOWN_INSTRUCTION);
|
||||||
}
|
}
|
||||||
@@ -611,6 +688,7 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp
|
|||||||
case TRVT_FORCE:
|
case TRVT_FORCE:
|
||||||
case TRVT_POWER_WEIGHT_RATIO:
|
case TRVT_POWER_WEIGHT_RATIO:
|
||||||
case TRVT_FORCE_WEIGHT_RATIO:
|
case TRVT_FORCE_WEIGHT_RATIO:
|
||||||
|
case TRVT_WAIT_AT_PBS:
|
||||||
SetTraceRestrictValue(item, 0);
|
SetTraceRestrictValue(item, 0);
|
||||||
if (!IsTraceRestrictTypeAuxSubtype(GetTraceRestrictType(item))) {
|
if (!IsTraceRestrictTypeAuxSubtype(GetTraceRestrictType(item))) {
|
||||||
SetTraceRestrictAuxField(item, 0);
|
SetTraceRestrictAuxField(item, 0);
|
||||||
@@ -648,6 +726,11 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp
|
|||||||
SetTraceRestrictAuxField(item, 0);
|
SetTraceRestrictAuxField(item, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRVT_SLOT_INDEX:
|
||||||
|
SetTraceRestrictValue(item, INVALID_TRACE_RESTRICT_SLOT_ID);
|
||||||
|
SetTraceRestrictAuxField(item, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
break;
|
break;
|
||||||
@@ -1320,3 +1403,307 @@ void TraceRestrictUpdateCompanyID(CompanyID old_company, CompanyID new_company)
|
|||||||
// update windows
|
// update windows
|
||||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::unordered_multimap<VehicleID, TraceRestrictSlotID> slot_vehicle_index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add vehicle ID to occupants if possible and not already an occupant
|
||||||
|
* @param id Vehicle ID
|
||||||
|
* @param force Add the vehicle even if the slot is at/over capacity
|
||||||
|
* @return whether vehicle ID is now an occupant
|
||||||
|
*/
|
||||||
|
bool TraceRestrictSlot::Occupy(VehicleID id, bool force)
|
||||||
|
{
|
||||||
|
if (this->IsOccupant(id)) return true;
|
||||||
|
if (this->occupants.size() >= this->max_occupancy && !force) return false;
|
||||||
|
this->occupants.push_back(id);
|
||||||
|
slot_vehicle_index.emplace(id, this->index);
|
||||||
|
SetBit(Train::Get(id)->flags, VRF_HAVE_SLOT);
|
||||||
|
SetWindowDirty(WC_VEHICLE_DETAILS, id);
|
||||||
|
InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove vehicle ID from occupants
|
||||||
|
* @param id Vehicle ID
|
||||||
|
*/
|
||||||
|
void TraceRestrictSlot::Vacate(VehicleID id)
|
||||||
|
{
|
||||||
|
if (container_unordered_remove(this->occupants, id)) {
|
||||||
|
this->DeIndex(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove all occupants */
|
||||||
|
void TraceRestrictSlot::Clear()
|
||||||
|
{
|
||||||
|
for (VehicleID id : this->occupants) {
|
||||||
|
this->DeIndex(id);
|
||||||
|
}
|
||||||
|
this->occupants.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TraceRestrictSlot::DeIndex(VehicleID id)
|
||||||
|
{
|
||||||
|
auto range = slot_vehicle_index.equal_range(id);
|
||||||
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
if (it->second == this->index) {
|
||||||
|
auto next = slot_vehicle_index.erase(it);
|
||||||
|
if (it == range.first && next == range.second) {
|
||||||
|
/* Only one item, which we've just erased, clear the vehicle flag */
|
||||||
|
ClrBit(Train::Get(id)->flags, VRF_HAVE_SLOT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetWindowDirty(WC_VEHICLE_DETAILS, id);
|
||||||
|
InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Rebuild slot vehicle index after loading */
|
||||||
|
void TraceRestrictSlot::RebuildVehicleIndex()
|
||||||
|
{
|
||||||
|
slot_vehicle_index.clear();
|
||||||
|
const TraceRestrictSlot *slot;
|
||||||
|
FOR_ALL_TRACE_RESTRICT_SLOTS(slot) {
|
||||||
|
for (VehicleID id : slot->occupants) {
|
||||||
|
slot_vehicle_index.emplace(id, slot->index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Slot pool is about to be cleared */
|
||||||
|
void TraceRestrictSlot::PreCleanPool()
|
||||||
|
{
|
||||||
|
slot_vehicle_index.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove vehicle ID from all slot occupants */
|
||||||
|
void TraceRestrictRemoveVehicleFromAllSlots(VehicleID id)
|
||||||
|
{
|
||||||
|
auto range = slot_vehicle_index.equal_range(id);
|
||||||
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
TraceRestrictSlot *slot = TraceRestrictSlot::Get(it->second);
|
||||||
|
container_unordered_remove(slot->occupants, id);
|
||||||
|
}
|
||||||
|
slot_vehicle_index.erase(range.first, range.second);
|
||||||
|
if (range.first != range.second) InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Replace all instance of a vehicle ID with another, in all slot occupants */
|
||||||
|
void TraceRestrictTransferVehicleOccupantInAllSlots(VehicleID from, VehicleID to)
|
||||||
|
{
|
||||||
|
auto range = slot_vehicle_index.equal_range(from);
|
||||||
|
std::vector<TraceRestrictSlotID> slots;
|
||||||
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
slots.push_back(it->second);
|
||||||
|
}
|
||||||
|
slot_vehicle_index.erase(range.first, range.second);
|
||||||
|
for (TraceRestrictSlotID slot_id : slots) {
|
||||||
|
TraceRestrictSlot *slot = TraceRestrictSlot::Get(slot_id);
|
||||||
|
for (VehicleID &id : slot->occupants) {
|
||||||
|
if (id == from) {
|
||||||
|
id = to;
|
||||||
|
slot_vehicle_index.emplace(to, slot_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!slots.empty()) InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get list of slots occupied by a vehicle ID */
|
||||||
|
void TraceRestrictGetVehicleSlots(VehicleID id, std::vector<TraceRestrictSlotID> &out)
|
||||||
|
{
|
||||||
|
auto range = slot_vehicle_index.equal_range(id);
|
||||||
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
|
out.push_back(it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called when a slot is about to be deleted
|
||||||
|
* Scan program pool and change any references to it to the invalid group ID, to avoid dangling references
|
||||||
|
*/
|
||||||
|
void TraceRestrictRemoveSlotID(TraceRestrictSlotID index)
|
||||||
|
{
|
||||||
|
TraceRestrictProgram *prog;
|
||||||
|
|
||||||
|
FOR_ALL_TRACE_RESTRICT_PROGRAMS(prog) {
|
||||||
|
for (size_t i = 0; i < prog->items.size(); i++) {
|
||||||
|
TraceRestrictItem &item = prog->items[i]; // note this is a reference,
|
||||||
|
if ((GetTraceRestrictType(item) == TRIT_SLOT || GetTraceRestrictType(item) == TRIT_COND_SLOT) && GetTraceRestrictValue(item) == index) {
|
||||||
|
SetTraceRestrictValueDefault(item, TRVT_SLOT_INDEX); // this updates the instruction in-place
|
||||||
|
}
|
||||||
|
if (IsTraceRestrictDoubleItem(item)) i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update windows
|
||||||
|
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsUniqueSlotName(const char *name)
|
||||||
|
{
|
||||||
|
const TraceRestrictSlot *slot;
|
||||||
|
FOR_ALL_TRACE_RESTRICT_SLOTS(slot) {
|
||||||
|
if (slot->name == name) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new slot.
|
||||||
|
* @param tile unused
|
||||||
|
* @param flags type of operation
|
||||||
|
* @param p1 unused
|
||||||
|
* @param p2 unused
|
||||||
|
* @param text new slot name
|
||||||
|
* @return the cost of this operation or an error
|
||||||
|
*/
|
||||||
|
CommandCost CmdCreateTraceRestrictSlot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
|
{
|
||||||
|
if (!TraceRestrictSlot::CanAllocateItem()) return CMD_ERROR;
|
||||||
|
if (StrEmpty(text)) return CMD_ERROR;
|
||||||
|
|
||||||
|
size_t length = Utf8StringLength(text);
|
||||||
|
if (length <= 0) return CMD_ERROR;
|
||||||
|
if (length >= MAX_LENGTH_TRACE_RESTRICT_SLOT_NAME_CHARS) return CMD_ERROR;
|
||||||
|
if (!IsUniqueSlotName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
TraceRestrictSlot *slot = new TraceRestrictSlot(_current_company);
|
||||||
|
slot->name = text;
|
||||||
|
|
||||||
|
// update windows
|
||||||
|
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||||
|
InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a slot.
|
||||||
|
* @param tile unused
|
||||||
|
* @param flags type of operation
|
||||||
|
* @param p1 index of array group
|
||||||
|
* - p1 bit 0-15 : Slot ID
|
||||||
|
* @param p2 unused
|
||||||
|
* @param text unused
|
||||||
|
* @return the cost of this operation or an error
|
||||||
|
*/
|
||||||
|
CommandCost CmdDeleteTraceRestrictSlot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
|
{
|
||||||
|
TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(p1);
|
||||||
|
if (slot == NULL || slot->owner != _current_company) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
/* notify tracerestrict that group is about to be deleted */
|
||||||
|
TraceRestrictRemoveSlotID(slot->index);
|
||||||
|
|
||||||
|
delete slot;
|
||||||
|
|
||||||
|
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||||
|
InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alter a slot
|
||||||
|
* @param tile unused
|
||||||
|
* @param flags type of operation
|
||||||
|
* @param p1 index of array group
|
||||||
|
* - p1 bit 0-15 : GroupID
|
||||||
|
* - p1 bit 16: 0 - Rename grouop
|
||||||
|
* 1 - Change max occupancy
|
||||||
|
* @param p2 new max occupancy
|
||||||
|
* @param text the new name
|
||||||
|
* @return the cost of this operation or an error
|
||||||
|
*/
|
||||||
|
CommandCost CmdAlterTraceRestrictSlot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
|
{
|
||||||
|
TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(GB(p1, 0, 16));
|
||||||
|
if (slot == NULL || slot->owner != _current_company) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (!HasBit(p1, 16)) {
|
||||||
|
/* Rename slot */
|
||||||
|
|
||||||
|
if (StrEmpty(text)) return CMD_ERROR;
|
||||||
|
size_t length = Utf8StringLength(text);
|
||||||
|
if (length <= 0) return CMD_ERROR;
|
||||||
|
if (length >= MAX_LENGTH_TRACE_RESTRICT_SLOT_NAME_CHARS) return CMD_ERROR;
|
||||||
|
if (!IsUniqueSlotName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
slot->name = text;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Change max occupancy */
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
slot->max_occupancy = p2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
// update windows
|
||||||
|
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||||
|
InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a vehicle to a slot
|
||||||
|
* @param tile unused
|
||||||
|
* @param flags type of operation
|
||||||
|
* @param p1 index of array group
|
||||||
|
* - p1 bit 0-15 : GroupID
|
||||||
|
* @param p2 index of vehicle
|
||||||
|
* - p2 bit 0-19 : VehicleID
|
||||||
|
* @param text unused
|
||||||
|
* @return the cost of this operation or an error
|
||||||
|
*/
|
||||||
|
CommandCost CmdAddVehicleTraceRestrictSlot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
|
{
|
||||||
|
TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(p1);
|
||||||
|
Vehicle *v = Vehicle::GetIfValid(p2);
|
||||||
|
if (slot == NULL || slot->owner != _current_company) return CMD_ERROR;
|
||||||
|
if (v == NULL || v->owner != _current_company) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
slot->Occupy(v->index, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a vehicle from a slot
|
||||||
|
* @param tile unused
|
||||||
|
* @param flags type of operation
|
||||||
|
* @param p1 index of array group
|
||||||
|
* - p1 bit 0-15 : GroupID
|
||||||
|
* @param p2 index of vehicle
|
||||||
|
* - p2 bit 0-19 : VehicleID
|
||||||
|
* @param text unused
|
||||||
|
* @return the cost of this operation or an error
|
||||||
|
*/
|
||||||
|
CommandCost CmdRemoveVehicleTraceRestrictSlot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
|
{
|
||||||
|
TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(p1);
|
||||||
|
Vehicle *v = Vehicle::GetIfValid(p2);
|
||||||
|
if (slot == NULL || slot->owner != _current_company) return CMD_ERROR;
|
||||||
|
if (v == NULL) return CMD_ERROR; // permit removing vehicles of other owners from your own slot
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
slot->Vacate(v->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
@@ -14,12 +14,16 @@
|
|||||||
#include "core/bitmath_func.hpp"
|
#include "core/bitmath_func.hpp"
|
||||||
#include "core/enum_type.hpp"
|
#include "core/enum_type.hpp"
|
||||||
#include "core/pool_type.hpp"
|
#include "core/pool_type.hpp"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "command_func.h"
|
#include "command_func.h"
|
||||||
#include "rail_map.h"
|
#include "rail_map.h"
|
||||||
#include "tile_type.h"
|
#include "tile_type.h"
|
||||||
#include "group_type.h"
|
#include "group_type.h"
|
||||||
|
#include "vehicle_type.h"
|
||||||
#include "3rdparty/cpp-btree/btree_map.h"
|
#include "3rdparty/cpp-btree/btree_map.h"
|
||||||
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
struct Train;
|
struct Train;
|
||||||
|
|
||||||
@@ -35,6 +39,19 @@ typedef Pool<TraceRestrictProgram, TraceRestrictProgramID, 16, 256000> TraceRest
|
|||||||
/** The actual pool for trace restrict nodes. */
|
/** The actual pool for trace restrict nodes. */
|
||||||
extern TraceRestrictProgramPool _tracerestrictprogram_pool;
|
extern TraceRestrictProgramPool _tracerestrictprogram_pool;
|
||||||
|
|
||||||
|
/** Slot pool ID type. */
|
||||||
|
typedef uint16 TraceRestrictSlotID;
|
||||||
|
struct TraceRestrictSlot;
|
||||||
|
|
||||||
|
/** Type of the pool for trace restrict slots. */
|
||||||
|
typedef Pool<TraceRestrictSlot, TraceRestrictSlotID, 16, 0xFFF0> TraceRestrictSlotPool;
|
||||||
|
/** The actual pool for trace restrict nodes. */
|
||||||
|
extern TraceRestrictSlotPool _tracerestrictslot_pool;
|
||||||
|
|
||||||
|
static const TraceRestrictSlotID NEW_TRACE_RESTRICT_SLOT_ID = 0xFFFD; // for GUI use only
|
||||||
|
static const TraceRestrictSlotID ALL_TRAINS_TRACE_RESTRICT_SLOT_ID = 0xFFFE; // for GUI use only
|
||||||
|
static const TraceRestrictSlotID INVALID_TRACE_RESTRICT_SLOT_ID = 0xFFFF;
|
||||||
|
|
||||||
extern const uint16 _tracerestrict_pathfinder_penalty_preset_values[];
|
extern const uint16 _tracerestrict_pathfinder_penalty_preset_values[];
|
||||||
|
|
||||||
#define FOR_ALL_TRACE_RESTRICT_PROGRAMS_FROM(var, start) FOR_ALL_ITEMS_FROM(TraceRestrictProgram, tr_index, var, start)
|
#define FOR_ALL_TRACE_RESTRICT_PROGRAMS_FROM(var, start) FOR_ALL_ITEMS_FROM(TraceRestrictProgram, tr_index, var, start)
|
||||||
@@ -100,6 +117,8 @@ enum TraceRestrictItemType {
|
|||||||
TRIT_PF_PENALTY = 2, ///< Add to pathfinder penalty
|
TRIT_PF_PENALTY = 2, ///< Add to pathfinder penalty
|
||||||
TRIT_RESERVE_THROUGH = 3, ///< Reserve through PBS signal
|
TRIT_RESERVE_THROUGH = 3, ///< Reserve through PBS signal
|
||||||
TRIT_LONG_RESERVE = 4, ///< Long reserve PBS signal
|
TRIT_LONG_RESERVE = 4, ///< Long reserve PBS signal
|
||||||
|
TRIT_WAIT_AT_PBS = 5, ///< Wait at PBS signal
|
||||||
|
TRIT_SLOT = 6, ///< Slot operation
|
||||||
|
|
||||||
TRIT_COND_BEGIN = 8, ///< Start of conditional item types, note that this has the same value as TRIT_COND_ENDIF
|
TRIT_COND_BEGIN = 8, ///< Start of conditional item types, note that this has the same value as TRIT_COND_ENDIF
|
||||||
TRIT_COND_ENDIF = 8, ///< This is an endif block or an else block
|
TRIT_COND_ENDIF = 8, ///< This is an endif block or an else block
|
||||||
@@ -115,6 +134,7 @@ enum TraceRestrictItemType {
|
|||||||
TRIT_COND_TRAIN_GROUP = 18, ///< Test train group membership
|
TRIT_COND_TRAIN_GROUP = 18, ///< Test train group membership
|
||||||
TRIT_COND_PHYS_PROP = 19, ///< Test train physical property
|
TRIT_COND_PHYS_PROP = 19, ///< Test train physical property
|
||||||
TRIT_COND_PHYS_RATIO = 20, ///< Test train physical property ratio
|
TRIT_COND_PHYS_RATIO = 20, ///< Test train physical property ratio
|
||||||
|
TRIT_COND_SLOT = 21, ///< Test train slot membership
|
||||||
TRIT_COND_TRAIN_OWNER = 24, ///< Test train owner
|
TRIT_COND_TRAIN_OWNER = 24, ///< Test train owner
|
||||||
/* space up to 31 */
|
/* space up to 31 */
|
||||||
};
|
};
|
||||||
@@ -202,6 +222,17 @@ enum TraceRestrictPathfinderPenaltyAuxField {
|
|||||||
/* space up to 3 */
|
/* space up to 3 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TraceRestrictItem repurposed condition operator field, for slot operation type actions
|
||||||
|
*/
|
||||||
|
enum TraceRestrictSlotCondOpField {
|
||||||
|
TRSCOF_ACQUIRE_WAIT = 0, ///< acquire a slot, or wait at the current signal
|
||||||
|
TRSCOF_ACQUIRE_TRY = 1, ///< try to acquire a slot, or carry on otherwise
|
||||||
|
TRSCOF_RELEASE_BACK = 2, ///< release a slot (back of train)
|
||||||
|
TRSCOF_RELEASE_FRONT = 3, ///< release a slot (front of train)
|
||||||
|
/* space up to 8 */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TraceRestrictItem pathfinder penalty preset index
|
* TraceRestrictItem pathfinder penalty preset index
|
||||||
* This may not be shortened, only lengthened, as preset indexes are stored in save games
|
* This may not be shortened, only lengthened, as preset indexes are stored in save games
|
||||||
@@ -220,6 +251,7 @@ enum TraceRestrictProgramResultFlags {
|
|||||||
TRPRF_DENY = 1 << 0, ///< Pathfinder deny is set
|
TRPRF_DENY = 1 << 0, ///< Pathfinder deny is set
|
||||||
TRPRF_RESERVE_THROUGH = 1 << 1, ///< Reserve through is set
|
TRPRF_RESERVE_THROUGH = 1 << 1, ///< Reserve through is set
|
||||||
TRPRF_LONG_RESERVE = 1 << 2, ///< Long reserve is set
|
TRPRF_LONG_RESERVE = 1 << 2, ///< Long reserve is set
|
||||||
|
TRPRF_WAIT_AT_PBS = 1 << 3, ///< Wait at PBS signal is set
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramResultFlags)
|
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramResultFlags)
|
||||||
|
|
||||||
@@ -230,9 +262,23 @@ enum TraceRestrictProgramActionsUsedFlags {
|
|||||||
TRPAUF_PF = 1 << 0, ///< Pathfinder deny or penalty are present
|
TRPAUF_PF = 1 << 0, ///< Pathfinder deny or penalty are present
|
||||||
TRPAUF_RESERVE_THROUGH = 1 << 1, ///< Reserve through action is present
|
TRPAUF_RESERVE_THROUGH = 1 << 1, ///< Reserve through action is present
|
||||||
TRPAUF_LONG_RESERVE = 1 << 2, ///< Long reserve action is present
|
TRPAUF_LONG_RESERVE = 1 << 2, ///< Long reserve action is present
|
||||||
|
TRPAUF_WAIT_AT_PBS = 1 << 3, ///< Wait at PBS signal action is present
|
||||||
|
TRPAUF_SLOT_ACQUIRE = 1 << 4, ///< Slot acquire action is present
|
||||||
|
TRPAUF_SLOT_RELEASE_BACK = 1 << 5, ///< Slot release (back) action is present
|
||||||
|
TRPAUF_SLOT_RELEASE_FRONT = 1 << 6, ///< Slot release (front) action is present
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramActionsUsedFlags)
|
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramActionsUsedFlags)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration for TraceRestrictProgram::actions_used_flags
|
||||||
|
*/
|
||||||
|
enum TraceRestrictProgramInputSlotPermissions {
|
||||||
|
TRPISP_ACQUIRE = 1 << 0, ///< Slot acquire is permitted
|
||||||
|
TRPISP_RELEASE_BACK = 1 << 1, ///< Slot release (back) is permitted
|
||||||
|
TRPISP_RELEASE_FRONT = 1 << 2, ///< Slot release (front) is permitted
|
||||||
|
};
|
||||||
|
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramInputSlotPermissions)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execution input of a TraceRestrictProgram
|
* Execution input of a TraceRestrictProgram
|
||||||
*/
|
*/
|
||||||
@@ -243,9 +289,11 @@ struct TraceRestrictProgramInput {
|
|||||||
Trackdir trackdir; ///< Track direction on tile of restrict signal, for direction testing
|
Trackdir trackdir; ///< Track direction on tile of restrict signal, for direction testing
|
||||||
PreviousSignalProc *previous_signal_callback; ///< Callback to retrieve tile and direction of previous signal, may be NULL
|
PreviousSignalProc *previous_signal_callback; ///< Callback to retrieve tile and direction of previous signal, may be NULL
|
||||||
const void *previous_signal_ptr; ///< Opaque pointer suitable to be passed to previous_signal_callback
|
const void *previous_signal_ptr; ///< Opaque pointer suitable to be passed to previous_signal_callback
|
||||||
|
TraceRestrictProgramInputSlotPermissions permitted_slot_operations; ///< Permitted slot operations
|
||||||
|
|
||||||
TraceRestrictProgramInput(TileIndex tile_, Trackdir trackdir_, PreviousSignalProc *previous_signal_callback_, const void *previous_signal_ptr_)
|
TraceRestrictProgramInput(TileIndex tile_, Trackdir trackdir_, PreviousSignalProc *previous_signal_callback_, const void *previous_signal_ptr_)
|
||||||
: tile(tile_), trackdir(trackdir_), previous_signal_callback(previous_signal_callback_), previous_signal_ptr(previous_signal_ptr_) { }
|
: tile(tile_), trackdir(trackdir_), previous_signal_callback(previous_signal_callback_), previous_signal_ptr(previous_signal_ptr_),
|
||||||
|
permitted_slot_operations(static_cast<TraceRestrictProgramInputSlotPermissions>(0)) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -440,6 +488,8 @@ enum TraceRestrictValueType {
|
|||||||
TRVT_FORCE = 15,///< takes a force
|
TRVT_FORCE = 15,///< takes a force
|
||||||
TRVT_POWER_WEIGHT_RATIO = 16,///< takes a power / weight ratio, * 100
|
TRVT_POWER_WEIGHT_RATIO = 16,///< takes a power / weight ratio, * 100
|
||||||
TRVT_FORCE_WEIGHT_RATIO = 17,///< takes a force / weight ratio, * 100
|
TRVT_FORCE_WEIGHT_RATIO = 17,///< takes a force / weight ratio, * 100
|
||||||
|
TRVT_WAIT_AT_PBS = 18,///< takes a value 0 = wait at PBS signal, 1 = cancel wait at PBS signal
|
||||||
|
TRVT_SLOT_INDEX = 19,///< takes a TraceRestrictSlotID
|
||||||
TRVT_OWNER = 40,///< takes a CompanyID
|
TRVT_OWNER = 40,///< takes a CompanyID
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -507,6 +557,11 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR
|
|||||||
out.cond_type = TRCOT_BINARY;
|
out.cond_type = TRCOT_BINARY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRIT_COND_SLOT:
|
||||||
|
out.value_type = TRVT_SLOT_INDEX;
|
||||||
|
out.cond_type = TRCOT_BINARY;
|
||||||
|
break;
|
||||||
|
|
||||||
case TRIT_COND_PHYS_PROP:
|
case TRIT_COND_PHYS_PROP:
|
||||||
switch (static_cast<TraceRestrictPhysPropCondAuxField>(GetTraceRestrictAuxField(item))) {
|
switch (static_cast<TraceRestrictPhysPropCondAuxField>(GetTraceRestrictAuxField(item))) {
|
||||||
case TRPPCAF_WEIGHT:
|
case TRPPCAF_WEIGHT:
|
||||||
@@ -562,6 +617,10 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR
|
|||||||
out.value_type = TRVT_RESERVE_THROUGH;
|
out.value_type = TRVT_RESERVE_THROUGH;
|
||||||
} else if (GetTraceRestrictType(item) == TRIT_LONG_RESERVE) {
|
} else if (GetTraceRestrictType(item) == TRIT_LONG_RESERVE) {
|
||||||
out.value_type = TRVT_LONG_RESERVE;
|
out.value_type = TRVT_LONG_RESERVE;
|
||||||
|
} else if (GetTraceRestrictType(item) == TRIT_WAIT_AT_PBS) {
|
||||||
|
out.value_type = TRVT_WAIT_AT_PBS;
|
||||||
|
} else if (GetTraceRestrictType(item) == TRIT_SLOT) {
|
||||||
|
out.value_type = TRVT_SLOT_INDEX;
|
||||||
} else {
|
} else {
|
||||||
out.value_type = TRVT_NONE;
|
out.value_type = TRVT_NONE;
|
||||||
}
|
}
|
||||||
@@ -662,5 +721,54 @@ void ShowTraceRestrictProgramWindow(TileIndex tile, Track track);
|
|||||||
void TraceRestrictRemoveDestinationID(TraceRestrictOrderCondAuxField type, uint16 index);
|
void TraceRestrictRemoveDestinationID(TraceRestrictOrderCondAuxField type, uint16 index);
|
||||||
void TraceRestrictRemoveGroupID(GroupID index);
|
void TraceRestrictRemoveGroupID(GroupID index);
|
||||||
void TraceRestrictUpdateCompanyID(CompanyID old_company, CompanyID new_company);
|
void TraceRestrictUpdateCompanyID(CompanyID old_company, CompanyID new_company);
|
||||||
|
void TraceRestrictRemoveSlotID(TraceRestrictSlotID index);
|
||||||
|
|
||||||
|
void TraceRestrictRemoveVehicleFromAllSlots(VehicleID id);
|
||||||
|
void TraceRestrictTransferVehicleOccupantInAllSlots(VehicleID from, VehicleID to);
|
||||||
|
void TraceRestrictGetVehicleSlots(VehicleID id, std::vector<TraceRestrictSlotID> &out);
|
||||||
|
|
||||||
|
static const uint MAX_LENGTH_TRACE_RESTRICT_SLOT_NAME_CHARS = 128; ///< The maximum length of a slot name in characters including '\0'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slot type, used for slot operations
|
||||||
|
*/
|
||||||
|
struct TraceRestrictSlot : TraceRestrictSlotPool::PoolItem<&_tracerestrictslot_pool> {
|
||||||
|
std::vector<VehicleID> occupants;
|
||||||
|
uint32 max_occupancy = 1;
|
||||||
|
std::string name;
|
||||||
|
OwnerByte owner;
|
||||||
|
|
||||||
|
static void RebuildVehicleIndex();
|
||||||
|
static void PreCleanPool();
|
||||||
|
|
||||||
|
TraceRestrictSlot(CompanyID owner = INVALID_COMPANY)
|
||||||
|
{
|
||||||
|
this->owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
~TraceRestrictSlot()
|
||||||
|
{
|
||||||
|
if (!CleaningPool()) this->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Test whether vehicle ID is already an occupant */
|
||||||
|
bool IsOccupant(VehicleID id) const {
|
||||||
|
for (size_t i = 0; i < occupants.size(); i++) {
|
||||||
|
if (occupants[i] == id) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Occupy(VehicleID id, bool force = false);
|
||||||
|
void Vacate(VehicleID id);
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DeIndex(VehicleID id);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define FOR_ALL_TRACE_RESTRICT_SLOTS_FROM(var, start) FOR_ALL_ITEMS_FROM(TraceRestrictSlot, slot_index, var, start)
|
||||||
|
#define FOR_ALL_TRACE_RESTRICT_SLOTS(var) FOR_ALL_TRACE_RESTRICT_SLOTS_FROM(var, 0)
|
||||||
|
|
||||||
#endif /* TRACERESTRICT_H */
|
#endif /* TRACERESTRICT_H */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,8 @@ struct Train;
|
|||||||
/** Rail vehicle flags. */
|
/** Rail vehicle flags. */
|
||||||
enum VehicleRailFlags {
|
enum VehicleRailFlags {
|
||||||
VRF_REVERSING = 0,
|
VRF_REVERSING = 0,
|
||||||
|
VRF_WAITING_RESTRICTION = 1, ///< Train is waiting due to a routing restriction, only valid when VRF_TRAIN_STUCK is also set.
|
||||||
|
VRF_HAVE_SLOT = 2, ///< Train has 1 or more slots
|
||||||
VRF_POWEREDWAGON = 3, ///< Wagon is powered.
|
VRF_POWEREDWAGON = 3, ///< Wagon is powered.
|
||||||
VRF_REVERSE_DIRECTION = 4, ///< Reverse the visible direction of the vehicle.
|
VRF_REVERSE_DIRECTION = 4, ///< Reverse the visible direction of the vehicle.
|
||||||
|
|
||||||
|
@@ -1397,6 +1397,10 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
|||||||
DeleteVehicleOrders(src);
|
DeleteVehicleOrders(src);
|
||||||
RemoveVehicleFromGroup(src);
|
RemoveVehicleFromGroup(src);
|
||||||
src->unitnumber = 0;
|
src->unitnumber = 0;
|
||||||
|
if (HasBit(src->flags, VRF_HAVE_SLOT)) {
|
||||||
|
TraceRestrictRemoveVehicleFromAllSlots(src->index);
|
||||||
|
ClrBit(src->flags, VRF_HAVE_SLOT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We weren't a front engine but are becoming one. So
|
/* We weren't a front engine but are becoming one. So
|
||||||
@@ -1603,11 +1607,12 @@ void Train::UpdateDeltaXY(Direction direction)
|
|||||||
* Mark a train as stuck and stop it if it isn't stopped right now.
|
* Mark a train as stuck and stop it if it isn't stopped right now.
|
||||||
* @param v %Train to mark as being stuck.
|
* @param v %Train to mark as being stuck.
|
||||||
*/
|
*/
|
||||||
static void MarkTrainAsStuck(Train *v)
|
static void MarkTrainAsStuck(Train *v, bool waiting_restriction = false)
|
||||||
{
|
{
|
||||||
if (!HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
if (!HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
||||||
/* It is the first time the problem occurred, set the "train stuck" flag. */
|
/* It is the first time the problem occurred, set the "train stuck" flag. */
|
||||||
SetBit(v->flags, VRF_TRAIN_STUCK);
|
SetBit(v->flags, VRF_TRAIN_STUCK);
|
||||||
|
SB(v->flags, VRF_WAITING_RESTRICTION, 1, waiting_restriction ? 1 : 0);
|
||||||
|
|
||||||
v->wait_counter = 0;
|
v->wait_counter = 0;
|
||||||
|
|
||||||
@@ -1616,6 +1621,9 @@ static void MarkTrainAsStuck(Train *v)
|
|||||||
v->subspeed = 0;
|
v->subspeed = 0;
|
||||||
v->SetLastSpeed();
|
v->SetLastSpeed();
|
||||||
|
|
||||||
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
|
||||||
|
} else if (waiting_restriction != HasBit(v->flags, VRF_WAITING_RESTRICTION)) {
|
||||||
|
ToggleBit(v->flags, VRF_WAITING_RESTRICTION);
|
||||||
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2823,6 +2831,21 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
|||||||
Track track = FindFirstTrack(tracks);
|
Track track = FindFirstTrack(tracks);
|
||||||
/* We need to check for signals only here, as a junction tile can't have signals. */
|
/* We need to check for signals only here, as a junction tile can't have signals. */
|
||||||
if (track != INVALID_TRACK && HasPbsSignalOnTrackdir(tile, TrackEnterdirToTrackdir(track, enterdir))) {
|
if (track != INVALID_TRACK && HasPbsSignalOnTrackdir(tile, TrackEnterdirToTrackdir(track, enterdir))) {
|
||||||
|
if (IsRestrictedSignal(tile) && v->force_proceed != TFP_SIGNAL) {
|
||||||
|
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, track);
|
||||||
|
if (prog && prog->actions_used_flags & (TRPAUF_WAIT_AT_PBS | TRPAUF_SLOT_ACQUIRE)) {
|
||||||
|
TraceRestrictProgramResult out;
|
||||||
|
TraceRestrictProgramInput input(tile, TrackEnterdirToTrackdir(track, enterdir), NULL, NULL);
|
||||||
|
input.permitted_slot_operations = TRPISP_ACQUIRE;
|
||||||
|
prog->Execute(v, input, out);
|
||||||
|
if (out.flags & TRPRF_WAIT_AT_PBS) {
|
||||||
|
if (mark_stuck) MarkTrainAsStuck(v, true);
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClrBit(v->flags, VRF_WAITING_RESTRICTION);
|
||||||
|
|
||||||
do_track_reservation = true;
|
do_track_reservation = true;
|
||||||
changed_signal = true;
|
changed_signal = true;
|
||||||
SetSignalStateByTrackdir(tile, TrackEnterdirToTrackdir(track, enterdir), SIGNAL_STATE_GREEN);
|
SetSignalStateByTrackdir(tile, TrackEnterdirToTrackdir(track, enterdir), SIGNAL_STATE_GREEN);
|
||||||
@@ -3717,6 +3740,19 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
goto reverse_train_direction;
|
goto reverse_train_direction;
|
||||||
} else {
|
} else {
|
||||||
TryReserveRailTrack(gp.new_tile, TrackBitsToTrack(chosen_track), false);
|
TryReserveRailTrack(gp.new_tile, TrackBitsToTrack(chosen_track), false);
|
||||||
|
|
||||||
|
if (IsPlainRailTile(gp.new_tile) && HasSignals(gp.new_tile) && IsRestrictedSignal(gp.new_tile)) {
|
||||||
|
const Trackdir dir = FindFirstTrackdir(trackdirbits);
|
||||||
|
if (HasSignalOnTrack(gp.new_tile, TrackdirToTrack(dir))) {
|
||||||
|
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(gp.new_tile, TrackdirToTrack(dir));
|
||||||
|
if (prog && prog->actions_used_flags & (TRPAUF_SLOT_ACQUIRE | TRPAUF_SLOT_RELEASE_FRONT)) {
|
||||||
|
TraceRestrictProgramResult out;
|
||||||
|
TraceRestrictProgramInput input(gp.new_tile, dir, NULL, NULL);
|
||||||
|
input.permitted_slot_operations = TRPISP_ACQUIRE | TRPISP_RELEASE_FRONT;
|
||||||
|
prog->Execute(v, input, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* The wagon is active, simply follow the prev vehicle. */
|
/* The wagon is active, simply follow the prev vehicle. */
|
||||||
@@ -3994,6 +4030,21 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
if (v->Next() == NULL) {
|
if (v->Next() == NULL) {
|
||||||
TrainMovedChangeSignal(v, gp.old_tile, ReverseDiagDir(enterdir));
|
TrainMovedChangeSignal(v, gp.old_tile, ReverseDiagDir(enterdir));
|
||||||
if (IsLevelCrossingTile(gp.old_tile)) UpdateLevelCrossing(gp.old_tile);
|
if (IsLevelCrossingTile(gp.old_tile)) UpdateLevelCrossing(gp.old_tile);
|
||||||
|
|
||||||
|
if (IsTileType(gp.old_tile, MP_RAILWAY) && HasSignals(gp.old_tile) && IsRestrictedSignal(gp.old_tile)) {
|
||||||
|
const TrackdirBits rev_tracks = TrackBitsToTrackdirBits(GetTrackBits(gp.old_tile)) & DiagdirReachesTrackdirs(ReverseDiagDir(enterdir));
|
||||||
|
const Trackdir rev_trackdir = FindFirstTrackdir(rev_tracks);
|
||||||
|
const Track track = TrackdirToTrack(rev_trackdir);
|
||||||
|
if (HasSignalOnTrack(gp.old_tile, track)) {
|
||||||
|
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(gp.old_tile, track);
|
||||||
|
if (prog && prog->actions_used_flags & TRPAUF_SLOT_RELEASE_BACK) {
|
||||||
|
TraceRestrictProgramResult out;
|
||||||
|
TraceRestrictProgramInput input(gp.old_tile, ReverseTrackdir(rev_trackdir), NULL, NULL);
|
||||||
|
input.permitted_slot_operations = TRPISP_RELEASE_BACK;
|
||||||
|
prog->Execute(first, input, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,6 +51,7 @@
|
|||||||
#include "tunnel_map.h"
|
#include "tunnel_map.h"
|
||||||
#include "depot_map.h"
|
#include "depot_map.h"
|
||||||
#include "gamelog.h"
|
#include "gamelog.h"
|
||||||
|
#include "tracerestrict.h"
|
||||||
#include "linkgraph/linkgraph.h"
|
#include "linkgraph/linkgraph.h"
|
||||||
#include "linkgraph/refresh.h"
|
#include "linkgraph/refresh.h"
|
||||||
#include "blitter/factory.hpp"
|
#include "blitter/factory.hpp"
|
||||||
@@ -856,6 +857,11 @@ void Vehicle::PreDestructor()
|
|||||||
|
|
||||||
if (this->owner == _local_company) InvalidateAutoreplaceWindow(this->engine_type, this->group_id);
|
if (this->owner == _local_company) InvalidateAutoreplaceWindow(this->engine_type, this->group_id);
|
||||||
DeleteGroupHighlightOfVehicle(this);
|
DeleteGroupHighlightOfVehicle(this);
|
||||||
|
if (this->type == VEH_TRAIN) {
|
||||||
|
extern void DeleteTraceRestrictSlotHighlightOfVehicle(const Vehicle *v);
|
||||||
|
|
||||||
|
DeleteTraceRestrictSlotHighlightOfVehicle(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->type == VEH_AIRCRAFT && this->IsPrimaryVehicle()) {
|
if (this->type == VEH_AIRCRAFT && this->IsPrimaryVehicle()) {
|
||||||
@@ -876,6 +882,11 @@ void Vehicle::PreDestructor()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->type == VEH_TRAIN && HasBit(Train::From(this)->flags, VRF_HAVE_SLOT)) {
|
||||||
|
TraceRestrictRemoveVehicleFromAllSlots(this->index);
|
||||||
|
ClrBit(Train::From(this)->flags, VRF_HAVE_SLOT);
|
||||||
|
}
|
||||||
|
|
||||||
if (this->Previous() == NULL) {
|
if (this->Previous() == NULL) {
|
||||||
InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile);
|
InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile);
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,9 @@
|
|||||||
#include "train.h"
|
#include "train.h"
|
||||||
#include "tbtr_template_gui_main.h"
|
#include "tbtr_template_gui_main.h"
|
||||||
#include "zoom_func.h"
|
#include "zoom_func.h"
|
||||||
|
#include "tracerestrict.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
@@ -176,6 +179,15 @@ Dimension BaseVehicleListWindow::GetActionDropdownSize(bool show_autoreplace, bo
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the Action dropdown window should be shown/available.
|
||||||
|
* @return Whether available
|
||||||
|
*/
|
||||||
|
bool BaseVehicleListWindow::ShouldShowActionDropdownList() const
|
||||||
|
{
|
||||||
|
return this->vehicles.Length() != 0 || (this->vli.vtype == VEH_TRAIN && _settings_client.gui.show_adv_tracerestrict_features);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the Action dropdown window.
|
* Display the Action dropdown window.
|
||||||
* @param show_autoreplace If true include the autoreplace item.
|
* @param show_autoreplace If true include the autoreplace item.
|
||||||
@@ -186,17 +198,21 @@ DropDownList *BaseVehicleListWindow::BuildActionDropdownList(bool show_autorepla
|
|||||||
StringID change_order_str, bool show_create_group)
|
StringID change_order_str, bool show_create_group)
|
||||||
{
|
{
|
||||||
DropDownList *list = new DropDownList();
|
DropDownList *list = new DropDownList();
|
||||||
|
bool disable = this->vehicles.Length() == 0;
|
||||||
|
|
||||||
if (show_autoreplace) *list->Append() = new DropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, false);
|
if (show_autoreplace) *list->Append() = new DropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, disable);
|
||||||
if (show_autoreplace && show_template_replace) {
|
if (show_autoreplace && show_template_replace) {
|
||||||
*list->Append() = new DropDownListStringItem(STR_TMPL_TEMPLATE_REPLACEMENT, ADI_TEMPLATE_REPLACE, false);
|
*list->Append() = new DropDownListStringItem(STR_TMPL_TEMPLATE_REPLACEMENT, ADI_TEMPLATE_REPLACE, disable);
|
||||||
}
|
}
|
||||||
*list->Append() = new DropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, false);
|
*list->Append() = new DropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, disable);
|
||||||
*list->Append() = new DropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, false);
|
*list->Append() = new DropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, disable);
|
||||||
|
|
||||||
if (show_group) {
|
if (show_group) {
|
||||||
*list->Append() = new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, false);
|
*list->Append() = new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, disable);
|
||||||
*list->Append() = new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, false);
|
*list->Append() = new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, disable);
|
||||||
|
}
|
||||||
|
if (this->vli.vtype == VEH_TRAIN && _settings_client.gui.show_adv_tracerestrict_features) {
|
||||||
|
*list->Append() = new DropDownListStringItem(STR_TRACE_RESTRICT_SLOT_MANAGE, ADI_TRACERESTRICT_SLOT_MGMT, false);
|
||||||
}
|
}
|
||||||
if (change_order_str != 0) {
|
if (change_order_str != 0) {
|
||||||
*list->Append() = new DropDownListStringItem(change_order_str, ADI_CHANGE_ORDER, false);
|
*list->Append() = new DropDownListStringItem(change_order_str, ADI_CHANGE_ORDER, false);
|
||||||
@@ -1713,7 +1729,7 @@ public:
|
|||||||
this->BuildVehicleList();
|
this->BuildVehicleList();
|
||||||
this->SortVehicleList();
|
this->SortVehicleList();
|
||||||
|
|
||||||
if (this->vehicles.Length() == 0 && this->IsWidgetLowered(WID_VL_MANAGE_VEHICLES_DROPDOWN)) {
|
if (!this->ShouldShowActionDropdownList() && this->IsWidgetLowered(WID_VL_MANAGE_VEHICLES_DROPDOWN)) {
|
||||||
HideDropDownMenu(this);
|
HideDropDownMenu(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1727,8 +1743,8 @@ public:
|
|||||||
}
|
}
|
||||||
if (this->owner == _local_company) {
|
if (this->owner == _local_company) {
|
||||||
this->SetWidgetDisabledState(WID_VL_AVAILABLE_VEHICLES, this->vli.type != VL_STANDARD);
|
this->SetWidgetDisabledState(WID_VL_AVAILABLE_VEHICLES, this->vli.type != VL_STANDARD);
|
||||||
|
this->SetWidgetDisabledState(WID_VL_MANAGE_VEHICLES_DROPDOWN, !this->ShouldShowActionDropdownList());
|
||||||
this->SetWidgetsDisabledState(this->vehicles.Length() == 0,
|
this->SetWidgetsDisabledState(this->vehicles.Length() == 0,
|
||||||
WID_VL_MANAGE_VEHICLES_DROPDOWN,
|
|
||||||
WID_VL_STOP_ALL,
|
WID_VL_STOP_ALL,
|
||||||
WID_VL_START_ALL,
|
WID_VL_START_ALL,
|
||||||
WIDGET_LIST_END);
|
WIDGET_LIST_END);
|
||||||
@@ -1769,7 +1785,7 @@ public:
|
|||||||
case WID_VL_MANAGE_VEHICLES_DROPDOWN: {
|
case WID_VL_MANAGE_VEHICLES_DROPDOWN: {
|
||||||
DropDownList *list = this->BuildActionDropdownList(VehicleListIdentifier::UnPack(this->window_number).type == VL_STANDARD, false,
|
DropDownList *list = this->BuildActionDropdownList(VehicleListIdentifier::UnPack(this->window_number).type == VL_STANDARD, false,
|
||||||
this->vli.vtype == VEH_TRAIN, this->GetChangeOrderStringID(), true);
|
this->vli.vtype == VEH_TRAIN, this->GetChangeOrderStringID(), true);
|
||||||
ShowDropDownList(this, list, 0, WID_VL_MANAGE_VEHICLES_DROPDOWN);
|
ShowDropDownList(this, list, -1, WID_VL_MANAGE_VEHICLES_DROPDOWN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1787,7 +1803,7 @@ public:
|
|||||||
this->vehicles.SetSortType(index);
|
this->vehicles.SetSortType(index);
|
||||||
break;
|
break;
|
||||||
case WID_VL_MANAGE_VEHICLES_DROPDOWN:
|
case WID_VL_MANAGE_VEHICLES_DROPDOWN:
|
||||||
assert(this->vehicles.Length() != 0);
|
assert(this->ShouldShowActionDropdownList());
|
||||||
|
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case ADI_REPLACE: // Replace window
|
case ADI_REPLACE: // Replace window
|
||||||
@@ -1811,6 +1827,12 @@ public:
|
|||||||
ShowQueryString(STR_EMPTY, STR_GROUP_RENAME_CAPTION, MAX_LENGTH_GROUP_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
|
ShowQueryString(STR_EMPTY, STR_GROUP_RENAME_CAPTION, MAX_LENGTH_GROUP_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ADI_TRACERESTRICT_SLOT_MGMT: {
|
||||||
|
extern void ShowTraceRestrictSlotWindow(CompanyID company);
|
||||||
|
ShowTraceRestrictSlotWindow(this->owner);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2059,6 +2081,7 @@ struct VehicleDetailsWindow : Window {
|
|||||||
Scrollbar *vscroll;
|
Scrollbar *vscroll;
|
||||||
bool vehicle_group_line_shown;
|
bool vehicle_group_line_shown;
|
||||||
bool vehicle_weight_ratio_line_shown;
|
bool vehicle_weight_ratio_line_shown;
|
||||||
|
bool vehicle_slots_line_shown;
|
||||||
|
|
||||||
/** Initialize a newly created vehicle details window */
|
/** Initialize a newly created vehicle details window */
|
||||||
VehicleDetailsWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
|
VehicleDetailsWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
|
||||||
@@ -2148,6 +2171,12 @@ struct VehicleDetailsWindow : Window {
|
|||||||
return (v->type == VEH_TRAIN && _settings_client.gui.show_train_weight_ratios_in_details);
|
return (v->type == VEH_TRAIN && _settings_client.gui.show_train_weight_ratios_in_details);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ShouldShowSlotsLine(const Vehicle *v) const
|
||||||
|
{
|
||||||
|
if (v->type != VEH_TRAIN) return false;
|
||||||
|
return HasBit(Train::From(v)->flags, VRF_HAVE_SLOT);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||||
{
|
{
|
||||||
switch (widget) {
|
switch (widget) {
|
||||||
@@ -2156,9 +2185,11 @@ struct VehicleDetailsWindow : Window {
|
|||||||
Dimension dim = { 0, 0 };
|
Dimension dim = { 0, 0 };
|
||||||
this->vehicle_group_line_shown = ShouldShowGroupLine(v);
|
this->vehicle_group_line_shown = ShouldShowGroupLine(v);
|
||||||
this->vehicle_weight_ratio_line_shown = ShouldShowWeightRatioLine(v);
|
this->vehicle_weight_ratio_line_shown = ShouldShowWeightRatioLine(v);
|
||||||
|
this->vehicle_slots_line_shown = ShouldShowSlotsLine(v);
|
||||||
int lines = 4;
|
int lines = 4;
|
||||||
if (this->vehicle_group_line_shown) lines++;
|
if (this->vehicle_group_line_shown) lines++;
|
||||||
if (this->vehicle_weight_ratio_line_shown) lines++;
|
if (this->vehicle_weight_ratio_line_shown) lines++;
|
||||||
|
if (this->vehicle_slots_line_shown) lines++;
|
||||||
size->height = WD_FRAMERECT_TOP + lines * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM;
|
size->height = WD_FRAMERECT_TOP + lines * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM;
|
||||||
|
|
||||||
for (uint i = 0; i < 5; i++) SetDParamMaxValue(i, INT16_MAX);
|
for (uint i = 0; i < 5; i++) SetDParamMaxValue(i, INT16_MAX);
|
||||||
@@ -2386,8 +2417,32 @@ struct VehicleDetailsWindow : Window {
|
|||||||
if (should_show_group) {
|
if (should_show_group) {
|
||||||
SetDParam(0, v->group_id);
|
SetDParam(0, v->group_id);
|
||||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_GROUP);
|
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_GROUP);
|
||||||
|
y += FONT_HEIGHT_NORMAL;
|
||||||
}
|
}
|
||||||
if (this->vehicle_group_line_shown != should_show_group || this->vehicle_weight_ratio_line_shown != should_show_weight_ratio) {
|
|
||||||
|
bool should_show_slots = this->ShouldShowSlotsLine(v);
|
||||||
|
if (should_show_slots) {
|
||||||
|
std::vector<TraceRestrictSlotID> slots;
|
||||||
|
TraceRestrictGetVehicleSlots(v->index, slots);
|
||||||
|
|
||||||
|
char text_buffer[512];
|
||||||
|
char *buffer = text_buffer;
|
||||||
|
const char * const last = lastof(text_buffer);
|
||||||
|
SetDParam(0, slots.size());
|
||||||
|
buffer = GetString(buffer, STR_TRACE_RESTRICT_SLOT_LIST_HEADER, last);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < slots.size(); i++) {
|
||||||
|
if (i != 0) buffer = GetString(buffer, STR_TRACE_RESTRICT_SLOT_LIST_SEPARATOR, last);
|
||||||
|
buffer = strecpy(buffer, TraceRestrictSlot::Get(slots[i])->name.c_str(), last);
|
||||||
|
}
|
||||||
|
SetDParamStr(0, text_buffer);
|
||||||
|
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_JUST_RAW_STRING);
|
||||||
|
y += FONT_HEIGHT_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->vehicle_weight_ratio_line_shown != should_show_weight_ratio ||
|
||||||
|
this->vehicle_weight_ratio_line_shown != should_show_weight_ratio ||
|
||||||
|
this->vehicle_slots_line_shown != should_show_slots) {
|
||||||
const_cast<VehicleDetailsWindow *>(this)->ReInit();
|
const_cast<VehicleDetailsWindow *>(this)->ReInit();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2975,7 +3030,7 @@ public:
|
|||||||
str = STR_VEHICLE_STATUS_STOPPED;
|
str = STR_VEHICLE_STATUS_STOPPED;
|
||||||
}
|
}
|
||||||
} else if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_TRAIN_STUCK) && !v->current_order.IsType(OT_LOADING)) {
|
} else if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_TRAIN_STUCK) && !v->current_order.IsType(OT_LOADING)) {
|
||||||
str = STR_VEHICLE_STATUS_TRAIN_STUCK;
|
str = HasBit(Train::From(v)->flags, VRF_WAITING_RESTRICTION) ? STR_VEHICLE_STATUS_TRAIN_STUCK_WAIT_RESTRICTION : STR_VEHICLE_STATUS_TRAIN_STUCK;
|
||||||
} else if (v->type == VEH_AIRCRAFT && HasBit(Aircraft::From(v)->flags, VAF_DEST_TOO_FAR) && !v->current_order.IsType(OT_LOADING)) {
|
} else if (v->type == VEH_AIRCRAFT && HasBit(Aircraft::From(v)->flags, VAF_DEST_TOO_FAR) && !v->current_order.IsType(OT_LOADING)) {
|
||||||
str = STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR;
|
str = STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR;
|
||||||
} else { // vehicle is in a "normal" state, show current order
|
} else { // vehicle is in a "normal" state, show current order
|
||||||
|
@@ -35,6 +35,7 @@ struct BaseVehicleListWindow : public Window {
|
|||||||
ADI_REMOVE_ALL,
|
ADI_REMOVE_ALL,
|
||||||
ADI_CHANGE_ORDER,
|
ADI_CHANGE_ORDER,
|
||||||
ADI_CREATE_GROUP,
|
ADI_CREATE_GROUP,
|
||||||
|
ADI_TRACERESTRICT_SLOT_MGMT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const StringID vehicle_depot_name[];
|
static const StringID vehicle_depot_name[];
|
||||||
@@ -53,6 +54,7 @@ struct BaseVehicleListWindow : public Window {
|
|||||||
Dimension GetActionDropdownSize(bool show_autoreplace, bool show_group, bool show_template_replace, StringID change_order_str = 0);
|
Dimension GetActionDropdownSize(bool show_autoreplace, bool show_group, bool show_template_replace, StringID change_order_str = 0);
|
||||||
DropDownList *BuildActionDropdownList(bool show_autoreplace, bool show_group, bool show_template_replace,
|
DropDownList *BuildActionDropdownList(bool show_autoreplace, bool show_group, bool show_template_replace,
|
||||||
StringID change_order_str = 0, bool show_create_group = false);
|
StringID change_order_str = 0, bool show_create_group = false);
|
||||||
|
bool ShouldShowActionDropdownList() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint GetVehicleListHeight(VehicleType type, uint divisor = 1);
|
uint GetVehicleListHeight(VehicleType type, uint divisor = 1);
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include "train.h"
|
#include "train.h"
|
||||||
#include "vehiclelist.h"
|
#include "vehiclelist.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
|
#include "tracerestrict.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
@@ -119,6 +120,14 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli
|
|||||||
|
|
||||||
const Vehicle *v;
|
const Vehicle *v;
|
||||||
|
|
||||||
|
auto fill_all_vehicles = [&]() {
|
||||||
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
if (!HasBit(v->subtype, GVSF_VIRTUAL) && v->type == vli.vtype && v->owner == vli.company && v->IsPrimaryVehicle()) {
|
||||||
|
*list->Append() = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
switch (vli.type) {
|
switch (vli.type) {
|
||||||
case VL_STATION_LIST:
|
case VL_STATION_LIST:
|
||||||
FOR_ALL_VEHICLES(v) {
|
FOR_ALL_VEHICLES(v) {
|
||||||
@@ -156,14 +165,11 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* FALL THROUGH */
|
fill_all_vehicles();
|
||||||
|
break;
|
||||||
|
|
||||||
case VL_STANDARD:
|
case VL_STANDARD:
|
||||||
FOR_ALL_VEHICLES(v) {
|
fill_all_vehicles();
|
||||||
if (!HasBit(v->subtype, GVSF_VIRTUAL) && v->type == vli.vtype && v->owner == vli.company && v->IsPrimaryVehicle()) {
|
|
||||||
*list->Append() = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VL_DEPOT_LIST:
|
case VL_DEPOT_LIST:
|
||||||
@@ -181,6 +187,19 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VL_SLOT_LIST: {
|
||||||
|
if (vli.index == ALL_TRAINS_TRACE_RESTRICT_SLOT_ID) {
|
||||||
|
fill_all_vehicles();
|
||||||
|
} else {
|
||||||
|
const TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(vli.index);
|
||||||
|
if (slot == NULL) return false;
|
||||||
|
for (VehicleID id : slot->occupants) {
|
||||||
|
*list->Append() = Vehicle::Get(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ enum VehicleListType {
|
|||||||
VL_STATION_LIST,
|
VL_STATION_LIST,
|
||||||
VL_DEPOT_LIST,
|
VL_DEPOT_LIST,
|
||||||
VL_GROUP_LIST,
|
VL_GROUP_LIST,
|
||||||
|
VL_SLOT_LIST,
|
||||||
VLT_END
|
VLT_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -712,6 +712,12 @@ enum WindowClass {
|
|||||||
*/
|
*/
|
||||||
WC_TRACE_RESTRICT,
|
WC_TRACE_RESTRICT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trace restrict slot window; %Window numbers:
|
||||||
|
* - Packed value = #SlotListWidgets / #VehicleListWidgets
|
||||||
|
*/
|
||||||
|
WC_TRACE_RESTRICT_SLOTS,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Programmable signals window
|
* Programmable signals window
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user