exact copy (not a duplicate)
Kit_sune
21 Oct 2012, 00:53So far I'm really enjoying using Quest. I haven't run into any real road blocks with the ideas I have, but right now I'm trying to find a simpler way to do something.
Basically, I'm wanting to have several "templates" that would hold all the values/attributes that the player's character would adopt when their race was chosen.
For instance, if human was chosen, I would copy all the attributes from the human template onto the player object.
Is this doable? Or would I have to literally write code for every attribute I wanted to change? I ask this because I'm using a lot of attributes.
Similarly, what if I wanted to make one thing exactly the same as another?
for instance, I have a four legged chair, and a three legged stool. The chair has the attribute "legs" set to 4, and the stool's legs set to 3.
I use a wand or whatever on the stool, and want to make it turn into a chair, so the stool is now a chair, and has 4 legs.
Thanks for your time,
Any ideas are welcomed, I've been dabling in various coding projects on various different programs, so I'm not a beginner, but I'm still a novice.
Basically, I'm wanting to have several "templates" that would hold all the values/attributes that the player's character would adopt when their race was chosen.
For instance, if human was chosen, I would copy all the attributes from the human template onto the player object.
Is this doable? Or would I have to literally write code for every attribute I wanted to change? I ask this because I'm using a lot of attributes.

Similarly, what if I wanted to make one thing exactly the same as another?
for instance, I have a four legged chair, and a three legged stool. The chair has the attribute "legs" set to 4, and the stool's legs set to 3.
I use a wand or whatever on the stool, and want to make it turn into a chair, so the stool is now a chair, and has 4 legs.
Thanks for your time,
Any ideas are welcomed, I've been dabling in various coding projects on various different programs, so I'm not a beginner, but I'm still a novice.
sgreig
21 Oct 2012, 04:24You'll want to use Types for this purpose. 

Kit_sune
21 Oct 2012, 06:37I'm trying to learn! I spent several hours trying to figure this out, so please know that much! (It's 1:40 am rightnow, and heading off to bed) Thanks for pointing me in the right direction.
I see the help has this to say
Well, here’s what I’m looking at so far. The thing is, I don’t know where to put it. I currently have it located after the “</start>” tag. I can’t see it in the Quest editor (not sure if supposed to).
Now, for the second part, I have the following code that I had put together that the game prompts right away. (shortened for space) I’m not clear on how I’m supposed to edit this to make it reference the “type” information above.
thanks

I see the help has this to say
<type name="food">
<health type="int">0</health>
<eat>It looks tasty, but you're not hungry right now.</eat>
</type>
<type name="fruit">
<inherit name="food"/>
<health>10</health>
</type>
Well, here’s what I’m looking at so far. The thing is, I don’t know where to put it. I currently have it located after the “</start>” tag. I can’t see it in the Quest editor (not sure if supposed to).
<type name="foxdemon">
<race>fox</race>
<hp type="int">75</hp>
<maxhp type="int">75</maxhp>
<speed type="int">6</speed>
<dodge type="int">7</dodge>
<str type="int">3</str>
<atk type="int">4</atk>
</type>
Now, for the second part, I have the following code that I had put together that the game prompts right away. (shortened for space) I’m not clear on how I’m supposed to edit this to make it reference the “type” information above.
<start type="script"><![CDATA[
LISTrace = NewStringList()
list add (LISTrace, "human")
list add (LISTrace, "cat")
list add (LISTrace, "dog")
list add (LISTrace, "fox")
-- snipped --
msg ("Are you human, demon, or a mixture of both?")
show menu ("I am ...", LISTrace, false) {
player.race = result
msg ("I am " + player.race)
--snipped--
}
]]></start>
thanks

