Merge branch 'tracerestrict' into tracerestrict-sx
Conflicts: src/tracerestrict_gui.cpp
This commit is contained in:
@@ -2391,6 +2391,8 @@ STR_TRACE_RESTRICT_VARIABLE_NEXT_ORDER :next order
|
|||||||
STR_TRACE_RESTRICT_VARIABLE_LAST_VISITED_STATION :last visited station
|
STR_TRACE_RESTRICT_VARIABLE_LAST_VISITED_STATION :last visited station
|
||||||
STR_TRACE_RESTRICT_VARIABLE_CARGO :cargo
|
STR_TRACE_RESTRICT_VARIABLE_CARGO :cargo
|
||||||
STR_TRACE_RESTRICT_VARIABLE_ENTRY_DIRECTION :entry direction
|
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_LONG :entered signal of PBS block
|
||||||
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED :undefined
|
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED :undefined
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_INTEGER :{STRING} {STRING} {STRING} {COMMA} then
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_INTEGER :{STRING} {STRING} {STRING} {COMMA} then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_SPEED :{STRING} {STRING} {STRING} {VELOCITY} then
|
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_SPEED :{STRING} {STRING} {STRING} {VELOCITY} then
|
||||||
@@ -2400,6 +2402,7 @@ STR_TRACE_RESTRICT_CONDITIONAL_ORDER_DEPOT :{STRING} {STRIN
|
|||||||
STR_TRACE_RESTRICT_CONDITIONAL_CARGO :{STRING} train {STRING} cargo: {STRING} then
|
STR_TRACE_RESTRICT_CONDITIONAL_CARGO :{STRING} train {STRING} cargo: {STRING} then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_ENTRY_DIRECTION :{STRING} train {STRING} entering from {STRING} tile edge then
|
STR_TRACE_RESTRICT_CONDITIONAL_ENTRY_DIRECTION :{STRING} train {STRING} entering from {STRING} tile edge then
|
||||||
STR_TRACE_RESTRICT_CONDITIONAL_ENTRY_SIGNAL_FACE :{STRING} train {STRING} entering from {STRING} of signal then
|
STR_TRACE_RESTRICT_CONDITIONAL_ENTRY_SIGNAL_FACE :{STRING} train {STRING} entering from {STRING} of signal then
|
||||||
|
STR_TRACE_RESTRICT_CONDITIONAL_TILE_INDEX :{STRING} {STRING} {STRING} at {NUM} x {NUM} 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}
|
||||||
@@ -2431,6 +2434,7 @@ STR_TRACE_RESTRICT_COPY :{BLACK}Copy
|
|||||||
STR_TRACE_RESTRICT_SHARE :{BLACK}Share
|
STR_TRACE_RESTRICT_SHARE :{BLACK}Share
|
||||||
STR_TRACE_RESTRICT_UNSHARE :{BLACK}Unshare
|
STR_TRACE_RESTRICT_UNSHARE :{BLACK}Unshare
|
||||||
STR_TRACE_RESTRICT_SELECT_TARGET :{BLACK}Select Target
|
STR_TRACE_RESTRICT_SELECT_TARGET :{BLACK}Select Target
|
||||||
|
STR_TRACE_RESTRICT_SELECT_SIGNAL :{BLACK}Select Signal
|
||||||
STR_TRACE_RESTRICT_INSERT_TOOLTIP :{BLACK}Insert an instruction
|
STR_TRACE_RESTRICT_INSERT_TOOLTIP :{BLACK}Insert an instruction
|
||||||
STR_TRACE_RESTRICT_REMOVE_TOOLTIP :{BLACK}Remove the selected instruction
|
STR_TRACE_RESTRICT_REMOVE_TOOLTIP :{BLACK}Remove the selected instruction
|
||||||
STR_TRACE_RESTRICT_RESET_TOOLTIP :{BLACK}Reset the current signal (without affecting shared programs)
|
STR_TRACE_RESTRICT_RESET_TOOLTIP :{BLACK}Reset the current signal (without affecting shared programs)
|
||||||
|
@@ -189,12 +189,88 @@ private:
|
|||||||
IsRestrictedSignal(tile);
|
IsRestrictedSignal(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called to retrieve the previous signal, as required
|
||||||
|
* This is not run all the time as it is somewhat expensive and most restrictions will not test for the previous signal
|
||||||
|
*/
|
||||||
|
static TileIndex TraceRestrictPreviousSignalCallback(const Train *v, const void *node_ptr)
|
||||||
|
{
|
||||||
|
const Node *node = static_cast<const Node *>(node_ptr);
|
||||||
|
for (;;) {
|
||||||
|
TileIndex last_signal_tile = node->m_segment->m_last_signal_tile;
|
||||||
|
if (last_signal_tile != INVALID_TILE) {
|
||||||
|
Trackdir last_signal_trackdir = node->m_segment->m_last_signal_td;
|
||||||
|
if (HasPbsSignalOnTrackdir(last_signal_tile, last_signal_trackdir)) {
|
||||||
|
return last_signal_tile;
|
||||||
|
} else {
|
||||||
|
return INVALID_TILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->m_parent) {
|
||||||
|
node = node->m_parent;
|
||||||
|
} else {
|
||||||
|
// scan forwards from vehicle position, for the case that train is waiting at/approaching PBS signal
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: can this be made more efficient?
|
||||||
|
* This track scan will have been performed upstack, however extracting the entry signal
|
||||||
|
* during that scan and passing it through to this point would likely require relatively
|
||||||
|
* invasive changes to the pathfinder code, or at least an extra param on a number of wrapper
|
||||||
|
* functions between there and here, which would be best avoided.
|
||||||
|
*/
|
||||||
|
|
||||||
|
TileIndex origin_tile = node->GetTile();
|
||||||
|
Trackdir origin_trackdir = node->GetTrackdir();
|
||||||
|
|
||||||
|
TileIndex tile = v->tile;
|
||||||
|
Trackdir trackdir = v->GetVehicleTrackdir();
|
||||||
|
|
||||||
|
CFollowTrackRail ft(v);
|
||||||
|
|
||||||
|
TileIndex candidate_tile = INVALID_TILE;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir)) {
|
||||||
|
if (HasPbsSignalOnTrackdir(tile, trackdir)) {
|
||||||
|
// found PBS signal
|
||||||
|
candidate_tile = tile;
|
||||||
|
} else {
|
||||||
|
// wrong type of signal
|
||||||
|
candidate_tile = INVALID_TILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile == origin_tile && trackdir == origin_trackdir) {
|
||||||
|
// reached pathfinder origin
|
||||||
|
return candidate_tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
// advance to next tile
|
||||||
|
if (!ft.Follow(tile, trackdir)) {
|
||||||
|
// ran out of track
|
||||||
|
return INVALID_TILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KillFirstBit(ft.m_new_td_bits) != TRACKDIR_BIT_NONE) {
|
||||||
|
// reached a junction tile
|
||||||
|
return INVALID_TILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
tile = ft.m_new_tile;
|
||||||
|
trackdir = FindFirstTrackdir(ft.m_new_td_bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
// returns true if dead end bit has been set
|
// returns true if dead end bit has been set
|
||||||
inline bool ExecuteTraceRestrict(Node& n, TileIndex tile, Trackdir trackdir, int& cost, TraceRestrictProgramResult &out)
|
inline bool ExecuteTraceRestrict(Node& n, TileIndex tile, Trackdir trackdir, int& cost, TraceRestrictProgramResult &out)
|
||||||
{
|
{
|
||||||
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, TrackdirToTrack(trackdir));
|
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, TrackdirToTrack(trackdir));
|
||||||
if (prog) {
|
if (prog) {
|
||||||
prog->Execute(Yapf().GetVehicle(), TraceRestrictProgramInput(tile, trackdir), out);
|
prog->Execute(Yapf().GetVehicle(), TraceRestrictProgramInput(tile, trackdir, &TraceRestrictPreviousSignalCallback, &n), out);
|
||||||
if (out.flags & TRPRF_DENY) {
|
if (out.flags & TRPRF_DENY) {
|
||||||
n.m_segment->m_end_segment_reason |= ESRB_DEAD_END;
|
n.m_segment->m_end_segment_reason |= ESRB_DEAD_END;
|
||||||
return true;
|
return true;
|
||||||
|
@@ -217,6 +217,9 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
|
|||||||
static std::vector<TraceRestrictCondStackFlags> condstack;
|
static std::vector<TraceRestrictCondStackFlags> condstack;
|
||||||
condstack.clear();
|
condstack.clear();
|
||||||
|
|
||||||
|
bool have_previous_signal = false;
|
||||||
|
TileIndex previous_signal_tile = INVALID_TILE;
|
||||||
|
|
||||||
size_t size = this->items.size();
|
size_t size = this->items.size();
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
TraceRestrictItem item = this->items[i];
|
TraceRestrictItem item = this->items[i];
|
||||||
@@ -313,6 +316,22 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TRIT_COND_PBS_ENTRY_SIGNAL: {
|
||||||
|
// TRVT_TILE_INDEX value type uses the next slot
|
||||||
|
i++;
|
||||||
|
uint32_t signal_tile = this->items[i];
|
||||||
|
if (!have_previous_signal) {
|
||||||
|
if (input.previous_signal_callback) {
|
||||||
|
previous_signal_tile = input.previous_signal_callback(v, input.previous_signal_ptr);
|
||||||
|
}
|
||||||
|
have_previous_signal = true;
|
||||||
|
}
|
||||||
|
bool match = (signal_tile != INVALID_TILE)
|
||||||
|
&& (previous_signal_tile == signal_tile);
|
||||||
|
result = TestBinaryConditionCommon(item, match);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
@@ -395,6 +414,14 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
|
|||||||
}
|
}
|
||||||
HandleCondition(condstack, condflags, true);
|
HandleCondition(condstack, condflags, true);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// check multi-word instructions
|
||||||
|
if (IsTraceRestrictDoubleItem(item)) {
|
||||||
|
i++;
|
||||||
|
if (i >= size) {
|
||||||
|
return_cmd_error(STR_TRACE_RESTRICT_ERROR_OFFSET_TOO_LARGE); // instruction ran off end
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!condstack.empty()) {
|
if(!condstack.empty()) {
|
||||||
@@ -403,6 +430,35 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
|
|||||||
return CommandCost();
|
return CommandCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an instruction index into an item array index
|
||||||
|
*/
|
||||||
|
size_t TraceRestrictProgram::InstructionOffsetToArrayOffset(const std::vector<TraceRestrictItem> &items, size_t offset)
|
||||||
|
{
|
||||||
|
size_t output_offset = 0;
|
||||||
|
size_t size = items.size();
|
||||||
|
for (size_t i = 0; i < offset && output_offset < size; i++, output_offset++) {
|
||||||
|
if (IsTraceRestrictDoubleItem(items[output_offset])) {
|
||||||
|
output_offset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an item array index into an instruction index
|
||||||
|
*/
|
||||||
|
size_t TraceRestrictProgram::ArrayOffsetToInstructionOffset(const std::vector<TraceRestrictItem> &items, size_t offset)
|
||||||
|
{
|
||||||
|
size_t output_offset = 0;
|
||||||
|
for (size_t i = 0; i < offset; i++, output_offset++) {
|
||||||
|
if (IsTraceRestrictDoubleItem(items[i])) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output_offset;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value and aux field of @p item, as per the value type in @p value_type
|
* Set the value and aux field of @p item, as per the value type in @p value_type
|
||||||
*/
|
*/
|
||||||
@@ -413,6 +469,7 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp
|
|||||||
case TRVT_INT:
|
case TRVT_INT:
|
||||||
case TRVT_DENY:
|
case TRVT_DENY:
|
||||||
case TRVT_SPEED:
|
case TRVT_SPEED:
|
||||||
|
case TRVT_TILE_INDEX:
|
||||||
SetTraceRestrictValue(item, 0);
|
SetTraceRestrictValue(item, 0);
|
||||||
SetTraceRestrictAuxField(item, 0);
|
SetTraceRestrictAuxField(item, 0);
|
||||||
break;
|
break;
|
||||||
@@ -595,6 +652,21 @@ static CommandCost TraceRestrictCheckTileIsUsable(TileIndex tile, Track track)
|
|||||||
return CommandCost();
|
return CommandCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an appropriate default value for the second item of a dual-item instruction
|
||||||
|
* @p item is the first item of the instruction
|
||||||
|
*/
|
||||||
|
static uint32 GetDualInstructionInitialValue(TraceRestrictItem item)
|
||||||
|
{
|
||||||
|
switch (GetTraceRestrictType(item)) {
|
||||||
|
case TRIT_COND_PBS_ENTRY_SIGNAL:
|
||||||
|
return INVALID_TILE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main command for editing a signal tracerestrict program.
|
* The main command for editing a signal tracerestrict program.
|
||||||
* @param tile The tile which contains the signal.
|
* @param tile The tile which contains the signal.
|
||||||
@@ -641,28 +713,46 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TRDCT_INSERT_ITEM:
|
case TRDCT_INSERT_ITEM:
|
||||||
items.insert(items.begin() + offset, item);
|
items.insert(TraceRestrictProgram::InstructionAt(items, offset), item);
|
||||||
if (IsTraceRestrictConditional(item) &&
|
if (IsTraceRestrictConditional(item) &&
|
||||||
GetTraceRestrictCondFlags(item) == 0 &&
|
GetTraceRestrictCondFlags(item) == 0 &&
|
||||||
GetTraceRestrictType(item) != TRIT_COND_ENDIF) {
|
GetTraceRestrictType(item) != TRIT_COND_ENDIF) {
|
||||||
// this is an opening if block, insert a corresponding end if
|
// this is an opening if block, insert a corresponding end if
|
||||||
TraceRestrictItem endif_item = 0;
|
TraceRestrictItem endif_item = 0;
|
||||||
SetTraceRestrictType(endif_item, TRIT_COND_ENDIF);
|
SetTraceRestrictType(endif_item, TRIT_COND_ENDIF);
|
||||||
items.insert(items.begin() + offset + 1, endif_item);
|
items.insert(TraceRestrictProgram::InstructionAt(items, offset) + 1, endif_item);
|
||||||
|
} else if (IsTraceRestrictDoubleItem(item)) {
|
||||||
|
items.insert(TraceRestrictProgram::InstructionAt(items, offset) + 1, GetDualInstructionInitialValue(item));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRDCT_MODIFY_ITEM: {
|
case TRDCT_MODIFY_ITEM: {
|
||||||
TraceRestrictItem old_item = items[offset];
|
std::vector<TraceRestrictItem>::iterator old_item = TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
if (IsTraceRestrictConditional(old_item) != IsTraceRestrictConditional(item)) {
|
if (IsTraceRestrictConditional(*old_item) != IsTraceRestrictConditional(item)) {
|
||||||
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_CHANGE_CONDITIONALITY);
|
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_CHANGE_CONDITIONALITY);
|
||||||
}
|
}
|
||||||
items[offset] = item;
|
bool old_is_dual = IsTraceRestrictDoubleItem(*old_item);
|
||||||
|
bool new_is_dual = IsTraceRestrictDoubleItem(item);
|
||||||
|
*old_item = item;
|
||||||
|
if (old_is_dual && !new_is_dual) {
|
||||||
|
items.erase(old_item + 1);
|
||||||
|
} else if (!old_is_dual && new_is_dual) {
|
||||||
|
items.insert(old_item + 1, GetDualInstructionInitialValue(item));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TRDCT_MODIFY_DUAL_ITEM: {
|
||||||
|
std::vector<TraceRestrictItem>::iterator old_item = TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
|
if (!IsTraceRestrictDoubleItem(*old_item)) {
|
||||||
|
return CMD_ERROR;
|
||||||
|
}
|
||||||
|
*(old_item + 1) = p2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TRDCT_REMOVE_ITEM: {
|
case TRDCT_REMOVE_ITEM: {
|
||||||
TraceRestrictItem old_item = items[offset];
|
TraceRestrictItem old_item = *TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
if (IsTraceRestrictConditional(old_item)) {
|
if (IsTraceRestrictConditional(old_item)) {
|
||||||
bool remove_whole_block = false;
|
bool remove_whole_block = false;
|
||||||
if (GetTraceRestrictCondFlags(old_item) == 0) {
|
if (GetTraceRestrictCondFlags(old_item) == 0) {
|
||||||
@@ -676,7 +766,7 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 recursion_depth = 1;
|
uint32 recursion_depth = 1;
|
||||||
std::vector<TraceRestrictItem>::iterator remove_start = items.begin() + offset;
|
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
std::vector<TraceRestrictItem>::iterator remove_end = remove_start + 1;
|
std::vector<TraceRestrictItem>::iterator remove_end = remove_start + 1;
|
||||||
|
|
||||||
// iterate until matching end block found
|
// iterate until matching end block found
|
||||||
@@ -709,12 +799,22 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (IsTraceRestrictDoubleItem(current_item)) {
|
||||||
|
// this is a double-item, jump over the next item as well
|
||||||
|
++remove_end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (recursion_depth != 0) return CMD_ERROR; // ran off the end
|
if (recursion_depth != 0) return CMD_ERROR; // ran off the end
|
||||||
items.erase(remove_start, remove_end);
|
items.erase(remove_start, remove_end);
|
||||||
} else {
|
} else {
|
||||||
items.erase(items.begin() + offset);
|
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
|
std::vector<TraceRestrictItem>::iterator remove_end = remove_start + 1;
|
||||||
|
|
||||||
|
if (IsTraceRestrictDoubleItem(old_item)) {
|
||||||
|
// this is a double-item, remove the next item as well
|
||||||
|
++remove_end;
|
||||||
|
}
|
||||||
|
items.erase(remove_start, remove_end);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -106,6 +106,7 @@ enum TraceRestrictItemType {
|
|||||||
TRIT_COND_LAST_STATION = 14, ///< Test train last visited station
|
TRIT_COND_LAST_STATION = 14, ///< Test train last visited station
|
||||||
TRIT_COND_CARGO = 15, ///< Test if train can carry cargo type
|
TRIT_COND_CARGO = 15, ///< Test if train can carry cargo type
|
||||||
TRIT_COND_ENTRY_DIRECTION = 16, ///< Test which side of signal/signal tile is being entered from
|
TRIT_COND_ENTRY_DIRECTION = 16, ///< Test which side of signal/signal tile is being entered from
|
||||||
|
TRIT_COND_PBS_ENTRY_SIGNAL = 17, ///< Test tile and PBS-state of previous signal
|
||||||
/* space up to 31 */
|
/* space up to 31 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -176,11 +177,15 @@ DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramResultFlags)
|
|||||||
* Execution input of a TraceRestrictProgram
|
* Execution input of a TraceRestrictProgram
|
||||||
*/
|
*/
|
||||||
struct TraceRestrictProgramInput {
|
struct TraceRestrictProgramInput {
|
||||||
TileIndex tile; ///< Tile of restrict signal, for direction testing
|
typedef TileIndex PreviousSignalProc(const Train *v, const void *ptr);
|
||||||
Trackdir trackdir; ///< Track direction on tile of restrict signal, for direction testing
|
|
||||||
|
|
||||||
TraceRestrictProgramInput(TileIndex tile_, Trackdir trackdir_)
|
TileIndex tile; ///< Tile of restrict signal, for direction testing
|
||||||
: tile(tile_), trackdir(trackdir_) { }
|
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
|
||||||
|
const void *previous_signal_ptr; ///< Opaque pointer suitable to be passed to previous_signal_callback
|
||||||
|
|
||||||
|
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_) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -216,6 +221,46 @@ struct TraceRestrictProgram : TraceRestrictProgramPool::PoolItem<&_tracerestrict
|
|||||||
|
|
||||||
static CommandCost Validate(const std::vector<TraceRestrictItem> &items);
|
static CommandCost Validate(const std::vector<TraceRestrictItem> &items);
|
||||||
|
|
||||||
|
static size_t InstructionOffsetToArrayOffset(const std::vector<TraceRestrictItem> &items, size_t offset);
|
||||||
|
|
||||||
|
static size_t ArrayOffsetToInstructionOffset(const std::vector<TraceRestrictItem> &items, size_t offset);
|
||||||
|
|
||||||
|
/** Call InstructionOffsetToArrayOffset on current program instruction list */
|
||||||
|
size_t InstructionOffsetToArrayOffset(size_t offset) const
|
||||||
|
{
|
||||||
|
return TraceRestrictProgram::InstructionOffsetToArrayOffset(this->items, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Call ArrayOffsetToInstructionOffset on current program instruction list */
|
||||||
|
size_t ArrayOffsetToInstructionOffset(size_t offset) const
|
||||||
|
{
|
||||||
|
return TraceRestrictProgram::ArrayOffsetToInstructionOffset(this->items, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get number of instructions in @p items */
|
||||||
|
static size_t GetInstructionCount(const std::vector<TraceRestrictItem> &items)
|
||||||
|
{
|
||||||
|
return ArrayOffsetToInstructionOffset(items, items.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Call GetInstructionCount on current program instruction list */
|
||||||
|
size_t GetInstructionCount() const
|
||||||
|
{
|
||||||
|
return TraceRestrictProgram::GetInstructionCount(this->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get an iterator to the instruction at a given @p instruction_offset in @p items */
|
||||||
|
static std::vector<TraceRestrictItem>::iterator InstructionAt(std::vector<TraceRestrictItem> &items, size_t instruction_offset)
|
||||||
|
{
|
||||||
|
return items.begin() + TraceRestrictProgram::InstructionOffsetToArrayOffset(items, instruction_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get a const_iterator to the instruction at a given @p instruction_offset in @p items */
|
||||||
|
static std::vector<TraceRestrictItem>::const_iterator InstructionAt(const std::vector<TraceRestrictItem> &items, size_t instruction_offset)
|
||||||
|
{
|
||||||
|
return items.begin() + TraceRestrictProgram::InstructionOffsetToArrayOffset(items, instruction_offset);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call validation function on current program instruction list
|
* Call validation function on current program instruction list
|
||||||
*/
|
*/
|
||||||
@@ -294,6 +339,12 @@ static inline bool IsTraceRestrictConditional(TraceRestrictItem item)
|
|||||||
return IsTraceRestrictTypeConditional(GetTraceRestrictType(item));
|
return IsTraceRestrictTypeConditional(GetTraceRestrictType(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Is TraceRestrictItem a double-item type? */
|
||||||
|
static inline bool IsTraceRestrictDoubleItem(TraceRestrictItem item)
|
||||||
|
{
|
||||||
|
return GetTraceRestrictType(item) == TRIT_COND_PBS_ENTRY_SIGNAL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Categorisation of what is allowed in the TraceRestrictItem condition op field
|
* Categorisation of what is allowed in the TraceRestrictItem condition op field
|
||||||
* see TraceRestrictTypePropertySet
|
* see TraceRestrictTypePropertySet
|
||||||
@@ -317,6 +368,7 @@ enum TraceRestrictValueType {
|
|||||||
TRVT_ORDER = 5, ///< takes an order target ID, as per the auxiliary field as type: TraceRestrictOrderCondAuxField
|
TRVT_ORDER = 5, ///< takes an order target ID, as per the auxiliary field as type: TraceRestrictOrderCondAuxField
|
||||||
TRVT_CARGO_ID = 6, ///< takes a CargoID
|
TRVT_CARGO_ID = 6, ///< takes a CargoID
|
||||||
TRVT_DIRECTION = 7, ///< takes a TraceRestrictDirectionTypeSpecialValue
|
TRVT_DIRECTION = 7, ///< takes a TraceRestrictDirectionTypeSpecialValue
|
||||||
|
TRVT_TILE_INDEX = 8, ///< takes a TileIndex in the next item slot
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -373,6 +425,11 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR
|
|||||||
out.cond_type = TRCOT_BINARY;
|
out.cond_type = TRCOT_BINARY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRIT_COND_PBS_ENTRY_SIGNAL:
|
||||||
|
out.value_type = TRVT_TILE_INDEX;
|
||||||
|
out.cond_type = TRCOT_BINARY;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
break;
|
break;
|
||||||
@@ -432,14 +489,15 @@ static inline const TraceRestrictProgram *GetExistingTraceRestrictProgram(TileIn
|
|||||||
* Enumeration for command action type field, indicates what command to do
|
* Enumeration for command action type field, indicates what command to do
|
||||||
*/
|
*/
|
||||||
enum TraceRestrictDoCommandType {
|
enum TraceRestrictDoCommandType {
|
||||||
TRDCT_INSERT_ITEM = 0, ///< insert new instruction before offset field as given value
|
TRDCT_INSERT_ITEM, ///< insert new instruction before offset field as given value
|
||||||
TRDCT_MODIFY_ITEM = 1, ///< modify instruction at offset field to given value
|
TRDCT_MODIFY_ITEM, ///< modify instruction at offset field to given value
|
||||||
TRDCT_REMOVE_ITEM = 2, ///< remove instruction at offset field
|
TRDCT_MODIFY_DUAL_ITEM, ///< modify second item of dual-part instruction at offset field to given value
|
||||||
|
TRDCT_REMOVE_ITEM, ///< remove instruction at offset field
|
||||||
|
|
||||||
TRDCT_PROG_COPY = 3, ///< copy program operation. Do not re-order this with respect to other values
|
TRDCT_PROG_COPY, ///< copy program operation. Do not re-order this with respect to other values
|
||||||
TRDCT_PROG_SHARE = 4, ///< share program operation
|
TRDCT_PROG_SHARE, ///< share program operation
|
||||||
TRDCT_PROG_UNSHARE = 5, ///< unshare program (copy as a new program)
|
TRDCT_PROG_UNSHARE, ///< unshare program (copy as a new program)
|
||||||
TRDCT_PROG_RESET = 6, ///< reset program state of signal
|
TRDCT_PROG_RESET, ///< reset program state of signal
|
||||||
};
|
};
|
||||||
|
|
||||||
void TraceRestrictDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, uint32 offset, uint32 value, StringID error_msg);
|
void TraceRestrictDoCommandP(TileIndex tile, Track track, TraceRestrictDoCommandType type, uint32 offset, uint32 value, StringID error_msg);
|
||||||
|
@@ -57,6 +57,7 @@ enum TraceRestrictWindowWidgets {
|
|||||||
TR_WIDGET_VALUE_INT,
|
TR_WIDGET_VALUE_INT,
|
||||||
TR_WIDGET_VALUE_DROPDOWN,
|
TR_WIDGET_VALUE_DROPDOWN,
|
||||||
TR_WIDGET_VALUE_DEST,
|
TR_WIDGET_VALUE_DEST,
|
||||||
|
TR_WIDGET_VALUE_SIGNAL,
|
||||||
|
|
||||||
TR_WIDGET_BLANK_L2,
|
TR_WIDGET_BLANK_L2,
|
||||||
TR_WIDGET_BLANK_L,
|
TR_WIDGET_BLANK_L,
|
||||||
@@ -91,6 +92,7 @@ enum PanelWidgets {
|
|||||||
DPR_VALUE_INT = 0,
|
DPR_VALUE_INT = 0,
|
||||||
DPR_VALUE_DROPDOWN,
|
DPR_VALUE_DROPDOWN,
|
||||||
DPR_VALUE_DEST,
|
DPR_VALUE_DEST,
|
||||||
|
DPR_VALUE_SIGNAL,
|
||||||
DPR_BLANK,
|
DPR_BLANK,
|
||||||
|
|
||||||
// Share
|
// Share
|
||||||
@@ -225,6 +227,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictI
|
|||||||
STR_TRACE_RESTRICT_VARIABLE_LAST_VISITED_STATION,
|
STR_TRACE_RESTRICT_VARIABLE_LAST_VISITED_STATION,
|
||||||
STR_TRACE_RESTRICT_VARIABLE_CARGO,
|
STR_TRACE_RESTRICT_VARIABLE_CARGO,
|
||||||
STR_TRACE_RESTRICT_VARIABLE_ENTRY_DIRECTION,
|
STR_TRACE_RESTRICT_VARIABLE_ENTRY_DIRECTION,
|
||||||
|
STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL,
|
||||||
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED,
|
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED,
|
||||||
INVALID_STRING_ID,
|
INVALID_STRING_ID,
|
||||||
};
|
};
|
||||||
@@ -236,6 +239,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictI
|
|||||||
TRIT_COND_LAST_STATION,
|
TRIT_COND_LAST_STATION,
|
||||||
TRIT_COND_CARGO,
|
TRIT_COND_CARGO,
|
||||||
TRIT_COND_ENTRY_DIRECTION,
|
TRIT_COND_ENTRY_DIRECTION,
|
||||||
|
TRIT_COND_PBS_ENTRY_SIGNAL,
|
||||||
TRIT_COND_UNDEFINED,
|
TRIT_COND_UNDEFINED,
|
||||||
};
|
};
|
||||||
static const TraceRestrictDropDownListSet set_cond = {
|
static const TraceRestrictDropDownListSet set_cond = {
|
||||||
@@ -436,16 +440,26 @@ static void DrawInstructionStringConditionalIntegerCommon(TraceRestrictItem item
|
|||||||
SetDParam(3, GetTraceRestrictValue(item));
|
SetDParam(3, GetTraceRestrictValue(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Common function for drawing an integer conditional instruction with an invalid value */
|
||||||
|
static void DrawInstructionStringConditionalInvalidValue(TraceRestrictItem item, const TraceRestrictTypePropertySet &properties, StringID &instruction_string, bool selected)
|
||||||
|
{
|
||||||
|
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_UNDEFINED;
|
||||||
|
DrawInstructionStringConditionalCommon(item, properties);
|
||||||
|
SetDParam(3, selected ? STR_TRACE_RESTRICT_WHITE : STR_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws an instruction in the programming GUI
|
* Draws an instruction in the programming GUI
|
||||||
* @param instruction The instruction to draw
|
* @param prog The program (may be NULL)
|
||||||
|
* @param item The instruction to draw
|
||||||
|
* @param index The instruction index
|
||||||
* @param y Y position for drawing
|
* @param y Y position for drawing
|
||||||
* @param selected True, if the order is selected
|
* @param selected True, if the order is selected
|
||||||
* @param indent How many levels the instruction is indented
|
* @param indent How many levels the instruction is indented
|
||||||
* @param left Left border for text drawing
|
* @param left Left border for text drawing
|
||||||
* @param right Right border for text drawing
|
* @param right Right border for text drawing
|
||||||
*/
|
*/
|
||||||
static void DrawInstructionString(TraceRestrictItem item, int y, bool selected, int indent, int left, int right)
|
static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestrictItem item, int index, int y, bool selected, int indent, int left, int right)
|
||||||
{
|
{
|
||||||
StringID instruction_string = INVALID_STRING_ID;
|
StringID instruction_string = INVALID_STRING_ID;
|
||||||
|
|
||||||
@@ -482,9 +496,7 @@ static void DrawInstructionString(TraceRestrictItem item, int y, bool selected,
|
|||||||
DrawInstructionStringConditionalIntegerCommon(item, properties);
|
DrawInstructionStringConditionalIntegerCommon(item, properties);
|
||||||
} else {
|
} else {
|
||||||
// this is an invalid station, use a seperate string
|
// this is an invalid station, use a seperate string
|
||||||
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_UNDEFINED;
|
DrawInstructionStringConditionalInvalidValue(item, properties, instruction_string, selected);
|
||||||
DrawInstructionStringConditionalCommon(item, properties);
|
|
||||||
SetDParam(3, selected ? STR_TRACE_RESTRICT_WHITE : STR_EMPTY);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -526,6 +538,23 @@ static void DrawInstructionString(TraceRestrictItem item, int y, bool selected,
|
|||||||
SetDParam(2, GetDropDownStringByValue(&_direction_value, GetTraceRestrictValue(item)));
|
SetDParam(2, GetDropDownStringByValue(&_direction_value, GetTraceRestrictValue(item)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRVT_TILE_INDEX: {
|
||||||
|
assert(prog != NULL);
|
||||||
|
assert(GetTraceRestrictType(item) == TRIT_COND_PBS_ENTRY_SIGNAL);
|
||||||
|
TileIndex tile = *(TraceRestrictProgram::InstructionAt(prog->items, index - 1) + 1);
|
||||||
|
if (tile == INVALID_TILE) {
|
||||||
|
DrawInstructionStringConditionalInvalidValue(item, properties, instruction_string, selected);
|
||||||
|
} else {
|
||||||
|
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_TILE_INDEX;
|
||||||
|
SetDParam(0, _program_cond_type[GetTraceRestrictCondFlags(item)]);
|
||||||
|
SetDParam(1, STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL_LONG);
|
||||||
|
SetDParam(2, GetDropDownStringByValue(GetCondOpDropDownListSet(properties), GetTraceRestrictCondOp(item)));
|
||||||
|
SetDParam(3, TileX(tile));
|
||||||
|
SetDParam(4, TileY(tile));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
break;
|
break;
|
||||||
@@ -757,6 +786,11 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TR_WIDGET_VALUE_SIGNAL: {
|
||||||
|
SetObjectToPlaceAction(widget, ANIMCURSOR_BUILDSIGNALS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TR_WIDGET_GOTO_SIGNAL:
|
case TR_WIDGET_GOTO_SIGNAL:
|
||||||
ScrollMainWindowToTile(this->tile);
|
ScrollMainWindowToTile(this->tile);
|
||||||
break;
|
break;
|
||||||
@@ -900,6 +934,10 @@ public:
|
|||||||
OnPlaceObjectDestination(pt, tile, widget, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
OnPlaceObjectDestination(pt, tile, widget, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TR_WIDGET_VALUE_SIGNAL:
|
||||||
|
OnPlaceObjectSignalTileValue(pt, tile, widget, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
break;
|
break;
|
||||||
@@ -996,6 +1034,32 @@ public:
|
|||||||
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_ITEM, this->selected_instruction - 1, item, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_ITEM, this->selected_instruction - 1, item, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common OnPlaceObject handler for instruction value modification actions which involve selecting a signal tile value
|
||||||
|
*/
|
||||||
|
void OnPlaceObjectSignalTileValue(Point pt, TileIndex tile, int widget, int error_message)
|
||||||
|
{
|
||||||
|
TraceRestrictItem item = GetSelected();
|
||||||
|
if (GetTraceRestrictTypeProperties(item).value_type != TRVT_TILE_INDEX) return;
|
||||||
|
|
||||||
|
if (!IsPlainRailTile(tile)) {
|
||||||
|
ShowErrorMessage(error_message, STR_ERROR_THERE_IS_NO_RAILROAD_TRACK, WL_INFO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetPresentSignals(tile) == 0) {
|
||||||
|
ShowErrorMessage(error_message, STR_ERROR_THERE_ARE_NO_SIGNALS, WL_INFO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsTileOwner(tile, _local_company)) {
|
||||||
|
ShowErrorMessage(error_message, STR_ERROR_AREA_IS_OWNED_BY_ANOTHER, WL_INFO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_DUAL_ITEM, this->selected_instruction - 1, tile, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void OnPlaceObjectAbort() OVERRIDE
|
virtual void OnPlaceObjectAbort() OVERRIDE
|
||||||
{
|
{
|
||||||
this->RaiseButtons();
|
this->RaiseButtons();
|
||||||
@@ -1053,7 +1117,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i >= scroll_position && this->vscroll->IsVisible(i)) {
|
if (i >= scroll_position && this->vscroll->IsVisible(i)) {
|
||||||
DrawInstructionString(item, y, i == this->selected_instruction, this_indent, r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT);
|
DrawInstructionString(prog, item, i, y, i == this->selected_instruction, this_indent, r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT);
|
||||||
y += line_height;
|
y += line_height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1109,7 +1173,7 @@ private:
|
|||||||
int GetItemCount(const TraceRestrictProgram *prog) const
|
int GetItemCount(const TraceRestrictProgram *prog) const
|
||||||
{
|
{
|
||||||
if (prog) {
|
if (prog) {
|
||||||
return 2 + prog->items.size();
|
return 2 + prog->GetInstructionCount();
|
||||||
} else {
|
} else {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@@ -1141,17 +1205,17 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (prog) {
|
if (prog) {
|
||||||
const std::vector<TraceRestrictItem> &items = prog->items;
|
size_t instruction_count = prog->GetInstructionCount();
|
||||||
|
|
||||||
if (static_cast<size_t>(index) == items.size() + 1) {
|
if (static_cast<size_t>(index) == instruction_count + 1) {
|
||||||
return MakeSpecialItem(TRNTSV_END);
|
return MakeSpecialItem(TRNTSV_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (static_cast<size_t>(index) > items.size() + 1) {
|
if (static_cast<size_t>(index) > instruction_count + 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return items[index - 1];
|
return prog->items[prog->InstructionOffsetToArrayOffset(index - 1)];
|
||||||
} else {
|
} else {
|
||||||
// No program defined, this is equivalent to an empty program
|
// No program defined, this is equivalent to an empty program
|
||||||
if (index == 1) {
|
if (index == 1) {
|
||||||
@@ -1230,6 +1294,7 @@ private:
|
|||||||
this->RaiseWidget(TR_WIDGET_VALUE_INT);
|
this->RaiseWidget(TR_WIDGET_VALUE_INT);
|
||||||
this->RaiseWidget(TR_WIDGET_VALUE_DROPDOWN);
|
this->RaiseWidget(TR_WIDGET_VALUE_DROPDOWN);
|
||||||
this->RaiseWidget(TR_WIDGET_VALUE_DEST);
|
this->RaiseWidget(TR_WIDGET_VALUE_DEST);
|
||||||
|
this->RaiseWidget(TR_WIDGET_VALUE_SIGNAL);
|
||||||
|
|
||||||
NWidgetStacked *left_2_sel = this->GetWidget<NWidgetStacked>(TR_WIDGET_SEL_TOP_LEFT_2);
|
NWidgetStacked *left_2_sel = this->GetWidget<NWidgetStacked>(TR_WIDGET_SEL_TOP_LEFT_2);
|
||||||
NWidgetStacked *left_sel = this->GetWidget<NWidgetStacked>(TR_WIDGET_SEL_TOP_LEFT);
|
NWidgetStacked *left_sel = this->GetWidget<NWidgetStacked>(TR_WIDGET_SEL_TOP_LEFT);
|
||||||
@@ -1244,6 +1309,7 @@ private:
|
|||||||
this->DisableWidget(TR_WIDGET_VALUE_INT);
|
this->DisableWidget(TR_WIDGET_VALUE_INT);
|
||||||
this->DisableWidget(TR_WIDGET_VALUE_DROPDOWN);
|
this->DisableWidget(TR_WIDGET_VALUE_DROPDOWN);
|
||||||
this->DisableWidget(TR_WIDGET_VALUE_DEST);
|
this->DisableWidget(TR_WIDGET_VALUE_DEST);
|
||||||
|
this->DisableWidget(TR_WIDGET_VALUE_SIGNAL);
|
||||||
|
|
||||||
this->DisableWidget(TR_WIDGET_INSERT);
|
this->DisableWidget(TR_WIDGET_INSERT);
|
||||||
this->DisableWidget(TR_WIDGET_REMOVE);
|
this->DisableWidget(TR_WIDGET_REMOVE);
|
||||||
@@ -1404,6 +1470,11 @@ private:
|
|||||||
GetDropDownStringByValue(&_direction_value, GetTraceRestrictValue(item));
|
GetDropDownStringByValue(&_direction_value, GetTraceRestrictValue(item));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRVT_TILE_INDEX:
|
||||||
|
right_sel->SetDisplayedPlane(DPR_VALUE_SIGNAL);
|
||||||
|
this->EnableWidget(TR_WIDGET_VALUE_SIGNAL);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1460,12 +1531,13 @@ private:
|
|||||||
|
|
||||||
std::vector<TraceRestrictItem> items = prog->items; // copy
|
std::vector<TraceRestrictItem> items = prog->items; // copy
|
||||||
|
|
||||||
if (offset >= (items.size() + (replace ? 0 : 1))) return false; // off the end of the program
|
if (offset >= (TraceRestrictProgram::GetInstructionCount(items) + (replace ? 0 : 1))) return false; // off the end of the program
|
||||||
|
|
||||||
|
uint array_offset = TraceRestrictProgram::InstructionOffsetToArrayOffset(items, offset);
|
||||||
if (replace) {
|
if (replace) {
|
||||||
items[offset] = item;
|
items[array_offset] = item;
|
||||||
} else {
|
} else {
|
||||||
items.insert(items.begin() + offset, item);
|
items.insert(items.begin() + array_offset, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TraceRestrictProgram::Validate(items).Succeeded();
|
return TraceRestrictProgram::Validate(items).Succeeded();
|
||||||
@@ -1539,6 +1611,8 @@ static const NWidgetPart _nested_program_widgets[] = {
|
|||||||
SetDataTip(STR_NULL, STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP), SetResize(1, 0),
|
SetDataTip(STR_NULL, STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP), SetResize(1, 0),
|
||||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_VALUE_DEST), SetMinimalSize(124, 12), SetFill(1, 0),
|
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_VALUE_DEST), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||||
SetDataTip(STR_TRACE_RESTRICT_SELECT_TARGET, STR_TRACE_RESTRICT_SELECT_TARGET), SetResize(1, 0),
|
SetDataTip(STR_TRACE_RESTRICT_SELECT_TARGET, STR_TRACE_RESTRICT_SELECT_TARGET), SetResize(1, 0),
|
||||||
|
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_VALUE_SIGNAL), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||||
|
SetDataTip(STR_TRACE_RESTRICT_SELECT_SIGNAL, STR_TRACE_RESTRICT_SELECT_SIGNAL), SetResize(1, 0),
|
||||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_BLANK_R), SetMinimalSize(124, 12), SetFill(1, 0),
|
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_BLANK_R), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||||
SetDataTip(STR_EMPTY, STR_NULL), SetResize(1, 0),
|
SetDataTip(STR_EMPTY, STR_NULL), SetResize(1, 0),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
|
Reference in New Issue
Block a user