Scheduled dispatch: Allow naming departure slot tags

This commit is contained in:
Jonathan G Rennison
2024-06-13 19:32:42 +01:00
parent fe294403aa
commit fff46974fd
11 changed files with 215 additions and 36 deletions

View File

@@ -306,6 +306,7 @@ CommandProc CmdScheduledDispatchAppendVehicleSchedules;
CommandProc CmdScheduledDispatchAdjust;
CommandProc CmdScheduledDispatchSwapSchedules;
CommandProcEx CmdScheduledDispatchSetSlotFlags;
CommandProc CmdScheduledDispatchRenameTag;
CommandProc CmdAddPlan;
CommandProcEx CmdAddPlanLine;
@@ -572,6 +573,7 @@ static const Command _command_proc_table[] = {
DEF_CMD(CmdScheduledDispatchAdjust, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_ADJUST
DEF_CMD(CmdScheduledDispatchSwapSchedules, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_SWAP_SCHEDULES
DEF_CMD(CmdScheduledDispatchSetSlotFlags, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_SET_SLOT_FLAGS
DEF_CMD(CmdScheduledDispatchRenameTag, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_RENAME_TAG
DEF_CMD(CmdAddPlan, 0, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN
DEF_CMD(CmdAddPlanLine, CMD_NO_TEST, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN_LINE

View File

@@ -522,6 +522,7 @@ enum Commands {
CMD_SCHEDULED_DISPATCH_ADJUST, ///< scheduled dispatch adjust time offsets in schedule
CMD_SCHEDULED_DISPATCH_SWAP_SCHEDULES, ///< scheduled dispatch swap schedules in order
CMD_SCHEDULED_DISPATCH_SET_SLOT_FLAGS, ///< scheduled dispatch set flags of dispatch slot
CMD_SCHEDULED_DISPATCH_RENAME_TAG, ///< scheduled dispatch rename departure tag
CMD_ADD_PLAN,
CMD_ADD_PLAN_LINE,

View File

@@ -1723,8 +1723,14 @@ STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_FIRST :is first slot
STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_NOT_FIRST :is not first slot
STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_LAST :is last slot
STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_NOT_LAST :is not last slot
###length 2
STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_HAS_TAG :has tag {NUM}
STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_HAS_TAG_NAMED :has tag {NUM} ({RAW_STRING})
###length 2
STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_DOESNT_HAVE_TAG :doesn't have tag {NUM}
STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_DOESNT_HAVE_TAG_NAMED :doesn't have tag {NUM} ({RAW_STRING})
STR_ORDERS_MANAGE_LIST :{BLACK}Manage List
STR_ORDERS_MANAGE_LIST_TOOLTIP :{BLACK}Manage this order list
@@ -2195,10 +2201,16 @@ STR_SCHDISPATCH_APPEND_VEHICLE_SCHEDULES :{BLACK}Append S
STR_SCHDISPATCH_APPEND_VEHICLE_SCHEDULES_TOOLTIP :{BLACK}Append the dispatch schedules from another vehicle.
STR_SCHDISPATCH_REUSE_DEPARTURE_SLOTS :Re-use departure slots
STR_SCHDISPATCH_REUSE_DEPARTURE_SLOTS_TOOLTIP :{BLACK}Set whether departure slots may be used more than once.
STR_SCHDISPATCH_RENAME_DEPARTURE_TAG :Rename tag {NUM}
STR_SCHDISPATCH_RENAME_DEPARTURE_TAG_NAMED :Rename tag {NUM}: {RAW_STRING}
STR_SCHDISPATCH_RENAME_DEPARTURE_TAG_TOOLTIP :{BLACK}Rename departure slot tags (for use with conditional orders)
STR_SCHDISPATCH_RENAME_DEPARTURE_TAG_CAPTION :{BLACK}Name departure slot tag
STR_ERROR_CAN_T_RENAME_DEPARTURE_TAG :{WHITE}Can't name departure tag...
STR_SCHDISPATCH_MANAGE_SLOT :{BLACK}Manage Slot
STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_SLOT :Re-use departure slot
STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_SLOT_TOOLTIP :{BLACK}Set whether the selected departure slot may be used more than once.
STR_SCHDISPATCH_TAG_DEPARTURE :Tag {NUM}
STR_SCHDISPATCH_TAG_DEPARTURE_NAMED :Tag {NUM}: {RAW_STRING}
STR_SCHDISPATCH_TAG_DEPARTURE_TOOLTIP :{BLACK}Tag the selected departure slot (for use with conditional orders).
STR_SCHDISPATCH_NO_SCHEDULES :{BLACK}No Schedules
STR_SCHDISPATCH_SCHEDULE_ID :{BLACK}Schedule {NUM} of {NUM}
@@ -2215,6 +2227,7 @@ STR_SCHDISPATCH_SLOT_TOOLTIP_NEXT :{}Next availabl
STR_SCHDISPATCH_SLOT_TOOLTIP_REUSE :{}Departure slot may be used more than once
STR_SCHDISPATCH_SLOT_TOOLTIP_TIME_SUFFIX : ({TT_TIME})
STR_SCHDISPATCH_SLOT_TOOLTIP_TAG :{}Tag {NUM}
STR_SCHDISPATCH_SLOT_TOOLTIP_TAG_NAMED :{}Tag {NUM}: {RAW_STRING}
STR_SCHDISPATCH_SUMMARY_NO_LAST_DEPARTURE :{BLACK}No previous departures.
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_PAST :{BLACK}Last departure at {TT_TIME}.

View File

@@ -742,7 +742,13 @@ struct DispatchSlot {
};
};
enum ScheduledDispatchSupplementaryNameType : uint16_t {
SDSNT_DEPARTURE_TAG = 0, ///< Departure slot tag
};
struct DispatchSchedule {
static constexpr uint DEPARTURE_TAG_COUNT = 4;
private:
friend SaveLoadTable GetDispatchScheduleDescription(); ///< Saving and loading of dispatch schedules
@@ -754,6 +760,7 @@ private:
uint8_t scheduled_dispatch_flags = 0; ///< Flags
std::string name; ///< Name of dispatch schedule
btree::btree_map<uint32_t, std::string> supplementary_names; ///< Supplementary name strings
inline void CopyBasicFields(const DispatchSchedule &other)
{
@@ -869,8 +876,14 @@ public:
inline std::string &ScheduleName() { return this->name; }
inline const std::string &ScheduleName() const { return this->name; }
std::string_view GetSupplementaryName(ScheduledDispatchSupplementaryNameType name_type, uint16_t id) const;
void SetSupplementaryName(ScheduledDispatchSupplementaryNameType name_type, uint16_t id, std::string name);
btree::btree_map<uint32_t, std::string> &GetSupplementaryNameMap() { return this->supplementary_names; }
};
static_assert(DispatchSchedule::DEPARTURE_TAG_COUNT == 1 + (DispatchSlot::SDSF_LAST_TAG - DispatchSlot::SDSF_FIRST_TAG));
/**
* Shared order list linking together the linked list of orders and the list
* of vehicles sharing this order list.

View File

@@ -1121,11 +1121,13 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
SetDParam(3, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + order->GetConditionComparator());
SetDParam(4, order->GetXData());
} else if (ocv == OCV_DISPATCH_SLOT) {
const DispatchSchedule *selected_schedule = nullptr;
SetDParam(0, STR_ORDER_CONDITIONAL_DISPATCH_SLOT_DISPLAY);
if (GB(order->GetXData(), 0, 16) != UINT16_MAX) {
bool have_name = false;
if (GB(order->GetXData(), 0, 16) < v->orders->GetScheduledDispatchScheduleCount()) {
const DispatchSchedule &ds = v->orders->GetDispatchScheduleByIndex(GB(order->GetXData(), 0, 16));
selected_schedule = &ds;
if (!ds.ScheduleName().empty()) {
_temp_special_strings[0] = ds.ScheduleName();
have_name = true;
@@ -1150,8 +1152,15 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
break;
case OCDM_TAG: {
auto tmp_params = MakeParameters(GB(value, ODFLCB_TAG_START, ODFLCB_TAG_COUNT) + 1);
_temp_special_strings[1] = GetStringWithArgs((order->GetConditionComparator() == OCC_IS_FALSE) ? STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_DOESNT_HAVE_TAG : STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_HAS_TAG, tmp_params);
StringID str = (order->GetConditionComparator() == OCC_IS_FALSE) ? STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_DOESNT_HAVE_TAG : STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_HAS_TAG;
uint tag_id = GB(value, ODFLCB_TAG_START, ODFLCB_TAG_COUNT);
std::string_view name;
if (selected_schedule != nullptr) {
name = selected_schedule->GetSupplementaryName(SDSNT_DEPARTURE_TAG, tag_id);
if (!name.empty()) str++;
}
auto tmp_params = MakeParameters(tag_id + 1, std::string{name});
_temp_special_strings[1] = GetStringWithArgs(str, tmp_params);
SetDParam(4, SPECSTR_TEMP_START + 1);
break;
}
@@ -3170,23 +3179,32 @@ public:
list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_LAST, true_cond | first_last_value, false));
list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_NOT_LAST, false_cond | first_last_value, false));
const DispatchSchedule *ds = nullptr;
uint16_t slot_flags = 0;
uint schedule_index = GB(o->GetXData(), 0, 16);
if (schedule_index < this->vehicle->orders->GetScheduledDispatchScheduleCount()) {
const DispatchSchedule &ds = this->vehicle->orders->GetDispatchScheduleByIndex(schedule_index);
for (const DispatchSlot &slot : ds.GetScheduledDispatch()) {
ds = &(this->vehicle->orders->GetDispatchScheduleByIndex(schedule_index));
for (const DispatchSlot &slot : ds->GetScheduledDispatch()) {
slot_flags |= slot.flags;
}
}
for (uint8_t tag = 0; tag <= (DispatchSlot::SDSF_LAST_TAG - DispatchSlot::SDSF_FIRST_TAG); tag++) {
for (uint8_t tag = 0; tag < DispatchSchedule::DEPARTURE_TAG_COUNT; tag++) {
if (HasBit(slot_flags, tag + DispatchSlot::SDSF_FIRST_TAG)) {
int tag_cond_value = 0;
SB(tag_cond_value, ODCB_MODE_START, ODCB_MODE_COUNT, OCDM_TAG);
SB(tag_cond_value, ODFLCB_TAG_START, ODFLCB_TAG_COUNT, tag);
SetDParam(0, tag + 1);
list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_HAS_TAG, true_cond | tag_cond_value, false));
list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_DOESNT_HAVE_TAG, false_cond | tag_cond_value, false));
uint string_offset = 0;
if (ds != nullptr) {
std::string_view name = ds->GetSupplementaryName(SDSNT_DEPARTURE_TAG, tag);
if (!name.empty()) {
SetDParamStr(1, name);
string_offset = 1;
}
}
list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_HAS_TAG + string_offset, true_cond | tag_cond_value, false));
list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_DOESNT_HAVE_TAG + string_offset, false_cond | tag_cond_value, false));
}
}

View File

@@ -480,6 +480,46 @@ CommandCost CmdScheduledDispatchRenameSchedule(TileIndex tile, DoCommandFlag fla
return CommandCost();
}
/**
* Rename scheduled dispatch departure tag
*
* @param tile Not used.
* @param flags Operation to perform.
* @param p1 Vehicle index
* @param p2 Tag ID
* @param text name
* @return the cost of this operation or an error
*/
CommandCost CmdScheduledDispatchRenameTag(TileIndex tile, DoCommandFlag flags, uint32_t p1, uint32_t p2, const char *text)
{
VehicleID veh = GB(p1, 0, 20);
uint schedule_index = GB(p1, 20, 12);
Vehicle *v = Vehicle::GetIfValid(veh);
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
CommandCost ret = CheckOwnership(v->owner);
if (ret.Failed()) return ret;
if (v->orders == nullptr) return CMD_ERROR;
if (schedule_index >= v->orders->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
if (p2 >= DispatchSchedule::DEPARTURE_TAG_COUNT) return CMD_ERROR;
std::string name;
if (!StrEmpty(text)) {
if (Utf8StringLength(text) >= MAX_LENGTH_VEHICLE_NAME_CHARS) return CMD_ERROR;
name = text;
}
if (flags & DC_EXEC) {
v->orders->GetDispatchScheduleByIndex(schedule_index).SetSupplementaryName(SDSNT_DEPARTURE_TAG, static_cast<uint16_t>(p2), std::move(name));
SetTimetableWindowsDirty(v, STWDF_SCHEDULED_DISPATCH | STWDF_ORDERS);
}
return CommandCost();
}
/**
* Duplicate scheduled dispatch schedule
*
@@ -801,3 +841,25 @@ void DispatchSchedule::UpdateScheduledDispatch(const Vehicle *v)
SetTimetableWindowsDirty(v, STWDF_SCHEDULED_DISPATCH);
}
}
static inline uint32_t SupplementaryNameKey(ScheduledDispatchSupplementaryNameType name_type, uint16_t id)
{
return (static_cast<uint32_t>(name_type) << 16) | id;
}
std::string_view DispatchSchedule::GetSupplementaryName(ScheduledDispatchSupplementaryNameType name_type, uint16_t id) const
{
auto iter = this->supplementary_names.find(SupplementaryNameKey(name_type, id));
if (iter == this->supplementary_names.end()) return {};
return iter->second;
}
void DispatchSchedule::SetSupplementaryName(ScheduledDispatchSupplementaryNameType name_type, uint16_t id, std::string name)
{
uint32_t key = SupplementaryNameKey(name_type, id);
if (name.empty()) {
this->supplementary_names.erase(key);
} else {
this->supplementary_names.insert({ key, std::move(name) });
}
}

View File

@@ -191,6 +191,7 @@ static void AddNewScheduledDispatchSchedule(VehicleID vindex)
struct SchdispatchWindow : GeneralVehicleWindow {
int schedule_index;
int clicked_widget; ///< The widget that was clicked (used to determine what to do in OnQueryTextFinished)
int click_subaction; ///< Subaction for clicked_widget
Scrollbar *vscroll; ///< Verticle scrollbar
uint num_columns; ///< Number of columns.
@@ -216,6 +217,7 @@ struct SchdispatchWindow : GeneralVehicleWindow {
SCH_MD_DUPLICATE_SCHEDULE,
SCH_MD_APPEND_VEHICLE_SCHEDULES,
SCH_MD_REUSE_DEPARTURE_SLOTS,
SCH_MD_RENAME_TAG,
};
@@ -469,6 +471,7 @@ struct SchdispatchWindow : GeneralVehicleWindow {
add_suffix(STR_SCHDISPATCH_DUPLICATE_SCHEDULE_TOOLTIP);
add_suffix(STR_SCHDISPATCH_APPEND_VEHICLE_SCHEDULES_TOOLTIP);
add_suffix(STR_SCHDISPATCH_REUSE_DEPARTURE_SLOTS_TOOLTIP);
add_suffix(STR_SCHDISPATCH_RENAME_DEPARTURE_TAG_TOOLTIP);
GuiShowTooltips(this, SPECSTR_TEMP_START, close_cond);
return true;
}
@@ -547,7 +550,9 @@ struct SchdispatchWindow : GeneralVehicleWindow {
for (uint8_t flag_bit = DispatchSlot::SDSF_FIRST_TAG; flag_bit <= DispatchSlot::SDSF_LAST_TAG; flag_bit++) {
if (HasBit(flags, flag_bit)) {
SetDParam(0, 1 + flag_bit - DispatchSlot::SDSF_FIRST_TAG);
_temp_special_strings[0] += GetString(STR_SCHDISPATCH_SLOT_TOOLTIP_TAG);
std::string_view name = ds.GetSupplementaryName(SDSNT_DEPARTURE_TAG, flag_bit - DispatchSlot::SDSF_FIRST_TAG);
SetDParamStr(1, name);
_temp_special_strings[0] += GetString(name.empty() ? STR_SCHDISPATCH_SLOT_TOOLTIP_TAG : STR_SCHDISPATCH_SLOT_TOOLTIP_TAG_NAMED);
}
}
}
@@ -1054,6 +1059,13 @@ struct SchdispatchWindow : GeneralVehicleWindow {
add_item(STR_SCHDISPATCH_APPEND_VEHICLE_SCHEDULES, SCH_MD_APPEND_VEHICLE_SCHEDULES);
list.push_back(MakeDropDownListDividerItem());
list.push_back(MakeDropDownListCheckedItem(schedule.GetScheduledDispatchReuseSlots(), STR_SCHDISPATCH_REUSE_DEPARTURE_SLOTS, SCH_MD_REUSE_DEPARTURE_SLOTS, false));
list.push_back(MakeDropDownListDividerItem());
for (uint8_t tag = 0; tag < DispatchSchedule::DEPARTURE_TAG_COUNT; tag++) {
SetDParam(0, tag + 1);
std::string_view name = schedule.GetSupplementaryName(SDSNT_DEPARTURE_TAG, tag);
SetDParamStr(1, name);
add_item(name.empty() ? STR_SCHDISPATCH_RENAME_DEPARTURE_TAG : STR_SCHDISPATCH_RENAME_DEPARTURE_TAG_NAMED, SCH_MD_RENAME_TAG | (tag << 16));
}
ShowDropDownList(this, std::move(list), -1, WID_SCHDISPATCH_MANAGEMENT);
break;
}
@@ -1115,7 +1127,9 @@ struct SchdispatchWindow : GeneralVehicleWindow {
list.push_back(MakeDropDownListDividerItem());
for (uint8_t flag_bit = DispatchSlot::SDSF_FIRST_TAG; flag_bit <= DispatchSlot::SDSF_LAST_TAG; flag_bit++) {
SetDParam(0, 1 + flag_bit - DispatchSlot::SDSF_FIRST_TAG);
add_item(STR_SCHDISPATCH_TAG_DEPARTURE, flag_bit, false);
std::string_view name = schedule.GetSupplementaryName(SDSNT_DEPARTURE_TAG, flag_bit - DispatchSlot::SDSF_FIRST_TAG);
SetDParamStr(1, name);
add_item(name.empty() ? STR_SCHDISPATCH_TAG_DEPARTURE : STR_SCHDISPATCH_TAG_DEPARTURE_NAMED, flag_bit, false);
}
ShowDropDownList(this, std::move(list), -1, WID_SCHDISPATCH_MANAGE_SLOT);
@@ -1167,7 +1181,7 @@ struct SchdispatchWindow : GeneralVehicleWindow {
switch (widget) {
case WID_SCHDISPATCH_MANAGEMENT: {
if (!this->IsScheduleSelected()) break;
switch((ManagementDropdown)index) {
switch((ManagementDropdown)index & 0xFFFF) {
case SCH_MD_RESET_LAST_DISPATCHED:
DoCommandP(0, this->vehicle->index | (this->schedule_index << 20), 0, CMD_SCHEDULED_DISPATCH_RESET_LAST_DISPATCH | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
break;
@@ -1201,6 +1215,14 @@ struct SchdispatchWindow : GeneralVehicleWindow {
DoCommandP(0, this->vehicle->index | (this->schedule_index << 20), this->GetSelectedSchedule().GetScheduledDispatchReuseSlots() ? 0 : 1, CMD_SCHEDULED_DISPATCH_SET_REUSE_SLOTS | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
break;
}
case SCH_MD_RENAME_TAG: {
this->clicked_widget = WID_SCHDISPATCH_MANAGEMENT;
this->click_subaction = index;
SetDParamStr(0, this->GetSelectedSchedule().GetSupplementaryName(SDSNT_DEPARTURE_TAG, index >> 16));
ShowQueryString(STR_JUST_RAW_STRING, STR_SCHDISPATCH_RENAME_DEPARTURE_TAG_CAPTION, MAX_LENGTH_VEHICLE_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
break;
}
}
break;
}
@@ -1298,6 +1320,17 @@ struct SchdispatchWindow : GeneralVehicleWindow {
}
break;
}
case WID_SCHDISPATCH_MANAGEMENT: {
if (str == nullptr) return;
switch (this->click_subaction & 0xFFFF) {
case SCH_MD_RENAME_TAG:
DoCommandP(0, v->index | (this->schedule_index << 20), this->click_subaction >> 16, CMD_SCHEDULED_DISPATCH_RENAME_TAG | CMD_MSG(STR_ERROR_CAN_T_RENAME_DEPARTURE_TAG), nullptr, str);
break;
}
break;
}
}
this->SetDirty();

View File

@@ -117,7 +117,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_STATION_CATCHMENT_INC, XSCF_NULL, 1, 1, "station_catchment_inc", nullptr, nullptr, nullptr },
{ XSLFI_CUSTOM_BRIDGE_HEADS, XSCF_NULL, 4, 4, "custom_bridge_heads", nullptr, nullptr, nullptr },
{ XSLFI_CHUNNEL, XSCF_NULL, 2, 2, "chunnel", nullptr, nullptr, "TUNN" },
{ XSLFI_SCHEDULED_DISPATCH, XSCF_NULL, 7, 7, "scheduled_dispatch", nullptr, nullptr, nullptr },
{ XSLFI_SCHEDULED_DISPATCH, XSCF_NULL, 8, 8, "scheduled_dispatch", nullptr, nullptr, nullptr },
{ XSLFI_MORE_TOWN_GROWTH_RATES, XSCF_NULL, 1, 1, "more_town_growth_rates", nullptr, nullptr, nullptr },
{ XSLFI_MULTIPLE_DOCKS, XSCF_NULL, 2, 2, "multiple_docks", nullptr, nullptr, nullptr },
{ XSLFI_TIMETABLE_EXTRA, XSCF_NULL, 7, 7, "timetable_extra", nullptr, nullptr, "ORDX" },

View File

@@ -311,6 +311,54 @@ static void SetupDescs_ORDL()
_filtered_ordl_slot_desc = SlFilterObject(GetDispatchSlotDescription());
}
static void SaveDispatchSchedule(DispatchSchedule &ds)
{
SlObjectSaveFiltered(&ds, _filtered_ordl_sd_desc);
SlWriteUint32((uint32_t)ds.GetScheduledDispatchMutable().size());
for (DispatchSlot &slot : ds.GetScheduledDispatchMutable()) {
SlObjectSaveFiltered(&slot, _filtered_ordl_slot_desc);
}
{
btree::btree_map<uint32_t, std::string> &names = ds.GetSupplementaryNameMap();
SlWriteUint32((uint32_t)names.size());
for (auto &it : names) {
SlWriteUint32(it.first);
SlStdString(it.second, SLE_STR);
}
}
}
static void LoadDispatchSchedule(DispatchSchedule &ds)
{
SlObjectLoadFiltered(&ds, _filtered_ordl_sd_desc);
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 4) && _old_scheduled_dispatch_start_full_date_fract != 0) {
_old_scheduled_dispatch_start_full_date_fract_map[&ds] = _old_scheduled_dispatch_start_full_date_fract;
}
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 6)) {
ds.GetScheduledDispatchMutable().reserve(_old_scheduled_dispatch_slots.size());
for (uint32_t slot : _old_scheduled_dispatch_slots) {
ds.GetScheduledDispatchMutable().push_back({ slot, 0 });
}
} else {
ds.GetScheduledDispatchMutable().resize(SlReadUint32());
for (DispatchSlot &slot : ds.GetScheduledDispatchMutable()) {
SlObjectLoadFiltered(&slot, _filtered_ordl_slot_desc);
}
}
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 8)) {
uint32_t string_count = SlReadUint32();
btree::btree_map<uint32_t, std::string> &names = ds.GetSupplementaryNameMap();
for (uint32_t i = 0; i < string_count; i++) {
uint32_t key = SlReadUint32();
SlStdString(names[key], SLE_STR);
}
}
}
static void Save_ORDL()
{
SetupDescs_ORDL();
@@ -321,12 +369,7 @@ static void Save_ORDL()
SlObjectSaveFiltered(list, _filtered_ordl_desc);
SlWriteUint32(list->GetScheduledDispatchScheduleCount());
for (DispatchSchedule &ds : list->GetScheduledDispatchScheduleSet()) {
SlObjectSaveFiltered(&ds, _filtered_ordl_sd_desc);
SlWriteUint32((uint32_t)ds.GetScheduledDispatchMutable().size());
for (DispatchSlot &slot : ds.GetScheduledDispatchMutable()) {
SlObjectSaveFiltered(&slot, _filtered_ordl_slot_desc);
}
SaveDispatchSchedule(ds);
}
}, list);
}
@@ -358,22 +401,7 @@ static void Load_ORDL()
uint count = SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 3) ? SlReadUint32() : 1;
list->GetScheduledDispatchScheduleSet().resize(count);
for (DispatchSchedule &ds : list->GetScheduledDispatchScheduleSet()) {
SlObjectLoadFiltered(&ds, _filtered_ordl_sd_desc);
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 4) && _old_scheduled_dispatch_start_full_date_fract != 0) {
_old_scheduled_dispatch_start_full_date_fract_map[&ds] = _old_scheduled_dispatch_start_full_date_fract;
}
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 6)) {
ds.GetScheduledDispatchMutable().reserve(_old_scheduled_dispatch_slots.size());
for (uint32_t slot : _old_scheduled_dispatch_slots) {
ds.GetScheduledDispatchMutable().push_back({ slot, 0 });
}
} else {
ds.GetScheduledDispatchMutable().resize(SlReadUint32());
for (DispatchSlot &slot : ds.GetScheduledDispatchMutable()) {
SlObjectLoadFiltered(&slot, _filtered_ordl_slot_desc);
}
}
LoadDispatchSchedule(ds);
}
}
}
@@ -426,6 +454,8 @@ void Save_BKOR()
* normal games this information isn't needed. */
if (!_networking || !_network_server) return;
SetupDescs_ORDL();
for (OrderBackup *ob : OrderBackup::Iterate()) {
SlSetArrayIndex(ob->index);
SlAutolength([](void *data) {
@@ -433,7 +463,7 @@ void Save_BKOR()
SlObject(ob, GetOrderBackupDescription());
SlWriteUint32((uint)ob->dispatch_schedules.size());
for (DispatchSchedule &ds : ob->dispatch_schedules) {
SlObject(&ds, GetDispatchScheduleDescription());
SaveDispatchSchedule(ds);
}
}, ob);
}
@@ -443,6 +473,8 @@ void Load_BKOR()
{
int index;
SetupDescs_ORDL();
while ((index = SlIterateArray()) != -1) {
/* set num_orders to 0 so it's a valid OrderList */
OrderBackup *ob = new (index) OrderBackup();
@@ -451,7 +483,11 @@ void Load_BKOR()
uint count = SlReadUint32();
ob->dispatch_schedules.resize(count);
for (DispatchSchedule &ds : ob->dispatch_schedules) {
SlObject(&ds, GetDispatchScheduleDescription());
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 8)) {
LoadDispatchSchedule(ds);
} else {
SlObject(&ds, GetDispatchScheduleDescription());
}
}
}
}

View File

@@ -1254,7 +1254,7 @@ static void SlString(void *ptr, size_t length, VarType conv)
* @param ptr the string being manipulated
* @param conv must be SLE_FILE_STRING
*/
static void SlStdString(std::string &str, VarType conv)
void SlStdString(std::string &str, VarType conv)
{
switch (_sl.action) {
case SLA_SAVE: {

View File

@@ -1061,6 +1061,7 @@ void SlLoadFromBuffer(const uint8_t *buffer, size_t length, F proc)
}
void SlGlobList(const SaveLoadTable &slt);
void SlStdString(std::string &str, VarType conv);
void SlArray(void *array, size_t length, VarType conv);
void SlObject(void *object, const SaveLoadTable &slt);
bool SlObjectMember(void *object, const SaveLoad &sld);