Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion code/__HELPERS/unsorted.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1291,11 +1291,12 @@ GLOBAL_LIST_INIT(WALLITEMS, list(
* * start_atom - starting point of the line
* * end_atom - ending point of the line
* * include_start_atom - when truthy includes start_atom in the list, default TRUE
* * z_level_transitions - prevent diagonal avoidance of obstacles, only needed for actual object traversal, default FALSE
*
* Returns:
* list - turfs from start_atom (in/exclusive) to end_atom (inclusive)
*/
/proc/get_line(atom/start_atom, atom/end_atom, include_start_atom = TRUE)
/proc/get_line(atom/start_atom, atom/end_atom, include_start_atom = TRUE, z_level_transitions = FALSE)
var/turf/start_turf = get_turf(start_atom)
var/turf/end_turf = get_turf(end_atom)
var/turf/end_turf_fall = end_turf //in case we are going cross fake z levels we store here the end tile to fall to
Expand Down Expand Up @@ -1336,6 +1337,51 @@ GLOBAL_LIST_INIT(WALLITEMS, list(

line += end_turf_fall

if(!reservation && z_level_transitions)
var/list/mutli_z_cross_points = list()
if(start_turf.z == end_turf.z)
return line
if(!SSmapping.same_z_map(start_atom.z, end_turf.z))
line.Cut()
line = list(start_turf) //We're trying to throw things accross maps somehow. Let's not.
return line

//Throwing accross Z levels on the same map. Fill in the vertical swapping over points so we're not diagnonally avoiding obstacle turfs.
var/turf/comparing_turf = start_turf
var/path_position = 0
if(length(line) > 1)
for(var/turf/turf_cross_point in line)
path_position++
if(comparing_turf.z == turf_cross_point.z)
comparing_turf = turf_cross_point
continue
else
mutli_z_cross_points += turf_cross_point
mutli_z_cross_points[turf_cross_point] = path_position
comparing_turf = turf_cross_point
else
path_position++ //Only one position in line and it's immediately into another Z.
mutli_z_cross_points += line[1]
mutli_z_cross_points[line[1]] = path_position

var/offset = SSmapping.level_trait(start_turf.z, ZTRAIT_UP)
var/turf/first_cross_point = mutli_z_cross_points[1]
if(first_cross_point.z != start_turf.z + offset)
offset = 0 // We only need to offset if we're entering from a lower Z.

for(var/turf/crossing_point in mutli_z_cross_points)
var/turf/switching_cross_point
switching_cross_point = locate(crossing_point.x, crossing_point.y, start_turf.z + offset)
if(offset > 0) //If we're ending up with multiple cross points, we're throwing across multiple Zs - This is probably only going to happen for throwing down, but just incase.
offset = offset + SSmapping.level_trait(switching_cross_point.z, ZTRAIT_UP)
else //So we need to adjust the offset for the next cross point.
offset = offset + SSmapping.level_trait(switching_cross_point.z, ZTRAIT_DOWN)
line.Insert(mutli_z_cross_points[crossing_point], switching_cross_point)

if(!istype(switching_cross_point, /turf/open_space))
line.Cut(max(1, mutli_z_cross_points[crossing_point] + 1), length(line) + 1) //Hit a non open_space turf. Shouldn't go through anything else. Stop here.
Comment on lines +1381 to +1382

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kinda the whole point. We shorten the line to the actual traversable tiles. We can't go any further because there is not an open_space that lets us do so.

So this stops get_line traversing Zs where it shouldn't be doing it. Because there's a tile to block it.

break

return line

//Key thing that stops lag. Cornerstone of performance in ss13, Just sitting here, in unsorted.dm.
Expand Down
56 changes: 28 additions & 28 deletions code/modules/movement/launching/launching.dm
Original file line number Diff line number Diff line change
Expand Up @@ -165,59 +165,59 @@
if(end_turf)
end_turf.on_throw_end(src)


// Proc for throwing or propelling movable atoms towards a target
/atom/movable/proc/launch_towards(datum/launch_metadata/LM, tracking = FALSE)
if (!istype(LM))
/atom/movable/proc/launch_towards(datum/launch_metadata/launching_data, tracking = FALSE)
if (!istype(launching_data))
CRASH("invalid launch_metadata passed to launch_towards")
if (!LM.target || !src)
if (!launching_data.target || !src)
return

if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_THROW, LM.thrower) & COMPONENT_CANCEL_THROW)
if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_THROW, launching_data.thrower) & COMPONENT_CANCEL_THROW)
return

// If we already have launch_metadata (from a previous throw), reset it and qdel the old launch_metadata datum
if (istype(launch_metadata))
qdel(launch_metadata)
launch_metadata = LM
launch_metadata = launching_data

