Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: timebandit on Fri 08/01/2021 11:45:15

Title: Enable dialogue if player has looked at an object
Post by: timebandit on Fri 08/01/2021 11:45:15
I want to make it so that cPlayer has to have had looked at an object, oHouse, before dKing2 happens.

I know what I would write if dKing2 was enabled by a dialogue option from another dialogue:
Code (ags) Select

Function cKing_Interact
{
if (dTroll.HasOptionBeenChosen(1))
{dKing2.Start();
}
else {dKing1.Start();}
}


So for necessary dialogues, I would need
"dTroll.HasOptionBeenChosen(number)".

And for necessary inventory items, I would need
"Player.HasInventory(iFootball)".

But what do I need to write if I want dKing2 to happen after cPlayer has looked at an object?

I haven't been able to find the answer in the manual, unlike the other two "conditions" I've mentioned here.

I searched the forums and found someone writing "(UsedAction (A_LOOK_AT))" but it didn't work for me and it was only written once on this forum.
Title: Re: Enable dialogue if player has looked at an object
Post by: eri0o on Fri 08/01/2021 12:00:14
You can create a global boolean variable like has_looked_at_house and set it to true after the player has done the action you want and just check for it when interacting with the King character. If you go this route there is a global variable menu in Project Explorer that should help making this easier.

See adventuregamestudio.github.io/ags-manual/GlobalVariables.html (https://adventuregamestudio.github.io/ags-manual/GlobalVariables.html)

If both the interactions (looking at the house and interacting with the king) are in the same room, then you don't even need a global variable at all, just declare the boolean variable at the top of the room script and set and check it in the appropriate look and interact functions. edit: I just remembered that character interactions are always in global script, while the object will be in Room Script. :/
Title: Re: Enable dialogue if player has looked at an object
Post by: isatche on Sat 16/01/2021 07:32:20
I would use variables here. Add something like: int look=0; at the very top
When the character looks at that something, add this line below the look description: look=1;
The you just check if (look==1) {dKing2.Start();} else {dKing1.Start();}

I hope it helps :)

P.S. I didn't test the code, it's just the path I would take.
Title: Re: Enable dialogue if player has looked at an object
Post by: timebandit on Mon 18/01/2021 21:17:46
Thanks to both of you. I haven't really understood how I create and define a global variable yet so I guess I'll have to understand that before I can proceed with your solutions.
Title: Re: Enable dialogue if player has looked at an object
Post by: Khris on Mon 18/01/2021 21:43:51
The Global Variables pane is part of the project tree in the editor. Open it and right-click the empty list to create a new variable.
Title: Re: Enable dialogue if player has looked at an object
Post by: timebandit on Tue 19/01/2021 16:36:45
But how do I tell AGS that the variable "has_looked_at_object" is supposed to relate to the player looking at the object? How do I define what the variable actually relates to?
Title: Re: Enable dialogue if player has looked at an object
Post by: Khris on Tue 19/01/2021 17:30:42
You don't have to do that at all, you set the variable when you want it to change, and you read the variable when you want to know its value.
If you're concerned with remembering what the variable is used for, use a name like "player_has_looked_at_weird_box_in_ante_room".
Title: Re: Enable dialogue if player has looked at an object
Post by: Manu on Wed 20/01/2021 18:29:07
Quote from: timebandit on Tue 19/01/2021 16:36:45
But how do I tell AGS that the variable "has_looked_at_object" is supposed to relate to the player looking at the object? How do I define what the variable actually relates to?

I know that people more expert than me will disagree, but this is why I prefer to use the custom properties of the objects. In my case I have defined a new boolean property called "hasBeenExamined" and it applies to all objects. This way I can do something like:

Code (ags) Select

if (oNotebook.GetProperty("hasBeenExamined")) {
   dDialog1.Start();
}
else {
   cCharacter.Say("Can't talk right now");
}


I believe it's more readable even thought the fact that there is no autocomplete/syntax check on the name of the property is annoying.
Title: Re: Enable dialogue if player has looked at an object
Post by: Crimson Wizard on Wed 20/01/2021 18:40:54
Quote from: emabolo on Wed 20/01/2021 18:29:07
I know that people more expert than me will disagree

Not at all, since custom properties were made precisely to be able to attach something new to game objects. The way they are currently made is not convenient for giving unique traits to individual objects, so that's a matter of compromise.

The biggest limitation of custom property actually is that it can only be an integer number or String, and nothing else. Also, as its bound to object, you cannot access it if the object is in another room.
Title: Re: Enable dialogue if player has looked at an object
Post by: timebandit on Wed 27/01/2021 11:19:35
Quote from: emabolo on Wed 20/01/2021 18:29:07

I know that people more expert than me will disagree, but this is why I prefer to use the custom properties of the objects. In my case I have defined a new boolean property called "hasBeenExamined" and it applies to all objects. This way I can do something like:

Code (ags) Select

if (oNotebook.GetProperty("hasBeenExamined")) {
   dDialog1.Start();
}
else {
   cCharacter.Say("Can't talk right now");
}


