Zepeus wrote:Yeah, I guess... So anyway, tell me how the commands work, because I know how to use commands like "sleep" or "kill self", but I don't know about using commands for all the monsters and enemies in the game.
Thx, Zepeus
THIS IS MOSTLY THEORY, trying to explain so you hopefully start to understand what, how, and~or why is going on with what you're doing.
At the very bottom, I'll give you the actual code (correct format and syntax) of stuff that you can copy, paste, and use within your games.
commands (and functions too) is(are) often used as a general term(s), which is very confusing for people new to coding. So, don't confuse these generalized usages of "commands" (and "functions") with the actual COMMANDS (and FUNCTIONS) in quest.
as stated~explained by Liam:
VERBS act upon only that object. This individual usage is known as "local"-ness. (You've probably come across "local" variables or attributes in your readings on here. This means that they only apply to the script that they are within. To make a variable or attribute "universal", to be able to still use it outside of the script that it was made within, you must attach~assign it to something permanent, such as objects ~ well objects that don't get removed or destroyed, lol). So, if you want to do an action beyond a single individual object, you create...
COMMANDS are "universal" verbs, they require extra coding in order for them to operate on whatever you want them to do so. Also, unlike Verbs, Commands are only activated by the game player~user literally typing in its "pattern", there's no buttons or hyperlinks to click on for Commands. In the GUI~Editor, you access (i.e. create~add) commands via the very top bar of: File ~ ??? ~ Add ~ ??? ~ Help, through the "Add" option. Commands are not attributes attached to an object, like verbs are as~via a tab you click on for that specific and only object in the GUI~Editor. Commands are coding~script, script blocks, like Functions.
----------------
I personally like to keep my Commands without the script blocks directly inside of them, instead using Functions for containing the huge script blocks (as functions are powerful too; good for doing complex stuff). Hopefully I can explain this so that it will make sense for you as you're still new to quest, and especially with coding (I'm going to use code, as it's just a lot easier and faster in trying to explain than with the GUI~Editor, that takes a lot of work, which I'd be glad to do for you, though when I've got the time to do so, which isn't right now, lol). And, by using functions for the script blocks, I can keep my Command's patterns (what you the user~player in game has to type in to activate the command) very short, as I hate writing~typing out more than I have too, lol.
so this is how I do this stuff, for examples:
Commands (in Code form):
<command name="help_command">
<pattern>help</pattern>
<script>
help_function
</script>
</command>
<command name="fight_command">
<pattern>fight #text#</pattern> // or you can use this too~instead: <pattern>fight #object#</pattern>
<script>
fight_function (game.pov,text) // or: fight_function (game.pov,object)
</script>
</command>
<command name="equip_command">
<pattern>equip #text#</pattern> // or you can use this too~instead: <pattern>equip #object#</pattern>
<script>
equip_function (text) // or: equip_function (object)
</script>
</command>
<command name="goto_command">
<pattern>goto #text#</pattern> // or you can use this too~instead: <pattern>goto #object#</pattern>
<script>
goto_function (text) // or: goto_function (object)
</script>
</command>
etc etc etc commands
extremely useful coding (means of organization:note making) stuff in general:
If you used any libraries, you've probably noticed this coding~scripting stuff:
the ' // ' tells the game engine, that everything to the right of this are your comments (which will show up in the GUI~Editor as green text; uber sweet!), and is not coding for it to execute~do~run.
' <!-- (your comments) --> ' this does the same thing as the ' // ', but unfortunately, it does not show up in your GUI~Editor.
and it can also be done in this format too:
<!--
(your comments)
-->
about the Command in code form:
<command name="(its name)"> // the name of the Command; NAME attributes are used for the game engine to identify it. Think of NAME attributes as a car's license plate or your SS# or Driver's ID card, and the game engine is the government which uses these things to identify you as you (or not as you, lol).
<pattern>(your "pattern")</pattern> // this is how (and what operation) that the game player~user must type in, in order to activate the command. for example for: ' <pattern>fight #text#</pattern> ' the game player~user has to type in: fight orc, in this case, the "orc" input is recognized as "text" by the game engine (due to your use of, #text#, in the pattern). If #object# is used instead, than the "orc" would be recognized as an object by the game engine. I'll explain this further later on, as there's a very big difference.
<script> // what you put below this (<script>), is what is done by the command. In my examples, I'm choosing to just using a single script line, call function (as it is known in the GUI~Editor choice), which is done in code, by simple typing in the NAME attribute of the function, which for my examples are, ' help_function ' or ' fight_function ' or ' equip_function ' or ' goto_function ', as my~those functions will contain the actual full script stuff of what and how I want my commands to do their stuff.
</script> // this tells the game engine that, that script has come to an end
</command> // this tells the game engine that, that command has come to an end
now, about the command pattern's choices, between #text# or #object# :
as mention: #text# tells the game engine that whatever the game player~user types in, it is to be recognized as text (a string) and #object# tells the game engine that whatever the game player~user types in, it is to be recognized as an object.
This matters greatly, as if you use #object#, whatever is typed in, must be an actual (existing) object in the game, as that is what the game engine will be searching for: an object with that NAME attribute that the game player~user types in, such as my example of: orc. So, if there's no actual object NAMED "orc", the command will not be able to do what you made it for doing. If you use #text#, then likewise, if you want your Command to act upon an object, it won't be able to as well, as remember that the game engine will search for text (a string) called "orc", but it won't ever actually GET the actual object (as it's not looking for an object) for you to do your action~stuff~command~function~script upon it. The game engine must actually GET the OBJECT, for it to then do stuff to the object. This may not be the best analogy, but think of it in terms of copy and paste. If you don't COPY (GET~STORE~SAVE~HAVE) the text, then the computer can't then paste (an action on) it. Well the same is true with quest's objects, you have to have the quest game engine GET the object, for it to be able to do an action upon that object. Text (a string) is not an object. So, if quest is searching (GETTING) for text (#text#), it's not searching for an object (#object#).
Now, that I've confused you deeply, lol, here's an example of it in action and how to deal with it:
<command name="fight_command">
<pattern>fight #text#</pattern>
<script>
fight_function (game.pov,text)
</script>
</command>
<function name="fight_function" parameters="game.pov,text">
enemy=GetObject(text)
</function>
<object name="orc">
<inherited name="editor_object"/>
</object>
we dealt with this by using this added script~code line: enemy=GetObject(text)
and here's it explained step by step:
1. the game player~user types in: fight orc
2. the command, fight_command, 's pattern of, fight #text#, tells the game engine to search (GET) for "orc" as TEXT (STRING)
3. but even if there was an "orc" as text (string), the command (and function) would be useless.
4. so we have to tell the game engine to get the OBJECT, which is done by: enemy=GetObject(text). The ' GetObject ' code, tells the game engine to search (GET) for an OBJECT (whereas it was priorly searching for text, a string, from the command's pattern's #text#). The (text) is what thing that the game engine will search (and GET, if it exists) for as its OBJECT, which is the "orc". So, now it utilizes the command's searching for the text of "orc", so the command's searching for the text wasn't actually pointless, to find what will be its OBJECT. The game engine finds the "orc" text (string) in: <object name="orc">, as the, ="orc", is a text (string) type of attribute. Then, it finally sets the OBJECT.ORC as "enemy", and being an actual GOTTEN OBJECT, the unwritten~missing (,so the, pretending,) rest of the coding~scripting by me lol, can now act upon it.
now, if we used #object#, then we wouldn't need the, GetObject(text), as the #object# does the same thing as the "GetObject"
You may be asking then why ever use the #text#, well there's many cases of why this can be useful and~or needed too. One example is with dialogue (such as conversation topics). Though, it's a bit too hard to explain, why else you might or need to use #text#, and I'm already writing so much already, lol. But, most often, you'll just want to use #object#, do to actions upon objects.
hopefully, you can understand functions in code, a bit now, as they're far too extensive to even begin to try to explain everything (all the coding) that they can do, lol.
however, you may have noticed the ' fight_function (game.pov,object or text) ' in the command ' fight_command ', and the ' parameters="game.pov,text or object" in the function ' fight_function ', so on to explaining parameters:
parameters are what things you acting upon, for example:
<command name="fight_command">
<pattern>fight #text or object#</pattern>
<script>
fight_function (game.pov,text or object)
</script>
</command>
<function name="fight_function" parameters="game.pov,text">
enemy=GetObject(text)
</function>
in the Command: two things will be used: (game.pov) and (text or object)
"game.pov" GETS "you" (the currently controlled Player Object), such as the (default) "player" Player Object, and SETS it as "THING_#1"
the <pattern>(its pattern)</pattern> SETS what is typed in by the game player~user as the "text" or "object", which then the...
"text or object" GETS, such as my example of "orc", and SETS it as "THING_#2"
now about parameters' format~syntax:
"THING_#1,THING_#2,THING_#3,etc"
this does not change, from the Command's parameter's in its script line ' fight_function (game.pov,text or object) ', to the Function's parameter's script line ' <function name="fight_function" parameters="game.pov,text or object"> '.
the "orc" (as text or object) is SET as THING_#1, due to it's position as first. After the initial~first parameter setting in the Command, the labels for the parameters don't matter.
let me explain by direct example:
default player object is currently controlled
game player~user types in: fight orc
<command name="fight_command">
<pattern>fight #text or object#</pattern>
<script>
fight_function (player,orc)
</script>
</command>
<function name="fight_function" parameters="player,orc">
enemy_object_orc=GetObject(parameter_label_orc)
object_name_player=parameter_label_player
</function>
now, let's change the non-initial parameter labels, but it results (things) still doesn't change: player and orc
default player object is currently controlled
game player~user types in: fight orc
<command name="fight_command">
<pattern>fight #text or object#</pattern>
<script>
fight_function (game.pov,text or object)
</script>
</command>
<function name="fight_function" parameters="self,target">
enemy_object_orc=GetObject(parameter_label_target)
object_name_player=parameter_label_self
fight_function_2
</function>
and still no change, for the CALLED, fight_function_2:
<function name="fight_function_two" parameters="target,self">
enemy_object_orc=GetObject(parameter_label_self)
object_name_player=parameter_label_target
</function>
so, only the POSITION~ORDER ("THING_#1,THING_#2,THING_#3,etc") is transfered from one parameter stringlist to another parameter stringlist.
parameter stringlist 1 = fight_function (THING_#1,THING_#2,THING_#3,etc)
parameter stringlist 2 = <function name="fight_function" paramaters="THING_#1,THING_#2,THING_#3,etc"
parameter stringlist 3 = <function name="fight_function_2" paramaters="THING_#1,THING_#2,THING_#3,etc"
the leftmost item in the parameter stringlists is ALWAYS "THING_#1", which in my example is: game.pov
the rightmost item (thing_#2, as we've only got two items in my example) is ALWAYS "THING_#2", which in my example is: orc
In parameter stringlists 2 and 3, I can label the "thing_#1" and "thing_02" as whatever I want (for each of the 2 stringlists), but that has no effect on the game engine in having~setting~using that position 1 is game.pov and position 2 is orc
however, the parameter stringlist 1 (and in this case, the command's pattern too), DOES SET what are the actual items to be used throughout the transfer of them from parameter stringlist to parameter stringlist.
-------------------
unfortunately, we're still not done yet, with commands, lol.
an entirely different problem is that "GETTING AN OBJECT", does so, only via its NAME attribute.
so, for example, here's a problem case:
<command name="fight_command">
<pattern>fight #text#</pattern>
<script>
fight_function (game.pov,text)
</script>
</command>
<function name="fight_function" parameters="game.pov,text">
enemy=GetObject(text)
</function>
<object name="red_orc_1">
<inherited name="editor_object"/>
<alias>orc</alias>
</object>
the ' GetObject ' will fail, because the game player~user sees the object's ALIAS, "orc", which he~she will type in: fight orc. But, the ' GetObject ' code tells the game engine to search for a NAME attribute of "orc". Notice that there's no NAME attribute of "orc", and so it fails to GET the orc object, because the orc object's NAME is "red_orc_1" and not "orc". So, to fix the problem of using ALIASES, we've got to add these code~script lines in:
null = game engine couldn't find it (though this isn't the only usage or meaning of "null")
<command name="fight_command">
<pattern>fight #text#</pattern>
<script>
fight_function (game.pov,text)
</script>
</command>
<function name="fight_function" parameters="game.pov,text">
enemy=GetObject(text)
if enemy=null {
foreach (obj,AllObjects()) {
if (obj.alias=text) {
enemy = obj
}
}
}
</function>
<object name="red_orc_1">
<inherited name="editor_object"/>
<alias>orc</alias>
</object>
did you spot the new code lines?
they're:
if enemy=null {
foreach (obj,AllObjects()) {
if (obj.alias=text) {
enemy = obj
}
}
}
this is what is going on here:
1. if there's no found object with the NAME of "orc", then...
2. search through all of the objects in the entire game, and "For Each" of those objects (labeled as "obj")...
3. if the object "obj" (i.e. any and each object from the searching of the entire game for all of its objects) 's ALIAS is "orc", then...
4. set that "obj" as~to "enemy" (the game engine will now finally recognize any usage of "enemy" as the "red_orc_1" object)
-----------------------------------------------
here's an example of "my" (ALL Credit goes to Pertex as I used his~her code structure, it's not really my code, lol) combat code (cleaned up by Pertex), it will be very daunting for you (and was very daunting for me, wow did I get a HIGH when I finally got it to work, hehe), but maybe if I've done well in explaining all this stuff, you might be able to understand at least some parts of it, lol. And feel free to use (or play, lol) it too!
it's old, so it's v5.3, and it may need some tinkering, to get it to work for 5.4, ask anyone who knows the changes to 5.4 and~or how to code well here, and it probably won't be too hard for them to convert it to being usable with v5.4 for you. The very least change is simply to change the first line of ' <asl version="530"> ' to ' <asl version="540"> '
<asl version="530">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Test">
<gameid>d83ba5bb-2e3c-4f31-80c9-3e88a2dc082c</gameid>
<version>1.0</version>
<pov type="object">player</pov>
<start type="script">
cc
</start>
<turns type="int">0</turns>
<statusattributes type="stringdictionary">turns = </statusattributes>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="defaultplayer" />
<inherit name="pc" />
<cur_hp type="int">999</cur_hp>
<max_hp type="int">999</max_hp>
<str type="int">100</str>
<end type="int">100</end>
<dex type="int">100</dex>
<agi type="int">100</agi>
<spd type="int">100</spd>
<hc type="int">100</hc>
<pd type="int">100</pd>
<pr type="int">100</pr>
</object>
<object name="orc1">
<inherit name="editor_object" />
<inherit name="npc" />
<hostile type="boolean">true</hostile>
<dead type="boolean">false</dead>
<alias>orc</alias>
<cur_hp type="int">999</cur_hp>
<max_hp type="int">999</max_hp>
<str type="int">25</str>
<end type="int">25</end>
<dex type="int">25</dex>
<agi type="int">25</agi>
<spd type="int">25</spd>
<hc type="int">25</hc>
<pd type="int">25</pd>
<pr type="int">25</pr>
</object>
</object>
<turnscript name="game_turns">
<enabled />
<script>
sa
game.turns = game.turns + 1
</script>
</turnscript>
<command name="fight">
<pattern>fight #text#</pattern>
<script>
battle_system (game.pov,text)
</script>
</command>
<type name="char">
<cur_hp type="int">0</cur_hp>
<drop type="boolean">false</drop>
<defending type="boolean">false</defending>
<max_hp type="int">0</max_hp>
<str type="int">0</str>
<end type="int">0</end>
<dex type="int">0</dex>
<agi type="int">0</agi>
<spd type="int">0</spd>
<hp type="int">0</hp>
<hc type="int">0</hc>
<pd type="int">0</pd>
<pr type="int">0</pr>
</type>
<type name="pc">
<inherit name="char" />
<statusattributes type="stringdictionary">hp = ;str = ;end = ;dex = ;agi = ;spd = ;hc = ;pd = ;pr = </statusattributes>
</type>
<type name="npc">
<inherit name="char" />
<dead type="boolean">false</dead>
<hostile type="boolean">false</hostile>
<displayverbs type="list">Look at; Talk; Fight</displayverbs>
</type>
<function name="cc">
msg ("What is your name?")
get input {
game.pov.alias = result
msg (" - " + game.pov.alias)
show menu ("What is your gender?", split ("male;female" , ";"), false) {
game.pov.gender = result
show menu ("What is your race?", split ("human;dwarf;elf" , ";"), false) {
game.pov.race = result
show menu ("What is your class?", split ("warrior;cleric;mage;thief" , ";"), false) {
game.pov.class = result
msg (game.pov.alias + " is a " + game.pov.gender + " " + game.pov.race + " " + game.pov.class + ".")
wait {
ClearScreen
}
}
}
}
}
</function>
<function name="sa">
game.pov.hp = game.pov.cur_hp + " / " + game.pov.max_hp
</function>
<function name="battle_system" parameters="self,text">
enemy = GetObject (text)
if (enemy = null) {
foreach (obj,AllObjects()) {
if (obj.alias=text) {
enemy = obj
}
}
}
if (enemy = null) {
msg ("There is no " + text + " here.")
}
else if (not Doesinherit (enemy,"npc")) {
msg ("You can not battle that!")
}
else if (not npc_reachable (enemy)) {
msg ("There is no " + enemy.alias + " in your vicinity.")
}
else if (GetBoolean (enemy,"dead") = true) {
msg (enemy.alias + " is already dead.")
}
else if (GetBoolean (enemy,"hostile") = false) {
msg (enemy.alias + " is not hostile.")
}
else {
battle_sequence (self,enemy)
}
</function>
<function name="battle_sequence" parameters="self,enemy"><![CDATA[
if (enemy.dead = false) {
playerfirst=false
if (GetInt (self,"spd") > GetInt (enemy,"spd")) {
playerfirst=true
} else if (GetInt (self,"spd") = GetInt (enemy,"spd") and RandomChance (50)) {
playerfirst=true
}
if (playerfirst) {
msg ("You get to go first for this round")
self_battle_turn (self,enemy)
on ready {
if (not enemy.dead){
enemy_battle_turn (self,enemy)
}
}
} else {
msg (enemy.alias + " gets to go first for this round.")
enemy_battle_turn (self,enemy)
msg ("It is now your turn.")
self_battle_turn (self,enemy)
}
on ready {
msg ("The round has ended.")
msg("")
battle_sequence (self,enemy)
}
} else {
msg ("The battle is over.")
}
]]></function>
<function name="self_battle_turn" parameters="self,enemy"><![CDATA[
msg (self.alias + " has " + self.cur_hp + " HP left.")
msg (enemy.alias + " has " + enemy.cur_hp + " HP left.")
wait {
show menu ("What is your battle choice?", split ("Attack;Defend;Cast;Item;Run", ";"), false) {
switch (result) {
case ("Attack") {
fourth_value = false
if (RandomChance (GetInt (enemy,"agi") - GetInt (self,"spd")) = true) {
msg (enemy.alias + "evaded your attack!")
fourth_value = true
}
else if (RandomChance (GetInt (enemy,"Dex") - GetInt (self,"agi")) = true) {
msg (enemy.alias + "parried your attack!")
fourth_value = true
}
else if (RandomChance (GetInt (enemy,"agi") - GetInt (self,"dex")) = true) {
msg (enemy.alias + "blocked your attack!")
fourth_value = true
}
else if (RandomChance (GetInt (self,"dex") - GetInt (enemy,"spd")) = false) {
msg ("Your attack missed " + enemy.alias +"!")
fourth_value = true
}
else if (RandomChance (GetInt (enemy,"pr") - GetInt (self,"hc")) = true) {
msg ("Your attack got resisted by " + enemy.alias +"!")
fourth_value = true
}
else if (fourth_value = false) {
if (self.defending = true and enemy.defending = true) {
enemy.cur_hp = enemy.cur_hp - (crit_hit (self) * 2 * GetInt (self,"pd") / 2 + GetInt (self,"pd") * (GetInt (self,"str") - GetInt (enemy,"end")) / 100)
msg (enemy.alias + " has " + enemy.cur_hp + " HP left.")
self.defending = false
}
else if (self.defending = true and enemy.defending = false) {
enemy.cur_hp = enemy.cur_hp - (crit_hit (self) * 2 * GetInt (self,"pd") + GetInt (self,"pd") * (GetInt (self,"str") - GetInt (enemy,"end")) / 100)
msg (enemy.alias + " has " + enemy.cur_hp + " HP left.")
self.defending = false
}
else if (self.defending = false and enemy.defending = true) {
enemy.cur_hp = enemy.cur_hp - (crit_hit (self) * GetInt (self,"pd") / 2 + GetInt (self,"pd") * (GetInt (self,"str") - GetInt (enemy,"end")) / 100)
msg (enemy.alias + " has " + enemy.cur_hp + " HP left.")
}
else if (self.defending = false and enemy.defending = false) {
enemy.cur_hp = enemy.cur_hp - (crit_hit (self) * GetInt (self,"pd") + GetInt (self,"pd") * (GetInt (self,"str") - GetInt (enemy,"end")) / 100)
msg (enemy.alias + " has " + enemy.cur_hp + " HP left.")
}
}
}
case ("Defend") {
if (self.defending = false) {
self.defending = true
}
}
case ("Cast") {
self.defending = false
}
case ("Item") {
self.defending = false
}
case ("Run") {
self.defending = false
}
}
if (GetInt (enemy,"cur_hp") > 0) {
if ( RandomChance (GetInt (self,"spd") - GetInt (enemy,"spd"))= true) {
msg ("You get an extra battle turn!")
self_battle_turn (self,enemy)
}
else {
msg ("Your battle turn is over.")
}
}
else if (GetInt (enemy,"cur_hp") <= 0) {
msg (enemy.alias + " is dead.")
msg ("You have won the battle!")
enemy.defending = false
enemy.dead = true
}
}
}
]]></function>
<function name="enemy_battle_turn" parameters="self,enemy"><![CDATA[
msg (self.alias + " has " + self.cur_hp + " HP left.")
msg (enemy.alias + " has " + enemy.cur_hp + " HP left.")
result = GetRandomInt (1,3)
switch (result) {
case (1) {
sixth_value = false
if (RandomChance (GetInt (self,"agi") - GetInt (enemy,"spd")) = true) {
msg ("You have evaded the attack!")
sixth_value = true
}
else if (RandomChance (GetInt (self,"dex") - GetInt (enemy,"agi")) = true) {
msg ("You have parried the attack!")
sixth_value = true
}
else if (RandomChance (GetInt (self,"agi") - GetInt (enemy,"dex")) = true) {
msg ("You have blocked the attack!")
sixth_value = true
}
else if (RandomChance (GetInt (enemy,"dex") - GetInt (self,"spd")) = false) {
msg (enemy.alias +"'s attack missed!")
sixth_value = true
}
else if (RandomChance (GetInt (self,"pr") - GetInt (enemy,"hc")) = true) {
msg ("You resisted the attack!")
sixth_value = true
}
else if (sixth_value = false) {
if (enemy.defending = true and self.defending = true) {
self.cur_hp = self.cur_hp - (crit_hit (enemy) * 2 * GetInt (enemy,"pd") / 2 + GetInt (enemy,"pd") * (GetInt (enemy,"str") - GetInt (self,"end")) / 100)
msg (self.alias + " has " + self.cur_hp + " HP left.")
enemy.defending = false
}
else if (enemy.defending = true and self.defending = false) {
self.cur_hp = self.cur_hp - (crit_hit (enemy) * 2 * GetInt (enemy,"pd") + GetInt (enemy,"pd") * (GetInt (enemy,"str") - GetInt (self,"end")) / 100)
msg (self.alias + " has " + self.cur_hp + " HP left.")
enemy.defending = false
}
else if (enemy.defending = false and self.defending = true) {
self.cur_hp = self.cur_hp - (crit_hit (enemy) * GetInt (enemy,"pd") / 2 + GetInt (enemy,"pd") * (GetInt (enemy,"str") - GetInt (self,"end")) / 100)
msg (self.alias + " has " + self.cur_hp + " HP left.")
}
else if (enemy.defending = false and self.defending = false) {
self.cur_hp = self.cur_hp - (crit_hit (enemy) * GetInt (enemy,"pd") + GetInt (enemy,"pd") * (GetInt (enemy,"str") - GetInt (self,"end")) / 100)
msg (self.alias + " has " + self.cur_hp + " HP left.")
}
}
}
case (2) {
if (enemy.defending = false) {
msg (enemy.alias + " has choosen to defend itself.")
enemy.defending = true
}
}
case (3) {
enemy.defending = false
msg ("Cast")
}
}
if (GetInt (self,"cur_hp") > 0) {
if (RandomChance (GetInt (enemy,"spd") - GetInt (self,"spd")) = 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,"cur_hp") <= 0) {
msg (self.alias + " has died.")
msg ("GAME OVER")
finish
}
]]></function>
<function name="npc_reachable" parameters="object" type="boolean">
value = false
foreach (x,ScopeReachableNotHeld ()) {
if (x=object) {
value = true
}
}
return (value)
</function>
<function name="crit_hit" parameters="object" type="int">
if (RandomChance (GetInt (object,"luck")) = true) {
value = 2
}
else {
value = 1
}
return (value)
</function>
</asl>
----------------------------------
P.S.
Lastly, another thing that Liam was explaining, is all of the "checks" that're needed with commands (or their used functions), to make the game engine understand what you want from it, here's my "checks" for my combat system:
<function name="battle_system" parameters="self,text">
enemy = GetObject (text)
if (enemy = null) {
foreach (obj,AllObjects()) {
if (obj.alias=text) {
enemy = obj
}
}
}
if (enemy = null) {
msg ("There is no " + text + " here.")
}
else if (not Doesinherit (enemy,"npc")) {
msg ("You can not battle that!")
}
else if (not npc_reachable (enemy)) {
msg ("There is no " + enemy.alias + " in your vicinity.")
}
else if (GetBoolean (enemy,"dead") = true) {
msg (enemy.alias + " is already dead.")
}
else if (GetBoolean (enemy,"hostile") = false) {
msg (enemy.alias + " is not hostile.")
}
else {
battle_sequence (self,enemy)
}
</function>
can you understand any of them?
based upon the game player~user being able to type in anything, I have to account for all of the possibilities, so the game engine responds in the correct ways with what was typed in.
1. you can't fight an "input (what the game player~user typed in)" if it doesn't exist
2. you can't fight a non-npc (npc=non-playable character) type of object, such as a "room" type of object or "flowers" object, lol
(I'm not distinguishing a "monster" type of object, as instead I'm implementing a "hostility" system instead, any "npc" can be friend or foe, depending on whether you've angered or pleased them, hehe)
3. you can't fight something that you haven't noticed (i.e. made accessible), for example, pretend that there's an orc inside of a box, well you can't fight the orc until you open the box up (and thus become aware of the orc and also make the orc within your "vicinity", as maybe you can see the orc, but you shouldn't be able to reach the orc, and so, shouldn't be able to fight the orc, as for example, you see the orc up on the mountain ledge above you, but you can't get up to that ledge).
4. you can't fight what is already dead.
5. you can't fight a non-hostile (i.e. neutral or ally) npc.
------------------
P.S.S.
with this desire:
Zepeus wrote:... but I don't know about using commands for all the monsters and enemies in the game.
Thx, Zepeus
and thus here's a big challenge for you (hehe):
can you now build your own fight (or whatever) command that can work on all and any of your monsters~enemies in your game? (using what I gave you here, you do have all that you need in order to do so, well except on how to use OBJECT TYPES, i.e. "inherited" attributes, and then being able to know -hint- to set the needed attributes on your monsters~enemies directly and~or via from your OBJECT TYPES having your needed attributes. Main attributes for monsters~enemies: "fightable due to not being dead / fightable due to being alive", "fightable due to being a monster~enemy", and "fightable due to the environment~scenero~conditions")