diff --git a/plugins/lua/orders.lua b/plugins/lua/orders.lua index 7a87e529f..91fd3bef6 100644 --- a/plugins/lua/orders.lua +++ b/plugins/lua/orders.lua @@ -62,12 +62,24 @@ local function do_export() }:show() end +local function do_reset() + dfhack.run_command('orders', 'reset') +end + +local function do_sort_type() + dfhack.run_command('orders', 'sort_type') +end + +local function do_sort_mat() + dfhack.run_command('orders', 'sort_material') +end + OrdersOverlay = defclass(OrdersOverlay, overlay.OverlayWidget) OrdersOverlay.ATTRS{ default_pos={x=53,y=-6}, default_enabled=true, viewscreens='dwarfmode/Info/WORK_ORDERS/Default', - frame={w=30, h=4}, + frame={w=75, h=4}, } function OrdersOverlay:init() @@ -95,13 +107,34 @@ function OrdersOverlay:init() }, widgets.HotkeyLabel{ frame={t=0, l=15}, - label='sort', + label='sort by freq', key='CUSTOM_CTRL_O', auto_width=true, on_activate=do_sort, }, widgets.HotkeyLabel{ frame={t=1, l=15}, + label='sort by type', + key='CUSTOM_CTRL_T', + auto_width=true, + on_activate=do_sort_type, + }, + widgets.HotkeyLabel{ + frame={t=0, l=35}, + label='sort by mat', + key='CUSTOM_CTRL_T', + auto_width=true, + on_activate=do_sort_mat, + }, + widgets.HotkeyLabel{ + frame={t=1, l=35}, + label='reset', + key='CUSTOM_CTRL_R', + auto_width=true, + on_activate=do_reset, + }, + widgets.HotkeyLabel{ + frame={t=1, l=55}, label='clear', key='CUSTOM_CTRL_C', auto_width=true, diff --git a/plugins/lua/sort.lua b/plugins/lua/sort.lua index 15d9ebabb..778bc87b9 100644 --- a/plugins/lua/sort.lua +++ b/plugins/lua/sort.lua @@ -212,7 +212,7 @@ local function melee_skill_effectiveness(unit) end local function get_melee_skill_effectiveness_rating(unit) - return get_rating(melee_skill_effectiveness(unit), 350000, 2350000, 78, 64, 49, 35) + return get_rating(melee_skill_effectiveness(unit), 350000, 2750000, 64, 52, 40, 28) end local function make_sort_by_melee_skill_effectiveness_desc() @@ -272,7 +272,7 @@ local function ranged_skill_effectiveness(unit) end local function get_ranged_skill_effectiveness_rating(unit) - return get_rating(ranged_skill_effectiveness(unit), 0, 500000, 90, 62, 44, 27) + return get_rating(ranged_skill_effectiveness(unit), 0, 800000, 72, 52, 31, 11) end local function make_sort_by_ranged_skill_effectiveness_desc(list) @@ -345,41 +345,41 @@ end -- Statistical rating that is higher for dwarves that are mentally stable local function get_mental_stability(unit) - local ALTRUISM = unit.status.current_soul.personality.traits.ALTRUISM - local ANXIETY_PROPENSITY = unit.status.current_soul.personality.traits.ANXIETY_PROPENSITY - local BRAVERY = unit.status.current_soul.personality.traits.BRAVERY - local CHEER_PROPENSITY = unit.status.current_soul.personality.traits.CHEER_PROPENSITY - local CURIOUS = unit.status.current_soul.personality.traits.CURIOUS - local DISCORD = unit.status.current_soul.personality.traits.DISCORD - local DUTIFULNESS = unit.status.current_soul.personality.traits.DUTIFULNESS - local EMOTIONALLY_OBSESSIVE = unit.status.current_soul.personality.traits.EMOTIONALLY_OBSESSIVE - local HUMOR = unit.status.current_soul.personality.traits.HUMOR - local LOVE_PROPENSITY = unit.status.current_soul.personality.traits.LOVE_PROPENSITY - local PERSEVERENCE = unit.status.current_soul.personality.traits.PERSEVERENCE - local POLITENESS = unit.status.current_soul.personality.traits.POLITENESS - local PRIVACY = unit.status.current_soul.personality.traits.PRIVACY - local STRESS_VULNERABILITY = unit.status.current_soul.personality.traits.STRESS_VULNERABILITY - local TOLERANT = unit.status.current_soul.personality.traits.TOLERANT - - local CRAFTSMANSHIP = setbelief.getUnitBelief(unit, df.value_type['CRAFTSMANSHIP']) - local FAMILY = setbelief.getUnitBelief(unit, df.value_type['FAMILY']) - local HARMONY = setbelief.getUnitBelief(unit, df.value_type['HARMONY']) - local INDEPENDENCE = setbelief.getUnitBelief(unit, df.value_type['INDEPENDENCE']) - local KNOWLEDGE = setbelief.getUnitBelief(unit, df.value_type['KNOWLEDGE']) - local LEISURE_TIME = setbelief.getUnitBelief(unit, df.value_type['LEISURE_TIME']) - local NATURE = setbelief.getUnitBelief(unit, df.value_type['NATURE']) - local SKILL = setbelief.getUnitBelief(unit, df.value_type['SKILL']) - - -- Calculate the rating using the defined variables - local rating = (CRAFTSMANSHIP * -0.01) + (FAMILY * -0.09) + (HARMONY * 0.05) - + (INDEPENDENCE * 0.06) + (KNOWLEDGE * -0.30) + (LEISURE_TIME * 0.24) - + (NATURE * 0.27) + (SKILL * -0.21) + (ALTRUISM * 0.13) - + (ANXIETY_PROPENSITY * -0.06) + (BRAVERY * 0.06) - + (CHEER_PROPENSITY * 0.41) + (CURIOUS * -0.06) + (DISCORD * 0.14) - + (DUTIFULNESS * -0.03) + (EMOTIONALLY_OBSESSIVE * -0.13) - + (HUMOR * -0.05) + (LOVE_PROPENSITY * 0.15) + (PERSEVERENCE * -0.07) - + (POLITENESS * -0.14) + (PRIVACY * 0.03) + (STRESS_VULNERABILITY * -0.20) - + (TOLERANT * -0.11) + local altruism = unit.status.current_soul.personality.traits.ALTRUISM + local anxiety_propensity = unit.status.current_soul.personality.traits.ANXIETY_PROPENSITY + local bravery = unit.status.current_soul.personality.traits.BRAVERY + local cheer_propensity = unit.status.current_soul.personality.traits.CHEER_PROPENSITY + local curious = unit.status.current_soul.personality.traits.CURIOUS + local discord = unit.status.current_soul.personality.traits.DISCORD + local dutifulness = unit.status.current_soul.personality.traits.DUTIFULNESS + local emotionally_obsessive = unit.status.current_soul.personality.traits.EMOTIONALLY_OBSESSIVE + local humor = unit.status.current_soul.personality.traits.HUMOR + local love_propensity = unit.status.current_soul.personality.traits.LOVE_PROPENSITY + local perseverence = unit.status.current_soul.personality.traits.PERSEVERENCE + local politeness = unit.status.current_soul.personality.traits.POLITENESS + local privacy = unit.status.current_soul.personality.traits.PRIVACY + local stress_vulnerability = unit.status.current_soul.personality.traits.STRESS_VULNERABILITY + local tolerant = unit.status.current_soul.personality.traits.TOLERANT + + local craftsmanship = setbelief.getUnitBelief(unit, df.value_type['CRAFTSMANSHIP']) + local family = setbelief.getUnitBelief(unit, df.value_type['FAMILY']) + local harmony = setbelief.getUnitBelief(unit, df.value_type['HARMONY']) + local independence = setbelief.getUnitBelief(unit, df.value_type['INDEPENDENCE']) + local knowledge = setbelief.getUnitBelief(unit, df.value_type['KNOWLEDGE']) + local leisure_time = setbelief.getUnitBelief(unit, df.value_type['LEISURE_TIME']) + local nature = setbelief.getUnitBelief(unit, df.value_type['NATURE']) + local skill = setbelief.getUnitBelief(unit, df.value_type['SKILL']) + + -- calculate the rating using the defined variables + local rating = (craftsmanship * -0.01) + (family * -0.09) + (harmony * 0.05) + + (independence * 0.06) + (knowledge * -0.30) + (leisure_time * 0.24) + + (nature * 0.27) + (skill * -0.21) + (altruism * 0.13) + + (anxiety_propensity * -0.06) + (bravery * 0.06) + + (cheer_propensity * 0.41) + (curious * -0.06) + (discord * 0.14) + + (dutifulness * -0.03) + (emotionally_obsessive * -0.13) + + (humor * -0.05) + (love_propensity * 0.15) + (perseverence * -0.07) + + (politeness * -0.14) + (privacy * 0.03) + (stress_vulnerability * -0.20) + + (tolerant * -0.11) return rating end diff --git a/plugins/orders.cpp b/plugins/orders.cpp index e3c57d0f1..ceaf84196 100644 --- a/plugins/orders.cpp +++ b/plugins/orders.cpp @@ -64,6 +64,9 @@ static command_result orders_export_command(color_ostream & out, const std::stri static command_result orders_import_command(color_ostream & out, const std::string & name); static command_result orders_clear_command(color_ostream & out); static command_result orders_sort_command(color_ostream & out); +static command_result orders_sort_type_command(color_ostream & out); +static command_result orders_sort_material_command(color_ostream & out); +static command_result orders_reset_command(color_ostream & out); static command_result orders_command(color_ostream & out, std::vector & parameters) { @@ -111,6 +114,21 @@ static command_result orders_command(color_ostream & out, std::vectorreaction_name.empty(); + bool b_has_reaction_name = !b->reaction_name.empty(); + + if (a_has_reaction_name != b_has_reaction_name) + { + return a_has_reaction_name; + } + else if (a_has_reaction_name && b_has_reaction_name) + { + if (a->reaction_name != b->reaction_name) + { + return a->reaction_name < b->reaction_name; + } + } + + // Compare job_type + return enum_item_key(a->job_type) < enum_item_key(b->job_type); +} + +static command_result orders_sort_type_command(color_ostream & out) +{ + CoreSuspender suspend; + if (!std::is_sorted(world->manager_orders.begin(), + world->manager_orders.end(), + compare_type)) + { + std::stable_sort(world->manager_orders.begin(), + world->manager_orders.end(), + compare_type); + out << "Manager orders are sorted by job type." << std::endl; + } + + return CR_OK; +} + +static bool compare_material(df::manager_order *a, df::manager_order *b) +{ + // Goal: Sort orders to easily find them in the list and to see dupclicated orders. + // Sorting by materials + + // Determine if only one of the orders has mat_type + bool a_has_material = (a->mat_type != -1 || a->mat_index != -1); + bool b_has_material = (b->mat_type != -1 || b->mat_index != -1); + + if (a_has_material != b_has_material) + { + return a_has_material; + } + else if (a_has_material && b_has_material) + { + // Compare mat_type using MaterialInfo + if (MaterialInfo(a).getToken() != MaterialInfo(b).getToken()) + { + return MaterialInfo(a).getToken() < MaterialInfo(b).getToken(); + } + } + + // Determine if only one order has material_category + bool a_has_material_category = (a->material_category.whole != 0); + bool b_has_material_category = (b->material_category.whole != 0); + + if (a_has_material_category != b_has_material_category) + { + return a_has_material_category; + } + else if (a_has_material_category && b_has_material_category) + { + std::vector a_mats, b_mats; + bitfield_to_string(&a_mats, a->material_category); + bitfield_to_string(&b_mats, b->material_category); + + // Checking that mats are not empty just in case + if (!a_mats.empty() && !b_mats.empty() && a_mats[0] != b_mats[0]) + { + return a_mats[0] < b_mats[0]; + } + } + + // By default orders are equal + return false; +} +static command_result orders_sort_material_command(color_ostream & out) +{ + CoreSuspender suspend; + if (!std::is_sorted(world->manager_orders.begin(), + world->manager_orders.end(), + compare_material)) + { + std::stable_sort(world->manager_orders.begin(), + world->manager_orders.end(), + compare_material); + out << "Manager orders are sorted by material." << std::endl; + } + + return CR_OK; +} + +static command_result orders_reset_command(color_ostream & out) +{ + for (auto it : world->manager_orders) + { + it->status.bits.active = false; + it->status.bits.validated = false; + } + return CR_OK; +} \ No newline at end of file