Merge branch 'tracerestrict-sx' into jgrpp
This commit is contained in:
@@ -2602,6 +2602,8 @@ STR_TRACE_RESTRICT_UNDEFINED_COMPANY :Undefined compa
|
|||||||
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
|
||||||
|
STR_TRACE_RESTRICT_UP_BTN_TOOLTIP :{BLACK}Move the selected instruction up{}Ctrl+Click to move conditional instruction instead of whole block
|
||||||
|
STR_TRACE_RESTRICT_DOWN_BTN_TOOLTIP :{BLACK}Move the selected instruction down{}Ctrl+Click to move conditional instruction instead of whole block
|
||||||
STR_TRACE_RESTRICT_TYPE_TOOLTIP :{BLACK}Type
|
STR_TRACE_RESTRICT_TYPE_TOOLTIP :{BLACK}Type
|
||||||
STR_TRACE_RESTRICT_COND_COMPARATOR_TOOLTIP :{BLACK}Comparison operator
|
STR_TRACE_RESTRICT_COND_COMPARATOR_TOOLTIP :{BLACK}Comparison operator
|
||||||
STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP :{BLACK}Value
|
STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP :{BLACK}Value
|
||||||
@@ -2616,7 +2618,7 @@ 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_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{}Ctrl+Click to remove the selected conditional instruction but retain its contents
|
||||||
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)
|
||||||
STR_TRACE_RESTRICT_COPY_TOOLTIP :{BLACK}Copy program from another signal
|
STR_TRACE_RESTRICT_COPY_TOOLTIP :{BLACK}Copy program from another signal
|
||||||
STR_TRACE_RESTRICT_SHARE_TOOLTIP :{BLACK}Share program with another signal
|
STR_TRACE_RESTRICT_SHARE_TOOLTIP :{BLACK}Share program with another signal
|
||||||
@@ -2626,11 +2628,13 @@ STR_TRACE_RESTRICT_INSTRUCTION_LIST_TOOLTIP :{BLACK}Click an
|
|||||||
STR_TRACE_RESTRICT_ERROR_CAN_T_INSERT_ITEM :{WHITE}Can't insert instruction
|
STR_TRACE_RESTRICT_ERROR_CAN_T_INSERT_ITEM :{WHITE}Can't insert instruction
|
||||||
STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM :{WHITE}Can't modify instruction
|
STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM :{WHITE}Can't modify instruction
|
||||||
STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM :{WHITE}Can't remove instruction
|
STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM :{WHITE}Can't remove instruction
|
||||||
|
STR_TRACE_RESTRICT_ERROR_CAN_T_MOVE_ITEM :{WHITE}Can't move instruction
|
||||||
STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE :{WHITE}Value too large, maximum is {DECIMAL}
|
STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE :{WHITE}Value too large, maximum is {DECIMAL}
|
||||||
STR_TRACE_RESTRICT_ERROR_NO_PROGRAM :No trace restrict program exists
|
STR_TRACE_RESTRICT_ERROR_NO_PROGRAM :No trace restrict program exists
|
||||||
STR_TRACE_RESTRICT_ERROR_OFFSET_TOO_LARGE :Offset too large
|
STR_TRACE_RESTRICT_ERROR_OFFSET_TOO_LARGE :Offset too large
|
||||||
STR_TRACE_RESTRICT_ERROR_CAN_T_CHANGE_CONDITIONALITY :Can't change conditionality
|
STR_TRACE_RESTRICT_ERROR_CAN_T_CHANGE_CONDITIONALITY :Can't change conditionality
|
||||||
STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ENDIF :Can't remove an 'end if'
|
STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ENDIF :Can't remove an 'end if'
|
||||||
|
STR_TRACE_RESTRICT_ERROR_CAN_T_SHALLOW_REMOVE_IF_ELIF :Can't shallow remove an 'if' block with one or more 'else if', 'or if' or 'else' blocks
|
||||||
STR_TRACE_RESTRICT_ERROR_VALIDATE_END_CONDSTACK :Validation failed: condstack non-empty at exit
|
STR_TRACE_RESTRICT_ERROR_VALIDATE_END_CONDSTACK :Validation failed: condstack non-empty at exit
|
||||||
STR_TRACE_RESTRICT_ERROR_VALIDATE_NO_IF :Validation failed: else/endif without opening if
|
STR_TRACE_RESTRICT_ERROR_VALIDATE_NO_IF :Validation failed: else/endif without opening if
|
||||||
STR_TRACE_RESTRICT_ERROR_VALIDATE_DUP_ELSE :Validation failed: duplicate else
|
STR_TRACE_RESTRICT_ERROR_VALIDATE_DUP_ELSE :Validation failed: duplicate else
|
||||||
|
@@ -192,9 +192,9 @@ private:
|
|||||||
{
|
{
|
||||||
const Node *node = static_cast<const Node *>(node_ptr);
|
const Node *node = static_cast<const Node *>(node_ptr);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
TileIndex last_signal_tile = node->m_segment->m_last_signal_tile;
|
TileIndex last_signal_tile = node->m_last_non_reserve_through_signal_tile;
|
||||||
if (last_signal_tile != INVALID_TILE) {
|
if (last_signal_tile != INVALID_TILE) {
|
||||||
Trackdir last_signal_trackdir = node->m_segment->m_last_signal_td;
|
Trackdir last_signal_trackdir = node->m_last_non_reserve_through_signal_td;
|
||||||
if (HasPbsSignalOnTrackdir(last_signal_tile, last_signal_trackdir)) {
|
if (HasPbsSignalOnTrackdir(last_signal_tile, last_signal_trackdir)) {
|
||||||
return last_signal_tile;
|
return last_signal_tile;
|
||||||
} else {
|
} else {
|
||||||
@@ -348,14 +348,18 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_reserve_through = false;
|
||||||
if (ShouldCheckTraceRestrict(n, tile)) {
|
if (ShouldCheckTraceRestrict(n, tile)) {
|
||||||
TraceRestrictProgramResult out;
|
TraceRestrictProgramResult out;
|
||||||
bool is_reserve_through = false;
|
|
||||||
if (ExecuteTraceRestrict(n, tile, trackdir, cost, out, &is_reserve_through)) {
|
if (ExecuteTraceRestrict(n, tile, trackdir, cost, out, &is_reserve_through)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (is_reserve_through) n.m_num_signals_res_through_passed++;
|
if (is_reserve_through) n.m_num_signals_res_through_passed++;
|
||||||
}
|
}
|
||||||
|
if (!is_reserve_through) {
|
||||||
|
n.m_last_non_reserve_through_signal_tile = tile;
|
||||||
|
n.m_last_non_reserve_through_signal_td = trackdir;
|
||||||
|
}
|
||||||
|
|
||||||
n.m_num_signals_passed++;
|
n.m_num_signals_passed++;
|
||||||
n.m_segment->m_last_signal_tile = tile;
|
n.m_segment->m_last_signal_tile = tile;
|
||||||
|
@@ -129,6 +129,8 @@ struct CYapfRailNodeT
|
|||||||
CYapfRailSegment *m_segment;
|
CYapfRailSegment *m_segment;
|
||||||
uint16 m_num_signals_passed;
|
uint16 m_num_signals_passed;
|
||||||
uint16 m_num_signals_res_through_passed;
|
uint16 m_num_signals_res_through_passed;
|
||||||
|
TileIndex m_last_non_reserve_through_signal_tile;
|
||||||
|
Trackdir m_last_non_reserve_through_signal_td;
|
||||||
union {
|
union {
|
||||||
uint32 m_inherited_flags;
|
uint32 m_inherited_flags;
|
||||||
struct {
|
struct {
|
||||||
@@ -147,6 +149,8 @@ struct CYapfRailNodeT
|
|||||||
if (parent == NULL) {
|
if (parent == NULL) {
|
||||||
m_num_signals_passed = 0;
|
m_num_signals_passed = 0;
|
||||||
m_num_signals_res_through_passed = 0;
|
m_num_signals_res_through_passed = 0;
|
||||||
|
m_last_non_reserve_through_signal_tile = INVALID_TILE;
|
||||||
|
m_last_non_reserve_through_signal_td = INVALID_TRACKDIR;
|
||||||
flags_u.m_inherited_flags = 0;
|
flags_u.m_inherited_flags = 0;
|
||||||
m_last_red_signal_type = SIGTYPE_NORMAL;
|
m_last_red_signal_type = SIGTYPE_NORMAL;
|
||||||
/* We use PBS as initial signal type because if we are in
|
/* We use PBS as initial signal type because if we are in
|
||||||
@@ -163,6 +167,8 @@ struct CYapfRailNodeT
|
|||||||
} else {
|
} else {
|
||||||
m_num_signals_passed = parent->m_num_signals_passed;
|
m_num_signals_passed = parent->m_num_signals_passed;
|
||||||
m_num_signals_res_through_passed = parent->m_num_signals_res_through_passed;
|
m_num_signals_res_through_passed = parent->m_num_signals_res_through_passed;
|
||||||
|
m_last_non_reserve_through_signal_tile = parent->m_last_non_reserve_through_signal_tile;
|
||||||
|
m_last_non_reserve_through_signal_td = parent->m_last_non_reserve_through_signal_td;
|
||||||
flags_u.m_inherited_flags = parent->flags_u.m_inherited_flags;
|
flags_u.m_inherited_flags = parent->flags_u.m_inherited_flags;
|
||||||
m_last_red_signal_type = parent->m_last_red_signal_type;
|
m_last_red_signal_type = parent->m_last_red_signal_type;
|
||||||
m_last_signal_type = parent->m_last_signal_type;
|
m_last_signal_type = parent->m_last_signal_type;
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "pathfinder/yapf/yapf_cache.h"
|
#include "pathfinder/yapf/yapf_cache.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
*
|
*
|
||||||
@@ -855,13 +856,152 @@ static uint32 GetDualInstructionInitialValue(TraceRestrictItem item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> T InstructionIteratorNext(T iter)
|
||||||
|
{
|
||||||
|
return IsTraceRestrictDoubleItem(*iter) ? iter + 2 : iter + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void InstructionIteratorAdvance(T &iter)
|
||||||
|
{
|
||||||
|
iter = InstructionIteratorNext(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandCost TraceRestrictProgramRemoveItemAt(std::vector<TraceRestrictItem> &items, uint32 offset, bool shallow_mode)
|
||||||
|
{
|
||||||
|
TraceRestrictItem old_item = *TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
|
if (IsTraceRestrictConditional(old_item) && GetTraceRestrictCondFlags(old_item) != TRCF_OR) {
|
||||||
|
bool remove_whole_block = false;
|
||||||
|
if (GetTraceRestrictCondFlags(old_item) == 0) {
|
||||||
|
if (GetTraceRestrictType(old_item) == TRIT_COND_ENDIF) {
|
||||||
|
// this is an end if, can't remove these
|
||||||
|
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ENDIF);
|
||||||
|
} else {
|
||||||
|
// this is an opening if
|
||||||
|
remove_whole_block = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 recursion_depth = 1;
|
||||||
|
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
|
std::vector<TraceRestrictItem>::iterator remove_end = InstructionIteratorNext(remove_start);
|
||||||
|
|
||||||
|
// iterate until matching end block found
|
||||||
|
for (; remove_end != items.end(); InstructionIteratorAdvance(remove_end)) {
|
||||||
|
TraceRestrictItem current_item = *remove_end;
|
||||||
|
if (IsTraceRestrictConditional(current_item)) {
|
||||||
|
if (GetTraceRestrictCondFlags(current_item) == 0) {
|
||||||
|
if (GetTraceRestrictType(current_item) == TRIT_COND_ENDIF) {
|
||||||
|
// this is an end if
|
||||||
|
recursion_depth--;
|
||||||
|
if (recursion_depth == 0) {
|
||||||
|
if (remove_whole_block) {
|
||||||
|
if (shallow_mode) {
|
||||||
|
// must erase endif first, as it is later in the vector
|
||||||
|
items.erase(remove_end, InstructionIteratorNext(remove_end));
|
||||||
|
} else {
|
||||||
|
// inclusively remove up to here
|
||||||
|
InstructionIteratorAdvance(remove_end);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// exclusively remove up to here
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this is an opening if
|
||||||
|
recursion_depth++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this is an else/or type block
|
||||||
|
if (recursion_depth == 1 && !remove_whole_block) {
|
||||||
|
// exclusively remove up to here
|
||||||
|
recursion_depth = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (recursion_depth == 1 && remove_whole_block && shallow_mode) {
|
||||||
|
// shallow-removing whole if block, and it contains an else/or if, bail out
|
||||||
|
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_SHALLOW_REMOVE_IF_ELIF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (recursion_depth != 0) return CMD_ERROR; // ran off the end
|
||||||
|
if (shallow_mode) {
|
||||||
|
items.erase(remove_start, InstructionIteratorNext(remove_start));
|
||||||
|
} else {
|
||||||
|
items.erase(remove_start, remove_end);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
|
std::vector<TraceRestrictItem>::iterator remove_end = InstructionIteratorNext(remove_start);
|
||||||
|
|
||||||
|
items.erase(remove_start, remove_end);
|
||||||
|
}
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandCost TraceRestrictProgramMoveItemAt(std::vector<TraceRestrictItem> &items, uint32 &offset, bool up, bool shallow_mode)
|
||||||
|
{
|
||||||
|
std::vector<TraceRestrictItem>::iterator move_start = TraceRestrictProgram::InstructionAt(items, offset);
|
||||||
|
std::vector<TraceRestrictItem>::iterator move_end = InstructionIteratorNext(move_start);
|
||||||
|
|
||||||
|
TraceRestrictItem old_item = *move_start;
|
||||||
|
if (!shallow_mode) {
|
||||||
|
if (IsTraceRestrictConditional(old_item)) {
|
||||||
|
if (GetTraceRestrictCondFlags(old_item) != 0) {
|
||||||
|
// can't move or/else blocks
|
||||||
|
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_MOVE_ITEM);
|
||||||
|
}
|
||||||
|
if (GetTraceRestrictType(old_item) == TRIT_COND_ENDIF) {
|
||||||
|
// this is an end if, can't move these
|
||||||
|
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_MOVE_ITEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 recursion_depth = 1;
|
||||||
|
// iterate until matching end block found
|
||||||
|
for (; move_end != items.end(); InstructionIteratorAdvance(move_end)) {
|
||||||
|
TraceRestrictItem current_item = *move_end;
|
||||||
|
if (IsTraceRestrictConditional(current_item)) {
|
||||||
|
if (GetTraceRestrictCondFlags(current_item) == 0) {
|
||||||
|
if (GetTraceRestrictType(current_item) == TRIT_COND_ENDIF) {
|
||||||
|
// this is an end if
|
||||||
|
recursion_depth--;
|
||||||
|
if (recursion_depth == 0) {
|
||||||
|
// inclusively remove up to here
|
||||||
|
InstructionIteratorAdvance(move_end);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this is an opening if
|
||||||
|
recursion_depth++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (recursion_depth != 0) return CMD_ERROR; // ran off the end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (up) {
|
||||||
|
if (move_start == items.begin()) return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_MOVE_ITEM);
|
||||||
|
std::rotate(TraceRestrictProgram::InstructionAt(items, offset - 1), move_start, move_end);
|
||||||
|
offset--;
|
||||||
|
} else {
|
||||||
|
if (move_end == items.end()) return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_MOVE_ITEM);
|
||||||
|
std::rotate(move_start, move_end, InstructionIteratorNext(move_end));
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
* @param flags Internal command handler stuff.
|
* @param flags Internal command handler stuff.
|
||||||
* Below apply for instruction modification actions only
|
* Below apply for instruction modification actions only
|
||||||
* @param p1 Bitstuffed items
|
* @param p1 Bitstuffed items
|
||||||
* @param p2 Item, for insert and modify operations
|
* @param p2 Item, for insert and modify operations. Flags for instruction move operations
|
||||||
* @return the cost of this operation (which is free), or an error
|
* @return the cost of this operation (which is free), or an error
|
||||||
*/
|
*/
|
||||||
CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
@@ -939,71 +1079,16 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TRDCT_REMOVE_ITEM: {
|
case TRDCT_REMOVE_ITEM:
|
||||||
TraceRestrictItem old_item = *TraceRestrictProgram::InstructionAt(items, offset);
|
case TRDCT_SHALLOW_REMOVE_ITEM: {
|
||||||
if (IsTraceRestrictConditional(old_item) && GetTraceRestrictCondFlags(old_item) != TRCF_OR) {
|
CommandCost res = TraceRestrictProgramRemoveItemAt(items, offset, type == TRDCT_SHALLOW_REMOVE_ITEM);
|
||||||
bool remove_whole_block = false;
|
if (res.Failed()) return res;
|
||||||
if (GetTraceRestrictCondFlags(old_item) == 0) {
|
break;
|
||||||
if (GetTraceRestrictType(old_item) == TRIT_COND_ENDIF) {
|
}
|
||||||
// this is an end if, can't remove these
|
|
||||||
return_cmd_error(STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ENDIF);
|
|
||||||
} else {
|
|
||||||
// this is an opening if
|
|
||||||
remove_whole_block = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 recursion_depth = 1;
|
case TRDCT_MOVE_ITEM: {
|
||||||
std::vector<TraceRestrictItem>::iterator remove_start = TraceRestrictProgram::InstructionAt(items, offset);
|
CommandCost res = TraceRestrictProgramMoveItemAt(items, offset, p2 & 1, p2 & 2);
|
||||||
std::vector<TraceRestrictItem>::iterator remove_end = remove_start + 1;
|
if (res.Failed()) return res;
|
||||||
|
|
||||||
// iterate until matching end block found
|
|
||||||
for (; remove_end != items.end(); ++remove_end) {
|
|
||||||
TraceRestrictItem current_item = *remove_end;
|
|
||||||
if (IsTraceRestrictConditional(current_item)) {
|
|
||||||
if (GetTraceRestrictCondFlags(current_item) == 0) {
|
|
||||||
if (GetTraceRestrictType(current_item) == TRIT_COND_ENDIF) {
|
|
||||||
// this is an end if
|
|
||||||
recursion_depth--;
|
|
||||||
if (recursion_depth == 0) {
|
|
||||||
if (remove_whole_block) {
|
|
||||||
// inclusively remove up to here
|
|
||||||
++remove_end;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// exclusively remove up to here
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// this is an opening if
|
|
||||||
recursion_depth++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// this is an else/or type block
|
|
||||||
if (recursion_depth == 1 && !remove_whole_block) {
|
|
||||||
// exclusively remove up to here
|
|
||||||
recursion_depth = 0;
|
|
||||||
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
|
|
||||||
items.erase(remove_start, remove_end);
|
|
||||||
} else {
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -629,6 +629,8 @@ enum TraceRestrictDoCommandType {
|
|||||||
TRDCT_MODIFY_ITEM, ///< modify instruction at offset field to given value
|
TRDCT_MODIFY_ITEM, ///< modify instruction at offset field to given value
|
||||||
TRDCT_MODIFY_DUAL_ITEM, ///< modify second item of dual-part instruction at offset field to given value
|
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_REMOVE_ITEM, ///< remove instruction at offset field
|
||||||
|
TRDCT_SHALLOW_REMOVE_ITEM, ///< shallow remove instruction at offset field, does not delete contents of block
|
||||||
|
TRDCT_MOVE_ITEM, ///< move instruction or block at offset field
|
||||||
|
|
||||||
TRDCT_PROG_COPY, ///< 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, ///< share program operation
|
TRDCT_PROG_SHARE, ///< share program operation
|
||||||
@@ -652,6 +654,9 @@ inline void TraceRestrictProgMgmtDoCommandP(TileIndex tile, Track track, TraceRe
|
|||||||
CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
||||||
CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
||||||
|
|
||||||
|
CommandCost TraceRestrictProgramRemoveItemAt(std::vector<TraceRestrictItem> &items, uint32 offset, bool shallow_mode);
|
||||||
|
CommandCost TraceRestrictProgramMoveItemAt(std::vector<TraceRestrictItem> &items, uint32 &offset, bool up, bool shallow_mode);
|
||||||
|
|
||||||
void ShowTraceRestrictProgramWindow(TileIndex tile, Track track);
|
void ShowTraceRestrictProgramWindow(TileIndex tile, Track track);
|
||||||
|
|
||||||
void TraceRestrictRemoveDestinationID(TraceRestrictOrderCondAuxField type, uint16 index);
|
void TraceRestrictRemoveDestinationID(TraceRestrictOrderCondAuxField type, uint16 index);
|
||||||
|
@@ -53,6 +53,9 @@ enum TraceRestrictWindowWidgets {
|
|||||||
TR_WIDGET_SEL_TOP_RIGHT,
|
TR_WIDGET_SEL_TOP_RIGHT,
|
||||||
TR_WIDGET_SEL_SHARE,
|
TR_WIDGET_SEL_SHARE,
|
||||||
|
|
||||||
|
TR_WIDGET_UP_BTN,
|
||||||
|
TR_WIDGET_DOWN_BTN,
|
||||||
|
|
||||||
TR_WIDGET_TYPE_COND,
|
TR_WIDGET_TYPE_COND,
|
||||||
TR_WIDGET_TYPE_NONCOND,
|
TR_WIDGET_TYPE_NONCOND,
|
||||||
TR_WIDGET_CONDFLAGS,
|
TR_WIDGET_CONDFLAGS,
|
||||||
@@ -965,6 +968,11 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (GetTraceRestrictTypeProperties(item).value_type == TRVT_TILE_INDEX) {
|
||||||
|
TileIndex tile = *(TraceRestrictProgram::InstructionAt(this->GetProgram()->items, sel - 1) + 1);
|
||||||
|
if (tile != INVALID_TILE) {
|
||||||
|
ScrollMainWindowToTile(tile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1022,7 +1030,28 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceRestrictDoCommandP(tile, track, TRDCT_REMOVE_ITEM, this->selected_instruction - 1, 0, STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM);
|
TraceRestrictDoCommandP(tile, track, _ctrl_pressed ? TRDCT_SHALLOW_REMOVE_ITEM : TRDCT_REMOVE_ITEM,
|
||||||
|
this->selected_instruction - 1, 0, STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TR_WIDGET_UP_BTN:
|
||||||
|
case TR_WIDGET_DOWN_BTN: {
|
||||||
|
TraceRestrictItem item = this->GetSelected();
|
||||||
|
if (this->GetOwner() != _local_company || item == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 p2 = 0;
|
||||||
|
if (widget == TR_WIDGET_UP_BTN) p2 |= 1;
|
||||||
|
if (_ctrl_pressed) p2 |= 2;
|
||||||
|
|
||||||
|
uint32 offset = this->selected_instruction - 1;
|
||||||
|
|
||||||
|
this->IsUpDownBtnUsable(widget == TR_WIDGET_UP_BTN, true);
|
||||||
|
|
||||||
|
TraceRestrictDoCommandP(tile, track, TRDCT_MOVE_ITEM,
|
||||||
|
offset, p2, STR_TRACE_RESTRICT_ERROR_CAN_T_MOVE_ITEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1580,6 +1609,12 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual EventState OnCTRLStateChange() OVERRIDE
|
||||||
|
{
|
||||||
|
this->UpdateButtonState();
|
||||||
|
return ES_NOT_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Helper function to make start and end instructions (these are not stored in the actual program)
|
* Helper function to make start and end instructions (these are not stored in the actual program)
|
||||||
@@ -1705,6 +1740,26 @@ private:
|
|||||||
this->UpdateButtonState();
|
this->UpdateButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsUpDownBtnUsable(bool up, bool update_selection = false) {
|
||||||
|
const TraceRestrictProgram *prog = this->GetProgram();
|
||||||
|
if (!prog) return false;
|
||||||
|
|
||||||
|
TraceRestrictItem item = this->GetSelected();
|
||||||
|
if (GetTraceRestrictType(item) == TRIT_NULL) return false;
|
||||||
|
|
||||||
|
std::vector<TraceRestrictItem> items = prog->items; // copy
|
||||||
|
uint32 offset = this->selected_instruction - 1;
|
||||||
|
if (TraceRestrictProgramMoveItemAt(items, offset, up, _ctrl_pressed).Succeeded()) {
|
||||||
|
TraceRestrictProgramActionsUsedFlags actions_used_flags;
|
||||||
|
if (TraceRestrictProgram::Validate(items, actions_used_flags).Succeeded()) {
|
||||||
|
if (update_selection) this->selected_instruction = offset + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update button states, text values, etc.
|
* Update button states, text values, etc.
|
||||||
*/
|
*/
|
||||||
@@ -1750,6 +1805,9 @@ private:
|
|||||||
this->DisableWidget(TR_WIDGET_BLANK_M);
|
this->DisableWidget(TR_WIDGET_BLANK_M);
|
||||||
this->DisableWidget(TR_WIDGET_BLANK_R);
|
this->DisableWidget(TR_WIDGET_BLANK_R);
|
||||||
|
|
||||||
|
this->DisableWidget(TR_WIDGET_UP_BTN);
|
||||||
|
this->DisableWidget(TR_WIDGET_DOWN_BTN);
|
||||||
|
|
||||||
left_2_sel->SetDisplayedPlane(DPL2_BLANK);
|
left_2_sel->SetDisplayedPlane(DPL2_BLANK);
|
||||||
left_sel->SetDisplayedPlane(DPL_BLANK);
|
left_sel->SetDisplayedPlane(DPL_BLANK);
|
||||||
middle_sel->SetDisplayedPlane(DPM_BLANK);
|
middle_sel->SetDisplayedPlane(DPM_BLANK);
|
||||||
@@ -1962,6 +2020,8 @@ private:
|
|||||||
this->EnableWidget(TR_WIDGET_INSERT);
|
this->EnableWidget(TR_WIDGET_INSERT);
|
||||||
this->EnableWidget(TR_WIDGET_REMOVE);
|
this->EnableWidget(TR_WIDGET_REMOVE);
|
||||||
}
|
}
|
||||||
|
if (this->IsUpDownBtnUsable(true)) this->EnableWidget(TR_WIDGET_UP_BTN);
|
||||||
|
if (this->IsUpDownBtnUsable(false)) this->EnableWidget(TR_WIDGET_DOWN_BTN);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
@@ -2091,6 +2151,8 @@ static const NWidgetPart _nested_program_widgets[] = {
|
|||||||
|
|
||||||
// Button Bar
|
// Button Bar
|
||||||
NWidget(NWID_HORIZONTAL),
|
NWidget(NWID_HORIZONTAL),
|
||||||
|
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TR_WIDGET_UP_BTN), SetMinimalSize(12, 12), SetDataTip(SPR_ARROW_UP, STR_TRACE_RESTRICT_UP_BTN_TOOLTIP),
|
||||||
|
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TR_WIDGET_DOWN_BTN), SetMinimalSize(12, 12), SetDataTip(SPR_ARROW_DOWN, STR_TRACE_RESTRICT_DOWN_BTN_TOOLTIP),
|
||||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||||
NWidget(NWID_SELECTION, INVALID_COLOUR, TR_WIDGET_SEL_TOP_LEFT_2),
|
NWidget(NWID_SELECTION, INVALID_COLOUR, TR_WIDGET_SEL_TOP_LEFT_2),
|
||||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, TR_WIDGET_TYPE_NONCOND), SetMinimalSize(124, 12), SetFill(1, 0),
|
NWidget(WWT_DROPDOWN, COLOUR_GREY, TR_WIDGET_TYPE_NONCOND), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||||
@@ -2127,7 +2189,7 @@ static const NWidgetPart _nested_program_widgets[] = {
|
|||||||
SetDataTip(STR_EMPTY, STR_NULL), SetResize(1, 0),
|
SetDataTip(STR_EMPTY, STR_NULL), SetResize(1, 0),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
NWidget(WWT_IMGBTN, COLOUR_GREY, TR_WIDGET_GOTO_SIGNAL), SetMinimalSize(12, 12), SetDataTip(SPR_ARROW_RIGHT, STR_TRACE_RESTRICT_GOTO_SIGNAL_TOOLTIP),
|
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, TR_WIDGET_GOTO_SIGNAL), SetMinimalSize(12, 12), SetDataTip(SPR_ARROW_RIGHT, STR_TRACE_RESTRICT_GOTO_SIGNAL_TOOLTIP),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
|
|
||||||
/* Second button row. */
|
/* Second button row. */
|
||||||
|
Reference in New Issue
Block a user