ID:156685
 
Right now, whenever I create 3 clones, the games CPU bumps up from 0 or 1 to about 20. Here is the verb.. I'm trying to find out how to make it more efficient.

        Multiple_Shadow_Clone()
set hidden = 1
if(!src.isclone&&src.CanUse()||src.Rasengan)
if(src.Clones<6)
if(src.Chakra>=src.MC*0.75-src.Control/2)
for(var/Jutsus/MultipleShadowCloneIcon/I in usr.Jutsus)
if(!(usr.Cooldown("[I.name]",I.Cooldown*10 , I)))
src.Seals(1)
src.Chakra-=src.MC*0.75-src.Control/2
src<<"Multple shadow clone jutsu!"
src.Seals=""
src.icon_state="Tiger"
src.PlaySound('Clones.wav',0,1)
sleep(3)
src.icon_state=""
var/mob/NPC/Clone2/D=new(src.loc)
var/mob/NPC/Clone2/E=new(src.loc)
var/mob/NPC/Clone2/F=new(src.loc)
D.owner=src
E.owner=src
F.owner=src
D.Move(locate(src.x+1,src.y,src.z))
E.Move(locate(src.x-1,src.y,src.z))
F.Move(locate(src.x,src.y+1,src.z))
new/obj/Smoke(src.loc)
for(var/mob/NPC/A in oview(src))
if(A.owner==src)
if(src.Rasengan)
A.Rasengan=1
A.Gathered=src.Gathered
if(src.SageMode)
A.SageMode=1
A.Following=0
A.icon=src.icon
A.overlays+=src.overlays
A.isclone=1
A.Stamina=1
A.Chakra=src.MC
A.MC=src.MC
A.Strength=src.MSTR
A.owner=src
A.Frozen=0
A.Ally=src.Ally
A.Body=src.Body
A.Base=src.Base
A.Hair=src.Hair
A.Weapon=src.Weapon
if(src.Byakugan)
src.Byakugan=1
src.Clones+=3
return
else
src<<"You haven't enough chakra to perform this jutsu."
src.Seals=""
src.icon_state=""
return
else
src<<"You can only have a maximum of 6 shadow clones out."
return


Also here's the wander just in case the problem lies in that.

        Wander()
while(src)
if(src.Wander)
if(!src.Following&&!src.Frozen&&!src.KO)
for(var/mob/M in oview(src))
if(!(M==src.owner||M.owner==src.owner||M==src.Ally||M.KO)||src.owner==null&&!M.KO)
if(src.Aggressive&&!src.Following)
step_towards(src,M)
src.Target=M
if(M in get_step(src,src.dir))
//view(src)<<"Im gonna attack!"
src.Attack()
/*else
if(!(istype(M,/mob/NPC/Clone)))
if(prob(50)&&!src.Doing)*/

//src.Random_Jutsu()
else
..()
var/M
if(!(M in get_step(src,src.dir)))
step_rand(src)
sleep(5)
walk(src,0)
else
var/mob/A = src.owner
for(var/mob/B in view(src))
if(B==A)
walk_towards(src,B)
sleep(5)
else
return
You need to think about condensing, and proper usage. Read Tiberaths' article: "It works, so it must be right!". <s>Also, it looks like you are using sources which are of very low quality. Bleach Beyond (the Activate proc from your post on the 12th), and the owner variable, from AnimeGameDemo. These aren't good to learn off of, they are inefficient.</s>
In response to OrangeWeapons
OrangeWeapons wrote:
You need to think about condensing, and proper usage. Read Tiberaths' article: "It works, so it must be right!". Also, it looks like you are using sources which are of very low quality. Bleach Beyond (the Activate proc from your post on the 12th), and the owner variable, from AnimeGameDemo. These aren't good to learn off of, they are inefficient.

I was unaware of either of those. I've been working with the owner variable over all my time here at BYOND and the activate proc was given to me when I asked for a way to activate a hotkey. I'll be looking in Tiberaths article though. Any tips you can give me for now though?
In terms of excessive CPU usage - after a quick glance I see that you aren't sleeping in the "if(!src.Following&&!src.Frozen&&!src.KO)" code block, unless there's something in Attack().
In response to Murrawhip
Murrawhip wrote:
In terms of excessive CPU usage - after a quick glance I see that you aren't sleeping in the "if(!src.Following&&!src.Frozen&&!src.KO)" code block, unless there's something in Attack().

There's something in Attack().
In response to AbdelJN
Bah ignore this post. I pooped up.
There are quite a couple of flaws in this code snippet, so, what do you want to accomplish in detail ( plain, proper English)?

The reason I'm asking this is simple. I want to help you design code to do what you have in mind, but the problem is that right now, I would have to guess at what you assume that the code you presented should do, meaning we have two points in the communication where somebody is blindly taking assumptions. That's never a good point, so by actually elaborating on what you have in mind, you grant the volunteers trying to assist you the chance to come up with a productive response that fits your need, instead of some random stuff you likely do not even want.

Just imagine you'd be writing a functional specification for the problem (if you do not have one already), where you explain everything you're trying to tell the computer to another human instead.

