diff --git a/code/game/pooling/atom_pool.dm b/code/game/pooling/atom_pool.dm new file mode 100644 index 00000000000..76804962fd1 --- /dev/null +++ b/code/game/pooling/atom_pool.dm @@ -0,0 +1,84 @@ + +/* +/tg/station13 /atom/movable Pool: +--------------------------------- +By RemieRichards + +Creation/Deletion is laggy, so let's reduce reuse and recycle! + +Locked to /atom/movable and it's subtypes due to Loc being a const var on /atom +being read&write on /movable due to how they... move. + +*/ + +var/global/list/GlobalPool = list() + +//You'll be using this proc 90% of the time. +//It grabs a type from the pool if it can +//And if it can't, it creates one +//The pool is flexible and will expand to fit +//The newley created atom when it eventually +//Goes into the pool + +/proc/PoolOrNew(var/get_type,var/new_loc) + if(!get_type || !new_loc) + return + + var/atom/movable/AM = GetFromPool(get_type,new_loc) + + if(!AM) + if(ispath(get_type)) + AM = new get_type (new_loc) + + if(AM) + return AM + + + +/proc/GetFromPool(var/get_type,var/new_loc) + if(!get_type || !new_loc) + return 0 + + if(isnull(GlobalPool[get_type])) + return 0 + + if(length(GlobalPool[get_type]) == 0) + return 0 + + var/atom/movable/AM = pick_n_take(GlobalPool[get_type]) + if(AM) + AM.ResetVars() + AM.loc = new_loc + return AM + return 0 + + + +/proc/PlaceInPool(var/atom/movable/AM) + if(!istype(AM)) + return + + if(AM in GlobalPool[AM.type]) + return + + AM.ResetVars() + + if(!GlobalPool[AM.type]) + GlobalPool[AM.type] = list() + + GlobalPool[AM.type] += AM + + + +/atom/movable/proc/ResetVars() + var/list/excluded = list("loc", "locs", "parent_type", "vars", "verbs", "type") + + for(var/V in vars) + if(V in excluded) + continue + + vars[V] = initial(vars[V]) + + vars["loc"] = null + + diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index e1ff0aa2a43..76aa62eda7e 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -119,13 +119,17 @@ else src.fire_delay = rand(20,100) src.shot_number = 0 - var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc ) + + var/obj/item/projectile/beam/emitter/A = PoolOrNew(/obj/item/projectile/beam/emitter,src.loc) + + A.dir = src.dir playsound(src.loc, 'sound/weapons/emitter.ogg', 25, 1) + if(prob(35)) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() - A.dir = src.dir + switch(dir) if(NORTH) A.yo = 20 diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 8d6659ff84a..e5213d7c967 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -50,10 +50,13 @@ var/forcedodge = 0 + /obj/item/projectile/proc/delete() // Garbage collect the projectiles loc = null + + /obj/item/projectile/proc/on_hit(var/atom/target, var/blocked = 0, var/hit_zone) if(!isliving(target)) return 0 if(isanimal(target)) return 0 @@ -67,8 +70,8 @@ else return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume -/obj/item/projectile/Bump(atom/A as mob|obj|turf|area) +/obj/item/projectile/Bump(atom/A as mob|obj|turf|area) if(A == firer) loc = A.loc return 0 //cannot shoot yourself @@ -120,8 +123,7 @@ permutated.Add(A) return 0 - density = 0 - invisibility = 101 + delete() return 0 return 1 @@ -141,9 +143,9 @@ delete() return kill_count-- - spawn while(src && src.loc) + spawn while(loc) if((!( current ) || loc == current)) - current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) + current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) if((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) delete() return diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index a64c3291f23..ef6596731cf 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -54,6 +54,8 @@ icon_state = "emitter" damage = 30 +/obj/item/projectile/beam/emitter/delete() //what projectiles use to set loc = null + PlaceInPool(src) /obj/item/projectile/lasertag name = "laser tag beam" diff --git a/tgstation.dme b/tgstation.dme index d95ef20d0cf..460f53f33af 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -662,6 +662,7 @@ #include "code\game\objects\structures\transit_tubes\station.dm" #include "code\game\objects\structures\transit_tubes\transit_tube.dm" #include "code\game\objects\structures\transit_tubes\transit_tube_pod.dm" +#include "code\game\pooling\atom_pool.dm" #include "code\game\turfs\simulated.dm" #include "code\game\turfs\turf.dm" #include "code\game\turfs\unsimulated.dm"