diff --git a/archive/maps/gateway_archive_vr/wildwest.dm b/archive/maps/gateway_archive_vr/wildwest.dm index e7ceb49e0e..d16e6080c9 100644 --- a/archive/maps/gateway_archive_vr/wildwest.dm +++ b/archive/maps/gateway_archive_vr/wildwest.dm @@ -21,8 +21,6 @@ var/insistinga = 0 /obj/machinery/wish_granter_dark/attack_hand(var/mob/living/carbon/human/user) - user.set_machine(src) - if(chargesa <= 0) to_chat(user, "The Wish Granter lies silent.") return diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm index c03f322ca1..4e0c5abdcd 100644 --- a/code/__defines/dcs/signals.dm +++ b/code/__defines/dcs/signals.dm @@ -323,6 +323,8 @@ ///from base of /obj/item/dice/proc/rollDice(mob/user as mob, var/silent = 0). Has the arguments of 'src, silent, result' #define COMSIG_MOB_ROLLED_DICE "mob_rolled_dice" //can give a return value if we want it to make the dice roll a specific number! +///from base of /client/Move(n, direct) : (direction) returns bool, if component handled movement +#define COMSIG_MOB_RELAY_MOVEMENT "mob_relay_movement" ///from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj #define COMSIG_MOB_ALLOWED "mob_allowed" ///from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources) @@ -415,6 +417,12 @@ #define COMSIG_LIVING_HANDLE_VISION "living_handle_vision" ///From /mob/handle_regular_hud_updates(). #define COMSIG_LIVING_HANDLE_HUD "living_handle_hud" + #define COMSIG_COMPONENT_HANDLED_HUD (1<<0) +///From /mob/living/proc/handle_hud_icons_health(). +#define COMSIG_LIVING_HANDLE_HUD_HEALTH_ICON "living_handle_hud_health_icon" + #define COMSIG_COMPONENT_HANDLED_HEALTH_ICON (1<<0) +///From /mob/living/proc/handle_darksight(). +#define COMSIG_LIVING_HANDLE_HUD_DARKSIGHT "living_handle_hud_darksight" // Damage specific signals for /mob/living diff --git a/code/datums/components/materials/machine_shim.dm b/code/datums/components/materials/machine_shim.dm index 9ca7db3654..fe3a348b6e 100644 --- a/code/datums/components/materials/machine_shim.dm +++ b/code/datums/components/materials/machine_shim.dm @@ -15,7 +15,6 @@ // Mob host_mob = parent RegisterSignal(host_mob, COMSIG_LIVING_LIFE, PROC_REF(on_mob_action)) - RegisterSignal(host_mob, COMSIG_LIVING_HANDLE_VISION, PROC_REF(on_mob_vision_update)) RegisterSignal(host_mob, COMSIG_OBSERVER_MOVED, PROC_REF(on_mob_action)) RegisterSignal(host_mob, COMSIG_MOB_LOGOUT, PROC_REF(on_mob_logout)) @@ -23,7 +22,6 @@ linked_machine = machine RegisterSignal(linked_machine, COMSIG_QDELETING, PROC_REF(on_machine_qdelete)) linked_machine.in_use = TRUE - on_mob_vision_update() // Lets complain if an object uses TGUI but is still setting the machine. if(length(linked_machine.tgui_data())) @@ -35,12 +33,10 @@ linked_machine.balloon_alert(host_mob,"you stop using \the [linked_machine]") // Machine UnregisterSignal(linked_machine, COMSIG_QDELETING) - linked_machine.remove_visual(host_mob) linked_machine.in_use = FALSE linked_machine = null // Mob UnregisterSignal(host_mob, COMSIG_OBSERVER_MOVED) - UnregisterSignal(host_mob, COMSIG_LIVING_HANDLE_VISION) UnregisterSignal(host_mob, COMSIG_LIVING_LIFE) UnregisterSignal(host_mob, COMSIG_MOB_LOGOUT) host_mob.reset_perspective() // Required, because our machine may have been operating a remote view @@ -51,31 +47,14 @@ PRIVATE_PROC(TRUE) SIGNAL_HANDLER if(host_mob.stat == DEAD || !host_mob.client || !host_mob.Adjacent(linked_machine)) - on_mob_vision_update() qdel(src) /datum/component/using_machine_shim/proc/on_machine_qdelete() SHOULD_NOT_OVERRIDE(TRUE) PRIVATE_PROC(TRUE) SIGNAL_HANDLER - on_mob_vision_update() qdel(src) -/datum/component/using_machine_shim/proc/on_mob_vision_update() - SHOULD_NOT_OVERRIDE(TRUE) - PRIVATE_PROC(TRUE) - SIGNAL_HANDLER - - if(host_mob.stat == DEAD) - return - var/viewflags = linked_machine.check_eye(host_mob) - if(viewflags < 0) - return - if(host_mob.is_remote_viewing()) - linked_machine.apply_visual(host_mob) - return - host_mob.sight |= viewflags - /datum/component/using_machine_shim/proc/on_mob_logout() SHOULD_NOT_OVERRIDE(TRUE) PRIVATE_PROC(TRUE) @@ -116,12 +95,6 @@ return AddComponent(/datum/component/using_machine_shim, O) -/// deprecated, do not use, return flags that should be added to the viewer's sight var. Otherwise return a negative number to indicate that the view should be cancelled. -/atom/proc/check_eye(user as mob) - if (isAI(user)) // WHYYYY - return 0 - return -1 - /// deprecated, do not use /obj/item/proc/updateSelfDialog() var/mob/M = src.loc diff --git a/code/datums/components/remote_view.dm b/code/datums/components/remote_view.dm index ada85c644f..dd065b6a83 100644 --- a/code/datums/components/remote_view.dm +++ b/code/datums/components/remote_view.dm @@ -2,37 +2,55 @@ * Use this if you need to remote view something. Remote view will end if you move or the remote view target is deleted. Cleared automatically if another remote view begins. */ /datum/component/remote_view + VAR_PROTECTED/datum/remote_view_config/settings = null VAR_PROTECTED/mob/host_mob VAR_PROTECTED/atom/remote_view_target - VAR_PROTECTED/forbid_movement = TRUE -/datum/component/remote_view/allow_moving - forbid_movement = FALSE - -/datum/component/remote_view/Initialize(atom/focused_on) +/datum/component/remote_view/Initialize(atom/focused_on, vconfig_path) . = ..() if(!ismob(parent)) return COMPONENT_INCOMPATIBLE + // Set config + if(!vconfig_path) + vconfig_path = /datum/remote_view_config + settings = new vconfig_path // Safety check, focus on ourselves if the target is deleted, and flag any movement to end the view. host_mob = parent if(QDELETED(focused_on)) focused_on = host_mob - forbid_movement = TRUE + settings.forbid_movement = TRUE // Begin remoteview host_mob.reset_perspective(focused_on) // Must be done before registering the signals - if(forbid_movement) + if(settings.forbid_movement) RegisterSignal(host_mob, COMSIG_MOVABLE_MOVED, PROC_REF(handle_hostmob_moved)) else RegisterSignal(host_mob, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(handle_hostmob_moved)) RegisterSignal(host_mob, COMSIG_MOB_RESET_PERSPECTIVE, PROC_REF(on_reset_perspective)) - RegisterSignal(host_mob, COMSIG_MOB_DEATH, PROC_REF(handle_endview)) RegisterSignal(host_mob, COMSIG_REMOTE_VIEW_CLEAR, PROC_REF(handle_forced_endview)) // Upon any disruptive status effects - RegisterSignal(host_mob, COMSIG_LIVING_STATUS_STUN, PROC_REF(handle_status_effects)) - RegisterSignal(host_mob, COMSIG_LIVING_STATUS_WEAKEN, PROC_REF(handle_status_effects)) - RegisterSignal(host_mob, COMSIG_LIVING_STATUS_PARALYZE, PROC_REF(handle_status_effects)) - RegisterSignal(host_mob, COMSIG_LIVING_STATUS_SLEEP, PROC_REF(handle_status_effects)) - RegisterSignal(host_mob, COMSIG_LIVING_STATUS_BLIND, PROC_REF(handle_status_effects)) + if(settings.will_stun) + RegisterSignal(host_mob, COMSIG_LIVING_STATUS_STUN, PROC_REF(handle_status_effects)) + if(settings.will_weaken) + RegisterSignal(host_mob, COMSIG_LIVING_STATUS_WEAKEN, PROC_REF(handle_status_effects)) + if(settings.will_paralyze) + RegisterSignal(host_mob, COMSIG_LIVING_STATUS_PARALYZE, PROC_REF(handle_status_effects)) + if(settings.will_sleep) + RegisterSignal(host_mob, COMSIG_LIVING_STATUS_SLEEP, PROC_REF(handle_status_effects)) + if(settings.will_blind) + RegisterSignal(host_mob, COMSIG_LIVING_STATUS_BLIND, PROC_REF(handle_status_effects)) + if(settings.will_death) + RegisterSignal(host_mob, COMSIG_MOB_DEATH, PROC_REF(handle_endview)) + // Handle relayed movement + if(settings.relay_movement) + RegisterSignal(host_mob, COMSIG_MOB_RELAY_MOVEMENT, PROC_REF(handle_relay_movement)) + RegisterSignal(host_mob, COMSIG_LIVING_HANDLE_VISION, PROC_REF(handle_mob_vision_update)) + // Hud overrides + if(settings.override_entire_hud) + RegisterSignal(host_mob, COMSIG_LIVING_HANDLE_HUD, PROC_REF(handle_hud_override)) + if(settings.override_health_hud) + RegisterSignal(host_mob, COMSIG_LIVING_HANDLE_HUD_HEALTH_ICON, PROC_REF(handle_hud_health)) + if(settings.override_darkvision_hud) + RegisterSignal(host_mob, COMSIG_LIVING_HANDLE_HUD_DARKSIGHT, PROC_REF(handle_hud_darkvision)) // Recursive move component fires this, we only want it to handle stuff like being inside a paicard when releasing turf lock if(isturf(focused_on)) RegisterSignal(host_mob, COMSIG_OBSERVER_MOVED, PROC_REF(handle_recursive_moved)) @@ -43,34 +61,68 @@ RegisterSignal(remote_view_target, COMSIG_MOB_RESET_PERSPECTIVE, PROC_REF(on_remotetarget_reset_perspective)) RegisterSignal(remote_view_target, COMSIG_REMOTE_VIEW_CLEAR, PROC_REF(handle_forced_endview)) +/datum/component/remote_view/RegisterWithParent() + // Update the mob's vision after we attach. + host_mob.handle_vision() + host_mob.handle_regular_hud_updates() + settings.attached_to_mob(src, host_mob) + /datum/component/remote_view/Destroy(force) . = ..() - if(forbid_movement) + // Basic handling + if(settings.forbid_movement) UnregisterSignal(host_mob, COMSIG_MOVABLE_MOVED) else UnregisterSignal(host_mob, COMSIG_MOVABLE_Z_CHANGED) UnregisterSignal(host_mob, COMSIG_MOB_RESET_PERSPECTIVE) - UnregisterSignal(host_mob, COMSIG_MOB_DEATH) UnregisterSignal(host_mob, COMSIG_REMOTE_VIEW_CLEAR) // Status effects - UnregisterSignal(host_mob, COMSIG_LIVING_STATUS_STUN) - UnregisterSignal(host_mob, COMSIG_LIVING_STATUS_WEAKEN) - UnregisterSignal(host_mob, COMSIG_LIVING_STATUS_PARALYZE) - UnregisterSignal(host_mob, COMSIG_LIVING_STATUS_SLEEP) - UnregisterSignal(host_mob, COMSIG_LIVING_STATUS_BLIND) + if(settings.will_stun) + UnregisterSignal(host_mob, COMSIG_LIVING_STATUS_STUN) + if(settings.will_weaken) + UnregisterSignal(host_mob, COMSIG_LIVING_STATUS_WEAKEN) + if(settings.will_paralyze) + UnregisterSignal(host_mob, COMSIG_LIVING_STATUS_PARALYZE) + if(settings.will_sleep) + UnregisterSignal(host_mob, COMSIG_LIVING_STATUS_SLEEP) + if(settings.will_blind) + UnregisterSignal(host_mob, COMSIG_LIVING_STATUS_BLIND) if(isturf(remote_view_target)) UnregisterSignal(host_mob, COMSIG_OBSERVER_MOVED) + if(settings.will_death) + UnregisterSignal(host_mob, COMSIG_MOB_DEATH) + // Handle relayed movement + if(settings.relay_movement) + UnregisterSignal(host_mob, COMSIG_MOB_RELAY_MOVEMENT) + UnregisterSignal(host_mob, COMSIG_LIVING_HANDLE_VISION) + // Hud overrides + if(settings.override_entire_hud) + UnregisterSignal(host_mob, COMSIG_LIVING_HANDLE_HUD) + if(settings.override_health_hud) + UnregisterSignal(host_mob, COMSIG_LIVING_HANDLE_HUD_HEALTH_ICON) + if(settings.override_darkvision_hud) + UnregisterSignal(host_mob, COMSIG_LIVING_HANDLE_HUD_DARKSIGHT) // Cleanup remote view - if(host_mob != remote_view_target) + if(host_mob != remote_view_target) // If target is not ourselves UnregisterSignal(remote_view_target, COMSIG_QDELETING) UnregisterSignal(remote_view_target, COMSIG_MOB_RESET_PERSPECTIVE) UnregisterSignal(remote_view_target, COMSIG_REMOTE_VIEW_CLEAR) + // Update the mob's vision right away + settings.detatch_from_mob(src, host_mob) + settings.handle_remove_visuals(src, host_mob) + host_mob.handle_vision() + host_mob.handle_regular_hud_updates() host_mob = null remote_view_target = null + // Clear settings + QDEL_NULL(settings) + +// Signal handlers /datum/component/remote_view/proc/handle_hostmob_moved(atom/source, atom/oldloc, direction, forced, movetime) SIGNAL_HANDLER PROTECTED_PROC(TRUE) + RETURN_TYPE(null) if(!host_mob) return end_view() @@ -79,6 +131,7 @@ /datum/component/remote_view/proc/handle_recursive_moved(atom/source, atom/oldloc, atom/new_loc) SIGNAL_HANDLER PROTECTED_PROC(TRUE) + RETURN_TYPE(null) ASSERT(isturf(remote_view_target)) // This signal handler is for recursive move decoupling us from /datum/component/remote_view/mob_holding_item's turf focusing when dropped in an item like a paicard // This signal is only hooked when we focus on a turf. Check the subtype for more info, this horrorshow took several days to make consistently behave. @@ -91,12 +144,14 @@ /datum/component/remote_view/proc/handle_forced_endview(datum/source) SIGNAL_HANDLER PROTECTED_PROC(TRUE) + RETURN_TYPE(null) handle_endview(source) /datum/component/remote_view/proc/handle_endview(datum/source) SIGNAL_HANDLER SHOULD_NOT_OVERRIDE(TRUE) PRIVATE_PROC(TRUE) + RETURN_TYPE(null) if(!host_mob) return end_view() @@ -105,6 +160,7 @@ /datum/component/remote_view/proc/handle_status_effects(datum/source, amount, ignore_canstun) SIGNAL_HANDLER PROTECTED_PROC(TRUE) + RETURN_TYPE(null) if(!host_mob) return // We don't really care what effect was caused, just that it was increasing the value and thus negatively affecting us. @@ -117,6 +173,7 @@ /datum/component/remote_view/proc/on_reset_perspective(datum/source) SIGNAL_HANDLER PRIVATE_PROC(TRUE) + RETURN_TYPE(null) if(!host_mob) return // Check if we're still remote viewing the SAME target! @@ -128,6 +185,7 @@ /datum/component/remote_view/proc/on_remotetarget_reset_perspective(datum/source) SIGNAL_HANDLER PRIVATE_PROC(TRUE) + RETURN_TYPE(null) // Non-mobs can't do this anyway if(!host_mob) return @@ -151,14 +209,56 @@ /datum/component/remote_view/proc/end_view() PROTECTED_PROC(TRUE) + RETURN_TYPE(null) host_mob.reset_perspective() +// Optional signal handlers for more advanced remote views + +/datum/component/remote_view/proc/handle_relay_movement(datum/source, direction) + SIGNAL_HANDLER + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + return settings.handle_relay_movement(src, host_mob, direction) + +/datum/component/remote_view/proc/handle_hud_override(datum/source) + SIGNAL_HANDLER + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + return settings.handle_hud_override(src, host_mob) + +/datum/component/remote_view/proc/handle_hud_health(datum/source) + SIGNAL_HANDLER + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + return settings.handle_hud_health(src, host_mob) + +/datum/component/remote_view/proc/handle_hud_darkvision(datum/source) + SIGNAL_HANDLER + SHOULD_NOT_OVERRIDE(TRUE) + RETURN_TYPE(null) + PRIVATE_PROC(TRUE) + settings.handle_hud_darkvision(src, host_mob) + +/datum/component/remote_view/proc/handle_mob_vision_update(datum/source) + SIGNAL_HANDLER + SHOULD_NOT_OVERRIDE(TRUE) + PRIVATE_PROC(TRUE) + return settings.handle_apply_visuals(src, host_mob) + +// Accessors + /datum/component/remote_view/proc/get_host() + RETURN_TYPE(/mob) return host_mob /datum/component/remote_view/proc/get_target() + RETURN_TYPE(/atom) return remote_view_target +/datum/component/remote_view/proc/get_coordinator() + RETURN_TYPE(/atom) + return null // For subtype + /datum/component/remote_view/proc/looking_at_target_already(atom/target) return (remote_view_target == target) @@ -170,11 +270,7 @@ VAR_PRIVATE/obj/item/host_item VAR_PRIVATE/show_message -/datum/component/remote_view/item_zoom/allow_moving - forbid_movement = FALSE - - -/datum/component/remote_view/item_zoom/Initialize(atom/focused_on, obj/item/our_item, viewsize, tileoffset, show_visible_messages) +/datum/component/remote_view/item_zoom/Initialize(atom/focused_on, vconfig_path, obj/item/our_item, viewsize, tileoffset, show_visible_messages) . = ..() host_item = our_item RegisterSignal(host_item, COMSIG_QDELETING, PROC_REF(handle_endview)) @@ -240,10 +336,7 @@ */ /datum/component/remote_view/mremote_mutation -/datum/component/remote_view/mremote_mutation/allow_moving - forbid_movement = FALSE - -/datum/component/remote_view/mremote_mutation/Initialize(atom/focused_on) +/datum/component/remote_view/mremote_mutation/Initialize(atom/focused_on, vconfig_path) if(!ismob(focused_on)) // What are you doing? This gene only works on mob targets, if you adminbus this I will personally eat your face. return COMPONENT_INCOMPATIBLE . = ..() @@ -277,10 +370,7 @@ VAR_PRIVATE/datum/view_coordinator // The object containing the viewer_list, with look() and unlook() logic VAR_PRIVATE/list/viewers // list from the view_coordinator, lists in byond are pass by reference, so this is the SAME list as on the coordinator! If you pass a null this will explode. -/datum/component/remote_view/viewer_managed/allow_moving - forbid_movement = FALSE - -/datum/component/remote_view/viewer_managed/Initialize(atom/focused_on, datum/coordinator, list/viewer_list) +/datum/component/remote_view/viewer_managed/Initialize(atom/focused_on, vconfig_path, datum/coordinator, list/viewer_list) . = ..() if(!islist(viewer_list)) // BAD BAD BAD NO CRASH("Passed a viewer_list that was not a list, or was null, to /datum/component/remote_view/viewer_managed component. Ensure the viewer_list exists before passing it into AddComponent.") @@ -289,9 +379,6 @@ view_coordinator.look(host_mob) LAZYDISTINCTADD(viewers, WEAKREF(host_mob)) RegisterSignal(view_coordinator, COMSIG_REMOTE_VIEW_CLEAR, PROC_REF(handle_forced_endview)) - // If you get this crash, it's because check_eye() in look() failed - if(!parent) - CRASH("Remoteview failed, look() cancelled view during component Initilize. Usually this is caused by check_eye().") /datum/component/remote_view/viewer_managed/Destroy(force) UnregisterSignal(view_coordinator, COMSIG_REMOTE_VIEW_CLEAR) @@ -301,6 +388,8 @@ viewers = null . = ..() +/datum/component/remote_view/viewer_managed/get_coordinator() + return view_coordinator /** * Remote view subtype that is handling a byond bug where mobs changing their client eye from inside of @@ -313,7 +402,7 @@ /datum/component/remote_view/mob_holding_item var/needs_to_decouple = FALSE // if the current top level atom is a mob -/datum/component/remote_view/mob_holding_item/Initialize(atom/focused_on) +/datum/component/remote_view/mob_holding_item/Initialize(atom/focused_on, vconfig_path) if(!isobj(focused_on)) // You shouldn't be using this if so. return COMPONENT_INCOMPATIBLE . = ..() @@ -384,11 +473,15 @@ // Yes this spawn is needed, yes I wish it wasn't. spawn(0) // Decouple the view to the turf on drop, or we'll be stuck on the mob that dropped us forever - cache_mob.AddComponent(/datum/component/remote_view, release_turf) - cache_mob.client.eye = release_turf // Yes-- - cache_mob.client.perspective = EYE_PERSPECTIVE // --this is required too. - if(!isturf(cache_mob.loc)) // For stuff like paicards - cache_mob.AddComponent(/datum/component/recursive_move) // Will rebuild parent chain. + if(!QDELETED(cache_mob)) + cache_mob.AddComponent(/datum/component/remote_view, release_turf) + cache_mob.client.eye = release_turf // Yes-- + cache_mob.client.perspective = EYE_PERSPECTIVE // --this is required too. + if(!isturf(cache_mob.loc)) // For stuff like paicards + cache_mob.AddComponent(/datum/component/recursive_move) // Will rebuild parent chain. + // If you somehow deleted before the decouple... Just fix this mess. + else + cache_mob.reset_perspective() // Because nested vore bellies do NOT get handled correctly for recursive prey. We need to tell the belly's occupants to decouple too... Then their own belly's occupants... // Yes, two loops is faster. Because we skip typechecking byondcode side and instead do it engine side when getting the contents of the mob, // we also skip typechecking every /obj in the mob on the byondcode side... Evil wizard knowledge. diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 762bfa722c..a62f94d187 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -374,9 +374,9 @@ return "Image icon: [icon] - icon_state: [icon_state] [loc ? "loc: [loc] ([loc.x],[loc.y],[loc.z])" : ""]" /// Begin coordinated remote viewing, this will call look() when the view begins, and unlook() when it ends. -/datum/proc/start_coordinated_remoteview(mob/user, atom/target, list/viewer_managed_list) +/datum/proc/start_coordinated_remoteview(mob/user, atom/target, list/viewer_managed_list, remote_view_config_path = null) ASSERT(islist(viewer_managed_list)) - user.AddComponent(/datum/component/remote_view/viewer_managed, focused_on = target, coordinator = src, viewer_list = viewer_managed_list) + user.AddComponent(/datum/component/remote_view/viewer_managed, focused_on = target, vconfig_path = remote_view_config_path, coordinator = src, viewer_list = viewer_managed_list) /// Called from /datum/component/remote_view/viewer_managed during Initilize(). /datum/proc/look(mob/user) diff --git a/code/datums/remote_view_config.dm b/code/datums/remote_view_config.dm new file mode 100644 index 0000000000..a8bcce6e27 --- /dev/null +++ b/code/datums/remote_view_config.dm @@ -0,0 +1,92 @@ +/datum/remote_view_config + // Signal config for remote view component. This controls what signals will be subbed to during init. + var/forbid_movement = TRUE + var/relay_movement = FALSE + // Status effects that will knock us out of remote view + var/will_death = TRUE + var/will_stun = TRUE + var/will_weaken = TRUE + var/will_paralyze = TRUE + var/will_sleep = TRUE + var/will_blind = TRUE + // Hud overrides, datum is responsible for restoring the hud state on attach and detatch + var/override_entire_hud = FALSE // Overrides all others, only this needs to be set if you do a fully custom hud + var/override_health_hud = FALSE + var/override_darkvision_hud = FALSE + +/// Called when remote view component finishes attaching to the mob +/datum/remote_view_config/proc/attached_to_mob( datum/component/remote_view/owner_component, mob/host_mob) + RETURN_TYPE(null) + return + +/// Called when remote view component is destroyed +/datum/remote_view_config/proc/detatch_from_mob( datum/component/remote_view/owner_component, mob/host_mob) + RETURN_TYPE(null) + return + +/// Handles relayed movement during a remote view. Override this in a subtype to handle specialized logic. If it returns true, the mob will not move, allowing you to handle remotely controlled movement. +/datum/remote_view_config/proc/handle_relay_movement( datum/component/remote_view/owner_component, mob/host_mob, datum/coordinator, atom/movable/remote_view_target, direction) + SIGNAL_HANDLER + // By default, we ask our remote_view_target to handle relaymove for us. + if(!remote_view_target) + return FALSE + return remote_view_target.relaymove(host_mob, direction) + +/// Handles visual changes to mob's hud or flags when in use, it is fired every life tick. +/datum/remote_view_config/proc/handle_apply_visuals( datum/component/remote_view/owner_component, mob/host_mob) + SIGNAL_HANDLER + RETURN_TYPE(null) + return + +/// Handles visual changes when ending the view +/datum/remote_view_config/proc/handle_remove_visuals( datum/component/remote_view/owner_component, mob/host_mob) + SIGNAL_HANDLER + RETURN_TYPE(null) + return + +/// Handles hud health indicator being replaced with a custom one (like showing the remote_view_target's health). +/datum/remote_view_config/proc/handle_hud_override( datum/component/remote_view/owner_component, mob/host_mob) + SIGNAL_HANDLER + return COMSIG_COMPONENT_HANDLED_HUD + +/// Handles hud health indicator being replaced with a custom one (like showing the remote_view_target's health). +/datum/remote_view_config/proc/handle_hud_health( datum/component/remote_view/owner_component, mob/host_mob) + SIGNAL_HANDLER + return COMSIG_COMPONENT_HANDLED_HEALTH_ICON + +/// Handles hud darkvision for if the remote view uses it's own logic for darkvision, or asks the remote_view_target to calculate it. +/datum/remote_view_config/proc/handle_hud_darkvision( datum/component/remote_view/owner_component, mob/host_mob) + SIGNAL_HANDLER + RETURN_TYPE(null) + return + + +////////////////////////////////////////////////////////////////////////////////////////////////// +// Basic subtypes +////////////////////////////////////////////////////////////////////////////////////////////////// +/// Remote view that allows moving without clearing the remote view. +/datum/remote_view_config/allow_movement + forbid_movement = FALSE + +/// Remote view that ignores stuns and other status effects ending the view +/datum/remote_view_config/effect_immune + will_stun = FALSE + will_weaken = FALSE + will_paralyze = FALSE + will_sleep = FALSE + will_blind = FALSE + +/// Remote view that relays movement to the remote_view_target +/datum/remote_view_config/relay_movement + relay_movement = TRUE + +/// Remote view that respects camera vision flags and checking for functionality of the camera. +/datum/remote_view_config/camera_standard + +/datum/remote_view_config/camera_standard/handle_apply_visuals( datum/component/remote_view/owner_component, mob/host_mob) + var/obj/machinery/camera/view_camera = owner_component.get_target() + if(!view_camera || !view_camera.can_use()) + host_mob.reset_perspective() + return + if(view_camera.isXRay()) + host_mob.sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS) diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 5cc79c7de6..e51a03fde4 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -244,7 +244,7 @@ break if (user.stat == 2) return - user.AddComponent(/datum/component/remote_view/item_zoom, focused_on = target, our_item = src, viewsize = null, tileoffset = 0, show_visible_messages = FALSE) + user.AddComponent(/datum/component/remote_view/item_zoom, focused_on = target, vconfig_path = /datum/remote_view_config/camera_standard, our_item = src, viewsize = null, tileoffset = 0, show_visible_messages = FALSE) /* /obj/item/cigarpacket diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 4917842c6e..b0da3df2f4 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -64,6 +64,7 @@ icon_state = "scanner_0" density = TRUE anchored = TRUE + flags = REMOTEVIEW_ON_ENTER use_power = USE_POWER_IDLE idle_power_usage = 50 active_power_usage = 300 diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index b7a71d2fc9..4582e6127a 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -91,6 +91,7 @@ density = TRUE anchored = TRUE unacidable = TRUE + flags = REMOTEVIEW_ON_ENTER circuit = /obj/item/circuitboard/sleeper var/mob/living/carbon/human/occupant = null var/list/available_chemicals = list() diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 1af296f0f2..37819f2e2d 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -9,6 +9,7 @@ density = TRUE anchored = TRUE unacidable = TRUE + flags = REMOTEVIEW_ON_ENTER circuit = /obj/item/circuitboard/body_scanner use_power = USE_POWER_IDLE idle_power_usage = 60 diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 1978f96986..64bf98efca 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -300,11 +300,6 @@ status = newstatus update_coverage() -/obj/machinery/camera/check_eye(mob/user) - if(!can_use()) return -1 - if(isXRay()) return SEE_TURFS|SEE_MOBS|SEE_OBJS - return 0 - /obj/machinery/camera/update_icon() if (!status || (stat & BROKEN)) icon_state = "[initial(icon_state)]1" @@ -407,7 +402,6 @@ to_chat(user, span_warning("\The [src] is broken.")) return - user.set_machine(src) wires.Interact(user) /obj/machinery/camera/proc/add_network(var/network_name) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index de7a320e22..7a67b18d15 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -30,6 +30,7 @@ desc = "An electronically-lockable pod for growing organic tissue." density = TRUE anchored = TRUE + flags = REMOTEVIEW_ON_ENTER circuit = /obj/item/circuitboard/clonepod icon = 'icons/obj/cloning.dmi' icon_state = "pod_0" diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index ec20dd5f37..34d6209e46 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -7,6 +7,7 @@ icon_state = "pod_preview" density = TRUE anchored = TRUE + flags = REMOTEVIEW_ON_ENTER layer = UNDER_JUNK_LAYER interact_offline = 1 diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 93ba213686..3ee0f78445 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -554,10 +554,3 @@ Class Procs: spark_system.start() qdel(spark_system) qdel(src) - -/datum/proc/apply_visual(mob/M) - M.sight = 0 //Just reset their mesons and stuff so they can't use them, by default. - return - -/datum/proc/remove_visual(mob/M) - return diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm index bd26bb2654..ac897d488b 100644 --- a/code/game/machinery/overview.dm +++ b/code/game/machinery/overview.dm @@ -3,7 +3,6 @@ set name = ".map" set category = "Object" set src in view(1) - usr.set_machine(src) if(!mapping) return log_game("[usr]([usr.key]) used station map L[z] in [src.loc.loc]") drawmap(usr) @@ -332,4 +331,3 @@ qdel(O) mapobjs = null - src.unset_machine() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 9dd58e939f..c0d8309a88 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -852,7 +852,7 @@ GLOBAL_LIST_EMPTY(blood_overlays_by_type) can_zoom = FALSE if(!zoom && can_zoom) - M.AddComponent(/datum/component/remote_view/item_zoom/allow_moving, focused_on = M, our_item = src, viewsize = viewsize, tileoffset = tileoffset, show_visible_messages = TRUE) + M.AddComponent(/datum/component/remote_view/item_zoom, focused_on = M, vconfig_path = /datum/remote_view_config/allow_movement, our_item = src, viewsize = viewsize, tileoffset = tileoffset, show_visible_messages = TRUE) return SEND_SIGNAL(src,COMSIG_REMOTE_VIEW_CLEAR) diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm index 936e97027c..04977ded8f 100644 --- a/code/game/objects/items/devices/spy_bug.dm +++ b/code/game/objects/items/devices/spy_bug.dm @@ -190,8 +190,12 @@ if(in_use) return + if(cameras.len == 1 && user.is_remote_viewing()) + user.reset_perspective() + return if(!can_use_cam(user)) return + if(cameras.len == 1) selected_camera = cameras[1] else @@ -209,7 +213,7 @@ unpair(selected_camera) selected_camera = null return - user.AddComponent(/datum/component/remote_view/item_zoom, focused_on = selected_camera, our_item = src, viewsize = null, tileoffset = 0, show_visible_messages = TRUE) + user.AddComponent(/datum/component/remote_view/item_zoom, focused_on = selected_camera, vconfig_path = /datum/remote_view_config/camera_standard, our_item = src, viewsize = null, tileoffset = 0, show_visible_messages = TRUE) /obj/item/bug_monitor/proc/can_use_cam(mob/user) if(!cameras.len) @@ -231,9 +235,6 @@ if(Adjacent(user)) . += "The time '12:00' is blinking in the corner of the screen and \the [src] looks very cheaply made." -/obj/machinery/camera/bug/check_eye(var/mob/user as mob) - return 0 - /obj/machinery/camera/bug network = list(NETWORK_SECURITY) diff --git a/code/game/objects/items/uav.dm b/code/game/objects/items/uav.dm index 3a429f1989..89b5efc7cc 100644 --- a/code/game/objects/items/uav.dm +++ b/code/game/objects/items/uav.dm @@ -281,12 +281,6 @@ /obj/item/uav/proc/remove_master(var/mob/living/M) LAZYREMOVE(masters, WEAKREF(M)) -/obj/item/uav/check_eye() - if(state == UAV_ON) - return 0 - else - return -1 - /obj/item/uav/proc/start_hover() if(!ion_trail.on) //We'll just use this to store if we're floating or not ion_trail.start() diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 3c26fb87d6..7de494a072 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -92,7 +92,6 @@ /obj/item/assembly/attack_self(mob/user as mob) if(!user) return 0 - user.set_machine(src) tgui_interact(user) return 1 diff --git a/code/modules/mob/freelook/ai/eye.dm b/code/modules/mob/freelook/ai/eye.dm index 37ac45c13f..34d2cad7a5 100644 --- a/code/modules/mob/freelook/ai/eye.dm +++ b/code/modules/mob/freelook/ai/eye.dm @@ -85,7 +85,7 @@ if(!src.eyeobj) return - if(client.eye) + if(client && client.eye) reset_perspective(src) for(var/datum/chunk/c in eyeobj.visibleChunks) diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 4280e35a62..078d4f9846 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -113,26 +113,6 @@ if(!.) return - if (healths) - if (stat != 2) - switch(health) - if(100 to INFINITY) - healths.icon_state = "health0" - if(80 to 100) - healths.icon_state = "health1" - if(60 to 80) - healths.icon_state = "health2" - if(40 to 60) - healths.icon_state = "health3" - if(20 to 40) - healths.icon_state = "health4" - if(0 to 20) - healths.icon_state = "health5" - else - healths.icon_state = "health6" - else - healths.icon_state = "health7" - client.screen.Remove(GLOB.global_hud.blurry,GLOB.global_hud.druggy,GLOB.global_hud.vimpaired) if ( stat != 2) @@ -144,6 +124,31 @@ set_fullscreen(eye_blurry, "blurry", /atom/movable/screen/fullscreen/blurry) set_fullscreen(druggy, "high", /atom/movable/screen/fullscreen/high) +/mob/living/carbon/alien/handle_hud_icons_health() + . = ..() + if(!. || !healths) + return + + if (stat == DEAD) + healths.icon_state = "health7" + return + + switch(health) + if(100 to INFINITY) + healths.icon_state = "health0" + if(80 to 100) + healths.icon_state = "health1" + if(60 to 80) + healths.icon_state = "health2" + if(40 to 60) + healths.icon_state = "health3" + if(20 to 40) + healths.icon_state = "health4" + if(0 to 20) + healths.icon_state = "health5" + else + healths.icon_state = "health6" + /mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment) // Both alien subtypes survive in vaccum and suffer in high temperatures, // so I'll just define this once, for both (see radiation comment above) diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index b3009e7edb..ac9809af50 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -177,26 +177,6 @@ if(!.) return - if (healths) - if (stat != DEAD) - switch(health) - if(100 to INFINITY) - healths.icon_state = "health0" - if(80 to 100) - healths.icon_state = "health1" - if(60 to 80) - healths.icon_state = "health2" - if(40 to 60) - healths.icon_state = "health3" - if(20 to 40) - healths.icon_state = "health4" - if(0 to 20) - healths.icon_state = "health5" - else - healths.icon_state = "health6" - else - healths.icon_state = "health7" - client.screen.Remove(GLOB.global_hud.blurry,GLOB.global_hud.druggy,GLOB.global_hud.vimpaired) if (stat != DEAD) @@ -207,3 +187,28 @@ set_fullscreen(disabilities & NEARSIGHTED, "impaired", /atom/movable/screen/fullscreen/impaired, 1) set_fullscreen(eye_blurry, "blurry", /atom/movable/screen/fullscreen/blurry) set_fullscreen(druggy, "high", /atom/movable/screen/fullscreen/high) + +/mob/living/carbon/brain/handle_hud_icons_health() + . = ..() + if(!. || !healths) + return + + if (stat == DEAD) + healths.icon_state = "health7" + return + + switch(health) + if(100 to INFINITY) + healths.icon_state = "health0" + if(80 to 100) + healths.icon_state = "health1" + if(60 to 80) + healths.icon_state = "health2" + if(40 to 60) + healths.icon_state = "health3" + if(20 to 40) + healths.icon_state = "health4" + if(0 to 20) + healths.icon_state = "health5" + else + healths.icon_state = "health6" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 925ffa394d..a28dfdcd69 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1006,7 +1006,7 @@ var/mob/target = input ("Who do you want to project your mind to?") as mob in creatures if(target) - AddComponent(/datum/component/remote_view/mremote_mutation, target) + AddComponent(/datum/component/remote_view/mremote_mutation, focused_on = target, vconfig_path = null) return /mob/living/carbon/human/get_visible_gender(mob/user, force) @@ -1548,11 +1548,6 @@ return remove_from_mob(W, src.loc) return ..() -/mob/living/carbon/human/reset_perspective(atom/A, update_hud = 1) - ..() - if(update_hud) - handle_regular_hud_updates() - /mob/living/carbon/human/Check_Shoegrip() if(shoes && (shoes.item_flags & NOSLIP) && istype(shoes, /obj/item/clothing/shoes/magboots)) //magboots + dense_object = no floating return 1 diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 71c8d35b63..4bec4ae3de 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1455,7 +1455,6 @@ if(stat == DEAD) //Dead if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO - if(healths) healths.icon_state = "health7" //DEAD healthmeter else if(stat == UNCONSCIOUS && health <= 0) //Crit //Critical damage passage overlay @@ -1533,48 +1532,6 @@ else clear_fullscreen("fear") - if(healths) - if(chem_effects[CE_PAINKILLER] > 100) - healths.icon_state = "health_numb" - else - // Generate a by-limb health display. - var/mutable_appearance/healths_ma = new(healths) - healths_ma.icon_state = "blank" - healths_ma.overlays = null - healths_ma.plane = PLANE_PLAYER_HUD - - var/no_damage = 1 - var/trauma_val = 0 // Used in calculating softcrit/hardcrit indicators. - if(!(species.flags & NO_PAIN)) - trauma_val = max(traumatic_shock,halloss)/species.total_health - var/limb_trauma_val = trauma_val*0.3 - // Collect and apply the images all at once to avoid appearance churn. - var/list/health_images = list() - for(var/obj/item/organ/external/E in organs) - if(no_damage && (E.brute_dam || E.burn_dam)) - no_damage = 0 - health_images += E.get_damage_hud_image(limb_trauma_val) - - // Apply a fire overlay if we're burning. - if(on_fire || get_hallucination_component()?.get_hud_state() == HUD_HALLUCINATION_ONFIRE) - health_images += image('icons/mob/OnFire.dmi',"[get_fire_icon_state()]") - - // Show a general pain/crit indicator if needed. - if(get_hallucination_component()?.get_hud_state() == HUD_HALLUCINATION_CRIT) - trauma_val = 2 - if(trauma_val) - if(!(species.flags & NO_PAIN)) - if(trauma_val > 0.7) - health_images += image('icons/mob/screen1_health.dmi',"softcrit") - if(trauma_val >= 1) - health_images += image('icons/mob/screen1_health.dmi',"hardcrit") - else if(no_damage) - health_images += image('icons/mob/screen1_health.dmi',"fullhealth") - - healths_ma.add_overlay(health_images) - healths.appearance = healths_ma - - var/fat_alert = /atom/movable/screen/alert/fat var/hungry_alert = /atom/movable/screen/alert/hungry var/starving_alert = /atom/movable/screen/alert/starving @@ -1658,10 +1615,58 @@ if(found_welder) client.screen |= GLOB.global_hud.darkMask -/mob/living/carbon/human/reset_perspective(atom/A) - ..() - if(machine_visual && machine_visual != A) - machine_visual.remove_visual(src) +/mob/living/carbon/human/handle_hud_icons_health() + . = ..() + if(!. || !healths) + return + + if(stat == DEAD) //Dead + healths.icon_state = "health7" //DEAD healthmeter + return + + if(stat == UNCONSCIOUS && health <= 0) //Crit + return + + if(chem_effects[CE_PAINKILLER] > 100) + healths.icon_state = "health_numb" + return + + // Generate a by-limb health display. + var/mutable_appearance/healths_ma = new(healths) + healths_ma.icon_state = "blank" + healths_ma.overlays = null + healths_ma.plane = PLANE_PLAYER_HUD + + var/no_damage = 1 + var/trauma_val = 0 // Used in calculating softcrit/hardcrit indicators. + if(!(species.flags & NO_PAIN)) + trauma_val = max(traumatic_shock,halloss)/species.total_health + var/limb_trauma_val = trauma_val*0.3 + // Collect and apply the images all at once to avoid appearance churn. + var/list/health_images = list() + for(var/obj/item/organ/external/E in organs) + if(no_damage && (E.brute_dam || E.burn_dam)) + no_damage = 0 + health_images += E.get_damage_hud_image(limb_trauma_val) + + // Apply a fire overlay if we're burning. + if(on_fire || get_hallucination_component()?.get_hud_state() == HUD_HALLUCINATION_ONFIRE) + health_images += image('icons/mob/OnFire.dmi',"[get_fire_icon_state()]") + + // Show a general pain/crit indicator if needed. + if(get_hallucination_component()?.get_hud_state() == HUD_HALLUCINATION_CRIT) + trauma_val = 2 + if(trauma_val) + if(!(species.flags & NO_PAIN)) + if(trauma_val > 0.7) + health_images += image('icons/mob/screen1_health.dmi',"softcrit") + if(trauma_val >= 1) + health_images += image('icons/mob/screen1_health.dmi',"hardcrit") + else if(no_damage) + health_images += image('icons/mob/screen1_health.dmi',"fullhealth") + + healths_ma.add_overlay(health_images) + healths.appearance = healths_ma /mob/living/carbon/human/handle_vision() if(stat == DEAD) @@ -1739,7 +1744,7 @@ if(!seer && !glasses_processed && seedarkness) see_invisible = see_invisible_default - if(!get_current_machine() && eyeobj && eyeobj.owner != src) + if(eyeobj && eyeobj.owner != src) reset_perspective() // Call parent to handle signals diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 3b6127fb6b..3c77cd824b 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -236,7 +236,7 @@ if(!.) return handle_darksight() - handle_hud_icons() + handle_hud_icons_health() /mob/living/proc/update_sight() if(!seedarkness) @@ -252,12 +252,11 @@ return -/mob/living/proc/handle_hud_icons() - handle_hud_icons_health() - return - /mob/living/proc/handle_hud_icons_health() - return + SHOULD_CALL_PARENT(TRUE) + if(SEND_SIGNAL(src,COMSIG_LIVING_HANDLE_HUD_HEALTH_ICON) & COMSIG_COMPONENT_HANDLED_HEALTH_ICON) + return FALSE + return TRUE /mob/living/proc/handle_light() if(glow_override) @@ -277,6 +276,7 @@ return FALSE /mob/living/proc/handle_darksight() + SEND_SIGNAL(src,COMSIG_LIVING_HANDLE_HUD_DARKSIGHT) if(!seedarkness) //Cheap 'always darksight' var dsoverlay.alpha = 255 return diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index efcfcf617e..1d117d730d 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -45,5 +45,6 @@ voice_sounds_list = DEFAULT_TALK_SOUNDS resize(size_multiplier, animate = FALSE, uncapped = has_large_resize_bounds(), ignore_prefs = TRUE, aura_animation = FALSE) init_vore(TRUE) + handle_regular_hud_updates() return . diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 16fea20c1a..40190de74e 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -441,10 +441,6 @@ var/list/ai_verbs_default = list( emergency_message_cooldown = 1 spawn(300) emergency_message_cooldown = 0 -/mob/living/silicon/ai/check_eye(var/mob/user as mob) - if (!camera) - return -1 - return 0 /mob/living/silicon/ai/restrained() return 0 @@ -513,21 +509,23 @@ var/list/ai_verbs_default = list( if(.) end_multicam() -/mob/living/silicon/ai/reset_perspective(atom/A) +/mob/living/silicon/ai/reset_perspective(atom/new_eye) if(camera) camera.set_light(0) - if(istype(A,/obj/machinery/camera)) - camera = A - if(A != GLOB.ai_camera_room_landmark) + if(istype(new_eye,/obj/machinery/camera)) + camera = new_eye + if(new_eye != GLOB.ai_camera_room_landmark) end_multicam() . = ..() if(.) - if(!A && isturf(loc) && eyeobj) + if(!new_eye && isturf(loc) && eyeobj) end_multicam() reset_perspective(eyeobj) - if(istype(A,/obj/machinery/camera)) - if(camera_light_on) A.set_light(AI_CAMERA_LUMINOSITY) - else A.set_light(0) + if(istype(new_eye,/obj/machinery/camera)) + if(camera_light_on) + new_eye.set_light(AI_CAMERA_LUMINOSITY) + else + new_eye.set_light(0) /mob/living/silicon/ai/proc/switchCamera(var/obj/machinery/camera/C) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 3f9c3b94b1..2817de3be5 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -131,11 +131,6 @@ . += "" . += show_silenced() -/mob/living/silicon/pai/check_eye(var/mob/user as mob) - if (!src.current) - return -1 - return 0 - /mob/living/silicon/pai/restrained() if(istype(src.loc,/obj/item/paicard)) return 0 @@ -177,16 +172,13 @@ /mob/living/silicon/pai/proc/switchCamera(var/obj/machinery/camera/C) if (!C) - src.unset_machine() src.reset_perspective() return 0 if (stat == 2 || !C.status || !(src.network in C.network)) return 0 // ok, we're alive, camera is good and in our network... - - src.set_machine(src) src.current = C - src.AddComponent(/datum/component/remote_view, C) + src.AddComponent(/datum/component/remote_view, focused_on = C, vconfig_path = /datum/remote_view_config/camera_standard) return 1 /mob/living/silicon/pai/verb/reset_record_view() @@ -205,9 +197,11 @@ /mob/living/silicon/pai/cancel_camera() set category = "Abilities.pAI Commands" set name = "Cancel Camera View" - src.reset_perspective() - src.unset_machine() - src.cameraFollow = null + reset_perspective() + +/mob/living/silicon/pai/reset_perspective(atom/new_eye) + . = ..() + current = null // Procs/code after this point is used to convert the stationary pai item into a // mobile pai mob. This also includes handling some of the general shit that can occur diff --git a/code/modules/mob/living/silicon/pai/pai_hud.dm b/code/modules/mob/living/silicon/pai/pai_hud.dm index 9465275b3a..518a04d1e8 100644 --- a/code/modules/mob/living/silicon/pai/pai_hud.dm +++ b/code/modules/mob/living/silicon/pai/pai_hud.dm @@ -393,33 +393,38 @@ if(!.) return - if(healths) - if(stat != DEAD) - var/heal_per = (health / getMaxHealth()) * 100 - switch(heal_per) - if(100 to INFINITY) - healths.icon_state = "health0" - if(80 to 100) - healths.icon_state = "health1" - if(60 to 80) - healths.icon_state = "health2" - if(40 to 60) - healths.icon_state = "health3" - if(20 to 40) - healths.icon_state = "health4" - if(0 to 20) - healths.icon_state = "health5" - else - healths.icon_state = "health6" - else - healths.icon_state = "health7" - if(pai_fold_display) if(loc == card) pai_fold_display.icon_state = "folded" else pai_fold_display.icon_state = "unfolded" +/mob/living/silicon/pai/handle_hud_icons_health() + . = ..() + if(!. || !healths) + return + + if(stat == DEAD) + healths.icon_state = "health7" + return + + var/heal_per = (health / getMaxHealth()) * 100 + switch(heal_per) + if(100 to INFINITY) + healths.icon_state = "health0" + if(80 to 100) + healths.icon_state = "health1" + if(60 to 80) + healths.icon_state = "health2" + if(40 to 60) + healths.icon_state = "health3" + if(20 to 40) + healths.icon_state = "health4" + if(0 to 20) + healths.icon_state = "health5" + else + healths.icon_state = "health6" + /mob/living/silicon/pai/toggle_hud_vis(full) if(!client) return FALSE diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index d7bffd27bc..fbff53459e 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -228,42 +228,6 @@ if(!.) return - if (healths) - if (stat != 2) - if(istype(src,/mob/living/silicon/robot/drone)) - switch(health) - if(35 to INFINITY) - healths.icon_state = "health0" - if(25 to 34) - healths.icon_state = "health1" - if(15 to 24) - healths.icon_state = "health2" - if(5 to 14) - healths.icon_state = "health3" - if(0 to 4) - healths.icon_state = "health4" - if(-35 to 0) - healths.icon_state = "health5" - else - healths.icon_state = "health6" - else - if(health >= 200) - healths.icon_state = "health0" - else if(health >= 150) - healths.icon_state = "health1" - else if(health >= 100) - healths.icon_state = "health2" - else if(health >= 50) - healths.icon_state = "health3" - else if(health >= 0) - healths.icon_state = "health4" - else if(health >= (-getMaxHealth())) - healths.icon_state = "health5" - else - healths.icon_state = "health6" - else - healths.icon_state = "health7" - if (syndicate) for(var/datum/mind/tra in traitors.current_antagonists) if(tra.current) @@ -294,9 +258,9 @@ else throw_alert("temp", /atom/movable/screen/alert/cold/robot, COLD_ALERT_SEVERITY_MODERATE) -//Oxygen and fire does nothing yet!! -// if (oxygen) oxygen.icon_state = "oxy[oxygen_alert ? 1 : 0]" -// if (fire) fire.icon_state = "fire[fire_alert ? 1 : 0]" + //Oxygen and fire does nothing yet!! + //if (oxygen) oxygen.icon_state = "oxy[oxygen_alert ? 1 : 0]" + //if (fire) fire.icon_state = "fire[fire_alert ? 1 : 0]" if(stat != 2) if(blinded) @@ -312,6 +276,49 @@ else clear_alert("hacked") +/mob/living/silicon/robot/handle_hud_icons_health() + . = ..() + if(!. || !healths) + return + + if(stat == DEAD) + healths.icon_state = "health7" + return + + if(istype(src,/mob/living/silicon/robot/drone)) + switch(health) + if(35 to INFINITY) + healths.icon_state = "health0" + if(25 to 34) + healths.icon_state = "health1" + if(15 to 24) + healths.icon_state = "health2" + if(5 to 14) + healths.icon_state = "health3" + if(0 to 4) + healths.icon_state = "health4" + if(-35 to 0) + healths.icon_state = "health5" + else + healths.icon_state = "health6" + return + + // Not a switch because of the -max_health() case + if(health >= 200) + healths.icon_state = "health0" + else if(health >= 150) + healths.icon_state = "health1" + else if(health >= 100) + healths.icon_state = "health2" + else if(health >= 50) + healths.icon_state = "health3" + else if(health >= 0) + healths.icon_state = "health4" + else if(health >= (-getMaxHealth())) + healths.icon_state = "health5" + else + healths.icon_state = "health6" + /mob/living/silicon/robot/proc/update_cell() if(cell) var/cellcharge = cell.charge/cell.maxcharge diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index c60477d5c7..2f440cac32 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -710,7 +710,7 @@ I.brute = C.brute_damage I.burn = C.electronics_damage - I.loc = src.loc + I.forceMove(loc) if(C.installed == 1) C.uninstall() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 28e45ac204..221326ebfa 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -398,8 +398,7 @@ /mob/living/silicon/reset_perspective(atom/new_eye) . = ..() - if(cameraFollow) - cameraFollow = null + cameraFollow = null /mob/living/silicon/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /atom/movable/screen/fullscreen/flash) if(affect_silicon) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 318d9e11b3..7c624924c7 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -306,10 +306,10 @@ if(remote_comp?.looking_at_target_already(loc)) return FALSE if(isitem(loc) || isbelly(loc)) // Requires more careful handling than structures because they are held by mobs - AddComponent(/datum/component/remote_view/mob_holding_item, loc) + AddComponent(/datum/component/remote_view/mob_holding_item, focused_on = loc, vconfig_path = null) return TRUE if(loc.flags & REMOTEVIEW_ON_ENTER) // Handle atoms that begin a remote view upon entering them. - AddComponent(/datum/component/remote_view, loc) + AddComponent(/datum/component/remote_view, focused_on = loc, vconfig_path = null) return TRUE return FALSE @@ -564,7 +564,7 @@ var/mob/mob_eye = targets[eye_name] if(client && mob_eye) - AddComponent(/datum/component/remote_view, focused_on = mob_eye) + AddComponent(/datum/component/remote_view, focused_on = mob_eye, vconfig_path = null) if(is_admin) client.adminobs = TRUE if(mob_eye == client.mob || !is_remote_viewing()) @@ -573,7 +573,6 @@ /mob/verb/cancel_camera() set name = "Cancel Camera View" set category = "OOC.Game" - unset_machine() reset_perspective() /mob/Topic(href, href_list) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 6a36bc04c5..48426543e1 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -561,7 +561,6 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT) /mob/proc/switch_to_camera(var/obj/machinery/camera/C) if (!C.can_use() || stat || (get_dist(C, src) > 1 || !check_current_machine(src) || blinded || !canmove)) return 0 - check_eye(src) return 1 /mob/living/silicon/ai/switch_to_camera(var/obj/machinery/camera/C) @@ -716,12 +715,13 @@ var/list/global/organ_rel_size = list( /mob/proc/recalculate_vis() return -/// General HUD updates done regularly (health puppet things, etc). Returns true if the mob has a client. +/// General HUD updates done regularly (health puppet things, etc). Returns true if the mob has a client and is allowed to update its hud. /mob/proc/handle_regular_hud_updates() SHOULD_CALL_PARENT(TRUE) if(!client) return FALSE - SEND_SIGNAL(src,COMSIG_LIVING_HANDLE_HUD) + if(SEND_SIGNAL(src,COMSIG_LIVING_HANDLE_HUD) & COMSIG_COMPONENT_HANDLED_HUD) + return FALSE return TRUE /// Handle eye things like the Byond SEE_TURFS, SEE_OBJS, etc. diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index e299b38a86..f6d3c0fe27 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -214,11 +214,8 @@ return // Relaymove could handle it - var/obj/machine = my_mob.get_current_machine() - if(machine) - var/result = machine.relaymove(my_mob, direct) - if(result) - return result + if(SEND_SIGNAL(my_mob, COMSIG_MOB_RELAY_MOVEMENT, direct)) + return TRUE // Can't control ourselves when drifting if((isspace(loc) || my_mob.lastarea?.get_gravity() == 0) && isturf(loc)) diff --git a/code/modules/modular_computers/computers/modular_computer/core.dm b/code/modules/modular_computers/computers/modular_computer/core.dm index d46be28ffe..02a84c22f1 100644 --- a/code/modules/modular_computers/computers/modular_computer/core.dm +++ b/code/modules/modular_computers/computers/modular_computer/core.dm @@ -271,24 +271,6 @@ update_uis() // Used by camera monitor program -/obj/item/modular_computer/check_eye(var/mob/user) - if(active_program) - return active_program.check_eye(user) - else - return ..() - -/obj/item/modular_computer/apply_visual(var/mob/user) - if(active_program) - return active_program.apply_visual(user) - -/obj/item/modular_computer/remove_visual(var/mob/user) - if(active_program) - return active_program.remove_visual(user) - -/obj/item/modular_computer/relaymove(var/mob/user, direction) - if(active_program) - return active_program.relaymove(user, direction) - /obj/item/modular_computer/proc/set_autorun(program) if(!hard_drive) return diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 7be70390cf..953e4fb8d0 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -219,24 +219,3 @@ if(istype(user)) computer.tgui_interact(user) // Re-open the UI on this computer. It should show the main screen now. - - - -// Relays the call to nano module, if we have one -/datum/computer_file/program/proc/check_eye(var/mob/user) - if(TM) - return TM.check_eye(user) - else - return -1 - -/datum/computer_file/program/apply_visual(mob/M) - if(TM) - return TM.apply_visual(M) - -/datum/computer_file/program/remove_visual(mob/M) - if(TM) - return TM.remove_visual(M) - -/datum/computer_file/program/proc/relaymove(var/mob/M, direction) - if(TM) - return TM.relaymove(M, direction) diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm index 12e48f7a72..9a4042efcf 100644 --- a/code/modules/organs/subtypes/machine.dm +++ b/code/modules/organs/subtypes/machine.dm @@ -102,6 +102,7 @@ stored_mmi.forceMove(drop_location()) if(owner.mind) owner.mind.transfer_to(stored_mmi.brainmob) + stored_mmi.brainmob.reset_perspective() ..() var/mob/living/holder_mob = loc diff --git a/code/modules/overmap/ships/computers/helm.dm b/code/modules/overmap/ships/computers/helm.dm index be6586e071..473595a1b7 100644 --- a/code/modules/overmap/ships/computers/helm.dm +++ b/code/modules/overmap/ships/computers/helm.dm @@ -270,11 +270,11 @@ GLOBAL_LIST_EMPTY(all_waypoints) . = TRUE if("manual") - if(check_eye(ui.user) < 0) + if(!get_dist(ui.user, src) > 1 || ui.user.blinded || !linked) return FALSE else if(!viewing_overmap(ui.user) && linked) if(!viewers) viewers = list() // List must exist for pass by reference to work - start_coordinated_remoteview(ui.user, linked, viewers) + start_coordinated_remoteview(ui.user, linked, viewers, /datum/remote_view_config/overmap_ship_control) else ui.user.reset_perspective() . = TRUE diff --git a/code/modules/overmap/ships/computers/sensors.dm b/code/modules/overmap/ships/computers/sensors.dm index 3632df5036..b752f55a9d 100644 --- a/code/modules/overmap/ships/computers/sensors.dm +++ b/code/modules/overmap/ships/computers/sensors.dm @@ -89,7 +89,7 @@ switch(action) if("viewing") if(ui.user && !isAI(ui.user)) - if(check_eye(ui.user) < 0) + if(!get_dist(ui.user, src) > 1 || ui.user.blinded || !linked) . = FALSE else if(!viewing_overmap(ui.user) && linked) if(!viewers) viewers = list() // List must exist for pass by reference to work diff --git a/code/modules/overmap/ships/computers/ship.dm b/code/modules/overmap/ships/computers/ship.dm index b173e1c750..faa0a7da20 100644 --- a/code/modules/overmap/ships/computers/ship.dm +++ b/code/modules/overmap/ships/computers/ship.dm @@ -67,22 +67,13 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov // Management of mob view displacement. look to shift view to the ship on the overmap; unlook to shift back. /obj/machinery/computer/ship/look(var/mob/user) - apply_visual(user) if(linked.real_appearance) user.client?.images += linked.real_appearance - user.set_machine(src) - if(isliving(user)) - var/mob/living/L = user - L.handle_vision() user.set_viewsize(world.view + extra_view) /obj/machinery/computer/ship/unlook(var/mob/user) - user.unset_machine() if(linked && linked.real_appearance && user.client) user.client.images -= linked.real_appearance - if(isliving(user)) - var/mob/living/L = user - L.handle_vision() user.set_viewsize() // reset to default /obj/machinery/computer/ship/proc/viewing_overmap(mob/user) @@ -92,13 +83,6 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov . = ..() user.reset_perspective() -/obj/machinery/computer/ship/check_eye(var/mob/user) - if(user.blinded || !linked) - user.reset_perspective() - return -1 - else - return 0 - /obj/machinery/computer/ship/sensors/Destroy() sensors = null . = ..() diff --git a/code/modules/tgui/modules/_base.dm b/code/modules/tgui/modules/_base.dm index 8fe164699c..cd3e98153c 100644 --- a/code/modules/tgui/modules/_base.dm +++ b/code/modules/tgui/modules/_base.dm @@ -37,9 +37,6 @@ Code is pretty much ripped verbatim from nano modules, but with un-needed stuff if(host) host.tgui_close(user) -/datum/tgui_module/proc/check_eye(mob/user) - return -1 - /datum/tgui_module/proc/can_still_topic(mob/user, datum/tgui_state/state) return (tgui_status(user, state) == STATUS_INTERACTIVE) diff --git a/code/modules/tgui/modules/ntos-only/uav.dm b/code/modules/tgui/modules/ntos-only/uav.dm index c24ca726ed..4fe65182c7 100644 --- a/code/modules/tgui/modules/ntos-only/uav.dm +++ b/code/modules/tgui/modules/ntos-only/uav.dm @@ -70,14 +70,14 @@ if(!current_uav) return FALSE - if(current_uav.check_eye(ui.user) < 0) + if(!current_uav.state) to_chat(ui.user,span_warning("The screen freezes for a moment, before returning to the UAV selection menu. It's not able to connect to that UAV.")) else - if(check_eye(ui.user) < 0) + if(get_dist(ui.user, tgui_host()) > 1 || ui.user.blinded) return FALSE else if(!viewing_uav(ui.user)) if(!viewers) viewers = list() // List must exist for pass by reference to work - start_coordinated_remoteview(ui.user, current_uav, viewers) + start_coordinated_remoteview(ui.user, current_uav, viewers, /datum/remote_view_config/uav_control) else ui.user.reset_perspective() return TRUE @@ -173,17 +173,12 @@ if(issilicon(user)) //Too complicated for me to want to mess with at the moment to_chat(user, span_warning("Regulations prevent you from controlling several corporeal forms at the same time!")) return - if(!current_uav) return - - if(!user.check_current_machine(tgui_host())) - user.set_machine(tgui_host()) current_uav.add_master(user) LAZYDISTINCTADD(viewers, WEAKREF(user)) /datum/tgui_module/uav/unlook(mob/user) - user.unset_machine() if(current_uav) current_uav.remove_master(user) LAZYREMOVE(viewers, WEAKREF(user)) @@ -192,45 +187,77 @@ . = ..() user.reset_perspective() -/datum/tgui_module/uav/check_eye(mob/user) - if(get_dist(user, tgui_host()) > 1 || user.blinded || !current_uav) - user.reset_perspective() - return -1 - - var/viewflag = current_uav.check_eye(user) - if(viewflag < 0) //camera doesn't work - user.reset_perspective() - return -1 - - return viewflag - //// -//// Relaying movements to the UAV +//// Settings for remote view //// -/datum/tgui_module/uav/relaymove(var/mob/user, direction) - if(current_uav) - return current_uav.relaymove(user, direction, signal_strength) +/datum/remote_view_config/uav_control + relay_movement = TRUE + override_health_hud = TRUE + var/original_health_hud_icon -//// -//// The effects when looking through a UAV -//// -/datum/tgui_module/uav/apply_visual(mob/M) - if(!M.client) +/datum/remote_view_config/uav_control/handle_relay_movement( datum/component/remote_view/owner_component, mob/host_mob, direction) + var/datum/tgui_module/uav/tgui_owner = owner_component.get_coordinator() + if(tgui_owner?.current_uav) + return tgui_owner.current_uav.relaymove(host_mob, direction, tgui_owner.signal_strength) + return FALSE + +/datum/remote_view_config/uav_control/handle_apply_visuals( datum/component/remote_view/owner_component, mob/host_mob) + var/datum/tgui_module/uav/tgui_owner = owner_component.get_coordinator() + if(!tgui_owner) return - if(WEAKREF(M) in viewers) - M.overlay_fullscreen("fishbed",/atom/movable/screen/fullscreen/fishbed) - M.overlay_fullscreen("scanlines",/atom/movable/screen/fullscreen/scanline) - - if(signal_strength <= 1) - M.overlay_fullscreen("whitenoise",/atom/movable/screen/fullscreen/noise) - else - M.clear_fullscreen("whitenoise", 0) + if(get_dist(host_mob, tgui_owner.tgui_host()) > 1 || !tgui_owner.current_uav) + host_mob.reset_perspective() + return + // Apply hud + host_mob.overlay_fullscreen("fishbed",/atom/movable/screen/fullscreen/fishbed) + host_mob.overlay_fullscreen("scanlines",/atom/movable/screen/fullscreen/scanline) + if(tgui_owner.signal_strength <= 1) + host_mob.overlay_fullscreen("whitenoise",/atom/movable/screen/fullscreen/noise) else - remove_visual(M) + host_mob.clear_fullscreen("whitenoise", 0) -/datum/tgui_module/uav/remove_visual(mob/M) - if(!M.client) - return - M.clear_fullscreen("fishbed",0) - M.clear_fullscreen("scanlines",0) - M.clear_fullscreen("whitenoise",0) +/datum/remote_view_config/uav_control/handle_remove_visuals( datum/component/remote_view/owner_component, mob/host_mob) + // Clear hud + host_mob.clear_fullscreen("fishbed",0) + host_mob.clear_fullscreen("scanlines",0) + host_mob.clear_fullscreen("whitenoise",0) + +// We are responsible for restoring the health UI's icons on removal +/datum/remote_view_config/uav_control/attached_to_mob( datum/component/remote_view/owner_component, mob/host_mob) + original_health_hud_icon = host_mob.healths?.icon + +/datum/remote_view_config/uav_control/detatch_from_mob( datum/component/remote_view/owner_component, mob/host_mob) + if(host_mob.healths && original_health_hud_icon) + host_mob.healths.icon = original_health_hud_icon + host_mob.healths.appearance = null + +// Show the uav health instead of the mob's while it is viewing +/datum/remote_view_config/uav_control/handle_hud_health( datum/component/remote_view/owner_component, mob/host_mob) + var/datum/tgui_module/uav/tgui_owner = owner_component.get_coordinator() + + var/mutable_appearance/MA = new (host_mob.healths) + MA.icon = 'icons/mob/screen1_robot_minimalist.dmi' + MA.cut_overlays() + + if(!tgui_owner?.current_uav) + MA.icon_state = "health7" + else + switch(tgui_owner.current_uav.health) + if(100 to INFINITY) + MA.icon_state = "health0" + if(80 to 100) + MA.icon_state = "health1" + if(60 to 80) + MA.icon_state = "health2" + if(40 to 60) + MA.icon_state = "health3" + if(20 to 40) + MA.icon_state = "health4" + if(0 to 20) + MA.icon_state = "health5" + else + MA.icon_state = "health6" + + host_mob.healths.icon_state = "blank" + host_mob.healths.appearance = MA + return COMSIG_COMPONENT_HANDLED_HEALTH_ICON diff --git a/code/modules/tgui/modules/overmap.dm b/code/modules/tgui/modules/overmap.dm index 7e93efadc5..738e118714 100644 --- a/code/modules/tgui/modules/overmap.dm +++ b/code/modules/tgui/modules/overmap.dm @@ -73,13 +73,6 @@ /datum/tgui_module/ship/proc/viewing_overmap(mob/user) return (WEAKREF(user) in viewers) -/datum/tgui_module/ship/check_eye(var/mob/user) - if(!get_dist(user, tgui_host()) > 1 || user.blinded || !linked) - user.reset_perspective() - return -1 - else - return 0 - // Navigation /datum/tgui_module/ship/nav name = "Navigation Display" @@ -136,11 +129,11 @@ return FALSE if(action == "viewing") - if(check_eye(ui.user) < 0) + if(!get_dist(ui.user, src) > 1 || ui.user.blinded || !linked) return FALSE else if(!viewing_overmap(ui.user)) if(!viewers) viewers = list() // List must exist for pass by reference to work - start_coordinated_remoteview(ui.user, linked, viewers) + start_coordinated_remoteview(ui.user, linked, viewers, /datum/remote_view_config/overmap_ship_control) else ui.user.reset_perspective() return TRUE @@ -406,11 +399,11 @@ . = TRUE if("manual") - if(check_eye(ui.user) < 0) + if(ui.user.blinded || !linked) return FALSE else if(!viewing_overmap(ui.user)) if(!viewers) viewers = list() - start_coordinated_remoteview(ui.user, linked, viewers) + start_coordinated_remoteview(ui.user, linked, viewers, /datum/remote_view_config/overmap_ship_control) else ui.user.reset_perspective() . = TRUE @@ -479,3 +472,23 @@ return /datum/tgui_module/ship/fullmonty/attempt_hook_up() return + +//// +//// Settings for remote view +//// +/datum/remote_view_config/overmap_ship_control + relay_movement = TRUE + +/datum/remote_view_config/overmap_ship_control/handle_relay_movement( datum/component/remote_view/owner_component, mob/host_mob, direction) + var/datum/tgui_module/ship/tgui_owner = owner_component.get_coordinator() + if(tgui_owner?.linked) + return tgui_owner.relaymove(host_mob, direction) + return FALSE + +/datum/remote_view_config/overmap_ship_control/handle_apply_visuals( datum/component/remote_view/owner_component, mob/host_mob) + var/datum/tgui_module/ship/tgui_owner = owner_component.get_coordinator() + if(!tgui_owner) + return + if(get_dist(host_mob, tgui_owner.tgui_host()) > 1 || !tgui_owner.linked) + host_mob.reset_perspective() + return diff --git a/vorestation.dme b/vorestation.dme index e152d745ee..97d089fa21 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -568,6 +568,7 @@ #include "code\datums\organs.dm" #include "code\datums\position_point_vector.dm" #include "code\datums\progressbar.dm" +#include "code\datums\remote_view_config.dm" #include "code\datums\riding.dm" #include "code\datums\signals.dm" #include "code\datums\soul_link.dm"