Merge pull request #4342 from Zuhayr/ihategit

Multiz changes.
This commit is contained in:
Ccomp5950
2014-01-25 20:24:49 -08:00
20 changed files with 129 additions and 124 deletions

View File

@@ -2,12 +2,12 @@
set name = "Move Upwards"
set category = "Object"
if(allow_thrust(0.01, usr))
var/turf/controlerlocation = locate(1, 1, usr.z)
var/turf/controllerlocation = locate(1, 1, usr.z)
var/legal = 0
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
legal = controler.up
if (controler.up)
var/turf/T = locate(usr.x, usr.y, controler.up_target)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
legal = controller.up
if (controller.up)
var/turf/T = locate(usr.x, usr.y, controller.up_target)
if(T && (istype(T, /turf/space) || istype(T, /turf/simulated/floor/open)))
var/blocked = 0
for(var/atom/A in T.contents)
@@ -28,12 +28,12 @@
set name = "Move Downwards"
set category = "Object"
if(allow_thrust(0.01, usr))
var/turf/controlerlocation = locate(1, 1, usr.z)
var/turf/controllerlocation = locate(1, 1, usr.z)
var/legal = 0
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
legal = controler.down
if (controler.down == 1)
var/turf/T = locate(usr.x, usr.y, controler.down_target)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
legal = controller.down
if (controller.down == 1)
var/turf/T = locate(usr.x, usr.y, controller.down_target)
var/turf/S = locate(usr.x, usr.y, usr.z)
if(T && (istype(S, /turf/space) || istype(S, /turf/simulated/floor/open)))
var/blocked = 0

View File

@@ -2,7 +2,7 @@
// parent class for pipes //
////////////////////////////
obj/machinery/atmospherics/pipe/zpipe
icon = 'code/TriDimension/multiz_pipe.dmi'
icon = 'icons/obj/structures.dmi'
icon_state = "up"
name = "upwards pipe"
@@ -117,7 +117,7 @@ obj/machinery/atmospherics/pipe/zpipe/disconnect(obj/machinery/atmospherics/refe
// the elusive up pipe //
/////////////////////////
obj/machinery/atmospherics/pipe/zpipe/up
icon = 'code/TriDimension/multiz_pipe.dmi'
icon = 'icons/obj/structures.dmi'
icon_state = "up"
name = "upwards pipe"
@@ -137,10 +137,10 @@ obj/machinery/atmospherics/pipe/zpipe/up/initialize()
node1 = target
break
var/turf/controlerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.up)
var/turf/above = locate(src.x, src.y, controler.up_target)
var/turf/controllerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up)
var/turf/above = locate(src.x, src.y, controller.up_target)
if(above)
for(var/obj/machinery/atmospherics/target in above)
if(target.initialize_directions && istype(target, /obj/machinery/atmospherics/pipe/zpipe/down))
@@ -156,7 +156,7 @@ obj/machinery/atmospherics/pipe/zpipe/up/initialize()
///////////////////////
obj/machinery/atmospherics/pipe/zpipe/down
icon = 'code/TriDimension/multiz_pipe.dmi'
icon = 'icons/obj/structures.dmi'
icon_state = "down"
name = "downwards pipe"
@@ -176,10 +176,10 @@ obj/machinery/atmospherics/pipe/zpipe/down/initialize()
node1 = target
break
var/turf/controlerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.down)
var/turf/below = locate(src.x, src.y, controler.down_target)
var/turf/controllerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.down)
var/turf/below = locate(src.x, src.y, controller.down_target)
if(below)
for(var/obj/machinery/atmospherics/target in below)
if(target.initialize_directions && istype(target, /obj/machinery/atmospherics/pipe/zpipe/up))

View File

