Taking/Using/Scripting multiple objects at once

Proudly Humble
02 Jul 2016, 17:58
I'm new to this sort of thing. I know next to nothing about coding, which is why I love the interface of Quest. I'm actually fairly well along in creating my first game. I just need to add a couple more puzzles to it, then decorate it with room/object descriptions. I'm looking forward to finishing it soon. :D

Anyway, to the question at hand, which has nothing to do with my planned game. Is there a way to gather or use multiple objects at once (other than saying something like "take all")? Let's look at the tutorial example, with the fridge. Now let's say a I add a knife to the kitchen. When I run the tutorial game and open the fridge, is the a way I can say something like "get food" and take all the food from the fridge, but leave the knife and key alone?

I've tried creating an object type "food" and then applied it to the appropriate objects, but that got me nowhere. I then tried editing the type itself, created an alias of "food," but as you probably can guess, everything was named "food" and when I tried to take food, I had to choose:

1. food
2. food
3. food
(etc.)

It's not a critical issue for me, I'm just trying to think outside of the box here and see what I can and cannot do with Quest. The extension of this concept would be to apply a script to objects that share a common element without having to specify each object by its actual name within the script. For instance, say I added a DVR and a stereo to the lounge and wanted to "turn on electronics."

So is there a way to apply a certain action to every object in a room that meets a certain category?

HegemonKhan
02 Jul 2016, 20:20
you are half way there by realizing you needed an Attribute (such as using Object Types / Inherited Attributes --- quest's user level of Groups/Classes, good job in learning about these, as they're a bit more advanced, than in just using the "normal" Attributes!) to be an "indicator/flag" to distinguish each Object from another Object ("food" vs "monster" vs "item" vs "equipment" vs "npc" vs "environment" vs "room" vs "etc etc etc").

The other half you're missing is a more advanced concept, involving using List Attributes and the 'foreach' Script/Function, to iterate (cycle) through those Objects (or Text) added as items to the List Attribute, to be able to then do whatever action you wish upon whichever of them (via using the 'if' Script/Function).

here's some links on it:

http://docs.textadventures.co.uk/quest/ ... lists.html
http://docs.textadventures.co.uk/quest/ ... reach.html
http://docs.textadventures.co.uk/quest/scopes.html
http://docs.textadventures.co.uk/quest/scripts/
http://docs.textadventures.co.uk/quest/functions/ (categorical order)
http://docs.textadventures.co.uk/quest/ ... tions.html (alphabetical order)
viewtopic.php?f=18&t=5137

there's also:

AllObjects(), Got(), Contains(), ListContains(), DictionaryContains() --- see the '(alphabetical order)' link

and there's also the 'displayverbs' and 'inventoryverbs' too, and the 'populate/format' ones too.

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

a quick brief sample example in code (hopefully you can understand it), using a Command to demonstrate it quickly:

<game name="sample">
</game>

<object name="room">
</object>

<object name="player">
<attr name="parent" type="object">room</attr>
<attr name="type_of_object_string_attribute" type="string">pc</attr>
</object>

<object name="apple">
<attr name="parent" type="object">room</attr>
<attr name="type_of_object_string_attribute" type="string">food</attr>
</object>

<object name="banana">
<attr name="parent" type="object">room</attr>
<attr name="type_of_object_string_attribute" type="string">food</attr>
</object>

<object name="orc">
<attr name="parent" type="object">room</attr>
<attr name="type_of_object_string_attribute" type="string">monster</attr>
</object>

<object name="tavernmaid">
<attr name="parent" type="object">room</attr>
<attr name="type_of_object_string_attribute" type="string">npc</attr>
</object>

<command name="collect_food_command">
<pattern>collect food</pattern> // you'd type this in when playing the game: collect food
<script>
foreach (object_variable, ScopeReachableNotHeld()) {
if (GetString (object_variable, "type_of_object_string_attribute") = "food") {
object_variable.parent = player
}
}
</script>
</command>


