Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Kinoko on Fri 13/08/2004 16:55:04

Title: character.view/updating functions - SOLVED
Post by: Kinoko on Fri 13/08/2004 16:55:04
A couple of questions actually.

Firstly, using (character[EGO].view==20) doesn't appear to work in a statement like this:


if ((moleret == CD_COLLISION) && (character[EGO].view==20) && (GetGlobalInt(6)==0)) {

blah blah blah...
}


I'm not sure why or what I can do instead.

Secondly, I have a collision detection set up to, once detected (and if GlobalInt 6 == 0), run a function which like this:


function InjureMe() {
Ã,  if (GetGlobalInt(6)==0) {
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, 
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, SetGlobalInt(6, 1);
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, ...blah blah...

Ã,  SetTimer(2, 80);
Ã,  }
Ã,  }


...and in the repeatedly_execute section:


if (IsTimerExpired(2)==1) {
Ã,  Ã,  SetGlobalInt (6, 0);
Ã,  Ã,  Wait(1);
Ã,  Ã,  }


I have it set up this way so that, if the character's collide and if the player isn't currently "being injured", he will get injured, and for 2 seconds afterwards, will be "invinsible" and unable to get harmed again. I have to use a Timer function instead of Wait so it isn't blocking.

The problem is that after being injured once, if the character just stands still, the interaction won't happen again at all. I have to have the character moving (or something updating the script) for it to allow him to get injured again. That's why I put the Wait(1); in, but it doesn't seem to do anything.

I'm pretty stumped on this... can anyone help?
Title: Re: character.view/updating functions
Post by: edmundito on Fri 13/08/2004 17:03:03
There's so many nitpicky things on AGS that could scre you up, but here's what I've noticed:

function InjureMe() {
Ã,  if (GetGlobalInt(6)==0) {

Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, ...blah blah...
Ã,  SetGlobalInt(6, 1);Ã,  // I'm sure you have this, right? :)
Ã,  SetTimer(2, 80);
Ã,  }
Ã,  }

And also:

if (IsTimerExpired(2) == 1 && GetGlobalInt(6) > 0) {
Ã,  Ã,  SetGlobalInt (6, 0);
Ã,  Ã,  //Wait(1);
Ã,  Ã,  }

Maybe that would help some. There may be some thing in your code (like under ...blah blah...) that could mess everything up.

Pumaman: You can't bold stuff under the [ code ] [ / code ] tags, which might be useful like in this case! You sense danger!
Title: Re: character.view/updating functions
Post by: Kinoko on Fri 13/08/2004 17:17:40
I did indeed have the SetGlobalInt line there, I should've mentioned it. I'll modify my original post.

I followed your suggestion with the rest anyway, but it made no difference. I'm not sure but I don't think the "(GetGlobalInt(6)>0) " line is necessary. As I understand it, IsTimerExpired only returns 1 once so the way it's setup to run directly after the function has executed, it shouldn't be a problem. I think, anyway.
Title: Re: character.view/updating functions
Post by: edmundito on Fri 13/08/2004 17:32:56
Oh ok. I downloaded the AGS help file, so I could read on the functions because I don't remember those kinds of details.

Well, here's my deductions. Your triggering condition (the if statement that checks to call InjureMe()) may have some sort of glitch.

if the condition is (moleret == CD_COLLISION) && (character[EGO].view==20) && (GetGlobalInt(6)==0) I'm not exactly sure what molert and CD_CONDITION, or mayb even the view may affect it. but I would make sure that you have the logic right in that condition and that all the flags are reset when the character stops "blinking" (well, I'm thinking about a console game where you get hit and you blink for a bit)
Title: Re: character.view/updating functions
Post by: Kinoko on Fri 13/08/2004 17:48:26
moleret/CD_COLLISION are due to the Character Collision plugin I'm using.

I'll recheck everything tomorrow when I'm not falling asleep. Thanks for your help so far, anyway.
Title: Re: character.view/updating functions
Post by: Pumaman on Sun 15/08/2004 11:16:33
Yeah, where are you calling InjureMe() from? It's probable that your logic there isn't running while the player is standing still.

Also, in terms of the view it's important to note that the character[].view  variable is the view number minus 1. So to check for view 20, do:

if (character[EGO].view == 19)

