Files
Bubberstation/code/modules/client/client_colour.dm
TiviPlus 0eaab0bc54 Grep for space indentation (#54850)
#54604 atomizing
Since a lot of the space indents are in lists ill atomize those later
2020-11-30 12:48:40 -05:00

214 lines
5.9 KiB
Plaintext

#define PRIORITY_ABSOLUTE 1
#define PRIORITY_HIGH 10
#define PRIORITY_NORMAL 100
#define PRIORITY_LOW 1000
/**
* Client Colour Priority System By RemieRichards (then refactored by another contributor)
* A System that gives finer control over which client.colour value to display on screen
* so that the "highest priority" one is always displayed as opposed to the default of
* "whichever was set last is displayed".
*
* Refactored to allow multiple overlapping client colours
* (e.g. wearing blue glasses under a yellow visor, even though the result is a little unsatured.)
* As well as some support for animated colour transitions.
*
* Define subtypes of this datum
*/
/datum/client_colour
///Any client.color-valid value
var/colour = ""
///The mob that owns this client_colour.
var/mob/owner
/**
* We prioritize colours with higher priority (lower numbers), so they don't get overriden by less important ones:
* eg: "Bloody screen" > "goggles colour" as the former is much more important
*/
var/priority = PRIORITY_NORMAL
///Will this client_colour prevent ones of lower priority from being applied?
var/override = FALSE
///IF non-zero, 'animate_client_colour(fade_in)' will be called instead of 'update_client_colour' when added.
var/fade_in = 0
///Same as above, but on removal.
var/fade_out = 0
/datum/client_colour/New(mob/_owner)
owner = _owner
/datum/client_colour/Destroy()
if(!QDELETED(owner))
owner.client_colours -= src
if(fade_out)
owner.animate_client_colour(fade_out)
else
owner.update_client_colour()
owner = null
return ..()
///Sets a new colour, then updates the owner's screen colour.
/datum/client_colour/proc/update_colour(new_colour, anim_time, easing = 0)
colour = new_colour
if(anim_time)
owner.animate_client_colour(anim_time, easing)
else
owner.update_client_colour()
/**
* Adds an instance of colour_type to the mob's client_colours list
* colour_type - a typepath (subtyped from /datum/client_colour)
*/
/mob/proc/add_client_colour(colour_type)
if(!ispath(colour_type, /datum/client_colour) || QDELING(src))
return
var/datum/client_colour/colour = new colour_type(src)
BINARY_INSERT(colour, client_colours, /datum/client_colour, colour, priority, COMPARE_KEY)
if(colour.fade_in)
animate_client_colour(colour.fade_in)
else
update_client_colour()
return colour
/**
* Removes an instance of colour_type from the mob's client_colours list
* colour_type - a typepath (subtyped from /datum/client_colour)
*/
/mob/proc/remove_client_colour(colour_type)
if(!ispath(colour_type, /datum/client_colour))
return
for(var/cc in client_colours)
var/datum/client_colour/colour = cc
if(colour.type == colour_type)
qdel(colour)
break
/**
* Gets the resulting colour/tone from client_colours.
* In the case of multiple colours, they'll be converted to RGBA matrices for compatibility,
* summed together, and then each element divided by the number of matrices. (except we do this with lists because byond)
* target is the target variable.
*/
#define MIX_CLIENT_COLOUR(target)\
var/_our_colour;\
var/_number_colours = 0;\
var/_pool_closed = INFINITY;\
for(var/_c in client_colours){\
var/datum/client_colour/_colour = _c;\
if(_pool_closed < _colour.priority){\
break\
};\
_number_colours++;\
if(_colour.override){\
_pool_closed = _colour.priority\
};\
if(!_our_colour){\
_our_colour = _colour.colour;\
continue\
};\
if(_number_colours == 2){\
_our_colour = color_to_full_rgba_matrix(_our_colour)\
};\
var/list/_colour_matrix = color_to_full_rgba_matrix(_colour.colour);\
var/list/_L = _our_colour;\
for(var/_i in 1 to 20){\
_L[_i] += _colour_matrix[_i]\
};\
};\
if(_number_colours > 1){\
var/list/_L = _our_colour;\
for(var/_i in 1 to 20){\
_L[_i] /= _number_colours\
};\
};\
target = _our_colour\
/**
* Resets the mob's client.color to null, and then reapplies a new color based
* on the client_colour datums it currently has.
*/
/mob/proc/update_client_colour()
if(!client)
return
client.color = ""
if(!client_colours.len)
return
MIX_CLIENT_COLOUR(client.color)
///Works similarly to 'update_client_colour', but animated.
/mob/proc/animate_client_colour(anim_time = 20, anim_easing = 0)
if(!client)
return
if(!client_colours.len)
animate(client, color = "", time = anim_time, easing = anim_easing)
return
MIX_CLIENT_COLOUR(var/anim_colour)
animate(client, color = anim_colour, time = anim_time, easing = anim_easing)
#undef MIX_CLIENT_COLOUR
/datum/client_colour/glass_colour
priority = PRIORITY_LOW
colour = "red"
/datum/client_colour/glass_colour/green
colour = "#aaffaa"
/datum/client_colour/glass_colour/lightgreen
colour = "#ccffcc"
/datum/client_colour/glass_colour/blue
colour = "#aaaaff"
/datum/client_colour/glass_colour/lightblue
colour = "#ccccff"
/datum/client_colour/glass_colour/yellow
colour = "#ffff66"
/datum/client_colour/glass_colour/red
colour = "#ffaaaa"
/datum/client_colour/glass_colour/darkred
colour = "#bb5555"
/datum/client_colour/glass_colour/orange
colour = "#ffbb99"
/datum/client_colour/glass_colour/lightorange
colour = "#ffddaa"
/datum/client_colour/glass_colour/purple
colour = "#ff99ff"
/datum/client_colour/glass_colour/gray
colour = "#cccccc"
/datum/client_colour/monochrome
colour = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
priority = PRIORITY_HIGH //we can't see colors anyway!
override = TRUE
fade_in = 20
fade_out = 20
/datum/client_colour/monochrome/trance
priority = PRIORITY_NORMAL
/datum/client_colour/monochrome/blind
priority = PRIORITY_NORMAL
/datum/client_colour/bloodlust
priority = PRIORITY_ABSOLUTE // Only anger.
colour = list(0,0,0,0,0,0,0,0,0,1,0,0) //pure red.
fade_out = 10
/datum/client_colour/bloodlust/New(mob/_owner)
..()
addtimer(CALLBACK(src, .proc/update_colour, list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0), 10, SINE_EASING|EASE_OUT), 1)
#undef PRIORITY_ABSOLUTE
#undef PRIORITY_HIGH
#undef PRIORITY_NORMAL
#undef PRIORITY_LOW