ID:2124093
 
(See the best response by Reformist.)
Code:
Object
Items
var
slot = ""
in_slot = ""
stack_size = 99

count = 1
description = ""
cost = 0

overlay_icon = null
overlay_state = ""
overlay_layer = 1

map_icon = null
map_state = ""

owner
capturing

New(atom/a, quantity = null)

if(isnum(a))
quantity = a
a = null

..(a)

if(!isnull(quantity))
count = quantity
Click()
if(src in usr.contents)
use()
else
return

proc
use(mob/m)

Pokeballs
icon = 'Items.dmi'
map_icon = 'Pokeballs.dmi'
var/catch_multi
var/catch_multi2
isbeingused

Pokeball
name = "Pokeball"
description = "Standard ball used to capture Pokemon"
icon_state = "pokeball"
map_state = "pokeball"
catch_multi = 1
density = 1

bound_x = 6
bound_y = 5
bound_width = 6
bound_height = 6

use()
var
mob/user = usr
Object/Items/Pokeballs/Pokeball/Ball = new()

Ball.owner = user
count -= 1
Ball.icon = map_icon
Ball.icon_state = map_state

Ball.loc = user.loc
Ball.dir = user.dir
Ball.step_x = user.step_x
Ball.step_y = user.step_y

if(Ball.dir == NORTH)
Ball.y += 1
if(Ball.dir == SOUTH)
Ball.y -= 1
if(Ball.dir == EAST)
Ball.x += 1
if(Ball.dir == WEST)
Ball.x -= 1

var/Pokemon/target = PokeballProjectile(user,Ball,8,1.5)

if(target)
target.canmove = 0
flick("[Ball.name] return",Ball)
Ball.icon_state = "[Ball.name] catching"
target.icon_state = "invisible"
if(target.number == "003"||target.number == "006"||target.number == "009"||target.number == "012"||target.number == "018"||target.number == "019"||target.number == "020")
target.underlays -= /obj/ShadowP1
else
target.underlays -= /obj/ShadowP

spawn(15)
target.Capture(target, Ball)
if(count == 0)
user.contents -= src
del(src)




proc/PokeballProjectile(mob/P, Object/Items/Pokeballs/O, distance, delay)
while(distance > 0 && O && P)

var/mob/target
for(var/Pokemon/A in get_step(O,O.dir))
if(A&&A!=P&&ismob(A))
target=A
step(O,O.dir)
spawn(delay)

distance--
if(target) return target

Pokemon
proc
Capture(Pokemon/target, Object/Items/Pokeballs/ball)


var/mob/user = ball.owner
var/capturerate = round(((target.capturerate/target.HP)+user.Trainer_Level/target.level)* ball.catch_multi)

if(prob(capturerate))
target.loc = user.PokemonBag
user.PokemonBag += target
target.owner = user
target.realowner = user
target.caughtwith = ball.name
user.PokemonOwned += 1
user << "Congratulations you have caught a [target.name]!"
target.hasowner = 1
target.icon_state = target.number
if(target.number == "003"||target.number == "006"||target.number == "009"||target.number == "012"||target.number == "018"||target.number == "019"||target.number == "020")
target.underlays -= /obj/ShadowP1
else
target.underlays -= /obj/ShadowP

else
target.icon_state = target.number
if(target.number == "003"||target.number == "006"||target.number == "009"||target.number == "012"||target.number == "018"||target.number == "019"||target.number == "020")
target.underlays -= /obj/ShadowP1
else
target.underlays -= /obj/ShadowP
user << "[target.name] has broke free!"

target.canmove = 1
del(ball)


Problem description:

Okay so I've been stuck for a few days now, some parts of this like the target shadow underlays will be taken out soon but they are there just for the time being, but my problem is that the spawn(15) sequence and even if I set it to sleep() it causes unimaginable lag and I honestly can't seem to find the problem and a lot of programmers I've asked haven't been able to help either so help would be really appreciated thanks.
A couple efficiency changes:

Sanity checking after spawn to avoid null reference runtime errors:
spawn(15)
if(target)
target.Capture(target, Ball)


for(var/Pokemon/A in get_step(O,O.dir))
if(A&&A!=P&&ismob(A))
target=A


Could be simplified to:

for(var/Pokemon/p in get_step(...))
if(non-catching conditions for pokemon p)
continue
return p


Side-note: No idea why you were checking if the pokemon was not the player. That should be a non-issue by design.

Additionally, instead of using del(ref), you can let the garbage collector automatically clean those up for you by setting their loc to null. However, in order for this to work, there must be no other references (variables) pointing to it. Use of del() can be costly.

But anyway, I'd like to know more about the "lag" you are experiencing. The term "lag" is so loosely used that you can never know what someone is referring to.

This is important to pinpointing a possible deeper-seated issue that may not be evident in the information provided. I don't see any thing that stands out as a major issue efficiency-wise though.
Well the second the spawn(15) is called it instantly becomes really slow, you can't move really but the animation for movement happens in well slow-mo and it'll remain this way until the spawn is over and yeah going over some of my coding to make it simpler and easier to use once I can figure out what's causing this issue, I've restarted the entire system twice
It's okay, with help from Reformist the problem has been solved, thanks anyways
What was the problem anyway (for future reference)?
In response to FKI
Best response
Something completely unrelated to the code he posted. I turned on the profiler after doing some preliminary text output debugging. Turns out when a Pokemon entered a ball its AI loop went haywire because the Pokemon couldn't move. It was creating a new instance of the AI() proc every time spawn() could be called. It ended up with an excessive number of calls in a short period.