timer wont expire in room_RepExec()

Started by georgeh, Thu 26/02/2015 09:17:41

Previous topic - Next topic

georgeh

Hello again.I am having a little trouble with timers(among others...).In my game i want a letter to be slipped under the door after lets say 10 sec,the player turns to face the letter,walk towards it,picks up and reads it.So far so good.I have set the timer in loadroom and the actions in room_repexec(with the "if isTimeExpired").The problem is that this action keeps repeating every 10 sec instead of once as i want to.I have read the manual,read most of the other posts about timers and repexec but i am a bit confused since i just have started using AGS.Here is my code:
function room_Load()
{
  SetTimer(1, 400);
}
//After more lines...//
function room_RepExec()
{
if (IsTimerExpired(1)==1){
  oenvelope.Visible=true;
  oenvelope.Move(162, 260, 2, eNoBlock, eAnywhere);
  cego.FaceObject(oenvelope,);
  Wait(80);
  cego.Walk(205, 260, eBlock, eWalkableAreas);
  cego.Say("What is this ???");
  SetTimer(1, 0);
}
}
The last"SetTimer" was put after i've tried many times the rest of the script to run once,as a final solution,but no.
Wouldnt the timer had expired in the above script?If i wanted to reset it ,wouldnt i have to put"SetTimer(1,400) again at the end of the script?
I saw that maybe the problem would be the"Wait" and "eBlock".I am confused about that after reading the manual.And again if i remove the "wait" and change the"eblock",the player doesnt walk at the specific command.He stays where he was.

PS(1) please be as specific as possible because in my first post for another problem i had i've recieved a vague answer like "the manual explains it better"and so i couldnt figure a solution and dropped it off.No disrespect,i am gratefull for your help but for us begginers something more specific would have been more help.
PS(2)forgive my looong post...

Mandle

#1
Quote from: georgeh on Thu 26/02/2015 09:17:41
PS(1) please be as specific as possible because in my first post for another problem i had i've recieved a vague answer like "the manual explains it better"and so i couldnt figure a solution and dropped it off.

Oh really? You "dropped it off"? I believe that was my post and it directed you to the part of the manual describing the "RepExec" function. And, well look, here you are using the "RepExec" function. So yeah, I guess my advice was vague and useless to you.

By the way. When I said the manual says it clearer than I could in the thread I wasn't being sarcastic as in "RTFM". I actually meant that there was no point in me describing the function when the manual describes it very clearly and that's why I linked you.

Now, for your current problem: To be honest I can't figure out what is wrong. Your code looks fine to me.

So: I would set a bool variable in Global Variables called "HasLetterCome" (initial value = false) or something and change code to:

Code: ags
if (IsTimerExpired(1)==1 && HasLetterCome==false){
  oenvelope.Visible=true;
  oenvelope.Move(162, 260, 2, eNoBlock, eAnywhere);
  cego.FaceObject(oenvelope,);
  Wait(80);
  cego.Walk(205, 260, eBlock, eWalkableAreas);
  cego.Say("What is this ???");
  SetTimer(1, 0);
  HasLetterCome=true;


It doesn't explain what is going wrong here but it should fix the problem. Messy I know but it should work. Someone will probably have a better solution.

EDIT: Oh, there is also a command to do something only once which works the same as setting the bool like I said except built into AGS. I don't have time right now to check the exact syntax but it should show up on google with something like "AGS manual do only once" search.

georgeh

Your advice was more helpfull than you can imagine.When i said vague i meant that reading the manual was putting me into the right direction but no solution for my problem.I know that you(or anybody in the forum)cant solve everybodys script problems but please be patient with us and our so many and sometimes stupid questions.I do not expect you to "write" my game,i want to do it my shelf by reading,trying and asking.And again i mean no disrespect.
For your second advice i thank you a lot.I will give it a try when i have the time.:(

NickyNyce

#3
You could put this in repeatedly execute...

Code: ags
  if(IsTimerExpired(1) && Game.DoOnceOnly("TheLetter"))
  {
    oEnvelope.Visible=true;
    oEnvelope.Move(162, 260, 2, eBlock, eAnywhere);
    cEgo.FaceObject(oenvelope,);
    Wait(80);
    cEgo.Walk(205, 260, eBlock, eWalkableAreas);
    cEgo.Say("What is this ???");    
  }


And put this in AfterFadeIn....

Code: ags
  if(Game.DoOnceOnly("LetterArrives"))
  { 
    SetTimer(1, 400);   
  }


I'm not sure if this is a reasonable way of doing it, but I think it should work. I'm wondering which is the better way to go about doing this? I seem to be hooked on Game.DoOnceOnly. This way the timer only starts once and never gets reset, or needs to be shut off. Also notice that I capitalized your object, Envelope, and Ego. You might want to change it to, oenvelope and cego, if you made it that way.

Mandle

Quote from: georgeh on Thu 26/02/2015 11:00:16
Your advice was more helpfull than you can imagine.When i said vague i meant that reading the manual was putting me into the right direction but no solution for my problem.I know that you(or anybody in the forum)cant solve everybodys script problems but please be patient with us and our so many and sometimes stupid questions.I do not expect you to "write" my game,i want to do it my shelf by reading,trying and asking.And again i mean no disrespect.
For your second advice i thank you a lot.I will give it a try when i have the time.:(

Okay, no worries mate. I hope I have helped a bit.

As for not solving the bus arriving on time problem: Well, I'm a bit surprised...If I remember correctly your problem was that the player had to leave the room and reenter to make the bus appear, and you wanted to know how to make it appear as soon as the condition(s) to ride it were met: RepExec is exactly the way to do this (plus Cassie's advice on using object numbers and not names in Global Script). Are you saying this didn't work? The code you provided in that thread should have worked (with object numbers) in Global Script in the RepExec...

If not then please post again in that thread and let's work it out :)

Cassiebsg

Yeah, don't just give up on your vision!
If it's not working, means only something is wrong, you probably are just missing an extra bool or something.
Post the code and ask again. I'm no expert so I refrain to write code, as chances are there's a better way... I can only give small help/hints on very basic coding so am "sure" not to be giving bad advice. ;)
There are those who believe that life here began out there...

georgeh

Thank you all.Both solutions worked like a charm.Can i ask NickyNyce why did you put two different "DoItOnce"?;-D

NickyNyce

#7
Every time you make a new DoOnceOnly, they must be named different. The engine checks if that key word was used, if it was, it will not run... Hence the DoOnceOnly. That's how the engine decides if it should run that part of the script.

Also, when you check a timer, you don't need == 1.

Also, if you are checking a condition with DoOnceOnly, always place the DoOnceOnly second, not first. If you place it first, and the second condition is not met, it will never be met because now the DoOnceOnly was already used. I hope that makes sense. So if you place the timer in front of it, and it is not expired, the engine stops reading the script there. The DoOnceOnly will not be used until that timer does expire.

I'm not great at scripting, but by posting all this mumbo jumbo, I'm hoping that Khris will get disgusted and come back.  ;)

georgeh

Thank you very much for that.Very helpfull.

SMF spam blocked by CleanTalk