mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 04:30:44 +01:00
Hologram Touchup (Init savings edition) (#74793)
## About The Pull Request ### Polishes and Reworks Holograms Hologram generation currently involves a bunch of icon operations, which are slow. Not to mention a series of get flats for the human models, which is even worse. We lose 0.05 seconds of init to em off just the 2 RCD holograms. it hurts man. So instead, let's use filters and render steps to achive the same effect. While I'm here I'll dim the holo light and make it blue, make the hologram and its beam emissive (so they glow), and do some fenangling with move_hologram() (it doesn't clear the hologram off failure anymore, instead relying on callers to do that) to ensure holocalls can't be accidentially ended by moving out of the area. Ah and I added RESET_ALPHA to the emissive appearance flags, cause the alpha does override and fuck with color rendering, which ends up looking dumb. If we're gonna support this stuff it should be first class not accidential. ### Makes Static Not Shit While I'm here (since holograms see static) lets ensure the static plane is always visible if you're seeing through an ai eye. The old solution was limited to applying it to JUST ais, which isn't satisfactory for this sort of thing and missed a LOT of cases (I didn't really get how ai eyes worked before I'ma be honest) I'm adding a signal off the hud for it detecting a change in its eye here. This is semi redundant, but avoids unneeded dupe work, so I'm ok with it. The pipeline here is less sane then I'd like, but it works and that's enough ## Why It's Good For The Game  More pretty, better ux, **static works** ## Changelog 🆑 add: Holograms glow now, pokes at the lighting for holocalls in general a bit to make em nicer. qol: You can no longer accidentally end a holocall (as a non ai) by leaving the area. Felt like garbage fix: Fixes static rendering improperly if viewed by a non ai /🆑
This commit is contained in:
@@ -1,2 +1,5 @@
|
||||
/// Sent from /datum/hud/proc/on_eye_change(): (atom/old_eye, atom/new_eye)
|
||||
#define COMSIG_HUD_EYE_CHANGED "hud_eye_changed"
|
||||
/// Sent from /datum/hud/proc/eye_z_changed() : (old_offset, new_offset)
|
||||
#define COMSIG_HUD_OFFSET_CHANGED "hud_offset_changed"
|
||||
|
||||
|
||||
@@ -76,7 +76,8 @@ GLOBAL_LIST_INIT(emissive_color, EMISSIVE_COLOR)
|
||||
/// A globaly 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)
|
||||
/// KEEP_APART to prevent parent hooking, KEEP_TOGETHER for children, and we reset the color and alpha of our parent so nothing gets overriden
|
||||
#define EMISSIVE_APPEARANCE_FLAGS (KEEP_APART|KEEP_TOGETHER|RESET_COLOR|RESET_ALPHA)
|
||||
/// 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].
|
||||
#define EM_MASK_MATRIX list(0,0,0,1/3, 0,0,0,1/3, 0,0,0,1/3, 0,0,0,0, 1,1,1,0)
|
||||
/// A globaly cached version of [EM_MASK_MATRIX] for quick access.
|
||||
|
||||
@@ -134,10 +134,12 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
|
||||
update_sightflags(mymob, mymob.sight, NONE)
|
||||
|
||||
/datum/hud/proc/client_refresh(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
RegisterSignal(mymob.client, COMSIG_CLIENT_SET_EYE, PROC_REF(on_eye_change))
|
||||
on_eye_change(null, null, mymob.client.eye)
|
||||
|
||||
/datum/hud/proc/clear_client(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
if(mymob.canon_client)
|
||||
UnregisterSignal(mymob.canon_client, COMSIG_CLIENT_SET_EYE)
|
||||
|
||||
@@ -148,6 +150,8 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
|
||||
|
||||
/datum/hud/proc/on_eye_change(datum/source, atom/old_eye, atom/new_eye)
|
||||
SIGNAL_HANDLER
|
||||
SEND_SIGNAL(src, COMSIG_HUD_EYE_CHANGED, old_eye, new_eye)
|
||||
|
||||
if(old_eye)
|
||||
UnregisterSignal(old_eye, COMSIG_MOVABLE_Z_CHANGED)
|
||||
if(new_eye)
|
||||
@@ -158,6 +162,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
|
||||
eye_z_changed(new_eye)
|
||||
|
||||
/datum/hud/proc/update_sightflags(datum/source, new_sight, old_sight)
|
||||
SIGNAL_HANDLER
|
||||
// If neither the old and new flags can see turfs but not objects, don't transform the turfs
|
||||
// This is to ensure parallax works when you can't see holder objects
|
||||
if(should_sight_scale(new_sight) == should_sight_scale(old_sight))
|
||||
|
||||
@@ -550,18 +550,31 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
|
||||
documentation = "Holds camera static images. Usually only visible to people who can well, see static.\
|
||||
<br>We use images rather then vis contents because they're lighter on maptick, and maptick sucks butt."
|
||||
plane = CAMERA_STATIC_PLANE
|
||||
start_hidden = TRUE
|
||||
|
||||
/atom/movable/screen/plane_master/camera_static/show_to(mob/mymob)
|
||||
// If we aren't an AI, we have no need for this plane master (most of the time, ai eyes are weird and annoying)
|
||||
if(force_hidden && isAI(mymob))
|
||||
unhide_plane(mymob)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(isAI(mymob))
|
||||
var/datum/hud/our_hud = home.our_hud
|
||||
if(isnull(our_hud))
|
||||
return
|
||||
return FALSE
|
||||
|
||||
// We'll hide the slate if we're not seeing through a camera eye
|
||||
// This can call on a cycle cause we don't clear in hide_from
|
||||
// Yes this is the best way of hooking into the hud, I hate myself too
|
||||
RegisterSignal(our_hud, COMSIG_HUD_EYE_CHANGED, PROC_REF(eye_changed), override = TRUE)
|
||||
eye_changed(our_hud, null, our_hud.mymob?.client?.eye)
|
||||
|
||||
/atom/movable/screen/plane_master/camera_static/proc/eye_changed(datum/hud/source, atom/old_eye, atom/new_eye)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!isaicamera(new_eye))
|
||||
if(!force_hidden)
|
||||
hide_plane(source.mymob)
|
||||
return
|
||||
|
||||
if(force_hidden)
|
||||
unhide_plane(source.mymob)
|
||||
|
||||
/atom/movable/screen/plane_master/high_game
|
||||
name = "High Game"
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
/mob/camera/ai_eye/remote/holo/setLoc(turf/destination, force_update = FALSE)
|
||||
. = ..()
|
||||
// If we're moving outside the space of our projector, then just... don't
|
||||
var/obj/machinery/holopad/H = origin
|
||||
H?.move_hologram(eye_user, loc)
|
||||
if(!H?.move_hologram(eye_user, destination))
|
||||
sprint = initial(sprint) // Reset sprint so it doesn't balloon in our calling proc
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/holopad/remove_eye_control(mob/living/user)
|
||||
if(user.client)
|
||||
@@ -63,9 +66,7 @@
|
||||
//cleans up ALL references :)
|
||||
/datum/holocall/Destroy()
|
||||
QDEL_NULL(hangup)
|
||||
|
||||
if(!QDELETED(eye))
|
||||
QDEL_NULL(eye)
|
||||
QDEL_NULL(eye)
|
||||
|
||||
if(connected_holopad && !QDELETED(hologram))
|
||||
hologram = null
|
||||
|
||||
@@ -2098,3 +2098,39 @@
|
||||
if(caller && (caller.pass_flags & pass_flags_self))
|
||||
return TRUE
|
||||
. = !density
|
||||
|
||||
/// Makes this atom look like a "hologram"
|
||||
/// So transparent, blue, with a scanline and an emissive glow
|
||||
/// This is acomplished using a combination of filters and render steps/overlays
|
||||
/// The degree of the opacity is optional, based off the opacity arg (0 -> 1)
|
||||
/atom/proc/makeHologram(opacity = 0.5)
|
||||
// First, we'll make things blue (roughly) and sorta transparent
|
||||
add_filter("HOLO: Color and Transparent", 1, color_matrix_filter(rgb(125,180,225, opacity * 255)))
|
||||
// Now we're gonna do a scanline effect
|
||||
// Gonna take this atom and give it a render target, then use it as a source for a filter
|
||||
// (We use an atom because it seems as if setting render_target on an MA is just invalid. I hate this engine)
|
||||
var/static/atom/movable/scanline
|
||||
if(!scanline)
|
||||
scanline = new(null)
|
||||
scanline.icon = 'icons/effects/effects.dmi'
|
||||
scanline.icon_state = "scanline"
|
||||
// * so it doesn't render
|
||||
scanline.render_target = "*HoloScanline"
|
||||
// Now we add it as a filter, and overlay the appearance so the render source is always around
|
||||
add_filter("HOLO: Scanline", 2, alpha_mask_filter(render_source = scanline.render_target))
|
||||
add_overlay(scanline)
|
||||
// Annd let's make the sucker emissive, so it glows in the dark
|
||||
if(!render_target)
|
||||
var/static/uid = 0
|
||||
render_target = "HOLOGRAM [uid]"
|
||||
uid++
|
||||
// I'm using static here to reduce the overhead, it does mean we need to do plane stuff manually tho
|
||||
var/static/atom/movable/render_step/emissive/glow = new(null)
|
||||
glow.render_source = render_target
|
||||
SET_PLANE_EXPLICIT(glow, initial(glow.plane), src)
|
||||
// We're creating a render step that copies ourselves, and draws it to the emissive plane
|
||||
// Then we overlay it, and release "ownership" back to this proc, since we get to keep the appearance it generates
|
||||
// We can't just use an MA from the start cause render_source setting starts going fuckey REALLY quick
|
||||
var/mutable_appearance/glow_appearance = new(glow)
|
||||
add_overlay(glow_appearance)
|
||||
LAZYADD(update_overlays_on_z, glow_appearance)
|
||||
|
||||
@@ -92,9 +92,6 @@
|
||||
user.remote_control = null
|
||||
current_user = null
|
||||
user.unset_machine()
|
||||
|
||||
for(var/atom/movable/screen/plane_master/plane_static in user.hud_used?.get_true_plane_masters(CAMERA_STATIC_PLANE))
|
||||
plane_static.hide_plane(user)
|
||||
playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE)
|
||||
|
||||
/obj/machinery/computer/camera_advanced/check_eye(mob/user)
|
||||
@@ -179,9 +176,6 @@
|
||||
eyeobj.setLoc(eyeobj.loc)
|
||||
if(should_supress_view_changes)
|
||||
user.client.view_size.supress()
|
||||
// Who passes control like this god I hate static code
|
||||
for(var/atom/movable/screen/plane_master/plane_static in user.hud_used?.get_true_plane_masters(CAMERA_STATIC_PLANE))
|
||||
plane_static.unhide_plane(user)
|
||||
|
||||
/mob/camera/ai_eye/remote
|
||||
name = "Inactive Camera Eye"
|
||||
|
||||
@@ -45,6 +45,9 @@ Possible to do for anyone motivated enough:
|
||||
max_integrity = 300
|
||||
armor_type = /datum/armor/machinery_holopad
|
||||
circuit = /obj/item/circuitboard/machine/holopad
|
||||
// Blue, dim light
|
||||
light_power = 0.8
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
/// associative lazylist of the form: list(mob calling us = hologram representing that mob).
|
||||
/// this is only populated for holopads answering calls from another holopad
|
||||
var/list/masters
|
||||
@@ -527,31 +530,29 @@ Possible to do for anyone motivated enough:
|
||||
to_chat(user, "[span_danger("ERROR:")] \black Image feed in progress.")
|
||||
return
|
||||
|
||||
var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location.
|
||||
// What to pull our appearance out of
|
||||
var/obj/effect/overlay/holo_pad_hologram/hologram = new(loc)//Spawn a blank effect at the location.
|
||||
var/atom/work_off = AI?.hologram_appearance || user
|
||||
|
||||
hologram.icon = work_off.icon
|
||||
hologram.icon_state = work_off.icon_state
|
||||
hologram.copy_overlays(work_off, TRUE)
|
||||
hologram.makeHologram()
|
||||
|
||||
if(AI)
|
||||
Hologram.icon = AI.holo_icon
|
||||
AI.eyeobj.setLoc(get_turf(src)) //ensure the AI camera moves to the holopad
|
||||
else //make it like real life
|
||||
Hologram.icon = user.icon
|
||||
Hologram.icon_state = user.icon_state
|
||||
Hologram.copy_overlays(user, TRUE)
|
||||
//codersprite some holo effects here
|
||||
Hologram.alpha = 100
|
||||
Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY)
|
||||
Hologram.Impersonation = user
|
||||
hologram.Impersonation = user
|
||||
hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it.
|
||||
hologram.layer = FLY_LAYER //Above all the other objects/mobs. Or the vast majority of them.
|
||||
SET_PLANE_EXPLICIT(hologram, ABOVE_GAME_PLANE, src)
|
||||
hologram.set_anchored(TRUE)//So space wind cannot drag it.
|
||||
hologram.name = "[user.name] (Hologram)"//If someone decides to right click.
|
||||
|
||||
Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it.
|
||||
Hologram.layer = FLY_LAYER //Above all the other objects/mobs. Or the vast majority of them.
|
||||
SET_PLANE_EXPLICIT(Hologram, ABOVE_GAME_PLANE, src)
|
||||
Hologram.set_anchored(TRUE)//So space wind cannot drag it.
|
||||
Hologram.name = "[user.name] (Hologram)"//If someone decides to right click.
|
||||
Hologram.set_light(2) //hologram lighting
|
||||
move_hologram()
|
||||
|
||||
set_holo(user, Hologram)
|
||||
set_holo(user, hologram)
|
||||
visible_message(span_notice("A holographic image of [user] flickers to life before your eyes!"))
|
||||
|
||||
return Hologram
|
||||
return hologram
|
||||
else
|
||||
to_chat(user, "[span_danger("ERROR:")] Unable to project hologram.")
|
||||
|
||||
@@ -672,20 +673,20 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf)
|
||||
if(LAZYLEN(masters) && masters[user])
|
||||
var/obj/effect/overlay/holo_pad_hologram/holo = masters[user]
|
||||
var/transfered = FALSE
|
||||
if(!validate_location(new_turf))
|
||||
if(!transfer_to_nearby_pad(new_turf,user))
|
||||
clear_holo(user)
|
||||
return FALSE
|
||||
else
|
||||
transfered = TRUE
|
||||
//All is good.
|
||||
holo.abstract_move(new_turf)
|
||||
SET_PLANE(holo, ABOVE_GAME_PLANE, new_turf)
|
||||
if(!transfered)
|
||||
update_holoray(user,new_turf)
|
||||
if(!LAZYLEN(masters) || !masters[user])
|
||||
return TRUE
|
||||
var/obj/effect/overlay/holo_pad_hologram/holo = masters[user]
|
||||
var/transfered = FALSE
|
||||
if(!validate_location(new_turf))
|
||||
if(!transfer_to_nearby_pad(new_turf,user))
|
||||
return FALSE
|
||||
else
|
||||
transfered = TRUE
|
||||
//All is good.
|
||||
holo.abstract_move(new_turf)
|
||||
SET_PLANE(holo, ABOVE_GAME_PLANE, new_turf)
|
||||
if(!transfered)
|
||||
update_holoray(user,new_turf)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -715,21 +716,19 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
// RECORDED MESSAGES
|
||||
|
||||
/obj/machinery/holopad/proc/setup_replay_holo(datum/holorecord/record)
|
||||
var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location.
|
||||
Hologram.add_overlay(record.caller_image)
|
||||
Hologram.alpha = 170
|
||||
Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY)
|
||||
Hologram.dir = SOUTH //for now
|
||||
var/datum/language_holder/holder = Hologram.get_language_holder()
|
||||
var/obj/effect/overlay/holo_pad_hologram/hologram = new(loc)//Spawn a blank effect at the location.
|
||||
hologram.add_overlay(record.caller_image)
|
||||
hologram.makeHologram()
|
||||
|
||||
var/datum/language_holder/holder = hologram.get_language_holder()
|
||||
holder.selected_language = record.language
|
||||
Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it.
|
||||
Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
|
||||
SET_PLANE_EXPLICIT(Hologram, ABOVE_GAME_PLANE, src)
|
||||
Hologram.set_anchored(TRUE)//So space wind cannot drag it.
|
||||
Hologram.name = "[record.caller_name] (Hologram)"//If someone decides to right click.
|
||||
Hologram.set_light(2) //hologram lighting
|
||||
hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it.
|
||||
hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
|
||||
SET_PLANE_EXPLICIT(hologram, ABOVE_GAME_PLANE, src)
|
||||
hologram.set_anchored(TRUE)//So space wind cannot drag it.
|
||||
hologram.name = "[record.caller_name] (Hologram)"//If someone decides to right click.
|
||||
visible_message(span_notice("A holographic image of [record.caller_name] flickers to life before your eyes!"))
|
||||
return Hologram
|
||||
return hologram
|
||||
|
||||
/obj/machinery/holopad/proc/replay_start()
|
||||
if(!replay_mode)
|
||||
@@ -827,6 +826,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
QDEL_NULL(disk.record)
|
||||
|
||||
/obj/effect/overlay/holo_pad_hologram
|
||||
// Adds KEEP_TOGETHER to ensure we render overlays right
|
||||
appearance_flags = TILE_BOUND|PIXEL_SCALE|LONG_GLIDE|KEEP_TOGETHER
|
||||
initial_language_holder = /datum/language_holder/universal
|
||||
var/mob/living/Impersonation
|
||||
var/datum/holocall/HC
|
||||
@@ -858,6 +859,25 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
alpha = 100
|
||||
var/atom/movable/render_step/emissive/glow
|
||||
|
||||
/obj/effect/overlay/holoray/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!render_target)
|
||||
var/static/uid = 0
|
||||
render_target = "holoray#[uid]"
|
||||
uid++
|
||||
// Let's GLOW BROTHER! (Doing it like this is the most robust option compared to duped overlays)
|
||||
glow = new(src, render_target)
|
||||
// We need to counteract the pixel offset to ensure we don't double offset (I hate byond)
|
||||
glow.pixel_x = 32
|
||||
glow.pixel_y = 32
|
||||
add_overlay(glow)
|
||||
LAZYADD(update_overlays_on_z, glow)
|
||||
|
||||
/obj/effect/overlay/holoray/Destroy(force)
|
||||
. = ..()
|
||||
QDEL_NULL(glow)
|
||||
|
||||
#undef CAN_HEAR_ACTIVE_HOLOCALLS
|
||||
#undef CAN_HEAR_ALL_FLAGS
|
||||
|
||||
@@ -163,13 +163,8 @@
|
||||
GLOBAL_VAR_INIT(icon_holographic_wall, init_holographic_wall())
|
||||
GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
|
||||
|
||||
// `initial` does not work here. Neither does instantiating a wall/whatever
|
||||
// and referencing that. I don't know why.
|
||||
/proc/init_holographic_wall()
|
||||
return getHologramIcon(
|
||||
icon('icons/turf/walls/wall.dmi', "wall-0"),
|
||||
opacity = 1,
|
||||
)
|
||||
return icon('icons/turf/walls/wall.dmi', "wall-0")
|
||||
|
||||
/proc/init_holographic_window()
|
||||
var/icon/grille_icon = icon('icons/obj/structures.dmi', "grille")
|
||||
@@ -177,7 +172,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
|
||||
|
||||
grille_icon.Blend(window_icon, ICON_OVERLAY)
|
||||
|
||||
return getHologramIcon(grille_icon)
|
||||
return grille_icon
|
||||
|
||||
/obj/item/construction/rcd/ui_action_click(mob/user, actiontype)
|
||||
if (!COOLDOWN_FINISHED(src, destructive_scan_cooldown))
|
||||
@@ -223,6 +218,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
|
||||
|
||||
var/obj/effect/rcd_hologram/hologram = new(surrounding_turf)
|
||||
hologram.icon = hologram_icon
|
||||
hologram.makeHologram()
|
||||
animate(hologram, alpha = 0, time = fade_time, easing = CIRCULAR_EASING | EASE_IN)
|
||||
|
||||
/obj/effect/rcd_hologram
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
var/aiRestorePowerRoutine = POWER_RESTORATION_OFF
|
||||
var/requires_power = POWER_REQ_ALL
|
||||
var/can_be_carded = TRUE
|
||||
var/icon/holo_icon //Default is assigned when AI is created.
|
||||
var/mutable_appearance/hologram_appearance //Default is assigned when AI is created.
|
||||
var/obj/controlled_equipment //A piece of equipment, to determine whether to relaymove or use the AI eye.
|
||||
var/radio_enabled = TRUE //Determins if a carded AI can speak with its built in radio or not.
|
||||
radiomod = ";" //AIs will, by default, state their laws on the internal radio.
|
||||
@@ -163,7 +163,7 @@
|
||||
INVOKE_ASYNC(src, PROC_REF(set_core_display_icon))
|
||||
|
||||
|
||||
holo_icon = getHologramIcon(icon('icons/mob/silicon/ai.dmi',"default"))
|
||||
hologram_appearance = mutable_appearance('icons/mob/silicon/ai.dmi',"default")
|
||||
|
||||
spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
@@ -674,22 +674,17 @@
|
||||
return
|
||||
var/mutable_appearance/character_icon = personnel_list[input]
|
||||
if(character_icon)
|
||||
qdel(holo_icon)//Clear old icon so we're not storing it in memory.
|
||||
character_icon.setDir(SOUTH)
|
||||
|
||||
var/icon/icon_for_holo = getFlatIcon(character_icon)
|
||||
holo_icon = getHologramIcon(icon(icon_for_holo))
|
||||
hologram_appearance = character_icon
|
||||
|
||||
if("My Character")
|
||||
switch(tgui_alert(usr,"WARNING: Your AI hologram will take the appearance of your currently selected character ([usr.client.prefs?.read_preference(/datum/preference/name/real_name)]). Are you sure you want to proceed?", "Customize", list("Yes","No")))
|
||||
if("Yes")
|
||||
var/mob/living/carbon/human/dummy/ai_dummy = new
|
||||
var/mutable_appearance/appearance = usr.client.prefs.render_new_preview_appearance(ai_dummy)
|
||||
var/icon/character_icon = getHologramIcon(getFlatIcon(appearance))
|
||||
if(character_icon)
|
||||
qdel(holo_icon)
|
||||
var/mutable_appearance/dummy_appearance = usr.client.prefs.render_new_preview_appearance(ai_dummy)
|
||||
if(dummy_appearance)
|
||||
qdel(ai_dummy)
|
||||
holo_icon = character_icon
|
||||
hologram_appearance = dummy_appearance
|
||||
if("No")
|
||||
return FALSE
|
||||
|
||||
@@ -715,16 +710,17 @@
|
||||
return
|
||||
if(isnull(icon_list[input]))
|
||||
return
|
||||
qdel(holo_icon)
|
||||
var/working_state = ""
|
||||
switch(input)
|
||||
if("poly")
|
||||
holo_icon = getHologramIcon(icon(icon_list[input],"parrot_fly"))
|
||||
working_state = "parrot_fly"
|
||||
if("chicken")
|
||||
holo_icon = getHologramIcon(icon(icon_list[input],"chicken_brown"))
|
||||
working_state = "chicken_brown"
|
||||
if("spider")
|
||||
holo_icon = getHologramIcon(icon(icon_list[input],"guard"))
|
||||
working_state = "guard"
|
||||
else
|
||||
holo_icon = getHologramIcon(icon(icon_list[input], input))
|
||||
working_state = input
|
||||
hologram_appearance = mutable_appearance(icon_list[input], working_state)
|
||||
else
|
||||
var/list/icon_list = list(
|
||||
"default" = 'icons/mob/silicon/ai.dmi',
|
||||
@@ -739,12 +735,13 @@
|
||||
return
|
||||
if(isnull(icon_list[input]))
|
||||
return
|
||||
qdel(holo_icon)
|
||||
var/working_state = ""
|
||||
switch(input)
|
||||
if("xeno queen")
|
||||
holo_icon = getHologramIcon(icon(icon_list[input],"alienq"))
|
||||
working_state = "alienq"
|
||||
else
|
||||
holo_icon = getHologramIcon(icon(icon_list[input], input))
|
||||
working_state = input
|
||||
hologram_appearance = mutable_appearance(icon_list[input], working_state)
|
||||
return
|
||||
|
||||
/datum/action/innate/core_return
|
||||
|
||||
@@ -112,7 +112,9 @@
|
||||
//Holopad
|
||||
if(istype(ai.current, /obj/machinery/holopad))
|
||||
var/obj/machinery/holopad/H = ai.current
|
||||
H.move_hologram(ai, destination)
|
||||
if(!H.move_hologram(ai, destination))
|
||||
H.clear_holo(ai)
|
||||
|
||||
if(ai.camera_light_on)
|
||||
ai.light_cameras()
|
||||
if(ai.master_multicam)
|
||||
|
||||
@@ -56,11 +56,6 @@
|
||||
* This should only be used internally. If you are directly creating more of these, you're
|
||||
* almost guaranteed to be doing something wrong.
|
||||
*/
|
||||
/**
|
||||
* Render step that modfies an atom's color
|
||||
* Useful for creating coherent emissive blockers out of things like glass floors by lowering alpha statically using matrixes
|
||||
* Other stuff too I'm sure
|
||||
*/
|
||||
/atom/movable/render_step/emissive_blocker
|
||||
name = "emissive blocker"
|
||||
plane = EMISSIVE_PLANE
|
||||
@@ -69,3 +64,18 @@
|
||||
/atom/movable/render_step/emissive_blocker/Initialize(mapload, source)
|
||||
. = ..()
|
||||
src.color = GLOB.em_block_color
|
||||
|
||||
|
||||
/**
|
||||
* Render step that makes the passed in render source GLOW
|
||||
*
|
||||
* Copies an appearance vis render_target and render_source on to the emissive plane
|
||||
*/
|
||||
/atom/movable/render_step/emissive
|
||||
name = "emissive"
|
||||
plane = EMISSIVE_PLANE
|
||||
appearance_flags = EMISSIVE_APPEARANCE_FLAGS|RESET_TRANSFORM
|
||||
|
||||
/atom/movable/render_step/emissive/Initialize(mapload, source)
|
||||
. = ..()
|
||||
src.color = GLOB.emissive_color
|
||||
|
||||
Reference in New Issue
Block a user