Wait() equivalent in repeatedly_execute

Started by Kinoko, Sun 05/09/2004 15:31:12

Previous topic - Next topic

Kinoko

I'm having a bit of trouble with a piece of code I'm written and I'm not sure of which direction to take it in...

Basically, I have a character that I'd like to do various actions in a loop. This is to be triggered with a GlobalInt, so I've put it in repeatedly_execute. There are a few random numbers involved to change the actions slightly but I want it to generally move in a back and forth loop between GlobalInt(9, 1) and (9, 2).

Code: ags

if (GetGlobalInt(9)==2) {
    if (randthree<2) {
      SetCharacterViewEx (MOLERAT, 21, 2, ALIGN_CENTRE);
      ccExecuteCommand (MOLERAT, 2);
      SetGlobalInt(9, 1);
      }
    else if (randthree==2) {
      SetCharacterViewEx (MOLERAT, 24, 1, ALIGN_CENTRE);
      ccExecuteCommand (MOLERAT, 3);
      SetGlobalInt(9, 1);
      }
    else if (randthree==3) {
      SetCharacterViewEx (MOLERAT, 21, 0, ALIGN_CENTRE);
      ccExecuteCommand (MOLERAT, 4);
      SetGlobalInt(9, 1);
      }
    }
  
else if (GetGlobalInt(9)==1) {
    if (randtwo<2) {
      if (randthree<2) {
        SetObjectView (0, 25);
        SetObjectPosition (0, 80, 90);
        ObjectOn(0);
        AnimateObject (0, 2, 5, 0);
        SetObjectFrame(0, 25, 3, 5);
        SetObjectPosition (0, 100, 90);
        SetObjectPosition (0, 120, 90);
        SetObjectPosition (0, 140, 90);
        SetObjectPosition (0, 160, 90);
        SetObjectPosition (0, 180, 90);
        SetObjectPosition (0, 200, 90);
        SetObjectPosition (0, 220, 90);
        SetObjectFrame(0, 25, 2, 1);
        ObjectOff(0);
        SetGlobalInt(9, 2);
        }
      else if (randthree==2) {
        SetObjectView (0, 25);
        SetObjectPosition (0, 80, 120);
        ObjectOn(0);
        AnimateObject (0, 2, 5, 0);
        SetObjectPosition (0, 100, 120);
        SetObjectPosition (0, 120, 120);
        SetObjectPosition (0, 140, 120);
        SetObjectPosition (0, 160, 120);
        SetObjectPosition (0, 180, 120);
        SetObjectPosition (0, 200, 120);
        SetObjectPosition (0, 220, 120);
        SetObjectFrame(0, 25, 2, 1);
        ObjectOff(0);
        SetGlobalInt(9, 2);
        }
      else if (randthree==3) {
        SetObjectView (0, 25);
        SetObjectPosition (0, 80, 150);
        ObjectOn(0);
        AnimateObject (0, 2, 5, 0);
        SetObjectPosition (0, 100, 150);
        SetObjectPosition (0, 120, 150);
        SetObjectPosition (0, 140, 150);
        SetObjectPosition (0, 160, 150);
        SetObjectPosition (0, 180, 150);
        SetObjectPosition (0, 200, 150);
        SetObjectPosition (0, 220, 150);
        SetObjectFrame(0, 25, 2, 1);
        ObjectOff(0);
        SetGlobalInt(9, 2);
        }
      }
    else if (randtwo==2) {
        if (randthree<2) {
        SetObjectView (0, 25);
        SetObjectPosition (0, 240, 90);
        ObjectOn(0);
        AnimateObject (0, 1, 5, 0);
        SetObjectFrame(0, 25, 3, 5);
        SetObjectPosition (0, 220, 90);
        SetObjectPosition (0, 200, 90);
        SetObjectPosition (0, 180, 90);
        SetObjectPosition (0, 160, 90);
        SetObjectPosition (0, 140, 90);
        SetObjectPosition (0, 120, 90);
        SetObjectPosition (0, 100, 90);
        SetObjectFrame(0, 25, 1, 1);
        ObjectOff(0);
        SetGlobalInt(9, 2);
        }
      else if (randthree==2) {
        SetObjectView (0, 25);
        SetObjectPosition (0, 240, 120);
        ObjectOn(0);
        AnimateObject (0, 1, 5, 0);
        SetObjectFrame(0, 25, 3, 5);
        SetObjectPosition (0, 220, 120);
        SetObjectPosition (0, 200, 120);
        SetObjectPosition (0, 180, 120);
        SetObjectPosition (0, 160, 120);
        SetObjectPosition (0, 140, 120);
        SetObjectPosition (0, 120, 120);
        SetObjectPosition (0, 100, 120);
        SetObjectFrame(0, 25, 1, 1);
        ObjectOff(0);
        SetGlobalInt(9, 2);
        }
      else if (randthree==3) {
        SetObjectView (0, 25);
        SetObjectPosition (0, 240, 150);
        ObjectOn(0);
        AnimateObject (0, 1, 5, 0);
        SetObjectFrame(0, 25, 3, 5);
        SetObjectPosition (0, 220, 150);
        SetObjectPosition (0, 200, 150);
        SetObjectPosition (0, 180, 150);
        SetObjectPosition (0, 160, 150);
        SetObjectPosition (0, 140, 150);
        SetObjectPosition (0, 120, 150);
        SetObjectPosition (0, 100, 150);
        SetObjectFrame(0, 25, 1, 1);
        ObjectOff(0);
        SetGlobalInt(9, 2);
        }
    }
} 


