diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 52a302764507..53ab1b691e15 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -40,6 +40,20 @@ /// The range unique planes can be in #define PLANE_RANGE (HIGHEST_EVER_PLANE - LOWEST_EVER_PLANE) +// FLOOR_PLANE layer(s) +// We need to force this plane to render as if we were not using sidemap +// this allows larger then bound floors to layer as we'd expect +// ANYTHING on the floor plane needs TOPDOWN_LAYER, and nothing that isn't on the floor plane can have it + +// NOTICE: we break from the pattern of increasing in steps of like 0.01 here +// Because TOPDOWN_LAYER is 10000 and that's enough to floating point our modifications away + +/// Used to shift all topdown layer emissives to a the game plane equivalent layers, as otherwise they render above everything else due to being KEEP_APART +#define TOPDOWN_TO_EMISSIVE_LAYER(layer) LERP(FLOOR_EMISSIVE_START_LAYER, FLOOR_EMISSIVE_END_LAYER, (layer - (TOPDOWN_LAYER + 1)) / TOPDOWN_LAYER_COUNT) + +// Must be equal to the offset of the highest topdown layer +#define TOPDOWN_LAYER_COUNT 18 + #define SPACE_LAYER 1.8 //#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define #define MID_TURF_LAYER 2.02 @@ -58,6 +72,8 @@ #define CLOSED_TURF_LAYER 2.05 #define BULLET_HOLE_LAYER 2.06 #define ABOVE_NORMAL_TURF_LAYER 2.08 +#define FLOOR_EMISSIVE_START_LAYER 2.09 +#define FLOOR_EMISSIVE_END_LAYER 2.26 #define LATTICE_LAYER 2.2 #define DISPOSAL_PIPE_LAYER 2.3 #define GAS_PIPE_HIDDEN_LAYER 2.35 diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index a9078e83d777..ea2a489864ff 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -81,14 +81,38 @@ /// Uses a dedicated render_target object to copy the entire appearance in real time to the blocking layer. For things that can change in appearance a lot from the base state, like humans. #define EMISSIVE_BLOCK_UNIQUE 2 +#define _EMISSIVE_COLOR(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, val,0,0,0) +#define _EMISSIVE_COLOR_NO_BLOOM(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,val,0,0) +#define _SPECULAR_COLOR(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,val,0) /// The color matrix applied to all emissive overlays. Should be solely dependent on alpha and not have RGB overlap with [EM_BLOCK_COLOR]. -#define EMISSIVE_COLOR list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 1,1,1,0) -/// A globaly cached version of [EMISSIVE_COLOR] for quick access. +#define EMISSIVE_COLOR _EMISSIVE_COLOR(1) +#define EMISSIVE_COLOR_NO_BLOOM _EMISSIVE_COLOR_NO_BLOOM(1) +#define SPECULAR_COLOR _SPECULAR_COLOR(1) +/// A globally cached version of [EMISSIVE_COLOR] for quick access. GLOBAL_LIST_INIT(emissive_color, EMISSIVE_COLOR) +GLOBAL_LIST_INIT(emissive_color_no_bloom, EMISSIVE_COLOR_NO_BLOOM) +GLOBAL_LIST_INIT(specular_color, SPECULAR_COLOR) + +// Types of emissives +/// Emissive that will not have bloom applied to it, encoded into the green channel +#define EMISSIVE_NO_BLOOM 0 +/// Emissive that will get bloom applied to it, encoded into the red channel +#define EMISSIVE_BLOOM 1 +/// Mimics a highly reflective surface, will not have any glow by itself but will amplify any lighting applied to it, encoded into the blue channel +#define EMISSIVE_SPECULAR 2 + +/// Light cutoff of specular emissives, controls how sharp a light must be before it starts reflecting +#define SPECULAR_EMISSIVE_CUTOFF 0.3 +/// Controls how bright specular emissives sourced from overlay lights are +/// Keep in mind that overlay lights are also affected by the specular cutoff, so the maximum light value achievable is (contrast - cutoff) +#define SPECULAR_EMISSIVE_OVERLAY_CONTRAST 1.4 + +#define _EM_BLOCK_COLOR(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,val, 0,0,0,0) /// The color matrix applied to all emissive blockers. Should be solely dependent on alpha and not have RGB overlap with [EMISSIVE_COLOR]. -#define EM_BLOCK_COLOR list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) -/// A globaly cached version of [EM_BLOCK_COLOR] for quick access. +#define EM_BLOCK_COLOR _EM_BLOCK_COLOR(1) +/// A globally cached version of [EM_BLOCK_COLOR] for quick access. GLOBAL_LIST_INIT(em_block_color, EM_BLOCK_COLOR) + /// A set of appearance flags applied to all emissive and emissive blocker overlays. #define EMISSIVE_APPEARANCE_FLAGS (KEEP_APART|KEEP_TOGETHER|RESET_COLOR) /// The color matrix used to mask out emissive blockers on the emissive plane. Alpha should default to zero, be solely dependent on the RGB value of [EMISSIVE_COLOR], and be independant of the RGB value of [EM_BLOCK_COLOR]. diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm index 930ab12b397a..154763a7de46 100644 --- a/code/__HELPERS/icon_smoothing.dm +++ b/code/__HELPERS/icon_smoothing.dm @@ -421,7 +421,7 @@ DEFINE_BITFIELD(smoothing_junction, list( var/turf/neighbor_turf = get_step(src, turned_adjacency & (NORTH|SOUTH)) if(!neighbor_turf) //You can step out of map boundaries return - var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER, plane = FLOOR_PLANE) + var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER, offset_spokesman = src, plane = FLOOR_PLANE) if(!neighbor_turf.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) neighbor_turf = get_step(src, turned_adjacency & (EAST|WEST)) if(!neighbor_turf) //You can step out of map boundaries diff --git a/code/__HELPERS/lighting.dm b/code/__HELPERS/lighting.dm index 08c360849b58..9d962178e7ab 100644 --- a/code/__HELPERS/lighting.dm +++ b/code/__HELPERS/lighting.dm @@ -1,11 +1,42 @@ /// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR]. -/proc/emissive_appearance(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE) - var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS) - appearance.color = GLOB.emissive_color +/proc/emissive_appearance(icon, icon_state = "", atom/offset_spokesman, layer, alpha = 255, appearance_flags = NONE, offset_const, effect_type = EMISSIVE_BLOOM) + if((isnull(layer) || layer == FLOAT_LAYER) && IS_TOPDOWN_PLANE(offset_spokesman.plane)) + layer = TOPDOWN_TO_EMISSIVE_LAYER(offset_spokesman.layer) + else if(isnull(layer)) + layer = FLOAT_LAYER + + var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, offset_spokesman, EMISSIVE_PLANE, 255, appearance_flags | EMISSIVE_APPEARANCE_FLAGS, offset_const) + if(alpha == 255) + switch(effect_type) + if(EMISSIVE_NO_BLOOM) + appearance.color = GLOB.emissive_color_no_bloom + if (EMISSIVE_BLOOM) + appearance.color = GLOB.emissive_color + if (EMISSIVE_SPECULAR) + appearance.color = GLOB.specular_color + else + var/alpha_ratio = alpha/255 + switch(effect_type) + if(EMISSIVE_NO_BLOOM) + appearance.color = _EMISSIVE_COLOR_NO_BLOOM(alpha_ratio) + if (EMISSIVE_BLOOM) + appearance.color = _EMISSIVE_COLOR(alpha_ratio) + if (EMISSIVE_SPECULAR) + appearance.color = _SPECULAR_COLOR(alpha_ratio) + return appearance /// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EM_BLOCK_COLOR]. -/proc/emissive_blocker(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE) - var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS) - appearance.color = GLOB.em_block_color +/proc/emissive_blocker(icon, icon_state = "", atom/offset_spokesman, layer, alpha = 255, appearance_flags = NONE, offset_const) + if (isnull(layer)) + if(IS_TOPDOWN_PLANE(offset_spokesman.plane)) + layer = TOPDOWN_TO_EMISSIVE_LAYER(offset_spokesman.layer) + else + layer = FLOAT_LAYER + var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, offset_spokesman, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS, offset_const) + if(alpha == 255) + appearance.color = GLOB.em_block_color + else + var/alpha_ratio = alpha/255 + appearance.color = _EM_BLOCK_COLOR(alpha_ratio) return appearance diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index b475b5707ae1..acc8bc697c47 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -212,6 +212,7 @@ GLOBAL_LIST_EMPTY(radial_menus) if(choice_id == NEXT_PAGE_ID) E.name = "Next Page" E.next_page = TRUE + E.icon_state = "radial_slice" // Resets the bg icon state to the default for next page buttons. E.add_overlay("radial_next") else if(istext(choices_values[choice_id])) @@ -267,6 +268,7 @@ GLOBAL_LIST_EMPTY(radial_menus) var/mutable_appearance/MA = new /mutable_appearance(to_extract_from) if(MA) + SET_PLANE_EXPLICIT(MA, ABOVE_HUD_PLANE, anchor) MA.layer = ABOVE_HUD_LAYER MA.appearance_flags |= RESET_TRANSFORM return MA @@ -285,9 +287,12 @@ GLOBAL_LIST_EMPTY(radial_menus) current_user = M.client //Blank menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing",layer = ABOVE_HUD_LAYER) - menu_holder.plane = ABOVE_HUD_PLANE + + SET_PLANE_EXPLICIT(menu_holder, ABOVE_HUD_PLANE, M) menu_holder.appearance_flags |= KEEP_APART menu_holder.vis_contents += elements + close_button + if(!isnull(close_button)) + menu_holder.vis_contents += close_button current_user.images += menu_holder /datum/radial_menu/proc/hide() diff --git a/code/datums/components/attachment.dm b/code/datums/components/attachment.dm index 5c0aa915c697..d4b06d1e180f 100644 --- a/code/datums/components/attachment.dm +++ b/code/datums/components/attachment.dm @@ -145,7 +145,7 @@ overlay_layer = parent.render_layer if(parent.render_plane) overlay_layer = parent.render_plane - overlays += mutable_appearance(parent.icon, "[parent.icon_state]-attached",overlay_layer,overlay_plane) + overlays += mutable_appearance(parent.icon, "[parent.icon_state]-attached", plane = overlay_layer, alpha = overlay_plane) /datum/component/attachment/proc/try_attach(obj/item/parent, obj/item/holder, mob/user, bypass_checks) SIGNAL_HANDLER diff --git a/code/datums/elements/turf_transparency.dm b/code/datums/elements/turf_transparency.dm index 715c6ab4ecbd..cc2e67ec3f37 100644 --- a/code/datums/elements/turf_transparency.dm +++ b/code/datums/elements/turf_transparency.dm @@ -72,7 +72,7 @@ if(!ispath(path)) warning("Z-level [our_turf.z] has invalid baseturf '[our_turf.virtual_level_trait(ZTRAIT_BASETURF)]'") path = /turf/open/space - var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER-0.02, plane = PLANE_SPACE) + var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = SPACE_LAYER + 0.1, offset_spokesman = our_turf, plane = PLANE_SPACE) underlay_appearance.appearance_flags = RESET_ALPHA | RESET_COLOR our_turf.underlays += underlay_appearance return TRUE diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm index f248da2a7323..04b22e63627a 100644 --- a/code/datums/mutable_appearance.dm +++ b/code/datums/mutable_appearance.dm @@ -4,18 +4,34 @@ // Mutable appearances are children of images, just so you know. -/mutable_appearance/New() +// Mutable appearances erase template vars on new, because they accept an appearance to copy as an arg +// If we have nothin to copy, we set the float plane +/mutable_appearance/New(mutable_appearance/to_copy) ..() - plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE - // And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var + if(!to_copy) + plane = FLOAT_PLANE // Helper similar to image() -/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE) - var/mutable_appearance/MA = new() - MA.icon = icon - MA.icon_state = icon_state - MA.layer = layer - MA.plane = plane - MA.alpha = alpha - MA.appearance_flags |= appearance_flags - return MA +/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, atom/offset_spokesman, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, offset_const) + var/mutable_appearance/appearance = new() + appearance.icon = icon + appearance.icon_state = icon_state + appearance.layer = layer + appearance.alpha = alpha + appearance.appearance_flags |= appearance_flags + if(plane != FLOAT_PLANE) + // You need to pass in some non null object to reference + if(isatom(offset_spokesman)) + // Note, we are ok with null turfs, that's not an error condition we'll just default to 0, the error would be + // Not passing ANYTHING in, key difference + SET_PLANE_EXPLICIT(appearance, plane, offset_spokesman) + // That or I'll let you pass in a static offset. Don't be stupid now + else if(!isnull(offset_const)) + SET_PLANE_W_SCALAR(appearance, plane, offset_const) + // otherwise if you're setting plane you better have the guts to back it up + else + stack_trace("No plane offset passed in as context for a non floating mutable appearance, things are gonna go to hell on multiz maps") + else if(!isnull(offset_spokesman) && !isatom(offset_spokesman)) + stack_trace("Why did you pass in offset_spokesman as [offset_spokesman]? We need an atom to properly offset planes") + + return appearance diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 0aa00b5630dd..6c24636f1e4b 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -718,11 +718,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27) emissive_state = "alarm2" . += mutable_appearance(icon, emissive_state) - . += mutable_appearance(icon, "light_emissive", layer, EMISSIVE_PLANE) + . += mutable_appearance(icon, "light_emissive", layer, src, plane = EMISSIVE_PLANE) if(perc_danger_level) //When there's any danger level, light up the "AIR" sign too . += mutable_appearance(icon, "alarm_sign") - . += mutable_appearance(icon, "alarm_sign", layer, EMISSIVE_PLANE) + . += mutable_appearance(icon, "alarm_sign", layer, src, plane = EMISSIVE_PLANE) /obj/machinery/airalarm/process(seconds_per_tick) if((machine_stat & (NOPOWER|BROKEN)) || shorted) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm index 2a36f15169f5..1166f9f071ff 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm @@ -115,6 +115,11 @@ if(icon_state != icon_aggro) icon_state = icon_aggro +/mob/living/simple_animal/hostile/asteroid/goliath/update_overlays() + . = ..() + if (stat != DEAD) + . += emissive_appearance(icon, "[icon_living]_e", src, effect_type = EMISSIVE_NO_BLOOM) + /mob/living/simple_animal/hostile/asteroid/goliath/pup name = "goliath pup" desc = "An immature goliath. Goliaths at this stage of life lack fully-developed tendrils, and are reliant on their parents to unearth and supply food." @@ -291,35 +296,90 @@ //tentacles /obj/effect/temp_visual/goliath_tentacle name = "goliath tentacle" - icon = 'icons/mob/lavaland/lavaland_monsters.dmi' - icon_state = "Goliath_tentacle_wiggle" + icon = 'icons/mob/lavaland/lavaland_monsters2.dmi' + icon_state = "goliath_tentacle_spawn" layer = BELOW_MOB_LAYER var/mob/living/spawner - var/wiggle = "Goliath_tentacle_spawn" - var/retract = "Goliath_tentacle_retract" + var/wiggle = "goliath_tentacle_wiggle" + var/retract = "goliath_tentacle_retract" var/difficulty = 3 -/obj/effect/temp_visual/goliath_tentacle/Initialize(mapload, mob/living/new_spawner,recursive = FALSE) +/obj/effect/temp_visual/goliath_tentacle/update_overlays() + . = ..() + . += emissive_appearance('icons/mob/lavaland/lavaland_monsters2.dmi', "[icon_state]_e", src, effect_type = EMISSIVE_NO_BLOOM) + . += emissive_appearance('icons/mob/lavaland/lavaland_monsters2.dmi', "[icon_state]_e_bloom", src) + +// Позже удалить, пока для примера останется тут. +/// A tentacle which grabs you if you don't get away from it +/obj/effect/goliath_tentacle + name = "goliath tentacle" + icon = 'icons/mob/lavaland/lavaland_monsters2.dmi' + icon_state = "goliath_tentacle_spawn" + layer = BELOW_MOB_LAYER + plane = GAME_PLANE + anchored = TRUE + /// Timer for our current action stage + var/action_timer + /// Time in which to grab people + var/grapple_time = 10 SECONDS + +/obj/effect/goliath_tentacle/Initialize(mapload, mob/living/new_spawner,recursive = FALSE) . = ..() - flick(wiggle,src) - for(var/obj/effect/temp_visual/goliath_tentacle/T in loc) - if(T != src) + if (ismineralturf(loc)) + var/turf/closed/mineral/floor = loc + floor.gets_drilled() + if (!isopenturf(loc) || isspaceturf(loc)) + return INITIALIZE_HINT_QDEL + for (var/obj/effect/temp_visual/goliath_tentacle/tentacle in loc) + if (tentacle != src) return INITIALIZE_HINT_QDEL - if(!QDELETED(new_spawner)) - spawner = new_spawner - if(ismineralturf(loc)) - var/turf/closed/mineral/M = loc - M.gets_drilled() - deltimer(timerid) - timerid = addtimer(CALLBACK(src, PROC_REF(tripanim)), 7, TIMER_STOPPABLE) - if(!recursive) + deltimer(action_timer) + action_timer = addtimer(CALLBACK(src, PROC_REF(animate_grab)), 0.7 SECONDS, TIMER_STOPPABLE) + update_appearance(UPDATE_OVERLAYS) + +/obj/effect/goliath_tentacle/Destroy() + deltimer(action_timer) + return ..() + +/// Change to next icon state and set up grapple +/obj/effect/goliath_tentacle/proc/animate_grab() + icon_state = "goliath_tentacle_wiggle" + update_appearance(UPDATE_OVERLAYS) + deltimer(action_timer) + addtimer(CALLBACK(src, PROC_REF(grab)), 0.3 SECONDS, TIMER_STOPPABLE) + +/// Grab everyone we share space with. If it's nobody, go home. +/obj/effect/goliath_tentacle/proc/grab() + for (var/mob/living/victim in loc) + if (victim.stat == DEAD) //if (victim.stat == DEAD || HAS_TRAIT(victim, TRAIT_TENTACLE_IMMUNE)) + continue + balloon_alert(victim, "grabbed") + visible_message(span_danger("[src] grabs hold of [victim]!")) + victim.apply_damage(rand(10,20), BRUTE, pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG), wound_bonus = CANT_WOUND) //already dangerous, don't break legs too + if(iscarbon(victim)) + var/obj/item/restraints/legcuffs/beartrap/goliath/B = new /obj/item/restraints/legcuffs/beartrap/goliath(get_turf(victim)) + B.on_entered(src, victim) + if (!has_buckled_mobs()) + retract() return - var/list/directions = get_directions() - for(var/i in 1 to difficulty) - var/spawndir = pick_n_take(directions) - var/turf/T = get_step(src, spawndir) - if(T) - new type(T, spawner) + deltimer(action_timer) + action_timer = addtimer(CALLBACK(src, PROC_REF(retract)), grapple_time, TIMER_STOPPABLE) + +/// Play exit animation. +/obj/effect/goliath_tentacle/proc/retract() + if (icon_state == "goliath_tentacle_retract") + return // Already retracting + //SEND_SIGNAL(src, COMSIG_GOLIATH_TENTACLE_RETRACTING) + unbuckle_all_mobs(force = TRUE) + icon_state = "goliath_tentacle_retract" + update_appearance(UPDATE_OVERLAYS) + deltimer(action_timer) + action_timer = QDEL_IN_STOPPABLE(src, 0.7 SECONDS) + +/obj/effect/goliath_tentacle/update_overlays() + . = ..() + . += emissive_appearance(icon, "[icon_state]_e", src, effect_type = EMISSIVE_NO_BLOOM) + . += emissive_appearance(icon, "[icon_state]_e_bloom", src) /obj/effect/temp_visual/goliath_tentacle/proc/get_directions() return GLOB.cardinals.Copy() diff --git a/code/modules/power/floodlight.dm b/code/modules/power/floodlight.dm index cad098e93d95..13a00e342b69 100644 --- a/code/modules/power/floodlight.dm +++ b/code/modules/power/floodlight.dm @@ -56,7 +56,7 @@ /obj/machinery/power/floodlight name = "floodlight" desc = "A pole with powerful mounted lights on it. Due to its high power draw, it must be powered by a direct connection to a wire node." - icon = 'icons/obj/lighting.dmi' + icon = 'mod_celadon/_storage_icons/icons/structures/obj/lighting.dmi' //icon = 'icons/obj/lighting.dmi' // [CELADON-EDIT] icon_state = "floodlight" density = TRUE max_integrity = 100 diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index afc0692513a6..2109b1d3c928 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -208,7 +208,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/light_construct/small, 28) /obj/machinery/light name = "light fixture" icon = 'icons/obj/lighting.dmi' - var/base_state = "tube" // base description and icon_state icon_state = "tube-on" desc = "A lighting fixture." layer = BELOW_OBJ_LAYER @@ -217,6 +216,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/light_construct/small, 28) idle_power_usage = 0 active_power_usage = 0 power_channel = AREA_USAGE_LIGHT //Lights are calc'd via area so they dont need to be in the machine list + // base description and icon_state + var/base_state = "tube" var/on = FALSE // 1 if on, 0 if off var/on_gs = FALSE var/static_power_used = 0 @@ -257,6 +258,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/light_construct/small, 28) ///wallmount trait var/is_wallmounted = TRUE + var/mod_light = FALSE // [CELADON-ADD] + /obj/machinery/light/Initialize(mapload) . = ..() if(is_wallmounted) @@ -333,8 +336,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/small/built, 28) //Setup area colours -pb var/area/A = get_area(src) if(bulb_colour == initial(bulb_colour)) - if(istype(src, /obj/machinery/light/small)) - bulb_colour = A.lighting_colour_bulb + if(istype(src, /obj/machinery/light/colored)) // [CELADON-EDIT] brightness = A.lighting_brightness_bulb else bulb_colour = A.lighting_colour_tube @@ -378,6 +380,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/small/built, 28) return ..() /obj/machinery/light/update_icon_state() + if(mod_light == TRUE) // [CELADON-ADD] + return ..() // [/CELADON-ADD] switch(status) // set icon_states if(LIGHT_OK) var/area/A = get_area(src) diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 44618e94c056..d13d81cad046 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -249,7 +249,7 @@ . += lips_overlay // eyes - var/mutable_appearance/sclera_overlay = mutable_appearance('icons/mob/human_face.dmi', "", -BODY_LAYER, SOUTH) + var/mutable_appearance/sclera_overlay = mutable_appearance('icons/mob/human_face.dmi', "", -BODY_LAYER, src, SOUTH) var/image/eyes_overlay = image('icons/mob/human_face.dmi', "eyes_missing", -BODY_LAYER, SOUTH) . += eyes_overlay diff --git a/icons/mob/lavaland/lavaland_monsters2.dmi b/icons/mob/lavaland/lavaland_monsters2.dmi new file mode 100644 index 000000000000..3f5eb9cbd3b5 Binary files /dev/null and b/icons/mob/lavaland/lavaland_monsters2.dmi differ diff --git a/mod_celadon/_storage_icons/icons/structures/obj/lighting.dmi b/mod_celadon/_storage_icons/icons/structures/obj/lighting.dmi new file mode 100644 index 000000000000..58048c0e69ea Binary files /dev/null and b/mod_celadon/_storage_icons/icons/structures/obj/lighting.dmi differ diff --git a/mod_celadon/_storage_icons/icons/structures/obj/lighting_editor.dmi b/mod_celadon/_storage_icons/icons/structures/obj/lighting_editor.dmi new file mode 100644 index 000000000000..94bf54358e58 Binary files /dev/null and b/mod_celadon/_storage_icons/icons/structures/obj/lighting_editor.dmi differ diff --git a/mod_celadon/_storage_icons/icons/structures/obj/lighting_overlay.dmi b/mod_celadon/_storage_icons/icons/structures/obj/lighting_overlay.dmi new file mode 100644 index 000000000000..df3f480f25c7 Binary files /dev/null and b/mod_celadon/_storage_icons/icons/structures/obj/lighting_overlay.dmi differ diff --git a/mod_celadon/neon_pack/code/light.dm b/mod_celadon/neon_pack/code/light.dm index 3964687df222..533f74402602 100644 --- a/mod_celadon/neon_pack/code/light.dm +++ b/mod_celadon/neon_pack/code/light.dm @@ -1,89 +1,136 @@ // Coloured lighting because fabulous /obj/machinery/light/colored name = "light fixture" - icon = 'mod_celadon/_storage_icons/icons/structures/obj/coloredlights.dmi' - base_state = "yellow" // base description and icon_state - icon_state = "yellow1" - // emissive_state = "emissive" desc = "A lighting fixture." + icon = MAP_SWITCH('mod_celadon/_storage_icons/icons/structures/obj/lighting.dmi', 'mod_celadon/_storage_icons/icons/structures/obj/lighting_editor.dmi') + icon_state = "tube_editor" + base_state = "tube" brightness = 8 bulb_power = 6 - light_color = LIGHT_COLOR_HALOGEN - var/emissive_state = "tube-emissive" - // var/on_wall = 1 + ///What overlay the light should use + var/overlay_icon = 'mod_celadon/_storage_icons/icons/structures/obj/lighting_overlay.dmi' + mod_light = TRUE /obj/machinery/light/colored/update_icon_state() . = ..() - cut_overlays() switch(status) if(LIGHT_OK) - icon_state = (on ? "[base_state]1" : "off") - if(on && emissive_state) - add_overlay(emissive_appearance(icon, emissive_state)) + var/area/local_area = get_area(src) + if(emergency_mode || (local_area?.fire)) + icon_state = "[base_state]-emergency" + else if(local_area?.vacuum) + icon_state = "[base_state]-vacuum" + else + icon_state = "[base_state]" if(LIGHT_EMPTY) - icon_state = "empty" - on = 0 + icon_state = "[base_state]-empty" if(LIGHT_BURNED) - icon_state = "tube-burned" - on = 0 + icon_state = "[base_state]-burned" if(LIGHT_BROKEN) - icon_state = "tube-broken" - on = 0 + icon_state = "[base_state]-broken" -MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/colored, 13) +/obj/machinery/light/colored/update_overlays() + . = ..() + if(!on || status != LIGHT_OK) + return + + . += emissive_appearance(overlay_icon, "[base_state]", src, alpha = src.alpha) + + if(flickering) + . += mutable_appearance(overlay_icon, "[base_state]_flickering") + return + var/area/local_area = get_area(src) + if(emergency_mode || (local_area?.fire) || (local_area?.vacuum)) + . += emissive_appearance(overlay_icon, "[base_state]_emergency") + return + var/mutable_appearance/light = mutable_appearance(overlay_icon, base_state) + if(local_area?.vacuum) + light.color = COLOR_BLUE + else if(nightshift_enabled) + . += mutable_appearance(overlay_icon, "[base_state]_nightshift") + return + else + light.color = bulb_colour + . += light /obj/machinery/light/colored/orange - base_state = "orange" // base description and icon_state - icon_state = "orange1" - color = LIGHT_COLOR_ORANGE - light_color = LIGHT_COLOR_ORANGE - -MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/orange, 13) + bulb_colour = LIGHT_COLOR_ORANGE + nightshift_light_color = LIGHT_COLOR_ORANGE + icon_state = "tube_editor_orange" /obj/machinery/light/colored/purple - base_state = "purple" // base description and icon_state - icon_state = "purple1" - color = LIGHT_COLOR_PURPLE - light_color = LIGHT_COLOR_PURPLE - -MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/purple, 13) + bulb_colour = LIGHT_COLOR_PURPLE + nightshift_light_color = LIGHT_COLOR_PURPLE + icon_state = "tube_editor_purple" /obj/machinery/light/colored/red - base_state = "red" // base description and icon_state - icon_state = "red1" - color = LIGHT_COLOR_RED - light_color = LIGHT_COLOR_RED - -MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/red, 13) + bulb_colour = LIGHT_COLOR_RED + nightshift_light_color = LIGHT_COLOR_RED + icon_state = "tube_editor_red" /obj/machinery/light/colored/pink - base_state = "pink" // base description and icon_state - icon_state = "pink1" - color = LIGHT_COLOR_PINK - light_color = LIGHT_COLOR_PINK - -MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/pink, 13) + bulb_colour = LIGHT_COLOR_PINK + nightshift_light_color = LIGHT_COLOR_PINK + icon_state = "tube_editor_pink" /obj/machinery/light/colored/blue - base_state = "blue" // base description and icon_state - icon_state = "blue1" - color = LIGHT_COLOR_BLUE light_color = LIGHT_COLOR_BLUE - -MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/blue, 13) + nightshift_light_color = LIGHT_COLOR_BLUE + icon_state = "tube_editor_blue" /obj/machinery/light/colored/green - base_state = "green" // base description and icon_state - icon_state = "green1" - color = LIGHT_COLOR_GREEN - light_color = LIGHT_COLOR_GREEN - -MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/green, 13) + bulb_colour = LIGHT_COLOR_GREEN + nightshift_light_color = LIGHT_COLOR_GREEN + icon_state = "tube_editor_green" /obj/machinery/light/colored/white - base_state = "white" // base description and icon_state - icon_state = "white1" - color = "#f0ffff" - light_color = "#f0ffff" - -MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/white, 13) + icon_state = "tube_editor" +/* +/obj/machinery/light/colored/built + icon_state = "tube-empty" + start_with_cell = FALSE + +/obj/machinery/light/small/mod + icon_state = "tube_editor_green" + +/obj/machinery/light/small/mod/broken + status = LIGHT_BROKEN + icon_state = "bulb-broken" + +/obj/machinery/light/small/mod/built + icon_state = "bulb-empty" + start_with_cell = FALSE +*/ + +// [HORIZON-ADD] +/// Create directional subtypes for a path to simplify mapping. +#define MAPPING_INVERSE_DIRECTIONAL_HELPERS(path, offset) ##path/directional/north {\ + dir = NORTH; \ + pixel_y = offset + 12; \ +} \ +##path/directional/south {\ + dir = SOUTH; \ + pixel_y = -offset - 6; \ +} \ +##path/directional/east {\ + dir = EAST; \ + pixel_x = offset + 8; \ +} \ +##path/directional/west {\ + dir = WEST; \ + pixel_x = -offset - 8; \ +} +// [/HORIZON-ADD] + +MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/small/broken, 28) +MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/light/built, 32) + +MAPPING_INVERSE_DIRECTIONAL_HELPERS(/obj/machinery/light/colored, 0) +MAPPING_INVERSE_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/default, 0) +MAPPING_INVERSE_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/orange, 0) +MAPPING_INVERSE_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/purple, 0) +MAPPING_INVERSE_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/red, 0) +MAPPING_INVERSE_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/pink, 0) +MAPPING_INVERSE_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/blue, 0) +MAPPING_INVERSE_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/green, 0) +MAPPING_INVERSE_DIRECTIONAL_HELPERS(/obj/machinery/light/colored/white, 0) diff --git a/mod_celadon/neon_pack/code/signs.dm b/mod_celadon/neon_pack/code/signs.dm index e11e59b1e42a..731080f3ca55 100644 --- a/mod_celadon/neon_pack/code/signs.dm +++ b/mod_celadon/neon_pack/code/signs.dm @@ -9,7 +9,7 @@ /obj/structure/sign/neon/Initialize() . = ..() if(emissive_state) - add_overlay(emissive_appearance(icon, emissive_state)) + add_overlay(emissive_appearance(icon, emissive_state, src)) /obj/structure/sign/neon/item name = "item store" @@ -225,7 +225,7 @@ /obj/structure/sign/neon/trafficsign/Initialize() . = ..() add_overlay(overlay_state) - add_overlay(emissive_appearance(icon, overlay_state)) + add_overlay(emissive_appearance(icon, overlay_state, src)) /obj/structure/sign/neon/trafficsign/emergency_stop name = "secondary road traffic sign"