It's looking like appearance/loc updates on image objects are somehow not being sent properly.
Here's a demo that reproduces the problem:
http://files.byondhome.com/Ter13/Farm.zip
1) Click on a tile and initiate a tilling job.
2) Click and drag on the tilling job to expand it to nearby tiles.
Notice how the drag operation is always one tile behind? Well my math isn't wrong. Everything checks out, but appearance and location updates of the image objects that make up the grid don't update properly at the edges.
The relevant code for the actual grid update:
mouse_action
job_drag
Stat()
if(valid)
var/x1 = ref_loc.x, x2 = hover_loc.x, y1 = ref_loc.y, y2 = hover_loc.y
var/lx = max(min(x1,x2),owner.bound_x/TILE_WIDTH - 1), rx = min(max(x1,x2),(owner.bound_x+owner.bound_width)/TILE_WIDTH + 1)
var/by = max(min(y1,y2),owner.bound_y/TILE_HEIGHT - 1), ty = min(max(y1,y2),(owner.bound_y+owner.bound_height)/TILE_HEIGHT + 1)
var/list/locs = block(locate(lx,by,ref_loc.z),locate(rx,ty,hover_loc.z))
var/ipos = 0, count, len = locs.len, ilen = images.len
var/image/i, turf/t
var/job/j = ref
var/list/nimages = list()
for(count in 1 to len)
t = locs[count]
if(j.canSchedule(t))
if(ilen==ipos)
i = image(job_appearance,t)
nimages += i
else
i = images[++ipos]
i.loc = t
if(nimages.len)
images += nimages
owner.images += nimages
else if(ipos<ilen)
var/nlen = ipos
owner.images -= images.Copy(ipos+1)
while(ipos<ilen)
i = images[++ipos]
i.loc = null
images.len = nlen
else if(images)
if(images.len)
owner.images -= images
var/count, len = images.len, image/i
for(count in 1 to len)
i = images[count]
i.loc = null
images = null
Meanwhile, the mousedrop hook for the mouse action in question generates jobs at the correct locations:
Drop(atom/src_object,atom/over_object,atom/src_location,atom/over_location,src_control,over_control,params)
if(valid)
valid = 0
var/x1 = ref_loc.x, x2 = hover_loc.x, y1 = ref_loc.y, y2 = hover_loc.y
var/lx = min(x1,x2), rx = max(x1,x2)
var/by = min(y1,y2), ty = max(y1,y2)
var/list/locs = block(locate(lx,by,ref_loc.z),locate(rx,ty,hover_loc.z))
var/count, len = locs.len
var/turf/t
var/job/j = ref, jobtype = job_ids[j.id]
for(count in 1 to len)
t = locs[count]
if(j.canSchedule(t))
new jobtype(t)
Destroy()
All of the math checks out, but image objects don't seem to be sending off updates when they are supposed to.
If I create regular old objects instead of image objects, it works plenty fine. It's just image objects that have been created and shown to the user in the same tick that don't seem to be updating their appearance.
I've tested their locations. They are located correctly. I've tested whether they are actually in the viewport of the user. They are in fact in the user's viewport.
Even weirder, When downsizing an area, the objects don't relocate properly at all. So there's definitely something wrong with the messaging involving /image objects and changing loc.