This is a pain I know, and were I to start AGS from scratch now I'd make sure it didn't do this, but unfortunately we've got to live with it.
Title: Re: character.view/updating functions
Post by: Kinoko on Sun 15/08/2004 14:35:24
Hmm, I hate having problems like this where I just can't see what's wrong logically.

Here's basically all of the scripting involved.


int moleret = spriteSpriteColDetect (EGO, CD_CHARACTER, egoslot, MOLERAT, CD_CHARACTER, 201);
///////////////////////////////
if ((moleret == CD_COLLISION) && (character[EGO].view==19) && (GetGlobalInt(6)==0)) {
  if ((Random(luck))<2) {
  TypeLineKaya (510, 130, 50, 1, 12, 200, 0, -1); //miss
}
else {
mondmg = ((str + wpnstr) + (RandomEx(((str/5)-str%5)*4,str)) - (RandomEx(((mondef/5)-mondef%5)*4,mondef)));
if (mondmg<1) mondmg=1;
kayahp -= mondmg;
DisplayDMG ();
Display ("Molerat takes %d damage! Molerat's HP is %d", mondmg, kayahp);
}
  }

else if ((moleret == CD_COLLISION) && (character[EGO].view!=19) && (GetGlobalInt(6)==0)) {
  InjureMe();
  }


Basically, this is defining a collision between the two characters (which works fine). If that collision happens and the character is in the "attacking" view, run the script regarding damage to the Molerat. If it's any other view, run InjureMe...


function InjureMe() {
  if (GetGlobalInt(6)==0) {
  SetGlobalInt (6, 1);
  SetCharacterView (EGO, 22);
  //displaydmg
  AnimateCharacterEx (EGO, character[EGO].loop, 0, 0, 0, 1);
  SetCharacterView (EGO, 19);
  SetTimer(2, 80);
  }
  }



Then in repeatedly_execute:


if ((IsTimerExpired(2)==1) && (GetGlobalInt(6)>0))  {
    SetGlobalInt (6, 0);
    //Wait(1);
    }


I don't know... when I look at it, I can't see what's wrong. The only thing that strikes me is that it -seems- like something isn't being updated until my character has moved. Though, that doesn't seem to make sense because I can move my character after it's been injured, and then stop it, and it still won't run InjureMe again when the collision occurs once more. The character has to be moving at the time of the collision for it to run the code again.
Title: Re: character.view/updating functions
Post by: Pumaman on Sun 15/08/2004 16:15:48
The first block of code that you posted -- is that in repeatedly_execute?
Title: Re: character.view/updating functions
Post by: Kinoko on Mon 16/08/2004 05:55:27
No, that's just at the end of my global script.
Title: Re: character.view/updating functions
Post by: Gilbert on Mon 16/08/2004 06:15:41
Then what function it's in?
Title: Re: character.view/updating functions
Post by: Kinoko on Mon 16/08/2004 07:45:08
Erm, it's not in a function. It's just at the end of the global script.
Title: Re: character.view/updating functions
Post by: Gilbert on Mon 16/08/2004 08:00:54
It must be in some function, else you cant tell the engine where to execute it.
Title: Re: character.view/updating functions
Post by: Kinoko on Mon 16/08/2004 14:40:03
Hmm, I thought you could just tack things on the end. In that case, I'm not sure where to put it exactly. I mean, almost everything I've added to the global script has gone outside of the pre-existing functions and they all work fine. I've been trying to avoid putting too many thing in repeatedly_execute in case it slows the game down.
Title: Re: character.view/updating functions
Post by: Gilbert on Tue 17/08/2004 03:17:35
Quote from: Kinoko on Mon 16/08/2004 14:40:03
I mean, almost everything I've added to the global script has gone outside of the pre-existing functions and they all work fine.

Actually I think that's quite strange, I wonder why they'll work and even compiled without errors.
Stuffs put outside of any functions are for initialisations and variable declarations, etc. only.
If you want some actions to be done in game, the scripts must be put into some functions, for example if you choose an interaction response to run script, it will create some function like room_a(), etc in the script, so everything should be in functions.

