Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Kinoko on Mon 11/07/2005 12:23:52

Title: SetGlobalInt not working
Post by: Kinoko on Mon 11/07/2005 12:23:52
(I'm sorry for all my threads but I've just been scripting almost non-stop for days so I have a lot of seperate issues.)

I wrote this code in a room script awhile ago to go alongside the character detection and CCS plugins. It always, seemingly, worked fine and today I decided to adjust it:


if ((fawnyaret == CD_COLLISION) && (GetGlobalInt(11)==0)) {
  FaceCharacter(FAWNYA, EGO);
  SetGlobalInt(11, 1);
  }
else if ((fawnyaret == CD_NO_COLLISION) && (GetGlobalInt(11)==1)) {
  SetGlobalInt(11, 0);
  cFawnya.FaceLocation(character[FAWNYA].x, character[FAWNYA].y+5, eNoBlock);
  Wait(1);
}


I basically just added the FaceLocation line so that when I walked away from the NPC, it would face downwards again. I also added to corresponding code in the global script:

if ((fawnyaret == CD_COLLISION) && (IsKeyPressed(keyx)) && (GetGlobalInt(11)==1)) TypeLineSay ("Blah blah blah", 20, 160, 275, 2, -1);

(added bold code) so that you could only talk to the NPC if you were facing each other.

I noticed neither change worked. I couldn't talk to the NPC nor would it turn downwards when I walked away, but it -would- face me when I 'collided' with it.

I tested a few things and discovered that the line " SetGlobalInt(11, 1); " wasn't happening. The GlobalInt is never changing. This would explain perfectly why the code isn't working, but I can't explain why the GlobalInt isn't changing, especially since the line of code directly before it is working.

Is there some problem with changing global ints in a room script? I've already checked both the room script and the global script for any other instance of GlobalInt(11 that might be conflicting but there's nada.
Title: Re: SetGlobalInt not working
Post by: SSH on Mon 11/07/2005 12:31:45
Maybe you need to check if the FaceCharacter is blocking or not: do you have the turning game parameter on? Maybe you need to use the player.FaceCharacter instead, so you can set it non-blocking?

Title: Re: SetGlobalInt not working
Post by: Kinoko on Mon 11/07/2005 12:38:37
Turn before walking is turned off in both general settings and for each individual character. I did try changing to player.FaceCharacter though, but it made no difference.
Title: Re: SetGlobalInt not working
Post by: GarageGothic on Mon 11/07/2005 13:00:06
And you're sure that the CD_NO_COLLISION and CD_COLLISION variables are triggered properly?
Title: Re: SetGlobalInt not working
Post by: Kinoko on Mon 11/07/2005 13:18:41
Positive. As I said, the code worked before I tried to check global int 11, and I've used it all over the place with no problems.
Title: Re: SetGlobalInt not working
Post by: SSH on Mon 11/07/2005 13:56:04
Progamming history is littered with "Yes, I'm sure that bit works, I haven't changed it at all since it was working apart from.... oh, ah, hmmm, OK"

Double-check your brackets: maybe you've accidnetally moved the code inside an "if".

Have you tried single-stepping through the code?

Title: Re: SetGlobalInt not working
Post by: Kinoko on Mon 11/07/2005 14:53:33
Double checked and triple checked... the thing that gets me is that it should be so simple, it's not a complicated code. Even if you forget the part in the global script, the room script section should be working. I've tested each part individually and the only line that isn't working is "SetGlobalInt(11,1);"

I've tried moving what's in the room script to the global script and I get the same thing, no change, so my theory of it being because of the room script is shot.
Title: Re: SetGlobalInt not working
Post by: SSH on Mon 11/07/2005 16:39:54
Try using a different globalint numbe, or use a specifically named global var, Try putting a Wait(1) after the setglobalint....
Title: Re: SetGlobalInt not working
Post by: Pumaman on Mon 11/07/2005 19:12:22
Well, an easy way to check if it's working is to add some code around it, like this:

Display("before: %d", GetGlobalInt(11));
SetGlobalInt(11,1);
Display("after: %d", GetGlobalInt(11));

You could also try activating teh debug console (~ key) and see if it sheds any light.
Title: Re: SetGlobalInt not working
Post by: Kinoko on Tue 12/07/2005 02:18:34
I used the Display code and it showed that the global int is turning on and off continuously when I 'collide' with the character (don't know why the GUI lebel I set up to tell me the value of the global int didn't work...)

I don't know why this is happening yet, but it seems for some reason the game is reading the collision as turning on and off.
Title: Re: SetGlobalInt not working
Post by: Gilbert on Tue 12/07/2005 03:11:04
Actually I'd want to see how (where) the variable fawnyaret is set to the values  CD_COLLISION and  CD_NO_COLLISION.
Title: Re: SetGlobalInt not working
Post by: Kinoko on Tue 12/07/2005 03:29:45
Okay, here's all the related script.

I have the line fawnyaret = charCharColDetectEx (EGO, 68, FAWNYA, 68); in my global script in repeatedly_execute.

I have this custom function:


function charCharColDetectEx(int CharID1, int slot1, int CharID2, int slot2) {
   int room1;
   int room2; 
   if (CharID1 != GetPlayerCharacter()) room1 = ccGetCharacterRoom(CharID1);
   else room1 = character[CharID1].room;
   if (CharID2 != GetPlayerCharacter()) room2 = ccGetCharacterRoom(CharID2);
   else room2 = character[CharID2].room; 
   if (room1 == room2) return spriteSpriteColDetect(CharID1, CD_CHARACTER, slot1, CharID2, CD_CHARACTER, slot2);
   else return CD_NO_COLLISION;
}


