SetGlobalInt not working

Started by Kinoko, Mon 11/07/2005 12:23:52

Previous topic - Next topic

Kinoko

(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:

Code: ags

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.

SSH

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?

12

Kinoko

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.

GarageGothic

And you're sure that the CD_NO_COLLISION and CD_COLLISION variables are triggered properly?

Kinoko

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.

SSH

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?

12

Kinoko

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.

SSH

Try using a different globalint numbe, or use a specifically named global var, Try putting a Wait(1) after the setglobalint....
12

Pumaman

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.

Kinoko

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.

Gilbert

Actually I'd want to see how (where) the variable fawnyaret is set to the values  CD_COLLISION and  CD_NO_COLLISION.

Kinoko

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:

Code: ags

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.

Gilbert

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:
Code: ags

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().

Kinoko

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.

Gilbert

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.

Kinoko

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);

Gilbert

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.

Kinoko

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.

SSH

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
12

Kinoko

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...

SMF spam blocked by CleanTalk