The CCS commands are just basic moves back and forth, but of course aren't blocking. Given that I can't use any blocking functions in repeatedly_execute (and I don't want to because this should all be happening without influencing the player character), everything just flies by and loops instantly.

Is there some way to achieve this without using a thousand SetTimer scripts between each SetObjectPosition etc? I can't have it simply move because I need the object to move to precise spots instantly.

Snarky

In the current code, you doing everything in one run through repeatedly_execute, which is called every game loop. You need to make it so it only does one step of the cycle each time it's called.

For the SetObjectPosition() lines, I would store all of the positions in arrays (you seem to have six cases, so I would use twelve arrays), and use an index into the arrays that's updated each loop. Then you write:

SetObjectPosition (0, randarray1x[index], randarray1y[index]);

Depending on what you're trying to do, you may also need to change the code so GlobalInt 9 isn't updated every loop, but only when a case is finished.

Scorpiorus

Yeah, I'm afraid you can't avoid using a timer but it is possible to simplify things a bit:

// action timer;
int timer=0;

int Objects1_Run = 0;
function Objects1() {

if (Objects1_Run) {

Ã, Ã,  Ã, Ã,  if (timer== 10)Ã,  Ã,  Ã,  Ã,  SetObjectView (0, 25);
elseif (timer== 20)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 80, 90);
elseif (timer== 30)Ã,  Ã,  Ã,  Ã,  ObjectOn(0);
elseif (timer== 40)Ã,  Ã,  Ã,  Ã,  AnimateObject (0, 2, 5, 0);
elseif (timer== 50)Ã,  Ã,  Ã,  Ã,  SetObjectFrame(0, 25, 3, 5);
elseif (timer== 60)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 100, 90);
elseif (timer== 70)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 120, 90);
elseif (timer== 80)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 140, 90);
elseif (timer== 90)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 160, 90);
elseif (timer==100)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 180, 90);
elseif (timer==110)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 200, 90);
elseif (timer==120)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 220, 90);
elseif (timer==130)Ã,  Ã,  Ã,  Ã,  SetObjectFrame(0, 25, 2, 1);
elseif (timer==140)Ã,  Ã,  Ã,  Ã,  ObjectOff(0);
elseif (timer==150)Ã,  Ã,  Ã,  Ã,  {SetGlobalInt(9, 2); timer = 0; Objects1_Run=0;} // disable itself
}

}


