Skip to content

Commit

Permalink
https://github.com/tgstation/tgstation/pull/65445
Browse files Browse the repository at this point in the history
  • Loading branch information
Tsar-Salat committed Aug 29, 2024
1 parent 354b0e7 commit 78531b8
Show file tree
Hide file tree
Showing 10 changed files with 406 additions and 61 deletions.
1 change: 1 addition & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -3314,6 +3314,7 @@
#include "code\modules\mod\mod_construction.dm"
#include "code\modules\mod\mod_control.dm"
#include "code\modules\mod\mod_core.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"
Expand Down
4 changes: 3 additions & 1 deletion code/game/gamemodes/clown_ops/clown_ops.dm
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
id = /obj/item/card/id/syndicate
backpack_contents = list(/obj/item/storage/box/syndie=1,\
/obj/item/knife/combat/survival,
/obj/item/reagent_containers/spray/waterflower/lube)
/obj/item/reagent_containers/spray/waterflower/lube,
/obj/item/mod/skin_applier/honkerative,
)
implants = list(/obj/item/implant/sad_trombone)

uplink_type = /obj/item/uplink/clownop
Expand Down
6 changes: 0 additions & 6 deletions code/modules/mod/mod_construction.dm
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,6 @@
/obj/item/mod/construction/plating/cosmohonk
theme = /datum/mod_theme/cosmohonk

/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"
Expand Down
53 changes: 20 additions & 33 deletions code/modules/mod/mod_control.dm
Original file line number Diff line number Diff line change
Expand Up @@ -372,14 +372,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.GetID())
return TRUE
Expand Down Expand Up @@ -521,23 +513,6 @@
return
picked_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
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) || get_charge() < 1)
return FALSE
Expand Down Expand Up @@ -639,6 +614,21 @@
balloon_alert(wearer, "no power!")
toggle_activate(wearer, force_deactivate = TRUE)

/obj/item/mod/control/proc/set_mod_color(new_color)
var/list/all_parts = mod_parts.Copy() + 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)
skin = new_skin
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()

/obj/item/mod/control/proc/on_exit(datum/source, atom/movable/part, direction)
SIGNAL_HANDLER

Expand All @@ -650,10 +640,10 @@
return
if(part.loc == wearer)
return
if(modules.Find(part))
if(part in modules)
uninstall(part)
return
if(mod_parts.Find(part))
if(part in mod_parts)
conceal(wearer, part)
if(active)
INVOKE_ASYNC(src, PROC_REF(toggle_activate), wearer, TRUE)
Expand All @@ -665,14 +655,11 @@
if(slowdown_inactive <= 0)
to_chat(user, "<span class='warning'>[src] has already been coated with red, that's as fast as it'll go!</span>")
return SPEED_POTION_STOP
if(wearer)
to_chat(user, "<span class='warning'>It's too dangerous to smear [speed_potion] on [src] while it's on someone!</span>")
if(active)
to_chat(user, "<span class='warning'>It's too dangerous to smear [speed_potion] on [src] while it's on active!</span>")
return SPEED_POTION_STOP
to_chat(user, "<span class='notice'>You slather the red gunk over [src], making it faster.</span>")
var/list/all_parts = mod_parts.Copy() + src
for(var/obj/item/part as anything in all_parts)
part.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
part.add_atom_colour("#FF0000", FIXED_COLOUR_PRIORITY)
set_mod_color("#FF0000")
slowdown_inactive = 0
slowdown_active = 0
update_speed()
Expand Down
196 changes: 196 additions & 0 deletions code/modules/mod/mod_paint.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
#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

/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/color_matrix_proxy_view/proxy_view
var/list/current_color

/obj/item/mod/paint/Initialize(mapload)
. = ..()
current_color = color_matrix_identity()

/obj/item/mod/paint/examine(mob/user)
. = ..()
. += "span class='notice'<b>Left-click</b> a MODsuit to change skin.</span>"
. += "span class='notice'<b>Right-click</b> a MODsuit to recolor.</span>"

/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 TRUE
paint_skin(mod, user)

/* Not usable until combat mode or alternative fire
/obj/item/mod/paint/pre_attack_secondary(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(editing_mod)
return TRUE
editing_mod = mod
proxy_view = new()
proxy_view.appearance = editing_mod.appearance
proxy_view.color = null
proxy_view.register_to_client(user.client)
ui_interact(user)
return TRUE
*/

/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

/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
Loading

0 comments on commit 78531b8

Please sign in to comment.