Skip to content

Commit

Permalink
Assorted performance improvements (ParadiseSS13#25649)
Browse files Browse the repository at this point in the history
* Improved efficiency of playsound.

* Improve performance of turf/Enter

* Improve performace of thrown objects.

* Improved performance of /atom/movable/CanPass.

* Improved pipeline destruction performance.

* Apply suggestions from code review

Co-authored-by: Luc <[email protected]>
Co-authored-by: 1080pCat <[email protected]>
Signed-off-by: Charlie Nolan <[email protected]>

---------

Signed-off-by: Charlie Nolan <[email protected]>
Co-authored-by: FunnyMan3595 (Charlie Nolan) <[email protected]>
Co-authored-by: Luc <[email protected]>
Co-authored-by: 1080pCat <[email protected]>
  • Loading branch information
4 people authored Jul 16, 2024
1 parent a5dd1a1 commit fb93e5a
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 60 deletions.
10 changes: 3 additions & 7 deletions code/controllers/subsystem/SSthrowing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,9 @@ SUBSYSTEM_DEF(throwing)
return
thrownthing.throwing = null
if(!hit)
for(var/atom/movable/obstacle as anything in get_turf(thrownthing)) //looking for our target on the turf we land on.
if(obstacle == target)
hit = TRUE
thrownthing.throw_impact(obstacle, src)
if(QDELETED(thrownthing)) //throw_impact can delete things, such as glasses smashing
return //deletion should already be handled by on_thrownthing_qdel()
break
if(get_turf(target) == get_turf(thrownthing))
hit = TRUE
thrownthing.throw_impact(target, src)
if(!hit)
thrownthing.throw_impact(get_turf(thrownthing), src) // we haven't hit something yet and we still must, let's hit the ground.
if(QDELETED(thrownthing)) //throw_impact can delete things, such as glasses smashing
Expand Down
5 changes: 3 additions & 2 deletions code/game/atoms_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -529,9 +529,10 @@
return FALSE

/atom/movable/CanPass(atom/movable/mover, turf/target, height=1.5)
if(mover in buckled_mobs)
// This condition is copied from atom to avoid an extra parent call, because this is a very hot proc.
if(!density || !height)
return TRUE
return ..()
return LAZYIN(buckled_mobs, mover)

/atom/movable/proc/get_spacemove_backup()
var/atom/movable/dense_object_backup
Expand Down
37 changes: 22 additions & 15 deletions code/game/sound.dm
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,32 @@ falloff_distance - Distance at which falloff begins. Sound is at peak volume (in
var/sound/S = sound(get_sfx(soundin))
var/maxdistance = SOUND_RANGE + extrarange

var/list/listeners = GLOB.player_list
if(!ignore_walls) //these sounds don't carry through walls
listeners = listeners & hearers(maxdistance, turf_source)

for(var/P in listeners)
var/mob/M = P
if(!M || !M.client)
continue

var/turf/T = get_turf(M) // These checks need to be changed if z-levels are ever further refactored
if(!T)
var/list/possible_listeners = list()
var/list/desired_turfs = list()
for(var/mob/P as anything in GLOB.player_list)
if(isnull(P) || !P.client)
continue
if(T.z != turf_source.z)
var/turf/T = get_turf(P)
if(!T || T.z != turf_source.z || get_dist(T, turf_source) > maxdistance)
continue

var/distance = get_dist(M, turf_source)
possible_listeners += P
desired_turfs |= T

var/list/listeners = list()
if(ignore_walls)
listeners = possible_listeners
else if(length(possible_listeners))
var/list/turf_vis = list()
for(var/turf/T as anything in desired_turfs)
turf_vis[T] = inLineOfSight(T.x, T.y, turf_source.x, turf_source.y, T.z)

for(var/mob/P in possible_listeners)
if(turf_vis[get_turf(P)])
listeners += P

if(distance <= maxdistance)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, 1, use_reverb)
for(var/mob/M as anything in listeners)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, 1, use_reverb)

/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = 1, use_reverb = TRUE)
if(!client || !can_hear())
Expand Down
29 changes: 18 additions & 11 deletions code/game/turfs/turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -195,16 +195,22 @@
// First, make sure it can leave its square
if(isturf(mover.loc))
// Nothing but border objects stop you from leaving a tile, only one loop is needed
for(var/obj/obstacle in mover.loc)
if(!obstacle.CheckExit(mover, src) && obstacle != mover && obstacle != forget)
// This as anything looks odd, since we check istype shortly after, but it's so we can save an istype check for items, which are far more common than other objects.
for(var/obj/obstacle as anything in mover.loc)
if(isitem(obstacle) || !istype(obstacle) || obstacle == mover || obstacle == forget)
continue
if(!obstacle.CheckExit(mover, src))
mover.Bump(obstacle, TRUE)
return FALSE

var/list/large_dense = list()
//Next, check objects to block entry that are on the border
for(var/atom/movable/border_obstacle in src)
// Next, check for border obstacles on this turf
// Everyting inside a turf is an atom/movable.
for(var/atom/movable/border_obstacle as anything in src)
if(isitem(border_obstacle) || border_obstacle == forget || isnull(border_obstacle))
continue
if(border_obstacle.flags & ON_BORDER)
if(!border_obstacle.CanPass(mover, mover.loc, 1) && (forget != border_obstacle))
if(!border_obstacle.CanPass(mover, mover.loc, 1))
mover.Bump(border_obstacle, TRUE)
return FALSE
else
Expand All @@ -215,14 +221,15 @@
mover.Bump(src, TRUE)
return FALSE