int Objects2_Run = 0;
function Objects2() {

if (Objects2_Run) {

Ã,  Ã, Ã,  Ã, if (timer== 10)Ã,  Ã,  Ã,  Ã,  SetObjectView (0, 25);
elseif (timer== 20)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 80, 120);
elseif (timer== 30)Ã,  Ã,  Ã,  Ã,  ObjectOn(0);
elseif (timer== 40)Ã,  Ã,  Ã,  Ã,  AnimateObject (0, 2, 5, 0);
elseif (timer== 50)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 100, 120);
elseif (timer== 60)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 120, 120);
elseif (timer== 70)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 140, 120);
elseif (timer== 80)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 160, 120);
elseif (timer== 90)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 180, 120);
elseif (timer==100)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 200, 120);
elseif (timer==110)Ã,  Ã,  Ã,  Ã,  SetObjectPosition (0, 220, 120);
elseif (timer==120)Ã,  Ã,  Ã,  Ã,  SetObjectFrame(0, 25, 2, 1);
elseif (timer==130)Ã,  Ã,  Ã,  Ã,  ObjectOff(0);
elseif (timer==140)Ã,  Ã,  Ã,  Ã,  {SetGlobalInt(9, 2); timer = 0; Objects2_Run=0;} // disable itself
}

}



function background_actions_RE() {

   if ((timer>0) && (IsGamePaused()==0)) {
   Ã, Ã,  Ã,  Ã, Ã,  Ã, Objects1();
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Objects2();
   Ã,  Ã, Ã,  Ã,  Ã,  timer++;
Ã,  Ã,  Ã,  }
}



function repeatedly_execute() {

background_actions_RE(); // executes all actions

.....
.....

else if (GetGlobalInt(9)==1) {
Ã,  Ã,  if (randtwo<2) {
Ã,  Ã,  Ã,  Ã,  ifÃ,  Ã,  Ã,  (randthree< 2) {timer=1; Objects1_Run = 1;} //start Objects1()
Ã,  Ã,  Ã,  Ã,  else if (randthree==2) {timer=1; Objects2_Run = 1;} //start Objects2()
Ã,  Ã,  Ã,  Ã,  ....

Kinoko

Oh hell, that makes things much easier, thanks. (Why can't I ever think of these methods?)

Scorpiorus

You're welcome,
Hehe, all these weird methods started to come into my mind when I thought about implementing the CCS via scripting. With the help of #defines it turned out into a mini sub-language based on the AGS script language. I tried to make parallel threading execution, processes management (each character could be consider as a standalone process) but then later it turned out to be rather slow so I gave up and wrote a plugin instead. :)

BTW, the one thing I'd do is to add the following defines:

#define START if(0) {}
#define LP    else if (timer==

So, we can have:

START
LP  10)   SetObjectView (0, 25);
LP  20)   SetObjectPosition (0, 80, 120);
LP  30)   ObjectOn(0);
LP  40)   AnimateObject (0, 2, 5, 0);
LP  50)   SetObjectPosition (0, 100, 120);
LP  60)   SetObjectPosition (0, 120, 120);
LP  70)   SetObjectPosition (0, 140, 120);
LP  80)   SetObjectPosition (0, 160, 120);
LP  90)   SetObjectPosition (0, 180, 120);
LP 100)   SetObjectPosition (0, 200, 120);
LP 110)   SetObjectPosition (0, 220, 120);
LP 120)   SetObjectFrame(0, 25, 2, 1);
LP 130)   ObjectOff(0);
LP 140)  {SetGlobalInt(9, 2); timer = 0; Objects2_Run=0;} // disable itself

instead of those elseifs

