Problem with non-playable character interactions [SOLVED]

Started by Python, Sun 11/12/2011 22:32:49

Previous topic - Next topic

Python

First of all, hello! I'm new to this forum and to AGS!  :)
I started with AGS for about a week or two, saw some tutorials on densming channel (which are awesome) and read the tutorials here on the site, but none of them actually explained if it is possibl to make non-playable characters interact with the background.  ???

For example: I have a cutscene where the non-playable character leaves the room, but to do that, he must open the door, etc.  ;D
Tried with IsCollidingWithChar, but failed, so here I am asking it. xD

Any help would be appreciated.  ;)

Khris

Your question doesn't make any sense whatsoever.
What's keeping you from simply putting everything you want to happen directly into the cutscene code?
You know exactly what's supposed to happen; you don't need to provide a reacting environment for an NPC, you can simply call the necessary commands.
And why the hell would you need IsCollidingWithChar..!?

The only way I can see in which your question makes any sense is if the interaction calls lots of commands and you don't want to have lots of duplicate code:

Code: ags
function char_leaves_room_by_door(Character*c) {
  c.Walk(243, 124, eBlock);
  // animation, reach for door knob
  if (c == player) c.LockView(3);
  else if (c == cNpc) c.LockView(4);
  c.Animate(3, 2);
  c.UnlockView();
  oDoor.SetView(7);
  oDoor.Animate(...);
  c.Walk(245, 119);
}


Now you can put this in the player's interaction:

Code: ags
function oDoor_Interact() {

  char_leaves_room_by_door(player);
  player.ChangeRoom(5);
}


And this in the cutscene code:

Code: ags
function ... {

  ...
  cNpc.Say("Ok, I'll go and get it.");
  char_leaves_room_by_door(cNpc);
  cNpc.ChangeRoom(-1);
  ...
}


This still isn't an NPC interaction; you simply told the NPC what to do.

monkey0506

Is there any reason you can't just run the same interactions that you would if it was the player?

For example:

Code: ags
// NPC leaves room through door
cNPC.Walk(oDoor.X + 10, oDoor.Y + 5); // or whatever coordinates match where the character would stand to open the door
// animate the character reaching for the door, if applicable
oDoor.Graphic = 42; // or whatever graphic matches the open door, or use Object.Animate
cNPC.Walk(oDoor.X + 10, oDoor.Y - 5); // or whatever coordinates match the character's position on the other side of the door, set WalkWhere to eAnywhere if necessary
// change oDoor.Graphic or animate oDoor if necessary to close it




Khris beat me. :=

If you wanted a function to do it, you could put in the room script:

Code: ags
// room script

void LeaveRoom(this Character*)
{
  this.Walk(oDoor.X + 10, oDoor.Y + 5);
  // ...
  oDoor.Graphic = 42;
  this.Walk(oDoor.X + 10, oDoor.Y - 5);
  // ...
}

// then, wherever within the room script
cNPC.LeaveRoom();
player.LeaveRoom();

Python

Wow guys, calm down, I'm just an AGS newbie trying to learn. Well, thanks for the replies, anyway.  :)
It's my first time doing cutscenes, so I just wanted to know how the things happens and as I do not know how some commands work, I just thought that maybe when he collides with the door, it could activate something, etc.

Khris

This isn't an issue of not knowing how some commands work.
A cutscene by definition doesn't require handling interactions in the sense that one defines how AGS reacts to player input because during a cutscene there won't be any. Every cutscene is a static series of events, there's simply no need to react, just to follow orders. You don't need to check for any collisions since you can simply order the NPC to walk to any set of specific coordinates, then issue the next command and so on.*

Conceptually, teaching a cop how to deal with a variety of threats is very different from telling them to get coffee and donuts.

*An exception would be a cutscene that includes the NPC waiting for/using some automatic feature of the current room. An example would be a paternoster with the NPC waiting for a free compartment. That's a special case though and monkey and I simply wanted to nip the misconception in the bud.

AnasAbdin

#5
with all due respect to my Yodas Khris & monkey_05_06 :) sometimes a beginner needs another beginner to help! LOL

Python, there is no difference which character interacts with whatever... All characters have views, inventories.. etc... so when an NPC has a problem, IMHO it would be a problem to the player character and every other character as well...
-For now- the main difference between the player character and NPCs is that the room of which the PLAYER character exists in IS the current displayed room.

So if we say that your NPC is Jimbo, a code like this would help:
Code: ags

cJimbo.Walk(...);          //to the door
cJimbo.ChangeView(...);    //Jimbo arm raise view
oDoor.SetView(...);        //door open view
cJimbo.Animate(...);       //animate Jimbo
oDoor.Animate(...);        //animate the door opening
cJimbo.ChangeView(...);    //Jimbo is back to his normal walking view
cJimbo.Walk(...);          //Jimbo walks through the door to the desired x,y
oDoor.Animate(...);        //animate the door backwards to close it
cJimbo.ChangeRoom(...);    //if you want to send Jimbo somewhere else...
Code not tested DAH!

put in mind that whenever you use eBlock the player cannot do anything until the animation/walk finishes.
I hope I was clear and helpful :)

Khris

Quote from: AnasAbdin on Mon 12/12/2011 05:13:09sometimes a beginner needs another beginner to help! LOL

I seriously doubt that, and your post kinda drives that home. It's confusing (especially the part about an NPC having a problem) and otherwise just reiterates how to code a cutscene using badly spelled or non-existent commands.
It also doesn't address the actual problem in any way.

