ID:1277723
 
(See the best response by Pirion.)
I'm trying to make a spell that creates a ball that follows the User, increasing some state.

This spell must be active for 20 seconds and then disappear. But it can be used up to 5 times, creating five balls, and each use must reset the counter, leaving it active for another 20 seconds every use.

Problem description:

I have no idea how to make a stackable counter that would delete all balls when run out.

If anyone can give me a tip I appreciate.
Best response
Create a datum that handles these balls.

Have the datum create a balls and set the timer to 20. Let this happen as long as balls > 5.

Have a loop decrement the timer, and then delete the balls when it expires.

In response to Pirion
    verb
SummonBall()
if(usr.cont >= 5)
return
else
B = new (usr.loc)
B.icon='energyball.dmi'
usr.cont++
usr.btime += 20
while(usr.btime>0)
sleep(10)
usr.btime--
if(usr.btime==0)
usr<<"[usr.btime]"
Die()


do not know if I did it right. But it is working.

Thanks Pirion
In response to Kewerson93
That's not a datum.
In response to A.T.H.K
What exactly i need to do?
You could use what you currently have in theory. However you will want to make a check at the:

usr.btime += 20


because with that it will add 20, so if you added 5 really quickly the timer will be 100 seconds and not reset the counter.

You could use an obj instead of a datum for the balls, depends on if they will move, how much control you want over their features, etc... If you don't plan to have them move, and just want them to be an overlay type of effect then use a datum as such:

datum
ball

(more code here)


or you could use an obj:

obj
ball
icon = 'energyball.dmi'
var
bTime = 20 //Make it so the ball controls the
//timer so you could make it
//slowly go away instead of all
//at once.
mob
owner
proc
BallTick()
while(btime>0)
sleep(10)
btime--
if(btime==0)
owner<<"[btime]"
Die()
New(mob/m)
owner = m
src.loc = owner.loc
BallTick() //Starts the tick once the ball is
//created
(any other code you need here)
..()

This would make each ball its own individual thing, and because it is an object it can still do things like an object, such as move.

This may work better because say each ball gives the player a buff than now you can refer to the owner in the New() definition to point to the owner's stats.

The above code may be buggy, and will probably not work from what is up there. It is meant to show an example and point you to another possibility.








In response to Akando5959
What New(mob/m) will do?

I am using the var cont to increase the status. I can do it a better way?
mob/m is an argument. This means that the New() proc of the object is expecting something to be passed into it.

In this case we have to change the verb for the player to:

verb
SummonBall()
new /obj/ball(src)


So whoever uses this verb will be the owner (from previous code) of the ball obj and their stats will be the one effected by created ball.

Well because we have made a new obj that refrences to the player that used it we could in theory change the obj's New Proc to:

  New(mob/m)
owner = m
src.loc = owner.loc
BallTick() //Starts the tick once the ball
// is created

(any other code you need here)
..()


Rough idea, I have to go to work so I can try to illaborate later.
Sorry, just a nit pick here!

Naming a looping proc "tick" is dangerous... Because it says it will tick, but not that it will loop. I much more prefer this design...

Thing
var/ticks = 0
proc/tick()
//this is where I get to do some processing
ticks++
proc/tick_loop()
while(src)
tick_loop()
sleep(world.tick_lag)


Having a proc named Tick which starts a loop is misleading.
creating a datum to handle this can be done in the following way:

ball_spell
var lifespan, list/balls, mob/owner

New(o)
owner = o
create_ball()
spawn(0)
tick() //start the timer
..()

proc/create_ball() //create the ball
if(balls.len > 5)
var/obj/magicball/magicball = new(owner)//set the ball to follow in ball logic.
balls += magicball
lifespan = 20 //set lifespan back to 20.

proc/tick() //here is our counter
while(lifespan--)
sleep(100)
del src

Del() //cleanup
for(var/obj/o in balls)
del o
..()