(if it's okay with omega, you can join us, as we're working together to make more progress on rpg aspects and eventually full games... lol)
(I'm trying to develop more code for RPG aspects like those seen in TES games: arena, daggerfall, morrowind, oblivion, skyrim)
(omega is kinda making a game with some RPG aspects like the Fallout games)
--------
this is asking a lot, laughs. A full combat+game system, is a massive amount of coding and design, lol. I'm working on a combat system still myelf, Omega too is working on one, and there's probably some others too.
I'll provide you some links that you can look at and use, and answer invidivudal questions and provide help, but you're going have to work on this stuff yourself, as everyone is pretty busy doing their own games and~or learning to code~make games with quest.
-------------
my old combat code (Credit to Pertex for help and the code structure, as I'm using his combat code structure):
<asl version="530">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Testing Game Stuff">
<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" type="boolean">
first_value = false
enemy = GetObject (text)
if (enemy = null) {
foreach (obj,AllObjects()) {
if (obj.alias=text) {
enemy = obj
}
}
}
if (enemy = null) {
msg ("There is no " + text + " here.")
first_value = false
}
else if (not Doesinherit (enemy,"npc")) {
msg ("You can not battle that!")
first_value = false
}
else if (not npc_reachable (enemy)) {
msg ("There is no " + enemy.alias + " in your vicinity.")
first_value = false
}
else if (GetBoolean (enemy,"dead") = true) {
msg (enemy.alias + " is already dead.")
first_value = false
}
else if (GetBoolean (enemy,"hostile") = false) {
msg (enemy.alias + " is not hostile.")
first_value = false
}
else if (battle_sequence (self,enemy) = true) {
msg ("The battle is over.")
first_value = true
}
return (first_value)
</function>
<function name="battle_sequence" parameters="self,enemy" type="boolean"><![CDATA[
second_value = false
if (enemy.dead = false) {
if (GetInt (self,"spd") > GetInt (enemy,"spd")) {
on ready {
msg ("You get to go first for this round")
if (self_battle_turn (self,enemy) = true) {
battle_sequence (self,enemy)
}
}
on ready {
if (enemy.dead = false) {
if (enemy_battle_turn (self,enemy) = true) {
msg ("The round has ended.")
}
}
}
on ready {
battle_sequence (self,enemy)
}
}
else if (GetInt (self,"spd") < GetInt (enemy,"spd")) {
on ready {
msg (enemy.alias + " gets to go first for this round.")
if (enemy_battle_turn (self,enemy) = true) {
msg ("It is now your turn.")
}
}
on ready {
if (self_battle_turn (self,enemy) = true) {
battle_sequence (self,enemy)
}
else {
msg ("The round has ended.")
}
}
on ready {
battle_sequence (self,enemy)
}
}
else if (GetInt (self,"spd") = GetInt (enemy,"spd")) {
if (RandomChance (50) = true) {
on ready {
msg ("You get to go first for this round")
if (self_battle_turn (self,enemy) = true) {
battle_sequence (self,enemy)
}
}
on ready {
if (enemy_battle_turn (self,enemy) = true) {
msg ("The round has ended.")
}
}
on ready {
battle_sequence (self,enemy)
}
}
else {
on ready {
msg (enemy.alias + " gets to go first for this round.")
if (enemy_battle_turn (self,enemy) = true) {
msg ("It is now your turn.")
}
}
on ready {
if (self_battle_turn (self,enemy) = true) {
battle_sequence (self,enemy)
}
else {
msg ("The round has ended.")
}
}
on ready {
battle_sequence (self,enemy)
}
}
}
}
else {
second_value = true
}
return (second_value)
]]></function>
<function name="self_battle_turn" parameters="self,enemy" type="boolean"><![CDATA[
third_value = false
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.")
third_value = false
}
}
else if (GetInt (enemy,"cur_hp") <= 0) {
msg (enemy.alias + " is dead.")
msg ("You have won the battle!")
enemy.defending = false
enemy.dead = true
third_value = true
wait {
ClearScreen
}
}
}
}
return (third_value)
]]></function>
<function name="enemy_battle_turn" parameters="self,enemy" type="boolean"><![CDATA[
fifth_value = false
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.")
fifth_value = true
}
}
else if (GetInt (self,"cur_hp") <= 0) {
msg (self.alias + " has died.")
msg ("GAME OVER")
finish
}
return (fifth_value)
]]></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>
and the legend~key for it (sorry, for this, but this is old code, I've learned to not use abrevs anymore, laughs):
01. cc = character creation function
02. sa = status attributes (mainly for implementing/displaying of ' cur / max ' stats) function
03. char = character object type ("pcs", "npcs", "monsters", etc., so, not a room, item, equipment, spell, etc)
04. pc = playable character object type ("player" characters / game.povs)
05. npc = non-playable character ("people", "monsters", and etc, so not a "player" character / not a game.pov, I'm going to have a hostility system, so any npc can be friendly or hostile, instead of having an actual "monster/enemy" type set aside)
06. hp = hit points (life) stat attribute
07. mp = mana points (magic) stat attribute
08. str = strength (physical damage, carry weight / equipment requirement, etc) stat attribute
09. end = endurance (physical defense, and etc) stat attribute
10. dex = dexterity (weapon~attack skill, think of this as "if your attack connects or not, do you 'whiff' or not", so not to gete confused with hc, and etc) stat attribute
11. agi = agility (dodging/evading, and etc) stat attribute
12. spd = speed (who goes first in battle, extra battle turns, escaping from battle, and etc) stat attribute
13. hc = hit chance (think of this more as piercing their armor or not, so not to get confused with dex, and etc) stat attribute
14. pd = physical damage stat attribute
15. fp = fire damage stat attribute
16. wp = water damage stat attribute
17. ap = air damage stat attribute
18. ed = earth damage stat attribute
19. ld = light damage stat attribute
20. dd = dark damage stat attribute
21. pr = physical resistance stat attribute
22. fr = fire resistance stat attribute
23. wr = water resistance stat attribute
24. ar = air resistance stat attribute
25. er = earth resistance stat attribute
26. lr = light resistance stat attribute
27. dr = dark resistance stat attribute
28. defending = boolean (reduces damage done for that character and increases the damage done by that character, if they chosoe to attack on the next turn)
29. escaped = boolean, run from battle (not completed/implemented yet)
30. hostile = boolean, any npc can be friendly or a(n) "monster/enemy", based upon a hostility scale (0-100), but not completed
31. dead = boolean
32. crit_hit = critical hit (bonus damage based upon luck)
33. luck = luck stat attribute
34. lvl = level stat attribute
35. exp = experience stat attribute
36. cash = cash stat attribute (currency)
37. lvlup = level up function
--------
other links:
01.
viewtopic.php?f=18&t=2901 (equipment)
02.
viewforum.php?f=18 (libraries: guides)
03.
viewtopic.php?f=18&t=266004.
viewtopic.php?f=18&t=255705.
viewtopic.php?f=18&t=351506.
http://quest5.net/wiki/Category:All_Fun ... t_Commands (page 1, range: A-S)
07.
http://quest5.net/w/index.php?title=Cat ... t#mw-pages (page 2, range: S-Z)
08.
http://quest5.net/wiki/How_to (guides, scroll down for the bottom half of guides too)
09.
http://quest5.net/wiki/Main_Page10.
http://quest5.net/wiki/Tutorial11.
http://quest5.net/wiki/Simple_Combat_System_(Advanced) .
12.
http://quest5.net/wiki/Using_Types_and_Tabs_(Advanced) (magic system, scroll down, especially at the very bottom are the links for Pixie's Spell library)
13.
viewtopic.php?f=18&t=4057 (interface allowing for clicking hyperlinks for adjusting stats~attributes at a level up)
-----------
HP and MP:
yes, having a second attribute is probably the easiest way to do it, for example (in code, sorry, but it's fast and easy for me to post help via code):
player.current_hit_point_integer = Value
player.maximum_hit_point_integer = Value
(optional: a minimum attribute too: player.minimum_hit_point_integer = Value, not so needed for HP, but some other game stats~attributes might~could use it)
if (player.current.hit_point_integer > player.maximum_hit_point_integer) {
player.current_hit_point_integer = player.maximum_hit_point_integer
}
if you want game code using min and max HP and MP, let me know, and I'll get one posted up for you.
--------
ensuring damage done to player by enemies, for example:
if (enemy.damage <= 0) {
enemy.damage = 1
}
player.hp = player.hp - enemy.damage
---------
saving and loading game:
I haven't worked with how saving games work, so someone else will have to help you on~with this
------
explore and travel:
my old explore and travel code:
<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Testing Game Stuff">
<gameid>eef801a1-4e6b-4b0a-bdbf-8f3ecfa8389c</gameid>
<version>1.0</version>
<firstpublished>2013</firstpublished>
<turns type="int">0</turns>
<statusattributes type="simplestringdictionary">turns=</statusattributes>
<start type="script">
msg ("Important Note:")
msg ("Type in: help")
</start>
</game>
<object name="homeland">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
<object name="grassland">
<inherit name="editor_room" />
</object>
<object name="plains">
<inherit name="editor_room" />
</object>
<object name="desert">
<inherit name="editor_room" />
</object>
<object name="tundra">
<inherit name="editor_room" />
</object>
<object name="swampland">
<inherit name="editor_room" />
</object>
<object name="mountains">
<inherit name="editor_room" />
</object>
<object name="forest">
<inherit name="editor_room" />
</object>
<object name="wasteland">
<inherit name="editor_room" />
</object>
<object name="coastland">
<inherit name="editor_room" />
</object>
<object name="hills">
<inherit name="editor_room" />
</object>
<command name="help_command">
<pattern>help</pattern>
<script>
help_function
</script>
</command>
<command name="explore_command">
<pattern>explore</pattern>
<script>
explore_function
</script>
</command>
<command name="travel_command">
<pattern>travel</pattern>
<script>
travel_function
</script>
</command>
<object name="data_object">
<inherit name="editor_object" />
<travel_string_list type="simplestringlist">homeland</travel_string_list>
<homeland_events_string_list type="simplestringlist">grassland_discovery;plains_discovery;desert_discovery;tundra_discovery;swampland_discovery;forest_discovery;mountains_discovery;hills_discovery;wasteland_discovery;coastland_discovery</homeland_events_string_list>
<homeland_events_script_dictionary type="scriptdictionary">
<item key="grassland_discovery">
list add (data_object.travel_string_list, "grassland")
msg ("You've discovered the grassland! Now, you can travel to the grassland and explore it!")
</item>
<item key="plains_discovery">
list add (data_object.travel_string_list, "plains")
msg ("You've discovered the plains! Now, you can travel to the plains and explore it!")
</item>
<item key="desert_discovery">
list add (data_object.travel_string_list, "desert")
msg ("You've discovered the desert! Now, you can travel to the desert and explore it!")
</item>
<item key="tundra_discovery">
list add (data_object.travel_string_list, "tundra")
msg ("You've discovered the tundra! Now, you can travel to the tundra and explore it!")
</item>
<item key="swampland_discovery">
list add (data_object.travel_string_list, "swampland")
msg ("You've discovered the swampland! Now, you can travel to the swampland and explore it!")
</item>
<item key="forest_discovery">
list add (data_object.travel_string_list, "forest")
msg ("You've discovered the forest! Now, you can travel to the forest and explore it!")
</item>
<item key="mountains_discovery">
list add (data_object.travel_string_list, "mountains")
msg ("You've discovered the mountains! Now, you can travel to the mountains and explore it!")
</item>
<item key="hills_discovery">
list add (data_object.travel_string_list, "hills")
msg ("You've discovered the hills! Now, you can travel to the hills and explore it!")
</item>
<item key="wasteland_discovery">
list add (data_object.travel_string_list, "wasteland")
msg ("You've discovered the wasteland! Now, you can travel to the wasteland and explore it!")
</item>
<item key="coastland_discovery">
list add (data_object.travel_string_list, "coastland")
msg ("You've discovered the coastland! Now, you can travel to the coastland and explore it!")
</item>
</homeland_events_script_dictionary>
</object>
<turnscript name="global_turnscript">
<enabled />
<script>
game.turns = game.turns + 1
</script>
</turnscript>
<function name="help_function">
msg ("Type 'explore' to explore your area.")
msg ("Type 'travel' to travel to different areas.")
</function>
<function name="explore_function"><![CDATA[
switch (game.pov.parent) {
case (homeland) {
result_1 = ListCount (data_object.homeland_events_string_list) - 1
if (result_1 >= 0) {
result_2 = StringListItem (data_object.homeland_events_string_list,GetRandomInt(0,result_1))
invoke (ScriptDictionaryItem (data_object.homeland_events_script_dictionary,result_2))
on ready {
foreach (item_x, split ("grassland_discovery;plains_discovery;desert_discovery;tundra_discovery;swampland_discovery;forest_discovery;mountains_discovery;hills_discovery;wasteland_discovery;coastland_discovery",";")) {
if (result_2 = item_x) {
list remove (data_object.homeland_events_string_list, result_2)
}
}
}
} else {
msg ("There seemingly is nothing left to explore in this area.")
}
}
}
]]></function>
<function name="travel_function">
show menu ("Where do you wish to travel?",data_object.travel_string_list,false) {
if (not game.pov.parent = GetObject (result)) {
game.pov.parent = GetObject (result)
} else {
msg ("You are already at this area.")
ask ("Try again?") {
if (result=true) {
travel_function
} else {
msg ("You realize that you need to discover a new area to travel to first, before you can travel to that place.")
}
}
}
}
</function>
</asl>
----------
ask me to help you with basic attribute usage, as there's a lot you can do, and I'll help you do it.
here's just the basic computational attribute usage:
addition:
Object_name.Attribute_name = Object_name.Attribute_name + Value
example: player.strength = player.strength + 1
subtraction:
Object_name.Attribute_name = Object_name.Attribute_name - Value
example: player.strength = player.strength - 10
multiplication:
Object_name.Attribute_name = Object_name.Attribute_name * Value
example: player.strength = player.strength * 20
division:
Object_name.Attribute_name = Object_name.Attribute_name / Value
example: player.strength = player.strength / 3
------------
my own leveling code:
(this doesn't provide the stat changes though, ask and I'll help you with a simple way of doing it)
<function name="leveling_function"><![CDATA[
if (player.experience >= player.level * 100 + 100) {
player.level = player.level + 1
player.experience = player.experience - player.level * 100 + 100
leveling_function
}
]]></function>
------------
if me and I can write a code example for you what a simple code would look like with being able to damage, kill, and loot (experience, currency~gold, and item taking off of the dead corpse).