Which came from Scorporius to solve a problem I was having with something or other (can't remember now).

Then I have that code I posted earlier in the room script.

I've been looking it all over trying to think of where it could be conflicting with something else but it seems pretty straightforward. I know there has to be some problem somewhere but I don't know what.
Title: Re: SetGlobalInt not working
Post by: Gilbert on Tue 12/07/2005 03:59:34
Hmmm actually I don't quite understand the part why did you use some function called ccGetCharacterRoom() to return a NPC's room (instead of directly using  character[CharID1].room), unless of course it's the limitation of a plugin, which has its own list of the characters' room, and won't put the characters into the real room unless it's the current room.

There doesn't seem to be problem with the function you posted, suspected trouble makers may be one (or both) of the following:
1. ccGetCharacterRoom(), for some reasons it returns a room number which is different from the player's (current room number), so CD_NO_COLLISION is returned.
2. spriteSpriteColDetect() it returns CD_NO_COLLISION (or even some other value) for some reasons.

Since I have absolutely no knowledge to these functions I can't tell where is the real problem.
You can, however, use that display trick again:

function charCharColDetectEx(int CharID1, int slot1, int CharID2, int slot2) {
int room1;
int room2;
if (CharID1 != GetPlayerCharacter()) room1 = ccGetCharacterRoom(CharID1);
else room1 = character[CharID1].room;
if (CharID2 != GetPlayerCharacter()) room2 = ccGetCharacterRoom(CharID2);
else room2 = character[CharID2].room;
if (room1 == room2) {
  aaa=spriteSpriteColDetect(CharID1, CD_CHARACTER, slot1, CharID2, CD_CHARACTER, slot2);
  Display("%d",aaa);
  return aaa;
  }
else return CD_NO_COLLISION;
}

So if nothing is displayed, it's gone the "room1!=room2" route (trouble maker 1), if something is displayed it will display a number, which is what would have returned by spriteSpriteColDetect().
Title: Re: SetGlobalInt not working
Post by: Kinoko on Tue 12/07/2005 05:03:16
Right, did that and basically is displays 0 until I collide with this particular character, when the display goes on/off/on/off repeatedly.

I'm using fawnyaret as an example, but I have this same exact code working with about 10 or so other characters in the room and so I tried colliding with them and it only worked with one or two other characters. There's 0 difference in the codes between all these characters save the names themselves, so I'm now wondering if the problem is the new walking code Steve has been writing for me. It seemed to be working fine but then again, back then I wasn't noticing the global int turning on and off until I added the extra 'if' to my talking codes. The thread is here, anyway: http://www.adventuregamestudio.co.uk/yabb/index.php?topic=21654.0

I suspected these problems might be related but I didn't know so I figured it was better to start a new thread. For all I knew, it could have been related to this thread of mine, another one of mine, or something totally new so I didn't want to presume anything.
Title: Re: SetGlobalInt not working
Post by: Gilbert on Tue 12/07/2005 05:12:48
So, I may assume the problem is from spriteSpriteColDetect() right?

What I'm thinking is, how does that function work, what I'm guessing is that it's just a bounding box overlapping check, they should work, unless the characters changed their coordinates.
Title: Re: SetGlobalInt not working
Post by: Kinoko on Tue 12/07/2005 05:18:43
I'll post what the readme for it says:

int spriteSpriteColDetect(int id1, int type1, int slot1,
           int id2, int type2, int slot2);

Pre-Condition(s):
  Both sprites exist.
  Both entities exist.   
   
Input:
  id1      - Id of first entity you want use for collision detection.
  type1    - Type of the first entity:
                CD_OBJECT(0) - If the entity is an object.
                CD_CHARACTER(1) - If the entity is a character.
  slot1    - Slot number of the first sprite (>0).
  id2      - Id of second entity you want use for collision detection.
  type2    - Type of the second entity:
                CD_OBJECT(0) - If the entity is an object.
                CD_CHARACTER(1) - If the entity is a character.
  slot2    - Slot number of the second sprite (>0).

Output:
  CD_NO_COLLISION(0) - No collision found.
  CD_COLLISION(1) - Collision found.
  CD_PARAM_ERROR(-1) - Parameter error (out of range).
  CD_SYS_ERROR(-2) - System error.

  if(debug mode)
    Generates "spriteSpriteColDetect.txt" in the current active directory

Post-Condition(s):
  None

Description:
Performs full object-to-object pixel-level collision detection. If the sprites
are touching each other, the overlapping rectangle is scanned pixel-by-pixel
in both sprites. If the same pixel is non-transparent for both of them, a
collision is detected.

Use this function if you need to test two full-sized objects for
pixel-perfect collision detection. This algorithm can be quite expensive,
especially if the overlapping region is mostly transparent. Perhaps you should
try to minimize its use in your game. You may want to determine at run-time
which objects need full, object-to-object pixel-level collision detection and
which objects can get away with one of the cheaper varieties.

The transparent color used is either the default (see resetTransparentColor
for more information) or set by the user (see setTransparentColor for more
information).

If debug mode is enabled, function data is written to
'spriteSpriteColDetect.txt'. This file is created in the output directory of
your game. If your game is stored in 'C:\games\my_game\', then
'spriteSpriteColDetect.txt' is stored in 'C:\games\my_game\compiled\'
alongside with your game's exe file. Keep in mind that this file is
overwritten every time this function is called (for more information, see
the notes section).

Currently, the 'spriteSpriteColDetect.txt' file contains the following
information:
  * Both sprites' room coordinates (x, y).
  * Both sprites' viewport coordinates (x, y).
  * Both sprites' dimensions(width, height).
  * Both sprites' color depth (bits) and transparent color (index, (R, G, B)).
  * Both sprites' scaling factor (%).
  * Both sprites' bounding box limits.
  * Both sprites' overlapping rectangle dimensions (width, height). (*)
  * Both sprites' overlapping rectangle limits. (*)
  * Collision detection result, which is also displayed next to the mouse
    cursor (for more information, please consult setDebugMode()). 

This function is the slowest of the bunch, but also the more accurate. This
offers you completely accurate collision detection, at the expense of speed!

Note: slot1 and slot2 parameters are temporary and will disappear in future
versions (see 'limitations' section). Don't get too attached to them!

(*) Only appears if the sprites' are overlapping.

Example(s):

   // Test for collisions between character EGO (sprite slot 30) and current
   // room's object 1 (sprite slot 10)
   int ret = spriteSpriteColDetect(EGO, CD_CHARACTER, 30, 1, CD_OBJECT, 10);

   // Test for collisions between current room's object 2 (sprite slot 25)
   // and current room's object 1 (sprite slot 10)
   int ret = spriteSpriteColDetect(2, CD_OBJECT, 25, 1, CD_OBJECT, 10);
Title: Re: SetGlobalInt not working
Post by: Gilbert on Tue 12/07/2005 05:32:24
Actually I have a thought, instead of checking that, you may just try switching to native AGS function AreCharObjColliding() (V2.62 or before) or cEGO.IsCollidingWithObject () (V2.7+), and see if it works in that case.

Also, I have some doubt as if whether pixel perfect overlaping check with a mask is really needed for cases like two characters colliding to start a talk.
Title: Re: SetGlobalInt not working
Post by: Kinoko on Tue 12/07/2005 05:40:16
It is because you can approach them from all 4 sides and I need to have a mask at their feet. I don't want character A to stand above overlapping with characters B's head and still be able to talk.
Title: Re: SetGlobalInt not working
Post by: SSH on Tue 12/07/2005 15:37:24
As I said earlier on IRC and so you don't forget ;)

if your collsion detect areas it were pure rectangle it would probably be easiest just to do


if (x1 < x2 + 10) && (x1 > x2 - 10) && ( y1 > y2-5) && y1 < y2+5


or something like that
Title: Re: SetGlobalInt not working
Post by: Kinoko on Sun 23/10/2005 11:09:11
Sorry to drag this up again but I'm only just now re-tackling the problem. I can't remember at all what your post was in relation to SSh, sorry ^_^; I know we talked about it on IRC but...
Title: Re: SetGlobalInt not working
Post by: RickJ on Sun 23/10/2005 13:27:36
I wonder if the the FaceLocation moves the characters away from each other?  Perhaps try commenting out the FaceLocation() statements to see what happens.
Title: Re: SetGlobalInt not working
Post by: Kinoko on Sun 23/10/2005 13:56:20
Commenting that out didn't make any difference (I -really- thought that could be it though, good idea!). The only thing that makes a difference still is taking out the condition of GlobalInt 11 from the line that deals with talking to another character.

When I do that, the character faces me, talks to me, but then doesn't turn back and face their original location. If I then walk away though, and and approach her from a different direction, she'll turn to face me again.
Title: Re: SetGlobalInt not working
Post by: RickJ on Sun 23/10/2005 15:06:36
Ok, but I bet fawnyaret is still toggling on/off.  Put in some more Display() commands like below to see what is actually going on.

Display("before - fawnuaret=%d, GlobalInt=%d",fawnyaret,(GetGlobalInt(11));
if ((fawnyaret == CD_COLLISION) && (GetGlobalInt(11)==0)) {
Display("if - fawnyaret=%d, GlobalInt=%d",fawnyaret,(GetGlobalInt(11));
  FaceCharacter(FAWNYA, EGO);
  SetGlobalInt(11, 1);
  }
else if ((fawnyaret == CD_NO_COLLISION) && (GetGlobalInt(11)==1)) {
Display("else if - fawnuaret=%d, GlobalInt=%d",fawnyaret,(GetGlobalInt(11));
  SetGlobalInt(11, 0);
  cFawnya.FaceLocation(character[FAWNYA].x, character[FAWNYA].y+5, eNoBlock);
  Wait(1);
}
Display("after - fawnyaret=%d, GlobalInt=%d",fawnyaret,(GetGlobalInt(11));

The collission detect may need to have two thresholds so that once a colission is detected then the characters must move further apart (some adjustable distance) to detect that they are no-longer colliding.