Checking if multiple objects are in a container.
Korota
15 May 2014, 00:51Hey, I'm trying out the Quest program for the first time, and I'm not sure how to make a script that checks if multiple objects are in a container before it does an action. Specifically, I'm trying to make a bowl(container) being used check to see if all the necessary ingredients are in the container before removing them and moving a new 'mixture' object into the bowl instead.
HegemonKhan
15 May 2014, 05:16HK's final edit (not the best, nor most comprehensive, but it should, hopefully, be functional)
the ~simpliest is this (not sure where to find the 'ListCount' Script and etc Scripts in the GUI~Editor 's 'add a script' scripts):
the ~simpliest is this (not sure where to find the 'ListCount' Script and etc Scripts in the GUI~Editor 's 'add a script' scripts):
<object name="global_data_object">
<inherit name="editor_object" />
<attr name="bowl_binary_flag_integer" type="int">0</attr>
</object>
'whatever' (custom) Verb Script for your 'bowl' Object:
if (global_data_object.bowl_binary_flag_integer = 0) {
if (name_of_your_ingredient_1.parent = bowl and name_of_your_ingredient_2.parent = bowl and name_of_your_ingredient_3.parent = bowl) {
global_data_object.bowl_objectlist = NewObjectList ()
list add (global_data_object.bowl_objectlist, name_of_your_ingredient_1)
list add (global_data_object.bowl_objectlist, name_of_your_ingredient_2)
list add (global_data_object.bowl_objectlist, name_of_your_ingredient_3)
foreach (item_x, global_data_object.bowl_objectlist) {
item_x.parent = global_data_object
}
on ready {
global_data_object.bowl_binary_flag_integer = 1
msg ("Keep checking the bowl, as your special brew might be finished!")
}
}
} else if (game.bowl_binary_flag_integer = 1) {
if (ListCount (global_data_object.bowl_objectlist) > 0) {
msg ("You got some extra objects still in the bowl, the recipe must be exact, so, you must remove them from the bowl.")
} else if (ListCount (global_data_object.bowl_objectlist) = 0) {
name_of_your_mixture_object.parent = bowl
msg ("Your special brew is finished, you may now pour it into your flask and take it with you.")
global_data_object.bowl_binary_flag_integer = 2
}
}
}
Korota
15 May 2014, 05:50I was worried this would happen. I haven't messed with the actual code behind Quest, so I really don't know how to use that. Is there a way to get that using the actual program interface? If not, I need more details on how and where to input that into the actual code.
HegemonKhan
15 May 2014, 06:31I edited my previous post, my code is now hopefully functional, heh.
HK edit #2, removed the 'on ready' on good advice from Jay
----------
it'd take me too long to try to convert (translate~explain ~ do a step by step guide) it into how to do it with the GUI~Editor (I was hoping you could figure out how to do~find the scripts in the GUI~Editor), so be brave and follow this for doing it in code:
(first save your game with different file name, so you got a backup of your game, which you don't touch, so you still got it if you mess up the other~another game file name that you try to add my code into your game file)
in the GUI~Editor (or you can just open your game file with 'notepad', 'wordpad', or 'notepad++' ~ google it, to download it), and at the top of the screen, is a horizontal bar, between the 'play' and 'help-?' buttons, is a notepaper-like-looking button, this button is a toggle button to switch back and forth between GUI~Editor mode and Code View mode, click on it to go into the Code View mode. In Code View mode (or just already in code, via opening up your game file with a '___pad', aka text, software), simply copy and paste my code into the same spots as shown below:
(indenting the code lines correctly, aka 'nesting', is very important!)
(I put in the blank-line-spaces, to separate the code blocks and some specific code lines, just so you can hopefully understand the code better, but if it causes problems for you to get the correct indentation of all the lines, then delete~remove the blank-line-spaces)
actually, here's the code, without the blank-line spaces for you, so use whichever you want:
------
P.S.
or you can just copy your entire game file's code (or your entire game code from being in the Code View mode), and paste it to me in a post as a pm, or if you don't mind making it public, then you can just post it in this thread, and in either case, I'll add in the code to your game code, and paste post it back to you, either privately as a pm, or as a public post here in this thread.
P.S.S.
but paste your game code within these tags within your public post or private (pm) post, please:
[code.]your_pasted_game_code[/code.]
but don't have the dots~periods within the brackets
it should look like this in your post:
HK edit #2, removed the 'on ready' on good advice from Jay
----------
it'd take me too long to try to convert (translate~explain ~ do a step by step guide) it into how to do it with the GUI~Editor (I was hoping you could figure out how to do~find the scripts in the GUI~Editor), so be brave and follow this for doing it in code:
(first save your game with different file name, so you got a backup of your game, which you don't touch, so you still got it if you mess up the other~another game file name that you try to add my code into your game file)
in the GUI~Editor (or you can just open your game file with 'notepad', 'wordpad', or 'notepad++' ~ google it, to download it), and at the top of the screen, is a horizontal bar, between the 'play' and 'help-?' buttons, is a notepaper-like-looking button, this button is a toggle button to switch back and forth between GUI~Editor mode and Code View mode, click on it to go into the Code View mode. In Code View mode (or just already in code, via opening up your game file with a '___pad', aka text, software), simply copy and paste my code into the same spots as shown below:
(indenting the code lines correctly, aka 'nesting', is very important!)
(I put in the blank-line-spaces, to separate the code blocks and some specific code lines, just so you can hopefully understand the code better, but if it causes problems for you to get the correct indentation of all the lines, then delete~remove the blank-line-spaces)
<asl version="your_version: 550 or whatever ###">
<game name="your_name_of_your_game">
// etc code lines
</game>
<object name="global_data_object">
<inherit name="editor_object" />
<attr name="bowl_binary_flag_integer" type="int">0</attr>
</object>
<object name="whatever it is named, but, if your bowl is inside of another object which is inside this room object, then let me know, if you don't know where to thus add my code lines in that scenario">
<inherit name="editor_room" />
// all your other code lines
<object name="bowl">
<inherit name="editor_room" />
// all your other code lines
<attr name="name_of_your_verb" type="script">
if (global_data_object.bowl_binary_flag_integer = 0) {
if (name_of_your_ingredient_1.parent = bowl and name_of_your_ingredient_2.parent = bowl and name_of_your_ingredient_3.parent = bowl) {
global_data_object.bowl_objectlist = NewObjectList ()
list add (global_data_object.bowl_objectlist, name_of_your_ingredient_1)
list add (global_data_object.bowl_objectlist, name_of_your_ingredient_2)
list add (global_data_object.bowl_objectlist, name_of_your_ingredient_3)
foreach (item_x, global_data_object.bowl_objectlist) {
item_x.parent = global_data_object
}
global_data_object.bowl_binary_flag_integer = 1
msg ("Keep checking the bowl, as your special brew might be finished!")
}
} else if (game.bowl_binary_flag_integer = 1) {
if (ListCount (global_data_object.bowl_objectlist) > 0) {
msg ("You got some extra objects still in the bowl, the recipe must be exact, so, you must remove them from the bowl.")
} else if (ListCount (global_data_object.bowl_objectlist) = 0) {
name_of_your_mixture_object.parent = bowl
msg ("Your special brew is finished, you may now pour it into your flask and take it with you.")
global_data_object.bowl_binary_flag_integer = 2
}
}
</attr>
<attr name="displayverbs" type="listextend">Name_of_your_verb</attr>
<attr name="displayverbs" type="listextend">Name_of_your_verb</attr>
</object>
</object>
// all your other 'tag' (<______>) code lines
</asl>
actually, here's the code, without the blank-line spaces for you, so use whichever you want:
<asl version="your_version: 550 or whatever ###">
<game name="your_name_of_your_game">
// etc code lines
</game>
<object name="global_data_object">
<inherit name="editor_object" />
<attr name="bowl_binary_flag_integer" type="int">0</attr>
</object>
<object name="whatever it is named, but, if your bowl is inside of another object which is inside this room object, then let me know, if you don't know where to thus add my code lines in that scenario">
<inherit name="editor_room" />
// all your other code lines
<object name="bowl">
<inherit name="editor_room" />
// all your other code lines
<attr name="name_of_your_verb" type="script">
if (global_data_object.bowl_binary_flag_integer = 0) {
if (name_of_your_ingredient_1.parent = bowl and name_of_your_ingredient_2.parent = bowl and name_of_your_ingredient_3.parent = bowl) {
global_data_object.bowl_objectlist = NewObjectList ()
list add (global_data_object.bowl_objectlist, name_of_your_ingredient_1)
list add (global_data_object.bowl_objectlist, name_of_your_ingredient_2)
list add (global_data_object.bowl_objectlist, name_of_your_ingredient_3)
foreach (item_x, global_data_object.bowl_objectlist) {
item_x.parent = global_data_object
}
global_data_object.bowl_binary_flag_integer = 1
msg ("Keep checking the bowl, as your special brew might be finished!")
}
} else if (game.bowl_binary_flag_integer = 1) {
if (ListCount (global_data_object.bowl_objectlist) > 0) {
msg ("You got some extra objects still in the bowl, the recipe must be exact, so, you must remove them from the bowl.")
} else if (ListCount (global_data_object.bowl_objectlist) = 0) {
name_of_your_mixture_object.parent = bowl
msg ("Your special brew is finished, you may now pour it into your flask and take it with you.")
global_data_object.bowl_binary_flag_integer = 2
}
}
</attr>
<attr name="displayverbs" type="listextend">Name_of_your_verb</attr>
<attr name="displayverbs" type="listextend">Name_of_your_verb</attr>
</object>
</object>
// all your other 'tag' (<______>) code lines
</asl>
------
P.S.
or you can just copy your entire game file's code (or your entire game code from being in the Code View mode), and paste it to me in a post as a pm, or if you don't mind making it public, then you can just post it in this thread, and in either case, I'll add in the code to your game code, and paste post it back to you, either privately as a pm, or as a public post here in this thread.
P.S.S.
but paste your game code within these tags within your public post or private (pm) post, please:
[code.]your_pasted_game_code[/code.]
but don't have the dots~periods within the brackets
it should look like this in your post:
your_pasted_game_code

jaynabonne
15 May 2014, 13:53Korota, the key line in all of the above (the part that directly answers your question) is this:
Just see if the parent for each object is the desired container. The rest is just setup of the objects (which I assume you already have) and some logic with flags that you may or may not want.
To remove the objects, set their parent to either null or some other place like a "limbo" or "storage" holding room that nobody can see (so they disappear effectively). Then set the parent of the new concoction to the container.
If that helps.
(Note to HK: I would *really* consider getting rid of the "on ready" stuff in your code. It doesn't do anything useful and probably just confuses things!)
if (name_of_your_ingredient_1.parent = bowl and name_of_your_ingredient_2.parent = bowl and name_of_your_ingredient_3.parent = bowl)
Just see if the parent for each object is the desired container. The rest is just setup of the objects (which I assume you already have) and some logic with flags that you may or may not want.
To remove the objects, set their parent to either null or some other place like a "limbo" or "storage" holding room that nobody can see (so they disappear effectively). Then set the parent of the new concoction to the container.
If that helps.
(Note to HK: I would *really* consider getting rid of the "on ready" stuff in your code. It doesn't do anything useful and probably just confuses things!)
HegemonKhan
15 May 2014, 14:17my apologizes for the 'on ready', I put it in whenever I'm unsure of if there'll be a conflict between running scripts, as I'm still not sure of, or nnot clear on, all the rules with them in their nested running. I do it as a precaution, but if it's not needed, then certainly remove my 'on ready'-ies. I guess until I learn better about the ordering-running (nesting) of scripts, I could instead not put it in, and if not having the 'on ready'-ies causes a problem, then put the 'on ready' into the code to fix the problem, as I didn't realize it would be confusing people having the 'on ready'-ies in my code, again my apologizes for any confusion with my code (HK still crosses his fingers that his entire code does work, laughs. I'm also still using v540, so the format or syntax may not be correct for v550, also).

jaynabonne
15 May 2014, 14:29I won't divert this thread too much, but "on ready" has specific uses related to delaying some things from happening until after all special input modes like "get input" and "showmenu" are completed. For example, if you do the following:
then you won't see "get input is done" until the get input finishes. While that can be useful as a concept, it's not really needed for everyday scripters - just put the msg inside the script attached to the get input itself. It's really only used (to my knowledge) deep down inside the core code where certain processing needs to be delayed until all special input modes are done - like showing room descriptions. If you were ever writing library code to be used inside a game, you *might* have a very special case where you'd want to delay the output until a get input/showmenu is done (I never have in all my time writing code), but for cases like the code you posted, it doesn't actually do anything. (And I only meant "confusing" in that, if people aren't really big on scripting anyway and trying to work out what everything does, throwing in something obscure like "on ready" is just going to raise more questions than it answers.)
And now back to your regularly scheduled thread...
get input {
// some script commands
}
on ready {
msg("get input is done")
}
then you won't see "get input is done" until the get input finishes. While that can be useful as a concept, it's not really needed for everyday scripters - just put the msg inside the script attached to the get input itself. It's really only used (to my knowledge) deep down inside the core code where certain processing needs to be delayed until all special input modes are done - like showing room descriptions. If you were ever writing library code to be used inside a game, you *might* have a very special case where you'd want to delay the output until a get input/showmenu is done (I never have in all my time writing code), but for cases like the code you posted, it doesn't actually do anything. (And I only meant "confusing" in that, if people aren't really big on scripting anyway and trying to work out what everything does, throwing in something obscure like "on ready" is just going to raise more questions than it answers.)
And now back to your regularly scheduled thread...

Espera
19 May 2014, 20:55From the perspective of someone who uses the code less and relies on the QUI, what you need to do is stack 'if' statements. I did this same thing in my first game, having the player collect different ingredients, put them into a cauldron and mix potions. It can get a bit ugly in the UI, but you have to bear with it. Start with a verb like 'mix', then for the verb script start with 'If object 'bowl' contains object 'eggs'." and for the 'then' script, instead put another 'if' script like 'if object 'bowl' contains object 'flour', and so on until the bowl contains all the objects, then you can do your outcome, which will likely involve removing all the ingredients and moving another object, like ''batter' into the bowl and describing the process.
HegemonKhan
20 May 2014, 00:35nested~indented~stacking 'if's' is certainly useful, not just for noobs, as it makes it easy for us to understand the flow of the conditions:
if (player.alias = "HK") {
-> if (player.age_integer = 18) { // I wish I was 18, lol
->-> if (player.gender_string = "male") {
->->-> if (player.eye_color_string = "blue") {
->->->-> if (player.hair_color_string = "dark brown") {
->->->->-> msg ("Yep, that's, indeed, me, HK!")
->->->-> } else if (not player.hair_color_string = "dark brown") {
->->->->-> msg ("nope, that's not me!")
->->->-> }
->->-> } else if (not player.eye_color_string = "blue") {
->->->-> msg ("nope, that's not me!")
->->-> }
->-> } else if (not player.gender_string = "male") {
->->-> msg ("nope, that's not me!")
->-> }
-> } else if (not player.age_integer = 18) {
->-> msg ("hmm... that number may be my real age, hehe")
-> }
} else if (not player.alias = "HK") {
-> msg ("nope, that's not me!")
}
though, if you want to shorten it, you can do this instead:
if (player.alias = "HK" and player.age_integer = 18 and player.gender_string = "male" and player.eye_color_string = "blue" and player.hair_color_string = "dark brown") {
-> msg ("Yep, that's, indeed, me, HK!")
} else if (not player.alias = "HK" and not player.age_integer = 18 and not player.gender_string = "male" and not player.eye_color_string = "blue" and not player.hair_color_string = "dark brown") {
-> msg ("nope, that's not me!")
}
and there's some other code methods, to shrink your code-typing amount even more (but these are a bit confusing for noobs):
StringListItem
ObjectListItem
StringDictionaryItem
ObjectDictionaryItem
ScriptDictinaryItem
and etc even more advanced coding methods
if (player.alias = "HK") {
-> if (player.age_integer = 18) { // I wish I was 18, lol
->-> if (player.gender_string = "male") {
->->-> if (player.eye_color_string = "blue") {
->->->-> if (player.hair_color_string = "dark brown") {
->->->->-> msg ("Yep, that's, indeed, me, HK!")
->->->-> } else if (not player.hair_color_string = "dark brown") {
->->->->-> msg ("nope, that's not me!")
->->->-> }
->->-> } else if (not player.eye_color_string = "blue") {
->->->-> msg ("nope, that's not me!")
->->-> }
->-> } else if (not player.gender_string = "male") {
->->-> msg ("nope, that's not me!")
->-> }
-> } else if (not player.age_integer = 18) {
->-> msg ("hmm... that number may be my real age, hehe")
-> }
} else if (not player.alias = "HK") {
-> msg ("nope, that's not me!")
}
though, if you want to shorten it, you can do this instead:
if (player.alias = "HK" and player.age_integer = 18 and player.gender_string = "male" and player.eye_color_string = "blue" and player.hair_color_string = "dark brown") {
-> msg ("Yep, that's, indeed, me, HK!")
} else if (not player.alias = "HK" and not player.age_integer = 18 and not player.gender_string = "male" and not player.eye_color_string = "blue" and not player.hair_color_string = "dark brown") {
-> msg ("nope, that's not me!")
}
and there's some other code methods, to shrink your code-typing amount even more (but these are a bit confusing for noobs):
StringListItem
ObjectListItem
StringDictionaryItem
ObjectDictionaryItem
ScriptDictinaryItem
and etc even more advanced coding methods