diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 90864cf359..1d37f639bf 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1235,3 +1235,18 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico var/icon/I = getFlatIcon(thing) return icon2html(I, target, sourceonly = sourceonly) +/* Gives the result RGB of a RGB string after a matrix transformation. No alpha. + * Input: rr, rg, rb, gr, gg, gb, br, bg, bb, cr, cg, cb + * Output: RGB string + */ +/proc/RGBMatrixTransform(list/color, list/cm) + ASSERT(cm.len >= 9) + if(cm.len < 12) // fill in the rest + for(var/i in 1 to (12 - cm.len)) + cm += 0 + if(!islist(color)) + color = ReadRGB(color) + color[1] = color[1] * cm[1] + color[2] * cm[2] + color[3] * cm[3] + cm[10] * 255 + color[2] = color[1] * cm[4] + color[2] * cm[5] + color[3] * cm[6] + cm[11] * 255 + color[3] = color[1] * cm[7] + color[2] * cm[8] + color[3] * cm[9] + cm[12] * 255 + return rgb(color[1], color[2], color[3]) diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm index af8efd425d..59fbb4ffc0 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -177,3 +177,9 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro for(x in 1 to 4) output[offset+x] = round(A[offset+1]*B[x] + A[offset+2]*B[x+4] + A[offset+3]*B[x+8] + A[offset+4]*B[x+12]+(y==5?B[x+16]:0), 0.001) return output + +/** + * Assembles a color matrix, defaulting to identity + */ +/proc/rgb_construct_color_matrix(rr = 1, rg, rb, gr, gg = 1, gb, br, bg, bb = 1, cr, cg, cb) + return list(rr, rg, rb, gr, gg, gb, br, bg, bb, cr, cg, cb) diff --git a/code/game/machinery/colormate.dm b/code/game/machinery/colormate.dm new file mode 100644 index 0000000000..38edcd6d8a --- /dev/null +++ b/code/game/machinery/colormate.dm @@ -0,0 +1,223 @@ +/obj/machinery/gear_painter + name = "\improper Color Mate" + desc = "A machine to give your apparel a fresh new color! Recommended to use with white items for best results." + icon = 'icons/obj/vending.dmi' + icon_state = "colormate" + density = TRUE + anchored = TRUE + circuit = /obj/item/circuitboard/machine/colormate + var/obj/item/inserted + var/activecolor = "#FFFFFF" + var/list/color_matrix_last + var/matrix_mode = FALSE + /// Minimum lightness for normal mode + var/minimum_normal_lightness = 50 + /// Minimum lightness for matrix mode, tested using 4 test colors of full red, green, blue, white. + var/minimum_matrix_lightness = 75 + /// Minimum matrix tests that must pass for something to be considered a valid color (see above) + var/minimum_matrix_tests = 2 + var/list/allowed_types = list( + /obj/item/clothing, + /obj/item/storage/backpack, + /obj/item/storage/belt + ) + +/obj/machinery/gear_painter/Initialize(mapload) + . = ..() + color_matrix_last = list( + 1, 0, 0, + 0, 1, 0, + 0, 0, 1, + 0, 0, 0 + ) + +/obj/machinery/gear_painter/update_icon_state() + if(panel_open) + icon_state = "colormate_open" + else if(!is_operational()) + icon_state = "colormate_off" + else if(inserted) + icon_state = "colormate_active" + else + icon_state = "colormate" + +/obj/machinery/gear_painter/Destroy() + inserted.forceMove(drop_location()) + return ..() + +/obj/machinery/gear_painter/attackby(obj/item/I, mob/living/user) + if(inserted) + to_chat(user, "The machine is already loaded.") + return + if(default_deconstruction_screwdriver(user, "colormate_open", "colormate", I)) + return + if(default_deconstruction_crowbar(I)) + return + if(default_unfasten_wrench(user, I, 40)) + return + if(user.a_intent == INTENT_HARM) + return ..() + + if(is_type_in_list(I, allowed_types) && is_operational()) + if(!user.transferItemToLoc(I, src)) + to_chat(user, "[I] is stuck to your hand!") + return + user.visible_message("[user] inserts [I] into [src]'s receptable.") + + inserted = I + update_icon() + else + return ..() + +/obj/machinery/gear_painter/AllowDrop() + return FALSE + +/obj/machinery/gear_painter/AltClick(mob/user) + . = ..() + if(!user.CanReach(src)) + return + if(!inserted) + return + to_chat(user, "You remove [inserted] from [src]") + inserted.forceMove(drop_location()) + inserted = null + update_icon() + updateUsrDialog() + +/obj/machinery/gear_painter/ui_interact(mob/user) + if(!is_operational()) + return + user.set_machine(src) + var/list/dat = list("Color Mate Control Panel
") + if(!inserted) + dat += "No item inserted." + else + dat += "Item inserted: [inserted]
" + dat += "Matrix mode: [matrix_mode? "On" : "Off"]" + if(!matrix_mode) + dat += "Select new color.
" + dat += "Color: " + dat += "Apply new color.