Could you write a step-by-step guide of what you do when creating the variable "hasBeenExamined" and making it work? Like, first you click "create global variable" or what it now says on the sidebar. What do you do after that?
Title: Re: Enable dialogue if player has looked at an object
Post by: Khris on Wed 27/01/2021 11:34:51
emabolo is doing precisely not that but creating custom properties instead.

Here's how: https://www.adventuregamestudio.co.uk/manual/ags19.htm#topic30
Title: Re: Enable dialogue if player has looked at an object
Post by: Manu on Mon 01/02/2021 15:17:32
Quote from: timebandit on Wed 27/01/2021 11:19:35
Could you write a step-by-step guide of what you do when creating the variable "hasBeenExamined" and making it work? Like, first you click "create global variable" or what it now says on the sidebar. What do you do after that?

Sorry for the delay, I didn't see your post, I hope you have already solved it. Anyway, just in case, here you have some more info

First, you have to define your new custom property. You do it by selecting an object (or hotspot, or inventory item) and accessing the Properties grid on the bottom right of the screen. Double-click "(Properties)" to open the definition of the custom properties. Initially, you won't see anything, so click  "Edit Schema" and then with a right-click, Add New Property. You can choose the type (for example "bool") and the default value (use "0", not "false").

What is important to understand, is that the properties are shared. If you create a property "hasBeenExamined" for the oKettle object, all the other objects can start using a new property called "hasBeenExamined", not just the kettle. But you can choose if the property applies only to objects, or also to hotspots for example. I normally select both inventory items and objects.

Now, in your code, you can do something like this:

Code (ags) Select

oKettle_Look() {
if (oKettle.GetProperty("hasBeenExamined") == 1) {
  player.Say("I already examined the kettle.");
}
else {
  player.Say("What a nice kettle!");
  oKettle.SetProperty("hasBeenExamined", 1);
}
}


It's a bit ugly that you have to use double quotes, and the fact that there is no autocomplete, but you just need to be careful. Also, since the definition is shared, it's not a good idea to do something like "maxSpeed" for the object "car", "numBullets" for the object "gun", "inkColor" for the object "pencil"  and things like that. But for generic properties, especially boolean, like "isEmpty", "hasBeenUsed", "hasBeenExamined", and so on, I believe it's a good choice.

Title: Re: Enable dialogue if player has looked at an object
Post by: Crimson Wizard on Mon 01/02/2021 15:37:22
Quote from: emabolo on Mon 01/02/2021 15:17:32
It's a bit ugly that you have to use double quotes, and the fact that there is no autocomplete, but you just need to be careful.

I posted this in another recent thread where similar problem was brought up: you can declare macros for your strings, then you'll have autocomplete + compiler will detect if you use wrong name by mistake.

For example:
Code (ags) Select

#define PROP_HASBEENEXAMINED "hasBeenExamined"


and then use it like
Code (ags) Select

oKettle.GetProperty(PROP_HASBEENEXAMINED);
Title: Re: Enable dialogue if player has looked at an object
Post by: Kyrridas on Mon 08/02/2021 02:49:21
sort of related:

is it possible to call a variable within the same dialogue? something like this, but that actually works:

Code (ags) Select

@S
  if (TriedTheDoor == true){
  Option-on 4
  }


obviously that doesnt work because Option-on is dialog scripting that doesnt get along with normal scripting. so is there scripting (in either 'language') that would accomplish this task? it seems like it would be a pretty common adventure game mechanic.

my knee-jerk reaction is to simply create two dialogs that are identical, except for the additional option, and simply call the appropriate one when conversation is started. but that seems needlessly heavy-handed.


basically, the player can ask a bartender for a suggestion on how to proceed. and once you've tried his suggestion, talking to him again should give an option for "hey, i tried that thing and it didnt work", to which he replies with a different suggestion.
Title: Re: Enable dialogue if player has looked at an object
Post by: Crimson Wizard on Mon 08/02/2021 03:11:22
Quote from: Kyrridas on Mon 08/02/2021 02:49:21
sort of related:

is it possible to call a variable within the same dialogue? something like this, but that actually works:

Code (ags) Select

@S
  if (TriedTheDoor == true){
  Option-on 4
  }


obviously that doesnt work because Option-on is dialog scripting that doesnt get along with normal scripting. so is there scripting (in either 'language') that would accomplish this task?

Yes ofcourse, just remove indentation from "option-on".

Dialog scripts are treated like this: if command has no indentation - that's special dialog command, if it has indentation - that's regular script command.
Kind of primitive parsing, but guess that was easiest to do at the time...
Title: Re: Enable dialogue if player has looked at an object
Post by: Kyrridas on Mon 08/02/2021 03:22:19
well, dang. that's easy enough. i figured indented and undented (is that a word?) scripting wouldn't function together like that. just tried it, works fine. thanks!
Title: Re: Enable dialogue if player has looked at an object
Post by: Crimson Wizard on Mon 08/02/2021 03:29:27
The dialog scripts are secretly converted into normal script during game compilation, so every option-on etc command ends up being either a regular script statement or a call to script function, like Dialog.SetOptionState.
Indentation rule there is only to make it easier for editor to distinguish them.