mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 15:45:25 +01:00
PS -> SMC Ports: LINDA, Spacedrift, Throwing
This commit ports LINDA, spacedrifting, and throwing to the SMC.
This commit is contained in:
@@ -0,0 +1,398 @@
|
||||
#define SSAIR_DEFERREDPIPENETS 1
|
||||
#define SSAIR_PIPENETS 2
|
||||
#define SSAIR_ATMOSMACHINERY 3
|
||||
#define SSAIR_ACTIVETURFS 4
|
||||
#define SSAIR_EXCITEDGROUPS 5
|
||||
#define SSAIR_HIGHPRESSURE 6
|
||||
#define SSAIR_HOTSPOTS 7
|
||||
#define SSAIR_SUPERCONDUCTIVITY 8
|
||||
|
||||
SUBSYSTEM_DEF(air)
|
||||
name = "Atmospherics"
|
||||
init_order = INIT_ORDER_AIR
|
||||
priority = FIRE_PRIORITY_AIR
|
||||
wait = 5
|
||||
flags = SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/cost_turfs = 0
|
||||
var/cost_groups = 0
|
||||
var/cost_highpressure = 0
|
||||
var/cost_hotspots = 0
|
||||
var/cost_superconductivity = 0
|
||||
var/cost_pipenets = 0
|
||||
var/cost_deferred_pipenets = 0
|
||||
var/cost_atmos_machinery = 0
|
||||
|
||||
var/list/excited_groups = list()
|
||||
var/list/active_turfs = list()
|
||||
var/list/hotspots = list()
|
||||
var/list/networks = list()
|
||||
var/list/atmos_machinery = list()
|
||||
var/list/pipe_init_dirs_cache = list()
|
||||
|
||||
|
||||
|
||||
//Special functions lists
|
||||
var/list/active_super_conductivity = list()
|
||||
var/list/high_pressure_delta = list()
|
||||
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/currentpart = SSAIR_PIPENETS
|
||||
|
||||
/datum/controller/subsystem/air/stat_entry(msg)
|
||||
msg += "C:{"
|
||||
msg += "AT:[round(cost_turfs,1)]|"
|
||||
msg += "EG:[round(cost_groups,1)]|"
|
||||
msg += "HP:[round(cost_highpressure,1)]|"
|
||||
msg += "HS:[round(cost_hotspots,1)]|"
|
||||
msg += "SC:[round(cost_superconductivity,1)]|"
|
||||
msg += "PN:[round(cost_pipenets,1)]|"
|
||||
msg += "DPN:[round(cost_deferred_pipenets,1)]|"
|
||||
msg += "AM:[round(cost_atmos_machinery,1)]"
|
||||
msg += "} "
|
||||
msg += "AT:[active_turfs.len]|"
|
||||
msg += "EG:[excited_groups.len]|"
|
||||
msg += "HS:[hotspots.len]|"
|
||||
msg += "PN:[networks.len]|"
|
||||
msg += "HP:[high_pressure_delta.len]|"
|
||||
msg += "AS:[active_super_conductivity.len]|"
|
||||
msg += "AT/MS:[round((cost ? active_turfs.len/cost : 0),0.1)]"
|
||||
..(msg)
|
||||
|
||||
|
||||
/datum/controller/subsystem/air/Initialize(timeofday)
|
||||
setup_overlays() // Assign icons and such for gas-turf-overlays
|
||||
setup_allturfs()
|
||||
setup_atmos_machinery()
|
||||
setup_pipenets()
|
||||
..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/air/fire(resumed = 0)
|
||||
var/timer = TICK_USAGE_REAL
|
||||
|
||||
if(currentpart == SSAIR_DEFERREDPIPENETS || !resumed)
|
||||
process_deferred_pipenets(resumed)
|
||||
cost_deferred_pipenets = MC_AVERAGE(cost_deferred_pipenets, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
currentpart = SSAIR_PIPENETS
|
||||
|
||||
if(currentpart == SSAIR_PIPENETS || !resumed)
|
||||
process_pipenets(resumed)
|
||||
cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
currentpart = SSAIR_ATMOSMACHINERY
|
||||
|
||||
if(currentpart == SSAIR_ATMOSMACHINERY)
|
||||
timer = TICK_USAGE_REAL
|
||||
process_atmos_machinery(resumed)
|
||||
cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
currentpart = SSAIR_ACTIVETURFS
|
||||
|
||||
if(currentpart == SSAIR_ACTIVETURFS)
|
||||
timer = TICK_USAGE_REAL
|
||||
process_active_turfs(resumed)
|
||||
cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
currentpart = SSAIR_EXCITEDGROUPS
|
||||
|
||||
if(currentpart == SSAIR_EXCITEDGROUPS)
|
||||
timer = TICK_USAGE_REAL
|
||||
process_excited_groups(resumed)
|
||||
cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
currentpart = SSAIR_HIGHPRESSURE
|
||||
|
||||
if(currentpart == SSAIR_HIGHPRESSURE)
|
||||
timer = TICK_USAGE_REAL
|
||||
process_high_pressure_delta(resumed)
|
||||
cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
currentpart = SSAIR_HOTSPOTS
|
||||
|
||||
if(currentpart == SSAIR_HOTSPOTS)
|
||||
timer = TICK_USAGE_REAL
|
||||
process_hotspots(resumed)
|
||||
cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
currentpart = SSAIR_SUPERCONDUCTIVITY
|
||||
|
||||
if(currentpart == SSAIR_SUPERCONDUCTIVITY)
|
||||
timer = TICK_USAGE_REAL
|
||||
process_super_conductivity(resumed)
|
||||
cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
if(state != SS_RUNNING)
|
||||
return
|
||||
resumed = 0
|
||||
currentpart = SSAIR_PIPENETS
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_deferred_pipenets(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = deferred_pipenet_rebuilds.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/obj/machinery/atmospherics/A = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(A)
|
||||
A.build_network()
|
||||
else
|
||||
deferred_pipenet_rebuilds.Remove(A)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_pipenets(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = networks.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/datum/pipeline/thing = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(thing)
|
||||
thing.process()
|
||||
else
|
||||
networks.Remove(thing)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_atmos_machinery(resumed = 0)
|
||||
var/seconds = wait * 0.1
|
||||
if (!resumed)
|
||||
src.currentrun = atmos_machinery.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/obj/machinery/M = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(!M || (M.process_atmos(seconds) == PROCESS_KILL))
|
||||
atmos_machinery.Remove(M)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_super_conductivity(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = active_super_conductivity.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/turf/simulated/T = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
T.super_conduct()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_hotspots(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = hotspots.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/obj/effect/hotspot/H = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if (H)
|
||||
H.process()
|
||||
else
|
||||
hotspots -= H
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_high_pressure_delta(resumed = 0)
|
||||
while (high_pressure_delta.len)
|
||||
var/turf/simulated/T = high_pressure_delta[high_pressure_delta.len]
|
||||
high_pressure_delta.len--
|
||||
T.high_pressure_movements()
|
||||
T.pressure_difference = 0
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_active_turfs(resumed = 0)
|
||||
//cache for sanic speed
|
||||
var/fire_count = times_fired
|
||||
if (!resumed)
|
||||
src.currentrun = active_turfs.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/turf/simulated/T = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if (T)
|
||||
T.process_cell(fire_count)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_excited_groups(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = excited_groups.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/datum/excited_group/EG = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
EG.breakdown_cooldown++
|
||||
if(EG.breakdown_cooldown == 10)
|
||||
EG.self_breakdown()
|
||||
else if(EG.breakdown_cooldown >= 20)
|
||||
EG.dismantle()
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/remove_from_active(turf/simulated/T)
|
||||
active_turfs -= T
|
||||
if(currentpart == SSAIR_ACTIVETURFS)
|
||||
currentrun -= T
|
||||
if(istype(T))
|
||||
T.excited = 0
|
||||
if(T.excited_group)
|
||||
T.excited_group.garbage_collect()
|
||||
|
||||
/datum/controller/subsystem/air/proc/add_to_active(turf/simulated/T, blockchanges = 1)
|
||||
if(istype(T) && T.air)
|
||||
T.excited = 1
|
||||
active_turfs |= T
|
||||
if(currentpart == SSAIR_ACTIVETURFS)
|
||||
currentrun |= T
|
||||
if(blockchanges && T.excited_group)
|
||||
T.excited_group.garbage_collect()
|
||||
else
|
||||
for(var/direction in cardinal)
|
||||
if(!(T.atmos_adjacent_turfs & direction))
|
||||
continue
|
||||
var/turf/simulated/S = get_step(T, direction)
|
||||
if(istype(S))
|
||||
add_to_active(S)
|
||||
|
||||
/datum/controller/subsystem/air/proc/setup_allturfs(var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz)))
|
||||
var/list/active_turfs = src.active_turfs
|
||||
|
||||
for(var/thing in turfs_to_init)
|
||||
var/turf/T = thing
|
||||
active_turfs -= T
|
||||
if(T.blocks_air)
|
||||
continue
|
||||
T.Initialize_Atmos(times_fired)
|
||||
CHECK_TICK
|
||||
|
||||
if(active_turfs.len)
|
||||
var/starting_ats = active_turfs.len
|
||||
sleep(world.tick_lag)
|
||||
var/timer = world.timeofday
|
||||
warning("There are [starting_ats] active turfs at roundstart, this is a mapping error caused by a difference of the air between the adjacent turfs. You can see its coordinates using \"Mapping -> Show roundstart AT list\" verb (debug verbs required)")
|
||||
|
||||
//now lets clear out these active turfs
|
||||
var/list/turfs_to_check = active_turfs.Copy()
|
||||
do
|
||||
var/list/new_turfs_to_check = list()
|
||||
for(var/turf/simulated/T in turfs_to_check)
|
||||
new_turfs_to_check += T.resolve_active_graph()
|
||||
CHECK_TICK
|
||||
|
||||
active_turfs += new_turfs_to_check
|
||||
turfs_to_check = new_turfs_to_check
|
||||
|
||||
while (turfs_to_check.len)
|
||||
var/ending_ats = active_turfs.len
|
||||
for(var/thing in excited_groups)
|
||||
var/datum/excited_group/EG = thing
|
||||
EG.self_breakdown()
|
||||
EG.dismantle()
|
||||
CHECK_TICK
|
||||
|
||||
var/msg = "HEY! LISTEN! [DisplayTimeText(world.timeofday - timer)] were wasted processing [starting_ats] turf(s) (connected to [ending_ats] other turfs) with atmos differences at round start."
|
||||
to_chat(world, "<span class='boldannounce'>[msg]</span>")
|
||||
warning(msg)
|
||||
|
||||
/turf/simulated/proc/resolve_active_graph()
|
||||
. = list()
|
||||
var/datum/excited_group/EG = excited_group
|
||||
if (blocks_air || !air)
|
||||
return
|
||||
if (!EG)
|
||||
EG = new
|
||||
EG.add_turf(src)
|
||||
|
||||
for (var/turf/simulated/ET in atmos_adjacent_turfs)
|
||||
if ( ET.blocks_air || !ET.air)
|
||||
continue
|
||||
|
||||
var/ET_EG = ET.excited_group
|
||||
if (ET_EG)
|
||||
if (ET_EG != EG)
|
||||
EG.merge_groups(ET_EG)
|
||||
EG = excited_group //merge_groups() may decide to replace our current EG
|
||||
else
|
||||
EG.add_turf(ET)
|
||||
if (!ET.excited)
|
||||
ET.excited = 1
|
||||
. += ET
|
||||
|
||||
/datum/controller/subsystem/air/proc/setup_atmos_machinery()
|
||||
var/watch = start_watch()
|
||||
var/count = 0
|
||||
log_startup_progress("Initializing atmospherics machinery...")
|
||||
for(var/obj/machinery/atmospherics/unary/U in machines)
|
||||
if(istype(U, /obj/machinery/atmospherics/unary/vent_pump))
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/T = U
|
||||
T.broadcast_status()
|
||||
count++
|
||||
else if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber))
|
||||
var/obj/machinery/atmospherics/unary/vent_scrubber/T = U
|
||||
T.broadcast_status()
|
||||
count++
|
||||
log_startup_progress(" Initialized [count] atmospherics machines in [stop_watch(watch)]s.")
|
||||
|
||||
//this can't be done with setup_atmos_machinery() because
|
||||
// all atmos machinery has to initalize before the first
|
||||
// pipenet can be built.
|
||||
/datum/controller/subsystem/air/proc/setup_pipenets()
|
||||
var/watch = start_watch()
|
||||
var/count = 0
|
||||
log_startup_progress("Initializing pipe networks...")
|
||||
for(var/obj/machinery/atmospherics/machine in machines)
|
||||
machine.build_network()
|
||||
count++
|
||||
log_startup_progress(" Initialized [count] pipes in [stop_watch(watch)]s.")
|
||||
|
||||
/datum/controller/subsystem/air/proc/setup_overlays()
|
||||
plmaster = new /obj/effect/overlay()
|
||||
plmaster.icon = 'icons/effects/tile_effects.dmi'
|
||||
plmaster.icon_state = "plasma"
|
||||
plmaster.layer = FLY_LAYER
|
||||
plmaster.mouse_opacity = 0
|
||||
|
||||
slmaster = new /obj/effect/overlay()
|
||||
slmaster.icon = 'icons/effects/tile_effects.dmi'
|
||||
slmaster.icon_state = "sleeping_agent"
|
||||
slmaster.layer = FLY_LAYER
|
||||
slmaster.mouse_opacity = 0
|
||||
|
||||
icemaster = new /obj/effect/overlay()
|
||||
icemaster.icon = 'icons/turf/overlays.dmi'
|
||||
icemaster.icon_state = "snowfloor"
|
||||
icemaster.layer = TURF_LAYER+0.1
|
||||
icemaster.mouse_opacity = 0
|
||||
|
||||
#undef SSAIR_PIPENETS
|
||||
#undef SSAIR_ATMOSMACHINERY
|
||||
#undef SSAIR_ACTIVETURFS
|
||||
#undef SSAIR_EXCITEDGROUPS
|
||||
#undef SSAIR_HIGHPRESSURE
|
||||
#undef SSAIR_HOTSPOT
|
||||
#undef SSAIR_SUPERCONDUCTIVITY
|
||||
@@ -0,0 +1,59 @@
|
||||
SUBSYSTEM_DEF(spacedrift)
|
||||
name = "Space Drift"
|
||||
priority = FIRE_PRIORITY_SPACEDRIFT
|
||||
wait = 5
|
||||
flags = SS_NO_INIT|SS_KEEP_TIMING
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
|
||||
/datum/controller/subsystem/spacedrift/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
|
||||
|
||||
/datum/controller/subsystem/spacedrift/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while (currentrun.len)
|
||||
var/atom/movable/AM = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if (!AM)
|
||||
processing -= AM
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
if (AM.inertia_next_move > world.time)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
if (!AM.loc || AM.loc != AM.inertia_last_loc || AM.Process_Spacemove(0))
|
||||
AM.inertia_dir = 0
|
||||
|
||||
if (!AM.inertia_dir)
|
||||
AM.inertia_last_loc = null
|
||||
processing -= AM
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
var/old_dir = AM.dir
|
||||
var/old_loc = AM.loc
|
||||
AM.inertia_moving = TRUE
|
||||
step(AM, AM.inertia_dir)
|
||||
AM.inertia_moving = FALSE
|
||||
AM.inertia_next_move = world.time + AM.inertia_move_delay
|
||||
if (AM.loc == old_loc)
|
||||
AM.inertia_dir = 0
|
||||
|
||||
AM.setDir(old_dir)
|
||||
AM.inertia_last_loc = AM.loc
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
#define MAX_THROWING_DIST 512 // 2 z-levels on default width
|
||||
#define MAX_TICKS_TO_MAKE_UP 3 //how many missed ticks will we attempt to make up for this run.
|
||||
|
||||
SUBSYSTEM_DEF(throwing)
|
||||
name = "Throwing"
|
||||
priority = FIRE_PRIORITY_THROWING
|
||||
wait = 1
|
||||
flags = SS_NO_INIT|SS_KEEP_TIMING|SS_TICKER
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/currentrun
|
||||
var/list/processing = list()
|
||||
|
||||
/datum/controller/subsystem/throwing/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
|
||||
|
||||
/datum/controller/subsystem/throwing/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(length(currentrun))
|
||||
var/atom/movable/AM = currentrun[currentrun.len]
|
||||
var/datum/thrownthing/TT = currentrun[AM]
|
||||
currentrun.len--
|
||||
if (!AM || !TT)
|
||||
processing -= AM
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
TT.tick()
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
currentrun = null
|
||||
|
||||
/datum/thrownthing
|
||||
var/atom/movable/thrownthing
|
||||
var/atom/target
|
||||
var/turf/target_turf
|
||||
var/init_dir
|
||||
var/maxrange
|
||||
var/speed
|
||||
var/mob/thrower
|
||||
var/diagonals_first
|
||||
var/dist_travelled = 0
|
||||
var/start_time
|
||||
var/dist_x
|
||||
var/dist_y
|
||||
var/dx
|
||||
var/dy
|
||||
var/pure_diagonal
|
||||
var/diagonal_error
|
||||
var/datum/callback/callback
|
||||
var/paused = FALSE
|
||||
var/delayed_time = 0
|
||||
var/last_move = 0
|
||||
|
||||
/datum/thrownthing/proc/tick()
|
||||
var/atom/movable/AM = thrownthing
|
||||
if (!isturf(AM.loc) || !AM.throwing)
|
||||
finalize()
|
||||
return
|
||||
|
||||
if(paused)
|
||||
delayed_time += world.time - last_move
|
||||
return
|
||||
|
||||
if (dist_travelled && hitcheck()) //to catch sneaky things moving on our tile while we slept
|
||||
finalize()
|
||||
return
|
||||
|
||||
var/atom/step
|
||||
|
||||
last_move = world.time
|
||||
|
||||
//calculate how many tiles to move, making up for any missed ticks.
|
||||
var/tilestomove = CEILING(min(((((world.time+world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait), 1)
|
||||
while (tilestomove-- > 0)
|
||||
if ((dist_travelled >= maxrange || AM.loc == target_turf) && has_gravity(AM, AM.loc))
|
||||
finalize()
|
||||
return
|
||||
|
||||
if (dist_travelled <= max(dist_x, dist_y)) //if we haven't reached the target yet we home in on it, otherwise we use the initial direction
|
||||
step = get_step(AM, get_dir(AM, target_turf))
|
||||
else
|
||||
step = get_step(AM, init_dir)
|
||||
|
||||
if (!pure_diagonal && !diagonals_first) // not a purely diagonal trajectory and we don't want all diagonal moves to be done first
|
||||
if (diagonal_error >= 0 && max(dist_x,dist_y) - dist_travelled != 1) //we do a step forward unless we're right before the target
|
||||
step = get_step(AM, dx)
|
||||
diagonal_error += (diagonal_error < 0) ? dist_x/2 : -dist_y
|
||||
|
||||
if (!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
|
||||
finalize()
|
||||
return
|
||||
|
||||
AM.Move(step, get_dir(AM, step))
|
||||
|
||||
if (!AM.throwing) // we hit something during our move
|
||||
finalize(hit = TRUE)
|
||||
return
|
||||
|
||||
dist_travelled++
|
||||
|
||||
if (dist_travelled > MAX_THROWING_DIST)
|
||||
finalize()
|
||||
return
|
||||
|
||||
/datum/thrownthing/proc/finalize(hit = FALSE, target=null)
|
||||
set waitfor = 0
|
||||
SSthrowing.processing -= thrownthing
|
||||
//done throwing, either because it hit something or it finished moving
|
||||
thrownthing.throwing = null
|
||||
if (!hit)
|
||||
for (var/thing in get_turf(thrownthing)) //looking for our target on the turf we land on.
|
||||
var/atom/A = thing
|
||||
if (A == target)
|
||||
hit = 1
|
||||
thrownthing.throw_impact(A, src)
|
||||
break
|
||||
if (!hit)
|
||||
thrownthing.throw_impact(get_turf(thrownthing), src) // we haven't hit something yet and we still must, let's hit the ground.
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
else
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
|
||||
if(target)
|
||||
thrownthing.throw_impact(target, src)
|
||||
|
||||
if (callback)
|
||||
callback.Invoke()
|
||||
|
||||
/datum/thrownthing/proc/hit_atom(atom/A)
|
||||
finalize(hit=TRUE, target=A)
|
||||
|
||||
/datum/thrownthing/proc/hitcheck()
|
||||
for (var/thing in get_turf(thrownthing))
|
||||
var/atom/movable/AM = thing
|
||||
if (AM == thrownthing)
|
||||
continue
|
||||
if(AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags & ON_BORDER))
|
||||
finalize(hit=TRUE, target=AM)
|
||||
return TRUE
|
||||
Reference in New Issue
Block a user