Assigning a type on the fly

homeeman
08 Mar 2013, 16:54
It this something you can do? I can't figure out a quick way to create a new <inherit> tag.
If it helps, I'm trying to give a player and their companions classes based on choice. If I can't assign types on the fly I can cope pretty easily, I just think it'll look cleaner if I employ type definitions.
Am I grossly misusing types?

levicki
08 Mar 2013, 17:42
With current quest implementation of player object (auto-creation in the first room before running start script), I am not sure what you want is possible, unless your "player" object inherits from all classes and then has a variable which tells you which class is active so you can handle skills and status attributes properly.

Check out this small demo of what I had in mind:


Note that I don't claim that is the best way to handle things, maybe someone has a better idea.

homeeman
08 Mar 2013, 22:49
Thanks for the quick response! I ended up going with using the POV switching. I predefined a separate object for every choose-able class (since there are only four) and switch to whichever class they choose when they choose it. As for the other NPCs, I'll probably do something similar, and simply move the created class objects as they're chosen, changing the alias to give them their given name (in case anyone else every stumbles across this post).

levicki
09 Mar 2013, 03:31
homeeman wrote:Thanks for the quick response! I ended up going with using the POV switching. I predefined a separate object for every choose-able class (since there are only four) and switch to whichever class they choose when they choose it. As for the other NPCs, I'll probably do something similar, and simply move the created class objects as they're chosen, changing the alias to give them their given name (in case anyone else every stumbles across this post).


You are welcome, I hope you did try my demo game, at least for lolz? ;-)

homeeman
09 Mar 2013, 06:01
I did, sir. And I got a laugh out of it. I appreciated the Star Wars reference. I feel like I haven't seen much of that, of all the references you get out of here!

HegemonKhan
09 Mar 2013, 08:41
that is interesting, that there's no way to set (or nor add) an inherited attribute ??

though for an alternative, couldn't you simply make an "If" script to add all the attributes you want, as a substitution method of an inherited attribute? use a script to give the same attributes as the inherited attribute would?

for example:

<turnscript name="game_turns_turnscript">
if (player.bear = true) {
player.strength = player.strength * 2
etc attributes
}
</turnscript>

which would be the same thing as using an inherited attribute:

<type name="bear">
player.strength = player.strength *2
etc attributes
</type>

