ID:174221
 
Hello y'all again.

I am trying to make a "magical" bush...basically a bush that regrows berries every 30 seconds.

I have this code so far:

obj/proc/FillBerries()
if(!src.Berries)
new/obj/Berries(src.loc)
src.Berries = 1
sleep(300)
FillBerries()

obj
var
Berries
obj
Berries
icon = 'Foliage.dmi'
icon_state = "Berries"
verb
Take_Berries()
set src in oview(1)
set category = "Other"
for(var/obj/Foliage/BerryBush/B in view(0))
B.Berries = 0
usr<<"You grab some berries!"
Move(usr)
Foliage
BerryBush
icon = 'Foliage.dmi'
icon_state = "B1"
density = 1
Berries = 1
New()
..()
FillBerries()


Now because of lag in the coding, it allows people to pick the same "berries" twice.

But more annoying is that the berries never come back!

Any help would be greatly appreciated!

~GokuSS4Neo~

Gokuss4neo wrote:
Hello y'all again.

I am trying to make a "magical" bush...basically a bush that regrows berries every 30 seconds.

I have this code so far:
obj/proc/FillBerries()
if(!src.Berries)
new/obj/Berries(src.loc)
src.Berries = 1
sleep(300)
FillBerries()
Huge problem here. Never ever loop a proc this way.

This is called recursion, and what happens is that the "old" run of the proc is put on hold to wait for the result of the new call. Get enough procs on hold like that and you get a stack overflow.

There are only two correct ways to do this: Use a while() loop, or use spawn() to call the proc again.

However, this loop is a bad idea in this case anyway; it won't regenerate the berries 30 seconds after they're picked, but rather every 30 seconds from an arbitrary point.
obj
Berries
icon = 'Foliage.dmi'
icon_state = "Berries"
verb
Take_Berries()
set src in oview(1)
set category = "Other"
for(var/obj/Foliage/BerryBush/B in view(0))
B.Berries = 0
usr<<"You grab some berries!"
Move(usr)
The reason for the double-picking here is that you never check to be sure that B.Berries is true, or even isturf(loc). A quick statement just before the for() loop would clear this right up:
if(!isturf(loc)) return
You also have a problem with the view(0), which should be view(0,src) since you're working from the berries' perspective, not the player's.

As an alternative to the FillBerries() loop, I suggest instead you simply call a proc instaed of setting B.Berries=0:
obj/Foliage/BerryBush
proc/TakeBerries()
if(!Berries) return
Berries=0
spawn(300)
if(!Berries)
Berries=1
new/obj/Berries(loc)
That should solve most of your problems.

I don't know why the berries would stop refilling after a double-pick, but whatever the reason, it should be fixable now.

Lummox JR
In response to Lummox JR
I got a bit confused while reading your post...me being a total idiot an' all.

So this is the code I have :

obj
var
Berries
obj
Berries
icon = 'Foliage.dmi'
icon_state = "Berries"
verb
Take_Berries()
set src in oview(1)
set category = "Other"
if(!isturf(loc)) return
for(var/obj/Foliage/BerryBush/B in view(0))
if(B.Berries)
B.Berries = 0
usr<<"You grab some berries!"
Move(usr)
else
Move(usr)
Foliage
BerryBush
icon = 'Foliage.dmi'
icon_state = "B1"
density = 1
Berries = 1
proc/TakeBerries()
if(!Berries) return
Berries=0
spawn(300)
if(!Berries)
Berries=1
new/obj/Berries(loc)


And it doesn't work :P

~GokuSS4Neo~
In response to Gokuss4neo
>               spawn(300)
> if(!Berries)
> Berries=1
> new/obj/Berries(loc)
>


The source code to be spawned should be indented once more.
In response to Theodis
Damn, I should've seen that! Thank you!!

~GokuSS4Neo~
In response to Gokuss4neo
Gokuss4neo wrote:
obj
Berries
icon = 'Foliage.dmi'
icon_state = "Berries"
verb
Take_Berries()
set src in oview(1)
set category = "Other"
if(!isturf(loc)) return
for(var/obj/Foliage/BerryBush/B in view(0))
if(B.Berries)
B.Berries = 0
usr<<"You grab some berries!"
Move(usr)
else
Move(usr)
You failed to follow much of what I said, and seem to have added some stuff out of the blue. Why do you have an else clause in that if(), for example? If there aren't any berries, you shouldn't do anything. That wasn't in there in your old code.

Furthermore, while you added the TakeBerries() proc to the bush, you never called it. I said not to set B.Berries=0 directly in the verb, but to call a proc (i.e., B.TakeBerries()) to do that for you. Without that the berries will never respawn.

Lummox JR