I swear something in the 1.08 patch is broken
So... This is a kinda serious bug, I've posted about it moooonths ago, but now it's really starting to get on my nerves and I was hoping someone knew a workaround for it.
Suppose you have a loop in your main procedure for a sprite. Now, let that sprite have a hit or talk procedure as well. When Dink talks or punches the sprite, the main procedure abrubtly ends ANYTHING it was doing and won't return to it. A good example of why this is a huge problem is the enemy missile script or even the original dragons in Dink! These scripts work by constantly calling procedures in a loop, at random times, to fire missiles at Dink or activate magic attacks. But, just try it, once you hit them or talk to them (and a hit/talk procedure exists) the whole script will cease to function. Insanely annoying.
So anyway, the thing I want to do is have a sprite walk from left to right and back again constantly and when you talk to it, it says something (normal say command). So in the main procedure I have a very simple move_stop() loop. But, as I explained, it will instanly stop when I talk to the sprite.
Hope anyone has a way to make this work without using a seperate script to control the movement from the sprite. Actually, I really really need this whole mess sorted out for boss and complicated enemy scripts anyway.
Suppose you have a loop in your main procedure for a sprite. Now, let that sprite have a hit or talk procedure as well. When Dink talks or punches the sprite, the main procedure abrubtly ends ANYTHING it was doing and won't return to it. A good example of why this is a huge problem is the enemy missile script or even the original dragons in Dink! These scripts work by constantly calling procedures in a loop, at random times, to fire missiles at Dink or activate magic attacks. But, just try it, once you hit them or talk to them (and a hit/talk procedure exists) the whole script will cease to function. Insanely annoying.
So anyway, the thing I want to do is have a sprite walk from left to right and back again constantly and when you talk to it, it says something (normal say command). So in the main procedure I have a very simple move_stop() loop. But, as I explained, it will instanly stop when I talk to the sprite.
Hope anyone has a way to make this work without using a seperate script to control the movement from the sprite. Actually, I really really need this whole mess sorted out for boss and complicated enemy scripts anyway.
It is kinda annoying sometimes... I work around it by jumping back to the loop via a goto loop in the talk procedure after he's said whatever, or by using a seperate script like you said
It's even worse than I thought. You just talk to a sprite that's moving EVEN when it's ordered to from another script and BAM, he stops moving.
I've used goto jumps to solve it in the past, but in this case it's impossible to know where it should jump back to inside the loop, because multiple things are going on.
I've used goto jumps to solve it in the past, but in this case it's impossible to know where it should jump back to inside the loop, because multiple things are going on.
In the bosses in three amulets I did that, made the script jump back to the loop when hitting or talking. This however will cause another problem, if you have a wait command before the thing the loop is doing, for example moving the sprite, it will slow down if you spam talk key and if the wait is long enough it will stop as it will redo the wait everytime you interupt the script. If you have the wait after the thing the loop is going to do it will do it faster if you spam a key.
The easiest way to minimize this problem without using global variables and/or external scripts is to divide the wait into two parts and do one before and one after.
I would tell you to check out the scripts for the octopus and tree boss in Three Amulets but those scripts are just a mess and can't be followed by anyone. I'm surprised myself that they work XD
EDIT:
Keep the loops as short as possible and use other sprites on the screen for the loops when possible.
The easiest way to minimize this problem without using global variables and/or external scripts is to divide the wait into two parts and do one before and one after.
I would tell you to check out the scripts for the octopus and tree boss in Three Amulets but those scripts are just a mess and can't be followed by anyone. I'm surprised myself that they work XD
EDIT:
Keep the loops as short as possible and use other sprites on the screen for the loops when possible.
If you want a sprite to walk from left to right and back again you should check out crystal of the gu.
If you don't want your loops to be interrupted you should have them in a separate script. You could spawn a script upon entering the screen that moves the sprite for example.
If you don't want your loops to be interrupted you should have them in a separate script. You could spawn a script upon entering the screen that moves the sprite for example.
Nope Erwin, even then, talking to the sprite will interrupt the movement instantly. It sucks, but I'll probably just have to learn to work around it as much as possible. Thanks for the fast replies
Nevermind. Not working as I remembered.. Perhaps it's just move that's acting weird.
After some testing...
If you hit the guy, he will continue saying blah...
If you hit the guy, he will still move and say blah...
If you hit the guy, he will stop where he is and will no longer say blah meaning the loop has been broken.
If you hit the guy, he will stop for a little, then go to the next direction from where he's standing. The loop will continue
So summed up, if you talk to the npc while he's using move_stop() the movement and the loop will both be terminated. On the other hand, if you use just move, only the current movement will be stopped and the loop will continue on.
You can overcome the stops by doing this.
If you hit the guy, he will continue saying blah...
//external script called @ end of main proc void extloop () { loop: wait(20); say("`3 Blahblahblah",¤t_sprite); goto loop; }
If you hit the guy, he will still move and say blah...
//external script called @ end of main proc void extloop () { loop: wait(20); say("`3 Blahblahblah",¤t_sprite); move(¤t_sprite,4,20,1); goto loop; }
If you hit the guy, he will stop where he is and will no longer say blah meaning the loop has been broken.
//external script called @ end of main proc void extloop () { loop: wait(20); say("`3 Blahblahblah",¤t_sprite); move_stop(¤t_sprite,4,20,1); goto loop; }
If you hit the guy, he will stop for a little, then go to the next direction from where he's standing. The loop will continue
//external script called @ end of main proc void extloop () { loop: move(¤t_sprite,4,200,1); wait(2000); move(¤t_sprite,6,400,1); wait(2000); goto loop; }
So summed up, if you talk to the npc while he's using move_stop() the movement and the loop will both be terminated. On the other hand, if you use just move, only the current movement will be stopped and the loop will continue on.
You can overcome the stops by doing this.
void extloop () { loop1: wait(20); &save_x = sp_x(¤t_sprite,-1); if (&save_x > 200) { move(¤t_sprite,4,200,1); goto loop1; } loop2: wait(20); &save_x = sp_x(¤t_sprite,-1); if (&save_x < 400) { move(¤t_sprite,6,400,1); goto loop2; } goto loop1; }
That's some very interesting testing, thanks for that. I assume all of that only counts as long as the script is external then? But that would be a much better method than spawning new scripts all the time to take care of it still. Definitely gonna look further into this, maybe try to fix some of the enemy missile scripts.
Yeah, that's using external(). Loops will still be broken if they are placed in the enemy script itself, and using spawn would require more work/vars to keep track of the enemy number.
Hey Kyle,
I am only a noob, and see that your knowledge o DinkC is way beyond mine,so please forgive me if my suggestions are uneducated.
Sometimes basics are all that is needed.
might seem simplistic but..
based on this:-
"So anyway, the thing I want to do is have a sprite walk from left to right and back again constantly and when you talk to it, it says something (normal say command)."
I have a guard sprite who walks left to right(Brain 10 I think)hemmed in by invisible hard sprites(fences).
walks back and forth talks
normal( over the fence) talk void talk
//modified
Oh thats only the talky bit.
I have not used the say command.I reckon it would work.
I am only a noob, and see that your knowledge o DinkC is way beyond mine,so please forgive me if my suggestions are uneducated.
Sometimes basics are all that is needed.
might seem simplistic but..
based on this:-
"So anyway, the thing I want to do is have a sprite walk from left to right and back again constantly and when you talk to it, it says something (normal say command)."
I have a guard sprite who walks left to right(Brain 10 I think)hemmed in by invisible hard sprites(fences).
walks back and forth talks
normal( over the fence) talk void talk
//modified
Oh thats only the talky bit.
I have not used the say command.I reckon it would work.
Hey Fairdinkum,
I'm afraid the "walks from left to right" was just meant as a simple example of the bug that plagues the 1.08 patch, not literally what I needed
But, thanks for trying to help with that, it doesn't matter how basic a suggestion is, DinkC benefits equally from the most complicated scripts as well as the most basic workarounds
I'm afraid the "walks from left to right" was just meant as a simple example of the bug that plagues the 1.08 patch, not literally what I needed
But, thanks for trying to help with that, it doesn't matter how basic a suggestion is, DinkC benefits equally from the most complicated scripts as well as the most basic workarounds
Hmm, the same (or a similar) thing happens with set_callback_random(). If there is a wait in the called procedure then the whole callback stops happening... I have a script with two callbacks happening at once and if either of them have a wait in then they both stop running.
It's basically the same as using a wait, so if another procedure is called before the wait is up, it's never going to execute. Since using a wait in an external script works, it should provide the same results with set_callback_random().