only the 'apple' and 'banana' Objects will be put into your "inventory", you won't put the 'orc', 'tavernmaid', and 'player' Objects into your inventory, lol.

(putting something into the "inventory" is actually jsut putting something inside of the Player Object, the so-called "inventory" is actually just the currently controlled Player Object itself and probably there's a built-in ObjectList Attribute too)

(I wonder what would happen if you try to put the 'player' Player Object inside of the 'player' Player Object, LOLOLOL --- I'm curious about what would happen!)

XanMag
03 Jul 2016, 01:30
It also depends on if those objects are going to remain in the same room. You could create a scenery object called 'electronics' and run a look at script that describes ALL of the electronic devices in that room (or turns them on/off, take, etc).

If they are transferable objects, you could use commands (X electronics, turn on electronics, et) to carry out all sorts of stuff depending on if they are in the current player room.

That's how I would handle it even if it might be more "hacky" than HKs method.

Proudly Humble
03 Jul 2016, 22:43

@HegemonKhan

Great! Thanks! After examining the code I was able to figure out what I needed to do in the Quest user interface. The script you supplied was what I needed!

I added the script, then figured out what I needed to do on my end to make it work. Once I got it working, I tried a few experiments. I changed that "type_of_object_string" to "test" and then "collectable" and made the other necessary corrections, and the script worked perfectly for those too. Then I changed the command so that "gather food" would work as well.

From that point, I added a new command line with an altered version of the same script to make food simply become invisible (using the Quest interface, of course). Then I changed it again to set object flags, and then tested to see if the flags worked. They did.

The links you gave me are, for the most part, over my head. They aren't as detailed as the tutorial is. I had previously looked at most of those pages. Interestingly, that ScopeReachableNotHeld() thing caught my attention, and I wondered if that was what I needed, but I didn't know how to use it to even find out.

So anyway, thanks for your help. Your example worked perfectly. By the way, if you try to parent an object to itself, this is what the output is:

Error running script: Parent of element 'player' cannot be set to itself

@XanMag

LOL, that's probably what I would do myself. Add the scenery object and then tell it what to do for all the devices at once. In the game I'm working on, I'm toying with the idea of two levels of difficulty. The hard one will have dark rooms, the easy will have none. I'm thinking of making a scenery light source follow the player on the easy level instead of messing with making scripts for each of the otherwise dark rooms.


hegemonkhan
04 Jul 2016, 00:16

glad you were able to make sense and/or figure it out, from my code heavy and not well-explained post(s), laughs. Helping someone through the GUI~Editor vs just copy and pasting code, is a lot more work... which is why I don't do it too often, takes too much precious time (never enough time to do everything sighs) and I am lazy, laughs.


you don't have to use a Command, you can put those scripts into various Verbs/Functions or where/what-ever else, and ya, you can change the 'name' of things, just make sure that it all matches up everywhere in your game's code/GUI~Editor where it's being used.

you can also expand upon the scripting too... putting in more conditionals ('if~else if~else' Scripts), for example using the Command again, instead of just checking if it's food, you can add additional 'else ifs' and do whatever you want (instead of making/having multiple, in this example case, Commands):

<command name="blah_command">
  <pattern>blah</pattern>
  <script>
    foreach (object_variable, ScopeReachableNotHeld()) {
      if (HasString (object_variable, "type_of_object_string_attribute") = "food") {
        object_variable.parent = player
      } else if (HasString (object_variable, "type_of_object_string_attribute") = "monster") {
        invoke (object_variable.fight_script)
      }
      // etc etc etc 'else ifs' as you want for your various types of Objects
    }
  </script>
</command>

Proudly Humble
04 Jul 2016, 14:43

I just used commands at the time for the sake of the simplicity of testing things. Yeah, I know that I can also place the script somewhere else, like when something is opened, looked at, taken, etc., or when I use a user-created verb on an object.

If also figured that about expanding the scripting too. Going back to the tutorial, I had thought about flagging the perishable items (or adding another type) and only taking the perishable food items when I run the command line in-game. But I'm taking this one step at a time.

Again, thanks for your help. I've got the script saved to my tutorial game for quick reference.


The Pixie
04 Jul 2016, 15:12

I think using a command is probably the only way this will work. You would want to set it up with say this pattern:

get food;get all food;take food;take all;pick up food;pick up all food

Then go though the objects in the room, and check which are food. You could do that with an attribute or by setting them to be a type (using the DoesInherit function to check). Is that enough to get you going, or do you want more details?


Jay Nabonne
04 Jul 2016, 15:22

err.... I don't know the new tags for these posts now... how to do the code box/quote box/etc stuff??

The forums now use "markdown". You can find things like the code tag here:

https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet


hegemonkhan
04 Jul 2016, 17:55

Thanks Jay!


Proudly Humble
05 Jul 2016, 16:17

Thanks, Pixie, I think I've got what I need to know for now. I got exactly the help I needed already, and have adapted the above script to figure out how to do other things as well. I really asked the question out of curiosity, because I thought there had to be more that I could do with types/attributes than what was given in the tutorial. As it turns out, I learned even more than I imagined, and am playing around with the game's response to the foreach (object_variable, ScopeReachableNotHeld()) line of the script. It's a pretty powerful line. Some time later I'll probably try another scope in it's place.

My next step might be to learn more about lists, but I'll save that for later. In the meantime, I'll be experimenting with the game, consulting the help pages, and looking at the forum.


hegemonkhan
05 Jul 2016, 17:45

Lists and their usage is a bit more advanced stuff, so they can take some time to learn, but they're very useful/powerful. You don't have to use a Scope (a built-in specific itemed list creation function), you can create your own lists, and do lots of cool stuff with them, such as randomly selecting one of its items:

the 'split' Script/Function is an easy quick way to create a List Attribute if you need doing so through scripting, for example:

orc.item_drop_list = split ("cash;club;potion", ";")

but I'll show the "normal" way in the code below:

<game name="sample">
  <attr name="start" type="script">
    orc.item_drop_list = NewStringList()
    list add (orc.item_drop_list, "cash")
    list add (orc.item_drop_list, "club")
    list add (orc.item_drop_list, "potion")
  </attr>
</game>

<object name="room">
</object>

<object name="club">
  <attr name="parent" type="object">orc</attr>
</object>

<object name="potion">
  <attr name="parent" type="object">orc</attr>
</object>

<object name="player">
  <attr name="parent" type="object">room</attr>
  <attr name="cash" type="int">0</attr>
</object>

<object name="orc">
  <attr name="parent" type="object">room</attr>
  <attr name="dead" type="boolean">false</attr>
  <attr name="cash" type="int">50</attr>
  <attr name="displayverbs" type="simplestringlist">fight</attr>
  <attr name="fight" type="script">
    if (orc.dead) {
      msg ("The orc is already dead and looted, silly")
    } else {
      msg ("You fight and kill the orc.")
      orc.dead = true
      item_drop_function (this)
    }
  </attr>
</object>

<function name="item_drop_function" parameters="character_parameter">
  selected_item_variable = StringListItem (character_parameter.item_drop_list, GetRandomInt (0, ListCount (character_parameter.item_drop_list) - 1))
  if (selected_item_variable = "cash") {
    player.cash = player.cash + character_parameter.cash
  } else {
    MoveObject (GetObject (selected_item_variable), player)
  }
</function>

<verb>
  <property>fight</property>
  <pattern>fight</pattern>
  <defaultexpression>You can't fight that!</attr>
</verb>

hegemonkhan
05 Jul 2016, 18:15

conceptual example of the 'foreach' Script/Function:

foreach (PLACEHOLDER_VARIABLE, OBJECT_NAME.LIST_ATTRIBUTE_NAME)

pretend that 'run_laps' is a Script Attribute on each of the team members, which will be run via the 'invoke' (or you can use the more powerful/useful 'do' instead if you need to do more advanced scripting) Script/Function, seen below

----

game.team = split ("john;joe;jim;jeff;james", ";")

foreach (team_member, game.team) {
  invoke (team_member.run_laps)
}

// conceptual effect/result of what the 'PLACEHOLDER_VARIABLE' does automatically (hidden / behind the scenes) in the 'foreach' Script/Function:

team_member = "john" -> invoke (john.run_laps)
team_member = "joe" -> invoke (joe.run_laps)
team_member = "jim" -> invoke (jim.run_laps)
team_member = "jeff" -> invoke (jeff.run_laps)
team_member = "james" -> invoke (james.run_laps)

Proudly Humble
07 Jul 2016, 20:53

Well, I'm not quite ready to try out lists, or at least I didn't think I was, but since you went through the trouble of giving that example of a code using lists, I took a close look at the post. Please tell me how well I interpreted what is going on:

  1. In the startup script of the game, you created a list called item_drop_list, and attached it to a NPC orc as an attribute.
  2. You designated cash, club, and potion as items on the list.
  3. The orc has three objects by those same names in its "inventory." The cash has a value of 50.
  4. You've added a boolean attribute called "dead" with a value preset to false.
  5. You've added an attribute called "fight" that runs a script.
  6. When then orc is killed in the game via the fight script, the orc calls a function, that you've named item_drop_function.
  7. That function has a parameter called character_parameter.
  8. The function then randomly gives one of three items in the list as a reward to the player. In this case, it will be a club, potion, or the cash.

And here are my questions:

  1. Is the function set up so that the player can loot other objects, such as a dragon, thief, baddie, etc. when they are defeated and the function is called again? It looks to me like it is, but they would also need to have their own item_drop_list.
  2. Does the line item_drop_function (this) actually tell the game to run the function and apply it specifically to the orc?
  3. Is character_parameter a specific phrase that the game naturally looks for and understands, or is it a variable? I'm guessing that is something that needs to be specific.
  4. In the three lines that added the items to orc.item_drop_list, would the same thing be accomplished be creating an orc, giving it a string attribute, and then manually adding those items, bypassing the need for a startup script?
  5. Is the script attribute the same thing as adding a verb to an object, and then applying a script? (Nevermind on this one, I just opened up the old tutorial game, added a verb to an object that moved the player from the lounge to the kitchen, then checked the object attributes and did indeed find the verb listed as a script attribute.)

hegemonkhan
08 Jul 2016, 02:38

you didn't have to jump into Lists, I was just posting the stuff for when you do, laughs. Oh well... Lists are useful, if you can wrap your head around them / understanding them.

good luck on understanding this post... YUCK! (I did a really bad job at trying to explain and answer your questions... grr, sighs)


I did do a bit of a more complex example here... due to the handling of me using different data types, so if you can understand this example, you're much much farther along in understanding List usage, hehe.

for your #3-understanding (all others are an accurate understanding):

the 'orc' Object contains 2 Objects: 'club' Object and 'potion' Object

the 'orc' (and 'player') Object(s) also contains a 'cash' Integer Attribute, the 'player' Object's 'cash' Integer Attribute's Value starts at 0, and the 'orc' Object has its 'cash' Integer Attribute's Value at 50.

because I decided to have a mix of Data Types (2 Objects and 1 Integer Attribute), I must use a String List Attribute as it holds strings/text as its items (an Object List Attribute must have all of its items as Objects - which the 'cash' Integer Attribute would cause an error, as it's not an Object)

Thus because I'm using a String List Attribute, its items are just strings/text, so if the 'potion' or the 'club' item is selected via the random selection code ( selected_item_variable = ...... ), (see the scripting under the 'else' condition) I must convert the string/text of 'potion' selected choice into the 'potion' Object, which the 'GetObject (string/text: selected_item_variable)' does. The same is done with/for the 'club' string/text into the 'club' Object. And now, we can act upon those Objects, which in this example is to move them over to (into) the 'player' Object (aka, the "inventory"). However, if the 'cash' string/text item is selected (which is checked via the 'if' condition), it's handled differently, we just simply add the Value (50) of the 'orc' Object's 'cash' Integer Attribute to the 'player' Object's 'cash' Integer Attribute's Value (of 0).


the 'orc' Object's 'fight' Script Attribute is the same as the GUI~Editor's: 'orc' Object -> 'Verb' Tab -> 'fight' Verb -> (set it up: add new script, etc etc etc)


VARIABLES (3 Types - keeping this simple):

  1. Variables: example: cash = 100
  2. Attributes: example: player.cash = 100
  3. Arguments/Parameters: (see Functions/Commands)

now, about the 'item_drop_function' Function:

Functions (and Commands) have 'argument/parameter' VARIABLES, these are inputs that are then able to be used by the Function's scripting.

so, in the 'orc' Object's 'fight' Script Attribute (the 'orc' Object's 'fight' Verb), we call/activate/run the 'item_drop_function' and provide the special 'this' keyword/keycommand as its input/argument.

The special 'this' keyword/keycommand, GETS the Object that is containing its scripting (in this case, the 'this' scripting, is / is inside, the 'fight' Script Attribute), which in this case, the 'fight' Script Attribute is contained by/in the 'orc' Object. So, 'this' GETS the 'orc' Object:

conceptual:
item_drop_function (argument/input)
item_drop_function (this)
item_drop_function (this ---> orc)
item_drop_function (orc)

now, I name/rename the Parameter VARIABLE that is holding the input/argument as 'character_parameter':

conceptually:
character_parameter = orc

which the scripting in the 'item_drop_function' can (and does) use that Parameter VARIABLE (character_parameter), so:

conceptually:

selected_item_variable = StringListItem (character_parameter.item_drop_list, GetRandomInt (0, ListCount (character_parameter.item_drop_list) - 1))
selected_item_variable = StringListItem (orc.item_drop_list, GetRandomInt (0, ListCount (orc.item_drop_list) - 1))
selected_item_variable = (one of these strings/text items: cash/club/potion)

player.cash = player.cash + character_parameter.cash
player.cash = player.cash + orc.cash
player.cash = (0) + (50)
player.cash = 50


your questions:

  1. yes, all you got to do is to call the Function:

if you're calling the Function from a Script Attribute of the Object (aka, in GUI~Editor: an Object's Verb):

// you can always replace 'this' with the name of the Object, but by using 'this' (only when its scripting is contained by that Object you want to use) then you don't have to for each different Object you're using with this Function

in code: item_drop_function (this)

GUI~Editor: add new script -> output -> 'call function' Script -> Name: item_drop_function, Add Parameter: this)

