Setting variable to an object's attribute, named by a string

playinful
13 Jun 2016, 22:07
I'm trying to set a new variable to an object's attribute. Thing is, this script is being used in several places, and the attribute name is not always the same. I would set it to object.whatever, but I need to set it to object.????whatever, where the ???? value changes every time... It's kind of hard to explain, sorry. I just need a function that can return an object's attribute given two variables: an object, and a string variable, where the string variable denotes the object's attribute. It seems so easy, but I simply can't find it out. Can anybody help?

HegemonKhan
13 Jun 2016, 23:01
I'm not quite understanding this/what you're saying (I'm having trouble due to not understanding the terminology you're using), sighs, but I'll give some guesses:

my terminology/understanding:

VARIABLE
-> Variable
-> Attribute
-> Parameter

Value
-> simple expression
-> complex expression

Variable:

these are erased (NOT preserved/saved) once the scripting that contains them is finished; Variables are temporary/local VARIABLES

Variable_name = Value

result = "HK"
result = x + 5
handled = false
handled = true
you_go_first = true
you_go_first = false
primary_pigment_color_list = split ("red;blue;yellow", ";")
right_hand = sword // 'sword' has to exist (be an actual/existing Object)
damage = 5 * (x + 4) / (x - 7)
damage = weapon_damage + weapon_damage * (strength / 100)
damage = strength
damage = strength + endurance

Attribute:

these are preserved/saved as they're attached/connected/contained/held to/by an Object (so long as the Object exists/still exists of course), and thus you can use/reuse them anywhere in your game (in other/any scripting); Attributes are permanent*/global VARIABLES

*again, so long as the Object exists/still exists

Attribute_name.Attribute_name = Value

game.state = 0
game.state = 1
game.state = 7
game.state = "0"
game.state = "1"
game.state = "7"
player.alias = "HK"
player.alias = "Playinful"
player.strength = 100
orc.dead = true
orc.dead = false
game.sex_list = split ("male;female", ";")
player.right_hand = sword // 'sword' has to exist (be an actual/existing Object)
player.damage = player.weapon.damage + player.weapon.damage * (player.strength / 100) - (orc.armor.defense + orc.armor.defense * (orc.endurance / 100))
player.damage = player.strength
player.damage = player.strength + player.endurance

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

the 'set' and 'do' Scripts/Functions are very powerful (you can concatenate):

http://docs.textadventures.co.uk/quest/scripts/set.html
http://docs.textadventures.co.uk/quest/scripts/do.html

for an example:

// game.primary_attribute_list = split ("strength;endurance;dexterity;agility;speed;luck;intelligence;spirituality;mentality;personality", ";")
foreach (primary_attribute, game.primary_attribute_list) {
set (player, primary_attribute + "_integer_attribute", 100)
set (monster_1, primary_attribute + "_integer_attribute", 10)
}

// monster_1.alias = orc
Set (monster_1, "alias", monster_1.alias + " (hostile)")

/*
result(s):

(I like my names describing what something is, I prefer 'player.strength_integer_attribute' over 'player.strength', as this let's me easily organize and keep them unique, for example, I can have this too along with the other attribute: player.strength_string_attribute = "strong/average/weak", whereas I couldn't do this obviously: player.strength = 100 and player.strength = "strong", and as I also don't like using upper case, and all the other standard conventions, either as they just confuse me)

player.strength_integer_attribute = 100
player.endurance_integer_attribute = 100
player.dexterity_integer_attribute = 100
player.agility_integer_attribute = 100
player.speed_integer_attribute = 100
player.luck_integer_attribute = 100
player.intelligence_integer_attribute = 100
player.spirituality_integer_attribute = 100
player.mentality_integer_attribute = 100
player.personality_integer_attribute = 100

monster_1.strength_integer_attribute = 10
monster_1.endurance_integer_attribute = 10
monster_1.dexterity_integer_attribute = 10
monster_1.agility_integer_attribute = 10
monster_1.speed_integer_attribute = 10
monster_1.luck_integer_attribute = 10
monster_1.intelligence_integer_attribute = 10
monster_1.spirituality_integer_attribute = 10
monster_1.mentality_integer_attribute = 10
monster_1.personality_integer_attribute = 10

orc (hostile)
*/


---------

maybe this is what you want/are asking for, an example:

you set your desired (changing/dynamic) Object's name and Attribute's name to the 'object_name_variable' and 'attribute_name_variable' Variables, and then you can use them in the 'set' Script/Function, possibly/probably needing the 'GetObject' Script/Function:

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

(I'm not sure if the below will work, as I've not gone that deep into this type of stuff yet)