Snarky

I think AnasAbdin has a point. Veterans may be too familiar with the assumptions that AGS programming are based on to realize that anyone could think in any other way, while recent newbies better remember the things they had to wrap their heads around as they were learning.

Python's question may have made no sense, but the way in which it made no sense gives some clues to how he's thinking. For example, the reference to IsCollidingWithChar seems to indicate that he hasn't grasped blocking functions, so he thinks he needs to check whether the NPC has reached the door yet.

Anas explained that, as well as some of the other basic points, like that there's very little difference between an NPC and a player character, and that "interacting with a background" pretty much always means either walking around or playing an animation (either on the character itself or on an object in the room). Whether the code itself is perfectly correct is less critical, IMO.

Python

Hey guys, thanks for the replies again. :)

@Anas:

Wow, that sure helped me a lot, really. I just knew 2 or 3 commands from that list. xD

@Others:

Actually, I think I solved my problem after all, haha. All I wanted was to make the non-playable character open the door and leaves the room, so I tried messing around with some codes and made it (well, at least it worked). Take a look:

cNonP.Walk(248, 159, eBlock, eWalkableAreas);
oDoor2C.Visible=false;
oDoor2O.Visible=true;
Wait(15);
cNonP.ChangeRoom(6, 61, 159);
oDoor2C.Visible=true;
oDoor2O.Visible=false;

I'm a game maker veteran, that's why I'm still not familiar with AGS 100%, hehe. The ways to create cutscenes aren't the same (as GM have timelines, etc), so I'm still trying to learn some new things.
Thanks for all the help again guys.  ;D

Khris

Quote from: Snarky on Mon 12/12/2011 08:57:47Veterans may be too familiar with the assumptions that AGS programming are based on to realize that anyone could think in any other way, while recent newbies better remember the things they had to wrap their heads around as they were learning.

That's right, in the special case that the guy with experience misses a crucial misconception. Good point about trying to substitute IsCollidingWithChar for eBlock. You caught it though, not the other newbie :)

Python:
Regarding AnasAbdin's code that "sure helped a lot":
He's using all the commands I've used in my very first reply, but misuses Character.ChangeView (instead of .LockView, Animate, UnlockView).

Regarding the door objects: instead of using one for the open door and one for the closed door you can use just one and change its graphic. To do that, the two sprites must be aligned properly, but even if they aren't you can easily change the object's position.

Python

Quote from: Khris on Mon 12/12/2011 13:17:59
Regarding the door objects: instead of using one for the open door and one for the closed door you can use just one and change its graphic. To do that, the two sprites must be aligned properly, but even if they aren't you can easily change the object's position.

Could you explain me how could I do that? oDoor2C.Graphic?

Thanks.  :)

NickyNyce

This might help... look in the manual under Object.Graphic


object[2].Graphic = 100;

[2] is the object number and 100 is the sprite #

Khris

It's not necessary to use the object array in a room script.

Python:
Delete one of the objects and rename the other to oDoor2.
Then set oDoor2.Graphic to the sprite's number, yes.

monkey0506

I'm not sure, from reading it, what Anas said that Khris and I didn't in some way try to explain, although I do understand that sometimes just saying something differently can be useful. Of course the bit about "code not tested" does imply that the "code" stands even a remote chance of compiling (it doesn't, seeing as none of the required parameters were passed to any of the functions).

I've never used Game Maker, so I'm not sure about timelines, but the manual has an entry (Scripting -> Understanding blocking scripts) that should help explain the difference between how blocking and non-blocking scripts work (the basic difference is what events are run). AGS handles checking for things like when the mouse is clicked or when a button on the keyboard is pressed (it is an engine after all), and it calls certain functions based on those events. Some functions are called specifically when the human player clicks the mouse on a certain hotspot, object, or character with a certain mouse mode specified. These are your interaction functions. You can call them yourself if you want, or you can just let AGS handle it.

If you want a specific non-player character to go through all the same motions, you could set up a custom function like me and Khris showed how to do, and then simply call that function for the player within the interaction function, and call it as needed for NPCs.

Oh, and the term "cutscene" is getting tossed around. I've always been of the impression that a "cutscene" is a "scene that can be cut, or skipped". Of course people have come up with the idea of a "non-skippable cutscene" but that's just a bunch of malarkey in my opinion. If you want a skippable cutscene you have to use the StartCutscene and EndCutscene functions. :=

Edit: This is what I get for leaving a half-typed reply, driving to work, and trying to finish it on my laptop. 4 new posts? Egads! But still, it's already typed so! :P

Python

Oh, I got it worked. Thank you Khris and everybody who replied.  ;D

Snarky

Quote from: monkey_05_06 on Mon 12/12/2011 14:20:22
Oh, and the term "cutscene" is getting tossed around. I've always been of the impression that a "cutscene" is a "scene that can be cut, or skipped". Of course people have come up with the idea of a "non-skippable cutscene" but that's just a bunch of malarkey in my opinion. If you want a skippable cutscene you have to use the StartCutscene and EndCutscene functions. :=

Wikipedia says:
The word "cutscene" itself was possibly first coined by Ron Gilbert while making Maniac Mansion, wherein he defined cutscenes as short "scenes" that "cut" away from the action itself, to show what else was happening in the game world when the player wasn't around.

But essentially a cutscene is any storytelling sequence that plays without player input or interaction.

SMF spam blocked by CleanTalk