if (LM.spin)
animation_spin(5, 1 + min(1, LM.range/20))
if (launching_data.spin)
animation_spin(5, 1 + min(1, launching_data.range/20))

var/old_speed = cur_speed
cur_speed = clamp(LM.speed, MIN_SPEED, MAX_SPEED) // Sanity check, also ~1 sec delay between each launch move is not very reasonable
cur_speed = clamp(launching_data.speed, MIN_SPEED, MAX_SPEED) // Sanity check, also ~1 sec delay between each launch move is not very reasonable
var/delay = 10/cur_speed - 0.5 // scales delay back to deciseconds for when sleep is called
var/pass_flags = LM.pass_flags
var/pass_flags = launching_data.pass_flags

throwing = TRUE

add_temp_pass_flags(pass_flags)
var/turf/start_turf
var/turf/start_turf = get_step_towards(src, launching_data.target)
var/turf/above = SSmapping.get_turf_above(loc)
var/turf/target_turf = get_turf(launching_data.target)
var/datum/turf_reservation/reservation = SSmapping.used_turfs[loc]
if(reservation && (reservation.is_below(loc, get_turf(LM.target))) || (LM.target.z > z) && istype(above, /turf/open_space))
start_turf = above
else
start_turf = get_step_towards(src, LM.target)
if(reservation && reservation.is_below(get_turf(LM.target), loc))
start_turf = get_step_towards(src, SSmapping.get_turf_above(LM.target))
var/list/turf/path = get_line(start_turf, LM.target)
var/last_loc = loc
if(reservation)
if((reservation.is_below(loc, target_turf)) || (launching_data.target.z > z) && istype(above, /turf/open_space))
start_turf = above
else if(reservation && reservation.is_below(target_turf, loc))
start_turf = get_step_towards(src, SSmapping.get_turf_above(launching_data.target))

var/list/turf/path = get_line(start_turf, launching_data.target, z_level_transitions = TRUE)
var/last_loc = loc
var/early_exit = FALSE
LM.dist = 0

launching_data.dist = 0
for (var/turf/T in path)
if (!src || !throwing || loc != last_loc || !isturf(src.loc))
break
if (!LM || QDELETED(LM))
if (!launching_data || QDELETED(launching_data))
early_exit = TRUE
break
if (LM.dist >= LM.range)
if (launching_data.dist >= launching_data.range)
break
if (!Move(T)) // If this returns FALSE, then a collision happened
break
last_loc = loc
if (++LM.dist >= LM.range)
if (++launching_data.dist >= launching_data.range)
break
sleep(delay)

Expand All @@ -226,21 +226,21 @@
var/turf/T = get_turf(src)
if(!istype(T))
return
var/atom/hit_atom = ismob(LM.target) ? null : T // TODO, just check for LM.target, the ismob is to prevent funky behavior with grenades 'n crates
var/atom/hit_atom = ismob(launching_data.target) ? null : T // TODO, just check for LM.target, the ismob is to prevent funky behavior with grenades 'n crates
if(!hit_atom)
for(var/atom/A in T)
if(A == LM.target)
if(A == launching_data.target)
hit_atom = A
break
if(!hit_atom && tracking && get_dist(src, LM.target) <= 1 && get_dist(start_turf, LM.target) <= 1) // If we missed, but we are tracking and the target is still next to us and the turf we launched from, then we still count it as a hit
hit_atom = LM.target
if(!hit_atom && tracking && get_dist(src, launching_data.target) <= 1 && get_dist(start_turf, launching_data.target) <= 1) // If we missed, but we are tracking and the target is still next to us and the turf we launched from, then we still count it as a hit
hit_atom = launching_data.target
launch_impact(hit_atom)
if (loc)
throwing = FALSE
rebounding = FALSE
cur_speed = old_speed
remove_temp_pass_flags(pass_flags)
LM.invoke_end_throw_callbacks(src)
launching_data.invoke_end_throw_callbacks(src)
QDEL_NULL(launch_metadata)

/atom/movable/proc/throw_random_direction(range, speed = 0, atom/thrower, spin, launch_type = NORMAL_LAUNCH, pass_flags = NO_FLAGS)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/projectiles/projectile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@
ammo.fire_bonus_projectiles(src, gun_damage_mult, projectile_max_range_add, gun_bonus_proj_scatter)
bonus_projectile_check = PROJECTILE_ORIGINAL //Mark this projectile as having spawned a set of bonus projectiles.

path = get_line(starting, target_turf)
path = get_line(starting, target_turf, z_level_transitions = TRUE)
p_x += clamp((rand()-0.5)*scatter*3, -8, 8)
p_y += clamp((rand()-0.5)*scatter*3, -8, 8)
update_angle(starting, target_turf)
Expand Down