object_name_variable = player // or: "HK", "Playinful", "monster_1", "etc etc etc"
attribute_name_variable = "strength" // or: "endurance", "dexterity", "etc etc etc"

set (GetObject(object_name_variable), attribute_name_variable, 50)

playinful
13 Jun 2016, 23:51
I see what you mean, I was admittedly being very confusing in that last post. What i mean is, in functions such as GetBoolean, the function is used as follows: GetBoolean(object, string attribute name); for instance, GetBoolean(monster, "dead"). The advantages to having the object and attribute be separate values is that the string attribute name can be derived from multiple parts-- GetBoolean(monster, "de" + "ad") --or using another variable-- attribute = "dead"; GetBoolean(monster, attribute). I know there are several functions that work like this, but is there a function to return the attribute's value, as is? For instance, function(monster, "righthand") returning object: club?

HegemonKhan
14 Jun 2016, 03:31
The 'GetXXX' Scripts/Functions will return the Value of an Attribute, if that Attribute and its Value exists (which includes it having to be the correct Attribute/Value Type), and if that Attribute doesn't exist, then it returns either 'false' or 'null' (not sure which).

whereas, the 'HasXXX' Scripts/Functions only return whether the Attribute exists ('true'), else it returns 'false'

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

Attribute Types ( http://docs.textadventures.co.uk/quest/types/ ):

String Attribute:

player.alias = "HK"
game.state = "0"
npc.greeting = "Hi, what is your name?"
HK.favorite_color = "black"
etc etc etc

Boolean Attribute:

orc.dead = false
orc.dead = true // this is often (for more code efficiency/possibly less confusion), shortened to or understood by quest, as this: orc.dead
player.flying = false
player.flying = true
game.dragon_killed_mission_completed = false
game.dragon_killed_mission_completed = true
player.poisoned = true
player.poisoned = false
etc etc tc

Integer Attribute:

player.strength = 100
game.state = 0
orc.damage = 10
katana.damage = 50

Double Attribute:

player.damage = 37.291018
// I don't think it uses double quotes, as that should/would turn it into a String Attribute/Value (any Value/thing in double quotes is a String), I'm assuming anyways

Object Attribute:

the Value does/can NOT have double quotes, as double quotes turns it (the Value) into a String, instead of an Object

***********************************
but has two conditions:
1. the Value can't be: 'true' nor 'false', as these are special/reserved keywords for the Boolean Attribute's Values
2. the Value has to be (the name of) an actual/existing Object (see below)

<object name="player">
</object>
<object name="sword">
</object>
player.right_hand = sword
// NO error

VS

<object name="player">
</object>
player.right_hand = sword
// ERROR, as there's no existing 'sword' Object
*************************************

List Attribute:

game.sex_list = split ("male;female", ";")
game.condition_list = split ("normal;poisoned;paralyzed;petrified;stunned;asleep;dead;unconscious;silenced", ";")
player.condition_list = split ("poisoned;petrified", ";")
HK.favorite_color_list = split ("black;red", ";")

and the other (less main) Attribute Types... I'm getting lazy and/or they're outside of my knowledge of them

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

so, how does the 'GetXXX' and 'HasXXX' work?

(I'm not sure if they return 'false' or 'null', not sure which it is, so that's why I use 'false/null' below, but you got to use either 'false' or 'null', and see which one works)

HAS:

it does NOT care at all about the Value of the Attribute; it only checks (true/false) if the Attribute exists.

the 'HasAttribute()' Script Function has internal coding that determines/parses what the Attribute Type it is, that it is checking for existance, so this is probably less efficient code-wise than using the specific Attribute Type 'HasSpecific_Attribute_Type()' Scripts/Functions, however, this means that the 'HasAttribute()' Script/Function is more powerful/useful, as it can be used when you don't know what Attribute Type you're using, and/or if you're using multiple Types of Attributes. Also, the 'HasAttribute()' works for List and Dictionary Attributes too (I think it's the only method... but I could be wrong).

HasSpecific_Attribute_Type: HasObject(), HasInt(), HasDouble(), HasString(), HasBoolean(), etc?

player.strength = 100
if (HasAttribute (player, "strength") = true) { // or shortened/efficient form: if (HasAttribute (player, "strength")) {
msg ("The 'player' Player Object indeed has a 'strength' Attribute")
} else if (HasAttribute (player, "strength") = false/null) { // or alternate/shortened/efficient form: if (not HasAttribute (player, "strength")) {
msg ("Sorry, but there is no 'player.strength' Attribute")
}
// output: The 'player' Player Object indeed has a 'strength' Attribute