The things would be even more better if AGS script language provided a THIS_LINE macro to get the current line number. :)

Kinoko

#5
Hmm, that would be really handy.

EDIT: Okay, I've hit a bit of a snag. The first part of the code (involving MOLERAT) runs fine, and then GlobalInt 9 is changed to 1... and nothing else happens.

Code: ags

#define START if (actiontimer==0) {}
#define LPÃ,  Ã,  else if (actiontimer==
int actiontimer=0;
int Objects1_Run = 0;
int Objects2_Run = 0;
int yaxis;


Code: ags

ccCreateCommand(2, "ROOM:6,5,150; MOVE:70,150; MOVE:5,150; SET:Global(9)=1;");
ccCreateCommand(3, "ROOM:6,280,150; MOVE:215,150; MOVE:280,150; SET:Global(9)=1;");
ccCreateCommand(4, "ROOM:6,155,50; MOVE:155,100; MOVE:155,50; SET:Global(9)=1;");


Code: ags

function Objects1() {

if (Objects1_Run) {

	START
	LPÃ,  10)Ã,  Ã, SetObjectView (0, 25);
	LPÃ,  20)Ã,  Ã, SetObjectPosition (0, 80, yaxis);
	LPÃ,  30)Ã,  Ã, ObjectOn(0);
	LPÃ,  40)Ã,  Ã, AnimateObject (0, 2, 5, 0);
	LPÃ,  50)Ã,  Ã, SetObjectFrame (0, 25, 2, 5);
	LPÃ,  60)Ã,  Ã, SetObjectPosition (0, 100, yaxis);
	LPÃ,  70)Ã,  Ã, SetObjectPosition (0, 120, yaxis);
	LPÃ,  80)Ã,  Ã, SetObjectPosition (0, 140, yaxis);
	LPÃ,  90)Ã,  Ã, SetObjectPosition (0, 160, yaxis);
	LP 100)Ã,  Ã, SetObjectPosition (0, 180, yaxis);
	LP 110)Ã,  Ã, SetObjectPosition (0, 200, yaxis);
	LP 120)Ã,  Ã, SetObjectPosition (0, 220, yaxis);
	LP 130)Ã,  Ã, SetObjectFrame(0, 25, 2, 1);
	LP 140)Ã,  Ã, ObjectOff(0);
	LP 150)Ã,  {SetGlobalInt(9, 2); actiontimer = 0; Objects2_Run=0;} // disable itself
	}
}

function Objects2() {

if (Objects2_Run) {

Ã,  Ã,  	START
	LPÃ,  10)Ã,  Ã, SetObjectView (0, 25);
	LPÃ,  20)Ã,  Ã, SetObjectPosition (0, 240, yaxis);
	LPÃ,  30)Ã,  Ã, ObjectOn(0);
	LPÃ,  40)Ã,  Ã, AnimateObject (0, 1, 5, 0);
	LPÃ,  50)Ã,  Ã, SetObjectFrame (0, 25, 3, 5);
	LPÃ,  60)Ã,  Ã, SetObjectPosition (0, 220, yaxis);
	LPÃ,  70)Ã,  Ã, SetObjectPosition (0, 200, yaxis);
	LPÃ,  80)Ã,  Ã, SetObjectPosition (0, 180, yaxis);
	LPÃ,  90)Ã,  Ã, SetObjectPosition (0, 160, yaxis);
	LP 100)Ã,  Ã, SetObjectPosition (0, 140, yaxis);
	LP 110)Ã,  Ã, SetObjectPosition (0, 120, yaxis);
	LP 120)Ã,  Ã, SetObjectPosition (0, 100, yaxis);
	LP 130)Ã,  Ã, SetObjectFrame(0, 25, 1, 1);
	LP 140)Ã,  Ã, ObjectOff(0);
	LP 150)Ã,  {SetGlobalInt(9, 2); actiontimer = 0; Objects2_Run=0;} // disable itself
	}
}Ã,  

