From d04d6ae9ebb524a67cc6fb1dda1f276f2a0aba75 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Mon, 25 May 2020 15:06:31 +0200 Subject: [PATCH] WIP --- code/__DEFINES/skills/defines.dm | 8 ++- code/__HELPERS/cmp.dm | 5 ++ code/datums/mind.dm | 2 +- code/datums/skills/_check_skills.dm | 70 +++++++++++++++++++++++++-- code/datums/skills/_skill.dm | 3 ++ code/datums/skills/_skill_holder.dm | 10 ++++ code/datums/skills/_skill_modifier.dm | 7 +++ code/datums/skills/engineering.dm | 1 + code/datums/skills/medical.dm | 1 + code/modules/client/asset_cache.dm | 4 ++ 10 files changed, 106 insertions(+), 5 deletions(-) diff --git a/code/__DEFINES/skills/defines.dm b/code/__DEFINES/skills/defines.dm index 659c0fe11b..60d2321927 100644 --- a/code/__DEFINES/skills/defines.dm +++ b/code/__DEFINES/skills/defines.dm @@ -100,4 +100,10 @@ ///Ascending priority defines. #define MODIFIER_SKILL_PRIORITY_LOW 100 #define MODIFIER_SKILL_PRIORITY_DEF 50 -#define MODIFIER_SKILL_PRIORITY_MAX 1 //max priority, meant for job/antag modifiers so they don't null out other (de)buffs \ No newline at end of file +#define MODIFIER_SKILL_PRIORITY_MAX 1 //max priority, meant for job/antag modifiers so they don't null out other (de)buffs + +// UI Defines +///Categories of skills, these will be displayed alphabetically. +#define SKILL_UI_CAT_ENG "Engineering" +#define SKILL_UI_CAT_MED "Medical" +#define SKILL_UI_CAT_MISC "Misc" diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 9b877e8fb0..963ed2a326 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -120,3 +120,8 @@ GLOBAL_VAR_INIT(cmp_field, "name") /proc/cmp_item_block_priority_asc(obj/item/A, obj/item/B) return A.block_priority - B.block_priority + +/proc/cmp_skill_categories(datum/skill/A, datum/skill/B) + if(A.ui_category == B.ui_category) + return sorttext(A.name, B.name) + return sorttext(A.ui_category, B.ui_category) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index b7eac62e83..a9438fa80b 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -67,7 +67,7 @@ var/datum/skill_holder/skill_holder /datum/mind/New(var/key) - skill_holder = new() + skill_holder = new(src) src.key = key soulOwner = src martial_art = default_martial_art diff --git a/code/datums/skills/_check_skills.dm b/code/datums/skills/_check_skills.dm index a94c7c95ba..d2921c8756 100644 --- a/code/datums/skills/_check_skills.dm +++ b/code/datums/skills/_check_skills.dm @@ -11,6 +11,70 @@ if(!mind.skill_holder) to_chat(usr, "How do you check the skills of [(usr == src)? "yourself when you are" : "something"] without the capability for skills? (PROBABLY A BUG, PRESS F1.)") return - var/datum/browser/B = new(usr, "skilldisplay_[REF(src)]", "Skills of [src]") - B.set_content(mind.skill_html_readout()) - B.open() + + mind.skill_holder.ui_interact(src) + +/datum/skill_holder/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state) + if(need_static_data_update) + update_static_data(user) + need_static_data_update = FALSE + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "check_skills", "[owner.name]'s Skills", 900, 480, master_ui, state) + ui.open() + +/datum/skill_holder/ui_static_data(mob/user) + . = list() + var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/skills) + + .["skills"] = list() + var/list/current + var/category + for(var/path in GLOB.skill_datums) + var/datum/skill/S = GLOB.skill_datums[path] + if(!current || S.ui_category != category) + if(category) + .["skills"][category] = current + current = list() + category = S.ui_category + + var/skill_value = owner.get_skill_value(path, FALSE) + var/skill_level = owner.get_skill_level(path, FALSE) + var/list/mod_ids = list() + + var/value_mods = LAZYACCESS(skill_value_mods, path) + var/mod_value = skill_value + for(var/k in value_mods) + var/datum/skill_modifier/M = GLOB.skill_modifiers[k] + mod_ids |= M.identifier + mod_value = M.apply_modifier(mod_value, path, src, MODIFIER_TARGET_VALUE) + + var/lvl_mods = LAZYACCESS(skill_level_mods, path) + var/mod_level = skill_level + for(var/k in lvl_mods) + var/datum/skill_modifier/M = GLOB.skill_modifiers[k] + mod_ids |= M.identifier + mod_level = M.apply_modifier(mod_level, path, src, MODIFIER_TARGET_LEVEL) + mod_level = SANITIZE_SKILL_LEVEL(S.type, round(mod_level, 1)) + + var/list/data = list( + name = S.name, + color = S.name_color, + skill_base = S.standard_render_value(skill_value, skill_level), + skill_mod = S.standard_render_value(mod_value, mod_level), + mod_ids = mod_ids + ) + current += list(data) + + if(category) + .["skills"][category] = current + + var/all_mods = list() + for(var/id in all_current_skill_modifiers) + var/datum/skill_modifier/M = GLOB.skill_modifiers[id] + all_mods[id] = list( + name = M.name, + desc = M.desc, + icon = assets.icon_class_name(M.icon) + ) + .["modifiers"] = all_mods diff --git a/code/datums/skills/_skill.dm b/code/datums/skills/_skill.dm index 571a8274d8..9490c7c7d9 100644 --- a/code/datums/skills/_skill.dm +++ b/code/datums/skills/_skill.dm @@ -8,6 +8,7 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums()) continue S = new path .[S.type] = S + . = sortTim(., /proc/cmp_skill_categories, TRUE) /** * Skill datums @@ -34,6 +35,8 @@ GLOBAL_LIST_INIT_TYPED(skill_datums, /datum/skill, init_skill_datums()) var/competency_multiplier = 1 /// A list of ways this skill can affect or be affected through actions and skill modifiers. var/list/skill_traits = list(SKILL_SANITY, SKILL_INTELLIGENCE) + /// Index of this skill in the UI + var/ui_category = SKILL_UI_CAT_MISC /** * Ensures what someone's setting as a value for this skill is valid. diff --git a/code/datums/skills/_skill_holder.dm b/code/datums/skills/_skill_holder.dm index 071db3306a..2b3c963c33 100644 --- a/code/datums/skills/_skill_holder.dm +++ b/code/datums/skills/_skill_holder.dm @@ -20,6 +20,15 @@ var/list/original_values var/list/original_affinities var/list/original_levels + /// The mind datum this skill is associated with, only used for the check_skills UI + var/datum/mind/owner + /// For static UI update. + var/need_static_data_update = TRUE + + +/datum/skill_holder/New(owner) + ..() + src.owner = owner /** * Grabs the value of a skill. @@ -79,6 +88,7 @@ CRASH("Invalid set_skill_value call. Use skill typepaths.") //until a time when we somehow need text ids for dynamic skills, I'm enforcing this. var/datum/skill/S = GLOB.skill_datums[skill] value = S.sanitize_value(value) + skill_holder.need_static_data_update = TRUE if(!isnull(value)) LAZYINITLIST(skill_holder.skills) S.set_skill_value(skill_holder, value, src, silent) diff --git a/code/datums/skills/_skill_modifier.dm b/code/datums/skills/_skill_modifier.dm index a28cf3aebd..5a81521b49 100644 --- a/code/datums/skills/_skill_modifier.dm +++ b/code/datums/skills/_skill_modifier.dm @@ -7,6 +7,9 @@ GLOBAL_LIST_EMPTY(potential_mods_per_skill) * and cause lots of edge cases. These are fairly simple overall... make a subtype though, don't use this one. */ /datum/skill_modifier + /// Name and description of the skill modifier, used in the UI + var/name = "???" + var/desc = "" /// flags for this skill modifier. var/modifier_flags = NONE /// target skills, can be a specific skill typepath or a list of skill traits. @@ -23,6 +26,8 @@ GLOBAL_LIST_EMPTY(potential_mods_per_skill) var/level_mod = 1 /// Priority of this skill modifier compared to other ones. var/priority = MODIFIER_SKILL_PRIORITY_DEF + /// Skill modifier icon, used in the UI + var/icon = "default" /datum/skill_modifier/New(id, register = FALSE) identifier = GET_SKILL_MOD_ID(type, id) @@ -110,6 +115,7 @@ GLOBAL_LIST_EMPTY(potential_mods_per_skill) if(M.modifier_flags & MODIFIER_SKILL_LEVEL) ADD_MOD_STEP(skill_holder.skill_level_mods, path, skill_holder.original_levels, get_skill_level(path, FALSE)) LAZYSET(skill_holder.all_current_skill_modifiers, id, TRUE) + skill_holder.need_static_data_update = TRUE if(M.modifier_flags & MODIFIER_SKILL_BODYBOUND) M.RegisterSignal(src, COMSIG_MIND_TRANSFER, /datum/skill_modifier.proc/on_mind_transfer) @@ -141,6 +147,7 @@ GLOBAL_LIST_EMPTY(potential_mods_per_skill) if(M.modifier_flags & MODIFIER_SKILL_LEVEL && skill_holder.skill_level_mods) REMOVE_MOD_STEP(skill_holder.skill_level_mods, path, skill_holder.original_levels) LAZYREMOVE(skill_holder.all_current_skill_modifiers, id) + skill_holder.need_static_data_update = TRUE if(!mind_transfer && M.modifier_flags & MODIFIER_SKILL_BODYBOUND) M.UnregisterSignal(src, COMSIG_MIND_TRANSFER) diff --git a/code/datums/skills/engineering.dm b/code/datums/skills/engineering.dm index db7b33450c..60e3fcc6a1 100644 --- a/code/datums/skills/engineering.dm +++ b/code/datums/skills/engineering.dm @@ -3,3 +3,4 @@ desc = "How proficient and knowledged you are at wiring beyond laying cables on the floor." name_color = COLOR_PALE_ORANGE skill_traits = list(SKILL_SANITY, SKILL_INTELLIGENCE, SKILL_USE_TOOL, SKILL_TRAINING_TOOL) + ui_category = SKILL_UI_CAT_ENG diff --git a/code/datums/skills/medical.dm b/code/datums/skills/medical.dm index 404c141157..3818a77db5 100644 --- a/code/datums/skills/medical.dm +++ b/code/datums/skills/medical.dm @@ -3,3 +3,4 @@ desc = "How proficient you are at doing surgery." name_color = COLOR_PALE_BLUE_GRAY competency_multiplier = 1.5 // 60% surgery speed up at max value of 100, considering the base multiplier. + ui_category = SKILL_UI_CAT_MED diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 6f62701590..73c857f78d 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -744,3 +744,7 @@ GLOBAL_LIST_EMPTY(asset_datums) "dna_undiscovered.gif" = 'html/dna_undiscovered.gif', "dna_extra.gif" = 'html/dna_extra.gif' ) + +/datum/asset/spritesheet/simple/skills + name = "skills" +