diff --git a/code/modules/reagents/Chemistry-Colours.dm b/code/modules/reagents/Chemistry-Colours.dm index e81561d733..55e76a07b8 100644 --- a/code/modules/reagents/Chemistry-Colours.dm +++ b/code/modules/reagents/Chemistry-Colours.dm @@ -1,39 +1,67 @@ -/proc/GetColors(hex) //Actually converts hex to rgb - hex = uppertext(hex) - var/hi1 = text2ascii(hex, 2) - var/lo1 = text2ascii(hex, 3) - var/hi2 = text2ascii(hex, 4) - var/lo2 = text2ascii(hex, 5) - var/hi3 = text2ascii(hex, 6) - var/lo3 = text2ascii(hex, 7) - return list(((hi1>= 65 ? hi1-55 : hi1-48)<<4) | (lo1 >= 65 ? lo1-55 : lo1-48), - ((hi2 >= 65 ? hi2-55 : hi2-48)<<4) | (lo2 >= 65 ? lo2-55 : lo2-48), - ((hi3 >= 65 ? hi3-55 : hi3-48)<<4) | (lo3 >= 65 ? lo3-55 : lo3-48)) - /proc/mix_color_from_reagents(var/list/reagent_list) - if(!reagent_list || !reagent_list.len) return 0 + if(!reagent_list || !length(reagent_list)) + return 0 - var/list/rgbcolor = list(0,0,0) - var/finalcolor = 0 - for(var/datum/reagent/re in reagent_list) //TODO: weigh final colour by amount of reagents; make this algorithm use hex - if(!finalcolor) - rgbcolor = GetColors(re.color) - finalcolor = re.color - else - var/newcolor[3] - var/prergbcolor[3] - prergbcolor = rgbcolor - newcolor = GetColors(re.color) + var/contents = length(reagent_list) + var/list/weight = new /list(contents) + var/list/redcolor = new /list(contents) + var/list/greencolor = new /list(contents) + var/list/bluecolor = new /list(contents) + var/i - rgbcolor[1] = (prergbcolor[1]+newcolor[1])/2 - rgbcolor[2] = (prergbcolor[2]+newcolor[2])/2 - rgbcolor[3] = (prergbcolor[3]+newcolor[3])/2 + //fill the list of weights + for(i=1; i<=contents; i++) + var/datum/reagent/re = reagent_list[i] + var/reagentweight = re.volume + if(istype(re, /datum/reagent/paint)) + reagentweight *= 20 //Paint colours a mixture twenty times as much + weight[i] = reagentweight - finalcolor = rgb(rgbcolor[1], rgbcolor[2], rgbcolor[3]) + //fill the lists of colours + for(i=1; i<=contents; i++) + var/datum/reagent/re = reagent_list[i] + var/hue = re.color + if(length(hue) != 7) + return 0 + redcolor[i]=hex2num(copytext(hue,2,4)) + greencolor[i]=hex2num(copytext(hue,4,6)) + bluecolor[i]=hex2num(copytext(hue,6,8)) + + //mix all the colors + var/red = mixOneColor(weight,redcolor) + var/green = mixOneColor(weight,greencolor) + var/blue = mixOneColor(weight,bluecolor) + + //assemble all the pieces + var/finalcolor = "#[red][green][blue]" return finalcolor -// This isn't a perfect color mixing system, the more reagents that are inside, -// the darker it gets until it becomes absolutely pitch black! I dunno, maybe -// that's pretty realistic? I don't do a whole lot of color-mixing anyway. -// If you add brighter colors to it it'll eventually get lighter, though. \ No newline at end of file +/proc/mixOneColor(var/list/weight, var/list/color) + if (!weight || !color || length(weight)!=length(color)) + return 0 + + var/contents = length(weight) + var/i + + //normalize weights + var/listsum = 0 + for(i=1; i<=contents; i++) + listsum += weight[i] + for(i=1; i<=contents; i++) + weight[i] /= listsum + + //mix them + var/mixedcolor = 0 + for(i=1; i<=contents; i++) + mixedcolor += weight[i]*color[i] + mixedcolor = round(mixedcolor) + + //until someone writes a formal proof for this algorithm, let's keep this in + if(mixedcolor<0x00 || mixedcolor>0xFF) + return 0 + + var/finalcolor = num2hex(mixedcolor) + while(length(finalcolor)<2) + finalcolor = text("0[]",finalcolor) //Takes care of leading zeroes + return finalcolor