if you're calling the 'item_drop_function' Function from another Function:

in code: item_drop_function (name_of_the_object_you_want_to_use)

GUI~Editor: add new script -> output -> 'call function' Script -> Name: item_drop_function, Add Parameter: name_of_the_object_you_want_to_use, --- you may be using scripting to determine the Object for what Object name to use)

if you're calling the 'item_drop_function' Function from a Command:

GUI~Editor: add new script -> output -> 'call function' Script -> Name: item_drop_function, Add Parameter: object, --- if using #object#, otherwise: objectXXX --- if using #objectXXX#)

and yes, each Object would need its own 'item_drop' list, unless you want a universal drop list, and/or have your own scripting for determining what 'Object.List' to use (such as with diablo games using its 'ilvl/alvl' Attributes in relation to which treasure_class/drop list to use) if you're doing more complex stuff in your game.

  1. yes, that's how it's done directly in code, you literally write the name of the function and in the parenthesis, you either type in: 'this' (if its scripting is contained by the desired Object), or you specifically type in the name of the Object, or you're using addition scripting for determing the Object and a variable for holding the name of the scripting-gotten Object

  2. 'character_variable' is just my own personal-custom name/label for the Parameter VARIABLE, you can use whatever you want for the name/label of it, such as a simple 'x':

