combat system. [solved]

So I'm trying to create a combat system but I'm completely lost as to how to even begin with. I've tried to look at Pixie combat lib but it is really extensive and complicated, there is a lot there I just don't need so I thought I'd ask if anyone could help me either create from scratch or modify the Lib for my need. It's a zombie game and here what I would like for the combat.

1- A simple system where the weapon dictates the damage done.
2- Enemy that attack when you enter a room and a way to set up outdoor room with a chance to spawn enemy and be attacked.
3- Armor for the player. (some wearable that reduces incoming damages)
4- Loot from a dead enemy, no need to be random.
5- Firearms with a reload. ( something like Handgun ammo: 13/15 ) the reload could be via clips where the player loses the current ammo remaining or via straight ammo for something like a shotgun. (if clips are too complicated straight ammo would do just fine.)
6-(optional) Accuracy - a chance for the gun to miss
7-(optional) a way to have multiple enemies attack at the same time.

Things I don't really like with Pixies Lib is the fact that it relies on stats and random roll for an attack, also the ammo system seems to be overlooked which is totally understandable for an RPG Lib but for a zombie game where you gradually get better guns allowing you to fight harder enemies it seems lacking unless I missed something and that wouldn't surprise me lol.


you can take a look at my old combat code (this is for an earlier version of quest, and some of the syntax, the list/dictionary stuff, has changed for the newer versions, so this won't work without updating it) for a start/idea on how to do a combat system:

(also, I got confused with some of my stats stuff, the damage vs resistance, as well, so my code also has these errors in it too)

see if this makes sense to you or not... if not, you can ask me to help you with it and to explain it

    <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">75</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>

and here is my key/legend for all of the abrevs I've used in it (I learned ever since to NEVER EVER use abrevs, lol):

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

Have you looked at the docs?
http://docs.textadventures.co.uk/quest/zombie-apocalypse-1.html


Wow thanks Pixie:) I've gone through the first part and it seems to be everything I need.

One thing tho, what this exactly mean? so I can adjust it

obj.damage = 1d8


1 eight sided dice is rolled to determine the damage a weapon gives. You can make either number whatever you want.


Is there anything I would do differently for the desktop version?


Log in to post a reply.

Support

Forums