mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-18 19:39:42 +01:00
cca0dfe7b6
Part one of our nefarious plans to destroy lag forever, and also accomplish some cool shit. This replaces our renderer system with plane masters, this will also be used to turn skyboxes into backdrops and thus totally remove skybox updating lag. Additionally, this will let us manipulate entire planes very easily to do all sorts of zany shit. All credit goes to the original coders, this is some seriously cool stuff. Also fixes some bizarre smoothing behaviour, reduces updateoverlays calls since now not every single structure in the game tries smoothing with nothing. <img width="1349" height="1349" alt="image" src="https://github.com/user-attachments/assets/9b7cecd7-3c47-448b-9dd8-9b904640bf82" /> <img width="1349" height="1349" alt="image" src="https://github.com/user-attachments/assets/647d75a2-1bff-45ca-ab92-0aea10631afd" /> --------- Co-authored-by: Matt Atlas <liermattia@gmail.com>
592 lines
16 KiB
Plaintext
592 lines
16 KiB
Plaintext
/**
|
|
Screen objects
|
|
Todo: improve/re-implement
|
|
|
|
Screen objects are only used for the hud and should not appear anywhere "in-game".
|
|
They are used with the client/screen list and the screen_loc var.
|
|
For more information, see the byond documentation on the screen_loc and screen vars.
|
|
*/
|
|
/atom/movable/screen
|
|
name = ""
|
|
icon = 'icons/mob/screen/generic.dmi'
|
|
plane = HUD_PLANE
|
|
layer = HUD_BASE_LAYER
|
|
/// A reference to the object in the slot. Grabs or items, generally.
|
|
var/obj/master = null
|
|
/// A reference to the owner HUD, if any.
|
|
var/datum/hud/hud = null
|
|
appearance_flags = NO_CLIENT_COLOR
|
|
|
|
/atom/movable/screen/Initialize(mapload, ...)
|
|
. = ..()
|
|
//This is done with signals because the screen code sucks, blame the ancient developers
|
|
if(hud)
|
|
RegisterSignal(hud, COMSIG_QDELETING, PROC_REF(handle_hud_destruction))
|
|
|
|
/atom/movable/screen/Destroy(force = FALSE)
|
|
master = null
|
|
screen_loc = null
|
|
hud = null
|
|
. = ..()
|
|
|
|
/// Screen elements are always on top of the players screen and don't move so yes they are adjacent
|
|
/atom/movable/screen/Adjacent(atom/neighbor, atom/target, atom/movable/mover)
|
|
return TRUE
|
|
|
|
/**
|
|
* Handles the deletion of the HUD this screen is associated to
|
|
*/
|
|
/atom/movable/screen/proc/handle_hud_destruction()
|
|
SIGNAL_HANDLER
|
|
|
|
UnregisterSignal(hud, COMSIG_QDELETING)
|
|
qdel(src)
|
|
|
|
/atom/movable/screen/text
|
|
icon = null
|
|
icon_state = null
|
|
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
|
screen_loc = "CENTER-7,CENTER-7"
|
|
maptext_height = 480
|
|
maptext_width = 480
|
|
|
|
/atom/movable/screen/inventory
|
|
/// The identifier for the slot. It has nothing to do with ID cards.
|
|
var/slot_id
|
|
/// Required for inventory/screen overlays.
|
|
var/list/object_overlays = list()
|
|
var/color_changed = FALSE
|
|
|
|
/atom/movable/screen/inventory/MouseEntered()
|
|
..()
|
|
add_overlays()
|
|
|
|
/atom/movable/screen/inventory/MouseExited()
|
|
..()
|
|
CutOverlays(object_overlays)
|
|
object_overlays.Cut()
|
|
|
|
/atom/movable/screen/inventory/proc/add_overlays()
|
|
var/mob/user = hud.mymob
|
|
|
|
if(hud && user && slot_id)
|
|
var/obj/item/holding = user.get_active_hand()
|
|
if(!holding || user.get_equipped_item(slot_id))
|
|
return
|
|
|
|
var/image/item_overlay = image(holding)
|
|
item_overlay.alpha = 92
|
|
if(!holding.mob_can_equip(user, slot_id, disable_warning = TRUE))
|
|
item_overlay.color = "#ff0000"
|
|
else
|
|
item_overlay.color = "#00ff00"
|
|
object_overlays += item_overlay
|
|
AddOverlays(object_overlays)
|
|
|
|
/atom/movable/screen/inventory/proc/set_color_for(var/set_color, var/set_time)
|
|
if(color_changed)
|
|
return
|
|
var/old_color = color
|
|
color = set_color
|
|
color_changed = TRUE
|
|
addtimer(CALLBACK(src, PROC_REF(set_color_to), old_color), set_time)
|
|
|
|
/atom/movable/screen/inventory/proc/set_color_to(var/set_color)
|
|
color = set_color
|
|
color_changed = FALSE
|
|
|
|
/atom/movable/screen/close
|
|
name = "close"
|
|
|
|
/atom/movable/screen/close/Click()
|
|
if(master)
|
|
if(istype(master, /obj/item/storage))
|
|
var/obj/item/storage/S = master
|
|
S.close(usr)
|
|
return 1
|
|
|
|
|
|
/atom/movable/screen/item_action
|
|
var/obj/item/owner
|
|
|
|
/atom/movable/screen/item_action/Destroy()
|
|
owner = null
|
|
. = ..()
|
|
|
|
/atom/movable/screen/item_action/Click()
|
|
if(!usr || !owner)
|
|
return 1
|
|
if(!usr.canClick())
|
|
return
|
|
|
|
if(usr.stat || usr.restrained() || usr.stunned || usr.lying)
|
|
return 1
|
|
|
|
if(!(owner in usr))
|
|
return 1
|
|
|
|
owner.ui_action_click()
|
|
return 1
|
|
|
|
/atom/movable/screen/grab
|
|
name = "grab"
|
|
|
|
/atom/movable/screen/grab/Click()
|
|
var/obj/item/grab/G = master
|
|
G.s_click(src)
|
|
return 1
|
|
|
|
/atom/movable/screen/grab/attack_hand()
|
|
return
|
|
|
|
/atom/movable/screen/grab/attackby()
|
|
return
|
|
|
|
|
|
/atom/movable/screen/storage
|
|
name = "storage"
|
|
screen_loc = "7,7 to 10,8"
|
|
plane = HUD_PLANE
|
|
layer = HUD_BASE_LAYER
|
|
|
|
/atom/movable/screen/storage/Click()
|
|
if(!usr.canClick())
|
|
return TRUE
|
|
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
|
|
return TRUE
|
|
if(master)
|
|
var/obj/item/I = usr.get_active_hand()
|
|
if(I)
|
|
usr.ClickOn(master)
|
|
return TRUE
|
|
|
|
/atom/movable/screen/storage/background
|
|
name = "background storage"
|
|
layer = HUD_BELOW_ITEM_LAYER
|
|
|
|
/atom/movable/screen/storage/background/Initialize(mapload, var/obj/set_master, var/set_icon_state)
|
|
. = ..()
|
|
master = set_master
|
|
if(master)
|
|
name = master.name
|
|
icon_state = set_icon_state
|
|
|
|
/atom/movable/screen/storage/background/Click()
|
|
if(usr.incapacitated())
|
|
return TRUE
|
|
if(master)
|
|
usr.ClickOn(master)
|
|
return TRUE
|
|
|
|
/atom/movable/screen/zone_sel
|
|
name = "damage zone"
|
|
icon_state = "zone_sel"
|
|
screen_loc = ui_zonesel
|
|
var/selecting = BP_CHEST
|
|
var/static/list/hover_overlays_cache = list()
|
|
var/hovering_choice
|
|
var/mutable_appearance/selecting_appearance
|
|
|
|
/atom/movable/screen/zone_sel/Click(location, control,params)
|
|
if(isobserver(usr))
|
|
return
|
|
|
|
var/list/PL = params2list(params)
|
|
var/icon_x = text2num(PL["icon-x"])
|
|
var/icon_y = text2num(PL["icon-y"])
|
|
var/choice = get_zone_at(icon_x, icon_y)
|
|
if(!choice)
|
|
return 1
|
|
|
|
return set_selected_zone(choice, usr)
|
|
|
|
/atom/movable/screen/zone_sel/MouseEntered(location, control, params)
|
|
MouseMove(location, control, params)
|
|
|
|
/atom/movable/screen/zone_sel/MouseMove(location, control, params)
|
|
if(isobserver(usr))
|
|
return
|
|
|
|
var/list/PL = params2list(params)
|
|
var/icon_x = text2num(PL["icon-x"])
|
|
var/icon_y = text2num(PL["icon-y"])
|
|
var/choice = get_zone_at(icon_x, icon_y)
|
|
|
|
if(hovering_choice == choice)
|
|
return
|
|
remove_vis_contents(hover_overlays_cache[hovering_choice])
|
|
hovering_choice = choice
|
|
|
|
var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice]
|
|
if(!overlay_object)
|
|
overlay_object = new
|
|
overlay_object.icon_state = "[choice]"
|
|
hover_overlays_cache[choice] = overlay_object
|
|
add_vis_contents(overlay_object)
|
|
|
|
|
|
/obj/effect/overlay/zone_sel
|
|
icon = 'icons/mob/zone_sel.dmi'
|
|
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
|
alpha = 128
|
|
anchored = TRUE
|
|
plane = HUD_ITEM_LAYER
|
|
|
|
/atom/movable/screen/zone_sel/MouseExited(location, control, params)
|
|
if(!isobserver(usr) && hovering_choice)
|
|
remove_vis_contents(hover_overlays_cache[hovering_choice])
|
|
hovering_choice = null
|
|
|
|
/atom/movable/screen/zone_sel/proc/get_zone_at(icon_x, icon_y)
|
|
switch(icon_y)
|
|
if(1 to 3) //Feet
|
|
switch(icon_x)
|
|
if(10 to 15)
|
|
return BP_R_FOOT
|
|
if(17 to 22)
|
|
return BP_L_FOOT
|
|
if(4 to 9) //Legs
|
|
switch(icon_x)
|
|
if(10 to 15)
|
|
return BP_R_LEG
|
|
if(17 to 22)
|
|
return BP_L_LEG
|
|
if(10 to 13) //Hands and groin
|
|
switch(icon_x)
|
|
if(8 to 11)
|
|
return BP_R_HAND
|
|
if(12 to 20)
|
|
return BP_GROIN
|
|
if(21 to 24)
|
|
return BP_L_HAND
|
|
if(14 to 22) //Chest and arms to shoulders
|
|
switch(icon_x)
|
|
if(8 to 11)
|
|
return BP_R_ARM
|
|
if(12 to 20)
|
|
return BP_CHEST
|
|
if(21 to 24)
|
|
return BP_L_ARM
|
|
if(23 to 30) //Head, but we need to check for eye or mouth
|
|
if(icon_x in 12 to 20)
|
|
switch(icon_y)
|
|
if(23 to 24)
|
|
if(icon_x in 15 to 17)
|
|
return BP_MOUTH
|
|
if(26) //Eyeline, eyes are on 15 and 17
|
|
if(icon_x in 14 to 18)
|
|
return BP_EYES
|
|
if(25 to 27)
|
|
if(icon_x in 15 to 17)
|
|
return BP_EYES
|
|
return BP_HEAD
|
|
|
|
/atom/movable/screen/zone_sel/proc/set_selected_zone(choice, mob/user)
|
|
if(isobserver(user))
|
|
return
|
|
if(choice != selecting)
|
|
selecting = choice
|
|
update_icon()
|
|
SEND_SIGNAL(user, COMSIG_MOB_ZONE_SEL_CHANGE, user)
|
|
|
|
/atom/movable/screen/zone_sel/update_icon()
|
|
ClearOverlays()
|
|
selecting_appearance = mutable_appearance('icons/mob/zone_sel.dmi', "[selecting]")
|
|
AddOverlays(selecting_appearance)
|
|
|
|
/atom/movable/screen/Click(location, control, params)
|
|
if(!usr)
|
|
return TRUE
|
|
var/list/modifiers = params2list(params)
|
|
var/client/viewer_client = usr?.client
|
|
switch(name)
|
|
if("toggle")
|
|
if(usr.hud_used.inventory_shown)
|
|
usr.hud_used.inventory_shown = 0
|
|
usr.client.screen -= usr.hud_used.other
|
|
else
|
|
usr.hud_used.inventory_shown = 1
|
|
usr.client.screen += usr.hud_used.other
|
|
|
|
usr.hud_used.hidden_inventory_update()
|
|
|
|
if("equip")
|
|
if(ishuman(usr))
|
|
var/mob/living/carbon/human/H = usr
|
|
H.quick_equip()
|
|
|
|
if("resist")
|
|
if(isliving(usr))
|
|
var/mob/living/L = usr
|
|
L.resist()
|
|
|
|
if("act_intent")
|
|
usr.a_intent_change("right")
|
|
if(I_HELP)
|
|
usr.set_intent(I_HELP)
|
|
usr.hud_used.action_intent.icon_state = "intent_help"
|
|
if(I_HURT)
|
|
usr.set_intent(I_HURT)
|
|
usr.hud_used.action_intent.icon_state = "intent_harm"
|
|
if(I_GRAB)
|
|
usr.set_intent(I_GRAB)
|
|
usr.hud_used.action_intent.icon_state = "intent_grab"
|
|
if(I_DISARM)
|
|
usr.set_intent(I_DISARM)
|
|
usr.hud_used.action_intent.icon_state = "intent_disarm"
|
|
|
|
if("pull")
|
|
usr.stop_pulling()
|
|
if("throw")
|
|
if(!usr.stat && isturf(usr.loc) && !usr.restrained())
|
|
usr.toggle_throw_mode()
|
|
if("drop")
|
|
if(usr.client)
|
|
usr.client.drop_item()
|
|
|
|
if("up hint")
|
|
if(modifiers["shift"])
|
|
if(ishuman(usr))
|
|
var/mob/living/carbon/human/H = usr
|
|
if(H.last_special + 50 > world.time)
|
|
to_chat(usr, "You cannot do that again so quickly.")
|
|
return
|
|
H.last_special = world.time
|
|
to_chat(usr, SPAN_NOTICE("You take look around to see if there are any holes in the roof around."))
|
|
for(var/turf/T in view(viewer_client.view, usr))
|
|
if(T.density)
|
|
continue
|
|
var/turf/above_turf = GET_TURF_ABOVE(T)
|
|
if(!isopenturf(above_turf))
|
|
continue
|
|
var/image/point_up = image(icon = 'icons/mob/screen/generic.dmi', icon_state = "arrow_up", loc = T)
|
|
point_up.plane = GAME_PLANE
|
|
point_up.layer = POINTER_LAYER
|
|
viewer_client?.images += point_up
|
|
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(remove_image_from_client), point_up, viewer_client), 3 SECONDS)
|
|
return
|
|
|
|
if(!isliving(usr))
|
|
return
|
|
var/mob/living/user = usr
|
|
var/turf/T1 = get_turf(user)
|
|
var/turf/T = GET_TURF_ABOVE(T1)
|
|
if (!T)
|
|
to_chat(user, SPAN_NOTICE("There is nothing above you!"))
|
|
else if (isopenturf(T))
|
|
user.look_up_open_space(T1)
|
|
else
|
|
to_chat(user, SPAN_NOTICE("You see a ceiling staring back at you."))
|
|
|
|
if("module")
|
|
if(isrobot(usr))
|
|
var/mob/living/silicon/robot/R = usr
|
|
if(modifiers["shift"])
|
|
if(R.module)
|
|
to_chat(R, SPAN_NOTICE("You currently have the [R.module.name] active."))
|
|
else
|
|
to_chat(R, SPAN_WARNING("You don't have a module active currently."))
|
|
return
|
|
R.pick_module()
|
|
|
|
if("Return-to-core")
|
|
if (istype(usr, /mob/living/silicon/robot/shell))
|
|
usr.body_return()
|
|
return
|
|
|
|
if("health")
|
|
if(isrobot(usr))
|
|
if(modifiers["shift"])
|
|
var/mob/living/silicon/robot/R = usr
|
|
R.self_diagnosis_verb()
|
|
|
|
if("inventory")
|
|
if(isrobot(usr))
|
|
var/mob/living/silicon/robot/R = usr
|
|
if(R.module)
|
|
R.hud_used.toggle_show_robot_modules()
|
|
return 1
|
|
else
|
|
to_chat(R, "You haven't selected a module yet.")
|
|
|
|
if("radio")
|
|
if(isrobot(usr))
|
|
var/mob/living/silicon/robot/R = usr
|
|
if(modifiers["shift"])
|
|
if(!R.radio.radio_desc)
|
|
R.radio.setupRadioDescription()
|
|
to_chat(R, SPAN_NOTICE("You analyze your integrated radio:"))
|
|
to_chat(R, R.radio.radio_desc)
|
|
return
|
|
|
|
R.radio_menu()
|
|
|
|
if("panel")
|
|
if(isrobot(usr))
|
|
var/mob/living/silicon/robot/R = usr
|
|
R.installed_modules()
|
|
|
|
if("store")
|
|
if(isrobot(usr))
|
|
var/mob/living/silicon/robot/R = usr
|
|
if(!R.module)
|
|
to_chat(R, SPAN_WARNING("You haven't selected a module yet."))
|
|
return
|
|
if(modifiers["alt"])
|
|
R.uneq_all()
|
|
return
|
|
R.uneq_active()
|
|
|
|
else
|
|
return 0
|
|
return 1
|
|
|
|
/atom/movable/screen/inventory/Click()
|
|
// At this point in client Click() code we have passed the 1/10 sec check and little else
|
|
// We don't even know if it's a middle click
|
|
if(!usr.canClick())
|
|
return TRUE
|
|
if(use_check_and_message(usr, USE_ALLOW_NON_ADJACENT|USE_ALLOW_NON_ADV_TOOL_USR)) //You're always adjacent to your inventory in practice.
|
|
return TRUE
|
|
switch(name)
|
|
if("right hand")
|
|
if(iscarbon(usr))
|
|
var/mob/living/carbon/C = usr
|
|
C.activate_hand("r")
|
|
if("left hand")
|
|
if(iscarbon(usr))
|
|
var/mob/living/carbon/C = usr
|
|
C.activate_hand("l")
|
|
if("swap")
|
|
usr.swap_hand()
|
|
if("hand")
|
|
usr.swap_hand()
|
|
else
|
|
if(usr.attack_ui(slot_id))
|
|
usr.update_inv_l_hand(0)
|
|
usr.update_inv_r_hand(0)
|
|
|
|
return 1
|
|
|
|
/atom/movable/screen/movement_intent
|
|
name = "mov_intent"
|
|
screen_loc = ui_movi
|
|
|
|
/// This updates the run/walk button on the hud.
|
|
/atom/movable/screen/movement_intent/proc/update_move_icon(var/mob/living/user)
|
|
if(!user.client)
|
|
return
|
|
|
|
if(user.max_stamina == -1 || user.stamina == user.max_stamina)
|
|
if(user.stamina_bar)
|
|
user.stamina_bar.end_progress()
|
|
QDEL_NULL(user.stamina_bar) //Because otherwise they stack weirdly when calculating the progress bar offsets
|
|
else
|
|
if(!user.stamina_bar)
|
|
user.stamina_bar = new(user, user.max_stamina, src)
|
|
user.stamina_bar.goal = user.max_stamina
|
|
user.stamina_bar.update(user.stamina)
|
|
|
|
if(user.m_intent == M_RUN)
|
|
icon_state = "running"
|
|
else if(user.m_intent == M_LAY)
|
|
icon_state = "lying"
|
|
else
|
|
icon_state = "walking"
|
|
|
|
#define BLACKLIST_SPECIES_RUNNING list(SPECIES_DIONA, SPECIES_DIONA_COEUS)
|
|
|
|
/atom/movable/screen/movement_intent/Click(location, control, params)
|
|
if(!usr)
|
|
return 1
|
|
var/list/modifiers = params2list(params)
|
|
|
|
if(iscarbon(usr))
|
|
var/mob/living/carbon/C = usr
|
|
if (modifiers["alt"])
|
|
C.set_walk_speed()
|
|
return
|
|
|
|
if(C.legcuffed)
|
|
to_chat(C, SPAN_NOTICE("You are legcuffed! You cannot run until you get [C.legcuffed] removed!"))
|
|
C.m_intent = M_WALK //Just incase
|
|
C.hud_used.move_intent.icon_state = "walking"
|
|
return 1
|
|
|
|
switch(usr.m_intent)
|
|
if(M_RUN)
|
|
usr.m_intent = M_WALK
|
|
if(M_WALK)
|
|
if(!(usr.get_species() in BLACKLIST_SPECIES_RUNNING))
|
|
usr.m_intent = M_RUN
|
|
if(M_LAY)
|
|
// No funny "haha i get the bonuses then stand up"
|
|
var/obj/item/gun/gun_in_hand = C.get_type_in_hands(/obj/item/gun)
|
|
if(gun_in_hand?.wielded)
|
|
to_chat(C, SPAN_WARNING("You cannot wield and stand up!"))
|
|
return
|
|
|
|
if(C.lying_is_intentional)
|
|
usr.m_intent = M_WALK
|
|
|
|
if(modifiers["button"] == "middle" && !C.lying) // See /mob/proc/update_canmove() for more logic on the lying FSM
|
|
// You want this bonus weapon or not? Wield it when you are lying, not before!
|
|
var/obj/item/gun/gun_in_hand = C.get_type_in_hands(/obj/item/gun)
|
|
if(gun_in_hand?.wielded)
|
|
to_chat(C, SPAN_WARNING("You cannot wield and lie down!"))
|
|
return
|
|
C.m_intent = M_LAY
|
|
|
|
// this works in conjunction with M_LAY to make the mob stand up or lie down instantly
|
|
C.update_canmove()
|
|
C.update_icon()
|
|
|
|
else if(istype(usr, /mob/living/simple_animal/hostile/morph))
|
|
var/mob/living/simple_animal/hostile/morph/M = usr
|
|
switch(usr.m_intent)
|
|
if(M_RUN)
|
|
usr.m_intent = M_WALK
|
|
if(M_WALK)
|
|
usr.m_intent = M_RUN
|
|
M.update_speed()
|
|
update_move_icon(usr)
|
|
|
|
#undef BLACKLIST_SPECIES_RUNNING
|
|
|
|
/// Hand slots are special to handle the handcuffs overlay
|
|
/atom/movable/screen/inventory/hand
|
|
var/image/handcuff_overlay
|
|
var/image/disabled_hand_overlay
|
|
var/image/removed_hand_overlay
|
|
|
|
/atom/movable/screen/inventory/hand/update_icon()
|
|
..()
|
|
if(!hud)
|
|
return
|
|
if(!handcuff_overlay)
|
|
var/state = (hud.l_hand_hud_object == src) ? "l_hand_hud_handcuffs" : "r_hand_hud_handcuffs"
|
|
handcuff_overlay = image("icon"='icons/mob/screen_gen.dmi', "icon_state" = state)
|
|
if(!disabled_hand_overlay)
|
|
var/state = (hud.l_hand_hud_object == src) ? "l_hand_disabled" : "r_hand_disabled"
|
|
disabled_hand_overlay = image("icon" = 'icons/mob/screen_gen.dmi', "icon_state" = state)
|
|
if(!removed_hand_overlay)
|
|
var/state = (hud.l_hand_hud_object == src) ? "l_hand_removed" : "r_hand_removed"
|
|
removed_hand_overlay = image("icon" = 'icons/mob/screen_gen.dmi', "icon_state" = state)
|
|
ClearOverlays()
|
|
if(hud.mymob && ishuman(hud.mymob))
|
|
var/mob/living/carbon/human/H = hud.mymob
|
|
var/obj/item/organ/external/O
|
|
if(hud.l_hand_hud_object == src)
|
|
O = H.organs_by_name[BP_L_HAND]
|
|
else
|
|
O = H.organs_by_name[BP_R_HAND]
|
|
if(!O || O.is_stump())
|
|
AddOverlays(removed_hand_overlay)
|
|
else if(O && (!O.is_usable() || O.is_malfunctioning()))
|
|
AddOverlays(disabled_hand_overlay)
|
|
if(H.handcuffed)
|
|
AddOverlays(handcuff_overlay)
|
|
|
|
/atom/movable/screen/inventory/back
|
|
name = "back"
|