// or, since we specifically have/know that 'player.strength' is an Integer Attribute, we can use the 'GetInt()' Script/Function instead:

player.strength = 100
if (HasInt (player, "strength") = true) { // or shortened/efficient form: if (HasInt (player, "strength")) {
msg ("The 'player' Player Object indeed has a 'strength' Attribute")
} else if (HasInt (player, "strength") = false/null) { // or alternate/shortened/efficient form: if (not HasInt (player, "strength")) {
msg ("Sorry, but there is no 'player.strength' Attribute")
}
// output: The 'player' Player Object indeed has a 'strength' Attribute

// vs:

player.endurance = 100
if (HasAttribute (player, "strength") = true) { // or shortened/efficient form: if (HasAttribute (player, "strength")) {
msg ("The 'player' Player Object indeed has a 'strength' Attribute")
} else if (HasAttribute (player, "strength") = false/null) { // or alternate/shortened/efficient form: if (not HasAttribute (player, "strength")) {
msg ("Sorry, but there is no 'player.strength' Attribute")
}
// output: Sorry, but there is no 'player.strength' Attribute

// or, since we specifically have/know that 'player.strength' is an Integer Attribute, we can use the 'GetInt()' Script/Function instead:

player.endurance = 100
if (HasInt (player, "strength") = true) { // or shortened/efficient form: if (HasInt (player, "strength")) {
msg ("The 'player' Player Object indeed has a 'strength' Attribute")
} else if (HasInt (player, "strength") = false/null) { // or alternate/shortened/efficient form: if (not HasInt (player, "strength")) {
msg ("Sorry, but there is no 'player.strength' Attribute")
}
// output: Sorry, but there is no 'player.strength' Attribute

// hopefully, you can understand how the other 'HasSpecific_Attribute_Type' work too, and now understanding how all the 'HasXXX' works...


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

GET:

this DOES care about the Value of the Attribute. It is the 'HasXXX' as it checks if the Attribute exists, but it ALSO checks if its Value matches up too. So there's two checks/conditions: (1) does the Attribute exist and (2) does its Value match up, if both checks/conditions are true, then it is TRUE, doing that script of yours, if one or both checks/conditions are false, then it is FALSE, doing that script of yours

