ID:141483
 
Code:
        Revive_world()
set category = "GM"
for(var/mob/PC/M in world)
if(M.dead)
if(!M.pk)
M.powerlevel = M.powerlevel_max
M.overlays -= M.halo
M.overlays -= halo
M.overlays -= M.halo
M.overlays -= halo
M.loc = locate(67,42,1)
M.safe = 1
M.dead = 0
M.charging = 0
M.charging1 = 0
world<<"[usr] is reviving people"
sleep(300)
if(!M)return
M.safe = 0
else
M.powerlevel = M.powerlevel_max
M.overlays -= M.halo
M.overlays -= halo
M.overlays -= M.halo
M.overlays -= halo
M.loc = locate(54,175,1)
M.safe = 1
M.dead = 0
world<<"[usr] is reviving people"
sleep(300)
if(!M)return
M.safe = 0


Problem description:
Alright some of you can probably spot similarities in the vars but thats not the point.

I got stuck at the point why for(var/mob/PC/M in world) doesnt affect all PC mobs at once. I have to keep clicking the verb. Same happened to my bomb verb(which is currently a disabled project) it explodes but only kills one person...
The if(!M) return part is your problem, it's causing the loop to stop. What you want is
if(!M) continue


Which will make the loop continue without reaching the code below the usage. You'll also want to add a spawn() somewhere in the loop if you want the action happening to everyone all at once, otherwise it happens to them one at a time as the loop goes through the mobs.
In response to Nadrew
i see...

i never used the continue verb before but now i see. So its like skipping if not a mob and continuing the loop. Unlike return which stops it.


Thats helpful thanks :)
In response to Nadrew
obj
radio
name = "Bomb drop radio"
icon = 'bomb.dmi'
icon_state = "radio"
verb
drop_bomb(varX as num, varY as num, varZ as num)
set name = "radio"
set category = "Actions"
set desc = "X,Y,Z"
if(varX > world.maxx) // if the number they put in is higher than the map's highest point make it go as close as it can, that way they dont go off map and have to relog
src.x = world.maxx
else
if(varX < 1) // if its less than one go to one since you cant have negative map points
src.x = 1
if(varY > world.maxy)
src.y = world.maxy
else
if(varY < 1)
src.y = 1
if(varZ > world.maxz)
src.z = world.maxz
else
if(varZ < 1)
src.z = 1
var/obj/bigassbomb/B = new/obj/bigassbomb
B.overlays += new /obj/Overlays/big_bomb
B.loc = locate(varX,varY+3,varZ)
sleep(5)
B.loc = locate(varX,varY+2,varZ)
sleep(5)
B.loc = locate(varX,varY+1,varZ)
sleep(5)
B.loc = locate(varX,varY,varZ)
Explode(new /Effect/BasicBoom(B.loc,1,4))
for(var/mob/M in view(B,4))
M.hp -= 100 - M.defence
usr.deathcheck2(M)
del(B)
del(src)


how about this. Ive been thinking why this only kills 1 player and the bomb dropped doesnt even dissapear. I spent a lot of time trying to fix this
In response to Gogeta126
Why would you modify the variables of the radio based on the varX and varY and varZ variables when you're using those to carry out the procedure? Look at min() and max().

varX = min(world.maxx, max(1, varX))
varY = min(world.maxy, max(1, varY))
varZ = min(world.maxz, max(1, varZ))


