Hey guys! I would like to know how to do something like in Art of Theft or 1213 where you interact with something pressing the UP key. This is what i tried:
function region2_Standing()
{
if (keycode == eKeyUpArrow) player.Say ("Something");
}
In that part there is a PC and you step on in front of it (Region 2) and i want the character to make a comment about the PC when UP is pressed (When I say UP, I mean the up arrow), but when i try to run it, it says:
Failed to save room room4.crm; details below
room4.asc(17): Error (line 17): undefined symbol 'keycode'
Could anyone out there help me? ???
I'm just guessing here, but try to make the (K) capital in keycode.....(Keycode)
if Keycode is the proper terminology when your typing it, Keycode should pop up after you type in the first three letters...
EDIT: And that's why I don't like to guess.
keycode is a local variable used by the on_key_press function.
Find it in the global script, then add this inside:
if (keycode == eKeyUpArrow) {
Region*rr = Region.GetAtRoomXY(player.x, player.y);
if (rr.ID > 0) {
// handling code, we'll fill this in later, see below
}
}
Now you need a way to assign the regions to hotspots and objects. Unfortunately, regions don't have custom properties, so we need to loop through objects and hotspots.
Put this function in the global script, above on_key_press:
int GetIDForRegion(int id) {
int i;
while (i < Room.ObjectCount) {
if (object[i].GetProperty("region") == id) return -i;
i++;
}
i = 1;
while (i < AGS_MAX_HOTSPOTS) {
if (hotspot[i].GetProperty("region") == id) return i;
i++;
}
}
Now open the Properties of the PC hotspot, click Edit Schema and add a new property by right-clicking in the empty window. Add a property of type "Number", name "region", default value "0". Use any description you want, maybe "region number". Mark only hotspots and objects, then click ok and close the schema editor.
Back at the PC's custom properties, set the region to 2.
Now we need the handling code.
int p = GetIDForRegion(rr.ID);
if (p > 0) hotspot[p].RunInteraction(eModeInteract);
else object[-p].RunInteraction(eModeInteract);
So what happens is if you press up while standing on a region, AGS checks the region property of all hotspots and objects in the current room and if it's the one you're standing on, AGS runs the event "Interact with ...".
So that's where you'd put code specific to interacting with the PC for example.
--------
(There is another way; you could use IsKeyPressed() (http://www.adventuregamestudio.co.uk/manual/IsKeyPressed.htm) and handle the interaction directly, the only problem is that holding the button even for a short time will trigger the event multiple times.)
Edit: Forget it, I corrected it!
Thanks guys for the help!
Did this code work for you without modification, Ekeko?
I'm doing something similar and not having any luck.
Quote from: KodiakBehr on Mon 10/10/2011 19:59:55
Did this code work for you without modification, Ekeko?
I'm doing something similar and not having any luck.
Yes it worked although I had a hard time making it work, I didn't had to change anything... :-\ What problem are you getting?
rr.ID never goes above zero.
Does the second bit of code that's intended to be above on_key_press need to be within a specific function?
Quote from: KodiakBehr on Mon 10/10/2011 20:21:47
rr.ID never goes above zero.
Does the second bit of code that's intended to be above on_key_press need to be within a specific function?
Hmmm... I didn't got that error... :-\ I pasted that code below the closing brace of the function
repeatedly_execute_always. Where did you paste it? Maybe there's the prob...
EDIT: Wait, have you modified the property of the hotspot?
I put it in the same place. The hotspot has a property known as "region" that is set to 2, as per the instructions.
The only difference was that the variables "i" and "p" were already in use and were substituted for unused two-character variables. I did this twice just to make sure there wasn't an "i" or a "p" missed. It's very frustrating when somebody holds your hand through the code like this and you still can't pull it together.
Quote from: KodiakBehr on Mon 10/10/2011 20:41:06
I put it in the same place. The hotspot has a property known as "region" that is set to 2, as per the instructions.
The only difference was that the variables "i" and "p" were already in use and were substituted for unused two-character variables. I did this twice just to make sure there wasn't an "i" or a "p" missed. It's very frustrating when somebody holds your hand through the code like this and you still can't pull it together.
Maybe I'm about to say something that might be wrong... But I think that two-character variables can't be used... Why don't you try numbers, for example? And have you already used ALL letters? (I don't really know if numbers can be used, because I have never made great use of variables, actually)
EDIT: So yeah, I was wrong.
Quote from: Ekeko on Mon 10/10/2011 20:57:24Maybe I'm about to say something that might be wrong... But I think that two-character variables can't be used
Nope. It just sounds like the hotspots aren't set up correctly.
Did you create global variables i & p? That's a bad idea; always use longer, descriptive names for global variables.
Just to make sure, it's supposed to look like this:
Global script:
...
...
int GetIDForRegion(int id) {
int i;
while (i < Room.ObjectCount) {
if (object[i].GetProperty("region") == id) return -i;
i++;
}
i = 1;
while (i < AGS_MAX_HOTSPOTS) {
if (hotspot[i].GetProperty("region") == id) return i;
i++;
}
}
function on_key_press(eKeyCode keycode) {
if (keycode == eKeyUpArrow) {
Region*rr = Region.GetAtRoomXY(player.x, player.y);
if (rr.ID > 0) {
int p = GetIDForRegion(rr.ID);
if (p > 0) hotspot[p].RunInteraction(eModeInteract);
else object[-p].RunInteraction(eModeInteract);
}
}
...
// rest of on_key_press code
...
}
...
If rr.ID keeps being 0, make sure that what you have drawn is actually regions, not walkbehinds or hotspots.
Also make sure that the player can actually step on them; they aren't a replacement for hotspots, they are meant to mark the part of the walkable area in front of the hotspot/object.
Variable names can have lots of characters, they obviously can't be numbers though.
That did it. I was using hotspots instead of regions. Silly me -- I didn't understand that both are necessary.
Thanks to all.
I suppose I can mark the thread as SOLVED since we're all happy now! ;)
It didn't occur to me until now but you don't really need to draw hotspots. It's enough to name them and set up the interaction(s) and region number.
Thinking about this further, that means it makes more sense to use regions only for objects and draw the hotspots not over the background object but the floor area.
That way one can use region 1 for object 1, region 2 for object 2, etc. while the game also checks for hotspots at the player's feet.
So no need for all the custom property business.
On the other hand, seeing all areas where pressing UP triggers something at once isn't such a bad thing either.
Quote from: LeKhris on Mon 10/10/2011 22:03:57
It didn't occur to me until now but you don't really need to draw hotspots. It's enough to name them and set up the interaction(s) and region number.
Thinking about this further, that means it makes more sense to use regions only for objects and draw the hotspots not over the background object but the floor area.
That way one can use region 1 for object 1, region 2 for object 2, etc. while the game also checks for hotspots at the player's feet.
So no need for all the custom property business.
On the other hand, seeing all areas where pressing UP triggers something at once isn't such a bad thing either.
Wow... You... Simply... ROCK, MAN!
In case you want to switch, here'd be code:
// in on_key_press
if (keycode == eKeyUpArrow) {
int x = player.x - GetViewportX(), y = player.y - GetViewportY();
Hotspot*h = Hotspot.GetAtScreenXY(x, y);
if (h.ID > 0) h.RunInteraction(eModeInteract);
else {
Region rr = Region.GetAtRoomXY(player.x, player.y);
if (rr.ID > 0) object[rr.ID].RunInteraction(eModeInteract);
}
}
So no extra function and no properties necessary.
Quote from: LeKhris on Tue 11/10/2011 00:02:29
In case you want to switch, here'd be code:
// in on_key_press
if (keycode == eKeyUpArrow) {
int x = player.x - GetViewportX(), y = player.y - GetViewportY();
Hotspot*h = Hotspot.GetAtScreenXY(x, y);
if (h.ID > 0) h.RunInteraction(eModeInteract);
else {
Region rr = Region.GetAtRoomXY(player.x, player.y);
if (rr.ID > 0) object[rr.ID].RunInteraction(eModeInteract);
}
}
So no extra function and no properties necessary.
Thanks! :D You are AWESOME!! :D