(I'm just using the 'GetInt()' for this example)

player.strength = 100
if (GetInt (player, "strength") = 100) {
msg ("blah1")
} else if (GetInt (player, "strength") >= 50) {
msg("blah2")
} else if (GetInt (player, "strength") = 30) {
msg ("blah3")
} else if (not Getint (player, "strength") = 100) {
msg ("blah4")
} else {
msg ("blah5")
}
// output: blah1

// vs:

player.strength = 70
if (GetInt (player, "strength") = 100) {
msg ("blah1")
} else if (GetInt (player, "strength") >= 50) {
msg("blah2")
} else if (GetInt (player, "strength") = 30) {
msg ("blah3")
} else if (not Getint (player, "strength") = 100) {
msg ("blah4")
} else {
msg ("blah5")
}
// output: blah2

// vs:

player.strength = 30
if (GetInt (player, "strength") = 100) {
msg ("blah1")
} else if (GetInt (player, "strength") >= 50) {
msg("blah2")
} else if (GetInt (player, "strength") = 30) {
msg ("blah3")
} else if (not Getint (player, "strength") = 100) {
msg ("blah4")
} else {
msg ("blah5")
}
// output: blah3

// vs:

player.strength = 10
if (GetInt (player, "strength") = 100) {
msg ("blah1")
} else if (GetInt (player, "strength") >= 50) {
msg("blah2")
} else if (GetInt (player, "strength") = 30) {
msg ("blah3")
} else if (not Getint (player, "strength") = 100) {
msg ("blah4")
} else {
msg ("blah5")
}
// output: blah4

// vs:

player.endurance = 100
if (GetInt (player, "strength") = 100) {
msg ("blah1")
} else if (GetInt (player, "strength") >= 50) {
msg("blah2")
} else if (GetInt (player, "strength") = 30) {
msg ("blah3")
} else if (not Getint (player, "strength") = 100) {
msg ("blah4")
} else {
msg ("blah5")
}
// output: blah5

// vs:

player.strength = "100"
if (GetInt (player, "strength") = 100) {
msg ("blah1")
} else if (GetInt (player, "strength") >= 50) {
msg("blah2")
} else if (GetInt (player, "strength") = 30) {
msg ("blah3")
} else if (not Getint (player, "strength") = 100) {
msg ("blah4")
} else {
msg ("blah5")
}
// output: blah5

HegemonKhan
14 Jun 2016, 03:43
playinful wrote: is there a function to return the attribute's value, as is? For instance, function(monster, "righthand") returning object: club?


yes:

// these just return the Attribute's Value (if it can), so these code lines can NOT exist by themselves:
GetObject (Object_name, "Object_Attribute_name")
~or~
GetAttribute (Object_name, "Object_attribute_name")

// these are for checking them, as to whether to do something or not:
if (GetObject (Object_name, "Object_Attribute_name") OPERATOR your_specified_value_for_matching) { /* script(s) */ }
~or~
if (GetAttribute (Object_name, "Object_Attribute_name") OPERATOR your_specified_value_for_matching) { /* script(s) */ }
~or~
if (not GetObject (Object_name, "Object_Attribute_name") OPERATOR your_specified_value_for_matching) { /* script(s) */ }
~or~
if (not GetAttribute (Object_name, "Object_Attribute_name") OPERATOR your_specified_value_for_matching) { /* script(s) */ }

--------

examples:

<object name="club">
</object>
monster.righthand = club
player.righthand = GetObject (monster, "righthand")
// you're looting the monster's corpse, (conceptually equipping) the monster's weapon (club) into your right hand
// you can NOT just have 'GetObject()' as it is returning that Value (an Object), thus, you must be putting/storing that returned Value into something (usually an Attribute), which is why I am putting/storing it into the 'player.righthand' Attribute


or:

<object name="club">
</object>
monster.righthand = club
if (GetObject (monster, "righthand") = club) {
player.righthand = GetObject (monster, "righthand") // or, in this case, you could jsut do this: player.righthand = club
} else if (GetObject (monster, "righthand") = evil_spell_book
destroy (GetObject (monster, "righthand")) // or, in this case, you could just do this: destroy (evil_spell_book)
// as the 'evil_spell_book' is an evil upon the in-game world, so you need to destroy it via in code, in order to save the in-game world! lolololol
}

playinful
14 Jun 2016, 03:46
So, if I'm looking for a list, would I use GetList()?

HegemonKhan
14 Jun 2016, 04:03
there is no 'GetList()' Script/function:

http://docs.textadventures.co.uk/quest/ ... tions.html (alphabetical order)

and I made a huge mistake in my previous posts:

you can NOT use 'GetAttribute()' for getting an item from a List Attribute, as which item is it to get? ERROR!

I think you can still use the 'HasAttribute()' for/with a List Attribute, as it's just checking if the Attribute exists or not.

instead, for checking if something is an item in a List/Dictionary Attribute, there's the:

http://docs.textadventures.co.uk/quest/ ... tions.html (alphabetical order)

Got()
Contains()
ListContains()
DictionaryContains()

and for getting an item from the List Attribute, there's:

http://docs.textadventures.co.uk/quest/ ... tions.html

ListItem ()
StringListItem ()
ObjectListItem ()
DictionaryItem ()
StringDictionaryItem ()
ObjectDictionaryItem ()
ScriptDictionaryItem ()

and there's the other mentioned ways of getting stuff, once you determine what you want to get from the list

you can use iteration to get/act upon the items in a List too

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

List/Dictionary Attributes are a bit more confusing/advanced... they work a bit differently, as you can iterate through their items and etc stuff with them, and do a bunch of really cool and other stuff with them:

viewtopic.php?f=18&t=5137 (HK's List/Dictionary guide)

if you're interested, you can try to make sense out of my attempted guide on them in the link above

playinful
14 Jun 2016, 04:39
Thank you, GetAttribute() is indeed the function I was looking for. I apologise for being so hard to understand. Thank you for all of your help, HegemonKhan!

HegemonKhan
14 Jun 2016, 04:50
(using a pseudo Diablo 2 game's drop/treasure_chest_class) example for you:

using an ObjectList Attribute:

<object name="katana"></object>
<object name="claymore"></object>
<object name="swortsword"></object>
<object name="longsword"></object>
<object name="broadsword"></object>
<object name="rapier"></object>
<object name="scimitar"></object>
<object name="cutlass"></object>
<object name="saber"></object>

<object name="player"></object>
<object name="monster"></object>

monster.sword_drop_treasure_chest_class_objectlist_attribute = NewObjectList ()
list add (monster.sword_drop_treasure_chest_class_objectlist_attribute, katana) // they may need the double quotes ("katana"), I'm not sure
list add (monster.sword_drop_treasure_chest_class_objectlist_attribute, claymore) // they may need the double quotes ("claymore"), I'm not sure
list add (monster.sword_drop_treasure_chest_class_objectlist_attribute, shortsword) // they may need the double quotes ("shortsword"), I'm not sure
// etc etc etc 'list adds'
random_selected_item_object_variable = ObjectListItem (monster.sword_drop_treasure_chest_class_objectlist_attribute, GetRandomInt (0, ListCount (monster.sword_drop_treasure_chest_class_objectlist_attribute) - 1))
MoveObject (random_selected_item_object_variable, player) // this actually puts the Object inside of the 'player' Player Object
player.right_hand = random_selected_item_object_variable // this just stores the name of the X Object into the 'player.right_hand' Attribute, which can be used to do actions upon/with it (the Object)


using a Stringlist Attribute:

<object name="katana"></object>
<object name="claymore"></object>
<object name="swortsword"></object>
<object name="longsword"></object>
<object name="broadsword"></object>
<object name="rapier"></object>
<object name="scimitar"></object>
<object name="cutlass"></object>
<object name="saber"></object>

<object name="player"></object>
<object name="monster"></object>

monster.sword_drop_treasure_chest_class_stringlist_attribute = NewStringList ()
list add (monster.sword_drop_treasure_chest_class_stringlist_attribute, "katana")
list add (monster.sword_drop_treasure_chest_class_stringlist_attribute, "claymore")
list add (monster.sword_drop_treasure_chest_class_stringlist_attribute, "shortsword")
// etc etc etc 'list adds'
random_selected_item_object_variable = GetObject (StringListItem (monster.sword_drop_treasure_chest_class_stringlist_attribute, GetRandomInt (0, ListCount (monster.sword_drop_treasure_chest_class_stringlist_attribute) - 1)))
MoveObject (random_selected_item_object_variable, player) // this actually puts the Object inside of the 'player' Player Object
player.right_hand = random_selected_item_object_variable // this just stores the name of the X Object into the 'player.right_hand' Attribute, which can be used to do actions upon/with it (the Object)

HegemonKhan
14 Jun 2016, 04:55
playinful wrote:Thank you, GetAttribute() is indeed the function I was looking for. I apologise for being so hard to understand. Thank you for all of your help, HegemonKhan!


if you're working with List Attributes, then the 'GetAttribute()' should not work for you. Or, does it? (I've no idea if it works or not, lol. If it does work, then it'd return the entire list itself, as it doesn't allow you to select a specific item from the list)

you'll need to use:

if (), etc
Got (), Contains (), ListContains (), foreach (), for (), etc
ListItem (), StringListItem (), ObjectListItem (), GetObject (), NewStringList (), NewObjectList (), list add (), list remove (), etc
etc etc etc List Scripts/Functions

HegemonKhan
14 Jun 2016, 05:31
P.S.

not a problem about the terminology... as the ("proper/standard") programming terminology (like all terminologies, lol) takes time to learn, as you're likely overwhelmed by it all if you're new to quest and/or especially progrmaming, as you can see, I too had extreme difficulty with it when I started out:

viewtopic.php?f=10&t=3348&p=22015#p22015

--------

Also, I think your terminology was coming from the GUI~Editor's 'add new script -> [xxx] Script's options stuff', which I could never make much sense of, and thus being one of the reasons I moved to learning to code, and away from using the GUI~Editor, lol. So, that's why I was so confused by your post's terminology as well.

---------

I was just having trouble following along and/or making sense of what you were saying in your post.

the fault is mine (I was having difficulty in understanding you/your post), that is not your fault. If I can't understand the chinese language, that's MY fault, not the chinese-speaking person's fault. If I can't understand a dog's barking/sounds/language, that's MY fault, not the dog's fault, I'm the stupid one, not the dog. If I can't understand body languge, that's MY fault, not theirs. If I can't understand Einstein's papers on Relativity, that's MY fault, not Einstein's, I'm the stupid one, not Einstein. etc etc etc. If I can't understand a post, that's MY fault, not the poster's fault.

playinful
14 Jun 2016, 05:33
I needed to use ListCount(), and GetAttribute() does return the entire list, so GetAttribute() is the one I was looking for.

HegemonKhan
14 Jun 2016, 05:42
ah... that's really cool to know!

the "normal" way of finding the quantity of items in a list (using quest's code/programming):

<function name="my_ListCount_function" type="int">
sum = 0
foreach (item_variable, my_object.my_list) {
sum = sum + 1
}
return (sum)
</function>


or

using 'for ()' Script/Function --- but I'm not familiar with how quest has it set up... I'm not sure how quest's 'for ()' Script/Function works/syntax, as it seems to be a bit different than the 'for()' in C++/Java Languages for example... as there's usually not (at least so far for me, lol) a need for using it in quest.