@@ -3,7 +3,7 @@
///////////////////////////////////////
/obj/multiz
icon = 'code/TriDimension/multiz.dmi'
icon = 'icons/obj/structures.dmi'
density = 0
opacity = 0
anchored = 1
@@ -14,27 +14,27 @@
/obj/multiz/ladder
icon_state = "ladderdown"
name = "ladder"
desc = "A Ladder. You climb up and down it."
desc = "A ladder. You climb up and down it."
var/d_state = 1
var/obj/multiz/target
New()
. = ..()
connect()
proc/connect()
if(icon_state == "ladderdown") // the upper will connect to the lower
d_state = 1
var/turf/controlerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.down)
var/turf/below = locate(src.x, src.y, controler.down_target)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.down)
var/turf/below = locate(src.x, src.y, controller.down_target)
for(var/obj/multiz/ladder/L in below)
target = L
L.target = src
d_state = 0
break
if(L.icon_state == "ladderup")
target = L
L.target = src
d_state = 0
break
return
/* ex_act(severity)
@@ -60,18 +60,19 @@
attackby(obj/item/C as obj, mob/user as mob)
(..)
// construction commented out for balance concerns
/* if (!target && istype(C, /obj/item/stack/rods))
var/turf/controlerlocation = locate(1, 1, z)
var/turf/controllerlocation = locate(1, 1, z)
var/found = 0
var/obj/item/stack/rods/S = C
if(S.amount < 2)
user << "You dont have enough rods to finish the ladder."
return
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.down)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.down)
found = 1
var/turf/below = locate(src.x, src.y, controler.down_target)
var/turf/below = locate(src.x, src.y, controller.down_target)
var/blocked = 0
for(var/atom/A in below.contents)
if(A.density)
@@ -132,7 +133,7 @@
attack_hand(var/mob/M)
if(!target || !istype(target.loc, /turf))
M << "The ladder is incomplete and cant be climbed."
M << "The ladder is incomplete and can't be climbed."
else
var/turf/T = target.loc
var/blocked = 0
@@ -211,7 +212,7 @@
New()
..()
var/turf/cl= locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroler/c in cl)
for(var/obj/effect/landmark/zcontroller/c in cl)
if(c.up)
var/turf/O = locate(src.x, src.y, c.up_target)
if(istype(O, /turf/space))
@@ -228,10 +229,10 @@
src.connected = S
src.icon_state = "ramptop"
src.density = 1
var/turf/controlerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.up)
var/turf/above = locate(src.x, src.y, controler.up_target)
var/turf/controllerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up)
var/turf/above = locate(src.x, src.y, controller.up_target)
if(istype(above,/turf/space) || istype(above,/turf/simulated/floor/open))
src.target = above
break

View File

@@ -54,14 +54,14 @@
return ..()
/turf/simulated/floor/open/proc/getbelow()
var/turf/controlerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
// check if there is something to draw below
if(!controler.down)
if(!controller.down)
src.ChangeTurf(/turf/space)
return 0
else
floorbelow = locate(src.x, src.y, controler.down_target)
floorbelow = locate(src.x, src.y, controller.down_target)
return 1
return 1

View File

@@ -1,6 +1,6 @@
/obj/effect/landmark/zcontroler
name = "Z-Level Controler"
var/initialized = 0 // when set to 1, turfs will report to the controler
/obj/effect/landmark/zcontroller
name = "Z-Level Controller"
var/initialized = 0 // when set to 1, turfs will report to the controller
var/up = 0 // 1 allows up movement
var/up_target = 0 // the Z-level that is above the current one
var/down = 0 // 1 allows down movement
@@ -14,7 +14,7 @@
var/normal_time
var/fast_time
/obj/effect/landmark/zcontroler/New()
/obj/effect/landmark/zcontroller/New()
..()
for (var/turf/T in world)
if (T.z == z)
@@ -28,11 +28,11 @@
initialized = 1
return 1
/obj/effect/landmark/zcontroler/Del()
/obj/effect/landmark/zcontroller/Del()
processing_objects.Remove(src)
return
/obj/effect/landmark/zcontroler/process()
/obj/effect/landmark/zcontroller/process()
if (world.time > fast_time)
calc(fast)
fast_time = world.time + 10
@@ -46,7 +46,7 @@
slow_time = world.time + 3000 */
return
/obj/effect/landmark/zcontroler/proc/add(var/list/L, var/I, var/transfer)
/obj/effect/landmark/zcontroller/proc/add(var/list/L, var/I, var/transfer)
while (L.len)
var/turf/T = pick(L)
@@ -65,15 +65,15 @@
if(transfer > 0)
if(up)
var/turf/controler_up = locate(1, 1, up_target)
for(var/obj/effect/landmark/zcontroler/c_up in controler_up)
var/turf/controller_up = locate(1, 1, up_target)
for(var/obj/effect/landmark/zcontroller/c_up in controller_up)
var/list/temp = list()
temp += locate(T.x, T.y, up_target)
c_up.add(temp, I, transfer-1)
if(down)
var/turf/controler_down = locate(1, 1, down_target)
for(var/obj/effect/landmark/zcontroler/c_down in controler_down)
var/turf/controller_down = locate(1, 1, down_target)
for(var/obj/effect/landmark/zcontroller/c_down in controller_down)
var/list/temp = list()
temp += locate(T.x, T.y, down_target)
c_down.add(temp, I, transfer-1)
@@ -85,8 +85,8 @@
/turf/New()
..()
var/turf/controler = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroler/c in controler)
var/turf/controller = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/c in controller)
if(c.initialized)
var/list/turf = list()
turf += src
@@ -95,8 +95,8 @@
/turf/space/New()
..()
var/turf/controler = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroler/c in controler)
var/turf/controller = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/c in controller)
if(c.initialized)
var/list/turf = list()
turf += src
@@ -105,14 +105,14 @@
atom/movable/Move() //Hackish
. = ..()
var/turf/controlerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.up || controler.down)
var/turf/controllerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up || controller.down)
var/list/temp = list()
temp += locate(src.x, src.y, src.z)
controler.add(temp,3,1)
controller.add(temp,3,1)
/obj/effect/landmark/zcontroler/proc/calc(var/list/L)
/obj/effect/landmark/zcontroller/proc/calc(var/list/L)
var/list/slowholder = list()
var/list/normalholder = list()
var/list/fastholder = list()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -81,11 +81,11 @@ proc/FloodFill(turf/simulated/start)
z_space += O.z
// handle Z-level connections
var/turf/controlerlocation = locate(1, 1, T.z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
var/turf/controllerlocation = locate(1, 1, T.z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
// connect upwards
if(controler.up)
var/turf/above_me = locate(T.x, T.y, controler.up_target)
if(controller.up)
var/turf/above_me = locate(T.x, T.y, controller.up_target)
// add the turf above this
if(istype(above_me, /turf/simulated/floor/open) && !(above_me in open) && !(above_me in closed))
open += above_me
@@ -96,8 +96,8 @@ proc/FloodFill(turf/simulated/start)
if(!(above_me.z in z_space))
z_space += above_me.z
// connect downwards
if(controler.down && istype(T, /turf/simulated/floor/open))
var/turf/below_me = locate(T.x, T.y, controler.down_target)
if(controller.down && istype(T, /turf/simulated/floor/open))
var/turf/below_me = locate(T.x, T.y, controller.down_target)
// add the turf below this
if(!(below_me in open) && !(below_me in closed))
open += below_me
@@ -118,10 +118,10 @@ proc/FloodFill(turf/simulated/start)
//through the evaluated tile
//if there is none, the zone can connect upwards to either vent from there or connect with the zone there
//also check if the turf below the space is actually part of this zone to prevent the edge tiles from transforming
var/turf/controlerloc = locate(1, 1, S.z)
for(var/obj/effect/landmark/zcontroler/controler in controlerloc)
if(controler.down)
var/turf/below = locate(S.x, S.y, controler.down_target)
var/turf/controllerloc = locate(1, 1, S.z)
for(var/obj/effect/landmark/zcontroller/controller in controllerloc)
if(controller.down)
var/turf/below = locate(S.x, S.y, controller.down_target)
if(!((S.z - 1) in z_space) && below in closed)
open += S.ChangeTurf(/turf/simulated/floor/open)
list_space -= S

View File

@@ -145,7 +145,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
air.group_multiplier++
T.zone = src
///// Z-Level Stuff
// also add the tile below it if its open space
if(istype(T, /turf/simulated/floor/open))
@@ -775,11 +775,11 @@ zone/proc/Rebuild()
lowest_id = adjacent_id
/////// Z-Level stuff
var/turf/controlerlocation = locate(1, 1, current.z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
var/turf/controllerlocation = locate(1, 1, current.z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
// upwards
if(controler.up)
var/turf/simulated/adjacent = locate(current.x, current.y, controler.up_target)
if(controller.up)
var/turf/simulated/adjacent = locate(current.x, current.y, controller.up_target)
if(adjacent in turfs && istype(adjacent, /turf/simulated/floor/open))
current_adjacents += adjacent
@@ -789,8 +789,8 @@ zone/proc/Rebuild()
lowest_id = adjacent_id
// downwards
if(controler.down && istype(current, /turf/simulated/floor/open))
var/turf/simulated/adjacent = locate(current.x, current.y, controler.down_target)
if(controller.down && istype(current, /turf/simulated/floor/open))
var/turf/simulated/adjacent = locate(current.x, current.y, controller.down_target)
if(adjacent in turfs)
current_adjacents += adjacent

View File

@@ -149,6 +149,7 @@ var/global/datum/controller/gameticker/ticker
master_controller.process() //Start master_controller.process()
lighting_controller.process() //Start processing DynamicAreaLighting updates
for(var/obj/multiz/ladder/L in world) L.connect() //Lazy hackfix for ladders. TODO: move this to an actual controller. ~ Z
if(config.sql_enabled)
spawn(3000)

View File

@@ -96,17 +96,17 @@ proc/secondaryexplosion(turf/epicenter, range)
///// Z-Level Stuff
proc/explosion_z_transfer(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, up = 1, down = 1)
var/turf/controlerlocation = locate(1, 1, epicenter.z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.down)
var/turf/controllerlocation = locate(1, 1, epicenter.z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.down)
//start the child explosion, no admin log and no additional transfers
explosion(locate(epicenter.x, epicenter.y, controler.down_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 0, 0)
explosion(locate(epicenter.x, epicenter.y, controller.down_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 0, 0)
if(devastation_range - 2 > 0 || heavy_impact_range - 2 > 0) //only transfer further if the explosion is still big enough
explosion(locate(epicenter.x, epicenter.y, controler.down_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 0, 1)
explosion(locate(epicenter.x, epicenter.y, controller.down_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 0, 1)
if(controler.up)
if(controller.up)
//start the child explosion, no admin log and no additional transfers
explosion(locate(epicenter.x, epicenter.y, controler.up_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 0, 0)
explosion(locate(epicenter.x, epicenter.y, controller.up_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 0, 0)
if(devastation_range - 2 > 0 || heavy_impact_range - 2 > 0) //only transfer further if the explosion is still big enough
explosion(locate(epicenter.x, epicenter.y, controler.up_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 1, 0)
explosion(locate(epicenter.x, epicenter.y, controller.up_target), max(devastation_range - 2, 0), max(heavy_impact_range - 2, 0), max(light_impact_range - 2, 0), max(flash_range - 2, 0), 1, 0)
///// Z-Level Stuff

View File

@@ -9,6 +9,9 @@
..()
name = "floor"
/turf/simulated/floor/airless/ceiling
icon_state = "rockvault"
/turf/simulated/floor/light
name = "Light floor"
luminosity = 5

View File

@@ -202,15 +202,15 @@
///// Z-Level Stuff ///// This makes sure that turfs are not changed to space when one side is part of a zone
if(N == /turf/space)
var/turf/controler = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroler/c in controler)
var/turf/controller = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroller/c in controller)
if(c.down)
var/turf/below = locate(src.x, src.y, c.down_target)
if((below.zone || zone) && !istype(below, /turf/space)) // dont make open space into space, its pointless and makes people drop out of the station
var/turf/W = src.ChangeTurf(/turf/simulated/floor/open)
var/list/temp = list()
temp += W
c.add(temp,3,1) // report the new open space to the zcontroler
c.add(temp,3,1) // report the new open space to the zcontroller
return W
///// Z-Level Stuff

View File

@@ -101,10 +101,10 @@
///// Z-Level Stuff
if(src.d1 == 11 || src.d2 == 11)
var/turf/controlerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.down)
var/turf/below = locate(src.x, src.y, controler.down_target)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.down)
var/turf/below = locate(src.x, src.y, controller.down_target)
for(var/obj/structure/cable/c in below)
if(c.d1 == 12 || c.d2 == 12)
c.Del()

View File

@@ -159,14 +159,14 @@
if(T)
. += power_list(T, src, d1, 1)
else if (d1 == 11 || d1 == 12)
var/turf/controlerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.up && d1 == 12)
T = locate(src.x, src.y, controler.up_target)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up && d1 == 12)
T = locate(src.x, src.y, controller.up_target)
if(T)
. += power_list(T, src, 11, 1)
if(controler.down && d1 == 11)
T = locate(src.x, src.y, controler.down_target)
if(controller.down && d1 == 11)
T = locate(src.x, src.y, controller.down_target)
if(T)
. += power_list(T, src, 12, 1)
else if(!d1)
@@ -174,14 +174,14 @@
. += power_list(T, src, d1, 1)
if(d2 == 11 || d2 == 12)
var/turf/controlerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.up && d2 == 12)
T = locate(src.x, src.y, controler.up_target)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up && d2 == 12)
T = locate(src.x, src.y, controller.up_target)
if(T)
. += power_list(T, src, 11, 1)
if(controler.down && d2 == 11)
T = locate(src.x, src.y, controler.down_target)
if(controller.down && d2 == 11)
T = locate(src.x, src.y, controller.down_target)
if(T)
. += power_list(T, src, 12, 1)
else

View File

@@ -177,7 +177,7 @@ mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory.
target_locked = image("icon" = 'icons/effects/Targeted.dmi', "icon_state" = "locked")
update_targeted()
//Adding the buttons to the controler person
//Adding the buttons to the controller person
var/mob/living/T = I.loc
if(T)
if(T.client)

View File

@@ -139,15 +139,15 @@
if(temp)
chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("dispense" = temp.id)))) // list in a list because Byond merges the first list...
data["chemicals"] = chemicals
// update the ui if it exists, returns null if no ui is passed/found
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
if (!ui)
// the ui does not exist, so we'll create a new() one
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
ui = new(user, src, ui_key, "chem_dispenser.tmpl", ui_title, 380, 650)
// when the ui is first opened this is the data it will use
ui.set_initial_data(data)
ui.set_initial_data(data)
// open the new ui window
ui.open()
@@ -1259,4 +1259,4 @@
var/amount = O.reagents.total_volume
O.reagents.trans_to(beaker, amount)
if(!O.reagents.total_volume)
remove_object(O)
remove_object(O)

View File

@@ -932,10 +932,10 @@
var/obj/structure/disposalpipe/P
if(nextdir == 12)
var/turf/controlerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.up)
T = locate(src.x, src.y, controler.up_target)
var/turf/controllerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up)
T = locate(src.x, src.y, controller.up_target)
if(!T)
H.loc = src.loc
return
@@ -985,10 +985,10 @@
var/obj/structure/disposalpipe/P
if(nextdir == 11)
var/turf/controlerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroler/controler in controlerlocation)
if(controler.down)
T = locate(src.x, src.y, controler.down_target)
var/turf/controllerlocation = locate(1, 1, src.z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.down)
T = locate(src.x, src.y, controller.down_target)
if(!T)
H.loc = src.loc
return