Closing The Loop

Encrtia
09 Oct 2015, 02:06
So I create some Wheat. And I let the player "Pick" the wheat with a new verb.

AddToInventory (Wheat Stem)
msg ("You decided to pick one of the wheat stems.")


That's great. Now, with the Wheat Stem Object, I let him eat it. He ate it. Cool.

Now, the player goes to pick up another Wheat stem.

Error running script: Unknown object or variable 'Wheat Stem'.

No doubt, the player can't add an object to his inventory that was already added & eaten (deleted?), so how do I allow the player to be permitted to continually add a maximum of 1 Wheat Stem to his inventory, even after the object's been eaten?

Disclaimer: I'm not sure what to search for in the forums to find a solution to this.. apologies if I'm duplicating a thread..

XanMag
09 Oct 2015, 02:23
After you 'eat wheat stem', use the move object script to move the wheat stem back to the place where you picked it. Then it will be pickable and edible again.

My desert berry in my first game is a bit more complex than that - it IS a magically berry after all... but the code for it is below. I think you can just do as I mentioned above and it should work though.

if (HasString(this, "eatmsg")) {
msg (this.eatmsg)
}
else {
msg (DynamicTemplate("Eaten", this))
}
if (HasInt(game.pov, "health")) {
game.pov.health = game.pov.health + this.eathealth
}
MoveObject (desert berry, desert shrub)
if (ListContains(ScopeVisible(), desert shrub)) {
msg ("<br/>You watch the purple gas swirl in the air, pause for a brief moment, and dive directly into the desert shrub. A flower blooms on the bush, and the flower morphs into a new berry right in front of your eyes!<br/>")
}
else if (not ListContains(ScopeVisible(), desert shrub)) {
msg ("<br/>The purple gas swirls in the air, pauses for a brief moment, and zooms off in the direction of the desert shrub from which it was plucked!<br/>")
}


You will probably want to put an 'If/Then' script to check to see if the player has already picked a wheat stem. If the player picks a wheat stem maybe raise a flag on the wheat and name it taken. Then if the player tries to pick the wheat again (while the flag is set), you can print a message like "You already have picked a wheat stem. You don't need more than one." When the player eats the wheat, unset the flag so that it can be picked again and move it back to the wheat plant so it can be picked again.

Let me know if it helps.

XanMag

Encrtia
09 Oct 2015, 03:02
One step at a time, adding the "Move Object" after the "Eat" Verb.

Under the "Edible" tab (GUI-Editor, Online-Based) there's no option to edit the script to cause that secondary action of "Move object to". So, I decided to disable it & remove the Object's listed verb of "Eat", then went under the Verb tab to add "Eat" so I can attach a scipt to it , but apparently the Verb already exists.

In order to achieve what you suggested, I've had to create a brand new object to create the Verb eat without it stating it already exists. Why is the first object still holding onto the Verb "Eat" ?

Furthermore, what else should I add to the script to make it function as the normal "Eat" script would? As when testing it, I'm able to continously eat the same Wheat Stem from the hyperlink on screen, despite it already being eaten.

HegemonKhan
09 Oct 2015, 03:13
What you're asking for directly, is actually really complicated~advanced, as can be seen here:

viewtopic.php?f=18&t=3515

------

unless you're a really good coder like Sora and others, it's better if you just work with Attributes, adjusting them as need be, instead of trying to move around tons of objects, or advancedly increase~decrease a quantity upon a container object of objects, like how Sora did it (way beyond my coding ability, lol).

