From 86ba327b9da7a697089b751c24b52a88f6d9ecf6 Mon Sep 17 00:00:00 2001 From: Jerry Wester Date: Fri, 20 Jan 2023 19:58:44 -0700 Subject: [PATCH] update painting --- code/modules/mod/mod_construction.dm | 6 - code/modules/mod/mod_control.dm | 33 ++--- code/modules/mod/mod_paint.dm | 207 +++++++++++++++++++++++++++ tgstation.dme | 1 + 4 files changed, 222 insertions(+), 25 deletions(-) create mode 100644 code/modules/mod/mod_paint.dm diff --git a/code/modules/mod/mod_construction.dm b/code/modules/mod/mod_construction.dm index 3fc8464b6b..9d50e733bd 100644 --- a/code/modules/mod/mod_construction.dm +++ b/code/modules/mod/mod_construction.dm @@ -87,12 +87,6 @@ /obj/item/mod/construction/armor/magnate theme = /datum/mod_theme/magnate -/obj/item/mod/paint - name = "MOD paint kit" - desc = "This kit will repaint your MODsuit to something unique." - icon = 'icons/obj/clothing/modsuit/mod_construction.dmi' - icon_state = "paintkit" - #define START_STEP "start" #define CORE_STEP "core" #define SCREWED_CORE_STEP "screwed_core" diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index 6a38ba550d..0853d04f82 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -344,14 +344,6 @@ else if(is_wire_tool(attacking_item) && open) wires.interact(user) return TRUE - else if(istype(attacking_item, /obj/item/mod/paint)) - if(active || activating) - balloon_alert(user, "suit is active!") - else if(paint(user, attacking_item)) - balloon_alert(user, "suit painted") - else - balloon_alert(user, "not painted!") - return TRUE else if(open && attacking_item.GetID()) update_access(user, attacking_item) return TRUE @@ -453,22 +445,25 @@ return selected_module.on_select() -/obj/item/mod/control/proc/paint(mob/user, obj/item/paint) - if(length(theme.skins) <= 1) - return FALSE - var/list/skins = list() - for(var/mod_skin in theme.skins) - skins[mod_skin] = image(icon = icon, icon_state = "[mod_skin]-control") - var/pick = show_radial_menu(user, src, skins, custom_check = FALSE, require_near = TRUE) - if(!pick || !user.is_holding(paint)) - return FALSE - skin = pick +/obj/item/mod/control/proc/set_mod_color(new_color) + var/list/all_parts = mod_parts + src + for(var/obj/item/part as anything in all_parts) + part.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) + part.add_atom_colour(new_color, FIXED_COLOUR_PRIORITY) + wearer?.regenerate_icons() + +/obj/item/mod/control/proc/set_mod_skin(new_skin) + if(active) + CRASH("[src] tried to set skin while active!") + skin = new_skin + var/list/used_skin = theme.skins[new_skin] + if(used_skin[CONTROL_LAYER]) + alternate_worn_layer = used_skin[CONTROL_LAYER] var/list/skin_updating = mod_parts.Copy() + src for(var/obj/item/piece as anything in skin_updating) piece.icon_state = "[skin]-[initial(piece.icon_state)]" update_flags() wearer?.regenerate_icons() - return TRUE /obj/item/mod/control/proc/shock(mob/living/user) if(!istype(user) || cell?.charge < 1) diff --git a/code/modules/mod/mod_paint.dm b/code/modules/mod/mod_paint.dm new file mode 100644 index 0000000000..44f4923002 --- /dev/null +++ b/code/modules/mod/mod_paint.dm @@ -0,0 +1,207 @@ +#define MODPAINT_MAX_COLOR_VALUE 1.25 +#define MODPAINT_MIN_COLOR_VALUE 0 +#define MODPAINT_MAX_SECTION_COLORS 2 +#define MODPAINT_MIN_SECTION_COLORS 0.25 +#define MODPAINT_MAX_OVERALL_COLORS 4 +#define MODPAINT_MIN_OVERALL_COLORS 1.5 +#define MODPAINT_MODE_RESKIN "reskin" +#define MODPAINT_MODE_REPAINT "repaint" + +/obj/item/mod/paint + name = "MOD paint kit" + desc = "This kit will repaint your MODsuit to something unique." + icon = 'icons/obj/clothing/modsuit/mod_construction.dmi' + icon_state = "paintkit" + var/obj/item/mod/control/editing_mod + var/atom/movable/screen/map_view/proxy_view + var/list/current_color + var/mode = MODPAINT_MODE_RESKIN + +/obj/item/mod/paint/Initialize(mapload) + . = ..() + current_color = color_matrix_identity() + +/obj/item/mod/paint/examine(mob/user) + . = ..() + . += span_notice("It is currently on [mode] mode.") + +/obj/item/mod/paint/attack_self(mob/user) + switch(mode) + if(MODPAINT_MODE_RESKIN) + mode = MODPAINT_MODE_REPAINT + if(MODPAINT_MODE_REPAINT) + mode = MODPAINT_MODE_RESKIN + to_chat(user, span_notice("Switched to [mode] mode.")) + +/obj/item/mod/paint/pre_attack(atom/attacked_atom, mob/living/user, params) + if(!istype(attacked_atom, /obj/item/mod/control)) + return ..() + var/obj/item/mod/control/mod = attacked_atom + if(mod.active || mod.activating) + balloon_alert(user, "suit is active!") + return STOP_ATTACK_PROC_CHAIN + switch(mode) + if(MODPAINT_MODE_RESKIN) + paint_skin(mod, user) + if(MODPAINT_MODE_REPAINT) + if(editing_mod) + return STOP_ATTACK_PROC_CHAIN + editing_mod = mod + var/map_name = "color_matrix_proxy_[REF(user.client)]" + proxy_view = new() + proxy_view.name = "screen" + proxy_view.assigned_map = map_name + proxy_view.del_on_map_removal = FALSE + proxy_view.screen_loc = "[map_name]:1,1" + + proxy_view.appearance = editing_mod.appearance + proxy_view.color = null + user.client.register_map_obj(proxy_view) + ui_interact(user) + return STOP_ATTACK_PROC_CHAIN + +/obj/item/mod/paint/ui_interact(mob/user, datum/tgui/ui) + if(!editing_mod) + return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MODpaint", name) + ui.open() + +/obj/item/mod/paint/ui_host() + return editing_mod + +/obj/item/mod/paint/ui_close(mob/user) + . = ..() + editing_mod = null + QDEL_NULL(proxy_view) + current_color = color_matrix_identity() + +/obj/item/mod/paint/ui_status(mob/user) + if(check_menu(editing_mod, user)) + return ..() + return UI_CLOSE + +/obj/item/mod/paint/ui_static_data(mob/user) + var/list/data = list() + data["mapRef"] = proxy_view.assigned_map + return data + +/obj/item/mod/paint/ui_data(mob/user) + var/list/data = list() + data["currentColor"] = current_color + return data + +/obj/item/mod/paint/ui_act(action, list/params) + . = ..() + if(.) + return + switch(action) + if("transition_color") + current_color = params["color"] + animate(proxy_view, time = 0.5 SECONDS, color = current_color) + if("confirm") + if(length(current_color) != 20) //20 is the length of a matrix identity list + return + for(var/color_value in current_color) + if(isnum(color_value)) + continue + return + var/total_color_value = 0 + var/list/total_colors = current_color.Copy() + total_colors.Cut(13, length(total_colors)) // 13 to 20 are just a and c, dont want to count them + var/red_value = current_color[1] + current_color[5] + current_color[9] //rr + gr + br + var/green_value = current_color[2] + current_color[6] + current_color[10] //rg + gg + bg + var/blue_value = current_color[3] + current_color[7] + current_color[11] //rb + gb + bb + if(red_value > MODPAINT_MAX_SECTION_COLORS) + balloon_alert(usr, "total red too high! ([red_value*100]%/[MODPAINT_MAX_SECTION_COLORS*100]%)") + return + else if(red_value < MODPAINT_MIN_SECTION_COLORS) + balloon_alert(usr, "total red too low! ([red_value*100]%/[MODPAINT_MIN_SECTION_COLORS*100]%)") + return + if(green_value > MODPAINT_MAX_SECTION_COLORS) + balloon_alert(usr, "total green too high! ([green_value*100]%/[MODPAINT_MAX_SECTION_COLORS*100]%)") + return + else if(green_value < MODPAINT_MIN_SECTION_COLORS) + balloon_alert(usr, "total green too low! ([green_value*100]%/[MODPAINT_MIN_SECTION_COLORS*100]%)") + return + if(blue_value > MODPAINT_MAX_SECTION_COLORS) + balloon_alert(usr, "total blue too high! ([blue_value*100]%/[MODPAINT_MAX_SECTION_COLORS*100]%)") + return + else if(blue_value < MODPAINT_MIN_SECTION_COLORS) + balloon_alert(usr, "total blue too low! ([blue_value*100]%/[MODPAINT_MIN_SECTION_COLORS*100]%)") + return + for(var/color_value in total_colors) + total_color_value += color_value + if(color_value > MODPAINT_MAX_COLOR_VALUE) + balloon_alert(usr, "one of colors too high! ([color_value*100]%/[MODPAINT_MAX_COLOR_VALUE*100]%") + return + else if(color_value < MODPAINT_MIN_COLOR_VALUE) + balloon_alert(usr, "one of colors too low! ([color_value*100]%/[MODPAINT_MIN_COLOR_VALUE*100]%") + return + if(total_color_value > MODPAINT_MAX_OVERALL_COLORS) + balloon_alert(usr, "total colors too high! ([total_color_value*100]%/[MODPAINT_MAX_OVERALL_COLORS*100]%)") + return + else if(total_color_value < MODPAINT_MIN_OVERALL_COLORS) + balloon_alert(usr, "total colors too low! ([total_color_value*100]%/[MODPAINT_MIN_OVERALL_COLORS*100]%)") + return + editing_mod.set_mod_color(current_color) + SStgui.close_uis(src) + +/obj/item/mod/paint/proc/paint_skin(obj/item/mod/control/mod, mob/user) + if(length(mod.theme.skins) <= 1) + balloon_alert(user, "no alternate skins!") + return + var/list/skins = list() + for(var/mod_skin in mod.theme.skins) + skins[mod_skin] = image(icon = mod.icon, icon_state = "[mod_skin]-control") + var/pick = show_radial_menu(user, mod, skins, custom_check = CALLBACK(src, .proc/check_menu, mod, user), require_near = TRUE) + if(!pick) + balloon_alert(user, "no skin picked!") + return + mod.set_mod_skin(pick) + +/obj/item/mod/paint/proc/check_menu(obj/item/mod/control/mod, mob/user) + if(user.incapacitated() || !user.is_holding(src) || !mod || mod.active || mod.activating) + return FALSE + return TRUE + +#undef MODPAINT_MAX_COLOR_VALUE +#undef MODPAINT_MIN_COLOR_VALUE +#undef MODPAINT_MAX_SECTION_COLORS +#undef MODPAINT_MIN_SECTION_COLORS +#undef MODPAINT_MAX_OVERALL_COLORS +#undef MODPAINT_MIN_OVERALL_COLORS +#undef MODPAINT_MODE_RESKIN +#undef MODPAINT_MODE_REPAINT + +/obj/item/mod/skin_applier + name = "MOD skin applier" + desc = "This one-use skin applier will add a skin to MODsuits of a specific type." + icon = 'icons/obj/clothing/modsuit/mod_construction.dmi' + icon_state = "skinapplier" + var/skin = "civilian" + var/compatible_theme = /datum/mod_theme + +/obj/item/mod/skin_applier/Initialize(mapload) + . = ..() + name = "MOD [skin] skin applier" + +/obj/item/mod/skin_applier/pre_attack(atom/attacked_atom, mob/living/user, params) + if(!istype(attacked_atom, /obj/item/mod/control)) + return ..() + var/obj/item/mod/control/mod = attacked_atom + if(mod.active || mod.activating) + balloon_alert(user, "suit is active!") + return TRUE + if(!istype(mod.theme, compatible_theme)) + balloon_alert(user, "incompatible theme!") + return TRUE + mod.set_mod_skin(skin) + balloon_alert(user, "skin applied") + qdel(src) + return TRUE + +/obj/item/mod/skin_applier/honkerative + skin = "honkerative" + compatible_theme = /datum/mod_theme/syndicate diff --git a/tgstation.dme b/tgstation.dme index c84b3bad03..a866602071 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2979,6 +2979,7 @@ #include "code\modules\mod\mod_clothes.dm" #include "code\modules\mod\mod_construction.dm" #include "code\modules\mod\mod_control.dm" +#include "code\modules\mod\mod_paint.dm" #include "code\modules\mod\mod_theme.dm" #include "code\modules\mod\mod_types.dm" #include "code\modules\mod\mod_ui.dm"