From efdd5e643d8cd43ad6f5a66981b5803ffb5a3e86 Mon Sep 17 00:00:00 2001 From: CHOMPStation2StaffMirrorBot <94713762+CHOMPStation2StaffMirrorBot@users.noreply.github.com> Date: Sun, 26 Jan 2025 08:20:35 -0700 Subject: [PATCH] [MIRROR] allows direct robot sprite testing (#9938) Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com> --- code/controllers/subsystems/robot_sprites.dm | 184 +++++++++++++++++++ code/modules/admin/admin_verb_lists.dm | 3 + code/modules/admin/admin_verb_lists_vr.dm | 3 + code/modules/admin/verbs/debug.dm | 8 + icons/mob/robot/testdir/usage.txt | 21 +++ 5 files changed, 219 insertions(+) create mode 100644 icons/mob/robot/testdir/usage.txt diff --git a/code/controllers/subsystems/robot_sprites.dm b/code/controllers/subsystems/robot_sprites.dm index d6d38ab50f..f8c16b7caa 100644 --- a/code/controllers/subsystems/robot_sprites.dm +++ b/code/controllers/subsystems/robot_sprites.dm @@ -5,9 +5,11 @@ SUBSYSTEM_DEF(robot_sprites) var/list/all_cyborg_sprites = list() var/list/cyborg_sprites_by_module = list() var/list/whitelisted_sprites_by_module = list() + var/list/all_test_sprites = list() /datum/controller/subsystem/robot_sprites/Initialize() initialize_borg_sprites() + load_test_sprites() return SS_INIT_SUCCESS /datum/controller/subsystem/robot_sprites/proc/initialize_borg_sprites() @@ -111,3 +113,185 @@ SUBSYSTEM_DEF(robot_sprites) . |= RS return + +// This is mostly for sprite testing, don't use it in active productions! +/datum/controller/subsystem/robot_sprites/proc/load_test_sprites() + var/list/test_sprites = list() + // file name must be robot_xxy.dmi -> testborg_64x32 + var/path = "icons/mob/robot/testdir/" + for(var/f in flist(path)) + if(!findtext(f, regex(".dmi"))) + continue + test_sprites += list("[f]" = file("[path][f]")) + for(var/sprite in test_sprites) + var/datum/robot_sprite/RS = new() + all_test_sprites += RS + RS.sprite_flags = 0 + RS.rest_sprite_options = list() + RS.sprite_icon = test_sprites[sprite] + var/splitted = splittext(sprite, "_") + RS.name = splitted[1] + RS.sprite_icon_state = splitted[1] + splitted = splittext(splitted[2], "x") + RS.pixel_x = (32 - text2num(splitted[1])) / 2 + RS.icon_x = text2num(splitted[1]) + RS.icon_y = text2num(splitted[2]) + RS.vis_height = text2num(splitted[2]) + var/list/icon_states = icon_states(RS.sprite_icon) + for(var/icon in icon_states) + // testing whitelist functionality ckey-... + if(findtext(icon, regex("ckey-"))) + var/list/owner = splittext(icon, "-") + RS.whitelist_ckey = owner[3] + RS.is_whitelisted = TRUE + continue + // testing module types slots modules-... + if(findtext(icon, regex("modules-"))) + var/list/jobs = splittext(icon, "-") + jobs -= "modules" + RS.module_type = jobs + continue + // Check for all the possible overlays + if(findtext(icon, regex("-roll"))) + RS.sprite_flags |= ROBOT_HAS_SPEED_SPRITE + continue + if(findtext(icon, regex("-shield"))) + RS.sprite_flags |= ROBOT_HAS_SHIELD_SPRITE + continue + if(findtext(icon, regex("-speed_shield"))) + RS.sprite_flags |= ROBOT_HAS_SHIELD_SPEED_SPRITE + continue + if(findtext(icon, regex("-melee",))) + RS.sprite_flags |= ROBOT_HAS_MELEE_SPRITE + continue + if(findtext(icon, regex("-dagger"))) + RS.sprite_flags |= ROBOT_HAS_DAGGER_SPRITE + continue + if(findtext(icon, regex("-blade"))) + RS.sprite_flags |= ROBOT_HAS_BLADE_SPRITE + continue + if(findtext(icon, regex("-gun"))) + RS.sprite_flags |= ROBOT_HAS_GUN_SPRITE + continue + if(findtext(icon, regex("-laser"))) + RS.sprite_flags |= ROBOT_HAS_LASER_SPRITE + continue + if(findtext(icon, regex("-taser"))) + RS.sprite_flags |= ROBOT_HAS_TASER_SPRITE + continue + if(findtext(icon, regex("-disabler"))) + RS.sprite_flags |= ROBOT_HAS_DISABLER_SPRITE + continue + if(findtext(icon, regex("-eyes"))) + RS.has_eye_sprites = TRUE + continue + if(findtext(icon, regex("-lights"))) + RS.has_eye_light_sprites = TRUE + continue + if(findtext(icon, regex("-decals"))) + RS.has_robotdecal_sprites = TRUE + continue + if(findtext(icon, regex("-openpanel_w"))) + RS.has_custom_open_sprites = TRUE + continue + if(findtext(icon, regex("-\\d-rest"))) + RS.has_vore_belly_resting_sprites = TRUE + continue + if(findtext(icon, regex("-\\d-sit"))) + RS.has_vore_belly_resting_sprites = TRUE + continue + if(findtext(icon, regex("-\\d-bellyup"))) + RS.has_vore_belly_resting_sprites = TRUE + continue + if(findtext(icon, regex("-\\d-\[a-z\]$"))) + var/list/belly = splittext(icon, "-") + var/capacity = text2num(belly[3]) + if(!RS.belly_light_list) + RS.belly_light_list = list() + if(isnum(capacity)) + if(!RS.belly_light_list[belly[2]]) + RS.belly_light_list[belly[2]] = capacity + else if(RS.belly_light_list[belly[2]] < capacity) + RS.belly_light_list[belly[2]] = capacity + continue + if(findtext(icon, regex("-\\d$"))) + var/list/belly = splittext(icon, "-") + var/capacity = text2num(belly[3]) + if(!RS.belly_capacity_list) + RS.belly_capacity_list = list() + if(isnum(capacity)) + if(!RS.belly_capacity_list[belly[2]]) + RS.belly_capacity_list[belly[2]] = capacity + else if(RS.belly_capacity_list[belly[2]] < capacity) + RS.belly_capacity_list[belly[2]] = capacity + continue + if(findtext(icon, regex("-sit"))) + RS.has_rest_sprites = TRUE + RS.rest_sprite_options |= list("Sit") + continue + if(findtext(icon, regex("-rest"))) + RS.has_rest_sprites = TRUE + RS.rest_sprite_options |= list("Default") + continue + if(findtext(icon, regex("-bellyup"))) + RS.has_rest_sprites = TRUE + RS.rest_sprite_options |= list("Bellyup") + continue + if(findtext(icon, regex("-wreck"))) + RS.has_dead_sprite = TRUE + continue + if(findtext(icon, regex("wreck-overlay"))) + RS.has_dead_sprite_overlay = TRUE + continue + // We want to test it, so just give it all if there were non defined in the dmi + if(!RS.module_type) + RS.module_type = list("Standard", "Engineering", "Surgeon", "Crisis", "Miner", "Janitor", "Service", "Clerical", "Security", "Research") + // Apply it to the possible modules, there will be no preview icon in the module selection as those datums are not ran through icon forge + if(islist(RS.module_type)) + for(var/M in RS.module_type) + if(RS.is_whitelisted) + if(!(M in whitelisted_sprites_by_module)) + whitelisted_sprites_by_module += M + whitelisted_sprites_by_module[M] = list() + whitelisted_sprites_by_module[M] |= RS + else + if(!(M in cyborg_sprites_by_module)) + cyborg_sprites_by_module += M + cyborg_sprites_by_module[M] = list() + cyborg_sprites_by_module[M] |= RS + else + if(RS.is_whitelisted) + if(!(RS.module_type in whitelisted_sprites_by_module)) + whitelisted_sprites_by_module += RS.module_type + whitelisted_sprites_by_module[RS.module_type] = list() + whitelisted_sprites_by_module[RS.module_type] |= RS + else + if(!(RS.module_type in cyborg_sprites_by_module)) + cyborg_sprites_by_module += RS.module_type + cyborg_sprites_by_module[RS.module_type] = list() + cyborg_sprites_by_module[RS.module_type] |= RS + +/datum/controller/subsystem/robot_sprites/proc/clear_test_sprites() + // Clears all our test sprites, allows spriters to reload the dmis after edits ingame + for(var/datum/robot_sprite/RS in all_test_sprites) + if(islist(RS.module_type)) + for(var/M in RS.module_type) + if(RS.is_whitelisted) + if(M in whitelisted_sprites_by_module) + whitelisted_sprites_by_module[M] -= RS + else + if(M in cyborg_sprites_by_module) + cyborg_sprites_by_module[M] -= RS + else + if(RS.is_whitelisted) + if(RS.module_type in whitelisted_sprites_by_module) + whitelisted_sprites_by_module[RS.module_type] -= RS + else + if(RS.module_type in cyborg_sprites_by_module) + cyborg_sprites_by_module[RS.module_type] -= RS + all_test_sprites -= RS + qdel(RS) + +/datum/controller/subsystem/robot_sprites/proc/reload_test_sprites() + clear_test_sprites() + load_test_sprites() diff --git a/code/modules/admin/admin_verb_lists.dm b/code/modules/admin/admin_verb_lists.dm index b082c5fecf..5978722d93 100644 --- a/code/modules/admin/admin_verb_lists.dm +++ b/code/modules/admin/admin_verb_lists.dm @@ -243,6 +243,7 @@ var/list/admin_verbs_debug = list( /datum/admins/proc/change_time, /client/proc/cmd_regenerate_asset_cache, /client/proc/cmd_clear_smart_asset_cache, + /client/proc/cmd_reload_robot_sprite_test, /client/proc/admin_give_modifier, /client/proc/simple_DPS, /datum/admins/proc/view_feedback, @@ -402,6 +403,7 @@ var/list/admin_verbs_event_manager = list( /datum/admins/proc/change_time, /client/proc/cmd_regenerate_asset_cache, /client/proc/cmd_clear_smart_asset_cache, + /client/proc/cmd_reload_robot_sprite_test, /client/proc/admin_give_modifier, /client/proc/Jump, /client/proc/jumptomob, @@ -431,6 +433,7 @@ var/list/admin_verbs_event_manager = list( /datum/admins/proc/change_time, /client/proc/cmd_regenerate_asset_cache, /client/proc/cmd_clear_smart_asset_cache, + /client/proc/cmd_reload_robot_sprite_test, /client/proc/admin_give_modifier, /datum/admins/proc/cmd_admin_dress, /client/proc/cmd_admin_gib_self, diff --git a/code/modules/admin/admin_verb_lists_vr.dm b/code/modules/admin/admin_verb_lists_vr.dm index 8097fb9302..42ea0ee3e2 100644 --- a/code/modules/admin/admin_verb_lists_vr.dm +++ b/code/modules/admin/admin_verb_lists_vr.dm @@ -288,6 +288,7 @@ var/list/admin_verbs_debug = list( /datum/admins/proc/change_time, /client/proc/cmd_regenerate_asset_cache, /client/proc/cmd_clear_smart_asset_cache, + /client/proc/cmd_reload_robot_sprite_test, /client/proc/admin_give_modifier, /client/proc/simple_DPS, /datum/admins/proc/view_feedback, @@ -467,6 +468,7 @@ var/list/admin_verbs_event_manager = list( /datum/admins/proc/change_time, /client/proc/cmd_regenerate_asset_cache, /client/proc/cmd_clear_smart_asset_cache, + /client/proc/cmd_reload_robot_sprite_test, /client/proc/admin_give_modifier, /client/proc/Jump, /client/proc/jumptomob, @@ -496,6 +498,7 @@ var/list/admin_verbs_event_manager = list( /datum/admins/proc/change_time, /client/proc/cmd_regenerate_asset_cache, /client/proc/cmd_clear_smart_asset_cache, + /client/proc/cmd_reload_robot_sprite_test, /client/proc/admin_give_modifier, /datum/admins/proc/cmd_admin_dress, /client/proc/cmd_admin_gib_self, diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 50c3368118..775a66af99 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -729,3 +729,11 @@ fdel("[ASSET_CROSS_ROUND_SMART_CACHE_DIRECTORY]/spritesheet_cache.[initial(A.name)].json") cleared++ to_chat(usr, span_notice("Cleared [cleared] asset\s.")) + +// For spriters with long world loads, allows to reload test robot sprites +/client/proc/cmd_reload_robot_sprite_test() + set category = "Debug.Sprites" + set name = "Reload Robot Test Sprites" + set desc = "Reloads the dmis from the test folder and creates the test datums." + + SSrobot_sprites.reload_test_sprites() diff --git a/icons/mob/robot/testdir/usage.txt b/icons/mob/robot/testdir/usage.txt new file mode 100644 index 0000000000..2c0049c03f --- /dev/null +++ b/icons/mob/robot/testdir/usage.txt @@ -0,0 +1,21 @@ +This directory is for testing robot dmis direclty without the need to define the sprite datums. + +For this, name the dmi in the following format: [sprite-name]_[x_size]x[y_size].dmi + +Don't use underlines within the name! + +An exaple would be: mydrake_64x64.dmi + +The states inside the dmi then need to match the name, so all icons need to follow the common format: + +mydrake +mydrake-[overlay] +etc. + +There are 2 special cases, for whitelist testing, you can just add an empty state called +ckey-[whatever], the sprite will then no longer show, if you enter your own key, you should see it +modules-[type]..., for example modules-Standard-Engineering-Surgeon-Crisis-Miner-Janitor-Service-Clerical-Security-Research, this is the default, so there is no need to name a state including all jobs. But if only a few are wanted, that is a quick way to do so + +Many examples for how the states should be named can be found in other robot dmis + +In game, the "Reload Robot Test Sprites" can be used to reload the dmis for testing without the need to recompile the game.