mirror of
https://github.com/evennia/evennia.git
synced 2026-03-31 13:07:16 +02:00
Updated HTML docs.
This commit is contained in:
parent
dbae67275a
commit
76d95c253e
87 changed files with 922 additions and 850 deletions
|
|
@ -61,28 +61,28 @@ RPG, it will hold everything relevant to that PC.</p>
|
|||
<p>Player Characters (PCs) are not the only “living” things in our world. We also have <em>NPCs</em>
|
||||
(like shopkeepers and other friendlies) as well as <em>monsters</em> (mobs) that can attack us.</p>
|
||||
<p>In code, there are a few ways we could structure this. If NPCs/monsters were just special cases of PCs, we could use a class inheritance like this:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">DefaultCharacter</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">DefaultCharacter</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureCharacter</span><span class="p">(</span><span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
<span class="c1"># stuff</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureCharacter</span><span class="p">(</span><span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
<span class="c1"># stuff </span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureNPC</span><span class="p">(</span><span class="n">EvAdventureCharacter</span><span class="p">):</span>
|
||||
<span class="c1"># more stuff </span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureMob</span><span class="p">(</span><span class="n">EvAdventureNPC</span><span class="p">):</span>
|
||||
<span class="c1"># more stuff </span>
|
||||
<span class="c1"># more stuff</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureMob</span><span class="p">(</span><span class="n">EvAdventureNPC</span><span class="p">):</span>
|
||||
<span class="c1"># more stuff</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>All code we put on the <code class="docutils literal notranslate"><span class="pre">Character</span></code> class would now be inherited to <code class="docutils literal notranslate"><span class="pre">NPC</span></code> and <code class="docutils literal notranslate"><span class="pre">Mob</span></code> automatically.</p>
|
||||
<p>However, in <em>Knave</em>, NPCs and particularly monsters are <em>not</em> using the same rules as PCs - they are simplified to use a Hit-Die (HD) concept. So while still character-like, NPCs should be separate from PCs like this:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">DefaultCharacter</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">DefaultCharacter</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureCharacter</span><span class="p">(</span><span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
<span class="c1"># stuff </span>
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureCharacter</span><span class="p">(</span><span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
<span class="c1"># stuff</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureNPC</span><span class="p">(</span><span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
<span class="c1"># separate stuff </span>
|
||||
|
||||
<span class="c1"># separate stuff</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureMob</span><span class="p">(</span><span class="n">EvadventureNPC</span><span class="p">):</span>
|
||||
<span class="c1"># more separate stuff</span>
|
||||
</pre></div>
|
||||
|
|
@ -97,17 +97,17 @@ RPG, it will hold everything relevant to that PC.</p>
|
|||
<li><p>All can get looted when defeated.</p></li>
|
||||
</ul>
|
||||
<p>We don’t want to code this separately for every class but we no longer have a common parent class to put it on. So instead we’ll use the concept of a <em>mixin</em> class:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">DefaultCharacter</span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">DefaultCharacter</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">LivingMixin</span><span class="p">:</span>
|
||||
<span class="c1"># stuff common for all living things</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureCharacter</span><span class="p">(</span><span class="n">LivingMixin</span><span class="p">,</span> <span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
<span class="c1"># stuff </span>
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureCharacter</span><span class="p">(</span><span class="n">LivingMixin</span><span class="p">,</span> <span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
<span class="c1"># stuff</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureNPC</span><span class="p">(</span><span class="n">LivingMixin</span><span class="p">,</span> <span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
<span class="c1"># stuff </span>
|
||||
|
||||
<span class="c1"># stuff</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureMob</span><span class="p">(</span><span class="n">LivingMixin</span><span class="p">,</span> <span class="n">EvadventureNPC</span><span class="p">):</span>
|
||||
<span class="c1"># more stuff</span>
|
||||
</pre></div>
|
||||
|
|
@ -116,7 +116,7 @@ RPG, it will hold everything relevant to that PC.</p>
|
|||
<p>In <a class="reference internal" href="../../../api/evennia.contrib.tutorials.evadventure.characters.html"><span class="std std-doc">evennia/contrib/tutorials/evadventure/characters.py</span></a>
|
||||
is an example of a character class structure.</p>
|
||||
</aside>
|
||||
<p>Above, the <code class="docutils literal notranslate"><span class="pre">LivingMixin</span></code> class cannot work on its own - it just ‘patches’ the other classes with some extra functionality all living things should be able to do. This is an example of <em>multiple inheritance</em>. It’s useful to know about, but one should not over-do multiple inheritance since it can also get confusing to follow the code.</p>
|
||||
<p>Above, the <code class="docutils literal notranslate"><span class="pre">LivingMixin</span></code> class cannot work on its own - it just ‘patches’ the other classes with some extra functionality all living things should be able to do. This is an example of <em>multiple inheritance</em>. The order of inheritance matters here - the <code class="docutils literal notranslate"><span class="pre">LivingMixin</span></code> must come <em>before</em> <code class="docutils literal notranslate"><span class="pre">DefaultCharacter</span></code> (or EvAdventureNPC etc) so that its methods are found first when called.Multiple inheritance is a powerful tool in object-oriented programming, and useful to know about. Be careful to over-use it, however. If you have too many mixins it can get hard to follow which method comes from where.</p>
|
||||
</section>
|
||||
<section id="living-mixin-class">
|
||||
<h2><span class="section-number">3.2. </span>Living mixin class<a class="headerlink" href="#living-mixin-class" title="Link to this heading">¶</a></h2>
|
||||
|
|
@ -124,14 +124,14 @@ is an example of a character class structure.</p>
|
|||
<div><p>Create a new module <code class="docutils literal notranslate"><span class="pre">mygame/evadventure/characters.py</span></code></p>
|
||||
</div></blockquote>
|
||||
<p>Let’s get some useful common methods all living things should have in our game.</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/evadventure/characters.py </span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/evadventure/characters.py</span>
|
||||
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">.rules</span><span class="w"> </span><span class="kn">import</span> <span class="n">dice</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">.rules</span><span class="w"> </span><span class="kn">import</span> <span class="n">dice</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">LivingMixin</span><span class="p">:</span>
|
||||
|
||||
<span class="c1"># makes it easy for mobs to know to attack PCs</span>
|
||||
<span class="n">is_pc</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="n">is_pc</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">hurt_level</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
|
|
@ -156,49 +156,49 @@ is an example of a character class structure.</p>
|
|||
<span class="k">elif</span> <span class="n">percent</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s2">"|RCollapsed!|n"</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">heal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">hp</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">""" </span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">heal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">hp</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Heal hp amount of health, not allowing to exceed our max hp</span>
|
||||
<span class="sd"> </span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">damage</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">hp_max</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">hp</span>
|
||||
<span class="n">healed</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">damage</span><span class="p">,</span> <span class="n">hp</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">hp</span> <span class="o">+=</span> <span class="n">healed</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">"You heal for </span><span class="si">{</span><span class="n">healed</span><span class="si">}</span><span class="s2"> HP."</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">damage</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">hp_max</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">hp</span>
|
||||
<span class="n">healed</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">damage</span><span class="p">,</span> <span class="n">hp</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">hp</span> <span class="o">+=</span> <span class="n">healed</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">"You heal for </span><span class="si">{</span><span class="n">healed</span><span class="si">}</span><span class="s2"> HP."</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">at_pay</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">amount</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""When paying coins, make sure to never detract more than we have"""</span>
|
||||
<span class="n">amount</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">amount</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">coins</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">coins</span> <span class="o">-=</span> <span class="n">amount</span>
|
||||
<span class="k">return</span> <span class="n">amount</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">at_attacked</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attacker</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">at_attacked</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attacker</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""Called when being attacked and combat starts."""</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">at_damage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">damage</span><span class="p">,</span> <span class="n">attacker</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""Called when attacked and taking damage."""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">hp</span> <span class="o">-=</span> <span class="n">damage</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">at_defeat</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">hp</span> <span class="o">-=</span> <span class="n">damage</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">at_defeat</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""Called when defeated. By default this means death."""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">at_death</span><span class="p">()</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">at_death</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""Called when this thing dies."""</span>
|
||||
<span class="c1"># this will mean different things for different living things</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">at_do_loot</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">looted</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""Called when looting another entity"""</span>
|
||||
<span class="w"> </span><span class="sd">"""Called when looting another entity"""</span>
|
||||
<span class="n">looted</span><span class="o">.</span><span class="n">at_looted</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">at_looted</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">looter</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""Called when looted by another entity"""</span>
|
||||
|
||||
<span class="c1"># default to stealing some coins </span>
|
||||
<span class="n">max_steal</span> <span class="o">=</span> <span class="n">dice</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="s2">"1d10"</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="sd">"""Called when looted by another entity"""</span>
|
||||
|
||||
<span class="c1"># default to stealing some coins</span>
|
||||
<span class="n">max_steal</span> <span class="o">=</span> <span class="n">dice</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="s2">"1d10"</span><span class="p">)</span>
|
||||
<span class="n">stolen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">at_pay</span><span class="p">(</span><span class="n">max_steal</span><span class="p">)</span>
|
||||
<span class="n">looter</span><span class="o">.</span><span class="n">coins</span> <span class="o">+=</span> <span class="n">stolen</span>
|
||||
|
||||
|
|
@ -213,28 +213,28 @@ is an example of a character class structure.</p>
|
|||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/evadventure/characters.py</span>
|
||||
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">DefaultCharacter</span><span class="p">,</span> <span class="n">AttributeProperty</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">.rules</span><span class="w"> </span><span class="kn">import</span> <span class="n">dice</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">.rules</span><span class="w"> </span><span class="kn">import</span> <span class="n">dice</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">LivingMixin</span><span class="p">:</span>
|
||||
<span class="c1"># ... </span>
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureCharacter</span><span class="p">(</span><span class="n">LivingMixin</span><span class="p">,</span> <span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">""" </span>
|
||||
<span class="sd"> A character to use for EvAdventure. </span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> A character to use for EvAdventure.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">is_pc</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="n">is_pc</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
|
||||
<span class="n">strength</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="n">strength</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="n">dexterity</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="n">constitution</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="n">intelligence</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="n">wisdom</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="n">charisma</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
|
||||
<span class="n">hp</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
|
||||
|
||||
<span class="n">hp</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
|
||||
<span class="n">hp_max</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="n">level</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="n">xp</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||||
<span class="n">coins</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||||
|
|
@ -249,13 +249,13 @@ is an example of a character class structure.</p>
|
|||
<span class="s2">"$You() $conj(collapse) in a heap, alive but beaten."</span><span class="p">,</span>
|
||||
<span class="n">from_obj</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">heal</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">hp_max</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">at_death</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""We rolled 'dead' on the death table."""</span>
|
||||
<span class="bp">self</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">"$You() collapse in a heap, embraced by death."</span><span class="p">,</span>
|
||||
<span class="n">from_obj</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
|
||||
<span class="c1"># TODO - go back into chargen to make a new character! </span>
|
||||
<span class="n">from_obj</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
|
||||
<span class="c1"># TODO - go back into chargen to make a new character!</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We make an assumption about our rooms here - that they have a property <code class="docutils literal notranslate"><span class="pre">.allow_death</span></code>. We need to make a note to actually add such a property to rooms later!</p>
|
||||
|
|
@ -287,26 +287,26 @@ is an example of a character class structure.</p>
|
|||
<section id="backtracking">
|
||||
<h3><span class="section-number">3.3.2. </span>Backtracking<a class="headerlink" href="#backtracking" title="Link to this heading">¶</a></h3>
|
||||
<p>We make our first use of the <code class="docutils literal notranslate"><span class="pre">rules.dice</span></code> roller to roll on the death table! As you may recall, in the previous lesson, we didn’t know just what to do when rolling ‘dead’ on this table. Now we know - we should be calling <code class="docutils literal notranslate"><span class="pre">at_death</span></code> on the character. So let’s add that where we had TODOs before:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/evadventure/rules.py </span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/evadventure/rules.py</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureRollEngine</span><span class="p">:</span>
|
||||
|
||||
<span class="c1"># ... </span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">roll_death</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="c1"># ...</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">roll_death</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="n">ability_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">roll_random_table</span><span class="p">(</span><span class="s2">"1d8"</span><span class="p">,</span> <span class="n">death_table</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">ability_name</span> <span class="o">==</span> <span class="s2">"dead"</span><span class="p">:</span>
|
||||
<span class="c1"># kill the character!</span>
|
||||
<span class="n">character</span><span class="o">.</span><span class="n">at_death</span><span class="p">()</span> <span class="c1"># <------ TODO no more</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># ... </span>
|
||||
|
||||
<span class="k">if</span> <span class="n">current_ability</span> <span class="o"><</span> <span class="o">-</span><span class="mi">10</span><span class="p">:</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">current_ability</span> <span class="o"><</span> <span class="o">-</span><span class="mi">10</span><span class="p">:</span>
|
||||
<span class="c1"># kill the character!</span>
|
||||
<span class="n">character</span><span class="o">.</span><span class="n">at_death</span><span class="p">()</span> <span class="c1"># <------- TODO no more</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># ... </span>
|
||||
<span class="c1"># ...</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -340,12 +340,12 @@ instead.</p>
|
|||
<div><p>Create a new module <code class="docutils literal notranslate"><span class="pre">mygame/evadventure/tests/test_characters.py</span></code></p>
|
||||
</div></blockquote>
|
||||
<p>For testing, we just need to create a new EvAdventure character and check that calling the methods on it doesn’t error out.</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/evadventure/tests/test_characters.py </span>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/evadventure/tests/test_characters.py</span>
|
||||
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">evennia.utils</span><span class="w"> </span><span class="kn">import</span> <span class="n">create</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">evennia.utils.test_resources</span><span class="w"> </span><span class="kn">import</span> <span class="n">BaseEvenniaTest</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">evennia.utils.test_resources</span><span class="w"> </span><span class="kn">import</span> <span class="n">BaseEvenniaTest</span>
|
||||
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">..characters</span><span class="w"> </span><span class="kn">import</span> <span class="n">EvAdventureCharacter</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">..characters</span><span class="w"> </span><span class="kn">import</span> <span class="n">EvAdventureCharacter</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">TestCharacters</span><span class="p">(</span><span class="n">BaseEvenniaTest</span><span class="p">):</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
|
|
@ -353,28 +353,28 @@ instead.</p>
|
|||
<span class="bp">self</span><span class="o">.</span><span class="n">character</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">EvAdventureCharacter</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"testchar"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">test_heal</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">character</span><span class="o">.</span><span class="n">hp</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">hp_max</span> <span class="o">=</span> <span class="mi">8</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">hp</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">hp_max</span> <span class="o">=</span> <span class="mi">8</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">heal</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">hp</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="c1"># make sure we can't heal more than max</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">heal</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">hp</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">test_at_pay</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">character</span><span class="o">.</span><span class="n">coins</span> <span class="o">=</span> <span class="mi">100</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">coins</span> <span class="o">=</span> <span class="mi">100</span>
|
||||
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">at_pay</span><span class="p">(</span><span class="mi">60</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="mi">60</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="mi">60</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">coins</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># can't get more coins than we have </span>
|
||||
|
||||
<span class="c1"># can't get more coins than we have</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">at_pay</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">character</span><span class="o">.</span><span class="n">coins</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># tests for other methods ... </span>
|
||||
|
||||
<span class="c1"># tests for other methods ...</span>
|
||||
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -391,11 +391,11 @@ instead.</p>
|
|||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/evadventure/characters.py</span>
|
||||
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">DefaultCharacter</span><span class="p">,</span> <span class="n">AttributeProperty</span>
|
||||
<span class="c1"># ... </span>
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">EvAdventureCharacter</span><span class="p">(</span><span class="n">LivingMixin</span><span class="p">,</span> <span class="n">DefaultCharacter</span><span class="p">):</span>
|
||||
|
||||
<span class="c1"># ... </span>
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
<span class="n">charclass</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="s2">"Fighter"</span><span class="p">)</span>
|
||||
<span class="n">charrace</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="s2">"Human"</span><span class="p">)</span>
|
||||
|
|
@ -410,7 +410,7 @@ instead.</p>
|
|||
<h2><span class="section-number">3.7. </span>Summary<a class="headerlink" href="#summary" title="Link to this heading">¶</a></h2>
|
||||
<p>With the <code class="docutils literal notranslate"><span class="pre">EvAdventureCharacter</span></code> class in place, we have a better understanding of how our PCs will look like under <em>Knave</em>.</p>
|
||||
<p>For now, we only have bits and pieces and haven’t been testing this code in-game. But if you want you can swap yourself into <code class="docutils literal notranslate"><span class="pre">EvAdventureCharacter</span></code> right now. Log into your game and run the command</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>type self = evadventure.characters.EvAdventureCharacter
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>type self = evadventure.characters.EvAdventureCharacter
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If all went well, <code class="docutils literal notranslate"><span class="pre">ex</span> <span class="pre">self</span></code> will now show your typeclass as being <code class="docutils literal notranslate"><span class="pre">EvAdventureCharacter</span></code>. Check out your strength with</p>
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ You<span class="w"> </span>use<span class="w"> </span>Potion<span class="w"> </s
|
|||
<span class="k">def</span><span class="w"> </span><span class="nf">get_sides</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">combatant</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Get a listing of the two 'sides' of this combat,</span>
|
||||
<span class="sd"> m the perspective of the provided combatant.</span>
|
||||
<span class="sd"> from the perspective of the provided combatant.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">allow_pvp</span><span class="p">:</span>
|
||||
<span class="c1"># in pvp, everyone else is an ememy</span>
|
||||
|
|
@ -257,7 +257,7 @@ You<span class="w"> </span>use<span class="w"> </span>Potion<span class="w"> </s
|
|||
<p>We use the <code class="docutils literal notranslate"><span class="pre">advantage/disadvantage_matrix</span></code> Attributes to track who has advantage against whom.</p>
|
||||
<aside class="sidebar">
|
||||
<p class="sidebar-title">.pop()</p>
|
||||
<p>The Python <code class="docutils literal notranslate"><span class="pre">.pop()</span></code> method exists on lists and dicts as well as some other iterables. It ‘pops’ and returns an element from the container. For a list, it’s either popped by index or by popping the last element. For a dict (like here), a specific key must be given to pop. If you don’t provide a default value as a second element, an error will be raised if the key you try to pop is not found.</p>
|
||||
<p>The Python <code class="docutils literal notranslate"><span class="pre">.pop()</span></code> method removes an element from a list or dict and returns it. For a list, it removes by index (or the last element by default). For a dict (like here), you specify which key to remove. Providing a default value as a second argument prevents an error if the key doesn’t exist.</p>
|
||||
</aside>
|
||||
<p>In the <code class="docutils literal notranslate"><span class="pre">has</span> <span class="pre">dis/advantage</span></code> methods we <code class="docutils literal notranslate"><span class="pre">pop</span></code> the target from the matrix which will result either in the value <code class="docutils literal notranslate"><span class="pre">True</span></code> or <code class="docutils literal notranslate"><span class="pre">False</span></code> (the default value we give to <code class="docutils literal notranslate"><span class="pre">pop</span></code> if the target is not in the matrix). This means that the advantage, once gained, can only be used once.</p>
|
||||
<p>We also consider everyone to have advantage against fleeing combatants.</p>
|
||||
|
|
@ -498,7 +498,7 @@ This is new compared to the base handler.</p>
|
|||
<span class="hll"><span class="linenos">49</span> <span class="n">surviving_combatant</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
</span><span class="linenos">50</span> <span class="n">allies</span><span class="p">,</span> <span class="n">enemies</span> <span class="o">=</span> <span class="p">(),</span> <span class="p">()</span>
|
||||
<span class="linenos">51</span> <span class="k">else</span><span class="p">:</span>
|
||||
<span class="linenos">52</span> <span class="c1"># grab a random survivor and check of they have any living enemies.</span>
|
||||
<span class="linenos">52</span> <span class="c1"># grab a random survivor and check if they have any living enemies.</span>
|
||||
<span class="linenos">53</span> <span class="n">surviving_combatant</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatants</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
|
||||
<span class="linenos">54</span> <span class="n">allies</span><span class="p">,</span> <span class="n">enemies</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_sides</span><span class="p">(</span><span class="n">surviving_combatant</span><span class="p">)</span>
|
||||
<span class="linenos">55</span>
|
||||
|
|
@ -764,7 +764,7 @@ This is new compared to the base handler.</p>
|
|||
</section>
|
||||
<section id="stepping-through-the-wizard">
|
||||
<h3><span class="section-number">11.4.5. </span>Stepping through the wizard<a class="headerlink" href="#stepping-through-the-wizard" title="Link to this heading">¶</a></h3>
|
||||
<p>Our particualr menu is very symmetric - you select an option and then you will just select a series of option before you come back. So we will make another goto-function to help us easily do this. To understand, let’s first show how we plan to use this:</p>
|
||||
<p>Our particular menu is very symmetric - you select an option and then you will just select a series of option before you come back. So we will make another goto-function to help us easily do this. To understand, let’s first show how we plan to use this:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in the base combat-node function (just shown as an example)</span>
|
||||
|
||||
<span class="n">options</span> <span class="o">=</span> <span class="p">[</span>
|
||||
|
|
@ -844,7 +844,7 @@ This is new compared to the base handler.</p>
|
|||
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
<span class="n">_get_default_wizard_options</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">_get_default_wizard_options</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">[</span>
|
||||
<span class="p">{</span>
|
||||
<span class="s2">"key"</span><span class="p">:</span> <span class="s2">"back"</span><span class="p">,</span>
|
||||
|
|
@ -956,7 +956,6 @@ This is new compared to the base handler.</p>
|
|||
<span class="n">Ability</span><span class="o">.</span><span class="n">DEX</span><span class="p">,</span>
|
||||
<span class="n">Ability</span><span class="o">.</span><span class="n">CON</span><span class="p">,</span>
|
||||
<span class="n">Ability</span><span class="o">.</span><span class="n">INT</span><span class="p">,</span>
|
||||
<span class="n">Ability</span><span class="o">.</span><span class="n">INT</span><span class="p">,</span>
|
||||
<span class="n">Ability</span><span class="o">.</span><span class="n">WIS</span><span class="p">,</span>
|
||||
<span class="n">Ability</span><span class="o">.</span><span class="n">CHA</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
|
|
@ -1001,7 +1000,7 @@ This is new compared to the base handler.</p>
|
|||
</pre></div>
|
||||
</div>
|
||||
<p>Our <a class="reference internal" href="Beginner-Tutorial-Equipment.html"><span class="std std-doc">equipment handler</span></a> has the very useful help method <code class="docutils literal notranslate"><span class="pre">.get_usable_objects_from_backpack</span></code>. We just call this to get a list of all the items we want to choose. Otherwise this node should look pretty familiar by now.</p>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">node_choose_wiqld_item</span></code> is very similar, except it uses <code class="docutils literal notranslate"><span class="pre">caller.equipment.get_wieldable_objects_from_backpack()</span></code> instead. We’ll leave the implementation of this up to the reader.</p>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">node_choose_wield_item</span></code> is very similar, except it uses <code class="docutils literal notranslate"><span class="pre">caller.equipment.get_wieldable_objects_from_backpack()</span></code> instead. We’ll leave the implementation of this up to the reader.</p>
|
||||
</section>
|
||||
<section id="the-main-menu-node">
|
||||
<h3><span class="section-number">11.4.9. </span>The main menu node<a class="headerlink" href="#the-main-menu-node" title="Link to this heading">¶</a></h3>
|
||||
|
|
@ -1103,12 +1102,12 @@ This is new compared to the base handler.</p>
|
|||
</pre></div>
|
||||
</div>
|
||||
<p>This starts off the <code class="docutils literal notranslate"><span class="pre">_step_wizard</span></code> for each action choice. It also lays out the <code class="docutils literal notranslate"><span class="pre">action_dict</span></code> for every action, leaving <code class="docutils literal notranslate"><span class="pre">None</span></code> values for the fields that will be set by the following nodes.</p>
|
||||
<p>Note how we add the <code class="docutils literal notranslate"><span class="pre">"repeat"</span></code> key to some actions. Having them automatically repeat means the player don’t have to insert the same action every time.</p>
|
||||
<p>Note how we add the <code class="docutils literal notranslate"><span class="pre">"repeat"</span></code> key to some actions. Having them automatically repeat means the player doesn’t have to insert the same action every time.</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="attack-command">
|
||||
<h2><span class="section-number">11.5. </span>Attack Command<a class="headerlink" href="#attack-command" title="Link to this heading">¶</a></h2>
|
||||
<p>We will only need one single Command to run the Turnbased combat system. This is the <code class="docutils literal notranslate"><span class="pre">attack</span></code> command. Once you use it once, you will be in the menu.</p>
|
||||
<p>We will only need one single command to run the turnbased combat system. This is the <code class="docutils literal notranslate"><span class="pre">attack</span></code> command. Once you use it once, you will be in the menu.</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in evadventure/combat_turnbased.py</span>
|
||||
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">Command</span><span class="p">,</span> <span class="n">CmdSet</span><span class="p">,</span> <span class="n">EvMenu</span>
|
||||
|
|
@ -1319,7 +1318,7 @@ This is new compared to the base handler.</p>
|
|||
<p>If editing this in an IDE, you may get errors on the <code class="docutils literal notranslate"><span class="pre">player</span> <span class="pre">=</span> <span class="pre">caller</span></code> line. This is because <code class="docutils literal notranslate"><span class="pre">caller</span></code> is not defined anywhere in this file. Instead <code class="docutils literal notranslate"><span class="pre">caller</span></code> (the one running the script) is injected by the <code class="docutils literal notranslate"><span class="pre">batchcode</span></code> runner.</p>
|
||||
<p>But apart from the <code class="docutils literal notranslate"><span class="pre">#</span> <span class="pre">HEADER</span></code> and <code class="docutils literal notranslate"><span class="pre">#</span> <span class="pre">CODE</span></code> specials, this just a series of normal Evennia api calls.</p>
|
||||
<p>Log into the game with a developer/superuser account and run</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> batchcmd evadventure.batchscripts.turnbased_combat_demo
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> batchcode evadventure.batchscripts.turnbased_combat_demo
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This should place you in the arena with the dummy (if not, check for errors in the output! Use <code class="docutils literal notranslate"><span class="pre">objects</span></code> and <code class="docutils literal notranslate"><span class="pre">delete</span></code> commands to list and delete objects if you need to start over.)</p>
|
||||
|
|
@ -1327,7 +1326,7 @@ This is new compared to the base handler.</p>
|
|||
</section>
|
||||
<section id="conclusions">
|
||||
<h2><span class="section-number">11.9. </span>Conclusions<a class="headerlink" href="#conclusions" title="Link to this heading">¶</a></h2>
|
||||
<p>At this point we have coverered some ideas on how to implement both twitch- and turnbased combat systems. Along the way you have been exposed to many concepts such as classes, scripts and handlers, Commands, EvMenus and more.</p>
|
||||
<p>At this point we have covered some ideas on how to implement both twitch- and turnbased combat systems. Along the way you have been exposed to many concepts such as classes, scripts and handlers, Commands, EvMenus and more.</p>
|
||||
<p>Before our combat system is actually usable, we need our enemies to actually fight back. We’ll get to that next.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ a given combatant has advantage.</p>
|
|||
<span class="linenos">37</span>
|
||||
<span class="linenos">38</span><span class="sd"> """</span>
|
||||
<span class="linenos">39</span> <span class="k">if</span> <span class="n">action_dict</span><span class="p">[</span><span class="s2">"key"</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">action_classes</span><span class="p">:</span>
|
||||
<span class="linenos">40</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"This is an unkown action!"</span><span class="p">)</span>
|
||||
<span class="linenos">40</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"This is an unknown action!"</span><span class="p">)</span>
|
||||
<span class="linenos">41</span> <span class="k">return</span>
|
||||
<span class="linenos">42</span>
|
||||
<span class="hll"><span class="linenos">43</span> <span class="c1"># store action dict and schedule it to run in dt time</span>
|
||||
|
|
@ -323,7 +323,7 @@ a given combatant has advantage.</p>
|
|||
<li><p><strong>Line 43</strong>: We simply store the given action dict in the Attribute <code class="docutils literal notranslate"><span class="pre">action_dict</span></code> on the handler. Simple and effective!</p></li>
|
||||
<li><p><strong>Line 44</strong>: When you enter e.g. <code class="docutils literal notranslate"><span class="pre">attack</span></code>, you expect in this type of combat to see the <code class="docutils literal notranslate"><span class="pre">attack</span></code> command repeat automatically even if you don’t enter anything more. To this end we are looking for a new key in action dicts, indicating that this action should <em>repeat</em> with a certain rate (<code class="docutils literal notranslate"><span class="pre">dt</span></code>, given in seconds). We make this compatible with all action dicts by simply assuming it’s zero if not specified.</p></li>
|
||||
</ul>
|
||||
<p><a class="reference internal" href="../../../api/evennia.utils.utils.html#evennia.utils.utils.repeat" title="evennia.utils.utils.repeat"><span class="xref myst py py-func">evennia.utils.utils.repeat</span></a> and <a class="reference internal" href="../../../api/evennia.utils.utils.html#evennia.utils.utils.unrepeat" title="evennia.utils.utils.unrepeat"><span class="xref myst py py-func">evennia.utils.utils.unrepeat</span></a> are convenient shortcuts to the <a class="reference internal" href="../../../Components/TickerHandler.html"><span class="std std-doc">TickerHandler</span></a>. You tell <code class="docutils literal notranslate"><span class="pre">repeat</span></code> to call a given method/function at a certain rate. What you get back is a reference that you can then later use to ‘un-repeat’ (stop the repeating) later. We make sure to store this reference (we don’t care exactly how it looks, just that we need to store it) in <code class="docutils literal notranslate"><span class="pre">the</span> <span class="pre">current_ticket_ref</span></code> Attribute (<strong>Line 26</strong>).</p>
|
||||
<p><a class="reference internal" href="../../../api/evennia.utils.utils.html#evennia.utils.utils.repeat" title="evennia.utils.utils.repeat"><span class="xref myst py py-func">evennia.utils.utils.repeat</span></a> and <a class="reference internal" href="../../../api/evennia.utils.utils.html#evennia.utils.utils.unrepeat" title="evennia.utils.utils.unrepeat"><span class="xref myst py py-func">evennia.utils.utils.unrepeat</span></a> are convenient shortcuts to the <a class="reference internal" href="../../../Components/TickerHandler.html"><span class="std std-doc">TickerHandler</span></a>. You tell <code class="docutils literal notranslate"><span class="pre">repeat</span></code> to call a given method/function at a certain rate. What you get back is a reference that you can then later use to ‘un-repeat’ (stop the repeating) later. We make sure to store this reference (we don’t care exactly how it looks, just that we need to store it) in the <code class="docutils literal notranslate"><span class="pre">current_ticker_ref</span></code> Attribute (<strong>Line 26</strong>).</p>
|
||||
<ul class="simple">
|
||||
<li><p><strong>Line 48</strong>: Whenever we queue a new action (it may replace an existing one) we must make sure to kill (un-repeat) any old repeats that are ongoing. Otherwise we would get old actions firing over and over and new ones starting alongside them.</p></li>
|
||||
<li><p><strong>Line 49</strong>: If <code class="docutils literal notranslate"><span class="pre">dt</span></code> is set, we call <code class="docutils literal notranslate"><span class="pre">repeat</span></code> to set up a new repeat action at the given rate. We store this new reference. After <code class="docutils literal notranslate"><span class="pre">dt</span></code> seconds, the <code class="docutils literal notranslate"><span class="pre">.execute_next_action</span></code> method will fire (we’ll create that in the next section).</p></li>
|
||||
|
|
@ -340,30 +340,30 @@ a given combatant has advantage.</p>
|
|||
<span class="linenos"> 7</span> <span class="c1"># ... </span>
|
||||
<span class="linenos"> 8</span>
|
||||
<span class="linenos"> 9</span> <span class="k">def</span><span class="w"> </span><span class="nf">execute_next_action</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="linenos">10</span><span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="linenos">11</span><span class="sd"> Triggered after a delay by the command</span>
|
||||
<span class="linenos">12</span><span class="sd"> """</span>
|
||||
<span class="linenos">13</span> <span class="n">combatant</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span>
|
||||
<span class="linenos">14</span> <span class="n">action_dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">action_dict</span>
|
||||
<span class="hll"><span class="linenos">15</span> <span class="n">action_class</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">action_classes</span><span class="p">[</span><span class="n">action_dict</span><span class="p">[</span><span class="s2">"key"</span><span class="p">]]</span>
|
||||
</span><span class="hll"><span class="linenos">16</span> <span class="n">action</span> <span class="o">=</span> <span class="n">action_class</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">combatant</span><span class="p">,</span> <span class="n">action_dict</span><span class="p">)</span>
|
||||
</span><span class="linenos">17</span>
|
||||
<span class="hll"><span class="linenos">18</span> <span class="k">if</span> <span class="n">action</span><span class="o">.</span><span class="n">can_use</span><span class="p">():</span>
|
||||
</span><span class="linenos">19</span> <span class="n">action</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span>
|
||||
<span class="linenos">20</span> <span class="n">action</span><span class="o">.</span><span class="n">post_execute</span><span class="p">()</span>
|
||||
<span class="linenos">21</span>
|
||||
<span class="hll"><span class="linenos">22</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">action_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"repeat"</span><span class="p">,</span> <span class="kc">True</span><span class="p">):</span>
|
||||
</span><span class="linenos">23</span> <span class="c1"># not a repeating action, use the fallback (normally the original attack)</span>
|
||||
<span class="linenos">24</span> <span class="bp">self</span><span class="o">.</span><span class="n">action_dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fallback_action_dict</span>
|
||||
<span class="linenos">25</span> <span class="bp">self</span><span class="o">.</span><span class="n">queue_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fallback_action_dict</span><span class="p">)</span>
|
||||
<span class="linenos">26</span>
|
||||
<span class="hll"><span class="linenos">27</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_stop_combat</span><span class="p">()</span>
|
||||
<span class="linenos">10</span><span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="linenos">11</span><span class="sd"> Triggered after a delay by the command</span>
|
||||
<span class="linenos">12</span><span class="sd"> """</span>
|
||||
<span class="linenos">13</span> <span class="n">combatant</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span>
|
||||
<span class="linenos">14</span> <span class="n">action_dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">action_dict</span>
|
||||
<span class="hll"><span class="linenos">15</span> <span class="n">action_class</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">action_classes</span><span class="p">[</span><span class="n">action_dict</span><span class="p">[</span><span class="s2">"key"</span><span class="p">]]</span>
|
||||
</span><span class="hll"><span class="linenos">16</span> <span class="n">action</span> <span class="o">=</span> <span class="n">action_class</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">combatant</span><span class="p">,</span> <span class="n">action_dict</span><span class="p">)</span>
|
||||
</span><span class="linenos">17</span>
|
||||
<span class="hll"><span class="linenos">18</span> <span class="k">if</span> <span class="n">action</span><span class="o">.</span><span class="n">can_use</span><span class="p">():</span>
|
||||
</span><span class="linenos">19</span> <span class="n">action</span><span class="o">.</span><span class="n">execute</span><span class="p">()</span>
|
||||
<span class="linenos">20</span> <span class="n">action</span><span class="o">.</span><span class="n">post_execute</span><span class="p">()</span>
|
||||
<span class="linenos">21</span>
|
||||
<span class="hll"><span class="linenos">22</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">action_dict</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"repeat"</span><span class="p">,</span> <span class="kc">True</span><span class="p">):</span>
|
||||
</span><span class="linenos">23</span> <span class="c1"># not a repeating action, use the fallback (normally the original attack)</span>
|
||||
<span class="linenos">24</span> <span class="bp">self</span><span class="o">.</span><span class="n">action_dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fallback_action_dict</span>
|
||||
<span class="linenos">25</span> <span class="bp">self</span><span class="o">.</span><span class="n">queue_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fallback_action_dict</span><span class="p">)</span>
|
||||
<span class="linenos">26</span>
|
||||
<span class="hll"><span class="linenos">27</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_stop_combat</span><span class="p">()</span>
|
||||
</span></pre></div>
|
||||
</div>
|
||||
<p>This is the method called after <code class="docutils literal notranslate"><span class="pre">dt</span></code> seconds in <code class="docutils literal notranslate"><span class="pre">queue_action</span></code>.</p>
|
||||
<ul class="simple">
|
||||
<li><p><strong>Line 5</strong>: We defined a ‘fallback action’. This is used after a one-time action (one that should not repeat) has completed.</p></li>
|
||||
<li><p><strong>Line 15</strong>: We take the <code class="docutils literal notranslate"><span class="pre">'key'</span></code> from the <code class="docutils literal notranslate"><span class="pre">action-dict</span></code> and use the <code class="docutils literal notranslate"><span class="pre">action_classes</span></code> mapping to get an action class (e.g. <code class="docutils literal notranslate"><span class="pre">ACtionAttack</span></code> we defined <a class="reference internal" href="Beginner-Tutorial-Combat-Base.html#attack-action"><span class="std std-ref">here</span></a>).</p></li>
|
||||
<li><p><strong>Line 15</strong>: We take the <code class="docutils literal notranslate"><span class="pre">'key'</span></code> from the <code class="docutils literal notranslate"><span class="pre">action_dict</span></code> and use the <code class="docutils literal notranslate"><span class="pre">action_classes</span></code> mapping to get an action class (e.g. <code class="docutils literal notranslate"><span class="pre">ActionAttack</span></code> we defined <a class="reference internal" href="Beginner-Tutorial-Combat-Base.html#attack-action"><span class="std std-ref">here</span></a>).</p></li>
|
||||
<li><p><strong>Line 16</strong>: Here we initialize the action class with the actual current data - the combatant and the <code class="docutils literal notranslate"><span class="pre">action_dict</span></code>. This calls the <code class="docutils literal notranslate"><span class="pre">__init__</span></code> method on the class and makes the action ready to use.</p></li>
|
||||
</ul>
|
||||
<aside class="sidebar">
|
||||
|
|
@ -402,7 +402,7 @@ a given combatant has advantage.</p>
|
|||
<span class="hll"><span class="linenos">18</span> <span class="n">enemies</span> <span class="o">=</span> <span class="p">[</span><span class="n">comb</span> <span class="k">for</span> <span class="n">comb</span> <span class="ow">in</span> <span class="n">enemies</span> <span class="k">if</span> <span class="n">comb</span><span class="o">.</span><span class="n">hp</span> <span class="o">></span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">comb</span><span class="o">.</span><span class="n">location</span> <span class="o">==</span> <span class="n">location</span><span class="p">]</span>
|
||||
</span><span class="hll"><span class="linenos">19</span>
|
||||
</span><span class="linenos">20</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">allies</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">enemies</span><span class="p">:</span>
|
||||
<span class="linenos">21</span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"The combat is over. Noone stands."</span><span class="p">,</span> <span class="n">broadcast</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||||
<span class="linenos">21</span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"The combat is over. No one stands."</span><span class="p">,</span> <span class="n">broadcast</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||||
<span class="linenos">22</span> <span class="bp">self</span><span class="o">.</span><span class="n">stop_combat</span><span class="p">()</span>
|
||||
<span class="linenos">23</span> <span class="k">return</span>
|
||||
<span class="linenos">24</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">allies</span><span class="p">:</span>
|
||||
|
|
@ -421,7 +421,7 @@ a given combatant has advantage.</p>
|
|||
<li><p><strong>Line 12</strong>: With our <code class="docutils literal notranslate"><span class="pre">.get_sides()</span></code> method we can easily get the two sides of the conflict.</p></li>
|
||||
<li><p><strong>Lines 18, 19</strong>: We get everyone still alive <em>and still in the same room</em>. The latter condition is important in case we move away from the battle - you can’t hit your enemy from another room.</p></li>
|
||||
</ul>
|
||||
<p>In the <code class="docutils literal notranslate"><span class="pre">stop_method</span></code> we’ll need to do a bunch of cleanup. We’ll hold off on implementing this until we have the Commands written out. Read on.</p>
|
||||
<p>In the <code class="docutils literal notranslate"><span class="pre">stop_combat</span></code> method we’ll need to do a bunch of cleanup. We’ll hold off on implementing this until we have the Commands written out. Read on.</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="commands">
|
||||
|
|
@ -448,7 +448,7 @@ a given combatant has advantage.</p>
|
|||
<span class="linenos"> 9</span>
|
||||
<span class="linenos">10</span><span class="k">class</span><span class="w"> </span><span class="nc">_BaseTwitchCombatCommand</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="linenos">11</span><span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="linenos">12</span><span class="sd"> Parent class for all twitch-combat commnads.</span>
|
||||
<span class="linenos">12</span><span class="sd"> Parent class for all twitch-combat commands.</span>
|
||||
<span class="linenos">13</span>
|
||||
<span class="linenos">14</span><span class="sd"> """</span>
|
||||
<span class="linenos">15</span>
|
||||
|
|
@ -668,7 +668,7 @@ You<span class="w"> </span><span class="o">(</span>Wounded<span class="o">)</spa
|
|||
<span class="c1"># something like `boost str target`</span>
|
||||
<span class="n">target</span> <span class="o">=</span> <span class="n">recipient</span> <span class="k">if</span> <span class="n">advantage</span> <span class="k">else</span> <span class="s2">"me"</span>
|
||||
<span class="n">recipient</span> <span class="o">=</span> <span class="s2">"me"</span> <span class="k">if</span> <span class="n">advantage</span> <span class="k">else</span> <span class="n">recipient</span>
|
||||
<span class="n">we</span> <span class="n">still</span> <span class="n">have</span> <span class="kc">None</span><span class="p">:</span><span class="n">s</span> <span class="n">at</span> <span class="n">this</span> <span class="n">point</span><span class="p">,</span> <span class="n">we</span> <span class="n">can</span><span class="s1">'t continue</span>
|
||||
<span class="c1"># if any values are still None at this point, we can't continue</span>
|
||||
<span class="k">if</span> <span class="kc">None</span> <span class="ow">in</span> <span class="p">(</span><span class="n">stunt_type</span><span class="p">,</span> <span class="n">recipient</span><span class="p">,</span> <span class="n">target</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">"Both ability, recipient and target of stunt must be given."</span><span class="p">)</span>
|
||||
<span class="k">raise</span> <span class="n">InterruptCommand</span><span class="p">()</span>
|
||||
|
|
@ -704,7 +704,7 @@ You<span class="w"> </span><span class="o">(</span>Wounded<span class="o">)</spa
|
|||
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This looks much longer, but that is only because the stunt command should understand many different input structures depending on if you are trying to create a advantage or disadvantage, and if an ally or enemy should receive the effect of the stunt.</p>
|
||||
<p>This looks much longer, but that is only because the stunt command should understand many different input structures depending on if you are trying to create an advantage or disadvantage, and if an ally or enemy should receive the effect of the stunt.</p>
|
||||
<p>Note the <code class="docutils literal notranslate"><span class="pre">enums.ABILITY_REVERSE_MAP</span></code> (created in the <a class="reference internal" href="Beginner-Tutorial-Utilities.html"><span class="std std-doc">Utilities lesson</span></a>) being useful to convert your input of ‘str’ into <code class="docutils literal notranslate"><span class="pre">Ability.STR</span></code> needed by the action dict.</p>
|
||||
<p>Once we’ve sorted out the string parsing, the <code class="docutils literal notranslate"><span class="pre">func</span></code> is simple - we find the target and recipient and use them to build the needed action-dict to queue.</p>
|
||||
</section>
|
||||
|
|
@ -777,8 +777,8 @@ You<span class="w"> </span><span class="o">(</span>Wounded<span class="o">)</spa
|
|||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">CmdWield</span><span class="p">(</span><span class="n">_BaseTwitchCombatCommand</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Wield a weapon or spell-rune. You will the wield the item, </span>
|
||||
<span class="sd"> swapping with any other item(s) you were wielded before.</span>
|
||||
<span class="sd"> Wield a weapon or spell-rune. You wield the item,</span>
|
||||
<span class="sd"> swapping with any other item(s) you were wielding before.</span>
|
||||
|
||||
<span class="sd"> Usage:</span>
|
||||
<span class="sd"> wield <weapon or spell></span>
|
||||
|
|
@ -906,7 +906,7 @@ You<span class="w"> </span><span class="o">(</span>Wounded<span class="o">)</spa
|
|||
|
||||
<span class="c1"># ...</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">TestEvAdventureTwitchCombat</span><span class="p">(</span><span class="n">EvenniaCommandTestMixin</span><span class="p">)</span>
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">TestEvAdventureTwitchCombat</span><span class="p">(</span><span class="n">EvenniaCommandTestMixin</span><span class="p">):</span>
|
||||
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">setUp</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">combathandler</span> <span class="o">=</span> <span class="p">(</span>
|
||||
|
|
@ -917,12 +917,12 @@ You<span class="w"> </span><span class="o">(</span>Wounded<span class="o">)</spa
|
|||
<span class="nd">@patch</span><span class="p">(</span><span class="s2">"evadventure.combat_twitch.unrepeat"</span><span class="p">,</span> <span class="n">new</span><span class="o">=</span><span class="n">Mock</span><span class="p">())</span>
|
||||
<span class="nd">@patch</span><span class="p">(</span><span class="s2">"evadventure.combat_twitch.repeat"</span><span class="p">,</span> <span class="n">new</span><span class="o">=</span><span class="n">Mock</span><span class="p">())</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">test_hold_command</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">call</span><span class="p">(</span><span class="n">combat_twitch</span><span class="p">,</span> <span class="n">CmdHold</span><span class="p">(),</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"You hold back, doing nothing"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">combat_twitch</span><span class="p">,</span> <span class="n">CmdHold</span><span class="p">(),</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"You hold back, doing nothing."</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">action_dict</span><span class="p">,</span> <span class="p">{</span><span class="s2">"key"</span><span class="p">:</span> <span class="s2">"hold"</span><span class="p">})</span>
|
||||
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">EvenniaCommandTestMixin</span></code> as a few default objects, including <code class="docutils literal notranslate"><span class="pre">self.char1</span></code>, which we make use of here.</p>
|
||||
<p>The <code class="docutils literal notranslate"><span class="pre">EvenniaCommandTestMixin</span></code> has a few default objects, including <code class="docutils literal notranslate"><span class="pre">self.char1</span></code>, which we make use of here.</p>
|
||||
<p>The two <code class="docutils literal notranslate"><span class="pre">@patch</span></code> lines are Python <a class="reference external" href="https://realpython.com/primer-on-python-decorators/">decorators</a> that ‘patch’ the <code class="docutils literal notranslate"><span class="pre">test_hold_command</span></code> method. What they do is basically saying “in the following method, whenever any code tries to access <code class="docutils literal notranslate"><span class="pre">evadventure.combat_twitch.un/repeat</span></code>, just return a Mocked object instead”.</p>
|
||||
<p>We do this patching as an easy way to avoid creating timers in the unit test - these timers would finish after the test finished (which includes deleting its objects) and thus fail.</p>
|
||||
<p>Inside the test, we use the <code class="docutils literal notranslate"><span class="pre">self.call()</span></code> method to explicitly fire the Command (with no argument) and check that the output is what we expect. Lastly we check that the combathandler is set up correctly, having stored the action-dict on itself.</p>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue