Referring to objects, rooms or npcs?

porunopal
Hey guys, this application is brilliant and so is the wiki, it is very comprehensive, but it lacks one thing: documentation on referring to other objects.

Let me explain:

I'm no newbie to programming, and I have a very very good game going so far, additionally, I'm building in my own battle system that is working very well except for a few things.

First of all
, I want to know how in the hell you refer to another object. I know you can go (and this is just an example) set var game.randomvariable = player.name
See that, you can refer to the game and the player nice and easy, however when I want to refer to another npc or the object I'm actually working on, it doesn't work.

I've tried self.name, object.name, me.name I've even tried making a variable that stores the name of the object and then tries to sub it in to no avail, I really need this, this issue is actually one of the things that is blocking me from making complete functions to reduce the workload.

The second
issue is my introduction. It uses a menu to set certain settings, it runs before the first room initialises its "this is what is inside me" script. However, I can't get the darn thing to wait until the user puts an input in before actually moving ahead, as soon as the menu is made it would automatically load the room description.

I put a wait command in but the thing is I don't want that because the player can skip the menu, and if I'm not careful it will keep the menu waiting for an input, so later on down the track when another opens they can't put their input in until they do it to the previous one!


Thirdly.
, warping to the current room or refreshing the rooms contents has been a piece of foshizzle. This comes down to the inability to refer to the current room name. I have read another post with this same issue, the purpose like mine is to refresh the room description, which involves going to another room, e.g. a battle dungeon, but how the hell do you get back to the previous room. Do you store the name of the room in a variable? If so, how do you refer to the current room then implement the variable in to warp the player?!!

Please help, these issues are game crippling, thanks for all your help!

jaynabonne
I hope I can answer your questions. One thing that would be helpful is to know whether you're using the online editor or the desktop (Windows) editor, as some options are different.

First of all, you refer to an object by its name. If you have an object called "apple", then you can use "apple.name" to see its name, "apple.parent" to get its current room, etc. You can set an attribute "x" to 3 by setting the var "apple.x" to 3. If that's not working for you, then it would be helpful to see some actual code so we can determine why.

Second, when you do your "show menu", be sure that you put the rest of your script *inside* the menu's "After choosing, run script" script. Things like menus, waiting for a key, etc are asynchronous and event-driven in Quest, meaning that statements *following* the "show menu" will execute immediately but once the user has made a choice, then the "After choosing" script will be run. There is no way to block in Quest for input. (There is something called "on ready", but it doesn't really help you, as you still have to put the desired additional code in a separate script block.)

Thirdly, to warp to a room, use MoveObject (e.g. MoveObject(player, room)). To refresh the room description, call the function ShowRoomDescription.

Again, the whole purpose of objects (including rooms) having names is so that you can refer to them. If we can solve why that is a problem for you, a lot of things should fall into place. (One thing to keep in mind: when you use an object's name, don't put it in quotes. It's a direct reference, not a string.)

HegemonKhan
reference to an Object or whatever:

Name Attribute = it's "ID" for the game engine (and also the game maker ~ for organization, info, and etc); just like with the government in real life, if two people have the same finger print, ID card, SS#, and etc, the government doesn't know what~who is what~who, it'll be confused and unable to function.

Name_Attribute_of_Object.name_of_Attribute

Example Object: an "orc" monster

Object' s Attributes, as done in the GUI~Editor:

this is our Object's reference (ID):
Name: name
Type: String
Value: orc_1


Name: alias
Type: String
Value: orc

Name: strength
Type: int (Integer)
Value: 50

for CREATION (or CHANGING) of the Object's Name Attribute (not sure if this works or not, lol), done as scripting:

object.name=orc_1

and as done in-code:

<object name="orc_1">
</object>

and with its other attributes:

<object name="orc_1">
-> <alias>orc</alias> // Or: <alias type="string">orc</alias>
-> <strength type="int">50</strength>
</object>

for USING ("refering to") an Object, for example, in creating its attributes ("alias" and "strength"), done as scripting:

(what object?).(what attribute?)=(what it "does"?, ie what Value or Expression?)
orc_1.alias=orc
orc_1.strength=50


and as done in-code:

~VS~

Alias Attribute = what we think of as a "name", mainly for the game player. You can have the same Alias Attributes, quest doesn't care as it doesn't use this for identification.

Local~Temporary Creation:

Variable = Object.Attribute
name_of_variable_string = name_of_Object.name_of_Attribute
example: enemy_damage = orc.strength

Global~Permanent Creation (provided that the Object remains existing):

Object.Attribute = Value (which includes an Expression)
name_of_Object.name_of_Attribute = name_of_Value (or simply your Expression)
example: orc_1.strength = 50
example: orc_1.damage = ((orc_1.strength - player.endurance) / 100) * orc_1.physical_damage + orc_1.physical_damage

very useful pages:

http://quest5.net/wiki/Category:All_Fun ... t_Commands (page 1, range: A-S)

http://quest5.net/w/index.php?title=Cat ... h#mw-pages (page 2, range: S-Z)

and, there's also:

1. Parameters ( http://quest5.net/wiki/Function_element )

2. GetObject ( http://quest5.net/wiki/GetObject ), HasObject ( http://quest5.net/wiki/HasObject ), ObjectListItem ( http://quest5.net/wiki/ObjectListItem ), ObjectDictionaryItem ( http://quest5.net/wiki/ObjectDictionaryItem )

3. only for within a Script that acts upon (ie is a "child" of) an Object (such as a Verb): you can use "this.name_of_Attribute" in place of "name_of_Object.name_of_Attribute".

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

for moving an object, here is what it looks like as done as scripting:

"parent" Attribute = the Room_Object (or Object_Object) that it is within

orc_1.parent = (the room you want it to be within ~ ie moved within)

Old Location: orc_1.parent = room
New Location ("moving it to"): orc_1.parent = room_2

player.parent = room_3

Part of Sgreig's "Following" Code (a tiny bit more fancy coding, lol):

orc_1.parent = player.parent

(since: orc_1.parent = player.parent = room_3, or in different ordering: player.parent = room_3 = orc_1.parent)
(the resulting effect is this: orc_1.parent = room_3, ie the "orc_1" is moved to whatever room that the "player" is within)

and, here's some code, for you to see lots of examples in use of what you ask for:

<!-- New Game Code -->

<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Colloseum">
<gameid>bbc85c01-6e80-4a71-8abf-c1e870fb5b42</gameid>
<version>1.0</version>
<firstpublished>2013</firstpublished>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
</asl>

<!-- Object Types -->

<type name="character_object_type">

<strength type="int">0</strength>
<endurance type="int">0</endurance>
<dexterity type="int">0</dexterity>
<agility type="int">0</agility>
<speed type="int">0</speed>
<intelligence type="int">0</intelligence>
<spirituality type="int">0</spirituality>
<mentality type="int">0</mentality>
<piety type="int">0</piety>
<luck type="int">0</luck>

<dead type="boolean">false</dead>

<undead type="boolean">false</undead>

<defending type="boolean">false</defending>
<casting type="boolean">false</casting>

<experience_points type="int">0</experience_points>
<cash type="int">0</cash>
<level type="int">0</level>

<health_points type="string">0/0</health_points>
<mana_points type="string">0/0</mana_points>

<current_health_points type="int">0</current_health_points>
<maximum_health_points type="int">0</maximum_health_points>
<current_mana_points type="int">0</current_mana_points>
<maximum_mana_points type="int">0</maximum_mana_points>

</type>

<!-- Turnscripts -->

<turnscript name="global_events_turnscript">
status_attributes_function
leveling_function
game.turns = game.turns + 1
</turnscript>

<!-- Commands -->

<command name="fight_command">
<pattern>fight #text#</pattern>
<script>
fight_function (game.pov,text)
</script>
</command>

<!-- Functions -->

<function name="fight_function" parameters="self,text">
enemy=GetObject(text)
if (enemy=null) {
foreach (obj,AllObjects()) {
if (obj.alias=text) {
enemy=obj
} else {
msg ("There seemingly is no " + text + " here.")
}
}
}
if (not check_reachable_function (enemy) = true) {
msg ("There seemingly is no " + enemy.alias + " here.")
} else if (not DoesInherit (enemy,"character_object_type")) {
msg (enemy.alias + "is seemingly not something that you can battle.")
} else if (GetBoolean (enemy,"hostile") = false) {
msg (enemy.alias + " is seemingly not something that you can battle.")
} else if (GetBoolean (enemy,"dead") = true) {
msg (enemy.alias + " is already dead.")
} else {
battle_sequence_function (self,enemy)
}
</function>

<function name="battle_sequence_function" parameters="self,enemy"><![CDATA[
if (enemy.dead=false or self.escaped=false) {
you_go_first=false
if (GetInt (self,"speed") > GetInt (enemy,"speed") {
you_go_first=true
} else if (GetInt (self,"speed") = GetInt (enemy,"speed") and RandomChance (50)=true) {
you_go_first=true
}
if (you_go_first=true) {
msg ("You get to go first for this round")
self_battle_turn_function (self,enemy)
on ready {
if (not enemy.dead=true or not self.escaped=true){
enemy_battle_turn_function (self,enemy)
}
}
} else {
msg (enemy.alias + " gets to go first for this round.")
enemy_battle_turn_function (self,enemy)
on ready {
if (not enemy.dead=true or not self.escaped=true){
msg ("It is now your turn.")
self_battle_turn_function (self,enemy)
}
}
}
on ready {
msg ("The round has ended.")
battle_sequence_function (self,enemy)
}
} else {
msg ("The battle is over.")
}
]]></function>

<function name="self_battle_turn_function" parameters="self,enemy"><![CDATA[
msg (self.alias + " has " + self.current_health_points + " HP left.")
msg (enemy.alias + " has " + enemy.current_health_points + " HP left.")
wait {
show menu ("What is your battle choice?", split ("Attack;Defend;Cast;Item;Run", ";"), false) {
switch (result) {
case ("Attack") {
self_attack_failed = false
if (RandomChance (GetInt (enemy,"agility") - GetInt (self,"speed")) = true) {
msg (enemy.alias + "evaded your attack!")
self_attack_failed = true
self.defending = false
} else if (RandomChance (GetInt (enemy,"dexterity") - GetInt (self,"agility")) = true) {
msg (enemy.alias + "parried your attack!")
self_attack_failed = true
self.defending = false
} else if (RandomChance (GetInt (enemy,"agility") - GetInt (self,"dexterity")) = true) {
msg (enemy.alias + "blocked your attack!")
self_attack_failed = true
self.defending = false
} else if (RandomChance (GetInt (self,"dexterity") - GetInt (enemy,"speed")) = false) {
msg ("Your attack missed " + enemy.alias +"!")
self_attack_failed = true
self.defending = false
} else if (RandomChance (GetInt (enemy,"armor_class") - GetInt (self,"attack_rating")) = true) {
msg ("Your attack failed to penetrate " + enemy.alias +"!")
self_attack_failed = true
self.defending = false
} else if (self_attack_failed = false) {
if (self.defending = true and enemy.defending = true) {
enemy.current_health_points = enemy.current_health_points - (critical_hit_function (self) * 2 * GetInt (self,"physical_damage") / 2 + GetInt (self,"physical_damage") * (GetInt (self,"strength") - GetInt (enemy,"endurance")) / 100)
msg (enemy.alias + " has " + enemy.current_health_points + " HP left.")
self.defending = false
} else if (self.defending = true and enemy.defending = false) {
enemy.current_health_points = enemy.current_health_points - (critical_hit_function (self) * 2 * GetInt (self,"physical_damage") + GetInt (self,"physical_damage") * (GetInt (self,"strength") - GetInt (enemy,"endurance")) / 100)
msg (enemy.alias + " has " + enemy.current_health_points + " HP left.")
self.defending = false
} else if (self.defending = false and enemy.defending = true) {
enemy.current_health_points = enemy.current_health_points - (critical_hit_function (self) * GetInt (self,"physical_damage") / 2 + GetInt (self,"physical_damage") * (GetInt (self,"strength") - GetInt (enemy,"endurance")) / 100)
msg (enemy.alias + " has " + enemy.current_health_points + " HP left.")
} else if (self.defending = false and enemy.defending = false) {
enemy.current_health_points = enemy.current_health_points - (critical_hit_function (self) * GetInt (self,"physical_damage") + GetInt (self,"physical_damage") * (GetInt (self,"strength") - GetInt (enemy,"endurance")) / 100)
msg (enemy.alias + " has " + enemy.current_health_points + " HP left.")
}
}
}
case ("Defend") {
msg ("You defend yourself against " + enemy.alias)
self.defending = true
}
case ("Cast") {
self.defending = false
}
case ("Item") {
self.defending = false
}
case ("Run") {
self.defending = false
self.escaping = true
}
}
if (GetInt (enemy,"current_health_points") > 0) {
if ( RandomChance (GetInt (self,"speed") - GetInt (enemy,"speed"))= true) {
msg ("You get an extra battle turn!")
self_battle_turn (self,enemy)
} else {
msg ("Your battle turn is over.")
}
} else if (GetInt (enemy,"current_health_points") <= 0) {
msg (enemy.alias + " is dead.")
msg ("You have won the battle!")
self.defending = false
self.escaping = false
enemy.defending = false
enemy.dead = true
}
}
}
]]></function>

<function name="enemy_battle_turn_function" parameters="self,enemy"><![CDATA[
msg (self.alias + " has " + self.current_health_points + " HP left.")
msg (enemy.alias + " has " + enemy.current_health_points + " HP left.")
result = GetRandomInt (1,3)
switch (result) {
case (1) {
enemy_attack_failed = false
if (RandomChance (GetInt (self,"agility") - GetInt (enemy,"speed")) = true) {
msg ("You have evaded the attack!")
enemy_attack_failed = true
enemy.defending = false
} else if (RandomChance (GetInt (self,"dexterity") - GetInt (enemy,"agility")) = true) {
msg ("You have parried the attack!")
enemy_attack_failed = true
enemy.defending = false
} else if (RandomChance (GetInt (self,"agility") - GetInt (enemy,"dexterity")) = true) {
msg ("You have blocked the attack!")
enemy_attack_failed = true
enemy.defending = false
} else if (RandomChance (GetInt (enemy,"dexterity") - GetInt (self,"speed")) = false) {
msg (enemy.alias +"'s attack missed!")
enemy_attack_failed = true
enemy.defending = false
} else if (RandomChance (GetInt (self,"armor_class") - GetInt (enemy,"attack_rating")) = true) {
msg ("You weren't penetrated by the attack!")
enemy_attack_failed = true
enemy.defending = false
} else if (enemy_attack_failed = false) {
if (enemy.defending = true and self.defending = true) {
self.current_health_points = self.current_health_points - (critical_hit_function (enemy) * 2 * GetInt (enemy,"physical_damage") / 2 + GetInt (enemy,"physical_damage") * (GetInt (enemy,"strength") - GetInt (self,"endurance")) / 100)
msg (self.alias + " has " + self.cur_hp + " HP left.")
enemy.defending = false
} else if (enemy.defending = true and self.defending = false) {
self.current_health_points = self.current_health_points - (critical_hit_function (enemy) * 2 * GetInt (enemy,"physical_damage") + GetInt (enemy,"physical_damage") * (GetInt (enemy,"strength") - GetInt (self,"endurance")) / 100)
msg (self.alias + " has " + self.current_health_points + " HP left.")
enemy.defending = false
} else if (enemy.defending = false and self.defending = true) {
self.current_health_points = self.current_health_points - (critical_hit_function (enemy) * GetInt (enemy,"physical_damage") / 2 + GetInt (enemy,"physical_damage") * (GetInt (enemy,"strength") - GetInt (self,"endurance")) / 100)
msg (self.alias + " has " + self.current_health_points + " HP left.")
} else if (enemy.defending = false and self.defending = false) {
self.current_health_points = self.current_health_points - (critical_hit_function (enemy) * GetInt (enemy,"physical_damage") + GetInt (enemy,"physical_damage") * (GetInt (enemy,"strength") - GetInt (self,"endurance")) / 100)
msg (self.alias + " has " + self.current_health_points + " HP left.")
}
}
}
case (2) {
msg (enemy.alias + " has choosen to defend itself.")
enemy.defending = true
}
case (3) {
enemy.defending = false
msg ("Cast")
}
}
if (GetInt (self,"current_health_points") > 0) {
if (RandomChance (GetInt (enemy,"speed") - GetInt (self,"speed")) = true) {
msg (enemy.alias + " gets an extra battle turn!")
wait {
enemy_battle_turn (self,enemy)
}
} else {
msg (enemy.alias + " 's battle turn is over.")
}
} else if (GetInt (self,"current_health_points") <= 0) {
msg (self.alias + " has died.")
msg ("GAME OVER")
finish
}
]]></function>

<function name="check_reachable_function" parameters="enemy" type="boolean">
foreach (obj,ScopeReachableNotHeld ()) {
if (obj=enemy) {
value = true
} else {
value = false
}
}
return (value)
</function>

<function name="critical_hit_function" parameters="target" type="int">
if (RandomChance (GetInt (target,"luck")) = true) {
value = 2
} else {
value = 1
}
return (value)
</function>

<function name="leveling_function"><![CDATA[
if (game.pov.experience_points >= game.pov.level * 100 + 100) {
game.pov.experience_points = game.pov.experience_points - (game.pov.level * 100 + 100)
game.pov.level = game.pov.level + 1
leveling_function
}
]]></function>

<function name="status_attributes_function">
game.pov.health_points = game.pov.current_health_points + "/" + game.pov.maximum_health_points
game.pov.mana_points = game.pov.current_mana_points + "/" + game.pov.maximum_mana_points
</function>

HegemonKhan
porunopal wrote:the purpose like mine is to refresh the room description, which involves going to another room, e.g. a battle dungeon, but how the hell do you get back to the previous room. Do you store the name of the room in a variable? If so, how do you refer to the current room then implement the variable in to warp the player?!!


(I did this coding super quick, so it's extremely poor ~ lacking a lot of scripts and has bad design, and~or maybe has errors in it ~ doesn't work, but it does demonstrate the aspects that you desire)

<game name="blah">
// blah code lines
<room_to_return_to_after_the_fight type="object">null</room_to_return_to_after_the_fight>
// blah code lines
</game>

<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="player_object" />
<inherit name="editor_object" />
</object>
// "orc_1" Object is suppose to be placed here too, but see below, as I don't want to try to redo it correctly, lol
<object>

<object name="battle_room">
<inherit name="editor_room" />
<object>

<object name="orc_1">
<inherit name="editor_object" />
<parent type="object">room</parent> // to account for not putting this, "orc_1", Object into the "room" Room Object.
<displayverbs type="simplestringlist">Lookat; Fight; Attack; etc</displayverbs>
<fight type="script">
if (this.dead=false) {
game.room_to_return_to_after_the_fight = player.parent // "saving" the location ("room")
this.parent=battle_room // moving "orc_1" to new location ("battle_room")
player.parent=battle_room // moving "player" to new location ("battle_room")
}
</fight>
<attack type="script">
if (this.parent=battle_room and player.parent=battle_room) {
if (this.dead=true) {
this.parent=game.room_to_return_to_after_the_fight // "loading" the saved location ("room"), ie moving "orc_1" back to "room".
player.parent=game.room_to_return_to_after_the_fight // // "loading" the saved location ("room"), ie moving "player" back to "room".
} else {
this.hp=this.hp-player.damage
player.hp=player.hp-this.damage
if (player.hp=0) {
finish
} else if (this.hp=0) {
this.dead=true
}
invoke (this.attack)
}
}
</attack>
</object>

porunopal
Hey guys, thanks a lot for your input, it has really helped and the room solution is fantastic!

I have another question tho, say I made a complete battle system function but it had to sub in the name of the enemy could I use something like:

create an attribute
name it game.enemyname
set variable: game.enemyname = minotaur.name/minotaur.alias

therefore in the function game.enemyname.name

so it would go minotaur.name therefore the name of the minotaur object is minotaur.

can you sub names in when referring to an object?

jaynabonne
If all you need is the enemy name, then you can do that. But if you want to actually refer to the current enemy, then it makes more sense to simply use the enemy object itself.

Let's say you have two enemies:

<object name="Minotaur">
...
</object>

<object name="Dragon">
...
</object>

and you want to have a generic combat system. Then you could have a function like:

<function name="BeginCombat" parameters="enemy">
// Set the current enemy in the game object.
game.currentenemy = enemy
</function>

You would invoke it by calling the function with the enemy *object* reference, not its name:

BeginCombat(Minotaur)

or

BeginCombat(Dragon)

Note that those are direct object references, not name strings (there are no quotes around them). Then any time you want, you can grab the attributes of that enemy. For example, to get it's name, you'd use:

msg("The current enemy name is " + game.currentenemy.name)

If you really do want to use the name of the enemy in spots as in incoming param, then I would still convert it to an object reference for use (using GetObject). It's too difficult storing and manipulating objects by their names all the time.

porunopal
Ah, ok, well I'll see if I can implement it!

Thanks again for your help, and thanks kan for yours!

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums