Initial implementation of tracerestrict counter mechanism
This commit is contained in:
@@ -245,6 +245,9 @@ CommandProc CmdAlterTraceRestrictSlot;
|
||||
CommandProc CmdDeleteTraceRestrictSlot;
|
||||
CommandProc CmdAddVehicleTraceRestrictSlot;
|
||||
CommandProc CmdRemoveVehicleTraceRestrictSlot;
|
||||
CommandProc CmdCreateTraceRestrictCounter;
|
||||
CommandProc CmdAlterTraceRestrictCounter;
|
||||
CommandProc CmdDeleteTraceRestrictCounter;
|
||||
|
||||
CommandProc CmdInsertSignalInstruction;
|
||||
CommandProc CmdModifySignalInstruction;
|
||||
@@ -469,6 +472,9 @@ static const Command _command_proc_table[] = {
|
||||
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(CmdCreateTraceRestrictCounter, 0, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_TRACERESTRICT_COUNTER
|
||||
DEF_CMD(CmdAlterTraceRestrictCounter, 0, CMDT_OTHER_MANAGEMENT ), // CMD_ALTER_TRACERESTRICT_COUNTER
|
||||
DEF_CMD(CmdDeleteTraceRestrictCounter, 0, CMDT_OTHER_MANAGEMENT ), // CMD_DELETE_TRACERESTRICT_COUNTER
|
||||
|
||||
DEF_CMD(CmdInsertSignalInstruction, 0, CMDT_OTHER_MANAGEMENT ), // CMD_INSERT_SIGNAL_INSTRUCTION
|
||||
DEF_CMD(CmdModifySignalInstruction, 0, CMDT_OTHER_MANAGEMENT ), // CMD_MODIFY_SIGNAL_INSTRUCTION
|
||||
|
@@ -408,6 +408,9 @@ enum Commands {
|
||||
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_CREATE_TRACERESTRICT_COUNTER, ///< create a tracerestrict counter
|
||||
CMD_ALTER_TRACERESTRICT_COUNTER, ///< alter a tracerestrict counter
|
||||
CMD_DELETE_TRACERESTRICT_COUNTER, ///< delete a tracerestrict counter
|
||||
|
||||
CMD_INSERT_SIGNAL_INSTRUCTION, ///< insert a signal instruction
|
||||
CMD_MODIFY_SIGNAL_INSTRUCTION, ///< modifies a signal instruction
|
||||
|
@@ -1006,6 +1006,12 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
case ADI_TRACERESTRICT_COUNTER_MGMT: {
|
||||
extern void ShowTraceRestrictCounterWindow(CompanyID company);
|
||||
ShowTraceRestrictCounterWindow(this->owner);
|
||||
break;
|
||||
}
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
break;
|
||||
|
@@ -2731,6 +2731,7 @@ STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY :slot occupancy
|
||||
STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY_REMAINING :slot occupancy remaining
|
||||
STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY_SHORT :occupancy
|
||||
STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY_REMAINING_SHORT :occupancy remaining
|
||||
STR_TRACE_RESTRICT_VARIABLE_COUNTER_VALUE :counter value
|
||||
STR_TRACE_RESTRICT_VARIABLE_TRAIN_WEIGHT :weight
|
||||
STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER :power
|
||||
STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE :max T.E.
|
||||
@@ -2762,6 +2763,8 @@ STR_TRACE_RESTRICT_CONDITIONAL_SLOT_STR :{STRING} train
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_SLOT_OCCUPANCY :{STRING} {STRING} of slot: {TRSLOT} {STRING} {COMMA} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_SLOT_OCCUPANCY_STR :{STRING} {STRING} of slot: {STRING} {BLACK}{STRING} {STRING} {COMMA} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_TRAIN_STATUS :{STRING} train {STRING} status: {STRING} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COUNTER :{STRING} value of counter: {TRCOUNTER} {STRING} {COMMA} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COUNTER_STR :{STRING} value of counter: {STRING} {BLACK}{STRING} {STRING} {COMMA} 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_PF_PENALTY_ITEM :Add pathfinder penalty: {COMMA}
|
||||
@@ -2799,6 +2802,7 @@ STR_TRACE_RESTRICT_SLOT_OP :Slot operation
|
||||
STR_TRACE_RESTRICT_REVERSE :Reverse
|
||||
STR_TRACE_RESTRICT_SPEED_RESTRICTION :Speed restriction
|
||||
STR_TRACE_RESTRICT_NEWS_CONTROL :News control
|
||||
STR_TRACE_RESTRICT_COUNTER_OP :Counter 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)
|
||||
@@ -2816,6 +2820,13 @@ STR_TRACE_RESTRICT_SLOT_PBS_RES_END_RELEASE_ITEM :PBS reservation
|
||||
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_COUNTER_NAME :{TRCOUNTER}
|
||||
STR_TRACE_RESTRICT_COUNTER_INCREASE :Increase
|
||||
STR_TRACE_RESTRICT_COUNTER_DECREASE :Decrease
|
||||
STR_TRACE_RESTRICT_COUNTER_SET :Set
|
||||
STR_TRACE_RESTRICT_COUNTER_INCREASE_ITEM :Increase counter: {STRING1}{BLACK}{STRING} by {COMMA}
|
||||
STR_TRACE_RESTRICT_COUNTER_DECREASE_ITEM :Decrease counter: {STRING1}{BLACK}{STRING} by {COMMA}
|
||||
STR_TRACE_RESTRICT_COUNTER_SET_ITEM :Set counter: {STRING1}{BLACK}{STRING} to {COMMA}
|
||||
STR_TRACE_RESTRICT_TRAIN_STATUS_EMPTY :empty
|
||||
STR_TRACE_RESTRICT_TRAIN_STATUS_FULL :full
|
||||
STR_TRACE_RESTRICT_TRAIN_STATUS_BROKEN_DOWN :broken down
|
||||
@@ -2859,6 +2870,23 @@ STR_TRACE_RESTRICT_SLOT_CREATE_CAPTION :{BLACK}Create a
|
||||
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_COUNTER_OP_TOOLTIP :{BLACK}Counter operation type
|
||||
STR_TRACE_RESTRICT_COUNTER_GUI_LIST_TOOLTIP :{BLACK}Counters - click on a counter to modify it.
|
||||
STR_TRACE_RESTRICT_COUNTER_CREATE :{BLACK}Create
|
||||
STR_TRACE_RESTRICT_COUNTER_DELETE :{BLACK}Delete
|
||||
STR_TRACE_RESTRICT_COUNTER_RENAME :{BLACK}Rename
|
||||
STR_TRACE_RESTRICT_COUNTER_SET_VALUE :{BLACK}Set Value
|
||||
STR_TRACE_RESTRICT_COUNTER_CREATE_TOOLTIP :{BLACK}Click to create a counter
|
||||
STR_TRACE_RESTRICT_COUNTER_DELETE_TOOLTIP :{BLACK}Delete the selected counter
|
||||
STR_TRACE_RESTRICT_COUNTER_RENAME_TOOLTIP :{BLACK}Rename the selected counter
|
||||
STR_TRACE_RESTRICT_COUNTER_SET_VALUE_TOOLTIP :{BLACK}Set the value of the selected counter
|
||||
STR_TRACE_RESTRICT_COUNTER_CAPTION :{WHITE}Routing Restrictions - Counter Management
|
||||
STR_TRACE_RESTRICT_COUNTER_MANAGE :Manage counters
|
||||
STR_TRACE_RESTRICT_COUNTER_RENAME_CAPTION :{BLACK}Rename a counter
|
||||
STR_TRACE_RESTRICT_COUNTER_CREATE_CAPTION :{BLACK}Create a counter
|
||||
STR_TRACE_RESTRICT_COUNTER_SET_VALUE_CAPTION :{BLACK}Set counter value
|
||||
STR_TRACE_RESTRICT_COUNTER_QUERY_DELETE_CAPTION :{WHITE}Delete counter
|
||||
STR_TRACE_RESTRICT_COUNTER_DELETE_QUERY_TEXT :{WHITE}Are you sure you want to delete this counter?
|
||||
STR_TRACE_RESTRICT_INSERT :{BLACK}Insert
|
||||
STR_TRACE_RESTRICT_REMOVE :{BLACK}Remove
|
||||
STR_TRACE_RESTRICT_RESET :{BLACK}Reset
|
||||
@@ -2903,6 +2931,10 @@ STR_TRACE_RESTRICT_ERROR_SLOT_CAN_T_RENAME :{WHITE}Can't re
|
||||
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...
|
||||
STR_TRACE_RESTRICT_ERROR_COUNTER_CAN_T_CREATE :{WHITE}Can't create counter...
|
||||
STR_TRACE_RESTRICT_ERROR_COUNTER_CAN_T_DELETE :{WHITE}Can't delete this counter...
|
||||
STR_TRACE_RESTRICT_ERROR_COUNTER_CAN_T_RENAME :{WHITE}Can't rename counter...
|
||||
STR_TRACE_RESTRICT_ERROR_COUNTER_CAN_T_MODIFY :{WHITE}Can't modify this counter...
|
||||
|
||||
# Programmable Pre-Signals
|
||||
STR_PROGRAM_SIGNAL_TOOLTIP :{BLACK}Program pre-signal
|
||||
|
@@ -71,6 +71,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_TRACE_RESTRICT_STATUSCND,XSCF_NULL, 1, 1, "tracerestrict_status_cond", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TRACE_RESTRICT_REVERSE, XSCF_NULL, 1, 1, "tracerestrict_reverse", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TRACE_RESTRICT_NEWSCTRL,XSCF_NULL, 1, 1, "tracerestrict_newsctrl", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TRACE_RESTRICT_COUNTER, XSCF_NULL, 1, 1, "tracerestrict_counter", nullptr, nullptr, "TRRC" },
|
||||
{ XSLFI_PROG_SIGS, XSCF_NULL, 1, 1, "programmable_signals", nullptr, nullptr, "SPRG" },
|
||||
{ XSLFI_ADJACENT_CROSSINGS, XSCF_NULL, 1, 1, "adjacent_crossings", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_SAFER_CROSSINGS, XSCF_NULL, 1, 1, "safer_crossings", nullptr, nullptr, nullptr },
|
||||
|
@@ -28,6 +28,7 @@ enum SlXvFeatureIndex {
|
||||
XSLFI_TRACE_RESTRICT_STATUSCND, ///< Trace restrict: train status condition
|
||||
XSLFI_TRACE_RESTRICT_REVERSE, ///< Trace restrict: reverse
|
||||
XSLFI_TRACE_RESTRICT_NEWSCTRL, ///< Trace restrict: news control
|
||||
XSLFI_TRACE_RESTRICT_COUNTER, ///< Trace restrict: counters
|
||||
XSLFI_PROG_SIGS, ///< programmable pre-signals patch
|
||||
XSLFI_ADJACENT_CROSSINGS, ///< Adjacent level crossings closure patch
|
||||
XSLFI_SAFER_CROSSINGS, ///< Safer level crossings
|
||||
|
@@ -170,6 +170,44 @@ static void Save_TRRS()
|
||||
}
|
||||
}
|
||||
|
||||
static const SaveLoad _trace_restrict_counter_desc[] = {
|
||||
SLE_VAR(TraceRestrictCounter, value, SLE_INT32),
|
||||
SLE_SSTR(TraceRestrictCounter, name, SLF_ALLOW_CONTROL),
|
||||
SLE_VAR(TraceRestrictCounter, owner, SLE_UINT8),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
/**
|
||||
* Load counter pool
|
||||
*/
|
||||
static void Load_TRRC()
|
||||
{
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
TraceRestrictCounter *ctr = new (index) TraceRestrictCounter();
|
||||
SlObject(ctr, _trace_restrict_counter_desc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a counter, used by SlAutolength
|
||||
*/
|
||||
static void RealSave_TRRC(TraceRestrictCounter *ctr)
|
||||
{
|
||||
SlObject(ctr, _trace_restrict_counter_desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save counter pool
|
||||
*/
|
||||
static void Save_TRRC()
|
||||
{
|
||||
for (TraceRestrictCounter *ctr : TraceRestrictCounter::Iterate()) {
|
||||
SlSetArrayIndex(ctr->index);
|
||||
SlAutolength((AutolengthProc*) RealSave_TRRC, ctr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update program reference counts from just-loaded mapping
|
||||
*/
|
||||
@@ -184,5 +222,6 @@ void AfterLoadTraceRestrict()
|
||||
extern const ChunkHandler _trace_restrict_chunk_handlers[] = {
|
||||
{ 'TRRM', Save_TRRM, Load_TRRM, nullptr, nullptr, CH_SPARSE_ARRAY}, // Trace Restrict Mapping chunk
|
||||
{ 'TRRP', Save_TRRP, Load_TRRP, nullptr, nullptr, CH_ARRAY}, // Trace Restrict Mapping Program Pool chunk
|
||||
{ 'TRRS', Save_TRRS, Load_TRRS, nullptr, nullptr, CH_ARRAY | CH_LAST}, // Trace Restrict Slot Pool chunk
|
||||
{ 'TRRS', Save_TRRS, Load_TRRS, nullptr, nullptr, CH_ARRAY}, // Trace Restrict Slot Pool chunk
|
||||
{ 'TRRC', Save_TRRC, Load_TRRC, nullptr, nullptr, CH_ARRAY | CH_LAST}, // Trace Restrict Counter Pool chunk
|
||||
};
|
||||
|
@@ -1783,6 +1783,15 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg
|
||||
break;
|
||||
}
|
||||
|
||||
case SCC_TR_COUNTER_NAME: { // {TRCOUNTER}
|
||||
const TraceRestrictCounter *ctr = TraceRestrictCounter::GetIfValid(args->GetInt32(SCC_TR_SLOT_NAME));
|
||||
if (ctr == nullptr) break;
|
||||
int64 args_array[] = {(int64)(size_t)ctr->name.c_str()};
|
||||
StringParameters tmp_params(args_array);
|
||||
buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last);
|
||||
break;
|
||||
}
|
||||
|
||||
case SCC_STATION_FEATURES: { // {STATIONFEATURES}
|
||||
buff = StationGetSpecialString(buff, args->GetInt32(SCC_STATION_FEATURES), last);
|
||||
break;
|
||||
|
@@ -48,6 +48,7 @@ enum StringControlCode {
|
||||
SCC_PRESIDENT_NAME,
|
||||
SCC_ENGINE_NAME,
|
||||
SCC_TR_SLOT_NAME,
|
||||
SCC_TR_COUNTER_NAME,
|
||||
|
||||
SCC_CURRENCY_SHORT,
|
||||
SCC_CURRENCY_LONG,
|
||||
|
@@ -127,6 +127,7 @@ static const CmdStruct _cmd_structs[] = {
|
||||
{"COMPANY_NUM", EmitSingleChar, SCC_COMPANY_NUM, 1, -1, C_NONE},
|
||||
{"PRESIDENT_NAME", EmitSingleChar, SCC_PRESIDENT_NAME, 1, -1, C_NONE | C_GENDER},
|
||||
{"TRSLOT", EmitSingleChar, SCC_TR_SLOT_NAME, 1, -1, C_NONE | C_GENDER},
|
||||
{"TRCOUNTER", EmitSingleChar, SCC_TR_COUNTER_NAME, 1, -1, C_NONE | C_GENDER},
|
||||
|
||||
{"", EmitSingleChar, '\n', 0, -1, C_DONTCOUNT},
|
||||
{"{", EmitSingleChar, '{', 0, -1, C_DONTCOUNT},
|
||||
|
@@ -69,6 +69,9 @@ INSTANTIATE_POOL_METHODS(TraceRestrictProgram)
|
||||
TraceRestrictSlotPool _tracerestrictslot_pool("TraceRestrictSlot");
|
||||
INSTANTIATE_POOL_METHODS(TraceRestrictSlot)
|
||||
|
||||
TraceRestrictCounterPool _tracerestrictcounter_pool("TraceRestrictCounter");
|
||||
INSTANTIATE_POOL_METHODS(TraceRestrictCounter)
|
||||
|
||||
/**
|
||||
* TraceRestrictRefId --> TraceRestrictProgramID (Pool ID) mapping
|
||||
* The indirection is mainly to enable shared programs
|
||||
@@ -499,6 +502,15 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
|
||||
break;
|
||||
}
|
||||
|
||||
case TRIT_COND_COUNTER_VALUE: {
|
||||
// TRVT_COUNTER_INDEX_INT value type uses the next slot
|
||||
i++;
|
||||
uint32_t value = this->items[i];
|
||||
const TraceRestrictCounter *ctr = TraceRestrictCounter::GetIfValid(GetTraceRestrictValue(item));
|
||||
result = TestCondition(ctr != nullptr ? ctr->value : 0, condop, value);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
@@ -657,6 +669,33 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
|
||||
}
|
||||
break;
|
||||
|
||||
case TRIT_COUNTER: {
|
||||
// TRVT_COUNTER_INDEX_INT value type uses the next slot
|
||||
i++;
|
||||
uint32_t value = this->items[i];
|
||||
if (!(input.permitted_slot_operations & TRPISP_CHANGE_COUNTER)) break;
|
||||
TraceRestrictCounter *ctr = TraceRestrictCounter::GetIfValid(GetTraceRestrictValue(item));
|
||||
if (ctr == nullptr) break;
|
||||
switch (static_cast<TraceRestrictCounterCondOpField>(GetTraceRestrictCondOp(item))) {
|
||||
case TRCCOF_INCREASE:
|
||||
ctr->UpdateValue(ctr->value + value);
|
||||
break;
|
||||
|
||||
case TRCCOF_DECREASE:
|
||||
ctr->UpdateValue(ctr->value - value);
|
||||
break;
|
||||
|
||||
case TRCCOF_SET:
|
||||
ctr->UpdateValue(value);
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
@@ -751,6 +790,7 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
|
||||
case TRIT_COND_TRAIN_OWNER:
|
||||
case TRIT_COND_TRAIN_STATUS:
|
||||
case TRIT_COND_LOAD_PERCENT:
|
||||
case TRIT_COND_COUNTER_VALUE:
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -834,6 +874,10 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
|
||||
actions_used_flags |= TRPAUF_TRAIN_NOT_STUCK;
|
||||
break;
|
||||
|
||||
case TRIT_COUNTER:
|
||||
actions_used_flags |= TRPAUF_CHANGE_COUNTER;
|
||||
break;
|
||||
|
||||
default:
|
||||
return_cmd_error(STR_TRACE_RESTRICT_ERROR_VALIDATE_UNKNOWN_INSTRUCTION);
|
||||
}
|
||||
@@ -943,6 +987,10 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp
|
||||
SetTraceRestrictValue(item, INVALID_TRACE_RESTRICT_SLOT_ID);
|
||||
break;
|
||||
|
||||
case TRVT_COUNTER_INDEX_INT:
|
||||
SetTraceRestrictValue(item, INVALID_TRACE_RESTRICT_COUNTER_ID);
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
break;
|
||||
@@ -1147,8 +1195,12 @@ static uint32 GetDualInstructionInitialValue(TraceRestrictItem item)
|
||||
return INVALID_TILE;
|
||||
|
||||
case TRIT_COND_SLOT_OCCUPANCY:
|
||||
case TRIT_COND_COUNTER_VALUE:
|
||||
return 0;
|
||||
|
||||
case TRIT_COUNTER:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
@@ -1636,9 +1688,20 @@ void TraceRestrictUpdateCompanyID(CompanyID old_company, CompanyID new_company)
|
||||
}
|
||||
}
|
||||
|
||||
for (TraceRestrictCounter *ctr : TraceRestrictCounter::Iterate()) {
|
||||
if (ctr->owner != old_company) continue;
|
||||
if (new_company == INVALID_OWNER) {
|
||||
TraceRestrictRemoveCounterID(ctr->index);
|
||||
delete ctr;
|
||||
} else {
|
||||
ctr->owner = new_company;
|
||||
}
|
||||
}
|
||||
|
||||
// update windows
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT_COUNTERS);
|
||||
}
|
||||
|
||||
static std::unordered_multimap<VehicleID, TraceRestrictSlotID> slot_vehicle_index;
|
||||
@@ -1922,7 +1985,7 @@ CommandCost CmdDeleteTraceRestrictSlot(TileIndex tile, DoCommandFlag flags, uint
|
||||
* @param flags type of operation
|
||||
* @param p1 index of array group
|
||||
* - p1 bit 0-15 : GroupID
|
||||
* - p1 bit 16: 0 - Rename grouop
|
||||
* - p1 bit 16: 0 - Rename group
|
||||
* 1 - Change max occupancy
|
||||
* @param p2 new max occupancy
|
||||
* @param text the new name
|
||||
@@ -2012,3 +2075,148 @@ CommandCost CmdRemoveVehicleTraceRestrictSlot(TileIndex tile, DoCommandFlag flag
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
void TraceRestrictCounter::UpdateValue(int32 new_value)
|
||||
{
|
||||
new_value = max<int32>(0, new_value);
|
||||
if (new_value != this->value) {
|
||||
this->value = new_value;
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT_COUNTERS);
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsUniqueCounterName(const char *name)
|
||||
{
|
||||
for (const TraceRestrictCounter *ctr : TraceRestrictCounter::Iterate()) {
|
||||
if (ctr->name == name) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when a counter is about to be deleted
|
||||
* Scan program pool and change any references to it to the invalid counter ID, to avoid dangling references
|
||||
*/
|
||||
void TraceRestrictRemoveCounterID(TraceRestrictCounterID index)
|
||||
{
|
||||
for (TraceRestrictProgram *prog : TraceRestrictProgram::Iterate()) {
|
||||
for (size_t i = 0; i < prog->items.size(); i++) {
|
||||
TraceRestrictItem &item = prog->items[i]; // note this is a reference,
|
||||
if ((GetTraceRestrictType(item) == TRIT_COUNTER || GetTraceRestrictType(item) == TRIT_COND_COUNTER_VALUE) && GetTraceRestrictValue(item) == index) {
|
||||
SetTraceRestrictValueDefault(item, TRVT_COUNTER_INDEX_INT); // this updates the instruction in-place
|
||||
}
|
||||
if (IsTraceRestrictDoubleItem(item)) i++;
|
||||
}
|
||||
}
|
||||
|
||||
// update windows
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new counter.
|
||||
* @param tile unused
|
||||
* @param flags type of operation
|
||||
* @param p1 unused
|
||||
* @param p2 unused
|
||||
* @param text new counter name
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdCreateTraceRestrictCounter(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
if (!TraceRestrictCounter::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 (!IsUniqueCounterName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
TraceRestrictCounter *ctr = new TraceRestrictCounter(_current_company);
|
||||
ctr->name = text;
|
||||
|
||||
// update windows
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT_COUNTERS);
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes a counter.
|
||||
* @param tile unused
|
||||
* @param flags type of operation
|
||||
* @param p1 index of array group
|
||||
* - p1 bit 0-15 : Counter ID
|
||||
* @param p2 unused
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdDeleteTraceRestrictCounter(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
TraceRestrictCounter *ctr = TraceRestrictCounter::GetIfValid(p1);
|
||||
if (ctr == nullptr || ctr->owner != _current_company) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
/* notify tracerestrict that counter is about to be deleted */
|
||||
TraceRestrictRemoveCounterID(ctr->index);
|
||||
|
||||
delete ctr;
|
||||
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT_COUNTERS);
|
||||
InvalidateWindowClassesData(WC_VEHICLE_ORDERS);
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter a counter
|
||||
* @param tile unused
|
||||
* @param flags type of operation
|
||||
* @param p1 index of array counter
|
||||
* - p1 bit 0-15 : Counter ID
|
||||
* - p1 bit 16: 0 - Rename counter
|
||||
* 1 - Change value
|
||||
* @param p2 new value
|
||||
* @param text the new name
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdAlterTraceRestrictCounter(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
TraceRestrictCounter *ctr = TraceRestrictCounter::GetIfValid(GB(p1, 0, 16));
|
||||
if (ctr == nullptr || ctr->owner != _current_company) return CMD_ERROR;
|
||||
|
||||
if (!HasBit(p1, 16)) {
|
||||
/* Rename counter */
|
||||
|
||||
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 (!IsUniqueCounterName(text)) return_cmd_error(STR_ERROR_NAME_MUST_BE_UNIQUE);
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
ctr->name = text;
|
||||
}
|
||||
} else {
|
||||
/* Change value */
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
ctr->UpdateValue(p2);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
// update windows
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT);
|
||||
InvalidateWindowClassesData(WC_TRACE_RESTRICT_COUNTERS);
|
||||
InvalidateWindowClassesData(WC_VEHICLE_ORDERS);
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
@@ -52,6 +52,18 @@ static const TraceRestrictSlotID NEW_TRACE_RESTRICT_SLOT_ID = 0xFFFD; //
|
||||
static const TraceRestrictSlotID ALL_TRAINS_TRACE_RESTRICT_SLOT_ID = 0xFFFE; // for GUI use only
|
||||
static const TraceRestrictSlotID INVALID_TRACE_RESTRICT_SLOT_ID = 0xFFFF;
|
||||
|
||||
/** Counter pool ID type. */
|
||||
typedef uint16 TraceRestrictCounterID;
|
||||
struct TraceRestrictCounter;
|
||||
|
||||
/** Type of the pool for trace restrict slots. */
|
||||
typedef Pool<TraceRestrictCounter, TraceRestrictCounterID, 16, 0xFFF0> TraceRestrictCounterPool;
|
||||
/** The actual pool for trace restrict nodes. */
|
||||
extern TraceRestrictCounterPool _tracerestrictcounter_pool;
|
||||
|
||||
static const TraceRestrictCounterID NEW_TRACE_RESTRICT_COUNTER_ID = 0xFFFE; // for GUI use only
|
||||
static const TraceRestrictCounterID INVALID_TRACE_RESTRICT_COUNTER_ID = 0xFFFF;
|
||||
|
||||
extern const uint16 _tracerestrict_pathfinder_penalty_preset_values[];
|
||||
|
||||
/** Type used for the TraceRestrictRefId -> TraceRestrictProgramID mapping */
|
||||
@@ -136,11 +148,13 @@ enum TraceRestrictItemType {
|
||||
TRIT_COND_TRAIN_OWNER = 24, ///< Test train owner
|
||||
TRIT_COND_TRAIN_STATUS = 25, ///< Test train status
|
||||
TRIT_COND_LOAD_PERCENT = 26, ///< Test train load percentage
|
||||
TRIT_COND_COUNTER_VALUE = 27, ///< Test counter value
|
||||
|
||||
TRIT_COND_END = 48, ///< End (exclusive) of conditional item types, note that this has the same value as TRIT_REVERSE
|
||||
TRIT_REVERSE = 48, ///< Reverse behind signal
|
||||
TRIT_SPEED_RESTRICTION = 49, ///< Speed restriction
|
||||
TRIT_NEWS_CONTROL = 50, ///< News control
|
||||
TRIT_COUNTER = 51, ///< Change counter value
|
||||
|
||||
/* space up to 63 */
|
||||
};
|
||||
@@ -294,6 +308,16 @@ enum TraceRestrictSlotOccupancyCondAuxField {
|
||||
/* space up to 3 */
|
||||
};
|
||||
|
||||
/**
|
||||
* TraceRestrictItem repurposed condition operator field, for counter operation type actions
|
||||
*/
|
||||
enum TraceRestrictCounterCondOpField {
|
||||
TRCCOF_INCREASE = 0, ///< increase counter by value
|
||||
TRCCOF_DECREASE = 1, ///< decrease counter by value
|
||||
TRCCOF_SET = 2, ///< set counter to value
|
||||
/* space up to 8 */
|
||||
};
|
||||
|
||||
/**
|
||||
* TraceRestrictItem pathfinder penalty preset index
|
||||
* This may not be shortened, only lengthened, as preset indexes are stored in save games
|
||||
@@ -336,6 +360,7 @@ enum TraceRestrictProgramActionsUsedFlags {
|
||||
TRPAUF_REVERSE = 1 << 9, ///< Reverse behind signal
|
||||
TRPAUF_SPEED_RESTRICTION = 1 << 10, ///< Speed restriction
|
||||
TRPAUF_TRAIN_NOT_STUCK = 1 << 11, ///< Train is not stuck
|
||||
TRPAUF_CHANGE_COUNTER = 1 << 12, ///< Change counter value is present
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramActionsUsedFlags)
|
||||
|
||||
@@ -349,6 +374,7 @@ enum TraceRestrictProgramInputSlotPermissions {
|
||||
TRPISP_PBS_RES_END_ACQUIRE = 1 << 3, ///< Slot acquire (PBS reservations ending at this signal) is permitted
|
||||
TRPISP_PBS_RES_END_ACQ_DRY = 1 << 4, ///< Dry-run slot acquire (PBS reservations ending at this signal) is permitted
|
||||
TRPISP_PBS_RES_END_RELEASE = 1 << 5, ///< Slot release (PBS reservations ending at this signal) is permitted
|
||||
TRPISP_CHANGE_COUNTER = 1 << 6, ///< Change counter value is permitted
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramInputSlotPermissions)
|
||||
|
||||
@@ -527,7 +553,7 @@ static inline bool IsTraceRestrictConditional(TraceRestrictItem item)
|
||||
static inline bool IsTraceRestrictDoubleItem(TraceRestrictItem item)
|
||||
{
|
||||
const TraceRestrictItemType type = GetTraceRestrictType(item);
|
||||
return type == TRIT_COND_PBS_ENTRY_SIGNAL || type == TRIT_COND_SLOT_OCCUPANCY;
|
||||
return type == TRIT_COND_PBS_ENTRY_SIGNAL || type == TRIT_COND_SLOT_OCCUPANCY || type == TRIT_COUNTER || type == TRIT_COND_COUNTER_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -571,6 +597,7 @@ enum TraceRestrictValueType {
|
||||
TRVT_TRAIN_STATUS = 41,///< takes a TraceRestrictTrainStatusValueField
|
||||
TRVT_REVERSE = 42,///< takes a TraceRestrictReverseValueField
|
||||
TRVT_NEWS_CONTROL = 43,///< takes a TraceRestrictNewsControlField
|
||||
TRVT_COUNTER_INDEX_INT = 44,///< takes a TraceRestrictCounterID, and an integer in the next item slot
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -696,6 +723,10 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR
|
||||
out.value_type = TRVT_PERCENT;
|
||||
break;
|
||||
|
||||
case TRIT_COND_COUNTER_VALUE:
|
||||
out.value_type = TRVT_COUNTER_INDEX_INT;
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
break;
|
||||
@@ -720,6 +751,8 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR
|
||||
out.value_type = TRVT_SPEED;
|
||||
} else if (GetTraceRestrictType(item) == TRIT_NEWS_CONTROL) {
|
||||
out.value_type = TRVT_NEWS_CONTROL;
|
||||
} else if (GetTraceRestrictType(item) == TRIT_COUNTER) {
|
||||
out.value_type = TRVT_COUNTER_INDEX_INT;
|
||||
} else {
|
||||
out.value_type = TRVT_NONE;
|
||||
}
|
||||
@@ -823,6 +856,7 @@ void TraceRestrictRemoveDestinationID(TraceRestrictOrderCondAuxField type, uint1
|
||||
void TraceRestrictRemoveGroupID(GroupID index);
|
||||
void TraceRestrictUpdateCompanyID(CompanyID old_company, CompanyID new_company);
|
||||
void TraceRestrictRemoveSlotID(TraceRestrictSlotID index);
|
||||
void TraceRestrictRemoveCounterID(TraceRestrictCounterID index);
|
||||
|
||||
void TraceRestrictRemoveVehicleFromAllSlots(VehicleID id);
|
||||
void TraceRestrictTransferVehicleOccupantInAllSlots(VehicleID from, VehicleID to);
|
||||
@@ -871,4 +905,20 @@ struct TraceRestrictSlot : TraceRestrictSlotPool::PoolItem<&_tracerestrictslot_p
|
||||
void DeIndex(VehicleID id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Slot type, used for slot operations
|
||||
*/
|
||||
struct TraceRestrictCounter : TraceRestrictCounterPool::PoolItem<&_tracerestrictcounter_pool> {
|
||||
int32 value = 0;
|
||||
std::string name;
|
||||
Owner owner;
|
||||
|
||||
TraceRestrictCounter(CompanyID owner = INVALID_COMPANY)
|
||||
{
|
||||
this->owner = owner;
|
||||
}
|
||||
|
||||
void UpdateValue(int32 new_value);
|
||||
};
|
||||
|
||||
#endif /* TRACERESTRICT_H */
|
||||
|
@@ -69,6 +69,7 @@ enum TraceRestrictWindowWidgets {
|
||||
TR_WIDGET_CONDFLAGS,
|
||||
TR_WIDGET_COMPARATOR,
|
||||
TR_WIDGET_SLOT_OP,
|
||||
TR_WIDGET_COUNTER_OP,
|
||||
TR_WIDGET_VALUE_INT,
|
||||
TR_WIDGET_VALUE_DECIMAL,
|
||||
TR_WIDGET_VALUE_DROPDOWN,
|
||||
@@ -100,6 +101,7 @@ enum PanelWidgets {
|
||||
|
||||
// Left
|
||||
DPL_TYPE = 0,
|
||||
DPL_COUNTER_OP,
|
||||
DPL_BLANK,
|
||||
|
||||
// Left aux
|
||||
@@ -153,6 +155,7 @@ static const StringID _program_insert_str[] = {
|
||||
STR_TRACE_RESTRICT_REVERSE,
|
||||
STR_TRACE_RESTRICT_SPEED_RESTRICTION,
|
||||
STR_TRACE_RESTRICT_NEWS_CONTROL,
|
||||
STR_TRACE_RESTRICT_COUNTER_OP,
|
||||
INVALID_STRING_ID
|
||||
};
|
||||
static const uint32 _program_insert_else_hide_mask = 8; ///< disable bitmask for else
|
||||
@@ -162,6 +165,7 @@ static const uint32 _program_wait_pbs_hide_mask = 0x100; ///< disable bitm
|
||||
static const uint32 _program_slot_hide_mask = 0x200; ///< disable bitmask for slot
|
||||
static const uint32 _program_reverse_hide_mask = 0x400; ///< disable bitmask for reverse
|
||||
static const uint32 _program_speed_res_hide_mask = 0x800; ///< disable bitmask for speed restriction
|
||||
static const uint32 _program_counter_hide_mask = 0x2000; ///< disable bitmask for counter
|
||||
static const uint _program_insert_val[] = {
|
||||
TRIT_COND_UNDEFINED, // if block
|
||||
TRIT_COND_UNDEFINED | (TRCF_ELSE << 16), // elif block
|
||||
@@ -176,6 +180,7 @@ static const uint _program_insert_val[] = {
|
||||
TRIT_REVERSE, // reverse
|
||||
TRIT_SPEED_RESTRICTION, // speed restriction
|
||||
TRIT_NEWS_CONTROL, // news control
|
||||
TRIT_COUNTER, // counter operation
|
||||
};
|
||||
|
||||
/** insert drop down list strings and values */
|
||||
@@ -392,6 +397,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
|
||||
STR_TRACE_RESTRICT_REVERSE,
|
||||
STR_TRACE_RESTRICT_SPEED_RESTRICTION,
|
||||
STR_TRACE_RESTRICT_NEWS_CONTROL,
|
||||
STR_TRACE_RESTRICT_COUNTER_OP,
|
||||
INVALID_STRING_ID,
|
||||
};
|
||||
static const uint val_action[] = {
|
||||
@@ -404,6 +410,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
|
||||
TRIT_REVERSE,
|
||||
TRIT_SPEED_RESTRICTION,
|
||||
TRIT_NEWS_CONTROL,
|
||||
TRIT_COUNTER,
|
||||
};
|
||||
static const TraceRestrictDropDownListSet set_action = {
|
||||
str_action, val_action,
|
||||
@@ -430,6 +437,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
|
||||
STR_TRACE_RESTRICT_VARIABLE_TRAIN_SLOT,
|
||||
STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY,
|
||||
STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY_REMAINING,
|
||||
STR_TRACE_RESTRICT_VARIABLE_COUNTER_VALUE,
|
||||
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED,
|
||||
INVALID_STRING_ID,
|
||||
};
|
||||
@@ -454,6 +462,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
|
||||
TRIT_COND_TRAIN_IN_SLOT,
|
||||
TRIT_COND_SLOT_OCCUPANCY | (TRSOCAF_OCCUPANTS << 16),
|
||||
TRIT_COND_SLOT_OCCUPANCY | (TRSOCAF_REMAINING << 16),
|
||||
TRIT_COND_COUNTER_VALUE,
|
||||
TRIT_COND_UNDEFINED,
|
||||
};
|
||||
static const TraceRestrictDropDownListSet set_cond = {
|
||||
@@ -465,7 +474,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
|
||||
if (_settings_client.gui.show_adv_tracerestrict_features) {
|
||||
*hide_mask = 0;
|
||||
} else {
|
||||
*hide_mask = is_conditional ? 0xE0000 : 0xF0;
|
||||
*hide_mask = is_conditional ? 0x1E0000 : 0xF0;
|
||||
}
|
||||
}
|
||||
return is_conditional ? &set_cond : &set_action;
|
||||
@@ -568,6 +577,46 @@ DropDownList GetSlotDropDownList(Owner owner, TraceRestrictSlotID slot_id, int &
|
||||
return dlist;
|
||||
}
|
||||
|
||||
/** Sort counters by their name */
|
||||
static bool CounterNameSorter(const TraceRestrictCounter * const &a, const TraceRestrictCounter * const &b)
|
||||
{
|
||||
int r = strnatcmp(a->name.c_str(), b->name.c_str()); // Sort by name (natural sorting).
|
||||
if (r == 0) return a->index < b->index;
|
||||
return r < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a DropDownList of the counter list
|
||||
*/
|
||||
DropDownList GetCounterDropDownList(Owner owner, TraceRestrictCounterID ctr_id, int &selected)
|
||||
{
|
||||
GUIList<const TraceRestrictCounter*> list;
|
||||
DropDownList dlist;
|
||||
|
||||
for (const TraceRestrictCounter *ctr : TraceRestrictCounter::Iterate()) {
|
||||
if (ctr->owner == owner) {
|
||||
list.push_back(ctr);
|
||||
}
|
||||
}
|
||||
|
||||
if (list.size() == 0) return dlist;
|
||||
|
||||
list.ForceResort();
|
||||
list.Sort(&CounterNameSorter);
|
||||
|
||||
selected = -1;
|
||||
|
||||
for (size_t i = 0; i < list.size(); ++i) {
|
||||
const TraceRestrictCounter *s = list[i];
|
||||
if (ctr_id == s->index) selected = ctr_id;
|
||||
DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_TRACE_RESTRICT_COUNTER_NAME, s->index, false);
|
||||
item->SetParam(0, s->index);
|
||||
dlist.emplace_back(item);
|
||||
}
|
||||
|
||||
return dlist;
|
||||
}
|
||||
|
||||
static const StringID _cargo_cond_ops_str[] = {
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_CARGO_EQUALS,
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_CARGO_NOT_EQUALS,
|
||||
@@ -620,6 +669,22 @@ static const TraceRestrictDropDownListSet _slot_op_cond_ops = {
|
||||
_slot_op_cond_ops_str, _slot_op_cond_ops_val,
|
||||
};
|
||||
|
||||
static const StringID _counter_op_cond_ops_str[] = {
|
||||
STR_TRACE_RESTRICT_COUNTER_INCREASE,
|
||||
STR_TRACE_RESTRICT_COUNTER_DECREASE,
|
||||
STR_TRACE_RESTRICT_COUNTER_SET,
|
||||
INVALID_STRING_ID,
|
||||
};
|
||||
static const uint _counter_op_cond_ops_val[] = {
|
||||
TRCCOF_INCREASE,
|
||||
TRCCOF_DECREASE,
|
||||
TRCCOF_SET,
|
||||
};
|
||||
/** counter operators dropdown list set */
|
||||
static const TraceRestrictDropDownListSet _counter_op_cond_ops = {
|
||||
_counter_op_cond_ops_str, _counter_op_cond_ops_val,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the StringID for a given CargoID @p cargo, or STR_NEWGRF_INVALID_CARGO
|
||||
*/
|
||||
@@ -1114,6 +1179,26 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric
|
||||
SetDParam(2, GetDropDownStringByValue(&_train_status_value, GetTraceRestrictValue(item)));
|
||||
break;
|
||||
|
||||
case TRVT_COUNTER_INDEX_INT: {
|
||||
assert(prog != nullptr);
|
||||
assert(GetTraceRestrictType(item) == TRIT_COND_COUNTER_VALUE);
|
||||
uint32 value = *(TraceRestrictProgram::InstructionAt(prog->items, index - 1) + 1);
|
||||
SetDParam(0, _program_cond_type[GetTraceRestrictCondFlags(item)]);
|
||||
if (GetTraceRestrictValue(item) == INVALID_TRACE_RESTRICT_COUNTER_ID) {
|
||||
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_COUNTER_STR;
|
||||
SetDParam(1, STR_TRACE_RESTRICT_VARIABLE_UNDEFINED_RED);
|
||||
SetDParam(2, selected ? STR_TRACE_RESTRICT_WHITE : STR_EMPTY);
|
||||
SetDParam(3, GetDropDownStringByValue(GetCondOpDropDownListSet(properties), GetTraceRestrictCondOp(item)));
|
||||
SetDParam(4, value);
|
||||
} else {
|
||||
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_COUNTER;
|
||||
SetDParam(1, GetTraceRestrictValue(item));
|
||||
SetDParam(2, GetDropDownStringByValue(GetCondOpDropDownListSet(properties), GetTraceRestrictCondOp(item)));
|
||||
SetDParam(3, value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
break;
|
||||
@@ -1277,6 +1362,36 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric
|
||||
}
|
||||
break;
|
||||
|
||||
case TRIT_COUNTER: {
|
||||
uint32 value = *(TraceRestrictProgram::InstructionAt(prog->items, index - 1) + 1);
|
||||
switch (static_cast<TraceRestrictCounterCondOpField>(GetTraceRestrictCondOp(item))) {
|
||||
case TRCCOF_INCREASE:
|
||||
instruction_string = STR_TRACE_RESTRICT_COUNTER_INCREASE_ITEM;
|
||||
break;
|
||||
|
||||
case TRCCOF_DECREASE:
|
||||
instruction_string = STR_TRACE_RESTRICT_COUNTER_DECREASE_ITEM;
|
||||
break;
|
||||
|
||||
case TRCCOF_SET:
|
||||
instruction_string = STR_TRACE_RESTRICT_COUNTER_SET_ITEM;
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
break;
|
||||
}
|
||||
if (GetTraceRestrictValue(item) == INVALID_TRACE_RESTRICT_COUNTER_ID) {
|
||||
SetDParam(0, STR_TRACE_RESTRICT_VARIABLE_UNDEFINED_RED);
|
||||
} else {
|
||||
SetDParam(0, STR_TRACE_RESTRICT_COUNTER_NAME);
|
||||
SetDParam(1, GetTraceRestrictValue(item));
|
||||
}
|
||||
SetDParam(2, selected ? STR_TRACE_RESTRICT_WHITE : STR_EMPTY);
|
||||
SetDParam(3, value);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
break;
|
||||
@@ -1400,7 +1515,7 @@ public:
|
||||
if (ElseIfInsertionDryRun(false)) disabled &= ~_program_insert_or_if_hide_mask;
|
||||
}
|
||||
}
|
||||
if (!_settings_client.gui.show_adv_tracerestrict_features) hidden |= _program_slot_hide_mask | _program_wait_pbs_hide_mask | _program_reverse_hide_mask | _program_speed_res_hide_mask;
|
||||
if (!_settings_client.gui.show_adv_tracerestrict_features) hidden |= _program_slot_hide_mask | _program_wait_pbs_hide_mask | _program_reverse_hide_mask | _program_speed_res_hide_mask | _program_counter_hide_mask;
|
||||
|
||||
this->ShowDropDownListWithValue(&_program_insert, 0, true, TR_WIDGET_INSERT, disabled, hidden, 0);
|
||||
break;
|
||||
@@ -1489,13 +1604,19 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
case TR_WIDGET_COUNTER_OP: {
|
||||
TraceRestrictItem item = this->GetSelected();
|
||||
this->ShowDropDownListWithValue(&_counter_op_cond_ops, GetTraceRestrictCondOp(item), false, TR_WIDGET_COUNTER_OP, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case TR_WIDGET_VALUE_INT: {
|
||||
TraceRestrictItem item = this->GetSelected();
|
||||
TraceRestrictValueType type = GetTraceRestrictTypeProperties(item).value_type;
|
||||
if (IsIntegerValueType(type)) {
|
||||
SetDParam(0, ConvertIntegerValue(type, GetTraceRestrictValue(item), true));
|
||||
ShowQueryString(STR_JUST_INT, STR_TRACE_RESTRICT_VALUE_CAPTION, 10, this, CS_NUMERAL, QSF_NONE);
|
||||
} else if (type == TRVT_SLOT_INDEX_INT) {
|
||||
} else if (type == TRVT_SLOT_INDEX_INT || type == TRVT_COUNTER_INDEX_INT) {
|
||||
SetDParam(0, *(TraceRestrictProgram::InstructionAt(this->GetProgram()->items, this->selected_instruction - 1) + 1));
|
||||
ShowQueryString(STR_JUST_INT, STR_TRACE_RESTRICT_VALUE_CAPTION, 10, this, CS_NUMERAL, QSF_NONE);
|
||||
}
|
||||
@@ -1595,6 +1716,13 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
case TRVT_COUNTER_INDEX_INT: {
|
||||
int selected;
|
||||
DropDownList dlist = GetCounterDropDownList(this->GetOwner(), GetTraceRestrictValue(item), selected);
|
||||
if (!dlist.empty()) ShowDropDownList(this, std::move(dlist), selected, TR_WIDGET_LEFT_AUX_DROPDOWN);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1670,7 +1798,7 @@ public:
|
||||
ShowErrorMessage(STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE, STR_EMPTY, WL_INFO);
|
||||
return;
|
||||
}
|
||||
} else if (type == TRVT_SLOT_INDEX_INT) {
|
||||
} else if (type == TRVT_SLOT_INDEX_INT || type == TRVT_COUNTER_INDEX_INT) {
|
||||
value = atoi(str);
|
||||
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_DUAL_ITEM, this->selected_instruction - 1, value, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
||||
return;
|
||||
@@ -1691,7 +1819,7 @@ public:
|
||||
|
||||
if (widget == TR_WIDGET_VALUE_DROPDOWN || widget == TR_WIDGET_LEFT_AUX_DROPDOWN) {
|
||||
TraceRestrictTypePropertySet type = GetTraceRestrictTypeProperties(item);
|
||||
if (this->value_drop_down_is_company || type.value_type == TRVT_GROUP_INDEX || type.value_type == TRVT_SLOT_INDEX || type.value_type == TRVT_SLOT_INDEX_INT) {
|
||||
if (this->value_drop_down_is_company || type.value_type == TRVT_GROUP_INDEX || type.value_type == TRVT_SLOT_INDEX || type.value_type == TRVT_SLOT_INDEX_INT || type.value_type == TRVT_COUNTER_INDEX_INT) {
|
||||
// this is a special company drop-down or group/slot-index drop-down
|
||||
SetTraceRestrictValue(item, index);
|
||||
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_ITEM, this->selected_instruction - 1, item, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
||||
@@ -1747,7 +1875,8 @@ public:
|
||||
}
|
||||
|
||||
case TR_WIDGET_COMPARATOR:
|
||||
case TR_WIDGET_SLOT_OP: {
|
||||
case TR_WIDGET_SLOT_OP:
|
||||
case TR_WIDGET_COUNTER_OP: {
|
||||
SetTraceRestrictCondOp(item, static_cast<TraceRestrictCondOp>(value));
|
||||
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_ITEM, this->selected_instruction - 1, item, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
|
||||
break;
|
||||
@@ -2023,7 +2152,7 @@ public:
|
||||
TraceRestrictValueType type = GetTraceRestrictTypeProperties(item).value_type;
|
||||
if (IsIntegerValueType(type)) {
|
||||
SetDParam(0, ConvertIntegerValue(type, GetTraceRestrictValue(item), true));
|
||||
} else if (type == TRVT_SLOT_INDEX_INT) {
|
||||
} else if (type == TRVT_SLOT_INDEX_INT || type == TRVT_COUNTER_INDEX_INT) {
|
||||
SetDParam(0, *(TraceRestrictProgram::InstructionAt(this->GetProgram()->items, this->selected_instruction - 1) + 1));
|
||||
}
|
||||
break;
|
||||
@@ -2068,7 +2197,7 @@ public:
|
||||
case TR_WIDGET_LEFT_AUX_DROPDOWN: {
|
||||
TraceRestrictItem item = this->GetSelected();
|
||||
TraceRestrictTypePropertySet type = GetTraceRestrictTypeProperties(item);
|
||||
if (type.value_type == TRVT_SLOT_INDEX_INT) {
|
||||
if (type.value_type == TRVT_SLOT_INDEX_INT || type.value_type == TRVT_COUNTER_INDEX_INT) {
|
||||
SetDParam(0, GetTraceRestrictValue(item));
|
||||
}
|
||||
break;
|
||||
@@ -2239,6 +2368,7 @@ private:
|
||||
this->RaiseWidget(TR_WIDGET_CONDFLAGS);
|
||||
this->RaiseWidget(TR_WIDGET_COMPARATOR);
|
||||
this->RaiseWidget(TR_WIDGET_SLOT_OP);
|
||||
this->RaiseWidget(TR_WIDGET_COUNTER_OP);
|
||||
this->RaiseWidget(TR_WIDGET_VALUE_INT);
|
||||
this->RaiseWidget(TR_WIDGET_VALUE_DECIMAL);
|
||||
this->RaiseWidget(TR_WIDGET_VALUE_DROPDOWN);
|
||||
@@ -2259,6 +2389,7 @@ private:
|
||||
this->DisableWidget(TR_WIDGET_CONDFLAGS);
|
||||
this->DisableWidget(TR_WIDGET_COMPARATOR);
|
||||
this->DisableWidget(TR_WIDGET_SLOT_OP);
|
||||
this->DisableWidget(TR_WIDGET_COUNTER_OP);
|
||||
this->DisableWidget(TR_WIDGET_VALUE_INT);
|
||||
this->DisableWidget(TR_WIDGET_VALUE_DECIMAL);
|
||||
this->DisableWidget(TR_WIDGET_VALUE_DROPDOWN);
|
||||
@@ -2576,6 +2707,36 @@ private:
|
||||
GetDropDownStringByValue(&_news_control_value, GetTraceRestrictValue(item));
|
||||
break;
|
||||
|
||||
case TRVT_COUNTER_INDEX_INT: {
|
||||
right_sel->SetDisplayedPlane(DPR_VALUE_INT);
|
||||
left_aux_sel->SetDisplayedPlane(DPLA_DROPDOWN);
|
||||
this->EnableWidget(TR_WIDGET_VALUE_INT);
|
||||
if (!IsTraceRestrictConditional(item)) {
|
||||
left_sel->SetDisplayedPlane(DPL_COUNTER_OP);
|
||||
this->EnableWidget(TR_WIDGET_COUNTER_OP);
|
||||
this->GetWidget<NWidgetCore>(TR_WIDGET_COUNTER_OP)->widget_data =
|
||||
GetDropDownStringByValue(&_counter_op_cond_ops, GetTraceRestrictCondOp(item));
|
||||
}
|
||||
|
||||
for (const TraceRestrictCounter *ctr : TraceRestrictCounter::Iterate()) {
|
||||
if (ctr->owner == this->GetOwner()) {
|
||||
this->EnableWidget(TR_WIDGET_LEFT_AUX_DROPDOWN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (GetTraceRestrictValue(item)) {
|
||||
case INVALID_TRACE_RESTRICT_COUNTER_ID:
|
||||
this->GetWidget<NWidgetCore>(TR_WIDGET_LEFT_AUX_DROPDOWN)->widget_data = STR_TRACE_RESTRICT_VARIABLE_UNDEFINED;
|
||||
break;
|
||||
|
||||
default:
|
||||
this->GetWidget<NWidgetCore>(TR_WIDGET_LEFT_AUX_DROPDOWN)->widget_data = STR_TRACE_RESTRICT_COUNTER_NAME;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2728,6 +2889,8 @@ static const NWidgetPart _nested_program_widgets[] = {
|
||||
NWidget(NWID_SELECTION, INVALID_COLOUR, TR_WIDGET_SEL_TOP_LEFT),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, TR_WIDGET_TYPE_COND), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_NULL, STR_TRACE_RESTRICT_TYPE_TOOLTIP), SetResize(1, 0),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, TR_WIDGET_COUNTER_OP), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_NULL, STR_TRACE_RESTRICT_COUNTER_OP_TOOLTIP), SetResize(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_BLANK_L), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_EMPTY, STR_NULL), SetResize(1, 0),
|
||||
EndContainer(),
|
||||
@@ -3488,3 +3651,343 @@ void DeleteTraceRestrictSlotHighlightOfVehicle(const Vehicle *v)
|
||||
TraceRestrictSlotWindow *w = FindTraceRestrictSlotWindow(v->owner);
|
||||
if (w != nullptr) w->UnselectVehicle(v->index);
|
||||
}
|
||||
|
||||
/** Counter GUI widget IDs */
|
||||
enum TraceRestrictCounterWindowWidgets {
|
||||
WID_TRCL_CAPTION,
|
||||
WID_TRCL_LIST_COUNTERS,
|
||||
WID_TRCL_LIST_COUNTERS_SCROLLBAR,
|
||||
WID_TRCL_CREATE_COUNTER,
|
||||
WID_TRCL_DELETE_COUNTER,
|
||||
WID_TRCL_RENAME_COUNTER,
|
||||
WID_TRCL_SET_COUNTER_VALUE,
|
||||
};
|
||||
|
||||
|
||||
static const NWidgetPart _nested_counter_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL), // Window header
|
||||
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_CAPTION, COLOUR_GREY, WID_TRCL_CAPTION), SetDataTip(STR_TRACE_RESTRICT_COUNTER_CAPTION, STR_NULL),
|
||||
NWidget(WWT_SHADEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
|
||||
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL),
|
||||
//NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalTextLines(1, WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM), SetFill(1, 0), EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_MATRIX, COLOUR_GREY, WID_TRCL_LIST_COUNTERS), SetMatrixDataTip(1, 0, STR_TRACE_RESTRICT_COUNTER_GUI_LIST_TOOLTIP),
|
||||
SetFill(1, 1), SetResize(1, 1), SetScrollbar(WID_TRCL_LIST_COUNTERS_SCROLLBAR),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_TRCL_LIST_COUNTERS_SCROLLBAR),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TRCL_CREATE_COUNTER), SetMinimalSize(75, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_TRACE_RESTRICT_COUNTER_CREATE, STR_TRACE_RESTRICT_COUNTER_CREATE_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TRCL_DELETE_COUNTER), SetMinimalSize(75, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_TRACE_RESTRICT_COUNTER_DELETE, STR_TRACE_RESTRICT_COUNTER_DELETE_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TRCL_RENAME_COUNTER), SetMinimalSize(75, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_TRACE_RESTRICT_COUNTER_RENAME, STR_TRACE_RESTRICT_COUNTER_RENAME_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TRCL_SET_COUNTER_VALUE), SetMinimalSize(75, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_TRACE_RESTRICT_COUNTER_SET_VALUE, STR_TRACE_RESTRICT_COUNTER_SET_VALUE_TOOLTIP),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
class TraceRestrictCounterWindow : public Window {
|
||||
private:
|
||||
enum QueryTextOperation {
|
||||
QTO_RENAME,
|
||||
QTO_SET_VALUE,
|
||||
};
|
||||
|
||||
CompanyID owner;
|
||||
QueryTextOperation qto; ///< Active query text operation
|
||||
TraceRestrictCounterID ctr_qt_op; ///< Counter being adjusted in query text operation, INVALID_TRACE_RESTRICT_COUNTER_ID if none
|
||||
TraceRestrictCounterID ctr_confirm; ///< Counter awaiting delete confirmation
|
||||
TraceRestrictCounterID selected; ///< Selected counter
|
||||
GUIList<const TraceRestrictCounter*> ctrs; ///< List of slots
|
||||
uint tiny_step_height; ///< Step height for the counter list
|
||||
uint value_col_width; ///< Value column width
|
||||
Scrollbar *sb;
|
||||
|
||||
void BuildCounterList()
|
||||
{
|
||||
if (!this->ctrs.NeedRebuild()) return;
|
||||
|
||||
this->ctrs.clear();
|
||||
|
||||
for (const TraceRestrictCounter *ctr : TraceRestrictCounter::Iterate()) {
|
||||
if (ctr->owner == this->owner) {
|
||||
this->ctrs.push_back(ctr);
|
||||
}
|
||||
}
|
||||
|
||||
this->ctrs.ForceResort();
|
||||
this->ctrs.Sort(&CounterNameSorter);
|
||||
this->ctrs.shrink_to_fit();
|
||||
this->ctrs.RebuildDone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute tiny_step_height and column_size
|
||||
* @return Total width required for the group list.
|
||||
*/
|
||||
uint ComputeInfoSize()
|
||||
{
|
||||
SetDParamMaxValue(0, 9999, 3);
|
||||
Dimension dim = GetStringBoundingBox(STR_JUST_COMMA);
|
||||
this->tiny_step_height = dim.height + WD_MATRIX_TOP;
|
||||
this->value_col_width = dim.width;
|
||||
|
||||
return WD_FRAMERECT_LEFT + 8 +
|
||||
170 + 8 +
|
||||
dim.width + 8 +
|
||||
WD_FRAMERECT_RIGHT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a row in the slot list.
|
||||
* @param y Top of the row.
|
||||
* @param left Left of the row.
|
||||
* @param right Right of the row.
|
||||
* @param g_id Group to list.
|
||||
*/
|
||||
void DrawCounterInfo(int y, int left, int right, TraceRestrictCounterID ctr_id) const
|
||||
{
|
||||
/* draw the selected counter in white, else we draw it in black */
|
||||
TextColour colour = ctr_id == this->selected ? TC_WHITE : TC_BLACK;
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
|
||||
SetDParam(0, ctr_id);
|
||||
DrawString(left + WD_FRAMERECT_LEFT + 8 + (rtl ? this->value_col_width + 8 : 0),
|
||||
right - WD_FRAMERECT_RIGHT - 8 - (rtl ? 0 : this->value_col_width + 8),
|
||||
y, STR_TRACE_RESTRICT_COUNTER_NAME, colour);
|
||||
|
||||
SetDParam(0, TraceRestrictCounter::Get(ctr_id)->value);
|
||||
DrawString(rtl ? left + WD_FRAMERECT_LEFT + 8 : right - WD_FRAMERECT_RIGHT - 8 - this->value_col_width,
|
||||
rtl ? left + WD_FRAMERECT_LEFT + 8 + this->value_col_width : right - WD_FRAMERECT_RIGHT - 8,
|
||||
y, STR_JUST_COMMA, colour, SA_RIGHT | SA_FORCE);
|
||||
}
|
||||
|
||||
public:
|
||||
TraceRestrictCounterWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
|
||||
{
|
||||
this->owner = (CompanyID)window_number;
|
||||
this->CreateNestedTree();
|
||||
|
||||
this->sb = this->GetScrollbar(WID_TRCL_LIST_COUNTERS_SCROLLBAR);
|
||||
|
||||
this->ctr_qt_op = INVALID_TRACE_RESTRICT_COUNTER_ID;
|
||||
this->ctr_confirm = INVALID_TRACE_RESTRICT_COUNTER_ID;
|
||||
this->selected = INVALID_TRACE_RESTRICT_COUNTER_ID;
|
||||
|
||||
this->ctrs.ForceRebuild();
|
||||
this->ctrs.NeedResort();
|
||||
this->BuildCounterList();
|
||||
|
||||
this->FinishInitNested(window_number);
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_TRCL_LIST_COUNTERS: {
|
||||
size->width = max<uint>(size->width, this->ComputeInfoSize());
|
||||
resize->height = this->tiny_step_height;
|
||||
size->height = max<uint>(size->height, 8 * resize->height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some data on this window has become invalid.
|
||||
* @param data Information about the changed data.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
virtual void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (data == 0) {
|
||||
/* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
|
||||
this->ctrs.ForceRebuild();
|
||||
} else {
|
||||
this->ctrs.ForceResort();
|
||||
}
|
||||
|
||||
if (this->ctr_qt_op != INVALID_TRACE_RESTRICT_COUNTER_ID && this->ctr_qt_op != NEW_TRACE_RESTRICT_COUNTER_ID &&
|
||||
!TraceRestrictCounter::IsValidID(this->ctr_qt_op)) {
|
||||
DeleteWindowByClass(WC_QUERY_STRING);
|
||||
this->ctr_qt_op = INVALID_TRACE_RESTRICT_COUNTER_ID;
|
||||
}
|
||||
|
||||
if (this->selected != INVALID_TRACE_RESTRICT_COUNTER_ID && !TraceRestrictCounter::IsValidID(this->selected)) {
|
||||
this->selected = INVALID_TRACE_RESTRICT_COUNTER_ID;
|
||||
}
|
||||
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
virtual void OnPaint() override
|
||||
{
|
||||
this->BuildCounterList();
|
||||
|
||||
this->sb->SetCount(this->ctrs.size());
|
||||
|
||||
/* Disable the counter specific functions when no counter is selected */
|
||||
this->SetWidgetsDisabledState(this->selected == INVALID_TRACE_RESTRICT_COUNTER_ID || _local_company != this->owner,
|
||||
WID_TRCL_DELETE_COUNTER,
|
||||
WID_TRCL_RENAME_COUNTER,
|
||||
WID_TRCL_SET_COUNTER_VALUE,
|
||||
WIDGET_LIST_END);
|
||||
|
||||
/* Disable remaining buttons for non-local companies
|
||||
* Needed while changing _local_company, eg. by cheats
|
||||
* All procedures (eg. move vehicle to a slot)
|
||||
* verify, whether you are the owner of the vehicle,
|
||||
* so it doesn't have to be disabled
|
||||
*/
|
||||
this->SetWidgetsDisabledState(_local_company != this->owner,
|
||||
WID_TRCL_CREATE_COUNTER,
|
||||
WIDGET_LIST_END);
|
||||
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_TRCL_LIST_COUNTERS: {
|
||||
int y1 = r.top + WD_FRAMERECT_TOP;
|
||||
int max = min(this->sb->GetPosition() + this->sb->GetCapacity(), this->ctrs.size());
|
||||
for (int i = this->sb->GetPosition(); i < max; ++i) {
|
||||
const TraceRestrictCounter *ctr = this->ctrs[i];
|
||||
|
||||
assert(ctr->owner == this->owner);
|
||||
|
||||
DrawCounterInfo(y1, r.left, r.right, ctr->index);
|
||||
|
||||
y1 += this->tiny_step_height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DeleteCounterCallback(Window *win, bool confirmed)
|
||||
{
|
||||
if (confirmed) {
|
||||
TraceRestrictCounterWindow *w = (TraceRestrictCounterWindow*)win;
|
||||
w->selected = INVALID_TRACE_RESTRICT_COUNTER_ID;
|
||||
DoCommandP(0, w->ctr_confirm, 0, CMD_DELETE_TRACERESTRICT_COUNTER | CMD_MSG(STR_TRACE_RESTRICT_ERROR_COUNTER_CAN_T_DELETE));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_TRCL_LIST_COUNTERS: { // Matrix
|
||||
uint id_s = this->sb->GetScrolledRowFromWidget(pt.y, this, WID_TRCL_LIST_COUNTERS, 0, this->tiny_step_height);
|
||||
if (id_s >= this->ctrs.size()) return;
|
||||
|
||||
this->selected = this->ctrs[id_s]->index;
|
||||
|
||||
this->SetDirty();
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_TRCL_CREATE_COUNTER: { // Create a new counter
|
||||
this->ShowCreateCounterWindow();
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_TRCL_DELETE_COUNTER: { // Delete the selected counter
|
||||
this->ctr_confirm = this->selected;
|
||||
ShowQuery(STR_TRACE_RESTRICT_COUNTER_QUERY_DELETE_CAPTION, STR_TRACE_RESTRICT_COUNTER_DELETE_QUERY_TEXT, this, DeleteCounterCallback);
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_TRCL_RENAME_COUNTER: // Rename the selected counter
|
||||
this->ShowRenameCounterWindow(this->selected);
|
||||
break;
|
||||
|
||||
case WID_TRCL_SET_COUNTER_VALUE:
|
||||
this->ShowSetCounterValueWindow(this->selected);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnQueryTextFinished(char *str) override
|
||||
{
|
||||
if (str != nullptr) {
|
||||
switch (this->qto) {
|
||||
case QTO_RENAME:
|
||||
if (this->ctr_qt_op == NEW_TRACE_RESTRICT_COUNTER_ID) {
|
||||
DoCommandP(0, 0, 0, CMD_CREATE_TRACERESTRICT_COUNTER | CMD_MSG(STR_TRACE_RESTRICT_ERROR_COUNTER_CAN_T_CREATE), nullptr, str);
|
||||
} else {
|
||||
DoCommandP(0, this->ctr_qt_op, 0, CMD_ALTER_TRACERESTRICT_COUNTER | CMD_MSG(STR_TRACE_RESTRICT_ERROR_COUNTER_CAN_T_MODIFY), nullptr, str);
|
||||
}
|
||||
break;
|
||||
|
||||
case QTO_SET_VALUE:
|
||||
if (!StrEmpty(str)) DoCommandP(0, this->ctr_qt_op | (1 << 16), atoi(str), CMD_ALTER_TRACERESTRICT_COUNTER | CMD_MSG(STR_TRACE_RESTRICT_ERROR_COUNTER_CAN_T_MODIFY));
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->ctr_qt_op = INVALID_TRACE_RESTRICT_COUNTER_ID;
|
||||
}
|
||||
|
||||
virtual void OnResize() override
|
||||
{
|
||||
this->sb->SetCapacityFromWidget(this, WID_TRCL_LIST_COUNTERS);
|
||||
}
|
||||
|
||||
virtual void OnGameTick() override
|
||||
{
|
||||
if (this->ctrs.NeedResort()) {
|
||||
this->SetDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void ShowRenameCounterWindow(TraceRestrictCounterID ctr_id)
|
||||
{
|
||||
assert(TraceRestrictCounter::IsValidID(ctr_id));
|
||||
this->qto = QTO_RENAME;
|
||||
this->ctr_qt_op = ctr_id;
|
||||
SetDParam(0, ctr_id);
|
||||
ShowQueryString(STR_TRACE_RESTRICT_COUNTER_NAME, STR_TRACE_RESTRICT_COUNTER_RENAME_CAPTION, MAX_LENGTH_TRACE_RESTRICT_SLOT_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
|
||||
}
|
||||
|
||||
void ShowSetCounterValueWindow(TraceRestrictCounterID ctr_id)
|
||||
{
|
||||
assert(TraceRestrictCounter::IsValidID(ctr_id));
|
||||
this->qto = QTO_SET_VALUE;
|
||||
this->ctr_qt_op = ctr_id;
|
||||
SetDParam(0, TraceRestrictCounter::Get(ctr_id)->value);
|
||||
ShowQueryString(STR_JUST_INT, STR_TRACE_RESTRICT_COUNTER_SET_VALUE_CAPTION, 5, this, CS_NUMERAL, QSF_ENABLE_DEFAULT);
|
||||
}
|
||||
|
||||
void ShowCreateCounterWindow()
|
||||
{
|
||||
this->qto = QTO_RENAME;
|
||||
this->ctr_qt_op = NEW_TRACE_RESTRICT_COUNTER_ID;
|
||||
ShowQueryString(STR_EMPTY, STR_TRACE_RESTRICT_COUNTER_CREATE_CAPTION, MAX_LENGTH_TRACE_RESTRICT_SLOT_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
|
||||
}
|
||||
};
|
||||
|
||||
static WindowDesc _counter_window_desc(
|
||||
WDP_AUTO, "list_tr_counters", 525, 246,
|
||||
WC_TRACE_RESTRICT_COUNTERS, WC_NONE,
|
||||
0,
|
||||
_nested_counter_widgets, lengthof(_nested_counter_widgets)
|
||||
);
|
||||
|
||||
/**
|
||||
* Show the trace restrict counter window for the given company.
|
||||
* @param company The company to show the window for.
|
||||
*/
|
||||
void ShowTraceRestrictCounterWindow(CompanyID company)
|
||||
{
|
||||
if (!Company::IsValidID(company)) return;
|
||||
|
||||
AllocateWindowDescFront<TraceRestrictCounterWindow>(&_counter_window_desc, (WindowNumber)company);
|
||||
}
|
||||
|
@@ -4123,10 +4123,10 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
||||
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 | TRPAUF_REVERSE | TRPAUF_SPEED_RESTRICTION)) {
|
||||
if (prog && prog->actions_used_flags & (TRPAUF_SLOT_ACQUIRE | TRPAUF_SLOT_RELEASE_FRONT | TRPAUF_REVERSE | TRPAUF_SPEED_RESTRICTION | TRPAUF_CHANGE_COUNTER)) {
|
||||
TraceRestrictProgramResult out;
|
||||
TraceRestrictProgramInput input(gp.new_tile, dir, nullptr, nullptr);
|
||||
input.permitted_slot_operations = TRPISP_ACQUIRE | TRPISP_RELEASE_FRONT;
|
||||
input.permitted_slot_operations = TRPISP_ACQUIRE | TRPISP_RELEASE_FRONT | TRPISP_CHANGE_COUNTER;
|
||||
prog->Execute(v, input, out);
|
||||
if (out.flags & TRPRF_REVERSE && GetSignalType(gp.new_tile, TrackdirToTrack(dir)) == SIGTYPE_PBS &&
|
||||
!HasSignalOnTrackdir(gp.new_tile, dir)) {
|
||||
|
@@ -367,6 +367,7 @@ DropDownList BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplac
|
||||
}
|
||||
if (this->vli.vtype == VEH_TRAIN && _settings_client.gui.show_adv_tracerestrict_features) {
|
||||
list.emplace_back(new DropDownListStringItem(STR_TRACE_RESTRICT_SLOT_MANAGE, ADI_TRACERESTRICT_SLOT_MGMT, false));
|
||||
list.emplace_back(new DropDownListStringItem(STR_TRACE_RESTRICT_COUNTER_MANAGE, ADI_TRACERESTRICT_COUNTER_MGMT, false));
|
||||
}
|
||||
if (change_order_str != 0) {
|
||||
list.emplace_back(new DropDownListStringItem(change_order_str, ADI_CHANGE_ORDER, disable));
|
||||
@@ -2115,6 +2116,12 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
case ADI_TRACERESTRICT_COUNTER_MGMT: {
|
||||
extern void ShowTraceRestrictCounterWindow(CompanyID company);
|
||||
ShowTraceRestrictCounterWindow(this->owner);
|
||||
break;
|
||||
}
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
break;
|
||||
|
@@ -51,6 +51,7 @@ struct BaseVehicleListWindow : public Window {
|
||||
ADI_CHANGE_ORDER,
|
||||
ADI_CREATE_GROUP,
|
||||
ADI_TRACERESTRICT_SLOT_MGMT,
|
||||
ADI_TRACERESTRICT_COUNTER_MGMT,
|
||||
};
|
||||
|
||||
static const StringID vehicle_depot_name[];
|
||||
|
@@ -733,6 +733,12 @@ enum WindowClass {
|
||||
*/
|
||||
WC_TRACE_RESTRICT_SLOTS,
|
||||
|
||||
/**
|
||||
* Trace restrict counter window; %Window numbers:
|
||||
* - Packed value = #SlotListWidgets / #VehicleListWidgets
|
||||
*/
|
||||
WC_TRACE_RESTRICT_COUNTERS,
|
||||
|
||||
/**
|
||||
* Programmable pre-signals window
|
||||
*/
|
||||
|
Reference in New Issue
Block a user