//Finally, check objects/mobs to block entry that are not on the border
// Finally, check objects/mobs that block entry and are not on the border
var/atom/movable/tompost_bump
var/top_layer = FALSE
for(var/atom/movable/obstacle in large_dense)
if(!obstacle.CanPass(mover, mover.loc, 1) && (forget != obstacle))
if(obstacle.layer > top_layer)
tompost_bump = obstacle
top_layer = obstacle.layer
for(var/atom/movable/obstacle as anything in large_dense)
if(obstacle.layer <= top_layer)
continue
if(!obstacle.CanPass(mover, mover.loc, 1))
tompost_bump = obstacle
top_layer = obstacle.layer
if(tompost_bump)
mover.Bump(tompost_bump, TRUE)
return FALSE
Expand Down
47 changes: 24 additions & 23 deletions code/modules/atmospherics/machinery/datum_pipeline.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@

/datum/pipeline/Destroy()
SSair.pipenets -= src
var/datum/gas_mixture/ghost = null
if(air && air.volume)
temporarily_store_air()
ghost = air
air = null
for(var/obj/machinery/atmospherics/pipe/P in members)
if(QDELETED(P))
continue
P.ghost_pipeline = ghost
P.parent = null
for(var/obj/machinery/atmospherics/A in other_atmosmch)
A.nullifyPipenet(src)
Expand All @@ -28,13 +33,14 @@

/datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/base)
var/volume = 0
var/list/ghost_pipelines = list()
if(istype(base, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/E = base
volume = E.volume
members += E
if(E.air_temporary)
air = E.air_temporary
E.air_temporary = null
if(E.ghost_pipeline)
ghost_pipelines[E.ghost_pipeline] = E.volume
E.ghost_pipeline = null
else
addMachineryMember(base)
if(!air)
Expand All @@ -59,15 +65,26 @@
volume += item.volume
item.parent = src

if(item.air_temporary)
air.merge(item.air_temporary)
item.air_temporary = null
if(item.ghost_pipeline)
if(!ghost_pipelines[item.ghost_pipeline])
ghost_pipelines[item.ghost_pipeline] = item.volume
else
ghost_pipelines[item.ghost_pipeline] += item.volume
item.ghost_pipeline = null
else
P.setPipenet(src, borderline)
addMachineryMember(P)

possible_expansions -= borderline

for(var/datum/gas_mixture/ghost in ghost_pipelines)
var/collected_ghost_volume = ghost_pipelines[ghost]
var/collected_fraction = collected_ghost_volume / ghost.volume

var/datum/gas_mixture/ghost_copy = new()
ghost_copy.copy_from(ghost)
air.merge(ghost_copy.remove_ratio(collected_fraction))

air.volume = volume

/datum/pipeline/proc/addMachineryMember(obj/machinery/atmospherics/A)
Expand Down Expand Up @@ -114,22 +131,6 @@
/obj/machinery/atmospherics/pipe/addMember(obj/machinery/atmospherics/A)
parent.addMember(A, src)

/datum/pipeline/proc/temporarily_store_air()
//Update individual gas_mixtures by volume ratio

for(var/obj/machinery/atmospherics/pipe/member in members)
member.air_temporary = new
member.air_temporary.volume = member.volume

member.air_temporary.set_oxygen(air.oxygen() * member.volume / air.volume)
member.air_temporary.set_nitrogen(air.nitrogen() * member.volume / air.volume)
member.air_temporary.set_toxins(air.toxins() * member.volume / air.volume)
member.air_temporary.set_carbon_dioxide(air.carbon_dioxide() * member.volume / air.volume)
member.air_temporary.set_sleeping_agent(air.sleeping_agent() * member.volume / air.volume)
member.air_temporary.set_agent_b(air.agent_b() * member.volume / air.volume)

member.air_temporary.set_temperature(air.temperature())

/datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity)
var/datum/milla_safe/pipeline_temperature_interact/milla = new()
milla.invoke_async(src, target, share_volume, thermal_conductivity)
Expand Down
7 changes: 5 additions & 2 deletions code/modules/atmospherics/machinery/pipes/pipe.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/obj/machinery/atmospherics/pipe
var/datum/gas_mixture/air_temporary //used when reconstructing a pipeline that broke
var/datum/gas_mixture/ghost_pipeline // used when reconstructing a pipeline that broke
var/datum/pipeline/parent
var/volume = 0
force = 20
Expand All @@ -23,7 +23,10 @@

/obj/machinery/atmospherics/pipe/Destroy()
var/turf/T = get_turf(src)
T.blind_release_air(air_temporary)
if(ghost_pipeline)
var/datum/gas_mixture/ghost_copy = new()
ghost_copy.copy_from(ghost_pipeline)
T.blind_release_air(ghost_copy.remove(volume / ghost_pipeline.volume))

for(var/obj/machinery/atmospherics/meter/meter in T)
if(meter.target == src)
Expand Down

0 comments on commit fb93e5a

Please sign in to comment.