ID:155938
 
I've been wracking my brain and doing quite a bit of research now for quite a while, and have not found a solution to this problem:


I have created an elevation system. However, I have one problem that throws everything off; places with walls above them are opaque in every single floor. Since this is a multiplayer game I cannot simply make the walls non-opaque when the player is not in the elevation(s) with the walls.


I have tried to create my own opacity system, but that didn't work. My elevation uses layers and the invisibility variable to give the impression of different levels.

How would I work around this, or is there a simple solution that I am overlooking?
I've found that using /images is the only actual way to do this.
In response to Kaiochao (#1)
What would I apply /images to?
In response to Duelmaster409 (#2)
You'd need completely black /images to be displayed on tiles that are in your range() but not view().
I am assuming you are using a system similar to:
http://www.byond.com/developer/Drumersl/Floors

I don't think it is possible to work with opacities when using a system like this. You would have to rewrite some of the view code which may not be possible within Byond.

This may be a good feature to put a request in for. Having levels of opacity similar to levels of invisibility would be useful.
In response to Drumersl (#4)
1. It is possible to fake opacity for higher levels. I've done it, though it isn't the fastest system out there.
Basically, every time you want to update opacity(mostly every time you're moved), find your view() and store it into view_a. Loop through view_a, changing every atom's opacity to 1 if they are supposed to be opaque(as defined in a separate variable).
Now find your view() and store that into view_b.
Reset the atoms in view_a to their previous opacity.
view_a is what you can or can't see. view_b is what you can see. Logically, view_a minus view_b tells you what you can't see.
Now place black /images onto every tile in what you can't see.

2. http://www.byond.com/members/ BYONDHelp?command=view_tracker_issue&tracker_issue=2392
In response to Kaiochao (#5)
A quicker method would be to use opacity as you usually would, but modify mob.sight so you can actually see through those objects. Then instead of changing the opacity of all of the atoms you just change mob.sight to normal opacity viewing, grab the values of view() and range() then change it back. Then apply a false opacity as needed.

Should be quick enough to work without much of a flicker, you could probably use a dummy mob attached to the player to get rid of flicker entirely by having all of the calculations done outside of the view of the player.

Still might be a bit sluggish if done too much, probably not a bad idea to work in some kind of caching system for it, so you don't have to run the calculations each time. Maybe add the false opacity to images as you enter a floor and only remove them after you've gone a few floors up (hiding and showing them as needed but not deleting them) so you can go back and forth a few floors without having to recalculate/redraw.
In response to Nadrew (#6)
I need to individually set things as opaque and non-opaque for a while, which causes enormous amounts of choppiness for some reason. I also tried using the sight variable, but unfortunately that won't work if there's an opaque object above or below, let's say, a window because that would obtrude the window, which is why I need to selectively set the opacities. Here is the code I have so far:

        for(var/x in ViewFilter) // ViewFilter caches the "Black.dmi" /images
client.screen-=x
del(x)

var/list/view_a=view(20,src)


for(var/obj/wall/A in view_a)
if(A.opaque && elevation<=A.elevation) A.opacity=1 // opaque is a variable I have defined for all opaque objects


var/list/view_b=view(20,src)


for(var/obj/A in view_a)
if(A.opaque && A.opacity) A.opacity=0


for(var/turf/T in view_a - view_b)
var/image/I=image('Black.dmi',T,FLY_LAYER)
ViewFilter.Add(I)
src<<I


If I have too many objects in my screen, the process becomes very sluggish. Is there something I can do to avoid looping through every object?
In response to Duelmaster409 (#7)
With your view size being 20, it's no doubt going to be sluggish. BYOND just isn't built for... a lot of things.