diff --git a/code/_compile_options.dm b/code/_compile_options.dm index ed6205e25d8..9350ce35f37 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -203,3 +203,8 @@ #ifdef MAP_TEST #warn Compiling in MAP_TEST mode. Certain game mechanics will be disabled. #endif + +/// Disable to use builtin DM-based generation. +/// IconForge is 250x times faster but requires storing the icons in tmp/ and may result in higher asset transport. +/// Note that the builtin GAGS editor still uses the 'legacy' generation to allow for debugging. +#define USE_RUSTG_ICONFORGE_GAGS diff --git a/code/controllers/subsystem/greyscale_previews.dm b/code/controllers/subsystem/greyscale_previews.dm index d74f16ff7a3..9a63cb6b2de 100644 --- a/code/controllers/subsystem/greyscale_previews.dm +++ b/code/controllers/subsystem/greyscale_previews.dm @@ -1,8 +1,3 @@ -/// If we are in unit tests OR if we are not using iconforge, then we should make sure the icons we are using are valid. -#if !defined(USE_RUSTG_ICONFORGE_GAGS) || defined(UNIT_TESTS) - #define CHECK_SPRITESHEET_ICON_VALIDITY -#endif - SUBSYSTEM_DEF(greyscale_previews) name = "Greyscale Previews" flags = SS_NO_FIRE @@ -135,6 +130,11 @@ SUBSYSTEM_DEF(greyscale_previews) /datum/controller/subsystem/greyscale_previews/proc/ExportMapPreviewsForType(filename, list/entries) var/list/icons = list() + #ifdef USE_RUSTG_ICONFORGE_GAGS + // make sure the error icon exists as a default + var/datum/universal_icon/empty_icon = uni_icon('icons/testing/greyscale_error.dmi', "") + icons[""] = empty_icon.to_list() + #endif for (var/entry in entries) var/atom/typepath @@ -162,25 +162,46 @@ SUBSYSTEM_DEF(greyscale_previews) // This is what the actual icon state will be in the map_icon .dmi var/key = reskin_icon_state ? "[typepath]--[icon_state]" : "[typepath]" - #ifdef CHECK_SPRITESHEET_ICON_VALIDITY + #ifdef USE_RUSTG_ICONFORGE_GAGS + // No large icons, use icon_preview and icon_preview_state instead. + var/datum/universal_icon/map_icon = SSgreyscale.GetColoredIconByTypeUniversalIcon(greyscale_config, greyscale_colors, icon_state) + icons[key] = map_icon.to_list() + #else var/icon/map_icon = icon(SSgreyscale.GetColoredIconByType(greyscale_config, greyscale_colors)) // No large icons, use icon_preview and icon_preview_state instead. + #ifdef UNIT_TESTS // this is much slower using legacy generation, so limit it to unit tests. if (map_icon.Width() > 32 || map_icon.Height() > 32) stack_trace("GAGS configuration is trying to generate a map preview graphic for '[typepath]' (icon state: [icon_state]), which has a large icon. This is not suppoorted; implement icon_preview instead.") continue if (!(icon_state in map_icon.IconStates())) stack_trace("GAGS configuration missing icon state ([icon_state]) needed to generate map preview graphic for '[typepath]'. Make sure the right greyscale_config is set up.") continue + #endif map_icon = icon(map_icon, icon_state) icons[key] = map_icon - #else // will be updated to use iconforge's new .dmi spritesheet generation instead - var/icon/map_icon = icon(SSgreyscale.GetColoredIconByType(greyscale_config, greyscale_colors)) - map_icon = icon(map_icon, icon_state) - icons[map_icon_key] = map_icon #endif + #ifdef USE_RUSTG_ICONFORGE_GAGS + // generate all previews in parallel + var/holder = "tmp/greyscale_previews.dmi" + var/list/headless_result = rustg_iconforge_generate_headless(holder, json_encode(icons), FALSE) + if(!istype(headless_result)) + stack_trace("Could not generate greyscale previews using rustg_iconforge_generate_headless! The output format was invalid (JSON did not decode to a list). Got: [headless_result]") + if(!length(headless_result)) + stack_trace("Could not generate greyscale previews using rustg_iconforge_generate_headless! The output list was empty. Got: [json_encode(headless_result)]") + if(!isnull(headless_result["error"])) + stack_trace("Could not generate greyscale previews using rustg_iconforge_generate_headless! There was an error: [headless_result["error"]]") + if(headless_result["file_path"] != holder) + stack_trace("Could not generate greyscale previews using rustg_iconforge_generate_headless! The output file_path differed from the input. Got: [json_encode(headless_result)]") + // testing size is cheap with rustg, so no need to limit to unit tests. + if(headless_result["width"] != 32 || headless_result["height"] != 32) + stack_trace("Could not generate greyscale previews using rustg_iconforge_generate_headless! The output size was not 32x32. Got: [json_encode(headless_result)]") + if(!fexists(holder)) + stack_trace("Could not generate greyscale previews using rustg_iconforge_generate_headless! The output file does not exist on the filesystem! Got: [json_encode(headless_result)]") + #else var/icon/holder = icon('icons/testing/greyscale_error.dmi') for(var/state in icons) holder.Insert(icons[state], state) + #endif var/filepath = "icons/map_icons/[filename].dmi" #ifdef UNIT_TESTS @@ -192,7 +213,3 @@ SUBSYSTEM_DEF(greyscale_previews) if(old_md5 != new_md5) stack_trace("Generated map icons were different than what is currently saved. If you see this in a CI run it means you need to run the game once through initialization and commit the resulting files in 'icons/map_icons/'") #endif - -#ifdef CHECK_SPRITESHEET_ICON_VALIDITY - #undef CHECK_SPRITESHEET_ICON_VALIDITY -#endif diff --git a/code/controllers/subsystem/processing/greyscale.dm b/code/controllers/subsystem/processing/greyscale.dm index 2fe8444bd7c..03b19ac2eff 100644 --- a/code/controllers/subsystem/processing/greyscale.dm +++ b/code/controllers/subsystem/processing/greyscale.dm @@ -1,8 +1,3 @@ -/// Disable to use builtin DM-based generation. -/// IconForge is 250x times faster but requires storing the icons in tmp/ and may result in higher asset transport. -/// Note that the builtin GAGS editor still uses the 'legacy' generation to allow for debugging. -#define USE_RUSTG_ICONFORGE_GAGS - PROCESSING_SUBSYSTEM_DEF(greyscale) name = "Greyscale" flags = SS_BACKGROUND diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index ac45ba08242..eaca9403857 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -475,7 +475,7 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/get_admin_commands() . = list() -/// Creates an icon from the preview outfit. +/// Creates a /datum/universal_icon from the preview outfit. /// Custom implementors of `get_preview_icon` should use this, as the /// result of `get_preview_icon` is expected to be the completed version. /datum/antagonist/proc/render_preview_outfit(datum/outfit/outfit, mob/living/carbon/human/dummy) @@ -483,34 +483,35 @@ GLOBAL_LIST_EMPTY(antagonists) dummy.equipOutfit(outfit, visuals_only = TRUE) dummy.wear_suit?.update_greyscale() dummy.set_combat_mode(TRUE) - var/icon = getFlatIcon(dummy) + var/datum/universal_icon/antag_icon = get_flat_uni_icon(dummy) // We don't want to qdel the dummy right away, since its items haven't initialized yet. SSatoms.prepare_deletion(dummy) - return icon + return antag_icon -/// Given an icon, will crop it to be consistent of those in the preferences menu. +/// Given a /datum/universal_icon, will crop it to be consistent of those in the preferences menu. /// Not necessary, and in fact will look bad if it's anything other than a human. -/datum/antagonist/proc/finish_preview_icon(icon/icon) +/datum/antagonist/proc/finish_preview_icon(datum/universal_icon/antag_icon) // Zoom in on the top of the head and the chest // I have no idea how to do this dynamically. - icon.Scale(115, 115) + antag_icon.scale(115, 115) // This is probably better as a Crop, but I cannot figure it out. - icon.Shift(WEST, 8) - icon.Shift(SOUTH, 30) + antag_icon.shift(WEST, 8) + antag_icon.shift(SOUTH, 30) - icon.Crop(1, 1, ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) + antag_icon.crop(1, 1, ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) - return icon + return antag_icon -/// Returns the icon to show on the preferences menu. +/// Returns the /datum/universal_icon to shown on the preferences menu. /datum/antagonist/proc/get_preview_icon() if (isnull(preview_outfit)) return null - return finish_preview_icon(render_preview_outfit(preview_outfit)) + var/datum/universal_icon/preview_icon = render_preview_outfit(preview_outfit) + return finish_preview_icon(preview_icon) /datum/antagonist/proc/edit_memory(mob/user) var/new_memo = tgui_input_text(user, "Write a new memory", "Antag Memory", antag_memory, multiline = TRUE) diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm index a1cf2f26502..380eea90b96 100644 --- a/code/modules/antagonists/abductor/abductor.dm +++ b/code/modules/antagonists/abductor/abductor.dm @@ -23,14 +23,14 @@ scientist.set_species(/datum/species/abductor) agent.set_species(/datum/species/abductor) - var/icon/scientist_icon = render_preview_outfit(/datum/outfit/abductor/scientist, scientist) - scientist_icon.Shift(WEST, 8) + var/datum/universal_icon/scientist_icon = render_preview_outfit(/datum/outfit/abductor/scientist, scientist) + scientist_icon.shift(WEST, 8) - var/icon/agent_icon = render_preview_outfit(/datum/outfit/abductor/agent, agent) - agent_icon.Shift(EAST, 8) + var/datum/universal_icon/agent_icon = render_preview_outfit(/datum/outfit/abductor/agent, agent) + agent_icon.shift(EAST, 8) - var/icon/final_icon = scientist_icon - final_icon.Blend(agent_icon, ICON_OVERLAY) + var/datum/universal_icon/final_icon = scientist_icon + final_icon.blend_icon(agent_icon, ICON_OVERLAY) qdel(scientist) qdel(agent) diff --git a/code/modules/antagonists/blob/blob_antag.dm b/code/modules/antagonists/blob/blob_antag.dm index a2e07edaa2e..51d9acdc891 100644 --- a/code/modules/antagonists/blob/blob_antag.dm +++ b/code/modules/antagonists/blob/blob_antag.dm @@ -44,10 +44,10 @@ /datum/antagonist/blob/get_preview_icon() var/datum/blobstrain/reagent/reactive_spines/reactive_spines = /datum/blobstrain/reagent/reactive_spines - var/icon/icon = icon('icons/mob/nonhuman-player/blob.dmi', "blob_core") - icon.Blend(initial(reactive_spines.color), ICON_MULTIPLY) - icon.Blend(icon('icons/mob/nonhuman-player/blob.dmi', "blob_core_overlay"), ICON_OVERLAY) - icon.Scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) + var/datum/universal_icon/icon = uni_icon('icons/mob/nonhuman-player/blob.dmi', "blob_core") + icon.blend_color(initial(reactive_spines.color), ICON_MULTIPLY) + icon.blend_icon(uni_icon('icons/mob/nonhuman-player/blob.dmi', "blob_core_overlay"), ICON_OVERLAY) + icon.scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) return icon @@ -159,17 +159,17 @@ pref_flag = ROLE_BLOB_INFECTION /datum/antagonist/blob/infection/get_preview_icon() - var/icon/blob_icon = ..() + var/datum/universal_icon/blob_icon = ..() var/datum/blobstrain/reagent/reactive_spines/reactive_spines = /datum/blobstrain/reagent/reactive_spines - var/icon/blob_head = icon('icons/mob/nonhuman-player/blob.dmi', "blob_head") - blob_head.Blend(initial(reactive_spines.complementary_color), ICON_MULTIPLY) + var/datum/universal_icon/blob_head = uni_icon('icons/mob/nonhuman-player/blob.dmi', "blob_head") + blob_head.blend_color(initial(reactive_spines.complementary_color), ICON_MULTIPLY) - var/icon/human_icon = render_preview_outfit(/datum/outfit/job/miner) - human_icon.Blend(blob_head, ICON_OVERLAY) - human_icon.ChangeOpacity(0.7) + var/datum/universal_icon/human_icon = render_preview_outfit(/datum/outfit/job/miner) + human_icon.blend_icon(blob_head, ICON_OVERLAY) + human_icon.change_opacity(0.7) - blob_icon.Blend(finish_preview_icon(human_icon), ICON_OVERLAY) + blob_icon.blend_icon(finish_preview_icon(human_icon), ICON_OVERLAY) return blob_icon diff --git a/code/modules/antagonists/blood_worm/blood_worm_antag.dm b/code/modules/antagonists/blood_worm/blood_worm_antag.dm index 16b4a56fdd7..8804d60c7b4 100644 --- a/code/modules/antagonists/blood_worm/blood_worm_antag.dm +++ b/code/modules/antagonists/blood_worm/blood_worm_antag.dm @@ -81,11 +81,11 @@ return ..() /datum/antagonist/blood_worm/get_preview_icon() - var/icon/icon = icon('icons/mob/nonhuman-player/blood_worm_32x32.dmi', "juvenile") + var/datum/universal_icon/icon = uni_icon('icons/mob/nonhuman-player/blood_worm_32x32.dmi', "juvenile") - icon.Crop(1, 1, 32, 32) - icon.Shift(SOUTH, 4) - icon.Scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) + icon.crop(1, 1, 32, 32) + icon.shift(SOUTH, 4) + icon.scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) return icon diff --git a/code/modules/antagonists/brother/brother.dm b/code/modules/antagonists/brother/brother.dm index 6cf17e5efab..4120c8de238 100644 --- a/code/modules/antagonists/brother/brother.dm +++ b/code/modules/antagonists/brother/brother.dm @@ -141,20 +141,20 @@ brother2.dna.features[FEATURE_MOTH_WINGS] = "Plain" brother2.set_species(/datum/species/moth) - var/icon/brother1_icon = render_preview_outfit(/datum/outfit/job/quartermaster, brother1) - var/icon/brother1_blood_icon = icon('icons/effects/blood.dmi', "maskblood") - brother1_blood_icon.Blend(BLOOD_COLOR_RED, ICON_MULTIPLY) - brother1_icon.Blend(brother1_blood_icon, ICON_OVERLAY) - brother1_icon.Shift(WEST, 8) + var/datum/universal_icon/brother1_icon = render_preview_outfit(/datum/outfit/job/quartermaster, brother1) + var/datum/universal_icon/brother1_blood_icon = uni_icon('icons/effects/blood.dmi', "maskblood") + brother1_blood_icon.blend_color(BLOOD_COLOR_RED, ICON_MULTIPLY) + brother1_icon.blend_icon(brother1_blood_icon, ICON_OVERLAY) + brother1_icon.shift(WEST, 8) - var/icon/brother2_icon = render_preview_outfit(/datum/outfit/job/scientist/consistent, brother2) - var/icon/brother2_blood_icon = icon('icons/effects/blood.dmi', "uniformblood") - brother2_blood_icon.Blend(BLOOD_COLOR_RED, ICON_MULTIPLY) - brother2_icon.Blend(brother2_blood_icon, ICON_OVERLAY) - brother2_icon.Shift(EAST, 8) + var/datum/universal_icon/brother2_icon = render_preview_outfit(/datum/outfit/job/scientist/consistent, brother2) + var/datum/universal_icon/brother2_blood_icon = uni_icon('icons/effects/blood.dmi', "uniformblood") + brother2_blood_icon.blend_color(BLOOD_COLOR_RED, ICON_MULTIPLY) + brother2_icon.blend_icon(brother2_blood_icon, ICON_OVERLAY) + brother2_icon.shift(EAST, 8) - var/icon/final_icon = brother1_icon - final_icon.Blend(brother2_icon, ICON_OVERLAY) + var/datum/universal_icon/final_icon = brother1_icon + final_icon.blend_icon(brother2_icon, ICON_OVERLAY) qdel(brother1) qdel(brother2) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 4f6e0385719..b841ec26626 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -1015,16 +1015,16 @@ return parts.Join("
") /datum/antagonist/changeling/get_preview_icon() - var/icon/final_icon = render_preview_outfit(/datum/outfit/changeling) - var/icon/split_icon = render_preview_outfit(/datum/outfit/job/engineer) + var/datum/universal_icon/final_icon = render_preview_outfit(/datum/outfit/changeling) + var/datum/universal_icon/split_icon = render_preview_outfit(/datum/outfit/job/engineer) - final_icon.Shift(WEST, ICON_SIZE_X / 2) - final_icon.Shift(EAST, ICON_SIZE_X / 2) + final_icon.shift(WEST, ICON_SIZE_X / 2) + final_icon.shift(EAST, ICON_SIZE_X / 2) - split_icon.Shift(EAST, ICON_SIZE_X / 2) - split_icon.Shift(WEST, ICON_SIZE_X / 2) + split_icon.shift(EAST, ICON_SIZE_X / 2) + split_icon.shift(WEST, ICON_SIZE_X / 2) - final_icon.Blend(split_icon, ICON_OVERLAY) + final_icon.blend_icon(split_icon, ICON_OVERLAY) return finish_preview_icon(final_icon) @@ -1064,7 +1064,7 @@ name = "\improper Space Changeling" /datum/antagonist/changeling/space/get_preview_icon() - var/icon/final_icon = render_preview_outfit(/datum/outfit/changeling_space) + var/datum/universal_icon/final_icon = render_preview_outfit(/datum/outfit/changeling_space) return finish_preview_icon(final_icon) /datum/antagonist/changeling/space/greet() diff --git a/code/modules/antagonists/cult/datums/cultist.dm b/code/modules/antagonists/cult/datums/cultist.dm index c637b2b45cb..de1d5ad2978 100644 --- a/code/modules/antagonists/cult/datums/cultist.dm +++ b/code/modules/antagonists/cult/datums/cultist.dm @@ -255,21 +255,21 @@ to_chat(cult_mind, span_cult_large("The Cult's Master, [owner.current.name], has fallen in \the [current_area]!")) /datum/antagonist/cult/get_preview_icon() - var/icon/icon = render_preview_outfit(preview_outfit) + var/datum/universal_icon/icon = render_preview_outfit(preview_outfit) // The longsword is 64x64, but getFlatIcon crunches to 32x32. // So I'm just going to add it in post, screw it. // Center the dude, because item icon states start from the center. // This makes the image 64x64. - icon.Crop(-15, -15, 48, 48) + icon.crop(-15, -15, 48, 48) - var/obj/item/melee/cultblade/longsword = new - icon.Blend(icon(longsword.lefthand_file, longsword.inhand_icon_state), ICON_OVERLAY) - qdel(longsword) + var/obj/item/melee/cultblade/blade_type = /obj/item/melee/cultblade + var/datum/universal_icon/blade_icon = uni_icon(blade_type::lefthand_file, blade_type::inhand_icon_state) + icon.blend_icon(blade_icon, ICON_OVERLAY) // Move the guy back to the bottom left, 32x32. - icon.Crop(17, 17, 48, 48) + icon.crop(17, 17, 48, 48) return finish_preview_icon(icon) diff --git a/code/modules/antagonists/fugitive/fugitive.dm b/code/modules/antagonists/fugitive/fugitive.dm index e42782bbf74..8f667a9a901 100644 --- a/code/modules/antagonists/fugitive/fugitive.dm +++ b/code/modules/antagonists/fugitive/fugitive.dm @@ -16,22 +16,22 @@ /datum/antagonist/fugitive/get_preview_icon() //start with prisoner at the front - var/icon/final_icon = render_preview_outfit(preview_outfit) + var/datum/universal_icon/final_icon = render_preview_outfit(preview_outfit) //then to the left add cultists of yalp elor - final_icon.Blend(make_background_fugitive_icon(/datum/outfit/yalp_cultist), ICON_UNDERLAY, -8, 0) + final_icon.blend_icon(make_background_fugitive_icon(/datum/outfit/yalp_cultist), ICON_UNDERLAY, -8, 0) //to the right add waldo (we just had to, okay?) - final_icon.Blend(make_background_fugitive_icon(/datum/outfit/waldo), ICON_UNDERLAY, 8, 0) + final_icon.blend_icon(make_background_fugitive_icon(/datum/outfit/waldo), ICON_UNDERLAY, 8, 0) - final_icon.Scale(64, 64) + final_icon.scale(64, 64) return finish_preview_icon(final_icon) /datum/antagonist/fugitive/proc/make_background_fugitive_icon(datum/outfit/fugitive_fit) var/mob/living/carbon/human/dummy/consistent/fugitive = new - var/icon/fugitive_icon = render_preview_outfit(fugitive_fit, fugitive) - fugitive_icon.ChangeOpacity(0.5) + var/datum/universal_icon/fugitive_icon = render_preview_outfit(fugitive_fit, fugitive) + fugitive_icon.change_opacity(0.5) qdel(fugitive) return fugitive_icon diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm index a34ef8418dd..ae1a5dfb932 100644 --- a/code/modules/antagonists/heretic/heretic_antag.dm +++ b/code/modules/antagonists/heretic/heretic_antag.dm @@ -315,7 +315,7 @@ return ..() /datum/antagonist/heretic/get_preview_icon() - var/icon/icon = render_preview_outfit(preview_outfit) + var/datum/universal_icon/icon = render_preview_outfit(preview_outfit) // MOTHBLOCKS TODO: Copied and pasted from cult, make this its own proc @@ -324,14 +324,14 @@ // Center the dude, because item icon states start from the center. // This makes the image 64x64. - icon.Crop(-15, -15, 48, 48) + icon.crop(-15, -15, 48, 48) - var/obj/item/melee/sickly_blade/blade = new - icon.Blend(icon(blade.lefthand_file, blade.inhand_icon_state), ICON_OVERLAY) - qdel(blade) + var/obj/item/melee/sickly_blade/blade_type = /obj/item/melee/sickly_blade + var/datum/universal_icon/blade_icon = uni_icon(blade_type::lefthand_file, blade_type::inhand_icon_state) + icon.blend_icon(blade_icon, ICON_OVERLAY) // Move the guy back to the bottom left, 32x32. - icon.Crop(17, 17, 48, 48) + icon.crop(17, 17, 48, 48) return finish_preview_icon(icon) diff --git a/code/modules/antagonists/malf_ai/malf_ai.dm b/code/modules/antagonists/malf_ai/malf_ai.dm index d35a00f8b7c..83b84c2e7b9 100644 --- a/code/modules/antagonists/malf_ai/malf_ai.dm +++ b/code/modules/antagonists/malf_ai/malf_ai.dm @@ -260,12 +260,12 @@ return result.Join("
") /datum/antagonist/malf_ai/get_preview_icon() - var/icon/malf_ai_icon = icon('icons/mob/silicon/ai.dmi', "ai-red") + var/datum/universal_icon/malf_ai_icon = uni_icon('icons/mob/silicon/ai.dmi', "ai-red") // Crop out the borders of the AI, just the face - malf_ai_icon.Crop(5, 27, 28, 6) + malf_ai_icon.crop(5, 6, 28, 27) - malf_ai_icon.Scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) + malf_ai_icon.scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) return malf_ai_icon diff --git a/code/modules/antagonists/nukeop/datums/operative.dm b/code/modules/antagonists/nukeop/datums/operative.dm index abf38593990..dccd7450f97 100644 --- a/code/modules/antagonists/nukeop/datums/operative.dm +++ b/code/modules/antagonists/nukeop/datums/operative.dm @@ -111,19 +111,19 @@ if (!preview_outfit) return null - var/icon/final_icon = render_preview_outfit(preview_outfit) + var/datum/universal_icon/final_icon = render_preview_outfit(preview_outfit) if (!isnull(preview_outfit_behind)) - var/icon/teammate = render_preview_outfit(preview_outfit_behind) - teammate.Blend(rgb(128, 128, 128, 128), ICON_MULTIPLY) + var/datum/universal_icon/teammate = render_preview_outfit(preview_outfit_behind) + teammate.blend_color("#80808080", ICON_MULTIPLY) - final_icon.Blend(teammate, ICON_UNDERLAY, -ICON_SIZE_X / 4, 0) - final_icon.Blend(teammate, ICON_UNDERLAY, ICON_SIZE_X / 4, 0) + final_icon.blend_icon(teammate, ICON_UNDERLAY, -ICON_SIZE_X / 4, 0) + final_icon.blend_icon(teammate, ICON_UNDERLAY, ICON_SIZE_X / 4, 0) if (!isnull(nuke_icon_state)) - var/icon/nuke = icon('icons/obj/machines/nuke.dmi', nuke_icon_state) - nuke.Shift(SOUTH, 6) - final_icon.Blend(nuke, ICON_OVERLAY) + var/datum/universal_icon/nuke = uni_icon('icons/obj/machines/nuke.dmi', nuke_icon_state) + nuke.shift(SOUTH, 6) + final_icon.blend_icon(nuke, ICON_OVERLAY) return finish_preview_icon(final_icon) diff --git a/code/modules/antagonists/obsessed/obsessed.dm b/code/modules/antagonists/obsessed/obsessed.dm index 0296c3c53ee..1cd433c055e 100644 --- a/code/modules/antagonists/obsessed/obsessed.dm +++ b/code/modules/antagonists/obsessed/obsessed.dm @@ -58,19 +58,15 @@ . = ..() /datum/antagonist/obsessed/get_preview_icon() - var/mob/living/carbon/human/dummy/consistent/victim_dummy = new - victim_dummy.set_haircolor("#bb9966", update = FALSE) - victim_dummy.set_hairstyle("Messy", update = TRUE) + var/datum/universal_icon/obsessed_icon = render_preview_outfit(preview_outfit) + var/datum/universal_icon/blood_icon = uni_icon('icons/effects/blood.dmi', "uniformblood") + blood_icon.blend_color(BLOOD_COLOR_RED, ICON_MULTIPLY) + obsessed_icon.blend_icon(blood_icon, ICON_OVERLAY) - var/icon/obsessed_icon = render_preview_outfit(preview_outfit) - var/icon/blood_icon = icon('icons/effects/blood.dmi', "uniformblood") - blood_icon.Blend(BLOOD_COLOR_RED, ICON_MULTIPLY) - obsessed_icon.Blend(blood_icon, ICON_OVERLAY) + var/datum/universal_icon/final_icon = finish_preview_icon(obsessed_icon) - var/icon/final_icon = finish_preview_icon(obsessed_icon) - - final_icon.Blend( - icon('icons/ui/antags/obsessed.dmi', "obsession"), + final_icon.blend_icon( + uni_icon('icons/ui/antags/obsessed.dmi', "obsession"), ICON_OVERLAY, ANTAGONIST_PREVIEW_ICON_SIZE - 30, 20, diff --git a/code/modules/antagonists/paradox_clone/paradox_clone.dm b/code/modules/antagonists/paradox_clone/paradox_clone.dm index 18631c51237..fe76e891a4f 100644 --- a/code/modules/antagonists/paradox_clone/paradox_clone.dm +++ b/code/modules/antagonists/paradox_clone/paradox_clone.dm @@ -9,18 +9,18 @@ preview_outfit = /datum/outfit/paradox_clone /datum/antagonist/paradox_clone/get_preview_icon() - var/icon/final_icon = render_preview_outfit(preview_outfit) + var/datum/universal_icon/final_icon = render_preview_outfit(preview_outfit) - final_icon.Blend(make_background_clone_icon(preview_outfit), ICON_UNDERLAY, -8, 0) - final_icon.Scale(64, 64) + final_icon.blend_icon(make_background_clone_icon(preview_outfit), ICON_UNDERLAY, -8, 0) + final_icon.scale(64, 64) return finish_preview_icon(final_icon) /datum/antagonist/paradox_clone/proc/make_background_clone_icon(datum/outfit/clone_fit) var/mob/living/carbon/human/dummy/consistent/clone = new - var/icon/clone_icon = render_preview_outfit(clone_fit, clone) - clone_icon.ChangeOpacity(0.5) + var/datum/universal_icon/clone_icon = render_preview_outfit(clone_fit, clone) + clone_icon.change_opacity(0.5) qdel(clone) return clone_icon diff --git a/code/modules/antagonists/revenant/revenant_antag.dm b/code/modules/antagonists/revenant/revenant_antag.dm index 8f15508989c..3227377779a 100644 --- a/code/modules/antagonists/revenant/revenant_antag.dm +++ b/code/modules/antagonists/revenant/revenant_antag.dm @@ -14,7 +14,7 @@ . = ..() /datum/antagonist/revenant/get_preview_icon() - return finish_preview_icon(icon('icons/mob/simple/mob.dmi', "revenant_idle")) + return finish_preview_icon(uni_icon('icons/mob/simple/mob.dmi', "revenant_idle")) /datum/antagonist/revenant/forge_objectives() var/datum/objective/revenant/objective = new diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm index 94e5f0c0484..4c4de17add0 100644 --- a/code/modules/antagonists/revolution/revolution.dm +++ b/code/modules/antagonists/revolution/revolution.dm @@ -222,21 +222,21 @@ return ..() + "(Leader)" /datum/antagonist/rev/head/get_preview_icon() - var/icon/final_icon = render_preview_outfit(preview_outfit) + var/datum/universal_icon/final_icon = render_preview_outfit(preview_outfit) - final_icon.Blend(make_assistant_icon("Business Hair"), ICON_UNDERLAY, -8, 0) - final_icon.Blend(make_assistant_icon("CIA"), ICON_UNDERLAY, 8, 0) + final_icon.blend_icon(make_assistant_icon("Business Hair"), ICON_UNDERLAY, -8, 0) + final_icon.blend_icon(make_assistant_icon("CIA"), ICON_UNDERLAY, 8, 0) // Apply the rev head HUD, but scale up the preview icon a bit beforehand. // Otherwise, the R gets cut off. - final_icon.Scale(64, 64) + final_icon.scale(64, 64) - var/icon/rev_head_icon = icon('icons/mob/huds/antag_hud.dmi', "rev_head") - rev_head_icon.Scale(48, 48) - rev_head_icon.Crop(1, 1, 64, 64) - rev_head_icon.Shift(EAST, 10) - rev_head_icon.Shift(NORTH, 16) - final_icon.Blend(rev_head_icon, ICON_OVERLAY) + var/datum/universal_icon/rev_head_icon = uni_icon('icons/mob/huds/antag_hud.dmi', "rev_head") + rev_head_icon.scale(48, 48) + rev_head_icon.crop(1, 1, 64, 64) + rev_head_icon.shift(EAST, 10) + rev_head_icon.shift(NORTH, 16) + final_icon.blend_icon(rev_head_icon, ICON_OVERLAY) return finish_preview_icon(final_icon) @@ -244,8 +244,8 @@ var/mob/living/carbon/human/dummy/consistent/assistant = new assistant.set_hairstyle(hairstyle, update = TRUE) - var/icon/assistant_icon = render_preview_outfit(/datum/outfit/job/assistant/consistent, assistant) - assistant_icon.ChangeOpacity(0.5) + var/datum/universal_icon/assistant_icon = render_preview_outfit(/datum/outfit/job/assistant/consistent, assistant) + assistant_icon.change_opacity(0.5) qdel(assistant) diff --git a/code/modules/antagonists/sentient_creature/sentient_creature.dm b/code/modules/antagonists/sentient_creature/sentient_creature.dm index b2035471c46..ef87cff49e6 100644 --- a/code/modules/antagonists/sentient_creature/sentient_creature.dm +++ b/code/modules/antagonists/sentient_creature/sentient_creature.dm @@ -6,17 +6,17 @@ ui_name = "AntagInfoSentient" /datum/antagonist/sentient_creature/get_preview_icon() - var/icon/final_icon = icon('icons/mob/simple/pets.dmi', "corgi") + var/datum/universal_icon/final_icon = uni_icon('icons/mob/simple/pets.dmi', "corgi") - var/icon/pandora = icon('icons/mob/simple/lavaland/lavaland_elites.dmi', "pandora") - pandora.Blend(rgb(128, 128, 128, 128), ICON_MULTIPLY) - final_icon.Blend(pandora, ICON_UNDERLAY, -ICON_SIZE_X / 4, 0) + var/datum/universal_icon/pandora = uni_icon('icons/mob/simple/lavaland/lavaland_elites.dmi', "pandora") + pandora.blend_color("#80808080", ICON_MULTIPLY) + final_icon.blend_icon(pandora, ICON_UNDERLAY, -ICON_SIZE_X / 4, 0) - var/icon/rat = icon('icons/mob/simple/animal.dmi', "regalrat") - rat.Blend(rgb(128, 128, 128, 128), ICON_MULTIPLY) - final_icon.Blend(rat, ICON_UNDERLAY, ICON_SIZE_X / 4, 0) + var/datum/universal_icon/rat = uni_icon('icons/mob/simple/animal.dmi', "regalrat") + rat.blend_color("#80808080", ICON_MULTIPLY) + final_icon.blend_icon(rat, ICON_UNDERLAY, ICON_SIZE_X / 4, 0) - final_icon.Scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) + final_icon.scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) return final_icon /datum/antagonist/sentient_creature/on_gain() diff --git a/code/modules/antagonists/space_dragon/space_dragon.dm b/code/modules/antagonists/space_dragon/space_dragon.dm index 320015c34bc..c71b5302b6e 100644 --- a/code/modules/antagonists/space_dragon/space_dragon.dm +++ b/code/modules/antagonists/space_dragon/space_dragon.dm @@ -107,13 +107,13 @@ return ..() /datum/antagonist/space_dragon/get_preview_icon() - var/icon/icon = icon('icons/mob/nonhuman-player/spacedragon.dmi', "spacedragon") + var/datum/universal_icon/icon = uni_icon('icons/mob/nonhuman-player/spacedragon.dmi', "spacedragon") - icon.Blend(COLOR_STRONG_VIOLET, ICON_MULTIPLY) - icon.Blend(icon('icons/mob/nonhuman-player/spacedragon.dmi', "spacedragon_overlay_base"), ICON_OVERLAY) + icon.blend_color(COLOR_STRONG_VIOLET, ICON_MULTIPLY) + icon.blend_icon(uni_icon('icons/mob/nonhuman-player/spacedragon.dmi', "spacedragon_overlay_base"), ICON_OVERLAY) - icon.Crop(10, 9, 54, 53) - icon.Scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) + icon.crop(10, 9, 54, 53) + icon.scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) return icon diff --git a/code/modules/antagonists/spy/spy.dm b/code/modules/antagonists/spy/spy.dm index d0297b9842c..3685800dcf1 100644 --- a/code/modules/antagonists/spy/spy.dm +++ b/code/modules/antagonists/spy/spy.dm @@ -196,7 +196,9 @@ var/mob/living/carbon/human/dummy/consistent/dummy = new() dummy.set_haircolor(COLOR_SILVER, update = FALSE) dummy.set_hairstyle("CIA", update = FALSE) - return finish_preview_icon(render_preview_outfit(preview_outfit, dummy)) + var/datum/universal_icon/dummy_icon = render_preview_outfit(preview_outfit, dummy) + qdel(dummy) + return finish_preview_icon(dummy_icon) /datum/outfit/spy name = "Spy (Preview only)" diff --git a/code/modules/antagonists/voidwalker/voidwalker.dm b/code/modules/antagonists/voidwalker/voidwalker.dm index 932582b4bd1..dc73f7aa9a8 100644 --- a/code/modules/antagonists/voidwalker/voidwalker.dm +++ b/code/modules/antagonists/voidwalker/voidwalker.dm @@ -22,8 +22,8 @@ /datum/antagonist/voidwalker/get_preview_icon() var/mob/living/basic/voidwalker/walker_type = /mob/living/basic/voidwalker - var/icon/icon = icon(walker_type::icon, walker_type::icon_state) - icon.Crop(5, 18, 30, 44) + var/datum/universal_icon/icon = uni_icon(walker_type::icon, walker_type::icon_state) + icon.crop(5, 18, 30, 44) return finish_preview_icon(icon) /datum/antagonist/voidwalker/forge_objectives() diff --git a/code/modules/antagonists/xeno/xeno.dm b/code/modules/antagonists/xeno/xeno.dm index 3f045a87ec5..2504f6b2ba0 100644 --- a/code/modules/antagonists/xeno/xeno.dm +++ b/code/modules/antagonists/xeno/xeno.dm @@ -44,7 +44,7 @@ return xeno_team /datum/antagonist/xeno/get_preview_icon() - return finish_preview_icon(icon('icons/mob/nonhuman-player/alien.dmi', "alienh")) + return finish_preview_icon(uni_icon('icons/mob/nonhuman-player/alien.dmi', "alienh")) /datum/antagonist/xeno/forge_objectives() var/datum/objective/advance_hive/objective = new diff --git a/code/modules/asset_cache/spritesheet/batched/universal_icon.dm b/code/modules/asset_cache/spritesheet/batched/universal_icon.dm index 0ecdd1ea349..efd120ac782 100644 --- a/code/modules/asset_cache/spritesheet/batched/universal_icon.dm +++ b/code/modules/asset_cache/spritesheet/batched/universal_icon.dm @@ -13,7 +13,7 @@ /datum/universal_icon/New(icon/icon_file, icon_state="", dir=null, frame=null, datum/icon_transformer/transform=null, color=null) #ifdef UNIT_TESTS // This check is kinda slow and shouldn't fail unless a developer makes a mistake. So it'll get caught in unit tests. - if(!isicon(icon_file) || !isfile(icon_file) || "[icon_file]" == "/icon" || !length("[icon_file]")) + if((!isicon(icon_file) && !isfile(icon_file)) || "[icon_file]" == "/icon" || !length("[icon_file]")) // bad! use 'icons/path_to_dmi.dmi' format only CRASH("FATAL: universal_icon was provided icon_file: [icon_file] - icons provided to batched spritesheets MUST be DMI files, they cannot be /image, /icon, or other runtime generated icons.") #endif diff --git a/code/modules/client/preferences/README.md b/code/modules/client/preferences/README.md index d6a96791e3b..e30198eafbd 100644 --- a/code/modules/client/preferences/README.md +++ b/code/modules/client/preferences/README.md @@ -397,24 +397,24 @@ Space Ninja, for example, looks like: preview_outift = /datum/outfit/ninja ``` -However, if you want to get creative, you can override `/get_preview_icon()`. This proc should return an icon of size `ANTAGONIST_PREVIEW_ICON_SIZE`x`ANTAGONIST_PREVIEW_ICON_SIZE`. +However, if you want to get creative, you can override `/get_preview_icon()`. This proc should return a /datum/universal_icon of size `ANTAGONIST_PREVIEW_ICON_SIZE`x`ANTAGONIST_PREVIEW_ICON_SIZE`. -There are some helper procs you can use as well. `render_preview_outfit(outfit_type)` will take an outfit and give you an icon of someone wearing those clothes. `finish_preview_outfit` will, given an icon, resize it appropriately and zoom in on the head. Note that this will look bad on anything that isn't a human, so if you have a non-human antagonist (such as sentient disease), just run `icon.Scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE)`. +There are some helper procs you can use as well. `render_preview_outfit(outfit_type)` will take an outfit and give you a /datum/universal_icon of someone wearing those clothes (using get_flat_uni_icon). `finish_preview_outfit` will, given an icon, resize it appropriately and zoom in on the head. Note that this will look bad on anything that isn't a human, so if you have a non-human antagonist (such as sentient disease), just run `icon.scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE)`. For inspiration, here is changeling's: ```dm /datum/antagonist/changeling/get_preview_icon() - var/icon/final_icon = render_preview_outfit(/datum/outfit/changeling) - var/icon/split_icon = render_preview_outfit(/datum/outfit/job/engineer) + var/datum/universal_icon/final_icon = render_preview_outfit(/datum/outfit/changeling) + var/datum/universal_icon/split_icon = render_preview_outfit(/datum/outfit/job/engineer) - final_icon.Shift(WEST, ICON_SIZE_X / 2) - final_icon.Shift(EAST, ICON_SIZE_X / 2) + final_icon.shift(WEST, ICON_SIZE_X / 2) + final_icon.shift(EAST, ICON_SIZE_X / 2) - split_icon.Shift(EAST, ICON_SIZE_X / 2) - split_icon.Shift(WEST, ICON_SIZE_X / 2) + split_icon.shift(EAST, ICON_SIZE_X / 2) + split_icon.shift(WEST, ICON_SIZE_X / 2) - final_icon.Blend(split_icon, ICON_OVERLAY) + final_icon.blend_icon(split_icon, ICON_OVERLAY) return finish_preview_icon(final_icon) ``` diff --git a/code/modules/client/preferences/middleware/antags.dm b/code/modules/client/preferences/middleware/antags.dm index 39948078b11..1d3a3c1aeed 100644 --- a/code/modules/client/preferences/middleware/antags.dm +++ b/code/modules/client/preferences/middleware/antags.dm @@ -36,7 +36,7 @@ GLOBAL_LIST_INIT(non_ruleset_antagonists, list( /datum/preference_middleware/antags/get_ui_assets() return list( - get_asset_datum(/datum/asset/spritesheet/antagonists), + get_asset_datum(/datum/asset/spritesheet_batched/antagonists), ) /datum/preference_middleware/antags/proc/set_antags(list/params, mob/user) @@ -136,14 +136,14 @@ GLOBAL_LIST_INIT(non_ruleset_antagonists, list( return get_remaining_days(antag_time_limits[checked_antag_flag] || 0) /// Sprites generated for the antagonists panel -/datum/asset/spritesheet/antagonists +/datum/asset/spritesheet_batched/antagonists name = "antagonists" early = TRUE - /// Mapping of spritesheet keys -> icons + /// List of keys -> universal icon datums var/list/antag_icons = list() -/datum/asset/spritesheet/antagonists/create_spritesheets() +/datum/asset/spritesheet_batched/antagonists/create_spritesheets() var/list/antagonists = GLOB.non_ruleset_antagonists.Copy() for (var/datum/dynamic_ruleset/ruleset as anything in subtypesof(/datum/dynamic_ruleset)) @@ -166,10 +166,13 @@ GLOBAL_LIST_INIT(non_ruleset_antagonists, list( if (!isnull(generated_icons[antagonist_type])) antag_icons[spritesheet_key] = generated_icons[antagonist_type] + // make sure IconForge also knows to generate this duplicate for the given key + // internal caching will prevent double generation of the same icon + insert_icon(spritesheet_key, generated_icons[antagonist_type]) continue var/datum/antagonist/antagonist = new antagonist_type - var/icon/preview_icon = antagonist.get_preview_icon() + var/datum/universal_icon/preview_icon = antagonist.get_preview_icon() if (isnull(preview_icon)) continue @@ -179,11 +182,12 @@ GLOBAL_LIST_INIT(non_ruleset_antagonists, list( // preview_icons are not scaled at this stage INTENTIONALLY. // If an icon is not prepared to be scaled to that size, it looks really ugly, and this // makes it harder to figure out what size it *actually* is. - generated_icons[antagonist_type] = preview_icon - antag_icons[spritesheet_key] = preview_icon - for (var/spritesheet_key in antag_icons) - Insert(spritesheet_key, antag_icons[spritesheet_key]) + // make sure no antagonists are rebuilt + generated_icons[antagonist_type] = preview_icon + // store for screenshot tests + antag_icons[spritesheet_key] = preview_icon + insert_icon(spritesheet_key, preview_icon) /// Serializes an antag name to be used for preferences UI /proc/serialize_antag_name(antag_name) diff --git a/code/modules/client/preferences/middleware/species.dm b/code/modules/client/preferences/middleware/species.dm index c7fc4265390..f45482a5069 100644 --- a/code/modules/client/preferences/middleware/species.dm +++ b/code/modules/client/preferences/middleware/species.dm @@ -3,16 +3,14 @@ /datum/preference_middleware/species/get_ui_assets() return list( - get_asset_datum(/datum/asset/spritesheet/species), + get_asset_datum(/datum/asset/spritesheet_batched/species), ) -/datum/asset/spritesheet/species +/datum/asset/spritesheet_batched/species name = "species" early = TRUE -/datum/asset/spritesheet/species/create_spritesheets() - var/list/to_insert = list() - +/datum/asset/spritesheet_batched/species/create_spritesheets() for (var/species_id in get_selectable_species()) var/datum/species/species_type = GLOB.species_list[species_id] @@ -21,13 +19,10 @@ dummy.equipOutfit(/datum/outfit/job/assistant/consistent, visuals_only = TRUE) dummy.dna.species.prepare_human_for_preview(dummy) - var/icon/dummy_icon = getFlatIcon(dummy) - dummy_icon.Scale(64, 64) - dummy_icon.Crop(15, 64 - 31, 15 + 31, 64) - dummy_icon.Scale(64, 64) - to_insert[sanitize_css_class_name(initial(species_type.name))] = dummy_icon + var/datum/universal_icon/dummy_icon = get_flat_uni_icon(dummy) + dummy_icon.scale(64, 64) + dummy_icon.crop(15, 64 - 31, 15 + 31, 64) + dummy_icon.scale(64, 64) + insert_icon(sanitize_css_class_name(initial(species_type.name)), dummy_icon) SSatoms.prepare_deletion(dummy) - - for (var/spritesheet_key in to_insert) - Insert(spritesheet_key, to_insert[spritesheet_key]) diff --git a/code/modules/unit_tests/screenshot_antag_icons.dm b/code/modules/unit_tests/screenshot_antag_icons.dm index 0a210ae31ed..a3f3f62af65 100644 --- a/code/modules/unit_tests/screenshot_antag_icons.dm +++ b/code/modules/unit_tests/screenshot_antag_icons.dm @@ -2,11 +2,26 @@ /datum/unit_test/screenshot_antag_icons /datum/unit_test/screenshot_antag_icons/Run() - var/datum/asset/spritesheet/antagonists/antagonists = get_asset_datum(/datum/asset/spritesheet/antagonists) + var/datum/asset/spritesheet_batched/antagonists/antagonists = get_asset_datum(/datum/asset/spritesheet_batched/antagonists) - for (var/antag_icon_key in antagonists.antag_icons) - var/icon/reference_icon = antagonists.antag_icons[antag_icon_key] + // Generates the spritesheet in /tmp, while also ensuring that ALL icons output to the same size (will error otherwise) + // Left here in case caching changes somehow and we want a fresh generator + var/test_icon_filepath = "tmp/antag_icon_screenshot_test.dmi" + var/list/headless_result = rustg_iconforge_generate_headless(test_icon_filepath, antagonists.entries_json, TRUE) + if(!istype(headless_result)) + TEST_FAIL("Could not generate antagonist icons using rustg_iconforge_generate_headless! The output format was invalid (JSON did not decode to a list). Got: [headless_result]") + if(!length(headless_result)) + TEST_FAIL("Could not generate antagonist icons using rustg_iconforge_generate_headless! The output list was empty. Got: [json_encode(headless_result)]") + if(!isnull(headless_result["error"])) + TEST_FAIL("Could not generate antagonist icons using rustg_iconforge_generate_headless! There was an error: [headless_result["error"]]") + if(headless_result["file_path"] != test_icon_filepath) + TEST_FAIL("Could not generate antagonist icons using rustg_iconforge_generate_headless! The output file_path differed from the input. Got: [json_encode(headless_result)]") + if(headless_result["width"] != ANTAGONIST_PREVIEW_ICON_SIZE || headless_result["height"] != ANTAGONIST_PREVIEW_ICON_SIZE) + TEST_FAIL("Could not generate antagonist icons using rustg_iconforge_generate_headless! The output size was not ANTAGONIST_PREVIEW_ICON_SIZE. Got: [json_encode(headless_result)]") + if(!fexists(test_icon_filepath)) + TEST_FAIL("Could not generate antagonist icons using rustg_iconforge_generate_headless! The output file does not exist on the filesystem! Got: [json_encode(headless_result)]") + var/icon/test_icon = icon(file(test_icon_filepath)) - var/icon/icon = new() - icon.Insert(reference_icon, null, SOUTH, 1) + for (var/antag_icon_key in antagonists.entries) + var/icon/icon = icon(test_icon, antag_icon_key, SOUTH, 1) test_screenshot(antag_icon_key, icon) diff --git a/icons/map_icons/clothing/_clothing.dmi b/icons/map_icons/clothing/_clothing.dmi index 6c781a70ad1..6a9956844f4 100644 Binary files a/icons/map_icons/clothing/_clothing.dmi and b/icons/map_icons/clothing/_clothing.dmi differ diff --git a/icons/map_icons/clothing/accessory.dmi b/icons/map_icons/clothing/accessory.dmi index 1719b8a73bb..4c4244f716a 100644 Binary files a/icons/map_icons/clothing/accessory.dmi and b/icons/map_icons/clothing/accessory.dmi differ diff --git a/icons/map_icons/clothing/head/_head.dmi b/icons/map_icons/clothing/head/_head.dmi index 567646e1af5..67ffccf2c2a 100644 Binary files a/icons/map_icons/clothing/head/_head.dmi and b/icons/map_icons/clothing/head/_head.dmi differ diff --git a/icons/map_icons/clothing/head/beret.dmi b/icons/map_icons/clothing/head/beret.dmi index 975bbf80cf2..fb920ce8327 100644 Binary files a/icons/map_icons/clothing/head/beret.dmi and b/icons/map_icons/clothing/head/beret.dmi differ diff --git a/icons/map_icons/clothing/mask.dmi b/icons/map_icons/clothing/mask.dmi index e8fa3c8594c..2841cb9effc 100644 Binary files a/icons/map_icons/clothing/mask.dmi and b/icons/map_icons/clothing/mask.dmi differ diff --git a/icons/map_icons/clothing/neck.dmi b/icons/map_icons/clothing/neck.dmi index 9adba4c1e50..3a5094318ef 100644 Binary files a/icons/map_icons/clothing/neck.dmi and b/icons/map_icons/clothing/neck.dmi differ diff --git a/icons/map_icons/clothing/shoes.dmi b/icons/map_icons/clothing/shoes.dmi index 97712fd9724..d6c336245fb 100644 Binary files a/icons/map_icons/clothing/shoes.dmi and b/icons/map_icons/clothing/shoes.dmi differ diff --git a/icons/map_icons/clothing/suit/_suit.dmi b/icons/map_icons/clothing/suit/_suit.dmi index ef633374f89..82feabad49e 100644 Binary files a/icons/map_icons/clothing/suit/_suit.dmi and b/icons/map_icons/clothing/suit/_suit.dmi differ diff --git a/icons/map_icons/clothing/suit/costume.dmi b/icons/map_icons/clothing/suit/costume.dmi index 3db98406230..b47fc0c68ab 100644 Binary files a/icons/map_icons/clothing/suit/costume.dmi and b/icons/map_icons/clothing/suit/costume.dmi differ diff --git a/icons/map_icons/clothing/under/_under.dmi b/icons/map_icons/clothing/under/_under.dmi index 82a09867c53..5d9b9146e86 100644 Binary files a/icons/map_icons/clothing/under/_under.dmi and b/icons/map_icons/clothing/under/_under.dmi differ diff --git a/icons/map_icons/clothing/under/color.dmi b/icons/map_icons/clothing/under/color.dmi index aa09a947f9d..87189da7548 100644 Binary files a/icons/map_icons/clothing/under/color.dmi and b/icons/map_icons/clothing/under/color.dmi differ diff --git a/icons/map_icons/clothing/under/costume.dmi b/icons/map_icons/clothing/under/costume.dmi index 4f3d049fe17..17e56c8eaa1 100644 Binary files a/icons/map_icons/clothing/under/costume.dmi and b/icons/map_icons/clothing/under/costume.dmi differ diff --git a/icons/map_icons/clothing/under/dress.dmi b/icons/map_icons/clothing/under/dress.dmi index fde8dfbebaa..14e11b72a7f 100644 Binary files a/icons/map_icons/clothing/under/dress.dmi and b/icons/map_icons/clothing/under/dress.dmi differ diff --git a/icons/map_icons/items/_item.dmi b/icons/map_icons/items/_item.dmi index ce998dbb391..9988f49c6fa 100644 Binary files a/icons/map_icons/items/_item.dmi and b/icons/map_icons/items/_item.dmi differ diff --git a/icons/map_icons/items/encryptionkey.dmi b/icons/map_icons/items/encryptionkey.dmi index be7514ad789..360180773f3 100644 Binary files a/icons/map_icons/items/encryptionkey.dmi and b/icons/map_icons/items/encryptionkey.dmi differ diff --git a/icons/map_icons/items/pda.dmi b/icons/map_icons/items/pda.dmi index 488e0ea2e7a..c28a9b7043f 100644 Binary files a/icons/map_icons/items/pda.dmi and b/icons/map_icons/items/pda.dmi differ diff --git a/icons/map_icons/mobs.dmi b/icons/map_icons/mobs.dmi index 6c781a70ad1..6a9956844f4 100644 Binary files a/icons/map_icons/mobs.dmi and b/icons/map_icons/mobs.dmi differ diff --git a/icons/map_icons/objects.dmi b/icons/map_icons/objects.dmi index faefc9cb0d6..dd3a926e2a7 100644 Binary files a/icons/map_icons/objects.dmi and b/icons/map_icons/objects.dmi differ diff --git a/icons/map_icons/turfs.dmi b/icons/map_icons/turfs.dmi index 6c781a70ad1..6a9956844f4 100644 Binary files a/icons/map_icons/turfs.dmi and b/icons/map_icons/turfs.dmi differ diff --git a/icons/map_icons/unsorted.dmi b/icons/map_icons/unsorted.dmi index 6c781a70ad1..6a9956844f4 100644 Binary files a/icons/map_icons/unsorted.dmi and b/icons/map_icons/unsorted.dmi differ