evennia/docs/0.95/_modules/evennia/contrib/turnbattle/tb_basic.html
2021-10-26 21:41:11 +02:00

886 lines
No EOL
90 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.contrib.turnbattle.tb_basic &#8212; Evennia 0.95 documentation</title>
<link rel="stylesheet" href="../../../../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../../../../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../../../../" src="../../../../_static/documentation_options.js"></script>
<script src="../../../../_static/jquery.js"></script>
<script src="../../../../_static/underscore.js"></script>
<script src="../../../../_static/doctools.js"></script>
<script src="../../../../_static/language_data.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"processClass": "tex2jax_process|mathjax_process|math|output_area"}})</script>
<link rel="shortcut icon" href="../../../../_static/favicon.ico"/>
<link rel="index" title="Index" href="../../../../genindex.html" />
<link rel="search" title="Search" href="../../../../search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../../index.html">Evennia 0.95</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="../../../evennia.html" accesskey="U">evennia</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.contrib.turnbattle.tb_basic</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.contrib.turnbattle.tb_basic</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Simple turn-based combat system</span>
<span class="sd">Contrib - Tim Ashley Jenkins 2017</span>
<span class="sd">This is a framework for a simple turn-based combat system, similar</span>
<span class="sd">to those used in D&amp;D-style tabletop role playing games. It allows</span>
<span class="sd">any character to start a fight in a room, at which point initiative</span>
<span class="sd">is rolled and a turn order is established. Each participant in combat</span>
<span class="sd">has a limited time to decide their action for that turn (30 seconds by</span>
<span class="sd">default), and combat progresses through the turn order, looping through</span>
<span class="sd">the participants until the fight ends.</span>
<span class="sd">Only simple rolls for attacking are implemented here, but this system</span>
<span class="sd">is easily extensible and can be used as the foundation for implementing</span>
<span class="sd">the rules from your turn-based tabletop game of choice or making your</span>
<span class="sd">own battle system.</span>
<span class="sd">To install and test, import this module&#39;s TBBasicCharacter object into</span>
<span class="sd">your game&#39;s character.py module:</span>
<span class="sd"> from evennia.contrib.turnbattle.tb_basic import TBBasicCharacter</span>
<span class="sd">And change your game&#39;s character typeclass to inherit from TBBasicCharacter</span>
<span class="sd">instead of the default:</span>
<span class="sd"> class Character(TBBasicCharacter):</span>
<span class="sd">Next, import this module into your default_cmdsets.py module:</span>
<span class="sd"> from evennia.contrib.turnbattle import tb_basic</span>
<span class="sd">And add the battle command set to your default command set:</span>
<span class="sd"> #</span>
<span class="sd"> # any commands you add below will overload the default ones.</span>
<span class="sd"> #</span>
<span class="sd"> self.add(tb_basic.BattleCmdSet())</span>
<span class="sd">This module is meant to be heavily expanded on, so you may want to copy it</span>
<span class="sd">to your game&#39;s &#39;world&#39; folder and modify it there rather than importing it</span>
<span class="sd">in your game and using it as-is.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">randint</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultCharacter</span><span class="p">,</span> <span class="n">Command</span><span class="p">,</span> <span class="n">default_cmds</span><span class="p">,</span> <span class="n">DefaultScript</span>
<span class="kn">from</span> <span class="nn">evennia.commands.default.help</span> <span class="kn">import</span> <span class="n">CmdHelp</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">----------------------------------------------------------------------------</span>
<span class="sd">OPTIONS</span>
<span class="sd">----------------------------------------------------------------------------</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="n">TURN_TIMEOUT</span> <span class="o">=</span> <span class="mi">30</span> <span class="c1"># Time before turns automatically end, in seconds</span>
<span class="n">ACTIONS_PER_TURN</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># Number of actions allowed per turn</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">----------------------------------------------------------------------------</span>
<span class="sd">COMBAT FUNCTIONS START HERE</span>
<span class="sd">----------------------------------------------------------------------------</span>
<span class="sd">&quot;&quot;&quot;</span>
<div class="viewcode-block" id="roll_init"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.roll_init">[docs]</a><span class="k">def</span> <span class="nf">roll_init</span><span class="p">(</span><span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Rolls a number between 1-1000 to determine initiative.</span>
<span class="sd"> Args:</span>
<span class="sd"> character (obj): The character to determine initiative for</span>
<span class="sd"> Returns:</span>
<span class="sd"> initiative (int): The character&#39;s place in initiative - higher</span>
<span class="sd"> numbers go first.</span>
<span class="sd"> Notes:</span>
<span class="sd"> By default, does not reference the character and simply returns</span>
<span class="sd"> a random integer from 1 to 1000.</span>
<span class="sd"> Since the character is passed to this function, you can easily reference</span>
<span class="sd"> a character&#39;s stats to determine an initiative roll - for example, if your</span>
<span class="sd"> character has a &#39;dexterity&#39; attribute, you can use it to give that character</span>
<span class="sd"> an advantage in turn order, like so:</span>
<span class="sd"> return (randint(1,20)) + character.db.dexterity</span>
<span class="sd"> This way, characters with a higher dexterity will go first more often.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1000</span><span class="p">)</span></div>
<div class="viewcode-block" id="get_attack"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.get_attack">[docs]</a><span class="k">def</span> <span class="nf">get_attack</span><span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Returns a value for an attack roll.</span>
<span class="sd"> Args:</span>
<span class="sd"> attacker (obj): Character doing the attacking</span>
<span class="sd"> defender (obj): Character being attacked</span>
<span class="sd"> Returns:</span>
<span class="sd"> attack_value (int): Attack roll value, compared against a defense value</span>
<span class="sd"> to determine whether an attack hits or misses.</span>
<span class="sd"> Notes:</span>
<span class="sd"> By default, returns a random integer from 1 to 100 without using any</span>
<span class="sd"> properties from either the attacker or defender.</span>
<span class="sd"> This can easily be expanded to return a value based on characters stats,</span>
<span class="sd"> equipment, and abilities. This is why the attacker and defender are passed</span>
<span class="sd"> to this function, even though nothing from either one are used in this example.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># For this example, just return a random integer up to 100.</span>
<span class="n">attack_value</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
<span class="k">return</span> <span class="n">attack_value</span></div>
<div class="viewcode-block" id="get_defense"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.get_defense">[docs]</a><span class="k">def</span> <span class="nf">get_defense</span><span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Returns a value for defense, which an attack roll must equal or exceed in order</span>
<span class="sd"> for an attack to hit.</span>
<span class="sd"> Args:</span>
<span class="sd"> attacker (obj): Character doing the attacking</span>
<span class="sd"> defender (obj): Character being attacked</span>
<span class="sd"> Returns:</span>
<span class="sd"> defense_value (int): Defense value, compared against an attack roll</span>
<span class="sd"> to determine whether an attack hits or misses.</span>
<span class="sd"> Notes:</span>
<span class="sd"> By default, returns 50, not taking any properties of the defender or</span>
<span class="sd"> attacker into account.</span>
<span class="sd"> As above, this can be expanded upon based on character stats and equipment.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># For this example, just return 50, for about a 50/50 chance of hit.</span>
<span class="n">defense_value</span> <span class="o">=</span> <span class="mi">50</span>
<span class="k">return</span> <span class="n">defense_value</span></div>
<div class="viewcode-block" id="get_damage"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.get_damage">[docs]</a><span class="k">def</span> <span class="nf">get_damage</span><span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Returns a value for damage to be deducted from the defender&#39;s HP after abilities</span>
<span class="sd"> successful hit.</span>
<span class="sd"> Args:</span>
<span class="sd"> attacker (obj): Character doing the attacking</span>
<span class="sd"> defender (obj): Character being damaged</span>
<span class="sd"> Returns:</span>
<span class="sd"> damage_value (int): Damage value, which is to be deducted from the defending</span>
<span class="sd"> character&#39;s HP.</span>
<span class="sd"> Notes:</span>
<span class="sd"> By default, returns a random integer from 15 to 25 without using any</span>
<span class="sd"> properties from either the attacker or defender.</span>
<span class="sd"> Again, this can be expanded upon.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># For this example, just generate a number between 15 and 25.</span>
<span class="n">damage_value</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span><span class="mi">15</span><span class="p">,</span> <span class="mi">25</span><span class="p">)</span>
<span class="k">return</span> <span class="n">damage_value</span></div>
<div class="viewcode-block" id="apply_damage"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.apply_damage">[docs]</a><span class="k">def</span> <span class="nf">apply_damage</span><span class="p">(</span><span class="n">defender</span><span class="p">,</span> <span class="n">damage</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Applies damage to a target, reducing their HP by the damage amount to a</span>
<span class="sd"> minimum of 0.</span>
<span class="sd"> Args:</span>
<span class="sd"> defender (obj): Character taking damage</span>
<span class="sd"> damage (int): Amount of damage being taken</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">defender</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span> <span class="o">-=</span> <span class="n">damage</span> <span class="c1"># Reduce defender&#39;s HP by the damage dealt.</span>
<span class="c1"># If this reduces it to 0 or less, set HP to 0.</span>
<span class="k">if</span> <span class="n">defender</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">defender</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span> <span class="o">=</span> <span class="mi">0</span></div>
<div class="viewcode-block" id="at_defeat"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.at_defeat">[docs]</a><span class="k">def</span> <span class="nf">at_defeat</span><span class="p">(</span><span class="n">defeated</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Announces the defeat of a fighter in combat.</span>
<span class="sd"> </span>
<span class="sd"> Args:</span>
<span class="sd"> defeated (obj): Fighter that&#39;s been defeated.</span>
<span class="sd"> </span>
<span class="sd"> Notes:</span>
<span class="sd"> All this does is announce a defeat message by default, but if you</span>
<span class="sd"> want anything else to happen to defeated fighters (like putting them</span>
<span class="sd"> into a dying state or something similar) then this is the place to</span>
<span class="sd"> do it.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">defeated</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> has been defeated!&quot;</span> <span class="o">%</span> <span class="n">defeated</span><span class="p">)</span></div>
<div class="viewcode-block" id="resolve_attack"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.resolve_attack">[docs]</a><span class="k">def</span> <span class="nf">resolve_attack</span><span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">,</span> <span class="n">attack_value</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">defense_value</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Resolves an attack and outputs the result.</span>
<span class="sd"> Args:</span>
<span class="sd"> attacker (obj): Character doing the attacking</span>
<span class="sd"> defender (obj): Character being attacked</span>
<span class="sd"> Notes:</span>
<span class="sd"> Even though the attack and defense values are calculated</span>
<span class="sd"> extremely simply, they are separated out into their own functions</span>
<span class="sd"> so that they are easier to expand upon.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Get an attack roll from the attacker.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">attack_value</span><span class="p">:</span>
<span class="n">attack_value</span> <span class="o">=</span> <span class="n">get_attack</span><span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">)</span>
<span class="c1"># Get a defense value from the defender.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">defense_value</span><span class="p">:</span>
<span class="n">defense_value</span> <span class="o">=</span> <span class="n">get_defense</span><span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">)</span>
<span class="c1"># If the attack value is lower than the defense value, miss. Otherwise, hit.</span>
<span class="k">if</span> <span class="n">attack_value</span> <span class="o">&lt;</span> <span class="n">defense_value</span><span class="p">:</span>
<span class="n">attacker</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">&#39;s attack misses </span><span class="si">%s</span><span class="s2">!&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">damage_value</span> <span class="o">=</span> <span class="n">get_damage</span><span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">)</span> <span class="c1"># Calculate damage value.</span>
<span class="c1"># Announce damage dealt and apply damage.</span>
<span class="n">attacker</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span>
<span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> hits </span><span class="si">%s</span><span class="s2"> for </span><span class="si">%i</span><span class="s2"> damage!&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">,</span> <span class="n">damage_value</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">apply_damage</span><span class="p">(</span><span class="n">defender</span><span class="p">,</span> <span class="n">damage_value</span><span class="p">)</span>
<span class="c1"># If defender HP is reduced to 0 or less, call at_defeat.</span>
<span class="k">if</span> <span class="n">defender</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">at_defeat</span><span class="p">(</span><span class="n">defender</span><span class="p">)</span></div>
<div class="viewcode-block" id="combat_cleanup"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.combat_cleanup">[docs]</a><span class="k">def</span> <span class="nf">combat_cleanup</span><span class="p">(</span><span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Cleans up all the temporary combat-related attributes on a character.</span>
<span class="sd"> Args:</span>
<span class="sd"> character (obj): Character to have their combat attributes removed</span>
<span class="sd"> Notes:</span>
<span class="sd"> Any attribute whose key begins with &#39;combat_&#39; is temporary and no</span>
<span class="sd"> longer needed once a fight ends.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="n">character</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">all</span><span class="p">():</span>
<span class="k">if</span> <span class="n">attr</span><span class="o">.</span><span class="n">key</span><span class="p">[:</span><span class="mi">7</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;combat_&quot;</span><span class="p">:</span> <span class="c1"># If the attribute name starts with &#39;combat_&#39;...</span>
<span class="n">character</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">attr</span><span class="o">.</span><span class="n">key</span><span class="p">)</span> <span class="c1"># ...then delete it!</span></div>
<div class="viewcode-block" id="is_in_combat"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.is_in_combat">[docs]</a><span class="k">def</span> <span class="nf">is_in_combat</span><span class="p">(</span><span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Returns true if the given character is in combat.</span>
<span class="sd"> Args:</span>
<span class="sd"> character (obj): Character to determine if is in combat or not</span>
<span class="sd"> Returns:</span>
<span class="sd"> (bool): True if in combat or False if not in combat</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnhandler</span><span class="p">)</span></div>
<div class="viewcode-block" id="is_turn"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.is_turn">[docs]</a><span class="k">def</span> <span class="nf">is_turn</span><span class="p">(</span><span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Returns true if it&#39;s currently the given character&#39;s turn in combat.</span>
<span class="sd"> Args:</span>
<span class="sd"> character (obj): Character to determine if it is their turn or not</span>
<span class="sd"> Returns:</span>
<span class="sd"> (bool): True if it is their turn or False otherwise</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">turnhandler</span> <span class="o">=</span> <span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnhandler</span>
<span class="n">currentchar</span> <span class="o">=</span> <span class="n">turnhandler</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">[</span><span class="n">turnhandler</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">turn</span><span class="p">]</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">character</span> <span class="o">==</span> <span class="n">currentchar</span><span class="p">)</span></div>
<div class="viewcode-block" id="spend_action"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.spend_action">[docs]</a><span class="k">def</span> <span class="nf">spend_action</span><span class="p">(</span><span class="n">character</span><span class="p">,</span> <span class="n">actions</span><span class="p">,</span> <span class="n">action_name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Spends a character&#39;s available combat actions and checks for end of turn.</span>
<span class="sd"> Args:</span>
<span class="sd"> character (obj): Character spending the action</span>
<span class="sd"> actions (int) or &#39;all&#39;: Number of actions to spend, or &#39;all&#39; to spend all actions</span>
<span class="sd"> Keyword Args:</span>
<span class="sd"> action_name (str or None): If a string is given, sets character&#39;s last action in</span>
<span class="sd"> combat to provided string</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">action_name</span><span class="p">:</span>
<span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_lastaction</span> <span class="o">=</span> <span class="n">action_name</span>
<span class="k">if</span> <span class="n">actions</span> <span class="o">==</span> <span class="s2">&quot;all&quot;</span><span class="p">:</span> <span class="c1"># If spending all actions</span>
<span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_actionsleft</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># Set actions to 0</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_actionsleft</span> <span class="o">-=</span> <span class="n">actions</span> <span class="c1"># Use up actions.</span>
<span class="k">if</span> <span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_actionsleft</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_actionsleft</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># Can&#39;t have fewer than 0 actions</span>
<span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnhandler</span><span class="o">.</span><span class="n">turn_end_check</span><span class="p">(</span><span class="n">character</span><span class="p">)</span> <span class="c1"># Signal potential end of turn.</span></div>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">----------------------------------------------------------------------------</span>
<span class="sd">CHARACTER TYPECLASS</span>
<span class="sd">----------------------------------------------------------------------------</span>
<span class="sd">&quot;&quot;&quot;</span>
<div class="viewcode-block" id="TBBasicCharacter"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicCharacter">[docs]</a><span class="k">class</span> <span class="nc">TBBasicCharacter</span><span class="p">(</span><span class="n">DefaultCharacter</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A character able to participate in turn-based combat. Has attributes for current</span>
<span class="sd"> and maximum HP, and access to combat commands.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="TBBasicCharacter.at_object_creation"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicCharacter.at_object_creation">[docs]</a> <span class="k">def</span> <span class="nf">at_object_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called once, when this object is first created. This is the</span>
<span class="sd"> normal hook to overload for most object types.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">max_hp</span> <span class="o">=</span> <span class="mi">100</span> <span class="c1"># Set maximum HP to 100</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">max_hp</span> <span class="c1"># Set current HP to maximum</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Adds attributes for a character&#39;s current and maximum HP.</span>
<span class="sd"> We&#39;re just going to set this value at &#39;100&#39; by default.</span>
<span class="sd"> You may want to expand this to include various &#39;stats&#39; that</span>
<span class="sd"> can be changed at creation and factor into combat calculations.</span>
<span class="sd"> &quot;&quot;&quot;</span></div>
<div class="viewcode-block" id="TBBasicCharacter.at_before_move"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicCharacter.at_before_move">[docs]</a> <span class="k">def</span> <span class="nf">at_before_move</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">destination</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called just before starting to move this object to</span>
<span class="sd"> destination.</span>
<span class="sd"> Args:</span>
<span class="sd"> destination (Object): The object we are moving to</span>
<span class="sd"> Returns:</span>
<span class="sd"> shouldmove (bool): If we should move or not.</span>
<span class="sd"> Notes:</span>
<span class="sd"> If this method returns False/None, the move is cancelled</span>
<span class="sd"> before it is even started.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Keep the character from moving if at 0 HP or in combat.</span>
<span class="k">if</span> <span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can&#39;t exit a room while in combat!&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span> <span class="c1"># Returning false keeps the character from moving.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">HP</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can&#39;t move, you&#39;ve been defeated!&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">return</span> <span class="kc">True</span></div></div>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">----------------------------------------------------------------------------</span>
<span class="sd">SCRIPTS START HERE</span>
<span class="sd">----------------------------------------------------------------------------</span>
<span class="sd">&quot;&quot;&quot;</span>
<div class="viewcode-block" id="TBBasicTurnHandler"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicTurnHandler">[docs]</a><span class="k">class</span> <span class="nc">TBBasicTurnHandler</span><span class="p">(</span><span class="n">DefaultScript</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is the script that handles the progression of combat through turns.</span>
<span class="sd"> On creation (when a fight is started) it adds all combat-ready characters</span>
<span class="sd"> to its roster and then sorts them into a turn order. There can only be one</span>
<span class="sd"> fight going on in a single room at a time, so the script is assigned to a</span>
<span class="sd"> room as its object.</span>
<span class="sd"> Fights persist until only one participant is left with any HP or all</span>
<span class="sd"> remaining participants choose to end the combat with the &#39;disengage&#39; command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="TBBasicTurnHandler.at_script_creation"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicTurnHandler.at_script_creation">[docs]</a> <span class="k">def</span> <span class="nf">at_script_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called once, when the script is created.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;Combat Turn Handler&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="mi">5</span> <span class="c1"># Once every 5 seconds</span>
<span class="bp">self</span><span class="o">.</span><span class="n">persistent</span> <span class="o">=</span> <span class="kc">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span> <span class="o">=</span> <span class="p">[]</span>
<span class="c1"># Add all fighters in the room with at least 1 HP to the combat.&quot;</span>
<span class="k">for</span> <span class="n">thing</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">contents</span><span class="p">:</span>
<span class="k">if</span> <span class="n">thing</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">thing</span><span class="p">)</span>
<span class="c1"># Initialize each fighter for combat</span>
<span class="k">for</span> <span class="n">fighter</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">initialize_for_combat</span><span class="p">(</span><span class="n">fighter</span><span class="p">)</span>
<span class="c1"># Add a reference to this script to the room</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnhandler</span> <span class="o">=</span> <span class="bp">self</span>
<span class="c1"># Roll initiative and sort the list of fighters depending on who rolls highest to determine turn order.</span>
<span class="c1"># The initiative roll is determined by the roll_init function and can be customized easily.</span>
<span class="n">ordered_by_roll</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">roll_init</span><span class="p">,</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span> <span class="o">=</span> <span class="n">ordered_by_roll</span>
<span class="c1"># Announce the turn order.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;Turn order is: </span><span class="si">%s</span><span class="s2"> &quot;</span> <span class="o">%</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">key</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">))</span>
<span class="c1"># Start first fighter&#39;s turn.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">start_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="c1"># Set up the current turn and turn timeout delay.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">turn</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">timer</span> <span class="o">=</span> <span class="n">TURN_TIMEOUT</span> <span class="c1"># Set timer to turn timeout specified in options</span></div>
<div class="viewcode-block" id="TBBasicTurnHandler.at_stop"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicTurnHandler.at_stop">[docs]</a> <span class="k">def</span> <span class="nf">at_stop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called at script termination.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">fighter</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">:</span>
<span class="n">combat_cleanup</span><span class="p">(</span><span class="n">fighter</span><span class="p">)</span> <span class="c1"># Clean up the combat attributes for every fighter.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnhandler</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Remove reference to turn handler in location</span></div>
<div class="viewcode-block" id="TBBasicTurnHandler.at_repeat"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicTurnHandler.at_repeat">[docs]</a> <span class="k">def</span> <span class="nf">at_repeat</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Called once every self.interval seconds.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">currentchar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">[</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">turn</span>
<span class="p">]</span> <span class="c1"># Note the current character in the turn order.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">timer</span> <span class="o">-=</span> <span class="bp">self</span><span class="o">.</span><span class="n">interval</span> <span class="c1"># Count down the timer.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">timer</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># Force current character to disengage if timer runs out.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">&#39;s turn timed out!&quot;</span> <span class="o">%</span> <span class="n">currentchar</span><span class="p">)</span>
<span class="n">spend_action</span><span class="p">(</span>
<span class="n">currentchar</span><span class="p">,</span> <span class="s2">&quot;all&quot;</span><span class="p">,</span> <span class="n">action_name</span><span class="o">=</span><span class="s2">&quot;disengage&quot;</span>
<span class="p">)</span> <span class="c1"># Spend all remaining actions.</span>
<span class="k">return</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">timer</span> <span class="o">&lt;=</span> <span class="mi">10</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">timeout_warning_given</span><span class="p">:</span> <span class="c1"># 10 seconds left</span>
<span class="c1"># Warn the current character if they&#39;re about to time out.</span>
<span class="n">currentchar</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;WARNING: About to time out!&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">timeout_warning_given</span> <span class="o">=</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="TBBasicTurnHandler.initialize_for_combat"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicTurnHandler.initialize_for_combat">[docs]</a> <span class="k">def</span> <span class="nf">initialize_for_combat</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Prepares a character for combat when starting or entering a fight.</span>
<span class="sd"> Args:</span>
<span class="sd"> character (obj): Character to initialize for combat.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">combat_cleanup</span><span class="p">(</span><span class="n">character</span><span class="p">)</span> <span class="c1"># Clean up leftover combat attributes beforehand, just in case.</span>
<span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_actionsleft</span> <span class="o">=</span> <span class="p">(</span>
<span class="mi">0</span> <span class="c1"># Actions remaining - start of turn adds to this, turn ends when it reaches 0</span>
<span class="p">)</span>
<span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnhandler</span> <span class="o">=</span> <span class="p">(</span>
<span class="bp">self</span> <span class="c1"># Add a reference to this turn handler script to the character</span>
<span class="p">)</span>
<span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_lastaction</span> <span class="o">=</span> <span class="s2">&quot;null&quot;</span> <span class="c1"># Track last action taken in combat</span></div>
<div class="viewcode-block" id="TBBasicTurnHandler.start_turn"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicTurnHandler.start_turn">[docs]</a> <span class="k">def</span> <span class="nf">start_turn</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Readies a character for the start of their turn by replenishing their</span>
<span class="sd"> available actions and notifying them that their turn has come up.</span>
<span class="sd"> Args:</span>
<span class="sd"> character (obj): Character to be readied.</span>
<span class="sd"> Notes:</span>
<span class="sd"> Here, you only get one action per turn, but you might want to allow more than</span>
<span class="sd"> one per turn, or even grant a number of actions based on a character&#39;s</span>
<span class="sd"> attributes. You can even add multiple different kinds of actions, I.E. actions</span>
<span class="sd"> separated for movement, by adding &quot;character.db.combat_movesleft = 3&quot; or</span>
<span class="sd"> something similar.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_actionsleft</span> <span class="o">=</span> <span class="n">ACTIONS_PER_TURN</span> <span class="c1"># Replenish actions</span>
<span class="c1"># Prompt the character for their turn and give some information.</span>
<span class="n">character</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;|wIt&#39;s your turn! You have </span><span class="si">%i</span><span class="s2"> HP remaining.|n&quot;</span> <span class="o">%</span> <span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span><span class="p">)</span></div>
<div class="viewcode-block" id="TBBasicTurnHandler.next_turn"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicTurnHandler.next_turn">[docs]</a> <span class="k">def</span> <span class="nf">next_turn</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Advances to the next character in the turn order.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Check to see if every character disengaged as their last action. If so, end combat.</span>
<span class="n">disengage_check</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">for</span> <span class="n">fighter</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">:</span>
<span class="k">if</span> <span class="p">(</span>
<span class="n">fighter</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_lastaction</span> <span class="o">!=</span> <span class="s2">&quot;disengage&quot;</span>
<span class="p">):</span> <span class="c1"># If a character has done anything but disengage</span>
<span class="n">disengage_check</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">disengage_check</span><span class="p">:</span> <span class="c1"># All characters have disengaged</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;All fighters have disengaged! Combat is over!&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> <span class="c1"># Stop this script and end combat.</span>
<span class="k">return</span>
<span class="c1"># Check to see if only one character is left standing. If so, end combat.</span>
<span class="n">defeated_characters</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">fighter</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">:</span>
<span class="k">if</span> <span class="n">fighter</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">HP</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">defeated_characters</span> <span class="o">+=</span> <span class="mi">1</span> <span class="c1"># Add 1 for every fighter with 0 HP left (defeated)</span>
<span class="k">if</span> <span class="n">defeated_characters</span> <span class="o">==</span> <span class="p">(</span>
<span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="p">):</span> <span class="c1"># If only one character isn&#39;t defeated</span>
<span class="k">for</span> <span class="n">fighter</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">:</span>
<span class="k">if</span> <span class="n">fighter</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">HP</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">LastStanding</span> <span class="o">=</span> <span class="n">fighter</span> <span class="c1"># Pick the one fighter left with HP remaining</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;Only </span><span class="si">%s</span><span class="s2"> remains! Combat is over!&quot;</span> <span class="o">%</span> <span class="n">LastStanding</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> <span class="c1"># Stop this script and end combat.</span>
<span class="k">return</span>
<span class="c1"># Cycle to the next turn.</span>
<span class="n">currentchar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">turn</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">turn</span> <span class="o">+=</span> <span class="mi">1</span> <span class="c1"># Go to the next in the turn order.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">turn</span> <span class="o">&gt;</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">turn</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># Go back to the first in the turn order once you reach the end.</span>
<span class="n">newchar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">turn</span><span class="p">]</span> <span class="c1"># Note the new character</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">timer</span> <span class="o">=</span> <span class="n">TURN_TIMEOUT</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_until_next_repeat</span><span class="p">()</span> <span class="c1"># Reset the timer.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">timeout_warning_given</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1"># Reset the timeout warning.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">&#39;s turn ends - </span><span class="si">%s</span><span class="s2">&#39;s turn begins!&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">currentchar</span><span class="p">,</span> <span class="n">newchar</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">start_turn</span><span class="p">(</span><span class="n">newchar</span><span class="p">)</span> <span class="c1"># Start the new character&#39;s turn.</span></div>
<div class="viewcode-block" id="TBBasicTurnHandler.turn_end_check"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicTurnHandler.turn_end_check">[docs]</a> <span class="k">def</span> <span class="nf">turn_end_check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Tests to see if a character&#39;s turn is over, and cycles to the next turn if it is.</span>
<span class="sd"> Args:</span>
<span class="sd"> character (obj): Character to test for end of turn</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">character</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_actionsleft</span><span class="p">:</span> <span class="c1"># Character has no actions remaining</span>
<span class="bp">self</span><span class="o">.</span><span class="n">next_turn</span><span class="p">()</span>
<span class="k">return</span></div>
<div class="viewcode-block" id="TBBasicTurnHandler.join_fight"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.TBBasicTurnHandler.join_fight">[docs]</a> <span class="k">def</span> <span class="nf">join_fight</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">character</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Adds a new character to a fight already in progress.</span>
<span class="sd"> Args:</span>
<span class="sd"> character (obj): Character to be added to the fight.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Inserts the fighter to the turn order, right behind whoever&#39;s turn it currently is.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">fighters</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">turn</span><span class="p">,</span> <span class="n">character</span><span class="p">)</span>
<span class="c1"># Tick the turn counter forward one to compensate.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">turn</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="c1"># Initialize the character like you do at the start.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">initialize_for_combat</span><span class="p">(</span><span class="n">character</span><span class="p">)</span></div></div>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">----------------------------------------------------------------------------</span>
<span class="sd">COMMANDS START HERE</span>
<span class="sd">----------------------------------------------------------------------------</span>
<span class="sd">&quot;&quot;&quot;</span>
<div class="viewcode-block" id="CmdFight"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdFight">[docs]</a><span class="k">class</span> <span class="nc">CmdFight</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Starts a fight with everyone in the same room as you.</span>
<span class="sd"> Usage:</span>
<span class="sd"> fight</span>
<span class="sd"> When you start a fight, everyone in the room who is able to</span>
<span class="sd"> fight is added to combat, and a turn order is randomly rolled.</span>
<span class="sd"> When it&#39;s your turn, you can attack other characters.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;fight&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;combat&quot;</span>
<div class="viewcode-block" id="CmdFight.func"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdFight.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This performs the actual command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">here</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">location</span>
<span class="n">fighters</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span><span class="p">:</span> <span class="c1"># If you don&#39;t have any hp</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can&#39;t start a fight if you&#39;ve been defeated!&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">):</span> <span class="c1"># Already in a fight</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You&#39;re already in a fight!&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">for</span> <span class="n">thing</span> <span class="ow">in</span> <span class="n">here</span><span class="o">.</span><span class="n">contents</span><span class="p">:</span> <span class="c1"># Test everything in the room to add it to the fight.</span>
<span class="k">if</span> <span class="n">thing</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">HP</span><span class="p">:</span> <span class="c1"># If the object has HP...</span>
<span class="n">fighters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">thing</span><span class="p">)</span> <span class="c1"># ...then add it to the fight.</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">fighters</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span> <span class="c1"># If you&#39;re the only able fighter in the room</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;There&#39;s nobody here to fight!&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">here</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnhandler</span><span class="p">:</span> <span class="c1"># If there&#39;s already a fight going on...</span>
<span class="n">here</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> joins the fight!&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">)</span>
<span class="n">here</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnhandler</span><span class="o">.</span><span class="n">join_fight</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">)</span> <span class="c1"># Join the fight!</span>
<span class="k">return</span>
<span class="n">here</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> starts a fight!&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">)</span>
<span class="c1"># Add a turn handler script to the room, which starts combat.</span>
<span class="n">here</span><span class="o">.</span><span class="n">scripts</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;contrib.turnbattle.tb_basic.TBBasicTurnHandler&quot;</span><span class="p">)</span></div></div>
<span class="c1"># Remember you&#39;ll have to change the path to the script if you copy this code to your own modules!</span>
<div class="viewcode-block" id="CmdAttack"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdAttack">[docs]</a><span class="k">class</span> <span class="nc">CmdAttack</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Attacks another character.</span>
<span class="sd"> Usage:</span>
<span class="sd"> attack &lt;target&gt;</span>
<span class="sd"> When in a fight, you may attack another character. The attack has</span>
<span class="sd"> a chance to hit, and if successful, will deal damage.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;attack&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;combat&quot;</span>
<div class="viewcode-block" id="CmdAttack.func"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdAttack.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="s2">&quot;This performs the actual command.&quot;</span>
<span class="s2">&quot;Set the attacker to the caller and the defender to the target.&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">):</span> <span class="c1"># If not in combat, can&#39;t attack.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can only do that in combat. (see: help fight)&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">):</span> <span class="c1"># If it&#39;s not your turn, can&#39;t attack.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can only do that on your turn.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span><span class="p">:</span> <span class="c1"># Can&#39;t attack if you have no HP.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can&#39;t attack, you&#39;ve been defeated.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">attacker</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="n">defender</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">defender</span><span class="p">:</span> <span class="c1"># No valid target given.</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">defender</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span><span class="p">:</span> <span class="c1"># Target object has no HP left or to begin with</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can&#39;t fight that!&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">attacker</span> <span class="o">==</span> <span class="n">defender</span><span class="p">:</span> <span class="c1"># Target and attacker are the same</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can&#39;t attack yourself!&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="s2">&quot;If everything checks out, call the attack resolving function.&quot;</span>
<span class="n">resolve_attack</span><span class="p">(</span><span class="n">attacker</span><span class="p">,</span> <span class="n">defender</span><span class="p">)</span>
<span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">action_name</span><span class="o">=</span><span class="s2">&quot;attack&quot;</span><span class="p">)</span> <span class="c1"># Use up one action.</span></div></div>
<div class="viewcode-block" id="CmdPass"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdPass">[docs]</a><span class="k">class</span> <span class="nc">CmdPass</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Passes on your turn.</span>
<span class="sd"> Usage:</span>
<span class="sd"> pass</span>
<span class="sd"> When in a fight, you can use this command to end your turn early, even</span>
<span class="sd"> if there are still any actions you can take.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;pass&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;wait&quot;</span><span class="p">,</span> <span class="s2">&quot;hold&quot;</span><span class="p">]</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;combat&quot;</span>
<div class="viewcode-block" id="CmdPass.func"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdPass.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This performs the actual command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">):</span> <span class="c1"># Can only pass a turn in combat.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can only do that in combat. (see: help fight)&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">):</span> <span class="c1"># Can only pass if it&#39;s your turn.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can only do that on your turn.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span>
<span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> takes no further action, passing the turn.&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="p">)</span>
<span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;all&quot;</span><span class="p">,</span> <span class="n">action_name</span><span class="o">=</span><span class="s2">&quot;pass&quot;</span><span class="p">)</span> <span class="c1"># Spend all remaining actions.</span></div></div>
<div class="viewcode-block" id="CmdDisengage"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdDisengage">[docs]</a><span class="k">class</span> <span class="nc">CmdDisengage</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Passes your turn and attempts to end combat.</span>
<span class="sd"> Usage:</span>
<span class="sd"> disengage</span>
<span class="sd"> Ends your turn early and signals that you&#39;re trying to end</span>
<span class="sd"> the fight. If all participants in a fight disengage, the</span>
<span class="sd"> fight ends.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;disengage&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;spare&quot;</span><span class="p">]</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;combat&quot;</span>
<div class="viewcode-block" id="CmdDisengage.func"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdDisengage.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This performs the actual command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">):</span> <span class="c1"># If you&#39;re not in combat</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can only do that in combat. (see: help fight)&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">):</span> <span class="c1"># If it&#39;s not your turn</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can only do that on your turn.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> disengages, ready to stop fighting.&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">)</span>
<span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;all&quot;</span><span class="p">,</span> <span class="n">action_name</span><span class="o">=</span><span class="s2">&quot;disengage&quot;</span><span class="p">)</span> <span class="c1"># Spend all remaining actions.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> The action_name kwarg sets the character&#39;s last action to &quot;disengage&quot;, which is checked by</span>
<span class="sd"> the turn handler script to see if all fighters have disengaged.</span>
<span class="sd"> &quot;&quot;&quot;</span></div></div>
<div class="viewcode-block" id="CmdRest"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdRest">[docs]</a><span class="k">class</span> <span class="nc">CmdRest</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Recovers damage.</span>
<span class="sd"> Usage:</span>
<span class="sd"> rest</span>
<span class="sd"> Resting recovers your HP to its maximum, but you can only</span>
<span class="sd"> rest if you&#39;re not in a fight.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;rest&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;combat&quot;</span>
<div class="viewcode-block" id="CmdRest.func"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdRest.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="s2">&quot;This performs the actual command.&quot;</span>
<span class="k">if</span> <span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">):</span> <span class="c1"># If you&#39;re in combat</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can&#39;t rest while you&#39;re in combat.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">max_hp</span> <span class="c1"># Set current HP to maximum</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> rests to recover HP.&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">)</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> You&#39;ll probably want to replace this with your own system for recovering HP.</span>
<span class="sd"> &quot;&quot;&quot;</span></div></div>
<div class="viewcode-block" id="CmdCombatHelp"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdCombatHelp">[docs]</a><span class="k">class</span> <span class="nc">CmdCombatHelp</span><span class="p">(</span><span class="n">CmdHelp</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> View help or a list of topics</span>
<span class="sd"> Usage:</span>
<span class="sd"> help &lt;topic or command&gt;</span>
<span class="sd"> help list</span>
<span class="sd"> help all</span>
<span class="sd"> This will search for help on commands and other</span>
<span class="sd"> topics related to the game.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Just like the default help command, but will give quick</span>
<span class="c1"># tips on combat when used in a fight with no arguments.</span>
<div class="viewcode-block" id="CmdCombatHelp.func"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.CmdCombatHelp.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span> <span class="c1"># In combat and entered &#39;help&#39; alone</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span>
<span class="s2">&quot;Available combat commands:|/&quot;</span>
<span class="o">+</span> <span class="s2">&quot;|wAttack:|n Attack a target, attempting to deal damage.|/&quot;</span>
<span class="o">+</span> <span class="s2">&quot;|wPass:|n Pass your turn without further action.|/&quot;</span>
<span class="o">+</span> <span class="s2">&quot;|wDisengage:|n End your turn and attempt to end combat.|/&quot;</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">func</span><span class="p">()</span> <span class="c1"># Call the default help command</span></div></div>
<div class="viewcode-block" id="BattleCmdSet"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.BattleCmdSet">[docs]</a><span class="k">class</span> <span class="nc">BattleCmdSet</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CharacterCmdSet</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This command set includes all the commmands used in the battle system.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;DefaultCharacter&quot;</span>
<div class="viewcode-block" id="BattleCmdSet.at_cmdset_creation"><a class="viewcode-back" href="../../../../api/evennia.contrib.turnbattle.tb_basic.html#evennia.contrib.turnbattle.tb_basic.BattleCmdSet.at_cmdset_creation">[docs]</a> <span class="k">def</span> <span class="nf">at_cmdset_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Populates the cmdset</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdFight</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdAttack</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdRest</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdPass</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdDisengage</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdCombatHelp</span><span class="p">())</span></div></div>
</pre></div>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../../../../index.html">
<img class="logo" src="../../../../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
<a href="https://discord.gg/NecFePw">Discord</a> -
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
</li>
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="../../../../../1.0-dev/index.html">1.0-dev (develop branch)</a></li>
<li><a href="tb_basic.html">0.95 (v0.9.5 branch)</a></li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../../index.html">Evennia 0.95</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="../../../evennia.html" >evennia</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.contrib.turnbattle.tb_basic</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2020, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>