diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index ea3977e3246..6f664ff848a 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -507,3 +507,8 @@ GLOBAL_LIST_INIT(heretic_path_to_color, list( #define CLIENT_COLOR_TEMPORARY_PRIORITY 5 // Temporary flashing effects #define CLIENT_COLOR_IMPORTANT_PRIORITY 6 // Gameplay important hints signifying antag status or near-death, should be always shown #define CLIENT_COLOR_OVERRIDE_PRIORITY 7 // For effects that are meant to mask all others for technical reasons + +//Luma coefficients suggested for HDTVs. If you change these, make sure they add up to 1. +#define LUMA_R 0.213 +#define LUMA_G 0.715 +#define LUMA_B 0.072 diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index 2e66a90f93c..ccd883011ad 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -27,6 +27,8 @@ //Special properties ///If the holder a sealed container - Used if you don't want reagent contents boiling out (plasma, specifically, in which case it only bursts out when at ignition temperatures) #define SEALED_CONTAINER (1<<10) +/// Prevents spilling and splashing but does prevent pouring and drinking reagents like the badly named spillable var. +#define SMART_CAP (1<<11) // Is an open container for all intents and purposes. #define OPENCONTAINER (REFILLABLE | DRAINABLE | TRANSPARENT) diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm index 777b4415a9d..90ad458e32a 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -1,8 +1,3 @@ -//Luma coefficients suggested for HDTVs. If you change these, make sure they add up to 1. -#define LUMA_R 0.213 -#define LUMA_G 0.715 -#define LUMA_B 0.072 - /// Datum which stores information about a matrix decomposed with decompose(). /datum/decompose_matrix ///? @@ -221,7 +216,3 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro stack_trace(message) return COLOR_MATRIX_IDENTITY CRASH(message) - -#undef LUMA_R -#undef LUMA_G -#undef LUMA_B diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index 453f293ce65..d249a40d806 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -220,22 +220,28 @@ GLOBAL_LIST_INIT(uncommon_loot, list(//uncommon: useful items /obj/item/stack/medical/mesh = 1, /obj/item/stack/medical/suture = 1, /obj/item/stack/medical/bandage = 1, - ) = 1, + ) = 4, list(//medical chems /obj/item/reagent_containers/cup/bottle/multiver = 1, /obj/item/reagent_containers/hypospray/medipen = 1, /obj/item/reagent_containers/syringe/convermol = 1, - ) = 1, + ) = 4, list(//drinks /obj/item/reagent_containers/cup/glass/bottle/vodka = 1, /obj/item/reagent_containers/cup/glass/drinkingglass/filled/nuka_cola = 1, /obj/item/reagent_containers/cup/soda_cans/grey_bull = 1, - ) = 1, + ) = 4, list(//sprayers /obj/item/reagent_containers/spray = 1, /obj/item/watertank = 1, /obj/item/watertank/janitor = 1, - ) = 1, + ) = 4, + list(//other chems + /obj/item/reagent_containers/cup/jerrycan/oil = 2, //Not the most exciting reagent, but a staple. And you get a cool can for your pyrotechnics. + /obj/item/reagent_containers/cup/jerrycan/space_cleaner = 2, //If you can't find the janitor, the medbay might also appreciate some readymade cleaner. + /obj/item/reagent_containers/cup/jerrycan/sus = 1, //what assitant wouldn't like a vibrant jug o' phlog? + /obj/item/reagent_containers/cup/jerrycan/diethylamine = 1, //Im sure the botanist would appreciate it, but it is also really cool for maintenance science projects. + ) = 2, ) = 8, list(//food diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 47d75d9c3c6..43842d75978 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -41,6 +41,8 @@ var/fill_icon = 'icons/obj/medical/reagent_fillings.dmi' ///The sound this container makes when picked up, dropped if there is liquid inside. var/reagent_container_liquid_sound = null + ///If we want to the contrast of the reagent overlay if the reagent mix color is very dark. + var/adjust_color_contrast = FALSE /obj/item/reagent_containers/apply_fantasy_bonuses(bonus) . = ..() @@ -128,7 +130,7 @@ /// Tries to splash the target, called when right-clicking with a reagent container. /obj/item/reagent_containers/proc/try_splash(mob/user, atom/target) - if (!spillable) + if (!spillable || reagent_flags & SMART_CAP) return FALSE if (!reagents?.total_volume) @@ -209,7 +211,7 @@ . = TRUE /obj/item/reagent_containers/proc/SplashReagents(atom/target, datum/thrownthing/throwingdatum, override_spillable = FALSE) - if(!reagents || !reagents.total_volume || (!spillable && !override_spillable)) + if(!reagents || !reagents.total_volume || (!spillable && !override_spillable) || reagent_flags & SMART_CAP) return var/mob/thrown_by = throwingdatum.get_thrower() @@ -286,7 +288,56 @@ if(threshold <= percent && percent < threshold_end) filling.icon_state = "[fill_name][fill_icon_thresholds[i]]" - filling.color = mix_color_from_reagents(reagents.reagent_list) + + if(!adjust_color_contrast) + filling.color = mix_color_from_reagents(reagents.reagent_list) + . += filling + return + + var/list/mix_colors = rgb2num(mix_color_from_reagents(reagents.reagent_list)) + //reagent color red + var/float_r = mix_colors[1] / 255 + //reagent color green + var/float_g = mix_colors[2] / 255 + //reagent color blue + var/float_b = mix_colors[3] / 255 + //reagent color alpha + var/float_a = mix_colors.len > 3 ? mix_colors[4] / 255 : 1 + + //value, used to make modifications depending on if our reagent color is light or dark. + var/float_v = (float_r + float_g + float_b) / 3 + + //max result of float_b - float_v is 0.6666 so we multiply with 1.5 to get something close to 1 at max blueness. + var/blue_mod = max(float_b - float_v, 0) * 1.5 + + //red multiplier + var/red_scale = 1.6 + //green_multiplier + var/green_scale = 1.5 + //blue scale + var/blue_scale = 1.1 * (1 + 0.60 * blue_mod) + + //additive red - modifies red across the board by val * 255 + var/red_base = -0.07 - (0.035 * float_v) + //additive green - modifies green across the board by val * 255 + var/green_base = -0.06 - (0.03 * float_v) + //additive blue - modifies blue across the board by val * 255 + var/blue_base = 0.10 - (0.050 * float_v) - (0.40 * blue_mod) + + var/list/reagent_color_and_contrast_matrix = list( + //Red - RR, RG, RB, RA + float_r * red_scale, 0, 0, 0, + //Green - GR - GG - GB - GA + 0, float_g * green_scale, 0, 0, + ///Blue - BR, BG, BB, BA + 0.25 * blue_mod, 0.33 * blue_mod, float_b * blue_scale, 0, + //Alpha - AR, AG, AB, AA + 0, 0, 0, float_a, + //Constant - CR, CG, CB, CA + red_base, green_base, blue_base, 0) + + filling.color = reagent_color_and_contrast_matrix + . += filling /obj/item/reagent_containers/dropped(mob/user, silent) diff --git a/code/modules/reagents/reagent_containers/jerrycan.dm b/code/modules/reagents/reagent_containers/jerrycan.dm new file mode 100644 index 00000000000..e3b97e82b99 --- /dev/null +++ b/code/modules/reagents/reagent_containers/jerrycan.dm @@ -0,0 +1,188 @@ +#define LABEL_TEXT "text" +#define LABEL_TEXT_OLD "old" +#define LABEL_INFLAMMABLE "inflammable" +#define LABEL_NT "nt" +#define LABEL_NT_MINI "nt_mini" +#define LABEL_SUSPICIOUS "sus" +#define LABEL_SUSPICIOUS_BLACK "sus_black" +#define LABEL_SUSPICIOUS_MINI "sus_mini" +#define LABEL_SUSPICIOUS_MINI_BLACK "sus_mini_black" +#define LABEL_EZ_NUTRIENT "ez" +#define LABEL_ROBUST_HARVEST "robust" +#define LABEL_LEFT_4_ZED "l4z" +#define LABEL_SPACE_CLEANER "space_cleaner" + +#define CAP_BLACK "black" +#define CAP_WHITE "white" +#define CAP_RED "red" +#define CAP_GREEN "green" +#define CAP_BLUE "blue" + +/** +* The jerrycan is not only a flavourful, setting appropriate way to store reagents, it offers several design benefits due to its unique combination of high roundstart capacity and bulky size. + +* It prevents one coworker from hogging a shared reagent container. + +* The high volume eases grinding and mixing without enabling big grenade creation. + +* It allows reagents to be stolen or borrowed due to being stored outside the safety of an inventory. + +* The highly visible inhand sprite allows you to see who is holding or transporting reagents. + +* The smart cap flag allows you to throw the container without spilling. + +* It reduces the tedium associated with dispensing and throwing away botany nutrient bottles, encouraging refilling. + +* Bulky size prevent players from looting the can unless it is something they really want. + +* Comes with a large number of visual customization options for coders who with to add new variants. +**/ +/obj/item/reagent_containers/cup/jerrycan + name = "plastic jerrycan" + desc = "A voluminous container made from the finest HDPE.\n\nNow with integrated Smart Cap™ technology to prevent expensive spills when handling industrial liquids." + icon = 'icons/obj/medical/chemical.dmi' + righthand_file = 'icons/mob/inhands/items/chemistry_righthand.dmi' + lefthand_file = 'icons/mob/inhands/items/chemistry_lefthand.dmi' + icon_state = "jerrycan" + inhand_icon_state = "jerrycan" + base_icon_state = "jerrycan" + custom_materials = list(/datum/material/plastic=SHEET_MATERIAL_AMOUNT*2) + w_class = WEIGHT_CLASS_BULKY + volume = 200 + obj_flags = UNIQUE_RENAME + reagent_flags = OPENCONTAINER | SMART_CAP + fill_icon_thresholds = list(0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200) + possible_transfer_amounts = list(5, 10, 15, 30, 50, 100, 200) + adjust_color_contrast = TRUE + /** + * If we want the can to have a label. Use the defines at the top, add new ones if you add new labels. + + * WARNING: How good any particular label looks is highly dependent on the colour of the reagent in the can. + + * Exercise good judgement and choose a label with enough contrast for the intended contents. + **/ + var/label_type + ///Different cap colours. + var/cap_type + ///You can use this var to tone down the strength of the highlight for less shiny types of plastic. + var/highlight_strenght = 1.0 + +/obj/item/reagent_containers/cup/jerrycan/update_overlays() + . = ..() + + var/mutable_appearance/highlight = mutable_appearance(icon, "[base_icon_state]_highlight") + highlight.opacity = highlight.opacity * highlight_strenght + . += highlight + + if(label_type) + . += mutable_appearance(icon, "[base_icon_state]_label_[label_type]") + + if(cap_type) + . += mutable_appearance(icon, "[base_icon_state]_cap_[cap_type]") + +/obj/item/reagent_containers/cup/jerrycan/worn_overlays(mutable_appearance/standing, isinhands, icon_file) + . = ..() + if(!isinhands) + return + if(fill_icon_thresholds && reagents.total_volume) + var/mutable_appearance/inhand_reagent_filling = mutable_appearance(icon_file, "[inhand_icon_state]_reagent_filling") + inhand_reagent_filling.color = mix_color_from_reagents(reagents.reagent_list) + . += inhand_reagent_filling + if(cap_type) + . += mutable_appearance(icon_file, "[base_icon_state]_cap_[cap_type]") + +/obj/item/reagent_containers/cup/jerrycan/Initialize(mapload) + . = ..() + update_appearance() + +/obj/item/reagent_containers/cup/jerrycan/opaque + fill_icon_thresholds = null + reagent_flags = REFILLABLE | DRAINABLE | SMART_CAP + highlight_strenght = 0.75 + +/obj/item/reagent_containers/cup/jerrycan/opaque/yellow + icon_state = "jerrycan_yellow" + inhand_icon_state = "jerrycan_yellow" + +/obj/item/reagent_containers/cup/jerrycan/eznutriment + name = "E-Z-Nutrient™ can" + desc = "A large container presumably filled to the brim with 'E-Z-Nutrient'-brand plant nutrient. It can't get easier than this." + label_type = LABEL_EZ_NUTRIENT + list_reagents = list(/datum/reagent/plantnutriment/eznutriment = 200) + custom_price = PAYCHECK_CREW * 1 + +/obj/item/reagent_containers/cup/jerrycan/left4zed + name = "Left 4 Zed™ can" + desc = "A large container labled 'Left 4 Zed' plant nutrient. A good choice when the stronger stuff is unavailable." + label_type = LABEL_LEFT_4_ZED + cap_type = CAP_GREEN + list_reagents = list(/datum/reagent/plantnutriment/left4zednutriment = 200) + custom_price = PAYCHECK_CREW * 1.2 + +/obj/item/reagent_containers/cup/jerrycan/robustharvest + name = "Robust Harvest™ can" + desc = "A large container labled 'Robust Harvest' plant nutrient. Only trust 'Robust Harvest' for a robust yield." + label_type = LABEL_ROBUST_HARVEST + list_reagents = list(/datum/reagent/plantnutriment/robustharvestnutriment = 200) + custom_price = PAYCHECK_CREW * 1.5 + +/obj/item/reagent_containers/cup/jerrycan/ammonia + name = "NT-AG ammonia can" + desc = "A large container labled 'NT-AG' anhydrous ammonia. A warning label reads: Store separately from chlorine-based cleaning products!" + label_type = LABEL_TEXT + cap_type = CAP_BLUE + list_reagents = list(/datum/reagent/ammonia = 200) + +/obj/item/reagent_containers/cup/jerrycan/diethylamine + name = "NT-AG diethylamine can" + label_type = LABEL_TEXT_OLD + cap_type = CAP_GREEN + desc = "A large container labled 'NT-AG' diethylamine. A disclaimer written in bold letters reads: FOR AGRICULTURAL USE ONLY. RESALE PROHIBITED." + list_reagents = list(/datum/reagent/diethylamine = 200) + +/obj/item/reagent_containers/cup/jerrycan/sus + name = "DonkCo great value phlogiston can" + label_type = LABEL_SUSPICIOUS_BLACK + desc = "A large can of phlogiston, ostensibly for removing dried out Donk-pocket™ filling from the production line." + list_reagents = list(/datum/reagent/phlogiston = 200) + +/obj/item/reagent_containers/cup/jerrycan/oil + name = "oil can" + label_type = LABEL_INFLAMMABLE + cap_type = CAP_RED + desc = "A large can full of synthetic lubricating oil." + list_reagents = list(/datum/reagent/fuel/oil = 200) + +/obj/item/reagent_containers/cup/jerrycan/space_cleaner + name = "BLAM!™-brand non-foaming space cleaner can" + label_type = LABEL_SPACE_CLEANER + cap_type = CAP_RED + desc = "Stubborn stains, grease and grime got you cornered? No duty to retreat when you got BLAM!™ on your side!\nBLAM!™ - A WaffleCo product." + list_reagents = list(/datum/reagent/space_cleaner = 200) + +/obj/item/reagent_containers/cup/jerrycan/milk + name = "milk jug" + label_type = LABEL_NT_MINI + cap_type = CAP_BLUE + desc = "A jug of most wholesome milk." + list_reagents = list(/datum/reagent/consumable/milk = 200) + + +#undef LABEL_TEXT +#undef LABEL_TEXT_OLD +#undef LABEL_INFLAMMABLE +#undef LABEL_NT +#undef LABEL_NT_MINI +#undef LABEL_SUSPICIOUS +#undef LABEL_SUSPICIOUS_BLACK +#undef LABEL_SUSPICIOUS_MINI +#undef LABEL_SUSPICIOUS_MINI_BLACK +#undef LABEL_EZ_NUTRIENT +#undef LABEL_ROBUST_HARVEST +#undef LABEL_LEFT_4_ZED +#undef LABEL_SPACE_CLEANER +#undef CAP_BLACK +#undef CAP_WHITE +#undef CAP_RED +#undef CAP_GREEN +#undef CAP_BLUE diff --git a/code/modules/research/designs/autolathe/multi-department_designs.dm b/code/modules/research/designs/autolathe/multi-department_designs.dm index 941dda328cd..a1a1037b2e2 100644 --- a/code/modules/research/designs/autolathe/multi-department_designs.dm +++ b/code/modules/research/designs/autolathe/multi-department_designs.dm @@ -269,6 +269,18 @@ build_path = /obj/item/reagent_containers/cup/beaker/large departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SERVICE | DEPARTMENT_BITFLAG_SCIENCE +/datum/design/jerrycan + name = "Jerrycan" + id = "jerrycan" + build_type = AUTOLATHE | PROTOLATHE | AWAY_LATHE + materials = list(/datum/material/plastic =SHEET_MATERIAL_AMOUNT * 2) + category = list( + RND_CATEGORY_INITIAL, + RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_CHEMISTRY, + ) + build_path = /obj/item/reagent_containers/cup/jerrycan + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SERVICE | DEPARTMENT_BITFLAG_SCIENCE + /datum/design/igniter name = "Igniter" id = "igniter" diff --git a/code/modules/research/techweb/nodes/medbay_nodes.dm b/code/modules/research/techweb/nodes/medbay_nodes.dm index 897a2edf18e..1c079b66762 100644 --- a/code/modules/research/techweb/nodes/medbay_nodes.dm +++ b/code/modules/research/techweb/nodes/medbay_nodes.dm @@ -29,6 +29,7 @@ "dropper", "pillbottle", "xlarge_beaker", + "jerrycan", ) experiments_to_unlock = list( /datum/experiment/autopsy/human, diff --git a/code/modules/vending/nutrimax.dm b/code/modules/vending/nutrimax.dm index de08b8c458f..d7b3a0aaa5c 100644 --- a/code/modules/vending/nutrimax.dm +++ b/code/modules/vending/nutrimax.dm @@ -10,9 +10,9 @@ products = list( /obj/item/cultivator = 3, /obj/item/plant_analyzer = 4, - /obj/item/reagent_containers/cup/bottle/nutrient/ez = 30, - /obj/item/reagent_containers/cup/bottle/nutrient/l4z = 20, - /obj/item/reagent_containers/cup/bottle/nutrient/rh = 10, + /obj/item/reagent_containers/cup/jerrycan/eznutriment = 6, + /obj/item/reagent_containers/cup/jerrycan/left4zed = 4, + /obj/item/reagent_containers/cup/jerrycan/robustharvest = 3, /obj/item/reagent_containers/spray/pestspray = 20, /obj/item/reagent_containers/syringe = 5, /obj/item/secateurs = 3, diff --git a/icons/mob/inhands/items/chemistry_lefthand.dmi b/icons/mob/inhands/items/chemistry_lefthand.dmi new file mode 100644 index 00000000000..8bd93ab5f2c Binary files /dev/null and b/icons/mob/inhands/items/chemistry_lefthand.dmi differ diff --git a/icons/mob/inhands/items/chemistry_righthand.dmi b/icons/mob/inhands/items/chemistry_righthand.dmi new file mode 100644 index 00000000000..5efadc4a482 Binary files /dev/null and b/icons/mob/inhands/items/chemistry_righthand.dmi differ diff --git a/icons/obj/medical/chemical.dmi b/icons/obj/medical/chemical.dmi index c1fa2d403a4..9b785b3ed60 100644 Binary files a/icons/obj/medical/chemical.dmi and b/icons/obj/medical/chemical.dmi differ diff --git a/icons/obj/medical/reagent_fillings.dmi b/icons/obj/medical/reagent_fillings.dmi index 45de9b065de..f3477820dbe 100644 Binary files a/icons/obj/medical/reagent_fillings.dmi and b/icons/obj/medical/reagent_fillings.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 74413654c02..96749b6ea34 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6064,6 +6064,7 @@ #include "code\modules\reagents\reagent_containers\condiment.dm" #include "code\modules\reagents\reagent_containers\dropper.dm" #include "code\modules\reagents\reagent_containers\hypospray.dm" +#include "code\modules\reagents\reagent_containers\jerrycan.dm" #include "code\modules\reagents\reagent_containers\medigel.dm" #include "code\modules\reagents\reagent_containers\misc.dm" #include "code\modules\reagents\reagent_containers\patch.dm"