function background_actions_RE() {

Ã,  Ã, if ((actiontimer>0) && (IsGamePaused()==0)) {
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Objects1();
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Objects2();
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  actiontimer++;
Ã,  Ã,  Ã,  }
}


In repeatedly_execute:

Code: ags

if (GetGlobalInt(9)==2) {
Ã,  Ã,  if (randthree<2) {
Ã,  Ã,  Ã,  SetGlobalInt(9, 0);
Ã,  Ã,  Ã,  SetCharacterViewEx (MOLERAT, 21, 2, ALIGN_CENTRE);
Ã,  Ã,  Ã,  ccExecuteCommand (MOLERAT, 2);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (randthree==2) {
Ã,  Ã,  Ã,  SetGlobalInt(9, 0);
Ã,  Ã,  Ã,  SetCharacterViewEx (MOLERAT, 24, 1, ALIGN_CENTRE);
Ã,  Ã,  Ã,  ccExecuteCommand (MOLERAT, 3);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (randthree==3) {
Ã,  Ã,  Ã,  SetGlobalInt(9, 0);
Ã,  Ã,  Ã,  SetCharacterViewEx (MOLERAT, 21, 0, ALIGN_CENTRE);
Ã,  Ã,  Ã,  ccExecuteCommand (MOLERAT, 4);
Ã,  Ã,  Ã,  }
Ã,  Ã,  }
	
if (GetGlobalInt(9)==1) {
  SetGlobalInt(9, 0);
Ã,  Ã,  if (randtwo<2) {
Ã,  Ã,  Ã,  Ã,  ifÃ,  Ã,  Ã,  (randthree< 2) {yaxis=90; actiontimer=1; Objects1_Run = 1;} //start Objects1()
Ã,  Ã,  Ã,  Ã,  else if (randthree==2) {yaxis=120; actiontimer=1; Objects1_Run = 1;} //start Objects1()
Ã,  Ã,  Ã,  Ã,  else if (randthree==3) {yaxis=150; actiontimer=1; Objects1_Run = 1;} //start Objects1()
Ã,  Ã,  Ã,  Ã,  }
Ã,  Ã,  if (randtwo==2) {
Ã,  Ã,  Ã,  Ã,  ifÃ,  Ã,  Ã,  (randthree< 2) {yaxis=90; actiontimer=1; Objects2_Run = 1;} //start Objects2()
Ã,  Ã,  Ã,  Ã,  else if (randthree==2) {yaxis=120; actiontimer=1; Objects2_Run = 1;} //start Objects2()
Ã,  Ã,  Ã,  Ã,  else if (randthree==3) {yaxis=150; actiontimer=1; Objects2_Run = 1;} //start Objects2()
Ã,  Ã,  Ã,  Ã,  }
}

background_actions_RE();


I'm relying on the ~ debug function to tell me what's going on and all I know is that once GlobalInt 9 becomes 1, nothing else happens. I can't figure out at what point the problem begins. I changed quite a few things in your code to suit myself, but I don't think any of the changes should be a problem except for the #START define (I just didn't know what "if(0) {}" was doing...) and exactly where the 'background_actions_RE();' goes - which I'm not sure of.

One another thing relating to the CCS plugin... does it ignore "flipped" frames in views? Because it seems to be doing that for me.

EDIT2: After tearing my hair out a few times, I've managed to get it looping fairly nicely, I just need to slow it down and see how it looks then. Will post more when I've got it right.

Scorpiorus

#6
Quote from: Scorpiorus on Sun 05/09/2004 18:58:12The things would be even more better if AGS script language provided a THIS_LINE macro to get the current line number. :)
Quote from: Kinoko on Mon 06/09/2004 02:37:01Hmm, that would be really handy.
Yeah, but the problem with this sort of things is that if used without care they are not very reliable and may lead to numerous hard to track down bugs, since they are out of the compiler's scope.

But still using that method some interesting things can be accomplished.

By the way, I've just looked into my old scripts to remember how I did it that time and suddenly realized that I didn't use any numeration, so a THIS_LINE thing is not necessary. The system I worked on used a slightly different approach than 'elseifs' but it can surely be applied here as well. I'll try to come with something interesting later today.

Quote from: Kinoko on Mon 06/09/2004 02:37:01EDIT: Okay, I've hit a bit of a snag. The first part of the code (involving MOLERAT) runs fine, and then GlobalInt 9 is changed to 1... and nothing else happens.
Quote from: Kinoko on Mon 06/09/2004 02:37:01EDIT2: After tearing my hair out a few times, I've managed to get it looping fairly nicely, I just need to slow it down and see how it looks then. Will post more when I've got it right.
Glad it works! :) The only thing I noticed is in Objects1()'s code:
Code: ags
LP 150)Ã,  {SetGlobalInt(9, 2); actiontimer = 0; Objects2_Run=0;} // disable itself