simply create~add a 'wheat' Integer Attribute to your player object, and upon eating it, decrease your attribute. (also, you could alter 'take' or create a new like Verb, that instead of moving it to your player object, it increases your 'wheat' Attribute ~ XanMag can help you with this, and~or with the cloning, I'm sure, he can do this easily for you)

if you do want to move~take the wheat and put it into your inventory (into~on your player object), then, probably the best thing to do, is to use cloning:

http://docs.textadventures.co.uk/quest/ ... dmove.html
http://docs.textadventures.co.uk/quest/ ... bject.html
http://docs.textadventures.co.uk/quest/ ... clone.html

as if you just move your object (then it's no longer at it's original location), and upon eating it, you of course remove~destroy it, then you no longer have it. This is why for non-good coders, using and adjusting Attributes is much better than the headache of dealing with moving and cloning Objects around, at least once you learn Attribute usage, anyways (not that easy to learn for new people).

Encrtia
09 Oct 2015, 03:17
Oh right! Ok, will do. Wasn't aware it was complex haha, I hadn't touched attributes thinking this was going to be simple.

I'll go through the links provided, & see about understanding Attributes then.

XanMag
09 Oct 2015, 03:30
See if this helps at all. I just ran this through quickly in my tutorial game so pardon if there are any mistakes. The Quest .aslx is below. If I were you, I would download it and open it with Quest and play it and view it in the editor. You can use this as a template for what you want to do.

Also... I now no longer ever tick the edibles box for an object. If you don't click that, you can add the verb "eat" without any interference from Quest pre-programming. I would not tick the edible box and instead add the verb. I think this makes it easier to do other things when you eat something. Just my opinion. If you don't like doing it this way, I think there might be a microscopic button hidden in there where you can make an editable copy of the built-in eat command.



I'm not sure how your web-based version works as I've only used the download version of Quest, but, maybe you could start a new game and post this code between the /game and the /asl in the code view. Use this code and replace whatever is there. Let me know if it works.

  <object name="edibles room">
<inherit name="editor_room" />
<description type="script">
</description>
<object name="Watermelon">
<inherit name="editor_object" />
<look>It's a big, green, seedless watermelon! Eat up!</look>
<take />
<takemsg>It's heavy, but you take it. Now eat it!</takemsg>
<eat type="script">
msg ("You annihilate that watermelon like Gallagher at a comedy show. Watermelon eaten!")
RemoveObject (Watermelon)
</eat>
</object>
<object name="Magoo">
<inherit name="editor_object" />
<inherit name="editor_player" />
<inherit name="namedmale" />
<attr name="pov_look">You're Magoo. A simple being trapped in a test game.</attr>
<look type="script">
if (game.pov = Xanadu) {
msg ("Holy moly! That looks exactly like you! To take control of Magoo, just type 'switch to Magoo'.")
}
else {
msg ("You are a simple being trapped in a test game.")
}
</look>
</object>
<object name="apple tree">
<inherit name="editor_object" />
<inherit name="surface" />
<takemsg>You can't take the entire tree!</takemsg>
<feature_container />
<hidechildren />
<listchildren />
<look type="script">
if (Contains (apple tree,apple1)) {
msg ("It's a very healthy looking apple tree, but oddly enough it only contains one apple! It is within reach so you could pick it if you wish.")
MakeObjectVisible (apple1)
}
else {
msg ("It's a very healthy looking apple tree, but oddly enough it does not contain any apples!")
}
</look>
<object name="apple1">
<inherit name="editor_object" />
<alias>apple</alias>
<visible type="boolean">false</visible>
<scenery type="boolean">false</scenery>
<look type="script">
if (GetBoolean(apple1, "picked")) {
msg ("It's a lovely looking apple. You should eat it!")
}
else {
msg ("It's a lovely looking apple. You should pick it from the tree if you want it!")
}
</look>
<pick type="script">
msg ("You stand on your tippy toes and snatch the apple from the tree.")
AddToInventory (apple1)
</pick>
<eat type="script"><![CDATA[
if (Got(apple1)) {
msg ("You scarf the apple down in one giant bite. Tasty!<br/><br/>You hear an odd sound like one you have never heard before - something on the apple tree catches your eye.")
MoveObject (apple1, apple tree)
MakeObjectInvisible (apple1)
}
]]></eat>
</object>
</object>
</object>
<verb>
<property>pick</property>
<pattern>pick</pattern>
<defaultexpression>"You can't pick " + object.article + "."</defaultexpression>
</verb>

XanMag
09 Oct 2015, 03:50
If you can get the above to work by copy-pasting code...

I know you mentioned flag use to me. Here is the code for the flag setting and unsetting demo I have in my tutorial.

  <object name="flag setting unsetting room">
<inherit name="editor_room" />
<description><![CDATA[In this room, you will hopefully master flag setting and unsetting!<br/><br/>There are flags in the room. Look at them. To raise them, type "raise flag (of your choice)". To lower them, type "lower flag (of your choice)".<br/><br/>This room assumes you have knowledge of 'If'/'Then' statements. If you don't type "if then help".<br/><br/>Notice that when you raise a flag, I have set that particular flag on that flag object to 'raised'. If you look at the particular flag, I have used an 'If'/'Else' script to give a different viewpoint of the flag. The country's flag with a flag titled 'raised' will look as though it is standing erect. When you "lower" the flag, I unset that country's flag 'raised' so it appears in the look at description as on the ground.]]></description>
<alias>flag setting and unsetting room</alias>
<enter type="script">
</enter>
<object name="The Flag of England">
<inherit name="editor_object" />
<alt type="stringlist">
<value>english flag</value>
</alt>
<usedefaultprefix type="boolean">false</usedefaultprefix>
<look type="script">
if (GetBoolean(The Flag of England, "raised")) {
msg ("You behold the proud English flag rippling in the breeze. To lower the flag, simply type 'lower' flag.")
}
else {
msg ("The English Flag and its pole rest on the ground. To raise the flag, simply type 'raise' flag.")
}
</look>
<raise type="script"><![CDATA[
msg ("You lift the English Flag from the ground and nestle the pole it is tied to neatly into the ground. The English Flag is now raised!<br/><br/>In code, we have set flag 'object' 'The Flag of England' 'flag name' \"raised\"")
SetObjectFlagOn (The Flag of England, "raised")
]]></raise>
<lower type="script"><![CDATA[
msg ("You lift the English Flag from the earth and rest it gently on the ground.<br/><br/>In code, we have Unset flag 'object' 'The Flag of England' 'flag name' \"raised\".")
SetObjectFlagOff (The Flag of England, "raised")
]]></lower>
</object>
<object name="The Flag of the USA">
<inherit name="editor_object" />
<usedefaultprefix type="boolean">false</usedefaultprefix>
<raise type="script"><![CDATA[
msg ("You lift the American Flag from the ground and nestle the pole it is tied to neatly into the ground. The Stars and Stripes is now raised!<br/><br/>In code, we have set flag 'object' 'The Flag of the USA' 'flag name' \"raised\"")
SetObjectFlagOn (The Flag of the USA, "raised")
]]></raise>
<lower type="script"><![CDATA[
msg ("You lift the American Flag from the earth and rest it gently on the ground.<br/><br/>In code, we have Unset flag 'object' 'The Flag of the USA' 'flag name' \"raised\".")
SetObjectFlagOff (The Flag of the USA, "raised")
]]></lower>
<look type="script">
if (GetBoolean(The Flag of the USA, "raised")) {
msg ("You behold the proud American flag rippling in the breeze. To lower the flag, simply type 'lower' flag.")
}
else {
msg ("The American Flag and its pole rest on the ground. To raise the flag, simply type 'raise' flag.")
}
</look>
</object>
<object name="German Flag">
<inherit name="editor_object" />
<usedefaultprefix />
<look type="script">
if (GetBoolean(German Flag, "raised")) {
msg ("You behold the proud German flag rippling in the breeze. To lower the flag, simply type 'lower' flag.")
}
else {
msg ("The German Flag and its pole rest on the ground. To raise the flag simply type 'raise' flag.")
}
</look>
<raise type="script"><![CDATA[
msg ("You lift the German Flag from the ground and nestle the pole it is tied to neatly into the ground. The German Flag is now raised!<br/><br/>In code, we have set flag 'object' 'German Flag' 'flag name' \"raised\"")
SetObjectFlagOn (German Flag, "raised")
]]></raise>
<lower type="script"><![CDATA[
msg ("You lift the German Flag from the earth and rest it gently on the ground.<br/><br/>In code, we have Unset flag 'object' 'German Flag' 'flag name' \"raised\".")
SetObjectFlagOff (German Flag, "raised")
]]></lower>
</object>
<command name="I IE E help cmd">
<pattern>if then help</pattern>
<script><![CDATA[
msg ("An 'If' script is likely the most useful script in the game.<br/><br/>Simply put, you set a condition with the 'If' script. In the GUI change the 'expression' box to whatever condition you want to set. In this room, I have set an 'If' object has flag. Choose the object you want to conditionalize. I chose 'German Flag'. Then name the flag. In this room, I chose the flag name 'raised'.<br/><br/>Now, choose what happens next with the 'Then' script. Click 'add new script'. In this room, I set the description of the raised flag as a 'print a message' script. In this box I described the German Flag as if it had been raised.<br/><br/>In the 'Else' box, you choose what happens if the condition is NOT met. So, in this room, when the German Flag did NOT have the 'raised' flag name active, I described it as lying on the ground.<br/><br/>If you are interested in how to use the 'Else If' part of this script, visit the If Then room!")
]]></script>
</command>
<object name="Magoo">
<inherit name="editor_object" />
<inherit name="editor_player" />
<inherit name="namedmale" />
<attr name="pov_look">You're Magoo. A simple being trapped in a test game.</attr>
<look type="script">
if (game.pov = Xanadu) {
msg ("Holy moly! That looks exactly like you! To take control of Magoo, just type 'switch to Magoo'.")
}
else {
msg ("You are a simple being trapped in a test game.")
}
</look>
</object>
</object>
<verb>
<property>raise</property>
<pattern>raise</pattern>
<defaultexpression>"You can't raise " + object.article + "."</defaultexpression>
</verb>
<verb>
<property>lower</property>
<pattern>lower</pattern>
<defaultexpression>"You can't lower " + object.article + "."</defaultexpression>
</verb>

HegemonKhan
09 Oct 2015, 03:58
if you're using Attributes, you'll want to create~add to both your player object and the wheat object, for an example:

(think of these Attributes as imaginary, formally: logical, 'purses' or 'wallets' or 'bags' for your 'player' Object and for your 'wheat' Object)

'player' Player Object -> 'Attributes' Tab -> Attributes -> Add -> (see below)

(Object Name: player)
Attribute Name: wheat_quantity // or whatever you want to call it
Attribute Type: int (integer: a non-decimal number: etc, -100, -1, 0, 1, 100, etc)
Attribute Value: 0 // or whatever amount of wheat you want to start with

---------------

'wheat' Object -> 'Attributes' Tab -> Attributes -> Add -> (see below)

(Object Name: wheat)
Attribute Name: quantity // or whatever you want to call it
Attribute Type: int
Attribute Value: 99 // or whatever amount of wheat you want the wheat to be starting at

----------

Attribute Usage (Adjusting Attributes):

then you got to do an Attribute transaction (buy-sell structure) when you 'eat~take' the wheat or 'give~whatever' more wheat to the wheat object:

(we are imaginatorily~pretendingly, aka logically, transacting our imaginary quantities of wheat, as opposed to the actual "physical" wheat object~s, think of like trading stocks at wall street, imaginary money or imaginary quantities of products)

add new script -> variables -> 'set a variable or attribute' -> (see below)

set variable Object_name.Attribute_name = [expression] Object_name.Attribute_name OPERATOR Value

for my example of my own general format~syntax, hopefully explaning it for you:

replace my 'Object_name' with 'player'
replace my 'Attribute_name' with 'wheat_quantity'

replace my 'Object_name' with 'wheat'
replace my 'Attribute_name' with 'quantity'

replace my 'OPERATOR' with '+'
replace my 'OPERATOR' with '-'

replace my 'Value' with '1'

--------

so for example:

usually the OPERATOR is addition (+) or subtraction (-), but you can use multiplication (*), division: division_for_quotient (/), modulus: division_for_remainder (%), exponentials (probably: ** or ^, but not sure in quest what it is, lol), etc

-------------------

for 'eat~take':

increase the player's wheat quantity attribute by a value (usually 1, but you can do 5, 10, 50, 100, etc, lol):

set variable player.wheat_quantity = [expression] player.wheat_quantity + 1

conceptually of how it works:

initial value: player.wheat_quantity = 0

old value: player.wheat_quantity = 0

player.wheat_quantity (new) = player.wheat_quantity (old: 0) + 1
player.wheat_quantity (new) = (0) + 1 = 1

new value: player.wheat_quantity = 1

old value: player.wheat_quantity = 1

player.wheat_quantity (new) = player.wheat_quantity (old: 1) + 1
player.wheat_quantity (new) = (1) + 1 = 2

new value: player.wheat_quantity = 2

old value: player.wheat_quantity = 2

player.wheat_quantity (new) = player.wheat_quantity (old: 2) + 1
player.wheat_quantity (new) = (2) + 1 = 3

new value: player.wheat_quantity = 3

etc etc etc

---

decrease the wheat's quantity attribute by the same value amount:

set variable wheat.quantity = [expression] wheat.quantity - 1

-------------------

for 'give~whatever' (example of if the player was giving his wheat back to the wheat object):

decrease the player's wheat quantity attribute by a value (usually 1, but you can do 5, 10, 50, 100, etc, lol):

set variable player.wheat_quantity = [expression] player.wheat_quantity - 1

----

increase the wheat's quantity attribute by the same value amount

set variable wheat.quantity = [expression] wheat.quantity + 1

The Pixie
09 Oct 2015, 07:57
Encrtia wrote:Oh right! Ok, will do. Wasn't aware it was complex haha, I hadn't touched attributes thinking this was going to be simple.

I'll go through the links provided, & see about understanding Attributes then.

The first thing you need to do is decide exactly what the player will experience. As you have described it, a new wheat stem will magically appear when the player eats the old one. Does that make sense in the game?

From a realism point of view, the player should pick a wheat stem, but there should still be one left in the room (which you can do fairly easily using the clone script command; when the player picks a wheat stem, do not move it, but clone a new one, and put it in the player inventory).

But then what happens if the player picks another and another and another? Does it matter if he has two thousand in his inventory? Or do you want to limit it to just one?

Encrtia
09 Oct 2015, 08:58
Yes,The Pixie, I thought about this. I was going to go with the concept of, in non-coding terminology:

Command to pick a wheat stem -> check if Wheat stem clone exists in inventory. If no, clone wheat stem. If yes, "Only need 1 to look like you work on the farm" message + no clone.

I've yet to experiment with what's already typed in this thread.

Encrtia
09 Oct 2015, 11:24
I'm going to be honest - the attributes are still a little hazy for me. But as The Pixie was aware, having the player collect something isn't actually a top priority. So having this effect, at least currently, is a resource I'm aware of but not using for now. Thank you HegemonKhan.

Playing around with your EdiblesDemo, XanMag, I was sadly not able to interact with Magoo x3 However, I was able to see your example. As it currently stands though, I'm able to take an indefinite amount of Apples, but only actually take & eat one. A loop hole in effect.

So, what I'm thinking now - or at least, trying to tinker with - is the cloning concept. I forget that at the end of the day, when coding, it's not about making everything work the way you'd expect it to in real life, but make it look how it should.
Right now, I'm running this model:
if (Got(wheat1)) {
msg ("You can't.")
}
else if (not Got(wheat1)) {
msg ("You decided to pick one of the wheat stems.")
CloneObjectAndMove (Wheat Ste, player)
AddToInventory (wheat1)
MakeObjectInvisible (wheat1)
}

I would have initially done an "if the player has a clone of Wheat Stem", but I don't think you can haha, so instead, I've added the Wheat Stem to his inventory, & made it invisible, to fulfill the check. However, the if check can't detect Invisible objects? I'm not sure how to proceed with cloni....or perhaps I could simply make a random room that the player will never go into, clone the object & put it in there... then do the clone check on that room, which'll be fine if it's visible since the player will never enter that room... that could work. Is this method usable? Or will that eventually clog things up?

But then going back to XanMag's demonstration of Flagging...

if (GetBoolean(Wheat Ste, "taken")) {
msg ("You can't.")
}
else if (not GetBoolean(Wheat Ste, "taken")) {
msg ("You decided to pick one of the wheat stems.")
AddToInventory (Wheat Ste)
SetObjectFlagOn (Wheat Ste, "taken")
}

msg ("You ate it...")
MoveObject (Wheat Ste, Room1)
SetObjectFlagOff (Wheat Ste, "taken")

I'm set.. that does it perfectly. The only thing I need to cover from this thread in more depth now, is Attributes & tiny bit more on the cloning concept.

The Pixie
09 Oct 2015, 14:31
You have this:
if (Got(wheat1)) {
msg ("You can't.")
}
else if (not Got(wheat1)) {
msg ("You decided to pick one of the wheat stems.")
CloneObjectAndMove (Wheat Ste, player)
AddToInventory (wheat1)
MakeObjectInvisible (wheat1)
}

The last two lines are unnecessary. The cloned object will be the the inventory already, as you are moving it to the player, and you want the thing to be visible. The tricky bit then is checking if the player has the wheat, because each time it is cloned it will get a new name. This is where the flags come in.
if (GetBoolean(Wheat Ste, "taken")) {
msg ("You can't.")
}
else if (not Got(wheat1)) {
msg ("You decided to pick one of the wheat stems.")
CloneObjectAndMove (Wheat Ste, player)
SetObjectFlagOn (Wheat Ste, "taken")
}

When eating, you need one line less:
msg ("You ate it...")
SetObjectFlagOff (Wheat Ste, "taken")

HegemonKhan
10 Oct 2015, 12:19
@Encrtia:

don't worry about the Attributes, after you learned more with quest, you can come back to this thread later, and see if you understand them better, as right now, I'm sure my long Attribute explanation is daunting and~or you're overwhelmed by it or all the terms~stuff involved (I was ~3 years ago when I first discovered quest).

I understand Attributes now, because it's 3 years later, lol. It took me quite awhile to understand them, so don't worry if you don't get them right away.