jaynabonne
09 Mar 2013, 11:07
Another alternative (depending on exactly on what you're doing) is to have the classes broken out as objects, one per class, and then have a "class" attribute on the player which points to the one selected.

It does mean you have to reference the class stuff as "player.class." instead of "player." but it is another approach.

I have done this, and it worked well for me.

HegemonKhan
09 Mar 2013, 22:40
just echoing (and concuring~supporting) Jaynebonne's method:

objects (used as "object structures" or "data storages" as I think Pixie calls them) are really useful, as inside of the object, you can put whatever you want (like scripts, lists, dictionaries, attributes, and etc), it's like a super container+more, as it lets you to "call upon" ANYTHING, I love using them! :D

I think this is how quest is built, everything is an object, and that's why making+using objects are so powerful, hehe

a very poor example, and probably incorrect, but it's just for show of what you can do with objects used to hold whatever you want:

<object name="spell_storage_structure">
<fire_spells_list type="objectlist">fireball;inferno;heat;etc</fire_spells_list>
<water_spells_list type="objectlist">tidalwave;rain;drench;etc</water_spells_list>
</object>

<cast type="script">
if (HasObject (player.spell_structure.fire_spells_list = fireball) {
monster.hp = monster.hp - fireball.damage
} else {
msg ("You can't cast that spell.")
}
</cast>

jaynabonne
09 Mar 2013, 22:57
HK, I think you mean:

if (ListContains(player.spell_structure.fire_spells_list, fireball))

:)

HegemonKhan
09 Mar 2013, 23:00
thanks for the correction! (I just added in a comment to my previous post as you wrote yours too)

Unfortunately, I don't know coding well enough to write whatever coding correctly from the top of my head, laughs.

also, my setup of it is wrong too:

it should be something like:

if (player.fireball = spell_storage_structure.fire_spell_list.fireball) {

in the context of what I was trying to write as code, lol.

as if the object is a child of the player, it's not really being used as the "object structure" or "data storage", but merely instead as a "storage object".

---------

okay, I think this would be more closely to correct setup (as now my mind is thinking hard, lol):

<command name="cast_command">
<pattern>cast #text#</pattern>
<script>
cast_function (text)
</script>
</command>

<function name="cast_function" parameters="text">
if (text = spell_structure.fire_spells_list.fireball.name) {
if (GetObject (player.text) {
monster.hp = monster.hp - fireball.damage
} else {
msg ("You don't have this spell.")
}
} else {
msg ("You can't cast this, as it's not a spell")
}
</function>

<object name="spell_structure">
<fire_spells_list type="list">fireball;inferno;melt;hellfire;etc</fire_spells_list>
</object>

levicki
10 Mar 2013, 13:49
HegemonKhan wrote:that is interesting, that there's no way to set (or nor add) an inherited attribute ??


I am afraid that you have misunderstood both his question and my answer.

He asked if he could change from what type an object inherits after it was already created.

If you look at the code in any game you will see something like this:

<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
<inherit name="female_elf" />

What he asked was whether it is possible to, for example, dynamically replace inherit "female_elf" with say "male_golem" based on player's class choice. As far as I know that is currently not possible.

homeeman
10 Mar 2013, 18:09
levicki, I'm pretty sure that they understood what was being asked, they were merely suggesting alternative ways to deal with the situation since you already pointed out that there is no way to assign a type after play has begun.
As it happens, jaynabonne, what I ended up doing very nearly resembles your suggestion, except that I utilized the POV switching (very largely because I hadn't used it before and wanted to try it) to make the object that represents the class choice be used as the player (that is, I'll refer to things as "class.attribute"). Thanks to everyone for their suggestions!
I probably would have used HK's on my first game (had the issue come up) but I just hate how difficult it is to find things like attributes and abilities the player may have when they're buried in code. This is the first thing I'm writing for the game, and I just don't want to bother with that.

HegemonKhan
10 Mar 2013, 20:22
thanks for the clarification, Levicki, my apologies for not understanding homeeman's question correctly.

I don't know how easy it would be to implement, but maybe we should send a request to Alex for some kind of wat to add, remove, or other way of changing the inherited types (or the object types) during the game (after character~player~npc objects are created).

Until than, it'd probably be better to have a script that adds all the attributes you want, as that can be called upon, and would be able to switched (called upon again) with another function with its attributes.

<script>
if character_object = warrior
warrior_function
</script>

<script>
if character_object = wizzard
wizzard_function
</script>

<function name="warrior_class">
character_object.attribute
character_object.attribute
character_object.attribute
</function>

<function name="wizzard_class">
character_object.attribute
character_object.attribute
character_object.attribute
</function>

now... can a function be made to remove the attributes (so you don't ahve a huge list of attributes on your character_objects, lol (nvm, forgot about simply setting them to null, though I'm not sure if this actually removes the attributes' coding or not. still coming up with a function that is able to turn off all your old attributes may not be easy or possible to make, can this be done, as I'm still a noob and am learning coding, with many mistakes and misunderstandings, but I like to participate in things or code stuff beyond me, as it helps me learn, and see how much or little I know about stuff)

jaynabonne
10 Mar 2013, 22:09
My two cents: I personally wouldn't "go there" as far as even suggesting a feature for changing types like that. No computer language that I have used has ever allowed runtime switching of object types, and there are plenty of software design patterns for handling what people need to do (e.g. what I had proposed before is a basic "pimpl" design pattern).

But let's say that it was determined that changing an object's inheritance tree at runtime was desired, as opposed to the more typical composition that is supported with Quest (or switching of POV/object references in this case, which is a way to defer object creation/selection until a type is known). Consider the challenges involved with that, due to the multiple inheritance involved, especially as far as common attributes defined in multiple base types.

Consider this case:

  <type name="BaseA">
<color>Red</color>
</type>
<type name="BaseB">
<color>Blue</color>
</type>
<object name="Derived">
<inherit name="BaseA"/>
<inherit name="BaseB"/>
</object>


What is Derived.color? It turns out it's "Blue". So, at least empirically, it seems that the effective attribute for an object is in the latest <inherit'ed> type where it appears.

Now let's say someone wanted to *change* a base type. We would need methods to, perhaps, remove a base type, insert a base type, replace a base type? Would we want the ability to remove all inherited types and add new ones? Would we want to be able to remove BaseA and replace it with BaseC, or perhaps have BaseC be inserted into the inheritance list *after* BaseB?

And, in the end, it would be quite a complex undertaking to implement something that a) will actually rarely be used, and b) is really not needed, as there are plenty of ways of implementing software that don't need such a feature. There might even be objections from a purist software design point of view as well.

I'd say define your objects to be the types you want, statically. If you need dynamic, runtime selection of objects of different types, then use a contained object that you can redefine on the fly (POV is just such an indirect object pointer/reference).

jaynabonne
10 Mar 2013, 22:25
Another note: with the ability to loop over object attributes now, you could also quite easily have archetype/prototype objects that you simply copy attributes from.

Here is a sample function:

  <function name="CopyAttributes" parameters="source,target,copyInherited">
<![CDATA[
foreach (attribute, GetAttributeNames(source, copyInherited)) {
if (attribute <> "name") {
set (target, attribute, GetAttribute(source, attribute))
}
}
]]>
</function>


This will set into "target" all the attributes from "source". If you don't want all inherited attributes (e.g. from types), then set "copyInherited" to false. Otherwise, set it to true.

So now you can define objects as holders for basic attribute sets and then just copy them to the player object once the type is determined. And note that it will copy all attributes, even script, dictionaries, etc. (The only one it doesn't is "name", which is unique per object.)

  <object name="HumanPrototype">
<classname>Human</classname>
<strength type="int">5</strength>
<speed type="int">4</speed>
<agility type="int">7</agility>
<attack type="script">
msg("This is a human attacking...")
</attack>
</object>

...
CopyAttributes(HumanPrototype, player,false)