diff --git a/_maps/map_files/generic/CentCom_skyrat_z2.dmm b/_maps/map_files/generic/CentCom_skyrat_z2.dmm index 73cd62565fb..2a8bb65bacf 100644 --- a/_maps/map_files/generic/CentCom_skyrat_z2.dmm +++ b/_maps/map_files/generic/CentCom_skyrat_z2.dmm @@ -3568,7 +3568,7 @@ "aSn" = ( /obj/structure/table, /obj/machinery/light/directional/west{ - bulb_colour = "#e8eaff " + bulb_colour = "#e8eaff" }, /obj/item/soap, /obj/item/soap, diff --git a/code/__DEFINES/gradient.dm b/code/__DEFINES/gradient.dm index 6a920e322b0..573a339880b 100644 --- a/code/__DEFINES/gradient.dm +++ b/code/__DEFINES/gradient.dm @@ -1,3 +1,4 @@ // spacemandmm doesn't really implement gradient() right, so let's just handle that here yeah? +#define rgb_gradient(index, args...) UNLINT(gradient(args, index)) #define hsl_gradient(index, args...) UNLINT(gradient(args, space = COLORSPACE_HSL, index)) #define hsv_gradient(index, args...) UNLINT(gradient(args, space = COLORSPACE_HSV, index)) diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index 48a27ea88a4..5ea431a8cc1 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -102,23 +102,14 @@ GLOBAL_LIST_INIT(em_block_color, EM_BLOCK_COLOR) /// A globaly cached version of [EM_MASK_MATRIX] for quick access. GLOBAL_LIST_INIT(em_mask_matrix, EM_MASK_MATRIX) -/// Returns the red part of a #RRGGBB hex sequence as number -#define GETREDPART(hexa) hex2num(copytext(hexa, 2, 4)) - -/// Returns the green part of a #RRGGBB hex sequence as number -#define GETGREENPART(hexa) hex2num(copytext(hexa, 4, 6)) - -/// Returns the blue part of a #RRGGBB hex sequence as number -#define GETBLUEPART(hexa) hex2num(copytext(hexa, 6, 8)) - /// Parse the hexadecimal color into lumcounts of each perspective. #define PARSE_LIGHT_COLOR(source) \ do { \ if (source.light_color != COLOR_WHITE) { \ - var/__light_color = source.light_color; \ - source.lum_r = GETREDPART(__light_color) / 255; \ - source.lum_g = GETGREENPART(__light_color) / 255; \ - source.lum_b = GETBLUEPART(__light_color) / 255; \ + var/list/color_parts = rgb2num(source.light_color); \ + source.lum_r = color_parts[1] / 255; \ + source.lum_g = color_parts[2] / 255; \ + source.lum_b = color_parts[3] / 255; \ } else { \ source.lum_r = 1; \ source.lum_g = 1; \ diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 8cdcc29bb47..77900ac18d4 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -500,9 +500,6 @@ #define ROBOTIC_BRUTE_EXAMINE_TEXT "denting" #define ROBOTIC_BURN_EXAMINE_TEXT "charring" -// If a mob has a higher threshold than this, the icon shown will be increased to the big fire icon. -#define MOB_BIG_FIRE_STACK_THRESHOLD 3 - #define GRAB_PIXEL_SHIFT_PASSIVE 6 #define GRAB_PIXEL_SHIFT_AGGRESSIVE 12 #define GRAB_PIXEL_SHIFT_NECK 16 @@ -781,8 +778,8 @@ GLOBAL_LIST_INIT(human_heights_to_offsets, list( #define WOUND_LAYER 3 /// Blood cult ascended halo layer, because there's currently no better solution for adding/removing #define HALO_LAYER 2 -/// Fire layer when you're on fire -#define FIRE_LAYER 1 +/// The highest most layer for mob overlays. Unused +#define HIGHEST_LAYER 1 #define UPPER_BODY "upper body" #define LOWER_BODY "lower body" @@ -823,7 +820,7 @@ GLOBAL_LIST_INIT(layers_to_offset, list( // BODY_BEHIND_LAYER (external organs like wings) // BODY_FRONT_LAYER (external organs like wings) // DAMAGE_LAYER (full body) - // FIRE_LAYER (full body) + // HIGHEST_LAYER (full body) // UNIFORM_LAYER (full body) // WOUND_LAYER (full body) )) diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 768f1faa514..4e901c4ba2c 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -31,6 +31,11 @@ /// If the incapacitated status effect will ignore a mob being agressively grabbed #define IGNORE_GRAB (1<<2) +/// Maxamounts of fire stacks a mob can get +#define MAX_FIRE_STACKS 20 +/// If a mob has a higher threshold than this, the icon shown will be increased to the big fire icon. +#define MOB_BIG_FIRE_STACK_THRESHOLD 3 + // Grouped effect sources, see also code/__DEFINES/traits.dm #define STASIS_MACHINE_EFFECT "stasis_machine" diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 867f567be00..4e0a0f5b8f9 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -353,8 +353,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_TUMOR_SUPPRESSED "brain_tumor_suppressed" /// Prevents hallucinations from the hallucination brain trauma (RDS) #define TRAIT_RDS_SUPPRESSED "rds_suppressed" -/// mobs that have this trait cannot be extinguished -#define TRAIT_PERMANENTLY_ONFIRE "permanently_onfire" +/// Mobs that have this trait cannot be extinguished +#define TRAIT_NO_EXTINGUISH "no_extinguish" /// Indicates if the mob is currently speaking with sign language #define TRAIT_SIGN_LANG "sign_language" /// This mob is able to use sign language over the radio. diff --git a/code/__HELPERS/colors.dm b/code/__HELPERS/colors.dm index ad83dce8201..9f17d4c0028 100644 --- a/code/__HELPERS/colors.dm +++ b/code/__HELPERS/colors.dm @@ -19,13 +19,8 @@ /// Given a color in the format of "#RRGGBB" or "#RRGGBBAA", gives back a 4 entry list with the number values of each /proc/split_color(color) - var/list/output = list() - output += hex2num(copytext(color, 2, 4)) - output += hex2num(copytext(color, 4, 6)) - output += hex2num(copytext(color, 6, 8)) - if(length(color) == 9) - output += hex2num(copytext(color, 8, 10)) - else + var/list/output = rgb2num(color) + if(length(output) == 3) output += 255 return output @@ -49,10 +44,8 @@ CRASH("Given non-HTML argument!") else if(length_char(HTMLstring) != 7) CRASH("Given non-hex symbols in argument!") - var/textr = copytext(HTMLstring, 2, 4) - var/textg = copytext(HTMLstring, 4, 6) - var/textb = copytext(HTMLstring, 6, 8) - return rgb(255 - hex2num(textr), 255 - hex2num(textg), 255 - hex2num(textb)) + var/list/color = rgb2num(HTMLstring) + return rgb(255 - color[1], 255 - color[2], 255 - color[3]) ///Flash a color on the passed mob /proc/flash_color(mob_or_client, flash_color="#960000", flash_time=20) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 2d8fc3bf684..0b9de1df37e 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1,14 +1,22 @@ /* IconProcs README + A BYOND library for manipulating icons and colors + by Lummox JR + version 1.0 + The IconProcs library was made to make a lot of common icon operations much easier. BYOND's icon manipulation routines are very capable but some of the advanced capabilities like using alpha transparency can be unintuitive to beginners. + CHANGING ICONS + Several new procs have been added to the /icon datum to simplify working with icons. To use them, remember you first need to setup an /icon var like so: + GLOBAL_DATUM_INIT(my_icon, /icon, new('iconfile.dmi')) + icon/ChangeOpacity(amount = 1) A very common operation in DM is to try to make an icon more or less transparent. Making an icon more transparent is usually much easier than making it less so, however. This proc basically is a frontend @@ -40,58 +48,53 @@ icon/UseAlphaMask(mask, mode) Sometimes you may want to take the alpha values from one icon and use them on a different icon. This proc will do that. Just supply the icon whose alpha mask you want to use, and src will change so it has the same colors as before but uses the mask for opacity. + COLOR MANAGEMENT AND HSV + RGB isn't the only way to represent color. Sometimes it's more useful to work with a model called HSV, which stands for hue, saturation, and value. + * The hue of a color describes where it is along the color wheel. It goes from red to yellow to green to cyan to blue to magenta and back to red. * The saturation of a color is how much color is in it. A color with low saturation will be more gray, and with no saturation at all it is a shade of gray. * The value of a color determines how bright it is. A high-value color is vivid, moderate value is dark, and no value at all is black. -Just as BYOND uses "#rrggbb" to represent RGB values, a similar format is used for HSV: "#hhhssvv". The hue is three -hex digits because it ranges from 0 to 0x5FF. - * 0 to 0xFF - red to yellow - * 0x100 to 0x1FF - yellow to green - * 0x200 to 0x2FF - green to cyan - * 0x300 to 0x3FF - cyan to blue - * 0x400 to 0x4FF - blue to magenta - * 0x500 to 0x5FF - magenta to red -Knowing this, you can figure out that red is "#000ffff" in HSV format, which is hue 0 (red), saturation 255 (as colorful as possible), -value 255 (as bright as possible). Green is "#200ffff" and blue is "#400ffff". -More than one HSV color can match the same RGB color. + +While rgb is typically stored in the #rrggbb" format (with optional "aa" on the end), HSV never needs to be displayed. +Most procs that work in HSV "space" will simply accept RGB inputs and convert them in place using rgb2num(color, space = COLORSPACE_HSV). + +That said, if you want to manually modify these values rgb2hsv() will hand you back a list in the format list(hue, saturation, value, alpha). +Converting back is simple, just a hsv2rgb(hsv) call + +Hue ranges from 0 to 360 (it's in degrees of a color wheel) +Saturation ranges from 0 to 100 +Value ranges from 0 to 100 + +Knowing this, you can figure out that red is list(0, 100, 100) in HSV format, which is hue 0 (red), saturation 100 (as colorful as possible), +value 255 (as bright as possible). Green is list(120, 100, 100) and blue is list(240, 100, 100). + +It is worth noting that while we do not have helpers for them currently, these same ideas apply to all of byond's color spaces +HSV (hue saturation value), HSL (hue satriation luminosity) and HCY (hue chroma luminosity) + Here are some procs you can use for color management: -ReadRGB(rgb) - Takes an RGB string like "#ffaa55" and converts it to a list such as list(255,170,85). If an RGBA format is used - that includes alpha, the list will have a fourth item for the alpha value. -hsv(hue, sat, val, apha) - Counterpart to rgb(), this takes the values you input and converts them to a string in "#hhhssvv" or "#hhhssvvaa" - format. Alpha is not included in the result if null. -ReadHSV(rgb) - Takes an HSV string like "#100FF80" and converts it to a list such as list(256,255,128). If an HSVA format is used that - includes alpha, the list will have a fourth item for the alpha value. -RGBtoHSV(rgb) - Takes an RGB or RGBA string like "#ffaa55" and converts it into an HSV or HSVA color such as "#080aaff". -HSVtoRGB(hsv) - Takes an HSV or HSVA string like "#080aaff" and converts it into an RGB or RGBA color such as "#ff55aa". + BlendRGB(rgb1, rgb2, amount) Blends between two RGB or RGBA colors using regular RGB blending. If amount is 0, the first color is the result; if 1, the second color is the result. 0.5 produces an average of the two. Values outside the 0 to 1 range are allowed as well. - The returned value is an RGB or RGBA color. -BlendHSV(hsv1, hsv2, amount) - Blends between two HSV or HSVA colors using HSV blending, which tends to produce nicer results than regular RGB + Returns an RGB or RGBA string +BlendHSV(rgb1, rgb2, amount) + Blends between two RGB or RGBA colors using HSV blending, which tends to produce nicer results than regular RGB blending because the brightness of the color is left intact. If amount is 0, the first color is the result; if 1, the second color is the result. 0.5 produces an average of the two. Values outside the 0 to 1 range are allowed as well. - The returned value is an HSV or HSVA color. -BlendRGBasHSV(rgb1, rgb2, amount) - Like BlendHSV(), but the colors used and the return value are RGB or RGBA colors. The blending is done in HSV form. + Returns an RGB or RGBA string HueToAngle(hue) Converts a hue to an angle range of 0 to 360. Angle 0 is red, 120 is green, and 240 is blue. AngleToHue(hue) Converts an angle to a hue in the valid range. -RotateHue(hsv, angle) - Takes an HSV or HSVA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360. - (Rotating red by 60° produces yellow.) The result is another HSV or HSVA color with the same saturation and value - as the original, but a different hue. +RotateHue(rgb, angle) + Takes an RGB or RGBA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360. + (Rotating red by 60° produces yellow.) + Returns an RGB or RGBA string GrayScale(rgb) Takes an RGB or RGBA color and converts it to grayscale. Returns an RGB or RGBA string. ColorTone(rgb, tone) @@ -101,33 +104,42 @@ ColorTone(rgb, tone) /* Get Flat Icon DEMO by DarkCampainger + This is a test for the get flat icon proc, modified approprietly for icons and their states. Probably not a good idea to run this unless you want to see how the proc works in detail. mob icon = 'old_or_unused.dmi' icon_state = "green" + Login() // Testing image underlays underlays += image(icon='old_or_unused.dmi',icon_state="red") underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = 32) underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = -32) + // Testing image overlays add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = -32)) add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = 32)) add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = -32, pixel_y = -32)) + // Testing icon file overlays (defaults to mob's state) add_overlay('_flat_demoIcons2.dmi') + // Testing icon_state overlays (defaults to mob's icon) add_overlay("white") + // Testing dynamic icon overlays var/icon/I = icon('old_or_unused.dmi', icon_state="aqua") I.Shift(NORTH,16,1) add_overlay(I) + // Testing dynamic image overlays I=image(icon=I,pixel_x = -32, pixel_y = 32) add_overlay(I) + // Testing object types (and layers) add_overlay(/obj/effect/overlay_test) + loc = locate (10,10,1) verb Browse_Icon() @@ -138,9 +150,11 @@ mob src<

") + Output_Icon() set name = "2. Output Icon" to_chat(src, "Icon is: [icon2base64html(getFlatIcon(src))]") + Label_Icon() set name = "3. Label Icon" // Give it a name for the cache @@ -151,9 +165,11 @@ mob src< 57 && ch < 65) || (ch > 70 && ch < 97) || ch > 102) - break - ++digits - if(digits == 8) - break - - var/single = digits < 6 - if(digits != 3 && digits != 4 && digits != 6 && digits != 8) - return - if(digits == 4 || digits == 8) - usealpha = 1 - for(i=start, digits>0, ++i) - ch = text2ascii(rgb, i) - if(ch >= 48 && ch <= 57) - ch -= 48 - else if(ch >= 65 && ch <= 70) - ch -= 55 - else if(ch >= 97 && ch <= 102) - ch -= 87 - else - break - --digits - switch(which) - if(0) - r = (r << 4) | ch - if(single) - r |= r << 4 - ++which - else if(!(digits & 1)) - ++which - if(1) - g = (g << 4) | ch - if(single) - g |= g << 4 - ++which - else if(!(digits & 1)) - ++which - if(2) - b = (b << 4) | ch - if(single) - b |= b << 4 - ++which - else if(!(digits & 1)) - ++which - if(3) - alpha = (alpha << 4) | ch - if(single) - alpha |= alpha << 4 - - . = list(r, g, b) - if(usealpha) - . += alpha - -/proc/ReadHSV(hsv) - if(!hsv) - return - - // interpret the HSV or HSVA value - var/i=1,start=1 - if(text2ascii(hsv) == 35) - ++start // skip opening # - var/ch,which=0,hue=0,sat=0,val=0,alpha=0,usealpha - var/digits=0 - for(i=start, i <= length(hsv), ++i) - ch = text2ascii(hsv, i) - if(ch < 48 || (ch > 57 && ch < 65) || (ch > 70 && ch < 97) || ch > 102) - break - ++digits - if(digits == 9) - break - if(digits > 7) - usealpha = 1 - if(digits <= 4) - ++which - if(digits <= 2) - ++which - for(i=start, digits>0, ++i) - ch = text2ascii(hsv, i) - if(ch >= 48 && ch <= 57) - ch -= 48 - else if(ch >= 65 && ch <= 70) - ch -= 55 - else if(ch >= 97 && ch <= 102) - ch -= 87 - else - break - --digits - switch(which) - if(0) - hue = (hue << 4) | ch - if(digits == (usealpha ? 6 : 4)) - ++which - if(1) - sat = (sat << 4) | ch - if(digits == (usealpha ? 4 : 2)) - ++which - if(2) - val = (val << 4) | ch - if(digits == (usealpha ? 2 : 0)) - ++which - if(3) - alpha = (alpha << 4) | ch - - . = list(hue, sat, val) - if(usealpha) - . += alpha - -/proc/HSVtoRGB(hsv) - if(!hsv) +/// Converts a list storing hsva into an rgb color +/proc/hsv2rgb(hsv) + if(length(hsv) < 3) return "#000000" - var/list/HSV = ReadHSV(hsv) - if(!HSV) - return "#000000" - - var/hue = HSV[1] - var/sat = HSV[2] - var/val = HSV[3] - - // Compress hue into easier-to-manage range - hue -= hue >> 8 - if(hue >= 0x5fa) - hue -= 0x5fa - - var/hi,mid,lo,r,g,b - hi = val - lo = round((255 - sat) * val / 255, 1) - mid = lo + round(abs(round(hue, 510) - hue) * (hi - lo) / 255, 1) - if(hue >= 765) - if(hue >= 1275) {r=hi; g=lo; b=mid} - else if(hue >= 1020) {r=mid; g=lo; b=hi } - else {r=lo; g=mid; b=hi } - else - if(hue >= 510) {r=lo; g=hi; b=mid} - else if(hue >= 255) {r=mid; g=hi; b=lo } - else {r=hi; g=mid; b=lo } - - return (HSV.len > 3) ? rgb(r,g,b,HSV[4]) : rgb(r,g,b) - -/proc/RGBtoHSV(rgb) - if(!rgb) - return "#0000000" - var/list/RGB = ReadRGB(rgb) - if(!RGB) - return "#0000000" - - var/r = RGB[1] - var/g = RGB[2] - var/b = RGB[3] - var/hi = max(r,g,b) - var/lo = min(r,g,b) - - var/val = hi - var/sat = hi ? round((hi-lo) * 255 / hi, 1) : 0 - var/hue = 0 - - if(sat) - var/dir - var/mid - if(hi == r) - if(lo == b) {hue=0; dir=1; mid=g} - else {hue=1535; dir=-1; mid=b} - else if(hi == g) - if(lo == r) {hue=512; dir=1; mid=b} - else {hue=511; dir=-1; mid=r} - else if(hi == b) - if(lo == g) {hue=1024; dir=1; mid=r} - else {hue=1023; dir=-1; mid=g} - hue += dir * round((mid-lo) * 255 / (hi-lo), 1) - - return hsv(hue, sat, val, (RGB.len>3 ? RGB[4] : null)) - -/proc/hsv(hue, sat, val, alpha) - if(hue < 0 || hue >= 1536) - hue %= 1536 - if(hue < 0) - hue += 1536 - if((hue & 0xFF) == 0xFF) - ++hue - if(hue >= 1536) - hue = 0 - if(sat < 0) - sat = 0 - if(sat > 255) - sat = 255 - if(val < 0) - val = 0 - if(val > 255) - val = 255 - . = "#" - . += TO_HEX_DIGIT(hue >> 8) - . += TO_HEX_DIGIT(hue >> 4) - . += TO_HEX_DIGIT(hue) - . += TO_HEX_DIGIT(sat >> 4) - . += TO_HEX_DIGIT(sat) - . += TO_HEX_DIGIT(val >> 4) - . += TO_HEX_DIGIT(val) - if(!isnull(alpha)) - if(alpha < 0) - alpha = 0 - if(alpha > 255) - alpha = 255 - . += TO_HEX_DIGIT(alpha >> 4) - . += TO_HEX_DIGIT(alpha) + if(length(hsv) == 3) + return rgb(hsv[1], hsv[2], hsv[3], space = COLORSPACE_HSV) + return rgb(hsv[1], hsv[2], hsv[3], hsv[4], space = COLORSPACE_HSV) /* - Smooth blend between HSV colors + Smooth blend between RGB colors interpreted as HSV + amount=0 is the first color amount=1 is the second color amount=0.5 is directly between the two colors + amount<0 or amount>1 are allowed */ /proc/BlendHSV(hsv1, hsv2, amount) - var/list/HSV1 = ReadHSV(hsv1) - var/list/HSV2 = ReadHSV(hsv2) - - // add missing alpha if needed - if(HSV1.len < HSV2.len) - HSV1 += 255 - else if(HSV2.len < HSV1.len) - HSV2 += 255 - var/usealpha = HSV1.len > 3 - - // normalize hsv values in case anything is screwy - if(HSV1[1] > 1536) - HSV1[1] %= 1536 - if(HSV2[1] > 1536) - HSV2[1] %= 1536 - if(HSV1[1] < 0) - HSV1[1] += 1536 - if(HSV2[1] < 0) - HSV2[1] += 1536 - if(!HSV1[3]) {HSV1[1] = 0; HSV1[2] = 0} - if(!HSV2[3]) {HSV2[1] = 0; HSV2[2] = 0} - - // no value for one color means don't change saturation - if(!HSV1[3]) - HSV1[2] = HSV2[2] - if(!HSV2[3]) - HSV2[2] = HSV1[2] - // no saturation for one color means don't change hues - if(!HSV1[2]) - HSV1[1] = HSV2[1] - if(!HSV2[2]) - HSV2[1] = HSV1[1] - - // Compress hues into easier-to-manage range - HSV1[1] -= HSV1[1] >> 8 - HSV2[1] -= HSV2[1] >> 8 - - var/hue_diff = HSV2[1] - HSV1[1] - if(hue_diff > 765) - hue_diff -= 1530 - else if(hue_diff <= -765) - hue_diff += 1530 - - var/hue = round(HSV1[1] + hue_diff * amount, 1) - var/sat = round(HSV1[2] + (HSV2[2] - HSV1[2]) * amount, 1) - var/val = round(HSV1[3] + (HSV2[3] - HSV1[3]) * amount, 1) - var/alpha = usealpha ? round(HSV1[4] + (HSV2[4] - HSV1[4]) * amount, 1) : null - - // normalize hue - if(hue < 0 || hue >= 1530) - hue %= 1530 - if(hue < 0) - hue += 1530 - // decompress hue - hue += round(hue / 255) - - return hsv(hue, sat, val, alpha) + return hsv_gradient(amount, 0, hsv1, 1, hsv2, "loop") /* Smooth blend between RGB colors + amount=0 is the first color amount=1 is the second color amount=0.5 is directly between the two colors + amount<0 or amount>1 are allowed */ /proc/BlendRGB(rgb1, rgb2, amount) - var/list/RGB1 = ReadRGB(rgb1) - var/list/RGB2 = ReadRGB(rgb2) - - // add missing alpha if needed - if(RGB1.len < RGB2.len) - RGB1 += 255 - else if(RGB2.len < RGB1.len) - RGB2 += 255 - var/usealpha = RGB1.len > 3 - - var/r = round(RGB1[1] + (RGB2[1] - RGB1[1]) * amount, 1) - var/g = round(RGB1[2] + (RGB2[2] - RGB1[2]) * amount, 1) - var/b = round(RGB1[3] + (RGB2[3] - RGB1[3]) * amount, 1) - var/alpha = usealpha ? round(RGB1[4] + (RGB2[4] - RGB1[4]) * amount, 1) : null - - return isnull(alpha) ? rgb(r, g, b) : rgb(r, g, b, alpha) - -/proc/BlendRGBasHSV(rgb1, rgb2, amount) - return HSVtoRGB(RGBtoHSV(rgb1), RGBtoHSV(rgb2), amount) + return rgb_gradient(amount, 0, rgb1, 1, rgb2, "loop") /proc/HueToAngle(hue) // normalize hsv in case anything is screwy @@ -596,10 +330,9 @@ world hue += round(hue / 255) return hue - // positive angle rotates forward through red->green->blue -/proc/RotateHue(hsv, angle) - var/list/HSV = ReadHSV(hsv) +/proc/RotateHue(rgb, angle) + var/list/HSV = rgb2hsv(rgb) // normalize hsv in case anything is screwy if(HSV[1] >= 1536) @@ -622,18 +355,18 @@ world // decompress hue HSV[1] += round(HSV[1] / 255) - return hsv(HSV[1], HSV[2], HSV[3], (HSV.len > 3 ? HSV[4] : null)) + return hsv2rgb(HSV) // Convert an rgb color to grayscale /proc/GrayScale(rgb) - var/list/RGB = ReadRGB(rgb) + var/list/RGB = rgb2num(rgb) var/gray = RGB[1]*0.3 + RGB[2]*0.59 + RGB[3]*0.11 return (RGB.len > 3) ? rgb(gray, gray, gray, RGB[4]) : rgb(gray, gray, gray) // Change grayscale color to black->tone->white range /proc/ColorTone(rgb, tone) - var/list/RGB = ReadRGB(rgb) - var/list/TONE = ReadRGB(tone) + var/list/RGB = rgb2num(rgb) + var/list/TONE = rgb2num(tone) var/gray = RGB[1]*0.3 + RGB[2]*0.59 + RGB[3]*0.11 var/tone_gray = TONE[1]*0.3 + TONE[2]*0.59 + TONE[3]*0.11 @@ -1013,7 +746,9 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) var/static/list/humanoid_icon_cache = list() if(icon_id && humanoid_icon_cache[icon_id]) return humanoid_icon_cache[icon_id] + var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key) + if(prefs) prefs.apply_prefs_to(body, TRUE) @@ -1319,6 +1054,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) GLOBAL_LIST_EMPTY(transformation_animation_objects) + /* * Creates animation that turns current icon into result appearance from top down. * diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm index e6a9e038849..68b94fc2fe6 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -178,7 +178,7 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro if(!color) return COLOR_MATRIX_IDENTITY if(istext(color)) - var/list/L = ReadRGB(color) + var/list/L = rgb2num(color) if(!L) var/message = "Invalid/unsupported color ([color]) argument in color_to_full_rgba_matrix()" if(return_identity_on_fail) @@ -193,7 +193,7 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro if(3 to 5) // row-by-row hexadecimals . = list() for(var/a in 1 to L.len) - var/list/rgb = ReadRGB(L[a]) + var/list/rgb = rgb2num(L[a]) for(var/b in rgb) . += b/255 if(length(rgb) % 4) // RGB has no alpha instruction diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 98e48852094..7e97724b562 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -338,14 +338,15 @@ GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH, var/length = length(string) if((length != 7 && length != 9) || length != length_char(string)) return COLOR_MATRIX_IDENTITY - var/r = hex2num(copytext(string, 2, 4))/255 - var/g = hex2num(copytext(string, 4, 6))/255 - var/b = hex2num(copytext(string, 6, 8))/255 + // For runtime safety + . = COLOR_MATRIX_IDENTITY + var/list/color = rgb2num(string) + var/r = color[1] / 255 + var/g = color[2] / 255 + var/b = color[3] / 255 var/a = 1 - if(length == 9) - a = hex2num(copytext(string, 8, 10))/255 - if(!isnum(r) || !isnum(g) || !isnum(b) || !isnum(a)) - return COLOR_MATRIX_IDENTITY + if(length(color) == 4) + a = color[4] / 255 return list(r,0,0,0, 0,g,0,0, 0,0,b,0, 0,0,0,a, 0,0,0,0) //will drop all values not on the diagonal diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index b30073dd71c..397f5f38a33 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -318,6 +318,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NO_DEBRAIN_OVERLAY" = TRAIT_NO_DEBRAIN_OVERLAY, "TRAIT_NO_DNA_COPY" = TRAIT_NO_DNA_COPY, "TRAIT_NO_DNA_SCRAMBLE" = TRAIT_NO_DNA_SCRAMBLE, + "TRAIT_NO_EXTINGUISH" = TRAIT_NO_EXTINGUISH, "TRAIT_NO_FLOATING_ANIM" = TRAIT_NO_FLOATING_ANIM, "TRAIT_NO_GLIDE" = TRAIT_NO_GLIDE, "TRAIT_NO_PLASMA_TRANSFORM" = TRAIT_NO_PLASMA_TRANSFORM, @@ -354,7 +355,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_PASSTABLE" = TRAIT_PASSTABLE, "TRAIT_PERFECT_ATTACKER" = TRAIT_PERFECT_ATTACKER, "TRAIT_PERMANENTLY_MORTAL" = TRAIT_PERMANENTLY_MORTAL, - "TRAIT_PERMANENTLY_ONFIRE" = TRAIT_PERMANENTLY_ONFIRE, "TRAIT_PHOTOGRAPHER" = TRAIT_PHOTOGRAPHER, "TRAIT_PIERCEIMMUNE" = TRAIT_PIERCEIMMUNE, "TRAIT_PLANT_SAFE" = TRAIT_PLANT_SAFE, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 1043844ddf2..ae27a70c9dd 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -129,6 +129,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_NO_AUGMENTS" = TRAIT_NO_AUGMENTS, "TRAIT_NO_BLOOD_OVERLAY" = TRAIT_NO_BLOOD_OVERLAY, "TRAIT_NO_DNA_COPY" = TRAIT_NO_DNA_COPY, + "TRAIT_NO_EXTINGUISH" = TRAIT_NO_EXTINGUISH, "TRAIT_NO_GLIDE" = TRAIT_NO_GLIDE, "TRAIT_NO_PLASMA_TRANSFORM" = TRAIT_NO_PLASMA_TRANSFORM, "TRAIT_NO_SLIP_ALL" = TRAIT_NO_SLIP_ALL, @@ -162,7 +163,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_PARALYSIS_R_LEG" = TRAIT_PARALYSIS_R_LEG, "TRAIT_PASSTABLE" = TRAIT_PASSTABLE, "TRAIT_PERFECT_ATTACKER" = TRAIT_PERFECT_ATTACKER, - "TRAIT_PERMANENTLY_ONFIRE" = TRAIT_PERMANENTLY_ONFIRE, "TRAIT_PHOTOGRAPHER" = TRAIT_PHOTOGRAPHER, "TRAIT_PIERCEIMMUNE" = TRAIT_PIERCEIMMUNE, "TRAIT_PLANT_SAFE" = TRAIT_PLANT_SAFE, diff --git a/code/datums/elements/permanent_fire_overlay.dm b/code/datums/elements/permanent_fire_overlay.dm new file mode 100644 index 00000000000..514d0f121a4 --- /dev/null +++ b/code/datums/elements/permanent_fire_overlay.dm @@ -0,0 +1,24 @@ +/// When applied to a mob, they will always have a fire overlay regardless of if they are *actually* on fire. +/datum/element/perma_fire_overlay + +/datum/element/perma_fire_overlay/Attach(atom/target) + . = ..() + if(!isliving(target)) + return ELEMENT_INCOMPATIBLE + + RegisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(add_fire_overlay)) + target.update_appearance(UPDATE_OVERLAYS) + +/datum/element/perma_fire_overlay/Detach(atom/target) + . = ..() + UnregisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS) + target.update_appearance(UPDATE_OVERLAYS) + +/datum/element/perma_fire_overlay/proc/add_fire_overlay(mob/living/source, list/overlays) + SIGNAL_HANDLER + + var/mutable_appearance/created_overlay = source.get_fire_overlay(stacks = MAX_FIRE_STACKS, on_fire = TRUE) + if(isnull(created_overlay)) + return + + overlays |= created_overlay diff --git a/code/datums/status_effects/debuffs/fire_stacks.dm b/code/datums/status_effects/debuffs/fire_stacks.dm index 4a6e7b6b730..2f32ff5b3be 100644 --- a/code/datums/status_effects/debuffs/fire_stacks.dm +++ b/code/datums/status_effects/debuffs/fire_stacks.dm @@ -7,7 +7,7 @@ /// Current amount of stacks we have var/stacks /// Maximum of stacks that we could possibly get - var/stack_limit = 20 + var/stack_limit = MAX_FIRE_STACKS /// What status effect types do we remove uppon being applied. These are just deleted without any deduction from our or their stacks when forced. var/list/enemy_types /// What status effect types do we merge into if they exist. Ignored when forced. @@ -116,12 +116,8 @@ owner.clear_alert(ALERT_FIRE) else if(!was_on_fire && owner.on_fire) owner.throw_alert(ALERT_FIRE, /atom/movable/screen/alert/fire) - -/** - * Used to update owner's effect overlay - */ - -/datum/status_effect/fire_handler/proc/update_overlay() + owner.update_appearance(UPDATE_OVERLAYS) + update_particles() /datum/status_effect/fire_handler/fire_stacks id = "fire_stacks" //fire_stacks and wet_stacks should have different IDs or else has_status_effect won't work @@ -132,8 +128,6 @@ /// If we're on fire var/on_fire = FALSE - /// Stores current fire overlay icon state, for optimisation purposes - var/last_icon_state /// Reference to the mob light emitter itself var/obj/effect/dummy/lighting_obj/moblight /// Type of mob light emitter we use when on fire @@ -160,8 +154,6 @@ return TRUE deal_damage(seconds_between_ticks) - update_overlay() - update_particles() /datum/status_effect/fire_handler/fire_stacks/update_particles() if(on_fire) @@ -239,8 +231,6 @@ moblight = new moblight_type(owner) cache_stacks() - update_overlay() - update_particles() SEND_SIGNAL(owner, COMSIG_LIVING_IGNITED, owner) return TRUE @@ -254,8 +244,6 @@ owner.clear_mood_event("on_fire") SEND_SIGNAL(owner, COMSIG_LIVING_EXTINGUISHED, owner) cache_stacks() - update_overlay() - update_particles() for(var/obj/item/equipped in owner.get_equipped_items()) equipped.extinguish() @@ -263,16 +251,26 @@ if(on_fire) extinguish() set_stacks(0) - update_overlay() - update_particles() + UnregisterSignal(owner, COMSIG_ATOM_UPDATE_OVERLAYS) + owner.update_appearance(UPDATE_OVERLAYS) return ..() -/datum/status_effect/fire_handler/fire_stacks/update_overlay() - last_icon_state = owner.update_fire_overlay(stacks, on_fire, last_icon_state) - /datum/status_effect/fire_handler/fire_stacks/on_apply() . = ..() - update_overlay() + RegisterSignal(owner, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(add_fire_overlay)) + owner.update_appearance(UPDATE_OVERLAYS) + +/datum/status_effect/fire_handler/fire_stacks/proc/add_fire_overlay(mob/living/source, list/overlays) + SIGNAL_HANDLER + + if(stacks <= 0 || !on_fire) + return + + var/mutable_appearance/created_overlay = owner.get_fire_overlay(stacks, on_fire) + if(isnull(created_overlay)) + return + + overlays |= created_overlay /obj/effect/dummy/lighting_obj/moblight/fire name = "fire" diff --git a/code/game/objects/items/frog_statue.dm b/code/game/objects/items/frog_statue.dm index 4d1bf9b6aa5..34c491d9dd7 100644 --- a/code/game/objects/items/frog_statue.dm +++ b/code/game/objects/items/frog_statue.dm @@ -1,7 +1,7 @@ #define STATUE_FILTER "statue_filter" #define FILTER_COLOR "#34b347" #define RECALL_DURATION 3 SECONDS -#define MINIMUM_COLOR_VALUE 60 +#define MINIMUM_COLOR_VALUE 20 /obj/item/frog_statue name = "frog statue" @@ -151,8 +151,8 @@ to_chat(user, span_warning("Please choose a valid color.")) select_frog_color(user, new_frog) return - var/temp_hsv = RGBtoHSV(frog_color) - if(ReadHSV(temp_hsv)[3] < MINIMUM_COLOR_VALUE) + var/list/hsv_frog = rgb2hsv(frog_color) + if(hsv_frog[3] < MINIMUM_COLOR_VALUE) to_chat(user, span_danger("This color is too dark!")) select_frog_color(user, new_frog) return diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index eab3f34d343..ca669a9733e 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -516,10 +516,10 @@ if(!greyscale_colors) // Generate a random valid lizard color for our plushie friend var/generated_lizard_color = "#" + random_color() - var/temp_hsv = RGBtoHSV(generated_lizard_color) + var/list/lizard_hsv = rgb2hsv(generated_lizard_color) // If our color is too dark, use the classic green lizard plush color - if(ReadHSV(temp_hsv)[3] < ReadHSV("#7F7F7F")[3]) + if(lizard_hsv[3] < 50) generated_lizard_color = "#66ff33" // Set our greyscale colors to the lizard color we made + black eyes diff --git a/code/game/objects/items/rcd/RLD.dm b/code/game/objects/items/rcd/RLD.dm index beef6152b57..6272c7a374d 100644 --- a/code/game/objects/items/rcd/RLD.dm +++ b/code/game/objects/items/rcd/RLD.dm @@ -73,7 +73,7 @@ if(new_choice == null) return - var/list/new_rgb = ReadRGB(new_choice) + var/list/new_rgb = rgb2num(new_choice) for(var/option in original_options) if(option == "Color Pick" || option == "Deconstruct" || option == "Silo Link") continue diff --git a/code/game/objects/items/stacks/wrap.dm b/code/game/objects/items/stacks/wrap.dm index 15247e3051d..c52fbe870f8 100644 --- a/code/game/objects/items/stacks/wrap.dm +++ b/code/game/objects/items/stacks/wrap.dm @@ -24,13 +24,13 @@ //Generate random valid colors for paper and ribbon var/generated_base_color = "#" + random_color() var/generated_ribbon_color = "#" + random_color() - var/temp_base_hsv = RGBtoHSV(generated_base_color) - var/temp_ribbon_hsv = RGBtoHSV(generated_ribbon_color) + var/list/base_hsv = rgb2hsv(generated_base_color) + var/list/ribbon_hsv = rgb2hsv(generated_ribbon_color) //If colors are too dark, set to original colors - if(ReadHSV(temp_base_hsv)[3] < ReadHSV("7F7F7F")[3]) + if(base_hsv[3] < 50) generated_base_color = "#00FF00" - if(ReadHSV(temp_ribbon_hsv)[3] < ReadHSV("7F7F7F")[3]) + if(ribbon_hsv[3] < 50) generated_ribbon_color = "#FF0000" //Set layers to these colors, base then ribbon diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index f8392159078..bbe56b68c16 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -180,12 +180,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) else if(HAS_TRAIT(race_changer, TRAIT_MUTANT_COLORS) && !HAS_TRAIT(race_changer, TRAIT_FIXED_MUTANT_COLORS)) var/new_mutantcolor = input(race_changer, "Choose your skin color:", "Race change", race_changer.dna.features["mcolor"]) as color|null if(new_mutantcolor) - var/temp_hsv = RGBtoHSV(new_mutantcolor) + var/list/mutant_hsv = rgb2hsv(new_mutantcolor) - if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright + if(mutant_hsv[3] >= 50) // mutantcolors must be bright race_changer.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor) race_changer.dna.update_uf_block(DNA_MUTANT_COLOR_BLOCK) - else to_chat(race_changer, span_notice("Invalid color. Your color is not bright enough.")) return TRUE diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm index 1a174723d85..8f9e7b44aa6 100644 --- a/code/game/turfs/open/lava.dm +++ b/code/game/turfs/open/lava.dm @@ -52,7 +52,8 @@ /turf/open/lava/Destroy() for(var/mob/living/leaving_mob in contents) - REMOVE_TRAIT(leaving_mob, TRAIT_PERMANENTLY_ONFIRE, TURF_TRAIT) + leaving_mob.RemoveElement(/datum/element/perma_fire_overlay) + REMOVE_TRAIT(leaving_mob, TRAIT_NO_EXTINGUISH, TURF_TRAIT) return ..() /turf/open/lava/update_overlays() @@ -144,7 +145,8 @@ /turf/open/lava/Exited(atom/movable/gone, direction) . = ..() if(isliving(gone) && !islava(gone.loc)) - REMOVE_TRAIT(gone, TRAIT_PERMANENTLY_ONFIRE, TURF_TRAIT) + gone.RemoveElement(/datum/element/perma_fire_overlay) + REMOVE_TRAIT(gone, TRAIT_NO_EXTINGUISH, TURF_TRAIT) /turf/open/lava/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(burn_stuff(AM)) @@ -292,11 +294,10 @@ if(QDELETED(burn_target)) return FALSE - . = TRUE if(isobj(burn_target)) var/obj/burn_obj = burn_target if(burn_obj.resistance_flags & ON_FIRE) // already on fire; skip it. - return + return TRUE if(!(burn_obj.resistance_flags & FLAMMABLE)) burn_obj.resistance_flags |= FLAMMABLE //Even fireproof things burn up in lava if(burn_obj.resistance_flags & FIRE_PROOF) @@ -305,17 +306,21 @@ burn_obj.set_armor_rating(FIRE, 50) burn_obj.fire_act(temperature_damage, 1000 * seconds_per_tick) if(istype(burn_obj, /obj/structure/closet)) - var/obj/structure/closet/burn_closet = burn_obj - for(var/burn_content in burn_closet.contents) + for(var/burn_content in burn_target) burn_stuff(burn_content) - return + return TRUE - var/mob/living/burn_living = burn_target - ADD_TRAIT(burn_living, TRAIT_PERMANENTLY_ONFIRE, TURF_TRAIT) - burn_living.ignite_mob() - burn_living.adjust_fire_stacks(lava_firestacks * seconds_per_tick) - burn_living.update_fire() - burn_living.adjustFireLoss(lava_damage * seconds_per_tick) + if(isliving(burn_target)) + var/mob/living/burn_living = burn_target + if(!HAS_TRAIT_FROM(burn_living, TRAIT_NO_EXTINGUISH, TURF_TRAIT)) + burn_living.AddElement(/datum/element/perma_fire_overlay) + ADD_TRAIT(burn_living, TRAIT_NO_EXTINGUISH, TURF_TRAIT) + burn_living.adjust_fire_stacks(lava_firestacks * seconds_per_tick) + burn_living.ignite_mob() + burn_living.adjustFireLoss(lava_damage * seconds_per_tick) + return TRUE + + return FALSE /turf/open/lava/can_cross_safely(atom/movable/crossing) return HAS_TRAIT(src, TRAIT_LAVA_STOPPED) || HAS_TRAIT(crossing, immunity_trait ) || HAS_TRAIT(crossing, TRAIT_MOVE_FLYING) diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index bf5d64d7e83..8d7d66979f4 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -612,10 +612,10 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0) GLOB.narsie_effect_last_modified = started var/starting_color = GLOB.starlight_color - var/list/target_color = ReadHSV(RGBtoHSV(starting_color)) + var/list/target_color = rgb2hsv(starting_color) target_color[2] = target_color[2] * 0.4 target_color[3] = target_color[3] * 0.5 - var/mid_color = HSVtoRGB(hsv(target_color[1], target_color[2], target_color[3])) + var/mid_color = hsv2rgb(target_color) var/end_color = "#c21d57" for(var/i in 1 to 9) if(GLOB.narsie_effect_last_modified > started) @@ -639,7 +639,7 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0) for(var/i in 1 to 4) if(GLOB.narsie_effect_last_modified > started) return - var/starlight_color = hsv_gradient(i, 1, starting_color, 4, end_color) + var/starlight_color = BlendHSV(i / 4, starting_color, end_color) set_starlight(starlight_color) sleep(8 SECONDS) diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm index d86531b5429..87f0dd63da9 100644 --- a/code/modules/atmospherics/machinery/datum_pipeline.dm +++ b/code/modules/atmospherics/machinery/datum_pipeline.dm @@ -348,7 +348,7 @@ var/gas_weight = air.gases[gas_path][MOLES] if(!gas_weight) continue - var/gas_color = RGBtoHSV(initial(gas_path.primary_color)) + var/gas_color = initial(gas_path.primary_color) current_weight += gas_weight if(!current_color) current_color = gas_color @@ -363,8 +363,6 @@ if(empty_weight > 0) current_color = BlendHSV("#000000", current_color, current_weight / (empty_weight + current_weight)) - current_color = HSVtoRGB(current_color) - if(gasmix_color != current_color) gasmix_color = current_color UpdateGasVisuals() diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index ba07c944652..d69665d6bcd 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -270,17 +270,17 @@ /mob/living/basic/on_fire_stack(seconds_per_tick, datum/status_effect/fire_handler/fire_stacks/fire_handler) adjust_bodytemperature((maximum_survivable_temperature + (fire_handler.stacks * 12)) * 0.5 * seconds_per_tick) -/mob/living/basic/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") - var/mutable_appearance/fire_overlay = mutable_appearance('icons/mob/effects/onfire.dmi', "generic_fire") - if(on_fire && isnull(last_icon_state)) - add_overlay(fire_overlay) - return fire_overlay - else if(!on_fire && !isnull(last_icon_state)) - cut_overlay(fire_overlay) - return null - else if(on_fire && !isnull(last_icon_state)) - return last_icon_state - return null +/mob/living/basic/get_fire_overlay(stacks, on_fire) + var/fire_icon = "generic_fire" + if(!GLOB.fire_appearances[fire_icon]) + GLOB.fire_appearances[fire_icon] = mutable_appearance( + 'icons/mob/effects/onfire.dmi', + fire_icon, + -HIGHEST_LAYER, + appearance_flags = RESET_COLOR, + ) + + return GLOB.fire_appearances[fire_icon] /mob/living/basic/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, ignore_animation = TRUE) . = ..() diff --git a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm index 9820b0b5a4b..c9505321b37 100644 --- a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm +++ b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm @@ -1,5 +1,5 @@ /// You can't make a dragon darker than this, it'd be hard to see -#define REJECT_DARK_COLOUR_THRESHOLD 50 +#define REJECT_DARK_COLOUR_THRESHOLD 20 /// Any interactions executed by the space dragon #define DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION "space dragon interaction" @@ -101,8 +101,8 @@ to_chat(src, span_warning("Not a valid colour, please try again.")) select_colour() return - var/temp_hsv = RGBtoHSV(chosen_colour) - if(ReadHSV(temp_hsv)[3] < REJECT_DARK_COLOUR_THRESHOLD) + var/list/skin_hsv = rgb2hsv(chosen_colour) + if(skin_hsv[3] < REJECT_DARK_COLOUR_THRESHOLD) to_chat(src, span_danger("Invalid colour. Your colour is not bright enough.")) select_colour() return diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index 9e8af56c8f3..2a17403a83e 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -278,8 +278,8 @@ update_held_items() update_worn_handcuffs() update_worn_legcuffs() - update_fire() update_body() + update_appearance(UPDATE_OVERLAYS) /mob/living/carbon/update_held_items() . = ..() @@ -315,27 +315,18 @@ hands += I.build_worn_icon(default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE) return hands -/mob/living/carbon/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") - var/fire_icon = "[dna?.species.fire_overlay || "human"]_[stacks > MOB_BIG_FIRE_STACK_THRESHOLD ? "big_fire" : "small_fire"][suffix]" +/mob/living/carbon/get_fire_overlay(stacks, on_fire) + var/fire_icon = "[dna?.species.fire_overlay || "human"]_[stacks > MOB_BIG_FIRE_STACK_THRESHOLD ? "big_fire" : "small_fire"]" if(!GLOB.fire_appearances[fire_icon]) - GLOB.fire_appearances[fire_icon] = mutable_appearance('icons/mob/effects/onfire.dmi', fire_icon, -FIRE_LAYER, appearance_flags = RESET_COLOR) + GLOB.fire_appearances[fire_icon] = mutable_appearance( + 'icons/mob/effects/onfire.dmi', + fire_icon, + -HIGHEST_LAYER, + appearance_flags = RESET_COLOR, + ) - if((stacks > 0 && on_fire) || HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE)) - if(fire_icon == last_icon_state) - return last_icon_state - - remove_overlay(FIRE_LAYER) - overlays_standing[FIRE_LAYER] = GLOB.fire_appearances[fire_icon] - apply_overlay(FIRE_LAYER) - return fire_icon - - if(!last_icon_state) - return last_icon_state - - remove_overlay(FIRE_LAYER) - apply_overlay(FIRE_LAYER) - return null + return GLOB.fire_appearances[fire_icon] /mob/living/carbon/update_damage_overlays() remove_overlay(DAMAGE_LAYER) diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index 7850dee6734..0a92d858f96 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -41,12 +41,6 @@ var/current_color var/default_color - var/r1 - var/g1 - var/b1 - var/static/r2 = 237 - var/static/g2 = 164 - var/static/b2 = 149 var/EMPeffect = FALSE var/emageffect = FALSE var/obj/effect/dummy/lighting_obj/ethereal_light @@ -61,9 +55,6 @@ return default_color = new_ethereal.dna.features["ethcolor"] fixed_hair_color = default_color - r1 = GETREDPART(default_color) - g1 = GETGREENPART(default_color) - b1 = GETBLUEPART(default_color) RegisterSignal(new_ethereal, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag_act)) RegisterSignal(new_ethereal, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act)) RegisterSignal(new_ethereal, COMSIG_HIT_BY_SABOTEUR, PROC_REF(on_saboteur)) @@ -116,15 +107,16 @@ SIGNAL_HANDLER if(isnull(ethereal_light)) return - if(default_color != ethereal.dna.features["ethcolor"]) - var/new_color = ethereal.dna.features["ethcolor"] - r1 = GETREDPART(new_color) - g1 = GETGREENPART(new_color) - b1 = GETBLUEPART(new_color) if(ethereal.stat != DEAD && !EMPeffect) var/healthpercent = max(ethereal.health, 0) / 100 if(!emageffect) - current_color = rgb(r2 + ((r1-r2)*healthpercent), g2 + ((g1-g2)*healthpercent), b2 + ((b1-b2)*healthpercent)) + var/static/list/skin_color = rgb2num("#eda495") + var/list/colors = rgb2num(ethereal.dna.features["ethcolor"]) + var/list/built_color = list() + for(var/i in 1 to 3) + built_color += skin_color[i] + ((colors[i] - skin_color[i]) * healthpercent) + current_color = rgb(built_color[1], built_color[2], built_color[3]) + ethereal_light.set_light_range_power_color(1 + (2 * healthpercent), 1 + (1 * healthpercent), current_color) ethereal_light.set_light_on(TRUE) fixed_mut_color = current_color diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index eaabee63485..b6fe0234bac 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -116,7 +116,7 @@ else internal_fire = FALSE - H.update_fire() + H.update_appearance(UPDATE_OVERLAYS) /datum/species/plasmaman/handle_fire(mob/living/carbon/human/H, seconds_per_tick, no_protection = FALSE) if(internal_fire) diff --git a/code/modules/mob/living/carbon/init_signals.dm b/code/modules/mob/living/carbon/init_signals.dm index 190fe9d8453..e64410ab635 100644 --- a/code/modules/mob/living/carbon/init_signals.dm +++ b/code/modules/mob/living/carbon/init_signals.dm @@ -13,12 +13,6 @@ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_TOXIMMUNE), PROC_REF(on_toximmune_trait_gain)) RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_GENELESS), PROC_REF(on_geneless_trait_gain)) - - RegisterSignals(src, list( - SIGNAL_ADDTRAIT(TRAIT_PERMANENTLY_ONFIRE), - SIGNAL_REMOVETRAIT(TRAIT_PERMANENTLY_ONFIRE), - ), PROC_REF(update_permanently_on_fire)) - /** * On gain of TRAIT_AGENDER * @@ -90,12 +84,6 @@ reagents.end_metabolization(keep_liverless = TRUE) -///On gain of TRAIT_PERMANENTLY_ONFIRE, update the visuals if not on fire -/mob/living/carbon/proc/update_permanently_on_fire(datum/source) - SIGNAL_HANDLER - if(!on_fire) - update_fire() - /** * On gain of TRAIT_VIRUSIMMUNE * diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 7ae344b658d..ad61cf4d00d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1654,11 +1654,6 @@ GLOBAL_LIST_EMPTY(fire_appearances) return fire_status.ignite(silent) -/mob/living/proc/update_fire() - var/datum/status_effect/fire_handler/fire_stacks/fire_stacks = has_status_effect(/datum/status_effect/fire_handler/fire_stacks) - if(fire_stacks) - fire_stacks.update_overlay() - /** * Extinguish all fire on the mob * @@ -1666,7 +1661,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) * Signals the extinguishing. */ /mob/living/proc/extinguish_mob() - if(HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE)) //The everlasting flames will not be extinguished + if(HAS_TRAIT(src, TRAIT_NO_EXTINGUISH)) //The everlasting flames will not be extinguished return var/datum/status_effect/fire_handler/fire_stacks/fire_status = has_status_effect(/datum/status_effect/fire_handler/fire_stacks) if(!fire_status || !fire_status.on_fire) @@ -1685,13 +1680,13 @@ GLOBAL_LIST_EMPTY(fire_appearances) /mob/living/proc/adjust_fire_stacks(stacks, fire_type = /datum/status_effect/fire_handler/fire_stacks) if(stacks < 0) - if(HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE)) //You can't reduce fire stacks of the everlasting flames + if(HAS_TRAIT(src, TRAIT_NO_EXTINGUISH)) //You can't reduce fire stacks of the everlasting flames return stacks = max(-fire_stacks, stacks) apply_status_effect(fire_type, stacks) /mob/living/proc/adjust_wet_stacks(stacks, wet_type = /datum/status_effect/fire_handler/wet_stacks) - if(HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE)) //The everlasting flames will not be extinguished + if(HAS_TRAIT(src, TRAIT_NO_EXTINGUISH)) //The everlasting flames will not be extinguished return if(stacks < 0) stacks = max(fire_stacks, stacks) @@ -1769,19 +1764,18 @@ GLOBAL_LIST_EMPTY(fire_appearances) ignite_mob() /** - * Sets fire overlay of the mob. + * Gets the fire overlay to use for this mob * - * Vars: + * Args: * * stacks: Current amount of fire_stacks * * on_fire: If we're lit on fire - * * last_icon_state: Holds last fire overlay icon state, used for optimization - * * suffix: Suffix for the fire icon state for special fire types * - * This should return last_icon_state for the fire status efect + * Return a mutable appearance, the overlay that will be applied. */ -/mob/living/proc/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") - return last_icon_state +/mob/living/proc/get_fire_overlay(stacks, on_fire) + RETURN_TYPE(/mutable_appearance) + return null /** * Handles effects happening when mob is on normal fire diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 31ead7ef718..8ba56f2a8e5 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -360,7 +360,7 @@ var/mutable_appearance/head_overlay = hat.build_worn_icon(default_layer = 20, default_icon_file = 'icons/mob/clothing/head/default.dmi') head_overlay.pixel_z += hat_offset add_overlay(head_overlay) - update_fire() + update_appearance(UPDATE_OVERLAYS) /mob/living/silicon/robot/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) if(same_z_layer) @@ -1034,26 +1034,19 @@ /mob/living/silicon/robot/proc/untip_roleplay() to_chat(src, span_notice("Your frustration has empowered you! You can now right yourself faster!")) - -/mob/living/silicon/robot/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") - var/fire_icon = "generic_fire[suffix]" +/mob/living/silicon/robot/get_fire_overlay(stacks, on_fire) + var/fire_icon = "generic_fire" if(!GLOB.fire_appearances[fire_icon]) - var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/effects/onfire.dmi', fire_icon, -FIRE_LAYER) - new_fire_overlay.appearance_flags = RESET_COLOR + var/mutable_appearance/new_fire_overlay = mutable_appearance( + 'icons/mob/effects/onfire.dmi', + fire_icon, + -HIGHEST_LAYER, + appearance_flags = RESET_COLOR, + ) GLOB.fire_appearances[fire_icon] = new_fire_overlay - if(stacks && on_fire) - if(last_icon_state == fire_icon) - return last_icon_state - add_overlay(GLOB.fire_appearances[fire_icon]) - return fire_icon - - if(!last_icon_state) - return last_icon_state - - cut_overlay(GLOB.fire_appearances[fire_icon]) - return null + return GLOB.fire_appearances[fire_icon] /// Draw power from the robot /mob/living/silicon/robot/proc/draw_power(power_to_draw) diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index a441e2b0a71..7a3e2006f66 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -186,9 +186,12 @@ . += mutable_appearance(overlay_icon, base_state) -//SKYRAT EDIT ADDITION BEGIN - AESTHETICS +// SKYRAT EDIT ADDITION BEGIN - AESTHETICS #define LIGHT_ON_DELAY_UPPER (2 SECONDS) #define LIGHT_ON_DELAY_LOWER (0.25 SECONDS) +/// Dynamically calculate nightshift brightness +#define NIGHTSHIFT_LIGHT_MODIFIER 0.15 +#define NIGHTSHIFT_COLOR_MODIFIER 0.15 //SKYRAT EDIT END // Area sensitivity is traditionally tied directly to power use, as an optimization @@ -211,16 +214,15 @@ /obj/machinery/light/proc/handle_fire(area/source, new_fire) SIGNAL_HANDLER - update(instant = TRUE, play_sound = FALSE) //SKYRAT EDIT CHANGE + update(instant = TRUE, play_sound = FALSE) //SKYRAT EDIT CHANGE - ORIGINAL: update() // update the icon_state and luminosity of the light depending on its state -/obj/machinery/light/proc/update(trigger = TRUE, instant = FALSE, play_sound = TRUE) //SKYRAT EDIT CHANGE +/obj/machinery/light/proc/update(trigger = TRUE, instant = FALSE, play_sound = TRUE) // SKYRAT EDIT CHANGE switch(status) if(LIGHT_BROKEN,LIGHT_BURNED,LIGHT_EMPTY) on = FALSE low_power_mode = FALSE if(on) - /* SKYRAT EDIT ORIGINAL var/brightness_set = brightness var/power_set = bulb_power var/color_set = bulb_colour @@ -234,15 +236,31 @@ power_set = fire_power brightness_set = fire_brightness else if (nightshift_enabled) - brightness_set = nightshift_brightness - power_set = nightshift_light_power + brightness_set -= brightness_set * NIGHTSHIFT_LIGHT_MODIFIER // SKYRAT EDIT CHANGE - ORIGINAL: brightness_set = nightshift_brightness + power_set -= power_set * NIGHTSHIFT_LIGHT_MODIFIER // SKYRAT EDIT CHANGE - ORIGINAL: power_set = nightshift_light_power if(!color) color_set = nightshift_light_color + // SKYRAT EDIT ADDITION START - Dynamic nightshift color + if(!color_set) + // Adjust light values to be warmer. I doubt caching would speed this up by any worthwhile amount, as it's all very fast number and string operations. + // Convert to numbers for easier manipulation. + var/list/color_parts = rgb2num(bulb_colour) + var/red = color_parts[1] + var/green = color_parts[2] + var/blue = color_parts[3] + + red += round(red * NIGHTSHIFT_COLOR_MODIFIER) + green -= round(green * NIGHTSHIFT_COLOR_MODIFIER * 0.3) + red = clamp(red, 0, 255) // clamp to be safe, or you can end up with an invalid hex value + green = clamp(green, 0, 255) + blue = clamp(blue, 0, 255) + color_set = rgb(red, green, blue) // Splice the numbers together and turn them back to hex. + // SKYRAT EDIT ADDITION END else if (major_emergency) color_set = bulb_low_power_colour brightness_set = brightness * bulb_major_emergency_brightness_mul var/matching = light && brightness_set == light.light_range && power_set == light.light_power && color_set == light.light_color - if(!matching) + if(!matching && (maploaded || instant)) // SKYRAT EDIT CHANGE - ORIGINAL: if(!matching) switchcount++ if( prob( min(60, (switchcount**2)*0.01) ) ) if(trigger) @@ -254,17 +272,15 @@ l_power = power_set, l_color = color_set ) - */ - //SKYRAT EDIT CHANGE BEGIN - AESTHETICS - if(instant) - turn_on(trigger, play_sound) - else if(maploaded) - turn_on(trigger, play_sound) - maploaded = FALSE - else if(!turning_on) + // SKYRAT EDIT ADDITION START + maploaded = FALSE + if(play_sound) + playsound(src.loc, 'modular_skyrat/modules/aesthetics/lights/sound/light_on.ogg', 65, 1) + else if(!matching && !turning_on) + switchcount++ turning_on = TRUE - addtimer(CALLBACK(src, PROC_REF(turn_on), trigger, play_sound), rand(LIGHT_ON_DELAY_LOWER, LIGHT_ON_DELAY_UPPER)) - //SKYRAT EDIT END + addtimer(CALLBACK(src, PROC_REF(delayed_turn_on), trigger, play_sound, color_set, power_set, brightness_set), rand(LIGHT_ON_DELAY_LOWER, LIGHT_ON_DELAY_UPPER)) + // SKYRAT EDIT ADDITION END else if(has_emergency_power(LIGHT_EMERGENCY_POWER_USE) && !turned_off()) use_power = IDLE_POWER_USE low_power_mode = TRUE @@ -280,7 +296,9 @@ //SKYRAT EDIT ADDITION BEGIN - AESTHETICS #undef LIGHT_ON_DELAY_UPPER #undef LIGHT_ON_DELAY_LOWER -//SKYRAT EDIT END +#undef NIGHTSHIFT_LIGHT_MODIFIER +#undef NIGHTSHIFT_COLOR_MODIFIER +// SKYRAT EDIT ADDITION END /obj/machinery/light/update_current_power_usage() if(!on && static_power_used > 0) //Light is off but still powered diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 5c1ef79c4d6..ce43d2841cf 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -642,31 +642,17 @@ exposed_human.skin_tone = "mixed3" //take current alien color and darken it slightly else if(HAS_TRAIT(exposed_human, TRAIT_MUTANT_COLORS) && !HAS_TRAIT(exposed_human, TRAIT_FIXED_MUTANT_COLORS)) - var/newcolor = "" - var/string = exposed_human.dna.features["mcolor"] - var/len = length(string) - var/char = "" - var/ascii = 0 - for(var/i=1, i <= len, i += length(char)) - char = string[i] - ascii = text2ascii(char) - switch(ascii) - if(48) - newcolor += "0" - if(49 to 57) - newcolor += ascii2text(ascii-1) //numbers 1 to 9 - if(97) - newcolor += "9" - if(98 to 102) - newcolor += ascii2text(ascii-1) //letters b to f lowercase - if(65) - newcolor += "9" - if(66 to 70) - newcolor += ascii2text(ascii+31) //letters B to F - translates to lowercase - else - break - if(ReadHSV(newcolor)[3] >= ReadHSV("#7F7F7F")[3]) - exposed_human.dna.features["mcolor"] = newcolor + var/list/existing_color = rgb2num(exposed_human.dna.features["mcolor"]) + var/list/darkened_color = list() + // Reduces each part of the color by 16 + for(var/channel in existing_color) + darkened_color += max(channel - 17, 0) + + var/new_color = rgb(darkened_color[1], darkened_color[2], darkened_color[3]) + var/list/new_hsv = rgb2hsv(new_color) + // Can't get too dark now + if(new_hsv[3] >= 50) + exposed_human.dna.features["mcolor"] = new_color exposed_human.update_body(is_creating = TRUE) if((methods & INGEST) && show_message) diff --git a/modular_skyrat/master_files/code/game/objects/items/hhmirror.dm b/modular_skyrat/master_files/code/game/objects/items/hhmirror.dm index bc8ef6c0724..27561067b6a 100644 --- a/modular_skyrat/master_files/code/game/objects/items/hhmirror.dm +++ b/modular_skyrat/master_files/code/game/objects/items/hhmirror.dm @@ -68,16 +68,20 @@ human_user.skin_tone = new_s_tone human_user.dna.update_ui_block(DNA_SKIN_TONE_BLOCK) + #define MIN_MCOLOR_VALUE 50 + if(HAS_TRAIT(human_user, TRAIT_MUTANT_COLORS) && !HAS_TRAIT(human_user, TRAIT_FIXED_MUTANT_COLORS)) var/new_mutantcolor = input(user, "Choose your skin color:", "Race change", human_user.dna.features["mcolor"]) as color|null if(new_mutantcolor) - var/temp_hsv = RGBtoHSV(new_mutantcolor) + var/mutantcolor_hsv = rgb2hsv(new_mutantcolor) - if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright + if(mutantcolor_hsv[3] >= MIN_MCOLOR_VALUE) // mutantcolors must be bright human_user.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor) else to_chat(human_user, span_notice("Invalid color. Your color is not bright enough.")) + + #undef MIN_MCOLOR_VALUE human_user.update_body() human_user.update_body_parts() diff --git a/modular_skyrat/modules/aesthetics/airlock/code/airlock.dm b/modular_skyrat/modules/aesthetics/airlock/code/airlock.dm index 15c5d45ba8b..574b66c5c66 100644 --- a/modular_skyrat/modules/aesthetics/airlock/code/airlock.dm +++ b/modular_skyrat/modules/aesthetics/airlock/code/airlock.dm @@ -41,7 +41,7 @@ . = ..() var/pre_light_range = 0 var/pre_light_power = 0 - var/pre_light_color = "" + var/pre_light_color = initial(light_color) var/lights_overlay = "" var/frame_state diff --git a/modular_skyrat/modules/aesthetics/lights/code/lighting.dm b/modular_skyrat/modules/aesthetics/lights/code/lighting.dm index c5c30f406b0..b99f420440e 100644 --- a/modular_skyrat/modules/aesthetics/lights/code/lighting.dm +++ b/modular_skyrat/modules/aesthetics/lights/code/lighting.dm @@ -20,52 +20,24 @@ var/flicker_timer = null var/roundstart_flicker = FALSE -/obj/machinery/light/proc/turn_on(trigger, play_sound = TRUE) +/obj/machinery/light/proc/delayed_turn_on(trigger, play_sound = TRUE, color_set, power_set, brightness_set) if(QDELETED(src)) return turning_on = FALSE if(!on) return - var/area/local_area = get_room_area(src) - var/new_brightness = brightness - var/new_power = bulb_power - var/new_color = bulb_colour - if (local_area?.fire) - new_color = fire_colour - new_brightness = fire_brightness - else if(color) - new_color = color - else if (nightshift_enabled) - new_brightness -= new_brightness * NIGHTSHIFT_LIGHT_MODIFIER - new_power -= new_power * NIGHTSHIFT_LIGHT_MODIFIER - if(!color && nightshift_light_color) - new_color = nightshift_light_color - else if(color) // In case it's spraypainted. - new_color = color - else // Adjust light values to be warmer. I doubt caching would speed this up by any worthwhile amount, as it's all very fast number and string operations. - // Convert to numbers for easier manipulation. - var/red = GETREDPART(bulb_colour) - var/green = GETGREENPART(bulb_colour) - var/blue = GETBLUEPART(bulb_colour) - - red += round(red * NIGHTSHIFT_COLOR_MODIFIER) - green -= round(green * NIGHTSHIFT_COLOR_MODIFIER * 0.3) - red = clamp(red, 0, 255) // clamp to be safe, or you can end up with an invalid hex value - green = clamp(green, 0, 255) - blue = clamp(blue, 0, 255) - new_color = "#[num2hex(red, 2)][num2hex(green, 2)][num2hex(blue, 2)]" // Splice the numbers together and turn them back to hex. - - var/matching = light && new_brightness == light.light_range && new_power == light.light_power && new_color == light.light_color - if(!matching) - switchcount++ - if( prob( min(60, (switchcount**2)*0.01) ) ) - if(trigger) - burn_out() - else - use_power = ACTIVE_POWER_USE - set_light(new_brightness, new_power, new_color) - if(play_sound) - playsound(src.loc, 'modular_skyrat/modules/aesthetics/lights/sound/light_on.ogg', 65, 1) + if( prob( min(60, (switchcount**2)*0.01) ) ) + if(trigger) + burn_out() + else + use_power = ACTIVE_POWER_USE + set_light( + l_range = brightness_set, + l_power = power_set, + l_color = color_set + ) + if(play_sound) + playsound(src.loc, 'modular_skyrat/modules/aesthetics/lights/sound/light_on.ogg', 65, 1) /obj/machinery/light/proc/start_flickering() on = FALSE diff --git a/modular_skyrat/modules/borgs/code/update_icons.dm b/modular_skyrat/modules/borgs/code/update_icons.dm index 22f7779d999..704ac198a47 100644 --- a/modular_skyrat/modules/borgs/code/update_icons.dm +++ b/modular_skyrat/modules/borgs/code/update_icons.dm @@ -68,4 +68,4 @@ icon_state = "[model.cyborg_base_icon]-wreck" - update_fire() + update_appearance(UPDATE_OVERLAYS) diff --git a/modular_skyrat/modules/emotes/code/additionalemotes/turf_emote.dm b/modular_skyrat/modules/emotes/code/additionalemotes/turf_emote.dm index a34e8450843..b8751e57901 100644 --- a/modular_skyrat/modules/emotes/code/additionalemotes/turf_emote.dm +++ b/modular_skyrat/modules/emotes/code/additionalemotes/turf_emote.dm @@ -131,14 +131,14 @@ switch(sprite_type.color_src) if(USE_MATRIXED_COLORS) - finished_list += ReadRGB("[color_list[1]]00") - finished_list += ReadRGB("[color_list[2]]00") - finished_list += ReadRGB("[color_list[3]]00") + finished_list += rgb2num("[color_list[1]]00") + finished_list += rgb2num("[color_list[2]]00") + finished_list += rgb2num("[color_list[3]]00") if(USE_ONE_COLOR) var/padded_string = "[color_list[1]]00" - finished_list += ReadRGB(padded_string) - finished_list += ReadRGB(padded_string) - finished_list += ReadRGB(padded_string) + finished_list += rgb2num(padded_string) + finished_list += rgb2num(padded_string) + finished_list += rgb2num(padded_string) finished_list += list(0,0,0,255) for(var/index in 1 to finished_list.len) diff --git a/modular_skyrat/modules/xenos_skyrat_redo/code/base_skyrat_xeno.dm b/modular_skyrat/modules/xenos_skyrat_redo/code/base_skyrat_xeno.dm index 9a39d931aa2..c4297e8babd 100644 --- a/modular_skyrat/modules/xenos_skyrat_redo/code/base_skyrat_xeno.dm +++ b/modular_skyrat/modules/xenos_skyrat_redo/code/base_skyrat_xeno.dm @@ -191,31 +191,6 @@ mind.transfer_to(xeno_to_transfer_to) qdel(src) -/mob/living/carbon/alien/adult/skyrat/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") - var/fire_icon = "generic_fire[suffix]" - - if(!GLOB.fire_appearances[fire_icon]) - var/mutable_appearance/xeno_fire_overlay = mutable_appearance('icons/mob/effects/onfire.dmi', fire_icon, -FIRE_LAYER, appearance_flags = RESET_COLOR) - xeno_fire_overlay.pixel_x = on_fire_pixel_x - xeno_fire_overlay.pixel_y = on_fire_pixel_y - GLOB.fire_appearances[fire_icon] = xeno_fire_overlay - - if((stacks > 0 && on_fire) || HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE)) - if(fire_icon == last_icon_state) - return last_icon_state - - remove_overlay(FIRE_LAYER) - overlays_standing[FIRE_LAYER] = GLOB.fire_appearances[fire_icon] - apply_overlay(FIRE_LAYER) - return fire_icon - - if(!last_icon_state) - return last_icon_state - - remove_overlay(FIRE_LAYER) - apply_overlay(FIRE_LAYER) - return null - /mob/living/carbon/alien/adult/skyrat/findQueen() //Yes we really do need to do this whole thing to let the queen finder work if(hud_used) hud_used.alien_queen_finder.cut_overlays() diff --git a/tgstation.dme b/tgstation.dme index a3ac49dcddf..ed8a2941e57 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1538,6 +1538,7 @@ #include "code\datums\elements\openspace_item_click_handler.dm" #include "code\datums\elements\ore_collecting.dm" #include "code\datums\elements\organ_set_bonus.dm" +#include "code\datums\elements\permanent_fire_overlay.dm" #include "code\datums\elements\pet_bonus.dm" #include "code\datums\elements\plant_backfire.dm" #include "code\datums\elements\point_of_interest.dm"