mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-13 17:14:47 +01:00
datum/client_colour refactor. (#54741)
This commit is contained in:
@@ -57,9 +57,6 @@ GLOBAL_VAR_INIT(cmp_field, "name")
|
||||
/proc/cmp_timer(datum/timedevent/a, datum/timedevent/b)
|
||||
return a.timeToRun - b.timeToRun
|
||||
|
||||
/proc/cmp_clientcolour_priority(datum/client_colour/A, datum/client_colour/B)
|
||||
return B.priority - A.priority
|
||||
|
||||
/proc/cmp_ruincost_priority(datum/map_template/ruin/A, datum/map_template/ruin/B)
|
||||
return initial(A.cost) - initial(B.cost)
|
||||
|
||||
|
||||
@@ -193,3 +193,40 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro
|
||||
for(x in 1 to 4)
|
||||
output[offset+x] = round(A[offset+1]*B[x] + A[offset+2]*B[x+4] + A[offset+3]*B[x+8] + A[offset+4]*B[x+12]+(y==5?B[x+16]:0), 0.001)
|
||||
return output
|
||||
|
||||
///Converts RGB shorthands into RGBA matrices complete of constants rows (ergo a 20 keys list in byond).
|
||||
/proc/color_to_full_rgba_matrix(color)
|
||||
if(istext(color))
|
||||
var/list/L = ReadRGB(color)
|
||||
if(!L)
|
||||
CRASH("Invalid/unsupported color format argument in color_to_full_rgba_matrix()")
|
||||
return list(L[1]/255,0,0,0, 0,L[2]/255,0,0, 0,0,L[3]/255,0, 0,0,0,L.len>3?L[4]/255:1, 0,0,0,0)
|
||||
else if(!islist(color)) //invalid format
|
||||
return color_matrix_identity()
|
||||
var/list/L = color
|
||||
switch(L.len)
|
||||
if(3 to 5) // row-by-row hexadecimals
|
||||
. = list()
|
||||
for(var/a in 1 to L.len)
|
||||
var/list/rgb = ReadRGB(L[a])
|
||||
for(var/b in rgb)
|
||||
. += b/255
|
||||
if(length(rgb) % 4) // RGB has no alpha instruction
|
||||
. += a != 4 ? 0 : 1
|
||||
if(L.len < 4) //missing both alphas and constants rows
|
||||
. += list(0,0,0,1, 0,0,0,0)
|
||||
else if(L.len < 5) //missing constants row
|
||||
. += list(0,0,0,0)
|
||||
if(9 to 12) //RGB
|
||||
. = list(L[1],L[2],L[3],0, L[4],L[5],L[6],0, L[7],L[8],L[9],0, 0,0,0,1)
|
||||
for(var/b in 1 to 3) //missing constants row
|
||||
. += L.len < 9+b ? 0 : L[9+b]
|
||||
. += 0
|
||||
if(16 to 20) // RGBA
|
||||
. = L.Copy()
|
||||
if(L.len < 20) //missing constants row
|
||||
for(var/b in 1 to 20-L.len)
|
||||
. += 0
|
||||
else
|
||||
CRASH("Invalid/unsupported color format argument in color_to_full_rgba_matrix()")
|
||||
|
||||
|
||||
@@ -156,18 +156,17 @@
|
||||
desc = "You feel angry just looking at it."
|
||||
duration = 1200 //2min
|
||||
color = "#FF0000"
|
||||
var/mob/living/doomslayer
|
||||
var/obj/item/chainsaw/doomslayer/chainsaw
|
||||
|
||||
/obj/effect/mine/pickup/bloodbath/mineEffect(mob/living/carbon/victim)
|
||||
if(!victim.client || !istype(victim))
|
||||
return
|
||||
to_chat(victim, "<span class='reallybig redtext'>RIP AND TEAR</span>")
|
||||
var/old_color = victim.client.color
|
||||
var/static/list/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0)
|
||||
var/static/list/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0)
|
||||
|
||||
INVOKE_ASYNC(src, .proc/blood_delusion, victim)
|
||||
|
||||
var/obj/item/chainsaw/doomslayer/chainsaw = new(victim.loc)
|
||||
chainsaw = new(victim.loc)
|
||||
victim.log_message("entered a blood frenzy", LOG_ATTACK)
|
||||
|
||||
ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT)
|
||||
@@ -177,15 +176,18 @@
|
||||
victim.reagents.add_reagent(/datum/reagent/medicine/adminordrazine,25)
|
||||
to_chat(victim, "<span class='warning'>KILL, KILL, KILL! YOU HAVE NO ALLIES ANYMORE, KILL THEM ALL!</span>")
|
||||
|
||||
victim.client.color = pure_red
|
||||
animate(victim.client,color = red_splash, time = 10, easing = SINE_EASING|EASE_OUT)
|
||||
sleep(10)
|
||||
animate(victim.client,color = old_color, time = duration)//, easing = SINE_EASING|EASE_OUT)
|
||||
sleep(duration)
|
||||
to_chat(victim, "<span class='notice'>Your bloodlust seeps back into the bog of your subconscious and you regain self control.</span>")
|
||||
qdel(chainsaw)
|
||||
victim.log_message("exited a blood frenzy", LOG_ATTACK)
|
||||
qdel(src)
|
||||
var/datum/client_colour/colour = victim.add_client_colour(/datum/client_colour/bloodlust)
|
||||
QDEL_IN(colour, 11)
|
||||
doomslayer = victim
|
||||
RegisterSignal(src, COMSIG_PARENT_QDELETING, .proc/end_blood_frenzy)
|
||||
QDEL_IN(src, duration)
|
||||
|
||||
/obj/effect/mine/pickup/bloodbath/proc/end_blood_frenzy()
|
||||
if(doomslayer)
|
||||
to_chat(doomslayer, "<span class='notice'>Your bloodlust seeps back into the bog of your subconscious and you regain self control.</span>")
|
||||
doomslayer.log_message("exited a blood frenzy", LOG_ATTACK)
|
||||
if(chainsaw)
|
||||
qdel(chainsaw)
|
||||
|
||||
/obj/effect/mine/pickup/bloodbath/proc/blood_delusion(mob/living/carbon/victim)
|
||||
new /datum/hallucination/delusion(victim, TRUE, "demon", duration, 0)
|
||||
|
||||
@@ -1,72 +1,155 @@
|
||||
#define PRIORITY_ABSOLUTE 1
|
||||
#define PRIORITY_HIGH 10
|
||||
#define PRIORITY_NORMAL 100
|
||||
#define PRIORITY_LOW 1000
|
||||
|
||||
/*
|
||||
Client Colour Priority System By RemieRichards
|
||||
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"
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Define subtypes of this datum
|
||||
*/
|
||||
/**
|
||||
* 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
|
||||
var/colour = "" //Any client.color-valid value
|
||||
var/priority = 1 //Since only one client.color can be rendered on screen, we take the one with the highest priority value:
|
||||
//eg: "Bloody screen" > "goggles colour" as the former is much more important
|
||||
///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
|
||||
|
||||
/*
|
||||
Adds an instance of colour_type to the mob's client_colours list
|
||||
colour_type - a typepath (subtyped from /datum/client_colour)
|
||||
*/
|
||||
/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/CC = new colour_type()
|
||||
client_colours |= CC
|
||||
sortTim(client_colours, /proc/cmp_clientcolour_priority)
|
||||
update_client_colour()
|
||||
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)
|
||||
*/
|
||||
/**
|
||||
* 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/CC = cc
|
||||
if(CC.type == colour_type)
|
||||
client_colours -= CC
|
||||
qdel(CC)
|
||||
var/datum/client_colour/colour = cc
|
||||
if(colour.type == colour_type)
|
||||
qdel(colour)
|
||||
break
|
||||
update_client_colour()
|
||||
|
||||
/**
|
||||
* 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 sets it to the highest priority
|
||||
client_colour datum, if one exists
|
||||
*/
|
||||
/**
|
||||
* 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
|
||||
var/datum/client_colour/CC = client_colours[1]
|
||||
if(CC)
|
||||
client.color = CC.colour
|
||||
|
||||
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 = 0
|
||||
priority = PRIORITY_LOW
|
||||
colour = "red"
|
||||
|
||||
/datum/client_colour/glass_colour/green
|
||||
@@ -104,10 +187,27 @@
|
||||
|
||||
/datum/client_colour/monochrome
|
||||
colour = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
|
||||
priority = INFINITY //we can't see colors anyway!
|
||||
priority = PRIORITY_HIGH //we can't see colors anyway!
|
||||
override = TRUE
|
||||
fade_in = 20
|
||||
fade_out = 20
|
||||
|
||||
/datum/client_colour/monochrome/trance
|
||||
priority = 1
|
||||
priority = PRIORITY_NORMAL
|
||||
|
||||
/datum/client_colour/monochrome/blind
|
||||
priority = 1
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user