Some obvious issues I see:
You could save yourself some trouble if you just kept reference to a player's clones in a list.
As you're checking multiple boolean values, I wonder if you wouldn't be better of checking a single bitflag instead.
I'm not sure why you have to loop through a 'Jutsus' list either, but there should likely be a common way to handle Chackra usage and 'Handsign display'.
Instead of hard-coding the number of clones, why not use a nice little loop and save yourself on repeating the same code three times?
And Instead of locating a turf one tile away, then using it as argument for Move, why not just step into the appropriate direction?
I'd completely redesign your 'wander' procedure as well, storing a single target and then acting according to the value of that variable, saving yourself and the server the trouble of repeatedly moving taking unnecessary actions, such as looping through every 'mob' in 'oview' and trying to move into it's direction if certain requirements are met.
In response to Schnitzelnagler
Schnitzelnagler wrote:
There are quite a couple of flaws in this code snippet, so, what do you want to accomplish in detail ( plain, proper English)?

The reason I'm asking this is simple. I want to help you design code to do what you have in mind, but the problem is that right now, I would have to guess at what you assume that the code you presented should do, meaning we have two points in the communication where somebody is blindly taking assumptions. That's never a good point, so by actually elaborating on what you have in mind, you grant the volunteers trying to assist you the chance to come up with a productive response that fits your need, instead of some random stuff you likely do not even want.

Just imagine you'd be writing a functional specification for the problem (if you do not have one already), where you explain everything you're trying to tell the computer to another human instead.

Some obvious issues I see:
You could save yourself some trouble if you just kept reference to a player's clones in a list.
As you're checking multiple boolean values, I wonder if you wouldn't be better of checking a single bitflag instead.
I'm not sure why you have to loop through a 'Jutsus' list either, but there should likely be a common way to handle Chackra usage and 'Handsign display'.
Instead of hard-coding the number of clones, why not use a nice little loop and save yourself on repeating the same code three times?
And Instead of locating a turf one tile away, then using it as argument for Move, why not just step into the appropriate direction?
I'd completely redesign your 'wander' procedure as well, storing a single target and then acting according to the value of that variable, saving yourself and the server the trouble of repeatedly moving taking unnecessary actions, such as looping through every 'mob' in 'oview' and trying to move into it's direction if certain requirements are met.


I know this is probily off topic but could you explain some more about bitflag? And how to use them in byond.

Nathan
In response to Schnitzelnagler
Schnitzelnagler wrote:
There are quite a couple of flaws in this code snippet, so, what do you want to accomplish in detail ( plain, proper English)?

The reason I'm asking this is simple. I want to help you design code to do what you have in mind, but the problem is that right now, I would have to guess at what you assume that the code you presented should do, meaning we have two points in the communication where somebody is blindly taking assumptions. That's never a good point, so by actually elaborating on what you have in mind, you grant the volunteers trying to assist you the chance to come up with a productive response that fits your need, instead of some random stuff you likely do not even want.

Just imagine you'd be writing a functional specification for the problem (if you do not have one already), where you explain everything you're trying to tell the computer to another human instead.

Yeah.. I'm sorry 'bout that. I was in a rush. What I'm trying to accomplish is three clones that will look for enemies in their view and attack them in an efficient manner. For wander, I'm trying to have the NPC wander until a nearby player comes by. Then the NPC will run towards that player and when that player is within range, start attacking them. 20% of the time that the NPC is walking towards the player, it will activate a skill from it's given Jutsus list.

Some obvious issues I see:
You could save yourself some trouble if you just kept reference to a player's clones in a list.

Seems like a good idea, I'll give it a try.

As you're checking multiple boolean values, I wonder if you wouldn't be better of checking a single bitflag instead.

I just checked that article on bitflags and I can't seem to understand how or when to use them.

I'm not sure why you have to loop through a 'Jutsus' list either, but there should likely be a common way to handle Chackra usage and 'Handsign display'.

Well I loop through the Jutsus to give the NPC an easy way to randomly choose a skill to use the Jutsus list.

Instead of hard-coding the number of clones, why not use a nice little loop and save yourself on repeating the same code three times?

I'm not sure how I can simplify it any further. I used a loop to give each clone their necessary variables.

And Instead of locating a turf one tile away, then using it as argument for Move, why not just step into the appropriate direction?

Well for Attack() it looks for players within one tile and automatically faces towards them if they are within 1 tile away from the enemy.

I'd completely redesign your 'wander' procedure as well, storing a single target and then acting according to the value of that variable, saving yourself and the server the trouble of repeatedly moving taking unnecessary actions, such as looping through every 'mob' in 'oview' and trying to move into it's direction if certain requirements are met.


Thanks :D I just altered my code and now it seems to be running much more smooth. Here is the new one:

        Wander()
while(src)
if(src.Wander)
if(!src.Following&&!src.Frozen&&!src.KO)
var/mob/M=src.Target
if(M)
//for(var/mob/M in oview(10, src))
if(get_dist(src, M)<4)
if(!(M==src.owner || M.owner==src.owner || M==src.Ally || M.KO) || src.owner==null && !M.KO)
if(src.Aggressive && !src.Following)
if(M in oview(1,src))
src.Attack()
sleep(1)
else
if(src.CanUse() && src.HasSkills && prob(20))
src.RandomJutsu()

else if(!src.movement_locked)
src.base_StepTowards(M)

else
step_rand(src)
else
for(var/mob/m in oview(8,src))
if(m!=src.owner)
src.Target=m
sleep(2)
src.icon_state="Run"
if(!src.movement_locked)
walk(src,0)
else
if(src.Following)
var/mob/A = src.owner
if((get_dist(src,A) <= 8))
if(!src.movement_locked)
walk_towards(src,A)
sleep(2)
else
return
sleep(2)