Judging from your code, I think you want it to happen every game loop right? Then it should be in repeatedly_execute(). You're right in saying that if you execute many stuffs all at once the engine may be slowed down with slower computers but you cant prevent it if you really want them to run together.
Title: Re: character.view/updating functions
Post by: Kinoko on Tue 17/08/2004 05:23:23
Whoa, sorry sorry... my mistake. That code is actually in on_key_press... I don't know what I was thinking.

I've shuffled it all around now, and put the code necessary into repeatedly_execute, and InjureMe now works fine.

The problem now is just that the attacking part of the code won't work.
This is all in repeatedly_execute:


if (character[EGO].loop == 0) {
Ã,  egoslot = 202;
Ã,  }
else if (character[EGO].loop == 1) {
Ã,  Ã,  egoslot = 203;
Ã,  }
else if (character[EGO].loop == 2) {
Ã,  Ã,  egoslot = 204;
Ã,  }
else if (character[EGO].loop == 3) {
Ã,  Ã,  egoslot = 200;
Ã,  }

///////////////////////////////// MONSTERS ///////////////////////////////
moleret = spriteSpriteColDetect (EGO, CD_CHARACTER, egoslot, MOLERAT, CD_CHARACTER, 201);
moleret2 = spriteSpriteColDetect (EGO, CD_CHARACTER, 68, MOLERAT, CD_CHARACTER, 201);
//////////////////////////////////////////////////////////////////////////
Ã, 
if (character[EGO].room == 1) {
Ã,  if ((moleret == CD_COLLISION) && (character[EGO].view==19)) {
Ã,  Ã,  Ã, if ((Random(luck))<2) {
Ã,  TypeLineKaya (510, 130, 50, 1, 12, 200, 0, -1); //miss
}
else {
mondmg = ((str + wpnstr) + (RandomEx(((str/5)-str%5)*4,str)) - (RandomEx(((mondef/5)-mondef%5)*4,mondef)));
if (mondmg<1) mondmg=1;
molehp -= mondmg;
DisplayDMG ();
Display ("Molerat takes %d damage! Molerat's HP is %d", mondmg, molehp);
}
Ã,  Ã,  Ã, }
Ã,  if ((moleret2 == CD_COLLISION) && (character[EGO].view!=19) && (GetGlobalInt(6)==0)) {
Ã,  Ã,  Ã, InjureMe();
Ã,  Ã,  Ã, }
}


It's now just the line if ((moleret == CD_COLLISION) && (character[EGO].view==19)) that doesn't appear to be working. The collision is fine because it works when I use (IsKeyPressed(88)) instead of the character[EGO].view line.  The necessary view is 20, so I have taken 1 off it.
Title: Re: character.view/updating functions
Post by: Gilbert on Tue 17/08/2004 07:21:28
Hmmm try putting a display line in it to check if the view was indeed 20-1, like:

Ã,  if ((moleret == CD_COLLISION)) {
/* && (character[EGO].view==19)) {*/
Display("%d",character[EGO].view);
Ã,  Ã,  Ã, if ((Random(luck))<2) {
Ã,  TypeLineKaya (510, 130, 50, 1, 12, 200, 0, -1); //miss
}
else {
mondmg = ((str + wpnstr) + (RandomEx(((str/5)-str%5)*4,str)) -
blah bla....


Also, check if your character is indeed called EGO, not something else.

Title: Re: character.view/updating functions
Post by: Kinoko on Tue 17/08/2004 07:37:22
I don't know why I didn't think of that myself. As far as I can tell, it does indeed seem to be on view 18 instead of 19 (or in actual terms, view 19 and 20) when the collision is detected. 18 (actually 19) is the normal walking view, and when the attack button is pushed, this code runs:


if (IsKeyPressed(88)) {
Ã,  Ã,  SetCharacterView(EGO, 20);
Ã,  Ã,  AnimateCharacterEx (EGO, character[EGO].loop, 2, 0, 0, 1);
Ã,  Ã,  SetCharacterView (EGO, 19);
Ã,  Ã,  }


So, it seems like maybe the game is checking the collision before this code has had time to change the view to 20. I don't know, I thought my code was fine. When both the collision is happening, AND the view is 20, then blah blah... Especially given that it's in repeatedly_execute. It seems like the first bunch of code shouldn't run until the view is 20.

EDIT: Unless it's just a feature of the character collision plugin that character collisions only count as collisions when they first occur, not AS they're occuring... but the InjureMe code works over and over as long as the collision has happened and continues to happen. That one doesn't seem to need the collision to re-happen.
Title: Re: character.view/updating functions
Post by: Kinoko on Fri 20/08/2004 01:34:21
Sorry for the double post but... *bump*

Anyone have any thoughts on this?
Title: Re: character.view/updating functions
Post by: Pumaman on Fri 20/08/2004 20:08:12
That AnimateCharacterEx call is blocking, so repeatedly_execute won't run while it is in progress. Then, the animation ends and the view gets set back to 19, then finally repeteatedly_execute runs.

This is likely to be the problem.
Title: Re: character.view/updating functions
Post by: Kinoko on Sun 22/08/2004 04:47:44
Ahh, I hadn't remembered that about repeatedly_execute. I moved the code in question into repeatedly_execute_always which still gives an error because of a blocking function, but that's referring to all the Display functions in there which were only temporary anyway.

What I need to put in their place is a non-blocking display function similar to DisplaySpeechBackground that allows the use of %d and %s (and a couple of other properties such as displaysing at specific coordinates and a transparent text window... which I think is being fixed in a later AGS version...?).

The semi-temporary  code I have now is:

In repeatedly_execute_always


if (character[EGO].room == 1) {
  if ((moleret == CD_COLLISION) && (character[EGO].view==19) && (GetGlobalInt(7)==0)) {
     if ((Random(luck))<2) {
// TypeLineKaya (510, 130, 50, 1, 12, 200, 0, -1); //miss
DisplaySpeechBackground (EGO, "Miss...");
     }
     else {
  SetTimer(3, 80);
  SetGlobalInt(7, 1);
  SetCharacterView (MOLERAT, 23);
  AnimateCharacterEx (MOLERAT, character[MOLERAT].loop, 0, 0, 0, 0);
  mondmg = ((str + wpnstr) + (RandomEx(((str/5)-str%5)*4,str)) - (RandomEx(((mondef/5)-mondef%5)*4,mondef)));
  if (mondmg<1) mondmg=1;
  molehp -= mondmg;
  //DisplayDMG ();
  DisplaySpeechBackground (EGO, "Hit!");
  //Display ("Molerat takes %d damage! Molerat's HP is %d", mondmg, molehp);
  }
    }
}


And in repeatedly_execute:


if (IsTimerExpired(3)==1) {
    SetCharacterView (MOLERAT, 21);
    SetGlobalInt(7, 0);
    Wait(1);
    }


It works fine, in that once a "Hit" has been made, I don't want another hit to be able to take place until the timer(3) has expired (which is why I've got GlobalInt(7) in there).

The only problem is that when the character attacks and a "hit" is made, at least two "Hit!"s or a "Hit!" and a "Miss..." appear at the same time immediately. Further attacks will be blocked after that until the timer has expired, but there's that little nanosecond where several will be registered at once. I'm not sure why more than one are making it in at the start...
Title: Re: character.view/updating functions
Post by: Pumaman on Sun 22/08/2004 15:59:28
Well, if it's a Miss, the GlobalInt 7 doesn't get set to 1, so there's nothing to stop the code all running again.

Offhand, I can't see how you'd be getting two hits in a row, though.

Also, there's a workaround for using %d/%s with any command, just do:

string buffer;
StrFormat(buffer, "Molerat takes %d damage! Molerat's HP is %d", mondmg, molehp);
DisplaySpeechBackground(EGO, buffer);
Title: Re: character.view/updating functions
Post by: Kinoko on Sun 22/08/2004 16:10:57
Ahh, I've fixed the code in the "miss" section, thanks for that. I'll keep that workaround in mind, too.

I really don't understand what's happening with the double(or more) ups either... I'm having a similar problem (thread currently in the Beginners Help) with trying to stop an action happening more than once with each key press. It seems to work, but if I keep a key held down, the action will continue to run continuously despite being told in the script not to run again until the first action is completed. I was hoping that if anyone, you'd have an idea of what was happening here ^_^;;; I don't understand it, but it just seems as though when the code is called, certain blocks don't happen quick enough before the code is called again. I really don't know...

EDIT: Well, that problem has been fixed and it seems to have fixed the problem of the double-ups too. I'm not sure why, but things are working well now. Crazy. Thanks for all your help, anyway.