item_drop_function (orc)
~OR for this example~
item_drop_function (this)

// parameter="x" <=== orc
// or
// for this example: parameter="x" <==== (this = orc)

<function name="item_drop_function" parameter="x">
  // x = orc
  // just for quick example:
  player.cash = player.cash + x.cash
  // conceptually: player.cash = player.cash + orc.cash
</function>
  1. yes... BUT NOT adding a String Attribute. YOU ADD A STRING LIST ATTRIBUTE, and add in its item Values.

there's various ways:

directly in code, as the 'creation' tag block (for initial game setting only):

<object name="orc">
  <attr name="item_drop_list" type="simplestringlist">cash;club;potion</attr>
</object>

// in full view of everything, after the start of the game, the 'orc' Object 'creation' tag block looks like this:

<object name="orc">
  <attr name="cash" type="int">50</attr>
  <attr name="dead" type="boolean">false</attr>
  <attr name="item_drop_list" type="simplestringlist">cash;club;potion</attr>
  <attr name="displayverbs" type="simplestringlist">fight</attr>
  <attr name="fight" type="script">
    // blah blah blah scripting, I'm lazy, lol
  </attr>
  <object name="club">
  </object>
  <object name="potion">
  </object>
</object>

the above (well, just demonstrating for this: the 'item_drop_list' String List Attribute), is the same as if you did it manually in the GUI~Editor:

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