Not that there is anything wrong with your way, this just looks cleaner (and may be a tad bit faster, I'm not certain). If that doesn't explain why your bomb may not be showing, then you may have a bomb with no icon. You know that it will only show for about 1.5 seconds, right?

Additionally, a for() loop for bomb movement may be cleaner. You want to use obj.Move() to handle object movement, especially if the bomb is dense or there are special tiles that get rid of the bomb or something. If the bomb is an aerial attack, don't make it dense. That way, dense objects do not stop it and it allows us to use obj.Move() for things later, such as catching a bomb and destroying it.

var/obj/bigassbomb/B = new
B.overlays += new/obj/Overlays/big_bomb
for(var/i=3 to 1 step -1)
if(!B) return // in case of bomb defenses
B.Move(locate(varX, varY+i, varZ), SOUTH)
sleep(5)
if(!B) return
B.Move(locate(varX, varY, varZ), SOUTH)
Explode(new /Effect/BasicBoom(B.loc,1,4))


Now, what I expect to be the culprit of the bomb not disappearing (I thought it said "appear" so I was focusing my entire post around that, still the extra information doesn't hurt) is usr.deathcheck2(M). It probably takes too long to finish. Is it even in the right order? Shouldn't you be checking M for Death and send usr as the killer?

Anyway, we'll have to spawn() off the deathcheck() procedure unless you can make it faster (AKA near-instant). The bomb should be deleted after the explosion, so it doesn't matter if we don't place any mechanisms to keep the stuff out of the loop from happening at the end of the procedure.

for(var/mob/M in view(B, 4))
M.hp -= (100 + M.defense) // minus to two values combined
spawn() usr.deathcheck2(M)
del(B)
del(src)


So, the entire code should look something like this:
obj/radio/verb/drop_bomb(varX as num, varY as num, varZ as num)
set name = "radio"
set category = "Actions"
varX = min(world.maxx, max(1, varX))
varY = min(world.maxy, max(1, varY))
varZ = min(world.maxz, max(1, varZ))
var/obj/bigassbomb/B = new
B.overlays += new/obj/Overlays/big_bomb
for(var/i=3 to 1 step -1)
if(!B) return // in case of bomb defenses
B.Move(locate(varX, varY+i, varZ), SOUTH)
sleep(5)
if(!B) return
B.Move(locate(varX, varY, varZ), SOUTH)
Explode(new /Effect/BasicBoom(B.loc,1,4))
for(var/mob/M in view(B, 4))
M.hp -= (100 + M.defense) // minus to two values combined
spawn() usr.deathcheck2(M)
del(B)
del(src)
In response to CaptFalcon33035
Dear Mr. CaptFalcon33035

Thank you for your help. I will be sure to use this knowledge in my future coding.
In response to CaptFalcon33035
Of course, no deathcheck() will be run because src is deleted before any can execute. But it's a pretty silly matter to spawn() off such calls in the first place; you don't need to worry about arbitrarily procs taking too long unless there is something Very Wrong in them or there is some bad out of place sleeping function there (where that proc would be what needs to be changed, possibly spawn()ing off the sleeping function itself depending on circumstances).
In response to Kaioken
Kaioken wrote:
Of course, no deathcheck() will be run because src is deleted before any can execute.

No, it will. Test it out. spawn() doesn't place the block within it under the control of anything but the direct stack, so when the parent procedure gets killed, the block within the spawn() statement doesn't.

But it's a pretty silly matter to spawn() off such calls in the first place; you don't need to worry about arbitrarily procs taking too long unless there is something Very Wrong in them or there is some bad out of place sleeping function there (where that proc would be what needs to be changed, possibly spawn()ing off the sleeping function itself depending on circumstances).

That's the idea behind it all. Still, using spawn() is not such a bad idea when you want something to affect all things at once (or as close as possible to at once).
In response to CaptFalcon33035
CaptFalcon33035 wrote:
No, it will. Test it out. spawn() doesn't place the block within it under the control of anything but the direct stack, so when the parent procedure gets killed, the block within the spawn() statement doesn't.

A spawned thread still retains all the properties of the original proc. This includes local vars and the src var, too. Therefore such a thread is killed (or "unscheduled") when src is deleted all the same for 'safety', and the thread is still object-oriented and depends on the object not being deleted to exist unless src is nulled out.

But it's a pretty silly matter to spawn() off such calls in the first place; you don't need to worry about arbitrarily procs taking too long [...]
That's the idea behind it all.

Then why did you spawn() off the proc call if the idea is that you shouldn't be worrying about that call taking too long? >_>

Still, using spawn() is not such a bad idea when you want something to affect all things at once (or as close as possible to at once).

Actually I think it can be, but that is a general statement which depends on context (where and how spawn() is used). It could actually potentially cause the execution not to happen at once, because it splits it out into different queued threads, which might not execute consequentially and might incur a delay causing whatever you want happening 'all at once' to take more than 1 tick. This is not necessarily likely and is said relatively to not using spawn(): in that case, you can be sure all your statements execute one after another consequentially, and there is no room for them not to execute "at once"/consequentially and they will execute at the same tick unless a slow (or sleeping) operation is taking place somewhere along the line.
In response to Kaioken
Kaioken wrote:
Then why did you spawn() off the proc call if the idea is that you shouldn't be worrying about that call taking too long? >_>

Because telling him to fix his deathcheck() won't be doing him much good in the short run, so he will return saying "omg you guys are no help" because if we can't provide a good solution for the immediate problem, what help will we be when things get a little more complicated (at least to him)?

By providing a solution and suggesting that deathcheck() is taking too long to execute (which I did), he is more likely to consider our other suggestions. It's all very simple, you see.

Still, using spawn() is not such a bad idea when you want something to affect all things at once (or as close as possible to at once).

Actually I think it can be, but that is a general statement which depends on context (where and how spawn() is used). It could actually potentially cause the execution not to happen at once, because it splits it out into different queued threads, which might no execute consequentially and might incur a delay causing whatever you want happening 'all at once' to take more than 1 tick. This is not necessarily likely and is said relatively to not using spawn(): then you can be sure all your statements execute one after another consequentially, and there is no room for them not to execute "at once"/consequentially/at the same tick unless a slow (or sleeping) operation is taking place somewhere along the line.

spawn() does nothing with threads and the execution will never be at once, but using spawn() allows us to do it as close as possible. No significant delay is incurred due to utilizing the main stack which is the main road for DM execution. And what, did you think BYOND did nothing while statements were sleeping? It executes other things while other procedures sleep.
In response to CaptFalcon33035
CaptFalcon33035 wrote:
Because telling him to fix his deathcheck() won't be doing him much good in the short run,

Uh, when something else is possible, why give less effective advice that helps short-term rather than long-term on purpose? Whether he decides to take the help or not is more of his problem. Though you're also free to give any help you want.

spawn() does nothing with threads

It schedules a new thread with the statements indented under it to run after a delay. That's the entire point seeing as if it ran in the current thread it would happen before the rest of the statements there, so it will still have to wait for it to finish.

and the execution will never be at once, but using spawn() allows us to do it as close as possible.

Uh, no. Calling a proc directly after another proc call without any spawn()ing involved runs both procs 'as close as possible' to each other, this should be obvious. The difference isn't significant, of course.

And what, did you think BYOND did nothing while statements were sleeping? It executes other things while other procedures sleep.

Obviously, otherwise whenever you sleep the game would be frozen. I was referring to the current proc (and therefore proc chain, ie the proc's caller) being frozen and doing nothing while something sleeps. For example, referring to a possible sleep() in Deathcheck() that causes the proc with the for() loop to wait (and so I said so if you fix such a sleep() f.ex., you don't need to spawn() the call to Deathcheck()).

BTW, making sure you understand whenever you agree with this or not, the fact stands the Deathcheck() calls won't actually run because src is deleted and all, which could be a little problematic. :P Of course, you're free to test it like you've told me to, hehe.
In response to Kaioken
Kaioken wrote:
Uh, when something else is possible, why give less effective advice that helps short-term rather than long-term on purpose? Whether he decides to take the help or not is more of his problem. Though you're also free to give any help you want.

Was there any reason to ask this at all? I answered this with the last post. I am trying to be effective as possible (and your argument with me should help should he revisit this thread).

It schedules a new thread with the statements indented under it to run after a delay. That's the entire point seeing as if it ran in the current thread it would happen before the rest of the statements there, so it will still have to wait for it to finish.

Are we thinking of the same "thread" here? You might be referring to thread of commands or thread of execution or something, whereas I am referring to actual CPU-related threads that most people seem to refer to on these threads. If that's the case, I will admit there was a misunderstanding on my part. If that is not the case, BYOND uses a stack and when you use spawn(), that block of code is added to the stack to await execution.

Uh, no. Calling a proc directly after another proc call without any spawn()ing involved runs both procs 'as close as possible' to each other, this should be obvious. The difference isn't significant, of course.

I think you knew what I meant here. When you run a procedure from a parent without using spawn(), the parent has to wait for that procedure to return before it can continue it's own execution. When you use spawn(), it places all of the procedures on the stack and they can each execute while one procedure sleeps (which, of course, is ideal for his slow deathcheck() procedure here). Again, this is simple stuff and it should not have been hard to figure this out--rather you do that then think that every way that isn't you way is wrong.

Obviously, otherwise whenever you sleep the game would be frozen. I was referring to the current proc (and therefore proc chain, ie the proc's caller) being frozen and doing nothing while something sleeps. For example, referring to a possible sleep() in Deathcheck() that causes the proc with the for() loop to wait (and so I said so if you fix such a sleep() f.ex., you don't need to spawn() the call to Deathcheck()).

A possibility indeed, but not a certainty. Enough has been said for him to have realized that his deathcheck() procedure is a bit on the slow side from my original post. And that's all that needs to have been said. A non-terminated loop could also be the culprit.

BTW, making sure you understand whenever you agree with this or not, the fact stands the Deathcheck() calls won't actually run because src is deleted and all, which could be a little problematic. :P Of course, you're free to test it like you've told me to, hehe.

You're probably confusing src with usr here. src is needed for no calls to deathcheck() in his procedure. I do disagree with you, but you are MOST certainly incorrect here. See for yourself.

test_datum
New()
spawn() loop_five()
sleep(5)
del(src)
Del()
world << "I IS GONE"
..()

proc/loop_five()
for(var/i=1 to 5)
world << i
sleep(5)
In response to CaptFalcon33035
test_datum
New()
spawn() loop_five()
sleep(5)
del(src)
Del()
world << "I IS GONE"
..()

proc/loop_five()
for(var/i=1 to 5)
world << i
sleep(5)


Well, I feel like an ass. If you can get those calls down before src is deleted, they continue working, but that's not the same as when they aren't executed before src is deleted. You outwit me once again.