ID:140580
 
Code:
obj
table
icon = 'Table.dmi'
icon_state = "x"
density = 1
New()
..()
spawn lighten_darken()
turf
table
icon = 'Table.dmi'
icon_state = "x"
density = 1
New()
..()
spawn lighten_darken()
obj
light
light = 50
New()
spawn cast_light()
green{color="green"}
red{color="red"}
blue{color="blue"}
yellow{color="yellow"}
obj
overlay
mouse_opacity = 0
atom
var
lit = 0
list/colors = list()
proc
lighten_darken()
while(src)
lit = round(lit)
if(lit < 0) lit = 0
if(lit > 100) lit = 100
overlays = null
var/obj/overlay/i = new()
i.layer = MOB_LAYER-1
i.icon = icon

if(lit <= 4) i.icon_state = "0"
else if(lit >= 100) i.icon_state = null
else i.icon_state = num2text(round(lit,5))

overlays += i

for(var/atom/a in colors)
var/obj/overlay/ii = new()
ii.layer = MOB_LAYER-2
ii.icon = icon
ii.icon_state = a.color
overlays += ii

lit = 0
for(var/b in colors) colors -= b
sleep(2)
sleep(0)
atom
var
light = 0
color = null
proc
cast_light()
var/distance = 0
while(src)
for(var/atom/a in oview(src))
distance = 100-(sqrt(abs(a.x-x)**2+abs(a.y-y)**2)*16)
if(light*distance/100 <= 0) continue
else a.lit += light*distance/100
if(color) a.colors += src
sleep(2)
sleep(0)


Problem description:
This code lightens/darkens all atoms in the world.
How light or dark an atom is is determined by an atom that casts light (in this case, obj/light/Any_and_all_of_its_children)

At the beginning of the code, I made 2 tables:
turf/table
and
obj/table

The code works fine for the turfs, but it doesn't [color] objects.

Turfs and Objs are lit and darkened,
Turfs are colored, Objs are not.

Any ideas of why this could possibly happen?

Both turf/table and obj/table share the same icon and icon_states (for both the object itself *and* the overlays), so, I doubt that's the problem.


If you need any more info, please go ahead and ask for it.

Thanks for reading!
The layer of the color overlay is below that of the obj. Furthermore, you shouldn't need an overlay for objs anyway, as the turf's overlay should be above it and therefore be sufficient.

Additionally, your system is rather massively inefficient. You should only be doing anything when the conditions change, not every 2 ticks.
In response to Garthor
I've tried to run the proc only when the atom is within the player's view(), but I failed. Hard.

"The layer of the color overlay is below that of the obj."
MOB_LAYER-2 < OBJ_LAYER ? Really? Wow, I didn't know that.
"Furthermore, you shouldn't need an overlay for objs anyway, as the turf's overlay should be above it and therefore be sufficient."
Each atom has its own color overlay and light/dark overlay, along with color overlays.

In response to Gooseheaded
Actually, I wasn't thinking much and missed that it was isometric. The way you're doing things is the way it has to be done, I believe.

I mean, aside from the excessive looping. You really should get rid of that.
In response to Garthor
Alright, colors are working. Thanks for the layer tip.

You rock Garthor.
Apart from making the update process activate only when it's actually needed, there are a couple more efficiency improvements you should make in your code:
  • Don't give every atom an initialized list. That's a waste of resources and could actually cause you to hit the heightened list limit. Only initialize the list once it becomes needed, and also delete it once it's no longer needed.
  • When you check lit, the 2nd if() should of course be else-if instead, but that's irrelevant since the better solution is to use min() and max() for bounds restrictions.
    lit = max(min(round(lit,1),100),0)
    
  • If icon_state = null gives you a blank icon, you shouldn't add that to overlays.
  • There's no need to keep creating a new dummy visual object (e.g. /obj, /image) each time you need an overlay. You only need one, which you can reuse for however many overlays and as such you need. In total, you only need to create 1 object throughout that proc.

  • for(var/b in colors) colors -= b
    

    There are various quicker ways to clear a list. First, the above amounts to the same as the single statement colors -= colors, second, there's a proc for clearing lists (or parts of them), Cut().
    As I've said before, though, what you should do is simply get rid of the list when it's no longer needed, rather than carry around an empty list. So just clear the reference to it to let it get deleted. This is what you're "doing" with overlays, except that with built-in list vars, that just clears the list instead.
  • Don't have 2 consecutive sleep() calls. What makes you think that helps with anything? sleep(2) already accomplishes much more than sleep(0), so adding it afterward is pointless.
    (Obviously, once you switch to the better, event-driven design instead, you won't have those loops at all, therefore no sleeps.)

EDIT: Also, as Garthor said, don't forget that you don't need extra overlays for movables, you should just increase the turf's overlay's layer to make it cover everything in its tile.
In response to Kaioken
Kaioken wrote:
EDIT: Also, as Garthor said, don't forget that you don't need extra overlays for movables, you should just increase the turf's overlay's layer to make it cover everything in its tile.

I already retracted that statement, as this would not apply for an isometric game.