New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vision Cones #24537
Vision Cones #24537
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,7 @@ var/datum/atom_hud/huds = list( \ | |
return | ||
for(var/i in hud_icons) | ||
M.client.images -= A.hud_list[i] | ||
M.client.hidden_images -= A.hud_list[i] | ||
|
||
/datum/atom_hud/proc/add_hud_to(mob/M) | ||
if(!M) | ||
|
@@ -66,9 +67,15 @@ var/datum/atom_hud/huds = list( \ | |
/datum/atom_hud/proc/add_to_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client | ||
if(!M || !M.client || !A) | ||
return | ||
var/in_cone = FALSE | ||
if(A in cone(M, OPPOSITE_DIR(M.dir), view(10, M))) | ||
in_cone = TRUE | ||
for(var/i in hud_icons) | ||
if(A.hud_list[i]) | ||
M.client.images |= A.hud_list[i] | ||
if(in_cone) | ||
M.client.hidden_images |= A.hud_list[i] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you had this be an associated list it would be faster then |= (but not by much) a better way would be to find some way to do tracking of what a client has so you can do += safely |
||
else | ||
M.client.images |= A.hud_list[i] | ||
|
||
//MOB PROCS | ||
/mob/proc/reload_huds() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -443,6 +443,12 @@ | |
if (s_active && !(s_active.ClickAccessible(src, depth=STORAGE_VIEW_DEPTH) || s_active.Adjacent(src))) | ||
s_active.close(src) | ||
|
||
for(var/mob/M in oview(src)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace this with viewers() and then you will only get mobs and can remove the type on the for and do a istypeless for. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Would that include ghosts then? I just realized its been tracking ghosts this whole time, which seems a bit pointless |
||
if(M.client && (src in cone(M, OPPOSITE_DIR(M.dir), view(10, M)))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the way this works, you could refactor it to cache the details for cone and view() by pivoting it to src rather then m so it only needs to be done once. I don't know of any situation for something to be in one things view but for that thing to not be in its view, view is two way link is it not? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. kor this isn't what I meant, you don't need to update the entire vision cone for a mob who isn't moving - they just need to know that this mob moved and then they need to check if the currently moving mob has entered or exited their cone zone and if so they need to hide or unhide appropriately There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, yeah that makes sense There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i.e the only mob that needs to actually call update_vision cone is the actually moving mob |
||
M.update_vision_cone() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. coming back to this, I wonder if it might be better to operate on the living mob list rather then do these complex view operations. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is going to be the biggest source of lag. this is 1 view operation, and then a loop of view operations. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could do it on the player list instead of the mob list, would be significantly smaller There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @KorPhaeron but then you can see animals and that's dumb, don't half-ass it. |
||
|
||
update_vision_cone() | ||
|
||
/mob/living/movement_delay(ignorewalk = 0) | ||
. = ..() | ||
if(isopenturf(loc) && !is_flying()) | ||
|
@@ -915,3 +921,8 @@ | |
"[C] topples over [src]!", \ | ||
"[C] leaps out of [src]'s way!")]</span>") | ||
C.Weaken(2) | ||
|
||
|
||
/mob/living/setDir(newdir) | ||
..() | ||
update_vision_cone() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/mob | ||
var/obj/screen/fov = null//The screen object because I can't figure out how the hell TG does their screen objects so I'm just using legacy code. | ||
|
||
client/ | ||
var/list/hidden_atoms = list() | ||
var/list/hidden_mobs = list() | ||
var/list/hidden_images = list() | ||
|
||
|
||
|
||
//Procs | ||
/atom/proc/InCone(atom/center = usr, dir = NORTH) | ||
if(get_dist(center, src) == 0 || src == center) return 0 | ||
var/d = get_dir(center, src) | ||
if(!d || d == dir) return 1 | ||
if(dir & (dir-1)) | ||
return (d & ~dir) ? 0 : 1 | ||
if(!(d & dir)) return 0 | ||
var/dx = abs(x - center.x) | ||
var/dy = abs(y - center.y) | ||
if(dx == dy) return 1 | ||
if(dy > dx) | ||
return (dir & (NORTH|SOUTH)) ? 1 : 0 | ||
return (dir & (EAST|WEST)) ? 1 : 0 | ||
|
||
/mob/dead/InCone(mob/center = usr, dir = NORTH)//So ghosts aren't calculated. | ||
return | ||
|
||
/proc/cone(atom/center = usr, dir = NORTH, list/list = oview(center)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can remove annoying
and then just doing
|
||
for(var/atom/A in list) | ||
if(!A.InCone(center, dir)) | ||
list -= A | ||
return list | ||
|
||
/mob/proc/update_vision_cone() | ||
return | ||
|
||
/mob/living/update_vision_cone() | ||
if(src.client) | ||
var/image/I = null | ||
for(I in src.client.hidden_atoms) | ||
I.override = 0 | ||
client.images -= I | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. var/list/imagecopy = client.images.Copy() then do all operations on the copy of the list, then assign client.images to the copy. this saves the overhead of byond parsing the image list so it does it only once. |
||
qdel(I) | ||
for(var/hidden_hud in client.hidden_images) | ||
client.images += hidden_hud | ||
client.hidden_images -= hidden_hud | ||
rest_cone_act() | ||
src.client.hidden_atoms = list() | ||
src.client.hidden_mobs = list() | ||
client.hidden_images = list() | ||
src.fov.dir = src.dir | ||
if(fov.alpha != 0) | ||
var/mob/living/M | ||
for(M in cone(src, OPPOSITE_DIR(src.dir), view(10, src))) | ||
I = image("split", M) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be cached to avoid building it so often I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can just be a global var There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can't be global, has to have it's loc set to M (can't just be an overlay because then everyone would see it, instead of just the person who's cone decided to hide M), meaning it must be unique-per-mob, this means you'll always need N images, which is still better than infinite creation. Hiding/Unhiding can then be done as: |
||
I.override = 1 | ||
src.client.images += I | ||
src.client.hidden_atoms += I | ||
src.client.hidden_mobs += M | ||
if(src.pulling == M)//If we're pulling them we don't want them to be invisible, too hard to play like that. | ||
I.override = 0 | ||
for(var/image/HUD in client.images) | ||
if(HUD.icon != 'icons/mob/hud.dmi') | ||
continue | ||
for(var/mob/living/M in client.hidden_mobs) | ||
if(HUD.loc == M) | ||
client.hidden_images += HUD | ||
client.images -= HUD | ||
break | ||
else | ||
return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trailing return, remove it please. |
||
|
||
/mob/proc/rest_cone_act()//For showing and hiding the cone when you rest or lie down. | ||
if(resting || lying) | ||
hide_cone() | ||
else | ||
show_cone() | ||
|
||
//Making these generic procs so you can call them anywhere. | ||
/mob/proc/show_cone() | ||
if(src.fov) | ||
src.fov.alpha = 255 | ||
|
||
/mob/proc/hide_cone() | ||
if(src.fov) | ||
src.fov.alpha = 0 | ||
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the wrong way to do this, I'm sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah press
F12
or whatever hotkey that was and its gone