Movecharacter without blocking and then return to script?

Started by Ravenous, Wed 04/02/2004 20:32:15

Previous topic - Next topic

Ravenous

Hi everyone!
I'm making my first game with a friend and we've run into a problem:

When a certain hotspot is clicked we want the character to move to point A and when he reached it, continue to point B.
But we want to be able to move the character to another place if he hasn't reached point A.

example:

MoveCharacter(GetPlayerCharacter(), x1, y1);

// Here we want the script to wait but not the entire game.

MoveCharacterBlocking(GetPlayerCharacter(), x2, y2,1);

Hopefully this makes sense and someone out there knows what to do.
If you do please help us!

strazer

Sorry for the late reply, but I had to gather my strength for all this text: ;)

As I understand it, AGS can't run two scripts at the same time, so it would be blocking either way, since no clicks could be processed while the script waits.

I use this workaround:

I've defined four variables in the global script

short lookat = -1; // storing what/who to look at next
short interact = -1; // storing what/who to interact with next
short talkto = -1; // storing what/who to talk to next
short use = -1; // storing what/who to use active inventory with

which I export of the end of the global script

export lookat,interact,talkto,use;

and import them into the script header, so they can be used in all (room) scripts too

import short lookat;
import short interact;
import short talkto;
import short use;

Now, if the user clicks on an object for example, I put

MoveCharacter(EGO,GetObjectX(0),GetObjectY(0)); // move ego to blue cup
lookat=ID_BLUECUP; // look at blue cup when ego finished walking there

in there. Note that 0 is the number of the object you want the action for.
ID_BLUCUP is defined at the beginning of the room script as

#define ID_BLUECUP    201

It is 201 in this example, but basically just has to be a unique number to differentiate all objects/hotspots/characters. Be sure to assign unique numbers to all objects/hotspots/characters.
For example, I use
numbers 101+ for hotspots
numbers 201+ for objects
numbers 301+ for characters
and numbers 501+ for inventory items.
This is important, because the action variables will be checked by both room and global script.

Now, to check if EGO has reached his destination, I use the repeatedly_execute of the room script

if (player.walking==0) { // player has finished walking
if (lookat > -1) { // player has to look at something
if (lookat==ID_BLUECUP) { // set by clicking on the object
lookat=-1; // reset variable
DisplaySpeech(EGO,"My, it's a blue cup!");
}
}

Note that in order for this to work, you also have to reset all variables when the user clicks the mouse, so he doesn't look at the cup when he finished walking although the user moved him somewhere else. So put in the global on_mouse_click function

...
else if (button==LEFT) {
...
lookat=-1; // stop queued look commands
interact=-1; // stop queued interact commands
talkto=-1; // stop queued talk commands
use=-1; // stop queued use inventory commands
...
ProcessClick(mouse.x, mouse.y,GetCursorMode());
...

That's it basically. Characters are handled in the global script, so you may want to put in its repeatedly_execute function

if (player.walking==0) { // player has finished walking
if (talkto > -1) {
  if (talkto==ID_MAN) {
     talkto=-1;
     FaceCharacter(EGO,MAN);
     RunDialog(1);
  }
}
}

You could of course put the room's repeatedly_execute stuff in the global script, but depending on how many rooms you're going to use, it may get a bit crowded in there. So I decided to handle objects and hotspots in the room script only.

Phew, my longest post ever. Now I'm exhausted. :P

Hope this helps  :)

strazer

P.S. This works for unhandled events too, just use

#define ALLOBJECTS 200

for example and script the appropriate actions in the unhandled_event function.

EDIT

Hm, re-reading the original question I may have gone overboard a bit. Sorry if this doesn't answer your question directly, but it should give you an idea on how to accomplish what you're trying to do.
Anyway, it fits the thread title quite well I think, so maybe it will be of some help to someone else looking for ideas.

Ravenous

Wow!!  :o

That's one hell of an answer... Thank you for taking the time..

And as you say it doesn't answer my question directly it gave me some usefull ideas.
The thing is that I want to make a global function for it so that I won't have to write the same code for the same thing in every room... (Laaaaazy of course ;))

Though I've been sitting with this for too long and my head had almost gone blank :)
So thanks..

strazer

QuoteI want to make a global function for it so that I won't have to write the same code for the same thing in every room...

As I said, I don't think it's possible to stop a script without blocking.

Could you elaborate what x2 and y2

MoveCharacterBlocking(GetPlayerCharacter(), x2, y2,1);

this refers to? Where is point B? Is it the same in every room or specific to the hotspot?

Ravenous

Well right now this is suppososed to be used for doors in rooms.

I have made it so that when the mousecursor for walk_to is over a door-hotspot, it switches to a "go out of the room"-cursor. And if you click the door-hotspot I want the character to move to the door (x1,y1) and then through the door (x2,y2) and then load a new room.

But if you change your mind while the character is moving towards the door you should be able to click on an another part of the room to make him go there instead.

The thing is, I have also made a doubleclick-script so that if you doubleclick the door you move to the new room at once.

All this is put into a global function so that I only have to write
dblclick(newroom,  x1, y1, x2, y2) in the anyclick on hotspot- interaction..

Maybe all this is asking to much and not the most important thing in the game but I am new to this and want to learn how and what is working in AGS..

ps. so point B is different in every room ds

strazer

Alright, so try this:

Global script

Top of global script:

int walkto=-1;

end of global script:

export walkto;

on_mouse_click function:

walkto=-1; // stop queued action commands

Script header

import int walkto;

Room script

Repeatedly_execute for room script (Note: it's not named "repeatedly_execute"):

if (player.walking==0) { // player has finished walking
if (walkto > -1) { // player has reached a door
if (walkto==1) { // if door is hotspot 1
MoveCharacterBlocking(GetPlayerCharacter(), x2, y2,1);
walkto=-1; // reset variable
}
else if (walkto==2) { // if door is hotspot 2
MoveCharacterBlocking(GetPlayerCharacter(), x3, y3,1);
walkto=-1; // reset variable
}
}
}

You could put the above in the global script rep_ex, but as I said depending on how many rooms/doors you have, it may get a bit crowded in there. If you DO put it in the global script, the walkto variable has to be assigned a unique number for every hotspot in the game!

In the "Any click" for each hotspot:

MoveCharacter(EGO,GetHotspotPointX(1),GetHotspotPointY(1)); // move ego to hotspot 1 non-blocking
walkto=1; // execute action 1 after ego reached hotspot

Is this what you were looking for?

Ravenous

Thanks a lot for helping me out this way...

I have to think for a while over here... but I'm  getting there..

Ravenous

YES!! I got it to work.... :o

Tanks a LOT for the help... I modified what you wrote and  got it to work just the way I wanted it!! And all thanks to you. :D

I now have a function in the globalscript called dblclick.
So all I have to put in the "Any click on hotspot"-interaction for a door-hotspot is:
dblclick(room, x1,y1,x2,y2)

Where:
room is the room I want to go to.

x1, y1 are Point A, the place I want the character to go to before going out the door

x2, y2 are Point B, the place I want the character to go to after reaching point A. (i.e going out the door)

And if I doubleclick the doorhotspot the character goes to the new room at once..

Now I am happy ;D

strazer

Excellent. Good work with the function!

Glad I could help.  :)

SMF spam blocked by CleanTalk