Fixing client eye (#18577)

* signal foundation

* reset_perspective implemented

* you too

* setting mob

* no

* fix

* tweak

* remote view element

* these too

* use element

* cleanup more manual code

* fix element

* mutation signal

* handle being dropped from holders, and fix pai hud

* handle qdel

* it's a component now

* ugly holder fix

* another fix

* follow view target

* item remote view

* doc update

* unneeded

* this needs a recode to work better

* many fixes

* these are all unneeded

* almost working viewerlist remotes

* this uses component too

* this needs to die to it's item

* don't allow spamming tgui menus

* tg style args

* fixing behaviors

* fuk

* working view release from holders

* only final matters

* comment order and disposal fix

* cryotube loc fix

* no mob should reset its view every life tick

* major improvements

* still forbid z level change even if we allow moving

* this too

* don't doubledip

* qdel on self is unneeded

* wipe remote views on logout

* vore bellies need to manually clear views

* fixAI hud

* belly release fixes

* cannot use binoculars in a vore belly

* pai card can be picked up and dropped correctly

* ventcrawl fix and distracted fix

* this is better

* forcemove

* vr console fix

* use flag for this

* belly stuff

* various cleanups

* oops

* fixes statue spell

* unneeded perspective clear

* automatic instead

* continued cleanup

* that was dumb

* needed

* none of this works

* are these even needed

* lets lock down to these

* lets try to make this work

* extremely close to working

* needs to solve final pai issues

* mob eye change signal

* Revert "mob eye change signal"

This reverts commit eedd5da934.

* significant progress

* safety

* expected to be not null

* likely not needed

* don't spam component changes

* endview on logout

* accessors

* egg fixing

* Revert "egg fixing"

This reverts commit 6a54049c69.

* getting closer

* even closer

* needs type

* close...

* extremely close to working

* fixing pai stuff

* this too

* promising fixes

* docs

* this is recursive move's responsibility tbh

* unneeded now

* oops

* better decouple

* topmost check

* cleanup

* holder released from egg fix

* pai fix for reset view

* debug info

* some better pai ejection code

* better way

* unneeded

* needs to be null

* better vision restore

* use correct handling

* no longer needed

* required

* handle decouple on mecha too

* name clarity

* do not allow double dipping zoom items

* ethereal jaunt needs a full cleanup later

* fix blackscreen flicker

* remove set machine from pda

* Update code/game/objects/items.dm

* Update code/game/objects/items.dm

* Update code/game/objects/items.dm

* Update code/game/objects/items.dm

---------

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
Will
2025-10-12 22:18:08 -04:00
committed by GitHub
co-authored by Cameron Lennox
parent 994be6bf05
commit 2194b87de0
95 changed files with 762 additions and 710 deletions
+5 -7
View File
@@ -33,7 +33,7 @@
ai.camera_visibility(src)
if(ai.client && !ai.multicam_on)
ai.client.eye = src
ai.reset_perspective(src)
if(ai.master_multicam)
ai.master_multicam.refresh_view()
@@ -58,8 +58,7 @@
eyeobj.owner = null
qdel(eyeobj) // No AI, no Eye
eyeobj = null
if(client)
client.eye = new_eye
reset_perspective(new_eye)
/mob/living/silicon/ai/proc/create_eyeobj(var/newloc)
if(eyeobj)
@@ -70,8 +69,7 @@
all_eyes += eyeobj
eyeobj.owner = src
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
if(client)
client.eye = eyeobj
reset_perspective(eyeobj)
SetName(src.name)
/atom/proc/move_camera_by_click()
@@ -88,9 +86,9 @@
if(!src.eyeobj)
return
if(client.eye)
reset_perspective(src)
if(client && client.eye)
client.eye = src
for(var/datum/chunk/c in eyeobj.visibleChunks)
c.remove(eyeobj)
src.eyeobj.setLoc(src)
+1 -3
View File
@@ -64,9 +64,7 @@
if(T != loc)
loc = T
if(owner.client)
owner.client.eye = src
owner.reset_perspective(src)
if(owner_follows_eye)
visualnet.updateVisibility(owner, 0)
owner.loc = loc
+13 -15
View File
@@ -30,7 +30,6 @@ var/list/holder_mob_icon_cache = list()
ASSERT(ismob(held))
. = ..()
held.forceMove(src)
held.reset_view(src)
START_PROCESSING(SSobj, src)
/mob/living/get_status_tab_items()
@@ -68,10 +67,10 @@ var/list/holder_mob_icon_cache = list()
. += ""
. += "Location: [location]"
/// Loads the mob into the holder and sets several vis_flags
/obj/item/holder/Entered(mob/held, atom/OldLoc)
if(held_mob)
held.forceMove(get_turf(src))
held.reset_view(null)
return
ASSERT(ismob(held))
. = ..()
@@ -83,38 +82,39 @@ var/list/holder_mob_icon_cache = list()
original_transform = held.transform
held.transform = null
/// Handles restoring the vis flags and scale of the mob, also makes the holder invisible now that it's empty.
/obj/item/holder/Exited(atom/movable/thing, atom/OldLoc)
if(thing == held_mob)
held_mob.transform = original_transform
held_mob.update_transform() //VOREStation edit
held_mob.update_transform()
held_mob.vis_flags = original_vis_flags
held_mob = null
invisibility = INVISIBILITY_ABSTRACT
..()
/// Dumps the mob if we still hold one, and if we are held by a mob clears us from its inventory.
/obj/item/holder/Destroy()
STOP_PROCESSING(SSobj, src)
if(held_mob)
var/mob/cached_mob = held_mob
dump_mob()
cached_mob.reset_perspective() // This case cannot be handled gracefully, make sure the mob view is cleaned up.
if(ismob(loc))
var/mob/M = loc
M.drop_from_inventory(src, get_turf(src))
return ..()
M.drop_from_inventory(src, loc)
. = ..()
/// If the mob somehow leaves the holder, clean us up.
/obj/item/holder/process()
if(held_mob?.loc != src || isturf(loc))
if(held_mob?.loc != src || isturf(loc) || isbelly(loc))
qdel(src)
/// Releases the mob from inside the holder. Calls forceMove() which calls Exited(). Then does cleanup for the client's eye location.
/obj/item/holder/proc/dump_mob()
if(!held_mob)
return
if (held_mob.loc == src || isnull(held_mob.loc))
held_mob.transform = original_transform
held_mob.update_transform()
held_mob.vis_flags = original_vis_flags
held_mob.reset_view(null)
held_mob.forceMove(get_turf(src))
held_mob = null
invisibility = INVISIBILITY_ABSTRACT
held_mob.forceMove(loc)
/obj/item/holder/throw_at(atom/target, range, speed, thrower)
if(held_mob)
@@ -146,12 +146,10 @@ var/list/holder_mob_icon_cache = list()
holster.clear_holster()
to_chat(held, span_warning("You extricate yourself from [holster]."))
forceMove(get_turf(src))
held.reset_view(null)
else if(isitem(loc))
var/obj/item/I = loc
to_chat(held, span_warning("You struggle free of [loc]."))
forceMove(get_turf(src))
held.reset_view(null)
if(istype(I))
I.on_holder_escape(src)
+2 -6
View File
@@ -132,12 +132,8 @@
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)
if(machine)
if(machine.check_eye(src) < 0)
reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
if(machine && machine.check_eye(src) < 0)
reset_perspective()
return 1
+2 -6
View File
@@ -207,11 +207,7 @@
set_fullscreen(eye_blurry, "blurry", /atom/movable/screen/fullscreen/blurry)
set_fullscreen(druggy, "high", /atom/movable/screen/fullscreen/high)
if (machine)
if (!( machine.check_eye(src) ))
reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
if (machine && machine.check_eye(src) < 0)
reset_perspective()
return 1
+8 -22
View File
@@ -890,8 +890,6 @@
set category = "Superpower"
if(stat!=CONSCIOUS)
reset_view(0)
remoteview_target = null
return
if(!(mMorph in mutations))
@@ -964,9 +962,7 @@
set name = "Project mind"
set category = "Abilities.Superpower"
if(stat!=CONSCIOUS)
reset_view(0)
remoteview_target = null
if(stat != CONSCIOUS)
return
if(!(mRemotetalk in src.mutations))
@@ -995,17 +991,11 @@
set name = "Remote View"
set category = "Abilities.Superpower"
if(stat!=CONSCIOUS)
remoteview_target = null
reset_view(0)
if(stat != CONSCIOUS)
return
if(!(mRemote in src.mutations))
remoteview_target = null
reset_view(0)
remove_verb(src, /mob/living/carbon/human/proc/remoteobserve)
if(client.eye != client.mob)
reset_view(0)
if(is_remote_viewing())
reset_perspective()
return
var/list/mob/creatures = list()
@@ -1022,13 +1012,9 @@
creatures += h
var/mob/target = input ("Who do you want to project your mind to?") as mob in creatures
if (target)
remoteview_target = target
reset_view(target)
else
remoteview_target = null
reset_view(0)
if(target)
AddComponent(/datum/component/remote_view/mremote_mutation, target)
return
/mob/living/carbon/human/get_visible_gender(mob/user, force)
switch(force)
@@ -1572,7 +1558,7 @@
return remove_from_mob(W, src.loc)
return ..()
/mob/living/carbon/human/reset_view(atom/A, update_hud = 1)
/mob/living/carbon/human/reset_perspective(atom/A, update_hud = 1)
..()
if(update_hud)
handle_regular_hud_updates()
@@ -87,7 +87,6 @@
var/xylophone = 0 //For the spoooooooky xylophone cooldown
var/mob/remoteview_target = null
var/hand_blood_color
var/list/flavor_texts = list()
@@ -367,17 +367,11 @@ This saves us from having to call add_fingerprint() any time something is put in
update_inv_r_hand()
W.hud_layerise()
if(W.zoom)
W.zoom()
W.in_inactive_hand(src)
//VOREStation Addition Start
if(istype(W, /obj/item))
var/obj/item/I = W
I.equip_special()
//VOREStation Addition End
return 1
+7 -24
View File
@@ -1663,7 +1663,7 @@
if(found_welder)
client.screen |= GLOB.global_hud.darkMask
/mob/living/carbon/human/reset_view(atom/A)
/mob/living/carbon/human/reset_perspective(atom/A)
..()
if(machine_visual && machine_visual != A)
machine_visual.remove_visual(src)
@@ -1672,13 +1672,6 @@
if(stat == DEAD)
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS|SEE_SELF
see_in_dark = 8
if(client)
if(client.view != world.view) // If mob dies while zoomed in with device, unzoom them.
for(var/obj/item/item in contents)
if(item.zoom)
item.zoom()
break
else //We aren't dead
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
@@ -1720,12 +1713,12 @@
var/glasses_processed = 0
var/obj/item/rig/rig = get_rig()
if(istype(rig) && rig.visor && !looking_elsewhere)
if(istype(rig) && rig.visor && !is_remote_viewing())
if(!rig.helmet || (head && rig.helmet == head))
if(rig.visor && rig.visor.vision && rig.visor.active && rig.visor.vision.glasses)
glasses_processed = process_glasses(rig.visor.vision.glasses)
if(glasses && !glasses_processed && !looking_elsewhere)
if(glasses && !glasses_processed && !is_remote_viewing())
glasses_processed = process_glasses(glasses)
if(XRAY in mutations)
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
@@ -1754,23 +1747,13 @@
if(machine)
var/viewflags = machine.check_eye(src)
if(viewflags < 0)
reset_view(null, 0)
else if(viewflags && !looking_elsewhere)
reset_perspective()
else if(viewflags && !is_remote_viewing())
sight |= viewflags
else
machine.apply_visual(src)
else if(eyeobj)
if(eyeobj.owner != src)
reset_view(null)
else
var/isRemoteObserve = 0
if((mRemote in mutations) && remoteview_target)
if(remoteview_target.stat==CONSCIOUS)
isRemoteObserve = 1
if(!isRemoteObserve && client && !client.adminobs)
remoteview_target = null
reset_view(null, 0)
else if(eyeobj && eyeobj.owner != src)
reset_perspective()
return 1
/mob/living/carbon/human/proc/process_glasses(var/obj/item/clothing/glasses/G)
@@ -365,7 +365,6 @@
src.drop_from_inventory(S.OurRig)
P.forceMove(S.OurRig)
S.OurRig.canremove = 1
P.reset_view()
else //Make one if not
to_chat(temporary_form, span_warning("Somehow, your RIG got disconnected from your species. This may have been caused by an admin heal. A new one has been created for you, contact a coder."))
new /obj/item/rig/protean(src,src)
@@ -16,6 +16,7 @@
seal_delay = 0
var/mob/living/myprotean
initial_modules = list(/obj/item/rig_module/protean/syphon, /obj/item/rig_module/protean/armor, /obj/item/rig_module/protean/healing)
flags = PHORONGUARD
item_flags = NOSTRIP
helm_type = /obj/item/clothing/head/helmet/space/rig/protean //These are important for sprite pointers
-2
View File
@@ -1270,8 +1270,6 @@
// We just swapped hands, so the thing in our inactive hand will notice it's not the focus
var/obj/item/I = get_inactive_hand()
if(I)
if(I.zoom)
I.zoom()
I.in_inactive_hand(src) //This'll do specific things, determined by the item
return
@@ -72,8 +72,6 @@
var/makes_dirt = TRUE //FALSE if the mob shouldn't be making dirt on the ground when it walks
var/looking_elsewhere = FALSE //If the mob's view has been relocated to somewhere else, like via a camera or with binocs
var/image/selected_image = null // Used for buildmode AI control stuff.
var/allow_self_surgery = FALSE // Used to determine if the mob can perform surgery on itself.
+2 -3
View File
@@ -515,7 +515,7 @@ var/list/ai_verbs_default = list(
if(.)
end_multicam()
/mob/living/silicon/ai/reset_view(atom/A)
/mob/living/silicon/ai/reset_perspective(atom/A)
if(camera)
camera.set_light(0)
if(istype(A,/obj/machinery/camera))
@@ -526,8 +526,7 @@ var/list/ai_verbs_default = list(
if(.)
if(!A && isturf(loc) && eyeobj)
end_multicam()
client.eye = eyeobj
client.perspective = MOB_PERSPECTIVE
reset_perspective(eyeobj)
if(istype(A,/obj/machinery/camera))
if(camera_light_on) A.set_light(AI_CAMERA_LUMINOSITY)
else A.set_light(0)
+1 -1
View File
@@ -7,7 +7,7 @@
if (src.stat != CONSCIOUS)
src.cameraFollow = null
src.reset_view(null)
src.reset_perspective()
disconnect_shell("Disconnecting from remote shell due to local system failure.")
src.updatehealth()
@@ -2,9 +2,5 @@
..()
for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
O.mode = 0
if(!isturf(loc))
if (client)
client.eye = loc
client.perspective = EYE_PERSPECTIVE
src.view_core()
return
@@ -246,7 +246,7 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
to_chat(src, span_notice("Multiple-camera viewing mode activated."))
/mob/living/silicon/ai/proc/refresh_multicam()
reset_view(GLOB.ai_camera_room_landmark)
reset_perspective(GLOB.ai_camera_room_landmark)
if(client)
for(var/atom/movable/screen/movable/pic_in_pic/P as anything in multicam_screens)
P.show_to(client)
@@ -259,7 +259,7 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
if(client)
for(var/atom/movable/screen/movable/pic_in_pic/P as anything in multicam_screens)
P.unshow_to(client)
reset_view()
reset_perspective(src)
to_chat(src, span_notice("Multiple-camera viewing mode deactivated."))
+47 -27
View File
@@ -177,7 +177,7 @@
/mob/living/silicon/pai/proc/switchCamera(var/obj/machinery/camera/C)
if (!C)
src.unset_machine()
src.reset_view(null)
src.reset_perspective()
return 0
if (stat == 2 || !C.status || !(src.network in C.network)) return 0
@@ -185,7 +185,7 @@
src.set_machine(src)
src.current = C
src.reset_view(C)
src.AddComponent(/datum/component/remote_view, C)
return 1
/mob/living/silicon/pai/verb/reset_record_view()
@@ -204,7 +204,7 @@
/mob/living/silicon/pai/cancel_camera()
set category = "Abilities.pAI Commands"
set name = "Cancel Camera View"
src.reset_view(null)
src.reset_perspective()
src.unset_machine()
src.cameraFollow = null
@@ -219,7 +219,25 @@
if(stat || sleeping || paralysis || weakened)
return
if(src.loc != card)
if(loc != card)
return
// Lets not trap the pai forever. These are special cases we want to escape out of when in our card
if(istype(loc.loc, /obj/item/pda))
var/obj/item/pda/ourpda = loc.loc
if(ourpda.pai == card)
ourpda.pai.forceMove(ourpda.loc)
ourpda.pai = null
visible_message(span_warning("\The [card] ejects itself from \the [ourpda]."))
return
if(istype(loc.loc, /obj/item/storage/vore_egg))
var/obj/item/storage/vore_egg/ouregg = loc.loc
to_chat(src, span_notice("You craftily use your built in rumble function to break free of \the [ouregg]'s confines!"))
ouregg.hatch(src)
return
if(is_folding_unsafe(loc.loc))
to_chat(src, span_danger("It's not safe to unfold while inside a [loc.loc]!"))
return
if(card.projector != PP_FUNCTIONAL && card.emitter != PP_FUNCTIONAL)
@@ -256,16 +274,15 @@
var/obj/item/pda/holder = card.loc
holder.pai = null
src.client.perspective = EYE_PERSPECTIVE
src.client.eye = src
src.forceMove(get_turf(card))
src.forceMove(card.loc)
card.forceMove(src)
card.screen_loc = null
canmove = TRUE
var/turf/T = get_turf(src)
if(istype(T)) T.visible_message(span_filter_notice(span_bold("[src]") + " folds outwards, expanding into a mobile form."))
if(isturf(loc))
var/turf/T = get_turf(src)
if(istype(T)) T.visible_message(span_filter_notice(span_bold("[src]") + " folds outwards, expanding into a mobile form."))
add_verb(src, /mob/living/silicon/pai/proc/pai_nom)
add_verb(src, /mob/living/proc/vertical_nom)
update_icon()
@@ -380,7 +397,12 @@
last_special = world.time + 100
if(src.loc == card)
if(loc == card)
return
// some snowflake locations where we really shouldn't fold up...
if(is_folding_unsafe(loc))
to_chat(src, span_danger("It's not safe to fold up while inside a [loc]!"))
return
release_vore_contents(FALSE) //VOREStation Add
@@ -388,40 +410,35 @@
var/turf/T = get_turf(src)
if(istype(T) && !silent) T.visible_message(span_filter_notice(span_bold("[src]") + " neatly folds inwards, compacting down to a rectangular card."))
if(client)
src.stop_pulling()
src.client.perspective = EYE_PERSPECTIVE
src.client.eye = card
stop_pulling()
//stop resting
resting = 0
// If we are being held, handle removing our holder from their inv.
var/obj/item/holder/H = loc
if(istype(H))
var/mob/living/M = H.loc
var/obj/item/holder/our_holder = loc
if(istype(our_holder))
var/turf/drop_turf = get_turf(our_holder)
var/mob/living/M = our_holder.loc
if(istype(M))
M.drop_from_inventory(H)
H.loc = get_turf(src)
src.loc = get_turf(H)
M.drop_from_inventory(our_holder)
src.forceMove(card)
card.forceMove(drop_turf)
if(isbelly(loc)) //If in tumby, when fold up, card go into tumby
var/obj/belly/B = loc
src.forceMove(card)
card.forceMove(B)
if(istype( src.loc,/obj/structure/disposalholder))
if(istype(loc,/obj/structure/disposalholder))
var/obj/structure/disposalholder/hold = loc
src.loc = card
card.loc = hold
src.forceMove(card)
card.forceMove(hold)
else //Otherwise go on floor
src.loc = card
card.loc = get_turf(card)
card.forceMove(get_turf(src))
src.forceMove(card)
card.forceMove(card.loc)
canmove = 1
resting = 0
icon_state = "[chassis]"
@@ -430,6 +447,9 @@
remove_verb(src, /mob/living/silicon/pai/proc/pai_nom)
remove_verb(src, /mob/living/proc/vertical_nom)
/mob/living/silicon/pai/proc/is_folding_unsafe(check_location)
return isbelly(check_location) || istype(check_location, /obj/machinery) || istype(check_location, /obj/item/storage/vore_egg || istype(check_location, /obj/item/pda))
// No binary for pAIs.
/mob/living/silicon/pai/binarycheck()
return 0
@@ -5,7 +5,7 @@
icon = 'icons/mob/pai_hud.dmi'
var/base_state
/atom/movable/pai/Click(location, control, params)
/atom/movable/screen/pai/Click(location, control, params)
. = ..()
if(!ispAI(usr))
return
@@ -105,7 +105,6 @@
user.visible_message(span_warning("[hound.name] is ingesting [trashmouse] into their [src.name]."), span_notice("You start ingesting [trashmouse] into your [src.name]..."))
if(do_after(user, 3 SECONDS, target = trashmouse) && length(contents) < max_item_count)
trashmouse.forceMove(src)
trashmouse.reset_view(src)
user.visible_message(span_warning("[hound.name]'s [src.name] groans lightly as [trashmouse] slips inside."), span_notice("Your [src.name] groans lightly as [trashmouse] slips inside."))
playsound(src, gulpsound, vol = 60, vary = 1, falloff = 0.1, preference = /datum/preference/toggle/eating_noises)
if(delivery)
@@ -125,7 +124,6 @@
user.visible_message(span_warning("[hound.name] is ingesting [trashman] into their [src.name]."), span_notice("You start ingesting [trashman] into your [src.name]..."))
if(do_after(user, 3 SECONDS, target = trashman) && !patient && !trashman.buckled && length(contents) < max_item_count)
trashman.forceMove(src)
trashman.reset_view(src)
START_PROCESSING(SSobj, src)
user.visible_message(span_warning("[hound.name]'s [src.name] groans lightly as [trashman] slips inside."), span_notice("Your [src.name] groans lightly as [trashman] slips inside."))
log_attack("[key_name(hound)] has eaten [key_name(patient)] with a cyborg belly. ([hound ? "<a href='byond://?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
@@ -155,7 +153,6 @@
return //If you try to eat two people at once, you can only eat one.
else //If you don't have someone in you, proceed.
H.forceMove(src)
H.reset_view(src)
update_patient()
START_PROCESSING(SSobj, src)
user.visible_message(span_warning("[hound.name]'s [src.name] lights up as [H.name] slips inside."), span_notice("Your [src] lights up as [H] slips inside. Life support functions engaged."))
@@ -206,7 +203,6 @@
if(ishuman(C))
var/mob/living/carbon/human/person = C
person.forceMove(get_turf(src))
person.reset_view()
else
var/obj/T = C
T.loc = hound.loc
@@ -416,7 +412,6 @@
if(ishuman(C))
var/mob/living/carbon/human/person = C
person.forceMove(get_turf(src))
person.reset_view()
else
var/obj/T = C
T.loc = hound.loc
@@ -292,12 +292,8 @@
set_fullscreen(eye_blurry, "blurry", /atom/movable/screen/fullscreen/blurry)
set_fullscreen(druggy, "high", /atom/movable/screen/fullscreen/high)
if (machine)
if (machine.check_eye(src) < 0)
reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
if (machine && machine.check_eye(src) < 0)
reset_perspective()
if(emagged)
throw_alert("hacked", /atom/movable/screen/alert/hacked)
+1 -1
View File
@@ -394,7 +394,7 @@
/mob/living/silicon/setEarDamage()
return
/mob/living/silicon/reset_view()
/mob/living/silicon/reset_perspective(atom/new_eye)
. = ..()
if(cameraFollow)
cameraFollow = null
@@ -171,7 +171,6 @@
forceMove(get_turf(host))
reset_view(null)
machine = null
if(ishuman(host))
@@ -180,7 +179,6 @@
if(head)
head.implants -= src
host.reset_view(null)
host.machine = null
host = null
@@ -331,8 +331,6 @@
forceMove(get_turf(host))
reset_view(null)
host = null
/mob/living/simple_mob/animal/sif/leech/verb/inject_victim()
+2 -5
View File
@@ -46,12 +46,9 @@
..()
SEND_SIGNAL(src, COMSIG_MOB_LOGIN)
if(loc && !isturf(loc))
client.eye = loc
client.perspective = EYE_PERSPECTIVE
else
client.eye = src
if(!restore_remote_views())
client.perspective = MOB_PERSPECTIVE
client.set_eye(src)
add_click_catcher()
update_client_color()
+67 -17
View File
@@ -244,19 +244,69 @@
/mob/proc/restrained()
return
/mob/proc/reset_view(atom/A)
if (client)
if (istype(A, /atom/movable))
client.perspective = EYE_PERSPECTIVE
client.eye = A
else
if (isturf(loc))
client.eye = client.mob
client.perspective = MOB_PERSPECTIVE
else
/**
* Reset the attached clients perspective (viewpoint)
*
* reset_perspective() set eye to common default : mob on turf, loc otherwise. If the client mob is inside an object with REMOTEVIEW_ON_ENTER, it will restart that object's remote view.
* reset_perspective(thing) set the eye to the thing (if it's equal to current default reset to mob perspective). This ignores REMOTEVIEW_ON_ENTER, and forces focus to the mob.
*/
/mob/proc/reset_perspective(atom/new_eye)
SHOULD_CALL_PARENT(TRUE)
if(!client)
return
if(new_eye)
if(ismovable(new_eye))
//Set the new eye unless it's us
if(new_eye != src)
client.perspective = EYE_PERSPECTIVE
client.eye = loc
client.set_eye(new_eye)
else
client.set_eye(client.mob)
client.perspective = MOB_PERSPECTIVE
else if(isturf(new_eye))
//Set to the turf unless it's our current turf
if(new_eye != loc)
client.perspective = EYE_PERSPECTIVE
client.set_eye(new_eye)
else
client.set_eye(client.mob)
client.perspective = MOB_PERSPECTIVE
else
return TRUE //no setting eye to stupid things like areas or whatever
else
//If we return focus to our own mob, but we are still inside something with an inherent remote view. Restart it.
if(restore_remote_views())
return TRUE
//Reset to common defaults: mob if on turf, otherwise current loc
if(isturf(loc))
client.set_eye(client.mob)
client.perspective = MOB_PERSPECTIVE
else
client.perspective = EYE_PERSPECTIVE
client.set_eye(loc)
/// Signal sent after the eye has been successfully updated, with the client existing.
SEND_SIGNAL(src, COMSIG_MOB_RESET_PERSPECTIVE)
return TRUE
/// Reapplies remote views based on object type and flags. Returns true if the view was assigned.
/mob/proc/restore_remote_views()
if(!loc) // Nullspace during respawn
return FALSE
if(isturf(loc)) // Cannot be remote if it was a turf, also obj and turf flags overlap so stepping into space triggers remoteview endlessly.
return FALSE
// Check if we actually need to drop our current remote view component, as this is expensive to do, and leads to more difficult to understand error prone logic
var/datum/component/remote_view/remote_comp = GetComponent(/datum/component/remote_view)
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)
return TRUE
if(loc.flags & REMOTEVIEW_ON_ENTER) // Handle atoms that begin a remote view upon entering them.
AddComponent(/datum/component/remote_view, loc)
return TRUE
return FALSE
/mob/proc/ret_grab(list/L, flag)
return
@@ -509,17 +559,17 @@
var/mob/mob_eye = targets[eye_name]
if(client && mob_eye)
client.eye = mob_eye
if (is_admin)
client.adminobs = 1
if(mob_eye == client.mob || client.eye == client.mob)
client.adminobs = 0
AddComponent(/datum/component/remote_view, focused_on = mob_eye)
if(is_admin)
client.adminobs = TRUE
if(mob_eye == client.mob || !is_remote_viewing())
client.adminobs = FALSE
/mob/verb/cancel_camera()
set name = "Cancel Camera View"
set category = "OOC.Game"
unset_machine()
reset_view(null)
reset_perspective()
/mob/Topic(href, href_list)
if(href_list["mach_close"])
-7
View File
@@ -205,13 +205,6 @@
if(L.is_incorporeal())//Move though walls
Process_Incorpmove(direct)
return
/* TODO observer unzoom
if(view != world.view) // If mob moves while zoomed in with device, unzoom them.
for(var/obj/item/item in mob.contents)
if(item.zoom)
item.zoom()
break
*/
if(Process_Grab())
return