(Object Name: orc)
Attribute Name: item_drop_list
Attribute Type: String List
Attribute Value (add item or whatever/however it's done in the GUI~Edtor, lol): cash; club; potion

and lastly, via scripting, which is what I originally used for my example (already seen, GUI~EDitor: 'game' Game Object -> 'Scripts' Tab -> 'start' Script -> set it up: add new script and etc etc tc).

  1. yes, a Script Attribute IS the GUI~Editor's "Verb", and vice versa. Well, there's a small caveat... if you're doing it in code, you must add in the 'verb' creation tag block and add in the item for the 'displayverbs/inventoryverbs', to make it be (has the functionality of) a Verb (the GUI~Editor does this for you and has the toggle options / options for you to use), otehrwise, it's still a Script Attribute and can be run/used/actvated, but it doesn't have the button and hyperlink functionality, as it's not fully set up as a Verb.

hegemonkhan
08 Jul 2016, 07:00

just to add on, more about a Function and its Arguments/Parameters (these examples probably explains about Functions and their arguments/parameters much better):

<game name="xxx">
  <attr name="start" type="script">
    answer = sum_of_five_values_function (1,2,3,4,5) // Arguments: 1,2,3,4,5 --- which match up with their Parameter slots/ordering (value_1,value_2,etc): '1' to 'value_1', '2' to 'value_2', etc etc etc
    msg ("The sum of 1+2+3+4+5 is: " + answer)
    // output: The sum of 1+2+3+4+5 is: 15
  </attr>
</game>

<function name="sum_of_five_values_function" parameters="value_1,value_2,value_3,value_4,value_5" type="int"> // type="XXX" is the return type
  sum = value_1 + value_2 + value_3 + value_4 + value_5
  return (sum)
</function>

and using different arguments:

<game name="xxx">
  <attr name="start" type="script">
    answer = sum_of_five_values_function (23,41,17,89,66) // Arguments: 23,41,17,89,66 --- which match up with their Parameter slots/ordering (value_1,value_2,etc): '23' to 'value_1', '41' to 'value_2', etc etc etc
    msg ("The sum of 23+41+17+89+66 is: " + answer)
    // output: The sum of 23+41+17+89+66 is: 236
  </attr>
</game>

<function name="sum_of_five_values_function" parameters="value_1,value_2,value_3,value_4,value_5" type="int"> // type="XXX" is the return type
  sum = value_1 + value_2 + value_3 + value_4 + value_5
  return (sum)
</function>

using Variables instead of constants for the arguments:

<game name="xxx">
  <attr name="start" type="script">
    arg1 = 32
    arg2 = 14
    arg3 = 71
    arg4 = 98
    arg5 = 66
    answer = sum_of_five_values_function (arg1,arg2,arg3,arg4,arg5) // Arguments: arg1,arg2,arg3,arg4,arg5 --- which match up with their Parameter slots/ordering (value_1,value_2,etc): 'arg1' to 'value_1', 'arg2' to 'value_2', etc etc etc
    msg ("The sum of 32+14+71+98+66 is: " + answer)
    // output: The sum of 32+14+71+98+66 is: 281
  </attr>
</game>

<function name="sum_of_five_values_function" parameters="value_1,value_2,value_3,value_4,value_5" type="int"> // type="XXX" is the return type
  sum = value_1 + value_2 + value_3 + value_4 + value_5
  return (sum)
</function>

using Attributes for the arguments:

<game name="xxx">
  <attr name="start" type="script">
    answer = sum_of_five_values_function (global_data_object.arg_1,global_data_object.arg_2,global_data_object.arg_3,global_data_object.arg_4,global_data_object.arg_5)
    msg ("The sum of 2+4+6+8+10 is: " + answer)
    // output: The sum of 2+4+6+8+10 is: 30
  </attr>
</game>

<object name="global_data_object">
  <attr name="arg_1" type="int">2</attr>
  <attr name="arg_2" type="int">4</attr>
  <attr name="arg_3" type="int">6</attr>
  <attr name="arg_4" type="int">8</attr>
  <attr name="arg_5" type="int">10</attr>
</object>

<function name="sum_of_five_values_function" parameters="value_1,value_2,value_3,value_4,value_5" type="int">
  sum = value_1 + value_2 + value_3 + value_4 + value_5
  return (sum)
</function>

using Attributes for the arguments:

(multiple uses/re-uses, one of the big purposes of Functions)

<game name="xxx">
  <attr name="turn" type="int">0</attr>
  <statusattributes type="simplestringdictionary">turn = Turn: !</statusattributes> // unfortunately, Dictionary Attributes still require this old syntax: <ATTRIBUTE_NAME type="xxx">content</ATTRIBUTE_NAME>, sighs. You can't do: <attr name="ATTRIBUTE_NAME" type="xxx">content</attr>
  <attr name="start" type="script">
    answer = sum_of_five_values_function (global_data_object.arg_1,global_data_object.arg_2,global_data_object.arg_3,global_data_object.arg_4,global_data_object.arg_5)
    msg ("The sum = " + answer)
  </attr>
</game>

<object name="global_data_object">
  <attr name="arg_1" type="int">1</attr>
  <attr name="arg_2" type="int">3</attr>
  <attr name="arg_3" type="int">6</attr>
  <attr name="arg_4" type="int">9</attr>
  <attr name="arg_5" type="int">12</attr>
</object>

<object name="room">
</object>

<object name="player">
  <attr name="parent" type="object">room</attr>
  <attr name="alias" type="string">HK</attr>
  <attr name="current_life" type="int">999</attr>
  <attr name="maximum_life" type="int">999</attr>
  <attr name="life" type="string">999/999</attr>
  <statusattributes type="simplestringdictionary">life = Life: !</statusattributes> // unfortunately, Dictionary Attributes still require this old syntax: <ATTRIBUTE_NAME type="xxx">content</ATTRIBUTE_NAME>, sighs. You can't do: <attr name="ATTRIBUTE_NAME" type="xxx">content</attr>
  <attr name="changedcurrent_life" type="script">
    this.life = this.current_life + "/" + this.maximum_life
  </attr>
  <attr name="changedmaximum_life" type="script">
    this.life = this.current_life + "/" + this.maximum_life
  </attr>
</object>

<object name="monster">
  <attr name="parent" type="object">room</attr>
  <attr name="alias" type="string">orc</attr>
  <attr name="dead" type="boolean">false</attr>
  <attr name="current_life" type="int">500</attr>
  <attr name="maximum_life" type="int">500</attr>
  <attr name="life" type="string">500/500</attr>
  <attr name="displayverbs" type="simplestringlist">look;fight</attr>
  <attr name="changedcurrent_life" type="script">
    this.life = this.current_life + "/" + this.maximum_life
  </attr>
  <attr name="changedmaximum_life" type="script">
    this.life = this.current_life + "/" + this.maximum_life
  </attr>
  <attr name="look" type="script">
    msg ("Life: " + this.life)
  </attr>
  <attr name="fight" type="script"><![CDATA[ // this '<![CDATA[ content:scripting ]]>' tag is needed to tell quest that any of the '<' and '>' symbols as the inside content:scripting are to be recognized as 'greater than' and 'lesser than' operations/symbols, and NOT as code tag symbols. Otherwise, we'd be getting an ERROR. This 'CDATA' tag is ONLY needed for if/when you're typing in the code directly. If you're using the GUI~Editor, then you don't need to ever worry about (don't need to use) this 'CDATA' tag, as it handles it for you.
    if (this.dead) {
      msg ("The " + this.alias + " is already dead, silly.")
    } else {
      damage = sum_of_five_values_function (10,20,30,40,50)
      this.current_life = this.current_life - damage
      msg (game.pov.alias + " attacked the " + this.alias + " for " + damage + " damage, leaving it with only " + this.current_life + " life left.")
      if (this.current_life <= 0) {
        this.dead = true
        msg (game.pov.alias + " inflicted so much damage, he actually killed the " + this.alias + ".")
      } else {
        game.pov.current_life = game.pov.current_life - damage
        msg (this.alias + " attacks " + game.pov.alias + ", doing " + damage + " damage to him, leaving " + game.pov.alias + " with only " + game.pov.current_life + " life left.")
        if (game.pov.current_life <= 0) {
          msg ("The " + this.alias + " has killed " + game.pov.alias + ".")
          msg ("GAME OVER")
          finish
        }
      }
    }
  ]]></attr>
</object>

<verb>
  <property>fight</proeprty>
  <pattern>fight</pattern>
  <defaultexpression>You can't fight that!</defaultexpression>
</verb>

<verb>
  <property>look</proeprty>
  <pattern>look</pattern>
  <defaultexpression>You can't look at that!</defaultexpression>
</verb>

<turnscript name="global_turnscript">
  <enabled /> // this (to the left) is the syntax quest-understood shorthand of this Boolean Atribute (of ONLY) when its Value is 'true', as shown in its longhand/normal syntax form: <attr name="enabled" type="boolean">true</attr>
  <script>
    answer = sum_of_five_values_function (9,8,7,6,5)
    msg (game.turn + ". The sum now = " + answer)
    game.turn = game.turn + 1
  </script>
</turnscript>

<function name="sum_of_five_values_function" parameters="value_1,value_2,value_3,value_4,value_5" type="int">
  sum = value_1 + value_2 + value_3 + value_4 + value_5
  return (sum)
</function>

hegemonkhan
08 Jul 2016, 09:18

P.S.

if you want, I got a (badly done / confusing, as I'm not good at explaining stuff well) guide on using Lists (and Dictionaries too and on Attirbutes in general as well):

http://textadventures.co.uk/forum/samples/topic/5137/list-and-dictionary-extensive-guide-by-hk
http://textadventures.co.uk/forum/samples/topic/5138/explore-and-travel-code-sample-by-hk (if you want to see more fancy/advanced usage, though my coding is old and poor quality as I was just learning this List+Dictionary stuff back then, lol)

http://textadventures.co.uk/forum/samples/topic/5559/attributes-and-if-script-guide-by-hk


Proudly Humble
08 Jul 2016, 12:11

Wow, that's a lot to read through, lol.

It's funny how I perceived the cash as an object. Facepalm on that one. I knew better than that. I was just using my imagination, looking at it from a player's point of view, seeing cash actually go from the orc to the player.

And yeah, I meant string list, in that question.

Anyway, I'll go back and process this at another time. I've spent so much time experimenting that I've neglected the game I want to finish, and I don't see myself using ANY of this stuff in it, lol. I want to go ahead and finish it.