jaynabonne
21 Oct 2012, 09:42Actually, you can't use types for this as such, as types can only be invoked at "build" time (or whatever name you want to give it). You can't manipulate or use a type in a script. You can say an object is of a certain type, but you couldn't peek into that type at run time and see attributes, etc.
You have two things to work out.
1) You need a place to store different attributes for different races.
2) You need a way to take those attributes and add them to the player object dynamically.
If you can live with a level of indirection for accessing the attributes, then I would place the different race attributes in to separate race objects and then simply store an attribute to the chosen race variable in the player.
Note three things. First, you have to use objects, not types. If you had made them types, you would not be able to use them in your scripts (their names aren't accessible to scripts). Second, if you use a dictionary for the menu instead of a straight list (it supports both flavors), then you can pair up a string (e.g. "human") with your desired result (e.g. the HumanRace object). And third, in the above example, all the race variables are nested under a "race" attribute. That means that instead of using "player.maxhp", you'd have to use "player.race.maxhp". I don't consider that too bad of a deal. But if it is for you, read on...
If you really do need a way to set all the attributes directly onto the player, then life becomes harder. The main thing that's missing for what you want to do is a way to enumerate attributes on an object. So you couldn't, say, look through all the attributes of the chosen race object and copy them to the player. One solution is to do it all by hand:
Which I assume is what you wanted to avoid...
A solution to that is to set up a string list (once) of all the attributes you care about, and then use *that* to enumerate the race object. It's not 100% automatic as you do have to maintain the list, but it's, well, *automated*.
You do have to set up the attributes list, but once you do that, the code handles the rest.
So those are three choices I can offer:
1) Use a nested "race" object attribute
2) Copy the attributes by hand
3) Set up a list of the attributes you want to copy.
Hope that helps!
(Note: the code above I just whacked in there. There might be a typo or two, so if you take it verbatim and it doesn't work straight off, it's me not you. Either ask for help, or work out the problem.
)
You have two things to work out.
1) You need a place to store different attributes for different races.
2) You need a way to take those attributes and add them to the player object dynamically.
If you can live with a level of indirection for accessing the attributes, then I would place the different race attributes in to separate race objects and then simply store an attribute to the chosen race variable in the player.
<object name="HumanRace">
<race>human</race>
<maxhp type="int">50</maxhp>
</object>
<object name="FoxDemon">
<race>fox demon</race>
<maxhp type="int">75</maxhp>
</object>
choices = NewStringDictionary()
dictionary add (choices, HumanRace.race, "HumanRace")
dictionary add (choices, CatRace.race, "CatRace")
dictionary add (choices, DogRace.race, "DogRace")
dictionary add (choices, FoxRace.race, "FoxRace")
-- snipped --
msg ("What is your race?")
show menu ("I am ...", choices, false) {
player.race = GetObject(result)
msg ("I am " + player.race.race)
msg ("My maxhp is " + player.race.maxhp)
Note three things. First, you have to use objects, not types. If you had made them types, you would not be able to use them in your scripts (their names aren't accessible to scripts). Second, if you use a dictionary for the menu instead of a straight list (it supports both flavors), then you can pair up a string (e.g. "human") with your desired result (e.g. the HumanRace object). And third, in the above example, all the race variables are nested under a "race" attribute. That means that instead of using "player.maxhp", you'd have to use "player.race.maxhp". I don't consider that too bad of a deal. But if it is for you, read on...

If you really do need a way to set all the attributes directly onto the player, then life becomes harder. The main thing that's missing for what you want to do is a way to enumerate attributes on an object. So you couldn't, say, look through all the attributes of the chosen race object and copy them to the player. One solution is to do it all by hand:
player.race = race.race
player.maxhp = race.maxhp
...
Which I assume is what you wanted to avoid...
A solution to that is to set up a string list (once) of all the attributes you care about, and then use *that* to enumerate the race object. It's not 100% automatic as you do have to maintain the list, but it's, well, *automated*.
<type name="RaceBase">
<attributes type="list">race; maxhp; speed; dodge; str</attributes>
<type>
<object name="HumanRace">
<inherit name="RaceBase"/>
<race>human</race>
<maxhp type="int">50</maxhp>
--snipped--
</object>
<object name="CatRace">
<inherit name="RaceBase"/>
<race>cat</race>
<maxhp type="int">35</maxhp>
--snipped--
</object>
choices = NewStringDictionary()
dictionary add (choices, HumanRace.race, "HumanRace")
dictionary add (choices, CatRace.race, "CatRace")
dictionary add (choices, DogRace.race, "DogRace")
dictionary add (choices, FoxRace.race, "FoxRace")
-- snipped --
msg ("What is your race?")
show menu ("I am ...", choices, false) {
// Copy all the attributes, using the "attributes" string list as key.
race = GetObject(result)
foreach (attribute, race.attributes) {
set (player, attribute, GetAttribute(race, attribute))
}
msg ("I am a " + player.race)
msg ("My maxhp is " + player.maxhp)
You do have to set up the attributes list, but once you do that, the code handles the rest.
So those are three choices I can offer:
1) Use a nested "race" object attribute
2) Copy the attributes by hand
3) Set up a list of the attributes you want to copy.
Hope that helps!
(Note: the code above I just whacked in there. There might be a typo or two, so if you take it verbatim and it doesn't work straight off, it's me not you. Either ask for help, or work out the problem.


jaynabonne
21 Oct 2012, 10:01Your second question above is a bit harder to answer, mostly because it's less clear to me what you want to do. Here's a stab... If you keep a level of indirection for the type an object, then you could easily change types at runtime. If you want to have direct attributes, then you'd have to copy attributes:
Or you could just copy attributes, perhaps using code like for races, but dynamically... (This code is even more whacked in there...
)
<object name="ChairType">
<name>chair</name>
<legs type="int">4<legs>
--etc--
</object>
<object name="StoolType">
<name>stool</name>
<legs type="int">3<legs>
--etc--
</object>
<object name="MySittingThing">
<type type="object">ChairType</type>
<domagic type="script">
this.type = StoolType
</domagic>
</object>
---some code ---
msg("My seat type is " + MySittingThing.type.name)
do (MySittingThing, "domagic")
msg("My seat type is now " + MySittingThing.type.name)
// You should see a change!
Or you could just copy attributes, perhaps using code like for races, but dynamically... (This code is even more whacked in there...


jaynabonne
21 Oct 2012, 11:16I'm going to comment on my own code here...
What I have above as:
could (and probably should) be easily re-written as:
The above parallel adds suggest a pattern. You don't have to do this, but depending on how many races you have, how often they change, what your coding aesthetics, are etc , it might make sense. This is optional...
The pattern established above is "dictonary add (choices, X.race, X.name)". This lends itself toward generalizing. In a nuthshell, you could do this:
First, add a string list attribute to your game:
The list would contain the object name for each race object you have created. Then you can simply do:
Then you can control which races you are using just by changing the string list attribute of the game...
What I have above as:
choices = NewStringDictionary()
dictionary add (choices, HumanRace.race, "HumanRace")
dictionary add (choices, CatRace.race, "CatRace")
dictionary add (choices, DogRace.race, "DogRace")
dictionary add (choices, FoxRace.race, "FoxRace")
could (and probably should) be easily re-written as:
choices = NewStringDictionary()
dictionary add (choices, HumanRace.race, HumanRace.name)
dictionary add (choices, CatRace.race, CatRace.name)
dictionary add (choices, DogRace.race, DogRace.name)
dictionary add (choices, FoxRace.race, FoxRace.name)
The above parallel adds suggest a pattern. You don't have to do this, but depending on how many races you have, how often they change, what your coding aesthetics, are etc , it might make sense. This is optional...
The pattern established above is "dictonary add (choices, X.race, X.name)". This lends itself toward generalizing. In a nuthshell, you could do this:
First, add a string list attribute to your game:
<game ...>
...
<races type="list">HumanRace; CatRace; DogRace; ThreeleggedRace; SpaceRace</races>
...
</game>
The list would contain the object name for each race object you have created. Then you can simply do:
choices = NewStringDictionary()
foreach (racename, game.races) {
raceobject = GetObject(racename)
dictionary add (choices, raceobject.race, raceobject.name)
}
Then you can control which races you are using just by changing the string list attribute of the game...
Alex
21 Oct 2012, 12:59There is a new function in Quest 5.3 called GetAttributeNames which returns a list of attribute names for the specified object. (It takes a second boolean parameter specifying whether to include the names of attributes from inherited types too).

jaynabonne
21 Oct 2012, 14:04Very cool! Now that's what I like to hear. 

Kit_sune
21 Oct 2012, 17:20Thanks jaynabonne, I like the way you think!
So, I put together the code you had in a test game to see how to get it to work, and after playing around with it for a while I can't seem to get around this one error that keeps popping up.
Here's what the file looks like, but I've also uploaded it. It's a test game so it's short.
So, I put together the code you had in a test game to see how to get it to work, and after playing around with it for a while I can't seem to get around this one error that keeps popping up.
Error running script: Error compiling expression 'raceobject.race': Variable does not refer to an object: 'raceobject'
Here's what the file looks like, but I've also uploaded it. It's a test game so it's short.
<!--Saved by Quest 5.2.4515.34846-->
<asl version="520">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Testing">
<gameid>e352a6d8-c005-4b44-8021-1cf6a3f13fde</gameid>
<description type="string"></description>
<races type="list">HumanRace; CatRace; DogRace; ThreeleggedRace; SpaceRace</races>
<start type="script">
choices = NewStringDictionary()
foreach (racename, game.races) {
raceobject = GetObject(racename)
dictionary add (choices, raceobject.race, raceobject.name)
msg ("What is your race?")
show menu ("My race is...", choices, false) {
// Copy all the attributes, using the "attributes" string list as key.
race = result
foreach (attribute, race.attributes) {
set (player, attribute, GetAttribute(race, attribute))
}
}
}
msg ("I am a " + player.race)
msg ("My maxhp is " + player.maxhp)
</start>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="defaultplayer" />
</object>
</object>
</asl>

jaynabonne
21 Oct 2012, 18:20There were a few problems. First, you hadn't defined the actual race objects (e.g. HumanRace, DogRace, etc). By the way, the "ThreeleggedRace, SpaceRace", were jokes...
I added the base type with the attributes list and the race objects.
Also, the part that ran the menu was inside the loop that was setting the items. So I rearranged that. And then the part that printed out the "I am..." wasn't inside the script that was executed after the menu was done. So it ran before the menu was even done.
See how the attached looks.

Also, the part that ran the menu was inside the loop that was setting the items. So I rearranged that. And then the part that printed out the "I am..." wasn't inside the script that was executed after the menu was done. So it ran before the menu was even done.
See how the attached looks.
The Pixie
21 Oct 2012, 18:41You need to set up the race objects, HumanRace, CatRace, etc. The line "raceobject = GetObject(racename)" is trying to find an object called HumanRace; as there is no such object, raceobject is set to null, rather than referring to an object. These objects will have attributes race, name and maxhp.
I think show menu needs a stringlist rather than a stringdictionary, so you would be better using the races attribute.
Also, you need to define race.attributes; personally I would change that to game.attributes, and set that up as a string list on the game object.
You script would look like this (untested):
I think show menu needs a stringlist rather than a stringdictionary, so you would be better using the races attribute.
Also, you need to define race.attributes; personally I would change that to game.attributes, and set that up as a string list on the game object.
You script would look like this (untested):
<start type="script">
show menu ("My race is...", races, false) {
raceobject = GetObject(result)
// Copy all the attributes, using the "attributes" string list as key.
foreach (attribute, game.attributes) {
set (player, attribute, GetAttribute(game, attribute))
}
}
}
msg ("I am a " + player.race)
msg ("My maxhp is " + player.maxhp)
</start>

jaynabonne
21 Oct 2012, 18:50Actually, "show menu" can take either a string list or a string dictionary. If it's a string list, the choices are the direct strings, and the result is the chosen string. If it's a string dictionary, then the "value" part of each entry is shown in the menu, and the "key" of the chosen entry is returned in result.
(Kit_Sune: check out my response in the other thread for what might be a better solution, following your lead.)
(Kit_Sune: check out my response in the other thread for what might be a better solution, following your lead.)
Kit_sune
21 Oct 2012, 19:09I knew those things looked a little jumbled, thanks for correcting that.
Alright, I get it now, I guess I didn't realize it was looking for actual objects! Perfect, now that the roadblock has been cleared - both in the game and in my brain, I can continue messing around in Quest.
There's so much work to do x.x
Battle System
Equipment system
Levelup system
Inventory
Editable player program (like changing appearance, which would have an affect on the game)
Value system (money)
Enemies
do you see what I did there? :3
Thank you to everyone who has given me some input, I look forward to continuing my programming education with Quest.
kitsune
edit -
checking right now
Alright, I get it now, I guess I didn't realize it was looking for actual objects! Perfect, now that the roadblock has been cleared - both in the game and in my brain, I can continue messing around in Quest.
There's so much work to do x.x
Battle System
Equipment system
Levelup system
Inventory
Editable player program (like changing appearance, which would have an affect on the game)
Value system (money)
Enemies
do you see what I did there? :3
Thank you to everyone who has given me some input, I look forward to continuing my programming education with Quest.
kitsune
edit -
jaynabonne wrote:
(Kit_Sune: check out my response in the other thread for what might be a better solution, following your lead.)
checking right now