" + else + // POGGERS +#define MATRIX_FIELD(field, default) " " + dat += "
" + dat += "" + dat += "[cm] is far too dark (min lightness [minimum_normal_lightness]!") + return FALSE + return TRUE + else // matrix + // We test using full red, green, blue, and white + // A predefined number of them must pass to be considered valid + var/passed = 0 +#define COLORTEST(thestring, thematrix) passed += (ReadHSV(RGBtoHSV(RGBMatrixTransform(thestring, thematrix)))[3] >= minimum_matrix_lightness) + COLORTEST("FF0000", cm) + COLORTEST("00FF00", cm) + COLORTEST("0000FF", cm) + COLORTEST("FFFFFF", cm) +#undef COLORTEST + if(passed < minimum_matrix_tests) + to_chat(user, "[english_list(color)] is not allowed (pased [passed] out of 4, minimum [minimum_matrix_tests], minimum lightness [minimum_matrix_lightness]).") + return FALSE + return TRUE diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index 8e59e91e38..4873962587 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -243,6 +243,12 @@ /obj/item/stack/sheet/glass = 1) def_components = list(/obj/item/stack/ore/bluespace_crystal = /obj/item/stack/ore/bluespace_crystal/artificial) +/obj/item/circuitboard/machine/colormate + name = "Colormate (Machine Board)" + build_path = /obj/machinery/gear_painter + req_components = list() + def_components = list() + /obj/item/circuitboard/machine/vendor name = "Custom Vendor (Machine Board)" desc = "You can turn the \"brand selection\" dial using a screwdriver." diff --git a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm index e0702be689..81b16d1118 100644 --- a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm +++ b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm @@ -163,3 +163,10 @@ category = list ("Misc. Machinery") departmental_flags = DEPARTMENTAL_FLAG_ALL +/datum/design/board/colormate + name = "ColorMate" + desc = "This machine lets you paint your gear." + id = "colormate" + build_path = /obj/item/circuitboard/machine/colormate + category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL diff --git a/code/modules/research/techweb/nodes/engineering_nodes.dm b/code/modules/research/techweb/nodes/engineering_nodes.dm index d024823c85..f4dce58740 100644 --- a/code/modules/research/techweb/nodes/engineering_nodes.dm +++ b/code/modules/research/techweb/nodes/engineering_nodes.dm @@ -8,7 +8,7 @@ design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin", "atmosalerts", "atmos_control", "recycler", "autolathe", "autolathe_secure", "high_micro_laser", "nano_mani", "mesons", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod", "apc_control", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine", "rcd_ammo","oxygen_tank", - "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt") + "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "colormate") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 6000) /datum/techweb_node/adv_engi diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index d8f5c1d334..c70fe9d44e 100644 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 72ab44c48a..bac0ffbdd3 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -793,6 +793,7 @@ #include "code\game\machinery\buttons.dm" #include "code\game\machinery\cell_charger.dm" #include "code\game\machinery\cloning.dm" +#include "code\game\machinery\colormate.dm" #include "code\game\machinery\constructable_frame.dm" #include "code\game\machinery\cryopod.dm" #include "code\game\machinery\dance_machine.dm"