it should be:
Code: ags
LP 150)Ã,  {SetGlobalInt(9, 2); actiontimer = 0; Objects1_Run=0;} // disable itself

Not sure if it was related to why it didn't work though.

QuoteI changed quite a few things in your code to suit myself, but I don't think any of the changes should be a problem except for the #START define (I just didn't know what "if(0) {}" was doing...) and exactly where the 'background_actions_RE();' goes - which I'm not sure of.
Hehe, "if(0) {}" does nothing (since the condition is always false because of 0). It's just here so that a compiler would allow us to write LPs afterwards (LP is 'else if' so we must put an if statement first):

if (0){ }Ã,  Ã,  Ã, ----> START
else if (....) ----> LP
else if (....) ----> LP
else if (....) ----> LP

As you can see if(0) is always false and we go to the next 'else if' instead.

Quote#define START if (actiontimer==0) {}
By the way, your having put 'actiontimer==0' inside is logically a very clever way, since yes if actiontimer is 0 then no actions shoud be executed. I put the same condition within the background_actions_RE() function to cover all actions at once but an extra check will never hurt. ;)

As for where background_actions_RE goes, it's supposed to be within the repeatedly_execute function, desirably at the top or at the bottom of it.

QuoteOne another thing relating to the CCS plugin... does it ignore "flipped" frames in views? Because it seems to be doing that for me.
Yep, because the CCS plugin uses its own animation routine it could be that I forgot about implementing that. Thanks for spotting the problem, I'll see what i can do about it.

Kinoko

Quote from: Scorpiorus on Mon 06/09/2004 13:31:56
The only thing I noticed is in Objects1()'s code:
Code: ags
LP 150)  {SetGlobalInt(9, 2); actiontimer = 0; Objects2_Run=0;} // disable itself

it should be:
Code: ags
LP 150)  {SetGlobalInt(9, 2); actiontimer = 0; Objects1_Run=0;} // disable itself

Not sure if it was related to why it didn't work though.

That was something I picked up on just after posting and by then I'd already editted this post about 20 times so I just couldn't be bothered ^_^ I -knew- you'd spot it though. Between my initially incorporating and changing your code to when I finally got it working right was hours and I found tonnes of tiny little scripting errors that took me forever to find. Got 'em all in the end though. One of my biggest problems was that the object's code would sometimes loop continually until I realised I had to "turn off" GlobalInt 9 after it started.

Quote
QuoteOne another thing relating to the CCS plugin... does it ignore "flipped" frames in views? Because it seems to be doing that for me.
Yep, because the CCS plugin uses its own animation routine it could be that I forgot about implementing that. Thanks for spotting the problem, I'll see what i can do about it.

Groovy, thanks ^_^ If it's gonna be fixed within the next 3 months, it'll be useful for me. Otherwise I'll mirror the images myself.

SMF spam blocked by CleanTalk