Updated HTML docs

This commit is contained in:
Evennia docbuilder action 2022-02-05 15:09:22 +00:00
parent f310a65256
commit ecb368ddb6
1797 changed files with 10075 additions and 330676 deletions

View file

@ -59,20 +59,22 @@
<span class="kn">import</span> <span class="nn">django</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">global_settings</span>
<span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="n">ImproperlyConfigured</span>
<span class="kn">from</span> <span class="nn">django.utils.deprecation</span> <span class="kn">import</span> <span class="n">RemovedInDjango40Warning</span>
<span class="kn">from</span> <span class="nn">django.utils.deprecation</span> <span class="kn">import</span> <span class="n">RemovedInDjango50Warning</span>
<span class="kn">from</span> <span class="nn">django.utils.functional</span> <span class="kn">import</span> <span class="n">LazyObject</span><span class="p">,</span> <span class="n">empty</span>
<span class="n">ENVIRONMENT_VARIABLE</span> <span class="o">=</span> <span class="s2">&quot;DJANGO_SETTINGS_MODULE&quot;</span>
<span class="n">PASSWORD_RESET_TIMEOUT_DAYS_DEPRECATED_MSG</span> <span class="o">=</span> <span class="p">(</span>
<span class="s1">&#39;The PASSWORD_RESET_TIMEOUT_DAYS setting is deprecated. Use &#39;</span>
<span class="s1">&#39;PASSWORD_RESET_TIMEOUT instead.&#39;</span>
<span class="c1"># RemovedInDjango50Warning</span>
<span class="n">USE_DEPRECATED_PYTZ_DEPRECATED_MSG</span> <span class="o">=</span> <span class="p">(</span>
<span class="s1">&#39;The USE_DEPRECATED_PYTZ setting, and support for pytz timezones is &#39;</span>
<span class="s1">&#39;deprecated in favor of the stdlib zoneinfo module. Please update your &#39;</span>
<span class="s1">&#39;code to use zoneinfo and remove the USE_DEPRECATED_PYTZ setting.&#39;</span>
<span class="p">)</span>
<span class="n">DEFAULT_HASHING_ALGORITHM_DEPRECATED_MSG</span> <span class="o">=</span> <span class="p">(</span>
<span class="s1">&#39;The DEFAULT_HASHING_ALGORITHM transitional setting is deprecated. &#39;</span>
<span class="s1">&#39;Support for it and tokens, cookies, sessions, and signatures that use &#39;</span>
<span class="s1">&#39;SHA-1 hashing algorithm will be removed in Django 4.0.&#39;</span>
<span class="n">USE_L10N_DEPRECATED_MSG</span> <span class="o">=</span> <span class="p">(</span>
<span class="s1">&#39;The USE_L10N setting is deprecated. Starting with Django 5.0, localized &#39;</span>
<span class="s1">&#39;formatting of data will always be enabled. For example Django will &#39;</span>
<span class="s1">&#39;display numbers and dates using the format of the current locale.&#39;</span>
<span class="p">)</span>
@ -186,18 +188,25 @@
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_wrapped</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">empty</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">PASSWORD_RESET_TIMEOUT_DAYS</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">USE_L10N</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">stack</span> <span class="o">=</span> <span class="n">traceback</span><span class="o">.</span><span class="n">extract_stack</span><span class="p">()</span>
<span class="c1"># Show a warning if the setting is used outside of Django.</span>
<span class="c1"># Stack index: -1 this line, -2 the caller.</span>
<span class="n">filename</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">filename</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">django</span><span class="o">.</span><span class="vm">__file__</span><span class="p">)):</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span>
<span class="n">PASSWORD_RESET_TIMEOUT_DAYS_DEPRECATED_MSG</span><span class="p">,</span>
<span class="n">RemovedInDjango40Warning</span><span class="p">,</span>
<span class="n">USE_L10N_DEPRECATED_MSG</span><span class="p">,</span>
<span class="n">RemovedInDjango50Warning</span><span class="p">,</span>
<span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__getattr__</span><span class="p">(</span><span class="s1">&#39;PASSWORD_RESET_TIMEOUT_DAYS&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__getattr__</span><span class="p">(</span><span class="s1">&#39;USE_L10N&#39;</span><span class="p">)</span>
<span class="c1"># RemovedInDjango50Warning.</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">_USE_L10N_INTERNAL</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># Special hook to avoid checking a traceback in internal use on hot</span>
<span class="c1"># paths.</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__getattr__</span><span class="p">(</span><span class="s1">&#39;USE_L10N&#39;</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Settings</span><span class="p">:</span>
@ -213,6 +222,7 @@
<span class="n">mod</span> <span class="o">=</span> <span class="n">importlib</span><span class="o">.</span><span class="n">import_module</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">SETTINGS_MODULE</span><span class="p">)</span>
<span class="n">tuple_settings</span> <span class="o">=</span> <span class="p">(</span>
<span class="s1">&#39;ALLOWED_HOSTS&#39;</span><span class="p">,</span>
<span class="s2">&quot;INSTALLED_APPS&quot;</span><span class="p">,</span>
<span class="s2">&quot;TEMPLATE_DIRS&quot;</span><span class="p">,</span>
<span class="s2">&quot;LOCALE_PATHS&quot;</span><span class="p">,</span>
@ -224,21 +234,20 @@
<span class="k">if</span> <span class="p">(</span><span class="n">setting</span> <span class="ow">in</span> <span class="n">tuple_settings</span> <span class="ow">and</span>
<span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">setting_value</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))):</span>
<span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span><span class="s2">&quot;The </span><span class="si">%s</span><span class="s2"> setting must be a list or a tuple. &quot;</span> <span class="o">%</span> <span class="n">setting</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span><span class="s2">&quot;The </span><span class="si">%s</span><span class="s2"> setting must be a list or a tuple.&quot;</span> <span class="o">%</span> <span class="n">setting</span><span class="p">)</span>
<span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">setting</span><span class="p">,</span> <span class="n">setting_value</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_explicit_settings</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">setting</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_overridden</span><span class="p">(</span><span class="s1">&#39;PASSWORD_RESET_TIMEOUT_DAYS&#39;</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_overridden</span><span class="p">(</span><span class="s1">&#39;PASSWORD_RESET_TIMEOUT&#39;</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span>
<span class="s1">&#39;PASSWORD_RESET_TIMEOUT_DAYS/PASSWORD_RESET_TIMEOUT are &#39;</span>
<span class="s1">&#39;mutually exclusive.&#39;</span>
<span class="p">)</span>
<span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;PASSWORD_RESET_TIMEOUT&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">PASSWORD_RESET_TIMEOUT_DAYS</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">24</span><span class="p">)</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">PASSWORD_RESET_TIMEOUT_DAYS_DEPRECATED_MSG</span><span class="p">,</span> <span class="n">RemovedInDjango40Warning</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">USE_TZ</span> <span class="ow">is</span> <span class="kc">False</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_overridden</span><span class="p">(</span><span class="s1">&#39;USE_TZ&#39;</span><span class="p">):</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span>
<span class="s1">&#39;The default value of USE_TZ will change from False to True &#39;</span>
<span class="s1">&#39;in Django 5.0. Set USE_TZ to False in your project settings &#39;</span>
<span class="s1">&#39;if you want to keep the current default behavior.&#39;</span><span class="p">,</span>
<span class="n">category</span><span class="o">=</span><span class="n">RemovedInDjango50Warning</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_overridden</span><span class="p">(</span><span class="s1">&#39;DEFAULT_HASHING_ALGORITHM&#39;</span><span class="p">):</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">DEFAULT_HASHING_ALGORITHM_DEPRECATED_MSG</span><span class="p">,</span> <span class="n">RemovedInDjango40Warning</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_overridden</span><span class="p">(</span><span class="s1">&#39;USE_DEPRECATED_PYTZ&#39;</span><span class="p">):</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">USE_DEPRECATED_PYTZ_DEPRECATED_MSG</span><span class="p">,</span> <span class="n">RemovedInDjango50Warning</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">time</span><span class="p">,</span> <span class="s1">&#39;tzset&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">TIME_ZONE</span><span class="p">:</span>
<span class="c1"># When we can, attempt to validate the timezone. If we can&#39;t find</span>
@ -252,6 +261,9 @@
<span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">&#39;TZ&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">TIME_ZONE</span>
<span class="n">time</span><span class="o">.</span><span class="n">tzset</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_overridden</span><span class="p">(</span><span class="s1">&#39;USE_L10N&#39;</span><span class="p">):</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">USE_L10N_DEPRECATED_MSG</span><span class="p">,</span> <span class="n">RemovedInDjango50Warning</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">is_overridden</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">setting</span><span class="p">):</span>
<span class="k">return</span> <span class="n">setting</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_explicit_settings</span>
@ -283,12 +295,11 @@
<span class="k">def</span> <span class="fm">__setattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_deleted</span><span class="o">.</span><span class="n">discard</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s1">&#39;PASSWORD_RESET_TIMEOUT_DAYS&#39;</span><span class="p">:</span>
<span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;PASSWORD_RESET_TIMEOUT&#39;</span><span class="p">,</span> <span class="n">value</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">24</span><span class="p">)</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">PASSWORD_RESET_TIMEOUT_DAYS_DEPRECATED_MSG</span><span class="p">,</span> <span class="n">RemovedInDjango40Warning</span><span class="p">)</span>
<span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s1">&#39;DEFAULT_HASHING_ALGORITHM&#39;</span><span class="p">:</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">DEFAULT_HASHING_ALGORITHM_DEPRECATED_MSG</span><span class="p">,</span> <span class="n">RemovedInDjango40Warning</span><span class="p">)</span>
<span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s1">&#39;USE_L10N&#39;</span><span class="p">:</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">USE_L10N_DEPRECATED_MSG</span><span class="p">,</span> <span class="n">RemovedInDjango50Warning</span><span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__setattr__</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s1">&#39;USE_DEPRECATED_PYTZ&#39;</span><span class="p">:</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">USE_DEPRECATED_PYTZ_DEPRECATED_MSG</span><span class="p">,</span> <span class="n">RemovedInDjango50Warning</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__delattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_deleted</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
@ -348,7 +359,6 @@
<h3>Versions</h3>
<ul>
<li><a href="conf.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -909,18 +909,17 @@
<span class="n">do_not_call_in_templates</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">_build_remove_filters</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">removed_vals</span><span class="p">):</span>
<span class="n">filters</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="bp">self</span><span class="o">.</span><span class="n">source_field_name</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">related_val</span><span class="p">})</span>
<span class="n">filters</span> <span class="o">=</span> <span class="n">Q</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">source_field_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">related_val</span><span class="p">))</span>
<span class="c1"># No need to add a subquery condition if removed_vals is a QuerySet without</span>
<span class="c1"># filters.</span>
<span class="n">removed_vals_filters</span> <span class="o">=</span> <span class="p">(</span><span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">removed_vals</span><span class="p">,</span> <span class="n">QuerySet</span><span class="p">)</span> <span class="ow">or</span>
<span class="n">removed_vals</span><span class="o">.</span><span class="n">_has_filters</span><span class="p">())</span>
<span class="k">if</span> <span class="n">removed_vals_filters</span><span class="p">:</span>
<span class="n">filters</span> <span class="o">&amp;=</span> <span class="n">Q</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="s1">&#39;</span><span class="si">%s</span><span class="s1">__in&#39;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">target_field_name</span><span class="p">:</span> <span class="n">removed_vals</span><span class="p">})</span>
<span class="n">filters</span> <span class="o">&amp;=</span> <span class="n">Q</span><span class="p">((</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">target_field_name</span><span class="si">}</span><span class="s1">__in&#39;</span><span class="p">,</span> <span class="n">removed_vals</span><span class="p">))</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">symmetrical</span><span class="p">:</span>
<span class="n">symmetrical_filters</span> <span class="o">=</span> <span class="n">Q</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="bp">self</span><span class="o">.</span><span class="n">target_field_name</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">related_val</span><span class="p">})</span>
<span class="n">symmetrical_filters</span> <span class="o">=</span> <span class="n">Q</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">target_field_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">related_val</span><span class="p">))</span>
<span class="k">if</span> <span class="n">removed_vals_filters</span><span class="p">:</span>
<span class="n">symmetrical_filters</span> <span class="o">&amp;=</span> <span class="n">Q</span><span class="p">(</span>
<span class="o">**</span><span class="p">{</span><span class="s1">&#39;</span><span class="si">%s</span><span class="s1">__in&#39;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_field_name</span><span class="p">:</span> <span class="n">removed_vals</span><span class="p">})</span>
<span class="n">symmetrical_filters</span> <span class="o">&amp;=</span> <span class="n">Q</span><span class="p">((</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">source_field_name</span><span class="si">}</span><span class="s1">__in&#39;</span><span class="p">,</span> <span class="n">removed_vals</span><span class="p">))</span>
<span class="n">filters</span> <span class="o">|=</span> <span class="n">symmetrical_filters</span>
<span class="k">return</span> <span class="n">filters</span>
@ -1280,7 +1279,6 @@
<h3>Versions</h3>
<ul>
<li><a href="related_descriptors.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -278,7 +278,6 @@
<h3>Versions</h3>
<ul>
<li><a href="manager.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -334,10 +334,14 @@
<span class="s1">&#39;QuerySet indices must be integers or slices, not </span><span class="si">%s</span><span class="s1">.&#39;</span>
<span class="o">%</span> <span class="nb">type</span><span class="p">(</span><span class="n">k</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span>
<span class="p">)</span>
<span class="k">assert</span> <span class="p">((</span><span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="nb">slice</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">k</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">))</span> <span class="ow">or</span>
<span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="nb">slice</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">k</span><span class="o">.</span><span class="n">start</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">k</span><span class="o">.</span><span class="n">start</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">and</span>
<span class="p">(</span><span class="n">k</span><span class="o">.</span><span class="n">stop</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">k</span><span class="o">.</span><span class="n">stop</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">))),</span> \
<span class="s2">&quot;Negative indexing is not supported.&quot;</span>
<span class="k">if</span> <span class="p">(</span>
<span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="nb">int</span><span class="p">)</span> <span class="ow">and</span> <span class="n">k</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">or</span>
<span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="nb">slice</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span>
<span class="p">(</span><span class="n">k</span><span class="o">.</span><span class="n">start</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">k</span><span class="o">.</span><span class="n">start</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">or</span>
<span class="p">(</span><span class="n">k</span><span class="o">.</span><span class="n">stop</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">k</span><span class="o">.</span><span class="n">stop</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">))</span>
<span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Negative indexing is not supported.&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_result_cache</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_result_cache</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
@ -523,7 +527,8 @@
<span class="c1"># PostgreSQL via the RETURNING ID clause. It should be possible for</span>
<span class="c1"># Oracle as well, but the semantics for extracting the primary keys is</span>
<span class="c1"># trickier so it&#39;s not done yet.</span>
<span class="k">assert</span> <span class="n">batch_size</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">batch_size</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="k">if</span> <span class="n">batch_size</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">batch_size</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Batch size must be a positive integer.&#39;</span><span class="p">)</span>
<span class="c1"># Check that the parents share the same concrete model with the our</span>
<span class="c1"># model to detect the inheritance pattern ConcreteGrandParent -&gt;</span>
<span class="c1"># MultiTableParent -&gt; ProxyChild. Simply checking self.model._meta.proxy</span>
@ -584,7 +589,7 @@
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">primary_key</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">fields</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;bulk_update() cannot be used with primary key fields.&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">objs</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="c1"># PK is used twice in the resulting update query, once in the filter</span>
<span class="c1"># and once in the WHEN. Each field will also have one CAST.</span>
<span class="n">max_batch_size</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="p">]</span><span class="o">.</span><span class="n">ops</span><span class="o">.</span><span class="n">bulk_batch_size</span><span class="p">([</span><span class="s1">&#39;pk&#39;</span><span class="p">,</span> <span class="s1">&#39;pk&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">fields</span><span class="p">,</span> <span class="n">objs</span><span class="p">)</span>
@ -606,9 +611,11 @@
<span class="n">case_statement</span> <span class="o">=</span> <span class="n">Cast</span><span class="p">(</span><span class="n">case_statement</span><span class="p">,</span> <span class="n">output_field</span><span class="o">=</span><span class="n">field</span><span class="p">)</span>
<span class="n">update_kwargs</span><span class="p">[</span><span class="n">field</span><span class="o">.</span><span class="n">attname</span><span class="p">]</span> <span class="o">=</span> <span class="n">case_statement</span>
<span class="n">updates</span><span class="o">.</span><span class="n">append</span><span class="p">(([</span><span class="n">obj</span><span class="o">.</span><span class="n">pk</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">batch_objs</span><span class="p">],</span> <span class="n">update_kwargs</span><span class="p">))</span>
<span class="n">rows_updated</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">with</span> <span class="n">transaction</span><span class="o">.</span><span class="n">atomic</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="p">,</span> <span class="n">savepoint</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="k">for</span> <span class="n">pks</span><span class="p">,</span> <span class="n">update_kwargs</span> <span class="ow">in</span> <span class="n">updates</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pk__in</span><span class="o">=</span><span class="n">pks</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="o">**</span><span class="n">update_kwargs</span><span class="p">)</span>
<span class="n">rows_updated</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pk__in</span><span class="o">=</span><span class="n">pks</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="o">**</span><span class="n">update_kwargs</span><span class="p">)</span>
<span class="k">return</span> <span class="n">rows_updated</span>
<span class="n">bulk_update</span><span class="o">.</span><span class="n">alters_data</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">def</span> <span class="nf">get_or_create</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
@ -697,19 +704,20 @@
<span class="s2">&quot;earliest() and latest() require either fields as positional &quot;</span>
<span class="s2">&quot;arguments or &#39;get_latest_by&#39; in the model&#39;s Meta.&quot;</span>
<span class="p">)</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">,</span> \
<span class="s2">&quot;Cannot change a query once a slice has been taken.&quot;</span>
<span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_chain</span><span class="p">()</span>
<span class="n">obj</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">set_limits</span><span class="p">(</span><span class="n">high</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">clear_ordering</span><span class="p">(</span><span class="n">force_empty</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">clear_ordering</span><span class="p">(</span><span class="n">force</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">add_ordering</span><span class="p">(</span><span class="o">*</span><span class="n">order_by</span><span class="p">)</span>
<span class="k">return</span> <span class="n">obj</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">earliest</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">fields</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot change a query once a slice has been taken.&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_earliest</span><span class="p">(</span><span class="o">*</span><span class="n">fields</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">latest</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">fields</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot change a query once a slice has been taken.&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">reverse</span><span class="p">()</span><span class="o">.</span><span class="n">_earliest</span><span class="p">(</span><span class="o">*</span><span class="n">fields</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">first</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
@ -727,8 +735,8 @@
<span class="sd"> Return a dictionary mapping each of the given IDs to the object with</span>
<span class="sd"> that ID. If `id_list` isn&#39;t provided, evaluate the entire QuerySet.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">,</span> \
<span class="s2">&quot;Cannot use &#39;limit&#39; or &#39;offset&#39; with in_bulk&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;Cannot use &#39;limit&#39; or &#39;offset&#39; with in_bulk().&quot;</span><span class="p">)</span>
<span class="n">opts</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span>
<span class="n">unique_fields</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">constraint</span><span class="o">.</span><span class="n">fields</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
@ -764,9 +772,8 @@
<span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Delete the records in the current QuerySet.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_not_support_combined_queries</span><span class="p">(</span><span class="s1">&#39;delete&#39;</span><span class="p">)</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">,</span> \
<span class="s2">&quot;Cannot use &#39;limit&#39; or &#39;offset&#39; with delete.&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;Cannot use &#39;limit&#39; or &#39;offset&#39; with delete().&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">distinct</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">distinct_fields</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot call delete() after .distinct().&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fields</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
@ -782,7 +789,7 @@
<span class="c1"># Disable non-supported fields.</span>
<span class="n">del_query</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">select_for_update</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">del_query</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">select_related</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">del_query</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">clear_ordering</span><span class="p">(</span><span class="n">force_empty</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">del_query</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">clear_ordering</span><span class="p">(</span><span class="n">force</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">collector</span> <span class="o">=</span> <span class="n">Collector</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="n">del_query</span><span class="o">.</span><span class="n">db</span><span class="p">)</span>
<span class="n">collector</span><span class="o">.</span><span class="n">collect</span><span class="p">(</span><span class="n">del_query</span><span class="p">)</span>
@ -815,8 +822,8 @@
<span class="sd"> fields to the appropriate values.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_not_support_combined_queries</span><span class="p">(</span><span class="s1">&#39;update&#39;</span><span class="p">)</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">,</span> \
<span class="s2">&quot;Cannot update a query once a slice has been taken.&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot update a query once a slice has been taken.&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_for_write</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">query</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">sql</span><span class="o">.</span><span class="n">UpdateQuery</span><span class="p">)</span>
<span class="n">query</span><span class="o">.</span><span class="n">add_update_values</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span>
@ -835,8 +842,8 @@
<span class="sd"> code (it requires too much poking around at model internals to be</span>
<span class="sd"> useful at that level).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">,</span> \
<span class="s2">&quot;Cannot update a query once a slice has been taken.&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot update a query once a slice has been taken.&#39;</span><span class="p">)</span>
<span class="n">query</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">sql</span><span class="o">.</span><span class="n">UpdateQuery</span><span class="p">)</span>
<span class="n">query</span><span class="o">.</span><span class="n">add_update_fields</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
<span class="c1"># Clear any annotations so that they won&#39;t be present in subqueries.</span>
@ -851,6 +858,27 @@
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">has_results</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_result_cache</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">contains</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return True if the queryset contains an object.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_not_support_combined_queries</span><span class="p">(</span><span class="s1">&#39;contains&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fields</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
<span class="s1">&#39;Cannot call QuerySet.contains() after .values() or &#39;</span>
<span class="s1">&#39;.values_list().&#39;</span>
<span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">obj</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">concrete_model</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">concrete_model</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;&#39;obj&#39; must be a model instance.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">obj</span><span class="o">.</span><span class="n">pk</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s1">&#39;QuerySet.contains() cannot be used on unsaved objects.&#39;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_result_cache</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">obj</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_result_cache</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="n">obj</span><span class="o">.</span><span class="n">pk</span><span class="p">)</span><span class="o">.</span><span class="n">exists</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">_prefetch_related_objects</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># This method can only be called once the result cache has been filled.</span>
<span class="n">prefetch_related_objects</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_result_cache</span><span class="p">,</span> <span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">_prefetch_related_lookups</span><span class="p">)</span>
@ -920,10 +948,10 @@
<span class="sd"> Return a list of date objects representing all available dates for</span>
<span class="sd"> the given field_name, scoped to &#39;kind&#39;.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">assert</span> <span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;year&#39;</span><span class="p">,</span> <span class="s1">&#39;month&#39;</span><span class="p">,</span> <span class="s1">&#39;week&#39;</span><span class="p">,</span> <span class="s1">&#39;day&#39;</span><span class="p">),</span> \
<span class="s2">&quot;&#39;kind&#39; must be one of &#39;year&#39;, &#39;month&#39;, &#39;week&#39;, or &#39;day&#39;.&quot;</span>
<span class="k">assert</span> <span class="n">order</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;ASC&#39;</span><span class="p">,</span> <span class="s1">&#39;DESC&#39;</span><span class="p">),</span> \
<span class="s2">&quot;&#39;order&#39; must be either &#39;ASC&#39; or &#39;DESC&#39;.&quot;</span>
<span class="k">if</span> <span class="n">kind</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;year&#39;</span><span class="p">,</span> <span class="s1">&#39;month&#39;</span><span class="p">,</span> <span class="s1">&#39;week&#39;</span><span class="p">,</span> <span class="s1">&#39;day&#39;</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;&#39;kind&#39; must be one of &#39;year&#39;, &#39;month&#39;, &#39;week&#39;, or &#39;day&#39;.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">order</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;ASC&#39;</span><span class="p">,</span> <span class="s1">&#39;DESC&#39;</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;&#39;order&#39; must be either &#39;ASC&#39; or &#39;DESC&#39;.&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">annotate</span><span class="p">(</span>
<span class="n">datefield</span><span class="o">=</span><span class="n">Trunc</span><span class="p">(</span><span class="n">field_name</span><span class="p">,</span> <span class="n">kind</span><span class="p">,</span> <span class="n">output_field</span><span class="o">=</span><span class="n">DateField</span><span class="p">()),</span>
<span class="n">plain_field</span><span class="o">=</span><span class="n">F</span><span class="p">(</span><span class="n">field_name</span><span class="p">)</span>
@ -931,15 +959,20 @@
<span class="s1">&#39;datefield&#39;</span><span class="p">,</span> <span class="n">flat</span><span class="o">=</span><span class="kc">True</span>
<span class="p">)</span><span class="o">.</span><span class="n">distinct</span><span class="p">()</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">plain_field__isnull</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span><span class="o">.</span><span class="n">order_by</span><span class="p">((</span><span class="s1">&#39;-&#39;</span> <span class="k">if</span> <span class="n">order</span> <span class="o">==</span> <span class="s1">&#39;DESC&#39;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;datefield&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">datetimes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field_name</span><span class="p">,</span> <span class="n">kind</span><span class="p">,</span> <span class="n">order</span><span class="o">=</span><span class="s1">&#39;ASC&#39;</span><span class="p">,</span> <span class="n">tzinfo</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">is_dst</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="c1"># RemovedInDjango50Warning: when the deprecation ends, remove is_dst</span>
<span class="c1"># argument.</span>
<span class="k">def</span> <span class="nf">datetimes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field_name</span><span class="p">,</span> <span class="n">kind</span><span class="p">,</span> <span class="n">order</span><span class="o">=</span><span class="s1">&#39;ASC&#39;</span><span class="p">,</span> <span class="n">tzinfo</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">is_dst</span><span class="o">=</span><span class="n">timezone</span><span class="o">.</span><span class="n">NOT_PASSED</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return a list of datetime objects representing all available</span>
<span class="sd"> datetimes for the given field_name, scoped to &#39;kind&#39;.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">assert</span> <span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;year&#39;</span><span class="p">,</span> <span class="s1">&#39;month&#39;</span><span class="p">,</span> <span class="s1">&#39;week&#39;</span><span class="p">,</span> <span class="s1">&#39;day&#39;</span><span class="p">,</span> <span class="s1">&#39;hour&#39;</span><span class="p">,</span> <span class="s1">&#39;minute&#39;</span><span class="p">,</span> <span class="s1">&#39;second&#39;</span><span class="p">),</span> \
<span class="s2">&quot;&#39;kind&#39; must be one of &#39;year&#39;, &#39;month&#39;, &#39;week&#39;, &#39;day&#39;, &#39;hour&#39;, &#39;minute&#39;, or &#39;second&#39;.&quot;</span>
<span class="k">assert</span> <span class="n">order</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;ASC&#39;</span><span class="p">,</span> <span class="s1">&#39;DESC&#39;</span><span class="p">),</span> \
<span class="s2">&quot;&#39;order&#39; must be either &#39;ASC&#39; or &#39;DESC&#39;.&quot;</span>
<span class="k">if</span> <span class="n">kind</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;year&#39;</span><span class="p">,</span> <span class="s1">&#39;month&#39;</span><span class="p">,</span> <span class="s1">&#39;week&#39;</span><span class="p">,</span> <span class="s1">&#39;day&#39;</span><span class="p">,</span> <span class="s1">&#39;hour&#39;</span><span class="p">,</span> <span class="s1">&#39;minute&#39;</span><span class="p">,</span> <span class="s1">&#39;second&#39;</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s2">&quot;&#39;kind&#39; must be one of &#39;year&#39;, &#39;month&#39;, &#39;week&#39;, &#39;day&#39;, &quot;</span>
<span class="s2">&quot;&#39;hour&#39;, &#39;minute&#39;, or &#39;second&#39;.&quot;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">order</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;ASC&#39;</span><span class="p">,</span> <span class="s1">&#39;DESC&#39;</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;&#39;order&#39; must be either &#39;ASC&#39; or &#39;DESC&#39;.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">settings</span><span class="o">.</span><span class="n">USE_TZ</span><span class="p">:</span>
<span class="k">if</span> <span class="n">tzinfo</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">tzinfo</span> <span class="o">=</span> <span class="n">timezone</span><span class="o">.</span><span class="n">get_current_timezone</span><span class="p">()</span>
@ -992,10 +1025,8 @@
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_filter_or_exclude</span><span class="p">(</span><span class="kc">True</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_filter_or_exclude</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">negate</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">):</span>
<span class="k">if</span> <span class="n">args</span> <span class="ow">or</span> <span class="n">kwargs</span><span class="p">:</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">,</span> \
<span class="s2">&quot;Cannot filter a query once a slice has been taken.&quot;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">args</span> <span class="ow">or</span> <span class="n">kwargs</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot filter a query once a slice has been taken.&#39;</span><span class="p">)</span>
<span class="n">clone</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_chain</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_defer_next_filter</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_defer_next_filter</span> <span class="o">=</span> <span class="kc">False</span>
@ -1031,7 +1062,7 @@
<span class="c1"># Clone the query to inherit the select list and everything</span>
<span class="n">clone</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_chain</span><span class="p">()</span>
<span class="c1"># Clear limits and ordering so they can be reapplied</span>
<span class="n">clone</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">clear_ordering</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>
<span class="n">clone</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">clear_ordering</span><span class="p">(</span><span class="n">force</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">clone</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">clear_limits</span><span class="p">()</span>
<span class="n">clone</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">combined_queries</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="p">,)</span> <span class="o">+</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">qs</span><span class="o">.</span><span class="n">query</span> <span class="k">for</span> <span class="n">qs</span> <span class="ow">in</span> <span class="n">other_qs</span><span class="p">)</span>
<span class="n">clone</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">combinator</span> <span class="o">=</span> <span class="n">combinator</span>
@ -1185,10 +1216,10 @@
<span class="k">def</span> <span class="nf">order_by</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">field_names</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a new QuerySet instance with the ordering changed.&quot;&quot;&quot;</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">,</span> \
<span class="s2">&quot;Cannot reorder a query once a slice has been taken.&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot reorder a query once a slice has been taken.&#39;</span><span class="p">)</span>
<span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_chain</span><span class="p">()</span>
<span class="n">obj</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">clear_ordering</span><span class="p">(</span><span class="n">force_empty</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">clear_ordering</span><span class="p">(</span><span class="n">force</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">clear_default</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">add_ordering</span><span class="p">(</span><span class="o">*</span><span class="n">field_names</span><span class="p">)</span>
<span class="k">return</span> <span class="n">obj</span>
@ -1197,8 +1228,8 @@
<span class="sd"> Return a new QuerySet instance that will select only distinct results.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_not_support_combined_queries</span><span class="p">(</span><span class="s1">&#39;distinct&#39;</span><span class="p">)</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">,</span> \
<span class="s2">&quot;Cannot create distinct fields once a slice has been taken.&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot create distinct fields once a slice has been taken.&#39;</span><span class="p">)</span>
<span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_chain</span><span class="p">()</span>
<span class="n">obj</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">add_distinct_fields</span><span class="p">(</span><span class="o">*</span><span class="n">field_names</span><span class="p">)</span>
<span class="k">return</span> <span class="n">obj</span>
@ -1207,8 +1238,8 @@
<span class="n">order_by</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">select_params</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Add extra SQL fragments to the query.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_not_support_combined_queries</span><span class="p">(</span><span class="s1">&#39;extra&#39;</span><span class="p">)</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">,</span> \
<span class="s2">&quot;Cannot change a query once a slice has been taken&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">is_sliced</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot change a query once a slice has been taken.&#39;</span><span class="p">)</span>
<span class="n">clone</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_chain</span><span class="p">()</span>
<span class="n">clone</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">add_extra</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">select_params</span><span class="p">,</span> <span class="n">where</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">tables</span><span class="p">,</span> <span class="n">order_by</span><span class="p">)</span>
<span class="k">return</span> <span class="n">clone</span>
@ -1336,7 +1367,7 @@
<span class="bp">self</span><span class="o">.</span><span class="n">_insert</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">fields</span><span class="o">=</span><span class="n">fields</span><span class="p">,</span> <span class="n">using</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="p">,</span> <span class="n">ignore_conflicts</span><span class="o">=</span><span class="n">ignore_conflicts</span><span class="p">)</span>
<span class="k">return</span> <span class="n">inserted_rows</span>
<span class="k">def</span> <span class="nf">_chain</span><span class="p">(</span><span class="bp">self</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="nf">_chain</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return a copy of the current QuerySet that&#39;s ready for another</span>
<span class="sd"> operation.</span>
@ -1345,7 +1376,6 @@
<span class="k">if</span> <span class="n">obj</span><span class="o">.</span><span class="n">_sticky_filter</span><span class="p">:</span>
<span class="n">obj</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">filter_is_sticky</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">obj</span><span class="o">.</span><span class="n">_sticky_filter</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">obj</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">return</span> <span class="n">obj</span>
<span class="k">def</span> <span class="nf">_clone</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
@ -1636,11 +1666,11 @@
<span class="k">def</span> <span class="nf">__getstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">obj_dict</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">queryset</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">queryset</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">queryset</span><span class="o">.</span><span class="n">_chain</span><span class="p">()</span>
<span class="c1"># Prevent the QuerySet from being evaluated</span>
<span class="n">obj_dict</span><span class="p">[</span><span class="s1">&#39;queryset&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">queryset</span><span class="o">.</span><span class="n">_chain</span><span class="p">(</span>
<span class="n">_result_cache</span><span class="o">=</span><span class="p">[],</span>
<span class="n">_prefetch_done</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">queryset</span><span class="o">.</span><span class="n">_result_cache</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">queryset</span><span class="o">.</span><span class="n">_prefetch_done</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">obj_dict</span><span class="p">[</span><span class="s1">&#39;queryset&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">queryset</span>
<span class="k">return</span> <span class="n">obj_dict</span>
<span class="k">def</span> <span class="nf">add_prefix</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">prefix</span><span class="p">):</span>
@ -2089,7 +2119,6 @@
<h3>Versions</h3>
<ul>
<li><a href="query.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -51,13 +51,11 @@
<span class="kn">import</span> <span class="nn">copy</span>
<span class="kn">import</span> <span class="nn">functools</span>
<span class="kn">import</span> <span class="nn">inspect</span>
<span class="kn">import</span> <span class="nn">warnings</span>
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">namedtuple</span>
<span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="n">FieldDoesNotExist</span><span class="p">,</span> <span class="n">FieldError</span>
<span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="n">FieldError</span>
<span class="kn">from</span> <span class="nn">django.db.models.constants</span> <span class="kn">import</span> <span class="n">LOOKUP_SEP</span>
<span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">tree</span>
<span class="kn">from</span> <span class="nn">django.utils.deprecation</span> <span class="kn">import</span> <span class="n">RemovedInDjango40Warning</span>
<span class="c1"># PathInfo is used when converting lookups (fk__somecol). The contents</span>
<span class="c1"># describe the relation in Model terms (model Options and Fields for both</span>
@ -65,32 +63,6 @@
<span class="n">PathInfo</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">&#39;PathInfo&#39;</span><span class="p">,</span> <span class="s1">&#39;from_opts to_opts target_fields join_field m2m direct filtered_relation&#39;</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">InvalidQueryType</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">_subclasses</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="n">FieldDoesNotExist</span><span class="p">,</span> <span class="n">FieldError</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__warn</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span>
<span class="s1">&#39;The InvalidQuery exception class is deprecated. Use &#39;</span>
<span class="s1">&#39;FieldDoesNotExist or FieldError instead.&#39;</span><span class="p">,</span>
<span class="n">category</span><span class="o">=</span><span class="n">RemovedInDjango40Warning</span><span class="p">,</span>
<span class="n">stacklevel</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">def</span> <span class="fm">__instancecheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__warn</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_subclasses</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__instancecheck__</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
<span class="k">def</span> <span class="fm">__subclasscheck__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subclass</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__warn</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">subclass</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_subclasses</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__subclasscheck__</span><span class="p">(</span><span class="n">subclass</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">InvalidQuery</span><span class="p">(</span><span class="ne">Exception</span><span class="p">,</span> <span class="n">metaclass</span><span class="o">=</span><span class="n">InvalidQueryType</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">def</span> <span class="nf">subclasses</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
<span class="k">yield</span> <span class="bp">cls</span>
<span class="k">for</span> <span class="n">subclass</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__subclasses__</span><span class="p">():</span>
@ -421,7 +393,6 @@
<h3>Versions</h3>
<ul>
<li><a href="query_utils.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1,160 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>django.utils.deconstruct &#8212; Evennia 1.0-dev 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 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" accesskey="U">Module code</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">django.utils.deconstruct</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for django.utils.deconstruct</h1><div class="highlight"><pre>
<span></span><span class="kn">from</span> <span class="nn">importlib</span> <span class="kn">import</span> <span class="n">import_module</span>
<span class="kn">from</span> <span class="nn">django.utils.version</span> <span class="kn">import</span> <span class="n">get_docs_version</span>
<span class="k">def</span> <span class="nf">deconstructible</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Class decorator that allows the decorated class to be serialized</span>
<span class="sd"> by the migrations subsystem.</span>
<span class="sd"> The `path` kwarg specifies the import path.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">decorator</span><span class="p">(</span><span class="n">klass</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="c1"># We capture the arguments to make returning them trivial</span>
<span class="n">obj</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">_constructor_args</span> <span class="o">=</span> <span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span>
<span class="k">return</span> <span class="n">obj</span>
<span class="k">def</span> <span class="nf">deconstruct</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return a 3-tuple of class import path, positional arguments,</span>
<span class="sd"> and keyword arguments.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Fallback version</span>
<span class="k">if</span> <span class="n">path</span><span class="p">:</span>
<span class="n">module_name</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">rpartition</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">module_name</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__module__</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span>
<span class="c1"># Make sure it&#39;s actually there and not an inner class</span>
<span class="n">module</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">module_name</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s2">&quot;Could not find object </span><span class="si">%s</span><span class="s2"> in </span><span class="si">%s</span><span class="s2">.</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;Please note that you cannot serialize things like inner &quot;</span>
<span class="s2">&quot;classes. Please move the object into the main module &quot;</span>
<span class="s2">&quot;body to use migrations.</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;For more information, see &quot;</span>
<span class="s2">&quot;https://docs.djangoproject.com/en/</span><span class="si">%s</span><span class="s2">/topics/migrations/#serializing-values&quot;</span>
<span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">module_name</span><span class="p">,</span> <span class="n">get_docs_version</span><span class="p">()))</span>
<span class="k">return</span> <span class="p">(</span>
<span class="n">path</span> <span class="ow">or</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">.</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__module__</span><span class="p">,</span> <span class="n">name</span><span class="p">),</span>
<span class="n">obj</span><span class="o">.</span><span class="n">_constructor_args</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
<span class="n">obj</span><span class="o">.</span><span class="n">_constructor_args</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
<span class="p">)</span>
<span class="n">klass</span><span class="o">.</span><span class="fm">__new__</span> <span class="o">=</span> <span class="nb">staticmethod</span><span class="p">(</span><span class="fm">__new__</span><span class="p">)</span>
<span class="n">klass</span><span class="o">.</span><span class="n">deconstruct</span> <span class="o">=</span> <span class="n">deconstruct</span>
<span class="k">return</span> <span class="n">klass</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="n">decorator</span>
<span class="k">return</span> <span class="n">decorator</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
</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="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="deconstruct.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (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 1.0-dev</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-this"><a href="">django.utils.deconstruct</a></li>
</ul>
<div class="develop">develop branch</div>
</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>

View file

@ -162,8 +162,10 @@
<span class="nb">setattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">method_name</span><span class="p">,</span> <span class="n">meth</span><span class="p">)</span>
<span class="bp">cls</span><span class="o">.</span><span class="n">_delegate_bytes</span> <span class="o">=</span> <span class="nb">bytes</span> <span class="ow">in</span> <span class="n">resultclasses</span>
<span class="bp">cls</span><span class="o">.</span><span class="n">_delegate_text</span> <span class="o">=</span> <span class="nb">str</span> <span class="ow">in</span> <span class="n">resultclasses</span>
<span class="k">assert</span> <span class="ow">not</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_delegate_bytes</span> <span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_delegate_text</span><span class="p">),</span> <span class="p">(</span>
<span class="s2">&quot;Cannot call lazy() with both bytes and text return types.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_delegate_bytes</span> <span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_delegate_text</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s1">&#39;Cannot call lazy() with both bytes and text return types.&#39;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_delegate_text</span><span class="p">:</span>
<span class="bp">cls</span><span class="o">.</span><span class="fm">__str__</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__text_cast</span>
<span class="k">elif</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_delegate_bytes</span><span class="p">:</span>
@ -498,7 +500,6 @@
<h3>Versions</h3>
<ul>
<li><a href="functional.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -507,7 +507,6 @@
<h3>Versions</h3>
<ul>
<li><a href="evennia.html">1.0-dev (develop branch)</a></li>
<li><a href="../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1883,7 +1883,6 @@
<h3>Versions</h3>
<ul>
<li><a href="accounts.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -656,7 +656,6 @@
<h3>Versions</h3>
<ul>
<li><a href="bots.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -373,7 +373,6 @@
<h3>Versions</h3>
<ul>
<li><a href="manager.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -258,7 +258,6 @@
<h3>Versions</h3>
<ul>
<li><a href="models.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -856,7 +856,6 @@
<h3>Versions</h3>
<ul>
<li><a href="cmdhandler.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -302,7 +302,6 @@
<h3>Versions</h3>
<ul>
<li><a href="cmdparser.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -752,7 +752,6 @@
<h3>Versions</h3>
<ul>
<li><a href="cmdset.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -742,7 +742,6 @@
<h3>Versions</h3>
<ul>
<li><a href="cmdsethandler.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -820,7 +820,6 @@
<h3>Versions</h3>
<ul>
<li><a href="command.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1131,7 +1131,6 @@
<h3>Versions</h3>
<ul>
<li><a href="account.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -681,7 +681,6 @@
<h3>Versions</h3>
<ul>
<li><a href="admin.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -897,7 +897,6 @@
<h3>Versions</h3>
<ul>
<li><a href="batchprocess.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -2616,15 +2616,16 @@
<span class="k">if</span> <span class="n">value</span><span class="p">:</span>
<span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">string</span><span class="si">}</span><span class="s2">: T&quot;</span>
<span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">string</span><span class="si">}</span><span class="s2">: F&quot;</span>
<span class="k">return</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="n">txt</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">_truefalse</span><span class="p">(</span><span class="n">opt</span><span class="p">,</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">cmdset</span><span class="p">,</span> <span class="n">opt</span><span class="p">))</span>
<span class="k">for</span> <span class="n">opt</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;no_exits&quot;</span><span class="p">,</span> <span class="s2">&quot;no_objs&quot;</span><span class="p">,</span> <span class="s2">&quot;no_channels&quot;</span><span class="p">,</span> <span class="s2">&quot;duplicates&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">cmdset</span><span class="p">,</span> <span class="n">opt</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
<span class="p">)</span></div>
<span class="p">)</span>
<span class="k">return</span> <span class="s2">&quot;, &quot;</span> <span class="o">+</span> <span class="n">txt</span> <span class="k">if</span> <span class="n">txt</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span></div>
<div class="viewcode-block" id="CmdExamine.format_single_cmdset"><a class="viewcode-back" href="../../../../api/evennia.commands.default.building.html#evennia.commands.default.building.CmdExamine.format_single_cmdset">[docs]</a> <span class="k">def</span> <span class="nf">format_single_cmdset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cmdset</span><span class="p">):</span>
<span class="n">options</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">format_single_cmdset_options</span><span class="p">(</span><span class="n">cmdset</span><span class="p">)</span>
<span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">cmdset</span><span class="o">.</span><span class="n">path</span><span class="si">}</span><span class="s2"> [</span><span class="si">{</span><span class="n">cmdset</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">] (</span><span class="si">{</span><span class="n">cmdset</span><span class="o">.</span><span class="n">mergetype</span><span class="si">}</span><span class="s2">, prio </span><span class="si">{</span><span class="n">cmdset</span><span class="o">.</span><span class="n">priority</span><span class="si">}{</span><span class="n">options</span><span class="si">}</span><span class="s2">&quot;</span></div>
<span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">cmdset</span><span class="o">.</span><span class="n">path</span><span class="si">}</span><span class="s2"> [</span><span class="si">{</span><span class="n">cmdset</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">] (</span><span class="si">{</span><span class="n">cmdset</span><span class="o">.</span><span class="n">mergetype</span><span class="si">}</span><span class="s2">, prio </span><span class="si">{</span><span class="n">cmdset</span><span class="o">.</span><span class="n">priority</span><span class="si">}{</span><span class="n">options</span><span class="si">}</span><span class="s2">)&quot;</span></div>
<div class="viewcode-block" id="CmdExamine.format_stored_cmdsets"><a class="viewcode-back" href="../../../../api/evennia.commands.default.building.html#evennia.commands.default.building.CmdExamine.format_stored_cmdsets">[docs]</a> <span class="k">def</span> <span class="nf">format_stored_cmdsets</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s2">&quot;cmdset&quot;</span><span class="p">):</span>
@ -4377,7 +4378,6 @@
<h3>Versions</h3>
<ul>
<li><a href="building.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -153,7 +153,6 @@
<h3>Versions</h3>
<ul>
<li><a href="cmdset_account.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -168,7 +168,6 @@
<h3>Versions</h3>
<ul>
<li><a href="cmdset_character.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -94,7 +94,6 @@
<h3>Versions</h3>
<ul>
<li><a href="cmdset_session.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -103,7 +103,6 @@
<h3>Versions</h3>
<ul>
<li><a href="cmdset_unloggedin.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1940,7 +1940,6 @@
<h3>Versions</h3>
<ul>
<li><a href="comms.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -815,7 +815,6 @@
<h3>Versions</h3>
<ul>
<li><a href="general.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1057,7 +1057,6 @@
<h3>Versions</h3>
<ul>
<li><a href="help.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -346,7 +346,6 @@
<h3>Versions</h3>
<ul>
<li><a href="muxcommand.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -181,7 +181,6 @@
<h3>Versions</h3>
<ul>
<li><a href="syscommands.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1231,7 +1231,6 @@
<h3>Versions</h3>
<ul>
<li><a href="system.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -2093,7 +2093,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -590,7 +590,6 @@
<h3>Versions</h3>
<ul>
<li><a href="unloggedin.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -931,7 +931,6 @@
<h3>Versions</h3>
<ul>
<li><a href="comms.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -580,7 +580,6 @@
<h3>Versions</h3>
<ul>
<li><a href="managers.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -789,7 +789,6 @@
<h3>Versions</h3>
<ul>
<li><a href="models.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1,970 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.contrib.base_systems.awsstorage.aws_s3_cdn &#8212; Evennia 1.0-dev 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 1.0-dev</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.base_systems.awsstorage.aws_s3_cdn</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.contrib.base_systems.awsstorage.aws_s3_cdn</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">AWS Storage System</span>
<span class="sd">The Right Honourable Reverend (trhr) 2020</span>
<span class="sd">ABOUT THIS PLUGIN:</span>
<span class="sd">This plugin migrates the Web-based portion of Evennia, namely images,</span>
<span class="sd">javascript, and other items located inside staticfiles into Amazon AWS (S3) for hosting.</span>
<span class="sd">Files hosted on S3 are &quot;in the cloud,&quot; and while your personal</span>
<span class="sd">server may be sufficient for serving multimedia to a minimal number of users,</span>
<span class="sd">the perfect use case for this plugin would be:</span>
<span class="sd">1) Servers supporting heavy web-based traffic (webclient, etc)</span>
<span class="sd">2) With a sizable number of users</span>
<span class="sd">3) Where the users are globally distributed</span>
<span class="sd">4) Where multimedia files are served to users as a part of gameplay</span>
<span class="sd">Bottom line - if you&#39;re sending an image to a player every time they traverse a</span>
<span class="sd">map, the bandwidth reduction will be substantial. If not, probably skip</span>
<span class="sd">this one.</span>
<span class="sd">Note that storing and serving files via S3 is not technically free outside of</span>
<span class="sd">Amazon&#39;s &quot;free tier&quot; offering, which you may or may not be eligible for;</span>
<span class="sd">evennia&#39;s base install currently requires 1.5MB of storage space on S3,</span>
<span class="sd">making the current total cost to install this plugin ~$0.0005 per year. If</span>
<span class="sd">you have substantial media assets and intend to serve them to many users,</span>
<span class="sd">caveat emptor on a total cost of ownership - check AWS&#39;s pricing structure.</span>
<span class="sd">See the ./README.md file for details and install instructions.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">ImproperlyConfigured</span><span class="p">,</span>
<span class="n">SuspiciousOperation</span><span class="p">,</span>
<span class="n">SuspiciousFileOperation</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span> <span class="k">as</span> <span class="n">ev_settings</span>
<span class="k">if</span> <span class="p">(</span>
<span class="ow">not</span> <span class="n">ev_settings</span><span class="o">.</span><span class="n">AWS_ACCESS_KEY_ID</span>
<span class="ow">or</span> <span class="ow">not</span> <span class="n">ev_settings</span><span class="o">.</span><span class="n">AWS_SECRET_ACCESS_KEY</span>
<span class="ow">or</span> <span class="ow">not</span> <span class="n">ev_settings</span><span class="o">.</span><span class="n">AWS_STORAGE_BUCKET_NAME</span>
<span class="ow">or</span> <span class="ow">not</span> <span class="n">ev_settings</span><span class="o">.</span><span class="n">AWS_S3_REGION_NAME</span>
<span class="p">):</span>
<span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span>
<span class="p">(</span>
<span class="s2">&quot;You must add AWS-specific settings&quot;</span>
<span class="s2">&quot;to mygame/server/conf/secret_settings.py to use this plugin.&quot;</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">if</span> <span class="s2">&quot;mygame-evennia&quot;</span> <span class="o">==</span> <span class="n">ev_settings</span><span class="o">.</span><span class="n">AWS_STORAGE_BUCKET_NAME</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span>
<span class="p">(</span>
<span class="s2">&quot;You must customize your AWS_STORAGE_BUCKET_NAME&quot;</span>
<span class="s2">&quot;in mygame/server/conf/secret_settings.py;&quot;</span>
<span class="s2">&quot;it must be unique among ALL other S3 users&quot;</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">io</span>
<span class="kn">import</span> <span class="nn">mimetypes</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">posixpath</span>
<span class="kn">import</span> <span class="nn">threading</span>
<span class="kn">from</span> <span class="nn">gzip</span> <span class="kn">import</span> <span class="n">GzipFile</span>
<span class="kn">from</span> <span class="nn">tempfile</span> <span class="kn">import</span> <span class="n">SpooledTemporaryFile</span>
<span class="kn">from</span> <span class="nn">django.core.files.base</span> <span class="kn">import</span> <span class="n">File</span>
<span class="kn">from</span> <span class="nn">django.core.files.storage</span> <span class="kn">import</span> <span class="n">Storage</span>
<span class="kn">from</span> <span class="nn">django.utils.deconstruct</span> <span class="kn">import</span> <span class="n">deconstructible</span>
<span class="kn">from</span> <span class="nn">django.utils.encoding</span> <span class="kn">import</span> <span class="n">filepath_to_uri</span><span class="p">,</span> <span class="n">force_bytes</span><span class="p">,</span> <span class="n">force_text</span><span class="p">,</span> <span class="n">smart_text</span>
<span class="kn">from</span> <span class="nn">django.utils.timezone</span> <span class="kn">import</span> <span class="n">is_naive</span><span class="p">,</span> <span class="n">make_naive</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">django.utils.six.moves.urllib</span> <span class="kn">import</span> <span class="n">parse</span> <span class="k">as</span> <span class="n">urlparse</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">urllib</span> <span class="kn">import</span> <span class="n">parse</span> <span class="k">as</span> <span class="n">urlparse</span>
<span class="k">try</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">boto3.session</span>
<span class="kn">from</span> <span class="nn">boto3</span> <span class="kn">import</span> <span class="n">__version__</span> <span class="k">as</span> <span class="n">boto3_version</span>
<span class="kn">from</span> <span class="nn">botocore.client</span> <span class="kn">import</span> <span class="n">Config</span>
<span class="kn">from</span> <span class="nn">botocore.exceptions</span> <span class="kn">import</span> <span class="n">ClientError</span>
<span class="k">except</span> <span class="ne">ImportError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span><span class="s2">&quot;Couldn&#39;t load S3 bindings. </span><span class="si">%s</span><span class="s2"> Did you run &#39;pip install boto3?&#39;&quot;</span> <span class="o">%</span> <span class="n">e</span><span class="p">)</span>
<span class="n">boto3_version_info</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">([</span><span class="nb">int</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">boto3_version</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;.&quot;</span><span class="p">)])</span>
<div class="viewcode-block" id="setting"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.setting">[docs]</a><span class="k">def</span> <span class="nf">setting</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper function to get a Django setting by name. If setting doesn&#39;t exist</span>
<span class="sd"> it will return a default.</span>
<span class="sd"> Args:</span>
<span class="sd"> name (str): A Django setting name</span>
<span class="sd"> Returns:</span>
<span class="sd"> The value of the setting variable by that name</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">ev_settings</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">default</span><span class="p">)</span></div>
<div class="viewcode-block" id="safe_join"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.safe_join">[docs]</a><span class="k">def</span> <span class="nf">safe_join</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="o">*</span><span class="n">paths</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper function, a version of django.utils._os.safe_join for S3 paths.</span>
<span class="sd"> Joins one or more path components to the base path component</span>
<span class="sd"> intelligently. Returns a normalized version of the final path.</span>
<span class="sd"> The final path must be located inside of the base path component</span>
<span class="sd"> (otherwise a ValueError is raised). Paths outside the base path</span>
<span class="sd"> indicate a possible security sensitive operation.</span>
<span class="sd"> Args:</span>
<span class="sd"> base (str): A path string to the base of the staticfiles</span>
<span class="sd"> *paths (list): A list of paths as referenced from the base path</span>
<span class="sd"> Returns:</span>
<span class="sd"> final_path (str): A joined path, base + filepath</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">base_path</span> <span class="o">=</span> <span class="n">force_text</span><span class="p">(</span><span class="n">base</span><span class="p">)</span>
<span class="n">base_path</span> <span class="o">=</span> <span class="n">base_path</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span>
<span class="n">paths</span> <span class="o">=</span> <span class="p">[</span><span class="n">force_text</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">paths</span><span class="p">]</span>
<span class="n">final_path</span> <span class="o">=</span> <span class="n">base_path</span> <span class="o">+</span> <span class="s2">&quot;/&quot;</span>
<span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">paths</span><span class="p">:</span>
<span class="n">_final_path</span> <span class="o">=</span> <span class="n">posixpath</span><span class="o">.</span><span class="n">normpath</span><span class="p">(</span><span class="n">posixpath</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">final_path</span><span class="p">,</span> <span class="n">path</span><span class="p">))</span>
<span class="c1"># posixpath.normpath() strips the trailing /. Add it back.</span>
<span class="k">if</span> <span class="n">path</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_final_path</span> <span class="o">+</span> <span class="s2">&quot;/&quot;</span> <span class="o">==</span> <span class="n">final_path</span><span class="p">:</span>
<span class="n">_final_path</span> <span class="o">+=</span> <span class="s2">&quot;/&quot;</span>
<span class="n">final_path</span> <span class="o">=</span> <span class="n">_final_path</span>
<span class="k">if</span> <span class="n">final_path</span> <span class="o">==</span> <span class="n">base_path</span><span class="p">:</span>
<span class="n">final_path</span> <span class="o">+=</span> <span class="s2">&quot;/&quot;</span>
<span class="c1"># Ensure final_path starts with base_path and that the next character after</span>
<span class="c1"># the base path is /.</span>
<span class="n">base_path_len</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">base_path</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">final_path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">base_path</span><span class="p">)</span> <span class="ow">or</span> <span class="n">final_path</span><span class="p">[</span><span class="n">base_path_len</span><span class="p">]</span> <span class="o">!=</span> <span class="s2">&quot;/&quot;</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;the joined path is located outside of the base path&quot;</span> <span class="s2">&quot; component&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">final_path</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="check_location"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.check_location">[docs]</a><span class="k">def</span> <span class="nf">check_location</span><span class="p">(</span><span class="n">storage</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper function to make sure that the storage location is configured correctly.</span>
<span class="sd"> Args:</span>
<span class="sd"> storage (Storage): A Storage object (Django)</span>
<span class="sd"> Raises:</span>
<span class="sd"> ImproperlyConfigured: If the storage location is not configured correctly,</span>
<span class="sd"> this is raised.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">storage</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">):</span>
<span class="n">correct</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span>
<span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.location cannot begin with a leading slash. Found &#39;</span><span class="si">{}</span><span class="s2">&#39;. Use &#39;</span><span class="si">{}</span><span class="s2">&#39; instead.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">storage</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">storage</span><span class="o">.</span><span class="n">location</span><span class="p">,</span> <span class="n">correct</span><span class="p">,</span>
<span class="p">)</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="lookup_env"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.lookup_env">[docs]</a><span class="k">def</span> <span class="nf">lookup_env</span><span class="p">(</span><span class="n">names</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper function for looking up names in env vars. Returns the first element found.</span>
<span class="sd"> Args:</span>
<span class="sd"> names (str): A list of environment variables</span>
<span class="sd"> Returns:</span>
<span class="sd"> value (str): The value of the found environment variable.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">names</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">if</span> <span class="n">value</span><span class="p">:</span>
<span class="k">return</span> <span class="n">value</span></div>
<div class="viewcode-block" id="get_available_overwrite_name"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.get_available_overwrite_name">[docs]</a><span class="k">def</span> <span class="nf">get_available_overwrite_name</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">max_length</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper function indicating files that will be overwritten during trunc.</span>
<span class="sd"> Args:</span>
<span class="sd"> name (str): The name of the file</span>
<span class="sd"> max_length (int): The maximum length of a filename</span>
<span class="sd"> Returns:</span>
<span class="sd"> joined (path): A joined path including directory, file, and extension</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">max_length</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="n">max_length</span><span class="p">:</span>
<span class="k">return</span> <span class="n">name</span>
<span class="c1"># Adapted from Django</span>
<span class="n">dir_name</span><span class="p">,</span> <span class="n">file_name</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">file_root</span><span class="p">,</span> <span class="n">file_ext</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">file_name</span><span class="p">)</span>
<span class="n">truncation</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">-</span> <span class="n">max_length</span>
<span class="n">file_root</span> <span class="o">=</span> <span class="n">file_root</span><span class="p">[:</span><span class="o">-</span><span class="n">truncation</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">file_root</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">SuspiciousFileOperation</span><span class="p">(</span>
<span class="s1">&#39;aws-s3-cdn tried to truncate away entire filename &quot;</span><span class="si">%s</span><span class="s1">&quot;. &#39;</span>
<span class="s2">&quot;Please make sure that the corresponding file field &quot;</span>
<span class="s1">&#39;allows sufficient &quot;max_length&quot;.&#39;</span> <span class="o">%</span> <span class="n">name</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">dir_name</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{}{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">file_root</span><span class="p">,</span> <span class="n">file_ext</span><span class="p">))</span></div>
<div class="viewcode-block" id="S3Boto3StorageFile"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3StorageFile">[docs]</a><span class="nd">@deconstructible</span>
<span class="k">class</span> <span class="nc">S3Boto3StorageFile</span><span class="p">(</span><span class="n">File</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> The default file object used by the S3Boto3Storage backend.</span>
<span class="sd"> This file implements file streaming using boto&#39;s multipart</span>
<span class="sd"> uploading functionality. The file can be opened in read or</span>
<span class="sd"> write mode.</span>
<span class="sd"> This class extends Django&#39;s File class. However, the contained</span>
<span class="sd"> data is only the data contained in the current buffer. So you</span>
<span class="sd"> should not access the contained file object directly. You should</span>
<span class="sd"> access the data via this class.</span>
<span class="sd"> Warning: This file *must* be closed using the close() method in</span>
<span class="sd"> order to properly write the file to S3. Be sure to close the file</span>
<span class="sd"> in your application.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">buffer_size</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_FILE_BUFFER_SIZE&quot;</span><span class="p">,</span> <span class="mi">5242880</span><span class="p">)</span>
<div class="viewcode-block" id="S3Boto3StorageFile.__init__"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3StorageFile.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="n">storage</span><span class="p">,</span> <span class="n">buffer_size</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Initializes the File object.</span>
<span class="sd"> Args:</span>
<span class="sd"> name (str): The name of the file</span>
<span class="sd"> mode (str): The access mode (&#39;r&#39; or &#39;w&#39;)</span>
<span class="sd"> storage (Storage): The Django Storage object</span>
<span class="sd"> buffer_size (int): The buffer size, for multipart uploads</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="s2">&quot;r&quot;</span> <span class="ow">in</span> <span class="n">mode</span> <span class="ow">and</span> <span class="s2">&quot;w&quot;</span> <span class="ow">in</span> <span class="n">mode</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Can&#39;t combine &#39;r&#39; and &#39;w&#39; in mode.&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_storage</span> <span class="o">=</span> <span class="n">storage</span>
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</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">_storage</span><span class="o">.</span><span class="n">location</span><span class="p">)</span> <span class="p">:]</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_mode</span> <span class="o">=</span> <span class="n">mode</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_force_mode</span> <span class="o">=</span> <span class="p">(</span><span class="k">lambda</span> <span class="n">b</span><span class="p">:</span> <span class="n">b</span><span class="p">)</span> <span class="k">if</span> <span class="s2">&quot;b&quot;</span> <span class="ow">in</span> <span class="n">mode</span> <span class="k">else</span> <span class="n">force_text</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="n">bucket</span><span class="o">.</span><span class="n">Object</span><span class="p">(</span><span class="n">storage</span><span class="o">.</span><span class="n">_encode_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="k">if</span> <span class="s2">&quot;w&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">mode</span><span class="p">:</span>
<span class="c1"># Force early RAII-style exception if object does not exist</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_is_dirty</span> <span class="o">=</span> <span class="kc">False</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_raw_bytes_written</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_multipart</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># 5 MB is the minimum part size (if there is more than one part).</span>
<span class="c1"># Amazon allows up to 10,000 parts. The default supports uploads</span>
<span class="c1"># up to roughly 50 GB. Increase the part size to accommodate</span>
<span class="c1"># for files larger than this.</span>
<span class="k">if</span> <span class="n">buffer_size</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">buffer_size</span> <span class="o">=</span> <span class="n">buffer_size</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_write_counter</span> <span class="o">=</span> <span class="mi">0</span></div>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">size</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper property to return filesize</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">content_length</span>
<span class="k">def</span> <span class="nf">_get_file</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper function to manage zipping and temporary files</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="o">=</span> <span class="n">SpooledTemporaryFile</span><span class="p">(</span>
<span class="n">max_size</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_storage</span><span class="o">.</span><span class="n">max_memory_size</span><span class="p">,</span>
<span class="n">suffix</span><span class="o">=</span><span class="s2">&quot;.S3Boto3StorageFile&quot;</span><span class="p">,</span>
<span class="nb">dir</span><span class="o">=</span><span class="n">setting</span><span class="p">(</span><span class="s2">&quot;FILE_UPLOAD_TEMP_DIR&quot;</span><span class="p">),</span>
<span class="p">)</span>
<span class="k">if</span> <span class="s2">&quot;r&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mode</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_is_dirty</span> <span class="o">=</span> <span class="kc">False</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">download_fileobj</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_file</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_file</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_storage</span><span class="o">.</span><span class="n">gzip</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">content_encoding</span> <span class="o">==</span> <span class="s2">&quot;gzip&quot;</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="o">=</span> <span class="n">GzipFile</span><span class="p">(</span><span class="n">mode</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_mode</span><span class="p">,</span> <span class="n">fileobj</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_file</span><span class="p">,</span> <span class="n">mtime</span><span class="o">=</span><span class="mf">0.0</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_file</span>
<span class="k">def</span> <span class="nf">_set_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="o">=</span> <span class="n">value</span>
<span class="n">file</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_get_file</span><span class="p">,</span> <span class="n">_set_file</span><span class="p">)</span>
<div class="viewcode-block" id="S3Boto3StorageFile.read"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3StorageFile.read">[docs]</a> <span class="k">def</span> <span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Checks if file is in read mode; then continues to boto3 operation</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="s2">&quot;r&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mode</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="s2">&quot;File was not opened in read mode.&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_force_mode</span><span class="p">(</span><span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">))</span></div>
<div class="viewcode-block" id="S3Boto3StorageFile.readline"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3StorageFile.readline">[docs]</a> <span class="k">def</span> <span class="nf">readline</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Checks if file is in read mode; then continues to boto3 operation</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="s2">&quot;r&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mode</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="s2">&quot;File was not opened in read mode.&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_force_mode</span><span class="p">(</span><span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">readline</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">))</span></div>
<div class="viewcode-block" id="S3Boto3StorageFile.write"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3StorageFile.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Checks if file is in write mode or needs multipart handling,</span>
<span class="sd"> then continues to boto3 operation.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="s2">&quot;w&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mode</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="s2">&quot;File was not opened in write mode.&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_is_dirty</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_multipart</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_multipart</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">initiate_multipart_upload</span><span class="p">(</span>
<span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">_storage</span><span class="o">.</span><span class="n">_get_write_parameters</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
<span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">buffer_size</span> <span class="o">&lt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer_file_size</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_flush_write_buffer</span><span class="p">()</span>
<span class="n">bstr</span> <span class="o">=</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_raw_bytes_written</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">bstr</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">bstr</span><span class="p">)</span></div>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">_buffer_file_size</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">pos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">SEEK_END</span><span class="p">)</span>
<span class="n">length</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="n">pos</span><span class="p">)</span>
<span class="k">return</span> <span class="n">length</span>
<span class="k">def</span> <span class="nf">_flush_write_buffer</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Flushes the write buffer.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer_file_size</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_write_counter</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">part</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_multipart</span><span class="o">.</span><span class="n">Part</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_write_counter</span><span class="p">)</span>
<span class="n">part</span><span class="o">.</span><span class="n">upload</span><span class="p">(</span><span class="n">Body</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">truncate</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">_create_empty_on_close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Attempt to create an empty file for this key when this File is closed if no bytes</span>
<span class="sd"> have been written and no object already exists on S3 for this key.</span>
<span class="sd"> This behavior is meant to mimic the behavior of Django&#39;s builtin FileSystemStorage,</span>
<span class="sd"> where files are always created after they are opened in write mode:</span>
<span class="sd"> f = storage.open(&quot;file.txt&quot;, mode=&quot;w&quot;)</span>
<span class="sd"> f.close()</span>
<span class="sd"> Raises:</span>
<span class="sd"> Exception: Raised if a 404 error occurs</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">assert</span> <span class="s2">&quot;w&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mode</span>
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">_raw_bytes_written</span> <span class="o">==</span> <span class="mi">0</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># Check if the object exists on the server; if so, don&#39;t do anything</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>
<span class="k">except</span> <span class="n">ClientError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="k">if</span> <span class="n">err</span><span class="o">.</span><span class="n">response</span><span class="p">[</span><span class="s2">&quot;ResponseMetadata&quot;</span><span class="p">][</span><span class="s2">&quot;HTTPStatusCode&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">404</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">Body</span><span class="o">=</span><span class="sa">b</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">_storage</span><span class="o">.</span><span class="n">_get_write_parameters</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">key</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span>
<div class="viewcode-block" id="S3Boto3StorageFile.close"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3StorageFile.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Manages file closing after multipart uploads</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_is_dirty</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_flush_write_buffer</span><span class="p">()</span>
<span class="n">parts</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span><span class="s2">&quot;ETag&quot;</span><span class="p">:</span> <span class="n">part</span><span class="o">.</span><span class="n">e_tag</span><span class="p">,</span> <span class="s2">&quot;PartNumber&quot;</span><span class="p">:</span> <span class="n">part</span><span class="o">.</span><span class="n">part_number</span><span class="p">}</span>
<span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_multipart</span><span class="o">.</span><span class="n">parts</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_multipart</span><span class="o">.</span><span class="n">complete</span><span class="p">(</span><span class="n">MultipartUpload</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;Parts&quot;</span><span class="p">:</span> <span class="n">parts</span><span class="p">})</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_multipart</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_multipart</span><span class="o">.</span><span class="n">abort</span><span class="p">()</span>
<span class="k">if</span> <span class="s2">&quot;w&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_mode</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_raw_bytes_written</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_create_empty_on_close</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_file</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="o">=</span> <span class="kc">None</span></div></div>
<div class="viewcode-block" id="S3Boto3Storage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage">[docs]</a><span class="nd">@deconstructible</span>
<span class="k">class</span> <span class="nc">S3Boto3Storage</span><span class="p">(</span><span class="n">Storage</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Amazon Simple Storage Service using Boto3</span>
<span class="sd"> This storage backend supports opening files in read or write</span>
<span class="sd"> mode and supports streaming(buffering) data in chunks to S3</span>
<span class="sd"> when writing.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">default_content_type</span> <span class="o">=</span> <span class="s2">&quot;application/octet-stream&quot;</span>
<span class="c1"># If config provided in init, signature_version and addressing_style settings/args are ignored.</span>
<span class="n">config</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># used for looking up the access and secret key from env vars</span>
<span class="n">access_key_names</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;AWS_S3_ACCESS_KEY_ID&quot;</span><span class="p">,</span> <span class="s2">&quot;AWS_ACCESS_KEY_ID&quot;</span><span class="p">]</span>
<span class="n">secret_key_names</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;AWS_S3_SECRET_ACCESS_KEY&quot;</span><span class="p">,</span> <span class="s2">&quot;AWS_SECRET_ACCESS_KEY&quot;</span><span class="p">]</span>
<span class="n">security_token_names</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;AWS_SESSION_TOKEN&quot;</span><span class="p">,</span> <span class="s2">&quot;AWS_SECURITY_TOKEN&quot;</span><span class="p">]</span>
<span class="n">security_token</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">access_key</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_ACCESS_KEY_ID&quot;</span><span class="p">,</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_ACCESS_KEY_ID&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">))</span>
<span class="n">secret_key</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_SECRET_ACCESS_KEY&quot;</span><span class="p">,</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_SECRET_ACCESS_KEY&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">))</span>
<span class="n">file_overwrite</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_FILE_OVERWRITE&quot;</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
<span class="n">object_parameters</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_OBJECT_PARAMETERS&quot;</span><span class="p">,</span> <span class="p">{})</span>
<span class="n">bucket_name</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_STORAGE_BUCKET_NAME&quot;</span><span class="p">)</span>
<span class="n">auto_create_bucket</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_AUTO_CREATE_BUCKET&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="n">default_acl</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_DEFAULT_ACL&quot;</span><span class="p">,</span> <span class="s2">&quot;public-read&quot;</span><span class="p">)</span>
<span class="n">bucket_acl</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_BUCKET_ACL&quot;</span><span class="p">,</span> <span class="n">default_acl</span><span class="p">)</span>
<span class="n">querystring_auth</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_QUERYSTRING_AUTH&quot;</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
<span class="n">querystring_expire</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_QUERYSTRING_EXPIRE&quot;</span><span class="p">,</span> <span class="mi">3600</span><span class="p">)</span>
<span class="n">signature_version</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_SIGNATURE_VERSION&quot;</span><span class="p">)</span>
<span class="n">reduced_redundancy</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_REDUCED_REDUNDANCY&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="n">location</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_LOCATION&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">encryption</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_ENCRYPTION&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="n">custom_domain</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_CUSTOM_DOMAIN&quot;</span><span class="p">)</span>
<span class="n">addressing_style</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_ADDRESSING_STYLE&quot;</span><span class="p">)</span>
<span class="n">secure_urls</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_SECURE_URLS&quot;</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
<span class="n">file_name_charset</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_FILE_NAME_CHARSET&quot;</span><span class="p">,</span> <span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
<span class="n">gzip</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_IS_GZIPPED&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="n">preload_metadata</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_PRELOAD_METADATA&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="n">gzip_content_types</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span>
<span class="s2">&quot;GZIP_CONTENT_TYPES&quot;</span><span class="p">,</span>
<span class="p">(</span>
<span class="s2">&quot;text/css&quot;</span><span class="p">,</span>
<span class="s2">&quot;text/javascript&quot;</span><span class="p">,</span>
<span class="s2">&quot;application/javascript&quot;</span><span class="p">,</span>
<span class="s2">&quot;application/x-javascript&quot;</span><span class="p">,</span>
<span class="s2">&quot;image/svg+xml&quot;</span><span class="p">,</span>
<span class="p">),</span>
<span class="p">)</span>
<span class="n">url_protocol</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_URL_PROTOCOL&quot;</span><span class="p">,</span> <span class="s2">&quot;http:&quot;</span><span class="p">)</span>
<span class="n">endpoint_url</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_ENDPOINT_URL&quot;</span><span class="p">)</span>
<span class="n">proxies</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_PROXIES&quot;</span><span class="p">)</span>
<span class="n">region_name</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_REGION_NAME&quot;</span><span class="p">)</span>
<span class="n">use_ssl</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_USE_SSL&quot;</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
<span class="n">verify</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_VERIFY&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="n">max_memory_size</span> <span class="o">=</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;AWS_S3_MAX_MEMORY_SIZE&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<div class="viewcode-block" id="S3Boto3Storage.__init__"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">acl</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">bucket</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">settings</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check if some of the settings we&#39;ve provided as class attributes</span>
<span class="sd"> need to be overwritten with values passed in here.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">settings</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="n">check_location</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="c1"># Backward-compatibility: given the anteriority of the SECURE_URL setting</span>
<span class="c1"># we fall back to https if specified in order to avoid the construction</span>
<span class="c1"># of unsecure urls.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">secure_urls</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">url_protocol</span> <span class="o">=</span> <span class="s2">&quot;https:&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_entries</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_bucket</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_connections</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">local</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">access_key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">secret_key</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_access_keys</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">security_token</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_security_token</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">config</span><span class="p">:</span>
<span class="n">kwargs</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
<span class="n">s3</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;addressing_style&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">addressing_style</span><span class="p">},</span>
<span class="n">signature_version</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">signature_version</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">boto3_version_info</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">4</span><span class="p">):</span>
<span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;proxies&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">proxies</span>
<span class="bp">self</span><span class="o">.</span><span class="n">config</span> <span class="o">=</span> <span class="n">Config</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<span class="k">def</span> <span class="nf">__getstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">state</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="n">state</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;_connections&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="n">state</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;_bucket&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="k">return</span> <span class="n">state</span>
<span class="k">def</span> <span class="nf">__setstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">state</span><span class="p">):</span>
<span class="n">state</span><span class="p">[</span><span class="s2">&quot;_connections&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">local</span><span class="p">()</span>
<span class="n">state</span><span class="p">[</span><span class="s2">&quot;_bucket&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span> <span class="o">=</span> <span class="n">state</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">connection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Creates the actual connection to S3</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">connection</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_connections</span><span class="p">,</span> <span class="s2">&quot;connection&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="k">if</span> <span class="n">connection</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">boto3</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">Session</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_connections</span><span class="o">.</span><span class="n">connection</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">resource</span><span class="p">(</span>
<span class="s2">&quot;s3&quot;</span><span class="p">,</span>
<span class="n">aws_access_key_id</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">access_key</span><span class="p">,</span>
<span class="n">aws_secret_access_key</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">secret_key</span><span class="p">,</span>
<span class="n">aws_session_token</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">security_token</span><span class="p">,</span>
<span class="n">region_name</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">region_name</span><span class="p">,</span>
<span class="n">use_ssl</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">use_ssl</span><span class="p">,</span>
<span class="n">endpoint_url</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">endpoint_url</span><span class="p">,</span>
<span class="n">config</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">,</span>
<span class="n">verify</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">verify</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_connections</span><span class="o">.</span><span class="n">connection</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">bucket</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the current bucket. If there is no current bucket object</span>
<span class="sd"> create it.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bucket</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_bucket</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_or_create_bucket</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bucket_name</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bucket</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">entries</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the locally cached files for the bucket.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">preload_metadata</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_entries</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_entries</span> <span class="o">=</span> <span class="p">{</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_decode_name</span><span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">key</span><span class="p">):</span> <span class="n">entry</span>
<span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">bucket</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">Prefix</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_entries</span>
<span class="k">def</span> <span class="nf">_get_access_keys</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Gets the access keys to use when accessing S3. If none is</span>
<span class="sd"> provided in the settings then get them from the environment</span>
<span class="sd"> variables.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">access_key</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">access_key</span> <span class="ow">or</span> <span class="n">lookup_env</span><span class="p">(</span><span class="n">S3Boto3Storage</span><span class="o">.</span><span class="n">access_key_names</span><span class="p">)</span>
<span class="n">secret_key</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">secret_key</span> <span class="ow">or</span> <span class="n">lookup_env</span><span class="p">(</span><span class="n">S3Boto3Storage</span><span class="o">.</span><span class="n">secret_key_names</span><span class="p">)</span>
<span class="k">return</span> <span class="n">access_key</span><span class="p">,</span> <span class="n">secret_key</span>
<span class="k">def</span> <span class="nf">_get_security_token</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Gets the security token to use when accessing S3. Get it from</span>
<span class="sd"> the environment variables.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">security_token</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">security_token</span> <span class="ow">or</span> <span class="n">lookup_env</span><span class="p">(</span><span class="n">S3Boto3Storage</span><span class="o">.</span><span class="n">security_token_names</span><span class="p">)</span>
<span class="k">return</span> <span class="n">security_token</span>
<span class="k">def</span> <span class="nf">_get_or_create_bucket</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Retrieves a bucket if it exists, otherwise creates it.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">bucket</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">connection</span><span class="o">.</span><span class="n">Bucket</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">auto_create_bucket</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># Directly call head_bucket instead of bucket.load() because head_bucket()</span>
<span class="c1"># fails on wrong region, while bucket.load() does not.</span>
<span class="n">bucket</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">head_bucket</span><span class="p">(</span><span class="n">Bucket</span><span class="o">=</span><span class="n">name</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ClientError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="k">if</span> <span class="n">err</span><span class="o">.</span><span class="n">response</span><span class="p">[</span><span class="s2">&quot;ResponseMetadata&quot;</span><span class="p">][</span><span class="s2">&quot;HTTPStatusCode&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">301</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span>
<span class="s2">&quot;Bucket </span><span class="si">%s</span><span class="s2"> exists, but in a different &quot;</span>
<span class="s2">&quot;region than we are connecting to. Set &quot;</span>
<span class="s2">&quot;the region to connect to by setting &quot;</span>
<span class="s2">&quot;AWS_S3_REGION_NAME to the correct region.&quot;</span> <span class="o">%</span> <span class="n">name</span>
<span class="p">)</span>
<span class="k">elif</span> <span class="n">err</span><span class="o">.</span><span class="n">response</span><span class="p">[</span><span class="s2">&quot;ResponseMetadata&quot;</span><span class="p">][</span><span class="s2">&quot;HTTPStatusCode&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">404</span><span class="p">:</span>
<span class="c1"># Notes: When using the us-east-1 Standard endpoint, you can create</span>
<span class="c1"># buckets in other regions. The same is not true when hitting region specific</span>
<span class="c1"># endpoints. However, when you create the bucket not in the same region, the</span>
<span class="c1"># connection will fail all future requests to the Bucket after the creation</span>
<span class="c1"># (301 Moved Permanently).</span>
<span class="c1">#</span>
<span class="c1"># For simplicity, we enforce in S3Boto3Storage that any auto-created</span>
<span class="c1"># bucket must match the region that the connection is for.</span>
<span class="c1">#</span>
<span class="c1"># Also note that Amazon specifically disallows &quot;us-east-1&quot; when passing bucket</span>
<span class="c1"># region names; LocationConstraint *must* be blank to create in US Standard.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">bucket_acl</span><span class="p">:</span>
<span class="n">bucket_params</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;ACL&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">bucket_acl</span><span class="p">}</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">bucket_params</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">region_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">connection</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">region_name</span>
<span class="k">if</span> <span class="n">region_name</span> <span class="o">!=</span> <span class="s2">&quot;us-east-1&quot;</span><span class="p">:</span>
<span class="n">bucket_params</span><span class="p">[</span><span class="s2">&quot;CreateBucketConfiguration&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;LocationConstraint&quot;</span><span class="p">:</span> <span class="n">region_name</span>
<span class="p">}</span>
<span class="n">bucket</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="o">**</span><span class="n">bucket_params</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span>
<span class="k">return</span> <span class="n">bucket</span>
<span class="k">def</span> <span class="nf">_clean_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Cleans the name so that Windows style paths work</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Normalize Windows style paths</span>
<span class="n">clean_name</span> <span class="o">=</span> <span class="n">posixpath</span><span class="o">.</span><span class="n">normpath</span><span class="p">(</span><span class="n">name</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">&quot;</span><span class="p">,</span> <span class="s2">&quot;/&quot;</span><span class="p">)</span>
<span class="c1"># os.path.normpath() can strip trailing slashes so we implement</span>
<span class="c1"># a workaround here.</span>
<span class="k">if</span> <span class="n">name</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">clean_name</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">):</span>
<span class="c1"># Add a trailing slash as it was stripped.</span>
<span class="n">clean_name</span> <span class="o">+=</span> <span class="s2">&quot;/&quot;</span>
<span class="k">return</span> <span class="n">clean_name</span>
<span class="k">def</span> <span class="nf">_normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Normalizes the name so that paths like /path/to/ignored/../something.txt</span>
<span class="sd"> work. We check to make sure that the path pointed to is not outside</span>
<span class="sd"> the directory specified by the LOCATION setting.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">safe_join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">SuspiciousOperation</span><span class="p">(</span><span class="s2">&quot;Attempted access to &#39;</span><span class="si">%s</span><span class="s2">&#39; denied.&quot;</span> <span class="o">%</span> <span class="n">name</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_encode_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="k">return</span> <span class="n">smart_text</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">file_name_charset</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_decode_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="k">return</span> <span class="n">force_text</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">file_name_charset</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_compress_content</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Gzip a given string content.&quot;&quot;&quot;</span>
<span class="n">content</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">zbuf</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">()</span>
<span class="c1"># The GZIP header has a modification time attribute (see http://www.zlib.org/rfc-gzip.html)</span>
<span class="c1"># Each time a file is compressed it changes even if the other contents don&#39;t change</span>
<span class="c1"># For S3 this defeats detection of changes using MD5 sums on gzipped files</span>
<span class="c1"># Fixing the mtime at 0.0 at compression time avoids this problem</span>
<span class="n">zfile</span> <span class="o">=</span> <span class="n">GzipFile</span><span class="p">(</span><span class="n">mode</span><span class="o">=</span><span class="s2">&quot;wb&quot;</span><span class="p">,</span> <span class="n">fileobj</span><span class="o">=</span><span class="n">zbuf</span><span class="p">,</span> <span class="n">mtime</span><span class="o">=</span><span class="mf">0.0</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">zfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">force_bytes</span><span class="p">(</span><span class="n">content</span><span class="o">.</span><span class="n">read</span><span class="p">()))</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">zfile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">zbuf</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="c1"># Boto 2 returned the InMemoryUploadedFile with the file pointer replaced,</span>
<span class="c1"># but Boto 3 seems to have issues with that. No need for fp.name in Boto3</span>
<span class="c1"># so just returning the BytesIO directly</span>
<span class="k">return</span> <span class="n">zbuf</span>
<span class="k">def</span> <span class="nf">_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s2">&quot;rb&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Opens the file, if it exists.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_clean_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="n">S3Boto3StorageFile</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ClientError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="k">if</span> <span class="n">err</span><span class="o">.</span><span class="n">response</span><span class="p">[</span><span class="s2">&quot;ResponseMetadata&quot;</span><span class="p">][</span><span class="s2">&quot;HTTPStatusCode&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">404</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">IOError</span><span class="p">(</span><span class="s2">&quot;File does not exist: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">name</span><span class="p">)</span>
<span class="k">raise</span> <span class="c1"># Let it bubble up if it was some other error</span>
<span class="k">return</span> <span class="n">f</span>
<span class="k">def</span> <span class="nf">_save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Stitches and cleans multipart uploads; normalizes file paths.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">cleaned_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_clean_name</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalize_name</span><span class="p">(</span><span class="n">cleaned_name</span><span class="p">)</span>
<span class="n">params</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_write_parameters</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">content</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">gzip</span>
<span class="ow">and</span> <span class="n">params</span><span class="p">[</span><span class="s2">&quot;ContentType&quot;</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">gzip_content_types</span>
<span class="ow">and</span> <span class="s2">&quot;ContentEncoding&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">params</span>
<span class="p">):</span>
<span class="n">content</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_compress_content</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;ContentEncoding&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;gzip&quot;</span>
<span class="n">encoded_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_name</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">bucket</span><span class="o">.</span><span class="n">Object</span><span class="p">(</span><span class="n">encoded_name</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">preload_metadata</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_entries</span><span class="p">[</span><span class="n">encoded_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj</span>
<span class="n">content</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">SEEK_SET</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">upload_fileobj</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="n">ExtraArgs</span><span class="o">=</span><span class="n">params</span><span class="p">)</span>
<span class="k">return</span> <span class="n">cleaned_name</span>
<div class="viewcode-block" id="S3Boto3Storage.delete"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage.delete">[docs]</a> <span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Deletes a file from S3.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_clean_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">bucket</span><span class="o">.</span><span class="n">Object</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_encode_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_entries</span><span class="p">:</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_entries</span><span class="p">[</span><span class="n">name</span><span class="p">]</span></div>
<div class="viewcode-block" id="S3Boto3Storage.exists"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage.exists">[docs]</a> <span class="k">def</span> <span class="nf">exists</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Checks if file exists.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_clean_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">entries</span><span class="p">:</span>
<span class="k">return</span> <span class="n">name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">entries</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">connection</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">head_object</span><span class="p">(</span><span class="n">Bucket</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">bucket_name</span><span class="p">,</span> <span class="n">Key</span><span class="o">=</span><span class="n">name</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">except</span> <span class="n">ClientError</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="S3Boto3Storage.listdir"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage.listdir">[docs]</a> <span class="k">def</span> <span class="nf">listdir</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Translational function to go from S3 file paths to the format</span>
<span class="sd"> Django&#39;s listdir expects.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_clean_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="c1"># The path needs to end with a slash, but if the root is empty, leave</span>
<span class="c1"># it.</span>
<span class="k">if</span> <span class="n">path</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">path</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">):</span>
<span class="n">path</span> <span class="o">+=</span> <span class="s2">&quot;/&quot;</span>
<span class="n">directories</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">files</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">paginator</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">connection</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">get_paginator</span><span class="p">(</span><span class="s2">&quot;list_objects&quot;</span><span class="p">)</span>
<span class="n">pages</span> <span class="o">=</span> <span class="n">paginator</span><span class="o">.</span><span class="n">paginate</span><span class="p">(</span><span class="n">Bucket</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">bucket_name</span><span class="p">,</span> <span class="n">Delimiter</span><span class="o">=</span><span class="s2">&quot;/&quot;</span><span class="p">,</span> <span class="n">Prefix</span><span class="o">=</span><span class="n">path</span><span class="p">)</span>
<span class="k">for</span> <span class="n">page</span> <span class="ow">in</span> <span class="n">pages</span><span class="p">:</span>
<span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;CommonPrefixes&quot;</span><span class="p">,</span> <span class="p">()):</span>
<span class="n">directories</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">posixpath</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">entry</span><span class="p">[</span><span class="s2">&quot;Prefix&quot;</span><span class="p">],</span> <span class="n">path</span><span class="p">))</span>
<span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">page</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Contents&quot;</span><span class="p">,</span> <span class="p">()):</span>
<span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">posixpath</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">entry</span><span class="p">[</span><span class="s2">&quot;Key&quot;</span><span class="p">],</span> <span class="n">path</span><span class="p">))</span>
<span class="k">return</span> <span class="n">directories</span><span class="p">,</span> <span class="n">files</span></div>
<div class="viewcode-block" id="S3Boto3Storage.size"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage.size">[docs]</a> <span class="k">def</span> <span class="nf">size</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Gets the filesize of a remote file.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_clean_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">entries</span><span class="p">:</span>
<span class="n">entry</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">entries</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">if</span> <span class="n">entry</span><span class="p">:</span>
<span class="k">return</span> <span class="n">entry</span><span class="o">.</span><span class="n">size</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">entry</span><span class="p">,</span> <span class="s2">&quot;size&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">entry</span><span class="o">.</span><span class="n">content_length</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">bucket</span><span class="o">.</span><span class="n">Object</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_encode_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span><span class="o">.</span><span class="n">content_length</span></div>
<span class="k">def</span> <span class="nf">_get_write_parameters</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">content</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">params</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">encryption</span><span class="p">:</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;ServerSideEncryption&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;AES256&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">reduced_redundancy</span><span class="p">:</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;StorageClass&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;REDUCED_REDUNDANCY&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_acl</span><span class="p">:</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;ACL&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_acl</span>
<span class="n">_type</span><span class="p">,</span> <span class="n">encoding</span> <span class="o">=</span> <span class="n">mimetypes</span><span class="o">.</span><span class="n">guess_type</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">content_type</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="s2">&quot;content_type&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="n">content_type</span> <span class="o">=</span> <span class="n">content_type</span> <span class="ow">or</span> <span class="n">_type</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_content_type</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;ContentType&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">content_type</span>
<span class="k">if</span> <span class="n">encoding</span><span class="p">:</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;ContentEncoding&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">encoding</span>
<span class="n">params</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_object_parameters</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="k">return</span> <span class="n">params</span>
<div class="viewcode-block" id="S3Boto3Storage.get_object_parameters"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage.get_object_parameters">[docs]</a> <span class="k">def</span> <span class="nf">get_object_parameters</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Returns a dictionary that is passed to file upload. Override this</span>
<span class="sd"> method to adjust this on a per-object basis to set e.g ContentDisposition.</span>
<span class="sd"> By default, returns the value of AWS_S3_OBJECT_PARAMETERS.</span>
<span class="sd"> Setting ContentEncoding will prevent objects from being automatically gzipped.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">object_parameters</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span></div>
<div class="viewcode-block" id="S3Boto3Storage.get_modified_time"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage.get_modified_time">[docs]</a> <span class="k">def</span> <span class="nf">get_modified_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Returns an (aware) datetime object containing the last modified time if</span>
<span class="sd"> USE_TZ is True, otherwise returns a naive datetime in the local timezone.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_clean_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="n">entry</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">entries</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="c1"># only call self.bucket.Object() if the key is not found</span>
<span class="c1"># in the preloaded metadata.</span>
<span class="k">if</span> <span class="n">entry</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">entry</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">bucket</span><span class="o">.</span><span class="n">Object</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_encode_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="k">if</span> <span class="n">setting</span><span class="p">(</span><span class="s2">&quot;USE_TZ&quot;</span><span class="p">):</span>
<span class="c1"># boto3 returns TZ aware timestamps</span>
<span class="k">return</span> <span class="n">entry</span><span class="o">.</span><span class="n">last_modified</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">make_naive</span><span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">last_modified</span><span class="p">)</span></div>
<div class="viewcode-block" id="S3Boto3Storage.modified_time"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage.modified_time">[docs]</a> <span class="k">def</span> <span class="nf">modified_time</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Returns a naive datetime object containing the last modified time.</span>
<span class="sd"> If USE_TZ=False then get_modified_time will return a naive datetime</span>
<span class="sd"> so we just return that, else we have to localize and strip the tz</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">mtime</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_modified_time</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">return</span> <span class="n">mtime</span> <span class="k">if</span> <span class="n">is_naive</span><span class="p">(</span><span class="n">mtime</span><span class="p">)</span> <span class="k">else</span> <span class="n">make_naive</span><span class="p">(</span><span class="n">mtime</span><span class="p">)</span></div>
<span class="k">def</span> <span class="nf">_strip_signing_parameters</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Boto3 does not currently support generating URLs that are unsigned. Instead we</span>
<span class="sd"> take the signed URLs and strip any querystring params related to signing and expiration.</span>
<span class="sd"> Note that this may end up with URLs that are still invalid, especially if params are</span>
<span class="sd"> passed in that only work with signed URLs, e.g. response header params.</span>
<span class="sd"> The code attempts to strip all query parameters that match names of known parameters</span>
<span class="sd"> from v2 and v4 signatures, regardless of the actual signature version used.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">split_url</span> <span class="o">=</span> <span class="n">urlparse</span><span class="o">.</span><span class="n">urlsplit</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
<span class="n">qs</span> <span class="o">=</span> <span class="n">urlparse</span><span class="o">.</span><span class="n">parse_qsl</span><span class="p">(</span><span class="n">split_url</span><span class="o">.</span><span class="n">query</span><span class="p">,</span> <span class="n">keep_blank_values</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">blacklist</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;x-amz-algorithm&quot;</span><span class="p">,</span>
<span class="s2">&quot;x-amz-credential&quot;</span><span class="p">,</span>
<span class="s2">&quot;x-amz-date&quot;</span><span class="p">,</span>
<span class="s2">&quot;x-amz-expires&quot;</span><span class="p">,</span>
<span class="s2">&quot;x-amz-signedheaders&quot;</span><span class="p">,</span>
<span class="s2">&quot;x-amz-signature&quot;</span><span class="p">,</span>
<span class="s2">&quot;x-amz-security-token&quot;</span><span class="p">,</span>
<span class="s2">&quot;awsaccesskeyid&quot;</span><span class="p">,</span>
<span class="s2">&quot;expires&quot;</span><span class="p">,</span>
<span class="s2">&quot;signature&quot;</span><span class="p">,</span>
<span class="p">}</span>
<span class="n">filtered_qs</span> <span class="o">=</span> <span class="p">((</span><span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">qs</span> <span class="k">if</span> <span class="n">key</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">blacklist</span><span class="p">)</span>
<span class="c1"># Note: Parameters that did not have a value in the original query string will have</span>
<span class="c1"># an &#39;=&#39; sign appended to it, e.g ?foo&amp;bar becomes ?foo=&amp;bar=</span>
<span class="n">joined_qs</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;=&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">keyval</span><span class="p">)</span> <span class="k">for</span> <span class="n">keyval</span> <span class="ow">in</span> <span class="n">filtered_qs</span><span class="p">)</span>
<span class="n">split_url</span> <span class="o">=</span> <span class="n">split_url</span><span class="o">.</span><span class="n">_replace</span><span class="p">(</span><span class="n">query</span><span class="o">=</span><span class="s2">&quot;&amp;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">joined_qs</span><span class="p">))</span>
<span class="k">return</span> <span class="n">split_url</span><span class="o">.</span><span class="n">geturl</span><span class="p">()</span>
<div class="viewcode-block" id="S3Boto3Storage.url"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage.url">[docs]</a> <span class="k">def</span> <span class="nf">url</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">parameters</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">expire</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Returns the URL of a remotely-hosted file</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Preserve the trailing slash after normalizing the path.</span>
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_clean_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">custom_domain</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">//</span><span class="si">{}</span><span class="s2">/</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">url_protocol</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">custom_domain</span><span class="p">,</span> <span class="n">filepath_to_uri</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
<span class="k">if</span> <span class="n">expire</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">expire</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">querystring_expire</span>
<span class="n">params</span> <span class="o">=</span> <span class="n">parameters</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span> <span class="k">if</span> <span class="n">parameters</span> <span class="k">else</span> <span class="p">{}</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;Bucket&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">bucket</span><span class="o">.</span><span class="n">name</span>
<span class="n">params</span><span class="p">[</span><span class="s2">&quot;Key&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_name</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="n">url</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">bucket</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">generate_presigned_url</span><span class="p">(</span>
<span class="s2">&quot;get_object&quot;</span><span class="p">,</span> <span class="n">Params</span><span class="o">=</span><span class="n">params</span><span class="p">,</span> <span class="n">ExpiresIn</span><span class="o">=</span><span class="n">expire</span>
<span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">querystring_auth</span><span class="p">:</span>
<span class="k">return</span> <span class="n">url</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_strip_signing_parameters</span><span class="p">(</span><span class="n">url</span><span class="p">)</span></div>
<div class="viewcode-block" id="S3Boto3Storage.get_available_name"><a class="viewcode-back" href="../../../../../api/evennia.contrib.base_systems.awsstorage.aws_s3_cdn.html#evennia.contrib.base_systems.awsstorage.aws_s3_cdn.S3Boto3Storage.get_available_name">[docs]</a> <span class="k">def</span> <span class="nf">get_available_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">max_length</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Overwrite existing file with the same name.&quot;&quot;&quot;</span>
<span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_clean_name</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">file_overwrite</span><span class="p">:</span>
<span class="k">return</span> <span class="n">get_available_overwrite_name</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">max_length</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">get_available_name</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">max_length</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="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="aws_s3_cdn.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (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 1.0-dev</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.base_systems.awsstorage.aws_s3_cdn</a></li>
</ul>
<div class="develop">develop branch</div>
</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>

View file

@ -684,7 +684,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1346,7 +1346,6 @@
<h3>Versions</h3>
<ul>
<li><a href="building_menu.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -253,7 +253,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -142,7 +142,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -406,7 +406,6 @@
<h3>Versions</h3>
<ul>
<li><a href="custom_gametime.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -130,7 +130,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -441,7 +441,6 @@
<h3>Versions</h3>
<ul>
<li><a href="email_login.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -112,7 +112,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -301,7 +301,6 @@
<h3>Versions</h3>
<ul>
<li><a href="callbackhandler.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -658,7 +658,6 @@
<h3>Versions</h3>
<ul>
<li><a href="commands.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -167,7 +167,6 @@
<h3>Versions</h3>
<ul>
<li><a href="eventfuncs.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -745,7 +745,6 @@
<h3>Versions</h3>
<ul>
<li><a href="scripts.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -619,7 +619,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -336,7 +336,6 @@
<h3>Versions</h3>
<ul>
<li><a href="utils.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -621,7 +621,6 @@
<h3>Versions</h3>
<ul>
<li><a href="mux_comms_cmds.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -162,7 +162,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -126,7 +126,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -374,7 +374,6 @@
<h3>Versions</h3>
<ul>
<li><a href="unixcommand.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -857,7 +857,6 @@
<h3>Versions</h3>
<ul>
<li><a href="commands.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -430,7 +430,6 @@
<h3>Versions</h3>
<ul>
<li><a href="menu.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1157,7 +1157,6 @@
<h3>Versions</h3>
<ul>
<li><a href="objects.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -316,7 +316,6 @@
<h3>Versions</h3>
<ul>
<li><a href="room.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -107,7 +107,6 @@
<h3>Versions</h3>
<ul>
<li><a href="scripts.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -384,7 +384,6 @@
<h3>Versions</h3>
<ul>
<li><a href="state.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -381,7 +381,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -271,7 +271,6 @@
<h3>Versions</h3>
<ul>
<li><a href="utils.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -975,7 +975,6 @@
<h3>Versions</h3>
<ul>
<li><a href="barter.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -223,7 +223,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -820,7 +820,6 @@
<h3>Versions</h3>
<ul>
<li><a href="clothing.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -209,7 +209,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -284,7 +284,6 @@
<h3>Versions</h3>
<ul>
<li><a href="cooldowns.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -223,7 +223,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1145,7 +1145,6 @@
<h3>Versions</h3>
<ul>
<li><a href="crafting.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -607,7 +607,6 @@
<h3>Versions</h3>
<ul>
<li><a href="example_recipes.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -765,7 +765,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -235,7 +235,6 @@
<h3>Versions</h3>
<ul>
<li><a href="gendersub.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -104,7 +104,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -436,7 +436,6 @@
<h3>Versions</h3>
<ul>
<li><a href="mail.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -123,7 +123,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -345,7 +345,6 @@
<h3>Versions</h3>
<ul>
<li><a href="multidescer.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -116,7 +116,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -894,7 +894,6 @@
<h3>Versions</h3>
<ul>
<li><a href="puzzles.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1051,7 +1051,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -45,7 +45,7 @@
<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">Contrib - Tim Ashley Jenkins 2017, Refactor by Griatch 2022</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>
@ -106,237 +106,235 @@
<span class="sd">&quot;&quot;&quot;</span>
<div class="viewcode-block" id="roll_init"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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>
<div class="viewcode-block" id="BasicCombatRules"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules">[docs]</a><span class="k">class</span> <span class="nc">BasicCombatRules</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"> Stores all combat rules and helper methods.</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="BasicCombatRules.roll_init"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.roll_init">[docs]</a> <span class="k">def</span> <span class="nf">roll_init</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"> Rolls a number between 1-1000 to determine initiative.</span>
<div class="viewcode-block" id="get_attack"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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"> character (obj): The character to determine initiative for</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"> initiative (int): The character&#39;s place in initiative - higher</span>
<span class="sd"> numbers go first.</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, does not reference the character and simply returns</span>
<span class="sd"> a random integer from 1 to 1000.</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"> 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"> 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>
<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_defense"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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>
<div class="viewcode-block" id="BasicCombatRules.get_attack"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.get_attack">[docs]</a> <span class="k">def</span> <span class="nf">get_attack</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="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"> 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"> 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 50, not taking any properties of the defender or</span>
<span class="sd"> attacker into account.</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"> 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>
<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="BasicCombatRules.get_defense"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.get_defense">[docs]</a> <span class="k">def</span> <span class="nf">get_defense</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="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>
<div class="viewcode-block" id="get_damage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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 attacked</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"> 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"> 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 50, not taking any properties of the defender or</span>
<span class="sd"> attacker into account.</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"> 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>
<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="BasicCombatRules.get_damage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.get_damage">[docs]</a> <span class="k">def</span> <span class="nf">get_damage</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="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>
<div class="viewcode-block" id="apply_damage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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"> 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"> 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>
<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="at_defeat"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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>
<div class="viewcode-block" id="BasicCombatRules.apply_damage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.apply_damage">[docs]</a> <span class="k">def</span> <span class="nf">apply_damage</span><span class="p">(</span><span class="bp">self</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"> defeated (obj): Fighter that&#39;s been defeated.</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.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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="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">at_defeat</span><span class="p">(</span><span class="n">defender</span><span class="p">)</span></div>
<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="BasicCombatRules.at_defeat"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.at_defeat">[docs]</a> <span class="k">def</span> <span class="nf">at_defeat</span><span class="p">(</span><span class="bp">self</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"> Args:</span>
<span class="sd"> defeated (obj): Fighter that&#39;s been defeated.</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="BasicCombatRules.resolve_attack"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.resolve_attack">[docs]</a> <span class="k">def</span> <span class="nf">resolve_attack</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="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="bp">self</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="bp">self</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="bp">self</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="bp">self</span><span class="o">.</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="bp">self</span><span class="o">.</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="BasicCombatRules.combat_cleanup"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.combat_cleanup">[docs]</a> <span class="k">def</span> <span class="nf">combat_cleanup</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"> 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="BasicCombatRules.is_in_combat"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.is_in_combat">[docs]</a> <span class="k">def</span> <span class="nf">is_in_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"> 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="BasicCombatRules.is_turn"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.is_turn">[docs]</a> <span class="k">def</span> <span class="nf">is_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"> 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="BasicCombatRules.spend_action"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.turnbattle.tb_basic.BasicCombatRules.spend_action">[docs]</a> <span class="k">def</span> <span class="nf">spend_action</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">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></div>
<div class="viewcode-block" id="combat_cleanup"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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="n">COMBAT_RULES</span> <span class="o">=</span> <span class="n">BasicCombatRules</span><span class="p">()</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">----------------------------------------------------------------------------</span>
@ -350,6 +348,7 @@
<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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="TBBasicCharacter.at_object_creation"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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>
@ -383,7 +382,7 @@
<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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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>
@ -411,6 +410,8 @@
<span class="sd"> remaining participants choose to end the combat with the &#39;disengage&#39; command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="TBBasicTurnHandler.at_script_creation"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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>
@ -432,9 +433,10 @@
<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="c1"># Roll initiative and sort the list of fighters depending on who rolls highest to determine</span>
<span class="c1"># turn order. The initiative roll is determined by the roll_init method and can be</span>
<span class="c1"># 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="bp">self</span><span class="o">.</span><span class="n">rules</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>
@ -452,7 +454,9 @@
<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="k">if</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">rules</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="n">fighter</span><span class="p">)</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.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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>
@ -467,7 +471,7 @@
<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="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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>
@ -483,7 +487,8 @@
<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="c1"># Clean up leftover combat attributes beforehand, just in case.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="n">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_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>
@ -604,6 +609,9 @@
<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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<span class="n">combat_handler_class</span> <span class="o">=</span> <span class="n">TBBasicTurnHandler</span>
<div class="viewcode-block" id="CmdFight.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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>
@ -614,7 +622,7 @@
<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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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>
@ -629,8 +637,7 @@
<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.game_systems.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>
<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="bp">self</span><span class="o">.</span><span class="n">command_handler_class</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdAttack"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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>
@ -647,15 +654,17 @@
<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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="CmdAttack.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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>
@ -678,8 +687,8 @@
<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>
<span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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>
@ -697,22 +706,25 @@
<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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="CmdPass.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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>
<span class="c1"># Spend all remaining actions.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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></div></div>
<div class="viewcode-block" id="CmdDisengage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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>
@ -731,20 +743,23 @@
<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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="CmdDisengage.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="c1"># Spend all remaining actions.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="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>
@ -765,10 +780,12 @@
<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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="CmdRest.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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>
@ -792,17 +809,21 @@
<span class="sd"> topics related to the game.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<span class="n">combat_help_text</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;Available combat commands:|/&quot;</span>
<span class="s2">&quot;|wAttack:|n Attack a target, attempting to deal damage.|/&quot;</span>
<span class="s2">&quot;|wPass:|n Pass your turn without further action.|/&quot;</span>
<span class="s2">&quot;|wDisengage:|n End your turn and attempt to end combat.|/&quot;</span>
<span class="p">)</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.game_systems.turnbattle.tb_basic.html#evennia.contrib.game_systems.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="c1"># In combat and entered &#39;help&#39; alone</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="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="bp">self</span><span class="o">.</span><span class="n">combat_help_text</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>
@ -858,7 +879,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tb_basic.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -45,7 +45,7 @@
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Simple turn-based combat system with equipment</span>
<span class="sd">Contrib - Tim Ashley Jenkins 2017</span>
<span class="sd">Contrib - Tim Ashley Jenkins 2017, Refactor by Griatch 2022</span>
<span class="sd">This is a version of the &#39;turnbattle&#39; contrib with a basic system for</span>
<span class="sd">weapons and armor implemented. Weapons can have unique damage ranges</span>
@ -99,8 +99,8 @@
<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="p">,</span> <span class="n">DefaultObject</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="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">Command</span><span class="p">,</span> <span class="n">default_cmds</span><span class="p">,</span> <span class="n">DefaultObject</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">tb_basic</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">----------------------------------------------------------------------------</span>
@ -118,276 +118,156 @@
<span class="sd">&quot;&quot;&quot;</span>
<div class="viewcode-block" id="roll_init"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<div class="viewcode-block" id="EquipmentCombatRules"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.EquipmentCombatRules">[docs]</a><span class="k">class</span> <span class="nc">EquipmentCombatRules</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">BasicCombatRules</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"> Has all the methods of the basic combat, with the addition of equipment.</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="EquipmentCombatRules.get_attack"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.EquipmentCombatRules.get_attack">[docs]</a> <span class="k">def</span> <span class="nf">get_attack</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="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>
<div class="viewcode-block" id="get_attack"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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"> 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"> 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"> In this example, a weapon&#39;s accuracy bonus is factored into the attack</span>
<span class="sd"> roll. Lighter weapons are more accurate but less damaging, and heavier</span>
<span class="sd"> weapons are less accurate but deal more damage. Of course, you can</span>
<span class="sd"> change this paradigm completely in your own game.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Start with a roll from 1 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="n">accuracy_bonus</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># If armed, add weapon&#39;s accuracy bonus.</span>
<span class="k">if</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span><span class="p">:</span>
<span class="n">weapon</span> <span class="o">=</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span>
<span class="n">accuracy_bonus</span> <span class="o">+=</span> <span class="n">weapon</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">accuracy_bonus</span>
<span class="c1"># If unarmed, use character&#39;s unarmed accuracy bonus.</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">accuracy_bonus</span> <span class="o">+=</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">unarmed_accuracy</span>
<span class="c1"># Add the accuracy bonus to the attack roll.</span>
<span class="n">attack_value</span> <span class="o">+=</span> <span class="n">accuracy_bonus</span>
<span class="k">return</span> <span class="n">attack_value</span></div>
<span class="sd"> Notes:</span>
<span class="sd"> In this example, a weapon&#39;s accuracy bonus is factored into the attack</span>
<span class="sd"> roll. Lighter weapons are more accurate but less damaging, and heavier</span>
<span class="sd"> weapons are less accurate but deal more damage. Of course, you can</span>
<span class="sd"> change this paradigm completely in your own game.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Start with a roll from 1 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="n">accuracy_bonus</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># If armed, add weapon&#39;s accuracy bonus.</span>
<span class="k">if</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span><span class="p">:</span>
<span class="n">weapon</span> <span class="o">=</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span>
<span class="n">accuracy_bonus</span> <span class="o">+=</span> <span class="n">weapon</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">accuracy_bonus</span>
<span class="c1"># If unarmed, use character&#39;s unarmed accuracy bonus.</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">accuracy_bonus</span> <span class="o">+=</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">unarmed_accuracy</span>
<span class="c1"># Add the accuracy bonus to the attack roll.</span>
<span class="n">attack_value</span> <span class="o">+=</span> <span class="n">accuracy_bonus</span>
<span class="k">return</span> <span class="n">attack_value</span></div>
<div class="viewcode-block" id="EquipmentCombatRules.get_defense"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.EquipmentCombatRules.get_defense">[docs]</a> <span class="k">def</span> <span class="nf">get_defense</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="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>
<div class="viewcode-block" id="get_defense"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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"> 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"> 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"> Characters are given a default defense value of 50 which can be</span>
<span class="sd"> modified up or down by armor. In this example, wearing armor actually</span>
<span class="sd"> makes you a little easier to hit, but reduces incoming damage.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Start with a defense value of 50 for a 50/50 chance to hit.</span>
<span class="n">defense_value</span> <span class="o">=</span> <span class="mi">50</span>
<span class="c1"># Modify this value based on defender&#39;s armor.</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">worn_armor</span><span class="p">:</span>
<span class="n">armor</span> <span class="o">=</span> <span class="n">defender</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">worn_armor</span>
<span class="n">defense_value</span> <span class="o">+=</span> <span class="n">armor</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">defense_modifier</span>
<span class="k">return</span> <span class="n">defense_value</span></div>
<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>
<div class="viewcode-block" id="EquipmentCombatRules.get_damage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.EquipmentCombatRules.get_damage">[docs]</a> <span class="k">def</span> <span class="nf">get_damage</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="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"> Notes:</span>
<span class="sd"> Characters are given a default defense value of 50 which can be</span>
<span class="sd"> modified up or down by armor. In this example, wearing armor actually</span>
<span class="sd"> makes you a little easier to hit, but reduces incoming damage.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Start with a defense value of 50 for a 50/50 chance to hit.</span>
<span class="n">defense_value</span> <span class="o">=</span> <span class="mi">50</span>
<span class="c1"># Modify this value based on defender&#39;s armor.</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">worn_armor</span><span class="p">:</span>
<span class="n">armor</span> <span class="o">=</span> <span class="n">defender</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">worn_armor</span>
<span class="n">defense_value</span> <span class="o">+=</span> <span class="n">armor</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">defense_modifier</span>
<span class="k">return</span> <span class="n">defense_value</span></div>
<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>
<div class="viewcode-block" id="get_damage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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"> Damage is determined by the attacker&#39;s wielded weapon, or the attacker&#39;s</span>
<span class="sd"> unarmed damage range if no weapon is wielded. Incoming damage is reduced</span>
<span class="sd"> by the defender&#39;s armor.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">damage_value</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># Generate a damage value from wielded weapon if armed</span>
<span class="k">if</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span><span class="p">:</span>
<span class="n">weapon</span> <span class="o">=</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span>
<span class="c1"># Roll between minimum and maximum damage</span>
<span class="n">damage_value</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span><span class="n">weapon</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">damage_range</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">weapon</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">damage_range</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="c1"># Use attacker&#39;s unarmed damage otherwise</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">damage_value</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span>
<span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">unarmed_damage_range</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">unarmed_damage_range</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="p">)</span>
<span class="c1"># If defender is armored, reduce incoming damage</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">worn_armor</span><span class="p">:</span>
<span class="n">armor</span> <span class="o">=</span> <span class="n">defender</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">worn_armor</span>
<span class="n">damage_value</span> <span class="o">-=</span> <span class="n">armor</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">damage_reduction</span>
<span class="c1"># Make sure minimum damage is 0</span>
<span class="k">if</span> <span class="n">damage_value</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="sd"> Notes:</span>
<span class="sd"> Damage is determined by the attacker&#39;s wielded weapon, or the attacker&#39;s</span>
<span class="sd"> unarmed damage range if no weapon is wielded. Incoming damage is reduced</span>
<span class="sd"> by the defender&#39;s armor.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">damage_value</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">return</span> <span class="n">damage_value</span></div>
<span class="c1"># Generate a damage value from wielded weapon if armed</span>
<span class="k">if</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span><span class="p">:</span>
<span class="n">weapon</span> <span class="o">=</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span>
<span class="c1"># Roll between minimum and maximum damage</span>
<span class="n">damage_value</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span><span class="n">weapon</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">damage_range</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">weapon</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">damage_range</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="c1"># Use attacker&#39;s unarmed damage otherwise</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">damage_value</span> <span class="o">=</span> <span class="n">randint</span><span class="p">(</span>
<span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">unarmed_damage_range</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">unarmed_damage_range</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="p">)</span>
<span class="c1"># If defender is armored, reduce incoming damage</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">worn_armor</span><span class="p">:</span>
<span class="n">armor</span> <span class="o">=</span> <span class="n">defender</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">worn_armor</span>
<span class="n">damage_value</span> <span class="o">-=</span> <span class="n">armor</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">damage_reduction</span>
<span class="c1"># Make sure minimum damage is 0</span>
<span class="k">if</span> <span class="n">damage_value</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">damage_value</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">return</span> <span class="n">damage_value</span></div>
<div class="viewcode-block" id="EquipmentCombatRules.resolve_attack"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.EquipmentCombatRules.resolve_attack">[docs]</a> <span class="k">def</span> <span class="nf">resolve_attack</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="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>
<div class="viewcode-block" id="apply_damage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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"> attacker (obj): Character doing the attacking</span>
<span class="sd"> defender (obj): Character being attacked</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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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"> Args:</span>
<span class="sd"> defeated (obj): Fighter that&#39;s been defeated.</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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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 the attacker&#39;s weapon type to reference in combat messages.</span>
<span class="n">attackers_weapon</span> <span class="o">=</span> <span class="s2">&quot;attack&quot;</span>
<span class="k">if</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span><span class="p">:</span>
<span class="n">weapon</span> <span class="o">=</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span>
<span class="n">attackers_weapon</span> <span class="o">=</span> <span class="n">weapon</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">weapon_type_name</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 </span><span class="si">%s</span><span class="s2"> 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">attackers_weapon</span><span class="p">,</span> <span class="n">defender</span><span class="p">)</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="k">if</span> <span class="n">damage_value</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</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 the attacker&#39;s weapon type to reference in combat messages.</span>
<span class="n">attackers_weapon</span> <span class="o">=</span> <span class="s2">&quot;attack&quot;</span>
<span class="k">if</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span><span class="p">:</span>
<span class="n">weapon</span> <span class="o">=</span> <span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">wielded_weapon</span>
<span class="n">attackers_weapon</span> <span class="o">=</span> <span class="n">weapon</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">weapon_type_name</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="bp">self</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="bp">self</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 </span><span class="si">%s</span><span class="s2"> strikes </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">attackers_weapon</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="s2">&quot;</span><span class="si">%s</span><span class="s2">&#39;s </span><span class="si">%s</span><span class="s2"> 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">attackers_weapon</span><span class="p">,</span> <span class="n">defender</span><span class="p">)</span>
<span class="p">)</span>
<span class="k">else</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 </span><span class="si">%s</span><span class="s2"> bounces harmlessly off </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">attackers_weapon</span><span class="p">,</span> <span class="n">defender</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>
<span class="n">damage_value</span> <span class="o">=</span> <span class="bp">self</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="k">if</span> <span class="n">damage_value</span> <span class="o">&gt;</span> <span class="mi">0</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 </span><span class="si">%s</span><span class="s2"> strikes </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">attackers_weapon</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="k">else</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 </span><span class="si">%s</span><span class="s2"> bounces harmlessly off </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">attackers_weapon</span><span class="p">,</span> <span class="n">defender</span><span class="p">)</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</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="bp">self</span><span class="o">.</span><span class="n">at_defeat</span><span class="p">(</span><span class="n">defender</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="combat_cleanup"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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="n">COMBAT_RULES</span> <span class="o">=</span> <span class="n">EquipmentCombatRules</span><span class="p">()</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">----------------------------------------------------------------------------</span>
@ -396,7 +276,7 @@
<span class="sd">&quot;&quot;&quot;</span>
<div class="viewcode-block" id="TBEquipTurnHandler"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipTurnHandler">[docs]</a><span class="k">class</span> <span class="nc">TBEquipTurnHandler</span><span class="p">(</span><span class="n">DefaultScript</span><span class="p">):</span>
<div class="viewcode-block" id="TBEquipTurnHandler"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipTurnHandler">[docs]</a><span class="k">class</span> <span class="nc">TBEquipTurnHandler</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">TBBasicTurnHandler</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>
@ -407,174 +287,7 @@
<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="TBEquipTurnHandler.at_script_creation"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipTurnHandler.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="TBEquipTurnHandler.at_stop"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipTurnHandler.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="TBEquipTurnHandler.at_repeat"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipTurnHandler.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="TBEquipTurnHandler.initialize_for_combat"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipTurnHandler.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="TBEquipTurnHandler.start_turn"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipTurnHandler.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="TBEquipTurnHandler.next_turn"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipTurnHandler.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="TBEquipTurnHandler.turn_end_check"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipTurnHandler.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="TBEquipTurnHandler.join_fight"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipTurnHandler.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="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span></div>
<span class="sd">&quot;&quot;&quot;</span>
@ -587,7 +300,9 @@
<div class="viewcode-block" id="TBEWeapon"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEWeapon">[docs]</a><span class="k">class</span> <span class="nc">TBEWeapon</span><span class="p">(</span><span class="n">DefaultObject</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A weapon which can be wielded in combat with the &#39;wield&#39; command.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="TBEWeapon.at_object_creation"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEWeapon.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>
@ -636,7 +351,7 @@
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Can&#39;t drop in combat.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">is_in_combat</span><span class="p">(</span><span class="n">dropper</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="n">dropper</span><span class="p">):</span>
<span class="n">dropper</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can&#39;t doff armor in a fight!&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>
@ -653,7 +368,7 @@
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Can&#39;t give away in combat.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">is_in_combat</span><span class="p">(</span><span class="n">giver</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="n">giver</span><span class="p">):</span>
<span class="n">dropper</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can&#39;t doff armor in a fight!&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>
@ -667,7 +382,7 @@
<span class="n">giver</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"> removes </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">giver</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span></div></div>
<div class="viewcode-block" id="TBEquipCharacter"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipCharacter">[docs]</a><span class="k">class</span> <span class="nc">TBEquipCharacter</span><span class="p">(</span><span class="n">DefaultCharacter</span><span class="p">):</span>
<div class="viewcode-block" id="TBEquipCharacter"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipCharacter">[docs]</a><span class="k">class</span> <span class="nc">TBEquipCharacter</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">TBBasicCharacter</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>
@ -691,32 +406,7 @@
<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="TBEquipCharacter.at_pre_move"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.TBEquipCharacter.at_pre_move">[docs]</a> <span class="k">def</span> <span class="nf">at_pre_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></div></div>
<span class="sd">&quot;&quot;&quot;</span>
@ -726,7 +416,7 @@
<span class="sd">&quot;&quot;&quot;</span>
<div class="viewcode-block" id="CmdFight"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<div class="viewcode-block" id="CmdFight"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdFight">[docs]</a><span class="k">class</span> <span class="nc">CmdFight</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">CmdFight</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>
@ -741,36 +431,11 @@
<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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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.game_systems.turnbattle.tb_equip.TBEquipTurnHandler&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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<span class="n">command_handler_class</span> <span class="o">=</span> <span class="n">TBEquipTurnHandler</span></div>
<div class="viewcode-block" id="CmdAttack"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<div class="viewcode-block" id="CmdAttack"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdAttack">[docs]</a><span class="k">class</span> <span class="nc">CmdAttack</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">CmdAttack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Attacks another character.</span>
@ -784,42 +449,10 @@
<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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span></div>
<div class="viewcode-block" id="CmdPass"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<div class="viewcode-block" id="CmdPass"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdPass">[docs]</a><span class="k">class</span> <span class="nc">CmdPass</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">CmdPass</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Passes on your turn.</span>
@ -834,25 +467,10 @@
<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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span></div>
<div class="viewcode-block" id="CmdDisengage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<div class="viewcode-block" id="CmdDisengage"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdDisengage">[docs]</a><span class="k">class</span> <span class="nc">CmdDisengage</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">CmdDisengage</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Passes your turn and attempts to end combat.</span>
@ -868,27 +486,10 @@
<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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span></div>
<div class="viewcode-block" id="CmdRest"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<div class="viewcode-block" id="CmdRest"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdRest">[docs]</a><span class="k">class</span> <span class="nc">CmdRest</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">CmdRest</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Recovers damage.</span>
@ -902,21 +503,10 @@
<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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span></div>
<div class="viewcode-block" id="CmdCombatHelp"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<div class="viewcode-block" id="CmdCombatHelp"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdCombatHelp">[docs]</a><span class="k">class</span> <span class="nc">CmdCombatHelp</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">CmdCombatHelp</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> View help or a list of topics</span>
@ -929,19 +519,7 @@
<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.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.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>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span></div>
<div class="viewcode-block" id="CmdWield"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdWield">[docs]</a><span class="k">class</span> <span class="nc">CmdWield</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
@ -962,13 +540,15 @@
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;wield&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;combat&quot;</span>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="CmdWield.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdWield.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="c1"># If in combat, check to see if it&#39;s your turn.</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="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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="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">args</span><span class="p">:</span>
@ -977,7 +557,8 @@
<span class="n">weapon</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="n">candidates</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">contents</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">weapon</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">weapon</span><span class="o">.</span><span class="n">is_typeclass</span><span class="p">(</span><span class="s2">&quot;evennia.contrib.game_systems.turnbattle.tb_equip.TBEWeapon&quot;</span><span class="p">,</span> <span class="n">exact</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">weapon</span><span class="o">.</span><span class="n">is_typeclass</span><span class="p">(</span><span class="s2">&quot;evennia.contrib.game_systems.turnbattle.tb_equip.TBEWeapon&quot;</span><span class="p">,</span>
<span class="n">exact</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">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;That&#39;s not a weapon!&quot;</span><span class="p">)</span>
<span class="c1"># Remember to update the path to the weapon typeclass if you move this module!</span>
<span class="k">return</span>
@ -992,8 +573,8 @@
<span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> lowers </span><span class="si">%s</span><span class="s2"> and wields </span><span class="si">%s</span><span class="s2">.&quot;</span> <span class="o">%</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="n">old_weapon</span><span class="p">,</span> <span class="n">weapon</span><span class="p">)</span>
<span class="p">)</span>
<span class="c1"># Spend an action if 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="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="mi">1</span><span class="p">,</span> <span class="n">action_name</span><span class="o">=</span><span class="s2">&quot;wield&quot;</span><span class="p">)</span> <span class="c1"># Use up one action.</span></div></div>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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;wield&quot;</span><span class="p">)</span> <span class="c1"># Use up one action.</span></div></div>
<div class="viewcode-block" id="CmdUnwield"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdUnwield">[docs]</a><span class="k">class</span> <span class="nc">CmdUnwield</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
@ -1010,13 +591,15 @@
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;unwield&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;combat&quot;</span>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="CmdUnwield.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdUnwield.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="c1"># If in combat, check to see if it&#39;s your turn.</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="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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="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">wielded_weapon</span><span class="p">:</span>
@ -1042,12 +625,14 @@
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;don&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;combat&quot;</span>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="CmdDon.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdDon.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="c1"># Can&#39;t do this 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="o">.</span><span class="n">caller</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="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 don armor in a fight!&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">args</span><span class="p">:</span>
@ -1056,7 +641,8 @@
<span class="n">armor</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="n">candidates</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">contents</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">armor</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">armor</span><span class="o">.</span><span class="n">is_typeclass</span><span class="p">(</span><span class="s2">&quot;evennia.contrib.game_systems.turnbattle.tb_equip.TBEArmor&quot;</span><span class="p">,</span> <span class="n">exact</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">armor</span><span class="o">.</span><span class="n">is_typeclass</span><span class="p">(</span><span class="s2">&quot;evennia.contrib.game_systems.turnbattle.tb_equip.TBEArmor&quot;</span><span class="p">,</span>
<span class="n">exact</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">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;That&#39;s not armor!&quot;</span><span class="p">)</span>
<span class="c1"># Remember to update the path to the armor typeclass if you move this module!</span>
<span class="k">return</span>
@ -1087,12 +673,14 @@
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;doff&quot;</span>
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">&quot;combat&quot;</span>
<span class="n">rules</span> <span class="o">=</span> <span class="n">COMBAT_RULES</span>
<div class="viewcode-block" id="CmdDoff.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tb_equip.html#evennia.contrib.game_systems.turnbattle.tb_equip.CmdDoff.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="c1"># Can&#39;t do this 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="o">.</span><span class="n">caller</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="o">.</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="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 doff armor in a fight!&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">worn_armor</span><span class="p">:</span>
@ -1214,7 +802,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tb_equip.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -160,45 +160,46 @@
<span class="c1"># Test combat functions</span>
<div class="viewcode-block" id="TestTurnBattleBasicFunc.test_tbbasicfunc"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tests.html#evennia.contrib.game_systems.turnbattle.tests.TestTurnBattleBasicFunc.test_tbbasicfunc">[docs]</a> <span class="k">def</span> <span class="nf">test_tbbasicfunc</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># Initiative roll</span>
<span class="n">initiative</span> <span class="o">=</span> <span class="n">tb_basic</span><span class="o">.</span><span class="n">roll_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="n">initiative</span> <span class="o">=</span> <span class="n">tb_basic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">roll_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">initiative</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">initiative</span> <span class="o">&lt;=</span> <span class="mi">1000</span><span class="p">)</span>
<span class="c1"># Attack roll</span>
<span class="n">attack_roll</span> <span class="o">=</span> <span class="n">tb_basic</span><span class="o">.</span><span class="n">get_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">attack_roll</span> <span class="o">=</span> <span class="n">tb_basic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">attack_roll</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">attack_roll</span> <span class="o">&lt;=</span> <span class="mi">100</span><span class="p">)</span>
<span class="c1"># Defense roll</span>
<span class="n">defense_roll</span> <span class="o">=</span> <span class="n">tb_basic</span><span class="o">.</span><span class="n">get_defense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">defense_roll</span> <span class="o">=</span> <span class="n">tb_basic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_defense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">defense_roll</span> <span class="o">==</span> <span class="mi">50</span><span class="p">)</span>
<span class="c1"># Damage roll</span>
<span class="n">damage_roll</span> <span class="o">=</span> <span class="n">tb_basic</span><span class="o">.</span><span class="n">get_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">damage_roll</span> <span class="o">=</span> <span class="n">tb_basic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">damage_roll</span> <span class="o">&gt;=</span> <span class="mi">15</span> <span class="ow">and</span> <span class="n">damage_roll</span> <span class="o">&lt;=</span> <span class="mi">25</span><span class="p">)</span>
<span class="c1"># Apply damage</span>
<span class="bp">self</span><span class="o">.</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">10</span>
<span class="n">tb_basic</span><span class="o">.</span><span class="n">apply_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">tb_basic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">apply_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</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">7</span><span class="p">)</span>
<span class="c1"># Resolve attack</span>
<span class="bp">self</span><span class="o">.</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">40</span>
<span class="n">tb_basic</span><span class="o">.</span><span class="n">resolve_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="n">attack_value</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">defense_value</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="n">tb_basic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">resolve_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span>
<span class="n">attack_value</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">defense_value</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</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">40</span><span class="p">)</span>
<span class="c1"># Combat cleanup</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">Combat_attribute</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">tb_basic</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="n">tb_basic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_attribute</span><span class="p">)</span>
<span class="c1"># Is in combat</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="c1"># Set up turn handler script for further tests</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">location</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="n">tb_basic</span><span class="o">.</span><span class="n">TBBasicTurnHandler</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">turnhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_TurnHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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="bp">self</span><span class="o">.</span><span class="n">turnhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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"># Set the turn handler&#39;s interval very high to keep it from repeating during tests.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">turnhandler</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="mi">10000</span>
<span class="c1"># Force turn order</span>
<span class="bp">self</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="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">]</span>
<span class="bp">self</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">turn</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># Test is turn</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_basic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="c1"># Spend actions</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</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">1</span>
<span class="n">tb_basic</span><span class="o">.</span><span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="n">tb_basic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="c1"># Initialize for combat</span>
@ -253,45 +254,45 @@
<span class="c1"># Test the combat functions in tb_equip too. They work mostly the same.</span>
<div class="viewcode-block" id="TestTurnBattleEquipFunc.test_tbequipfunc"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tests.html#evennia.contrib.game_systems.turnbattle.tests.TestTurnBattleEquipFunc.test_tbequipfunc">[docs]</a> <span class="k">def</span> <span class="nf">test_tbequipfunc</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># Initiative roll</span>
<span class="n">initiative</span> <span class="o">=</span> <span class="n">tb_equip</span><span class="o">.</span><span class="n">roll_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="n">initiative</span> <span class="o">=</span> <span class="n">tb_equip</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">roll_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">initiative</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">initiative</span> <span class="o">&lt;=</span> <span class="mi">1000</span><span class="p">)</span>
<span class="c1"># Attack roll</span>
<span class="n">attack_roll</span> <span class="o">=</span> <span class="n">tb_equip</span><span class="o">.</span><span class="n">get_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">attack_roll</span> <span class="o">=</span> <span class="n">tb_equip</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">attack_roll</span> <span class="o">&gt;=</span> <span class="o">-</span><span class="mi">50</span> <span class="ow">and</span> <span class="n">attack_roll</span> <span class="o">&lt;=</span> <span class="mi">150</span><span class="p">)</span>
<span class="c1"># Defense roll</span>
<span class="n">defense_roll</span> <span class="o">=</span> <span class="n">tb_equip</span><span class="o">.</span><span class="n">get_defense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">defense_roll</span> <span class="o">=</span> <span class="n">tb_equip</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_defense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">defense_roll</span> <span class="o">==</span> <span class="mi">50</span><span class="p">)</span>
<span class="c1"># Damage roll</span>
<span class="n">damage_roll</span> <span class="o">=</span> <span class="n">tb_equip</span><span class="o">.</span><span class="n">get_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">damage_roll</span> <span class="o">=</span> <span class="n">tb_equip</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">damage_roll</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">damage_roll</span> <span class="o">&lt;=</span> <span class="mi">50</span><span class="p">)</span>
<span class="c1"># Apply damage</span>
<span class="bp">self</span><span class="o">.</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">10</span>
<span class="n">tb_equip</span><span class="o">.</span><span class="n">apply_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">tb_equip</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">apply_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</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">7</span><span class="p">)</span>
<span class="c1"># Resolve attack</span>
<span class="bp">self</span><span class="o">.</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">40</span>
<span class="n">tb_equip</span><span class="o">.</span><span class="n">resolve_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="n">attack_value</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">defense_value</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="n">tb_equip</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">resolve_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="n">attack_value</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">defense_value</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</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">40</span><span class="p">)</span>
<span class="c1"># Combat cleanup</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">Combat_attribute</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">tb_equip</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="n">tb_equip</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_attribute</span><span class="p">)</span>
<span class="c1"># Is in combat</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="n">tb_equip</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="n">tb_equip</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="c1"># Set up turn handler script for further tests</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">location</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="n">tb_equip</span><span class="o">.</span><span class="n">TBEquipTurnHandler</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">turnhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_TurnHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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="bp">self</span><span class="o">.</span><span class="n">turnhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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"># Set the turn handler&#39;s interval very high to keep it from repeating during tests.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">turnhandler</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="mi">10000</span>
<span class="c1"># Force turn order</span>
<span class="bp">self</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="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">]</span>
<span class="bp">self</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">turn</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># Test is turn</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_equip</span><span class="o">.</span><span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_equip</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="c1"># Spend actions</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</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">1</span>
<span class="n">tb_equip</span><span class="o">.</span><span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="n">tb_equip</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="c1"># Initialize for combat</span>
@ -345,47 +346,49 @@
<span class="c1"># Test combat functions in tb_range too.</span>
<div class="viewcode-block" id="TestTurnBattleRangeFunc.test_tbrangefunc"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tests.html#evennia.contrib.game_systems.turnbattle.tests.TestTurnBattleRangeFunc.test_tbrangefunc">[docs]</a> <span class="k">def</span> <span class="nf">test_tbrangefunc</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># Initiative roll</span>
<span class="n">initiative</span> <span class="o">=</span> <span class="n">tb_range</span><span class="o">.</span><span class="n">roll_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="n">initiative</span> <span class="o">=</span> <span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">roll_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">initiative</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">initiative</span> <span class="o">&lt;=</span> <span class="mi">1000</span><span class="p">)</span>
<span class="c1"># Attack roll</span>
<span class="n">attack_roll</span> <span class="o">=</span> <span class="n">tb_range</span><span class="o">.</span><span class="n">get_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="s2">&quot;test&quot;</span><span class="p">)</span>
<span class="n">attack_roll</span> <span class="o">=</span> <span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span>
<span class="n">attack_type</span><span class="o">=</span><span class="s2">&quot;test&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">attack_roll</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">attack_roll</span> <span class="o">&lt;=</span> <span class="mi">100</span><span class="p">)</span>
<span class="c1"># Defense roll</span>
<span class="n">defense_roll</span> <span class="o">=</span> <span class="n">tb_range</span><span class="o">.</span><span class="n">get_defense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="s2">&quot;test&quot;</span><span class="p">)</span>
<span class="n">defense_roll</span> <span class="o">=</span> <span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_defense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span>
<span class="n">attack_type</span><span class="o">=</span><span class="s2">&quot;test&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">defense_roll</span> <span class="o">==</span> <span class="mi">50</span><span class="p">)</span>
<span class="c1"># Damage roll</span>
<span class="n">damage_roll</span> <span class="o">=</span> <span class="n">tb_range</span><span class="o">.</span><span class="n">get_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">damage_roll</span> <span class="o">=</span> <span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">damage_roll</span> <span class="o">&gt;=</span> <span class="mi">15</span> <span class="ow">and</span> <span class="n">damage_roll</span> <span class="o">&lt;=</span> <span class="mi">25</span><span class="p">)</span>
<span class="c1"># Apply damage</span>
<span class="bp">self</span><span class="o">.</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">10</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">apply_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">apply_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</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">7</span><span class="p">)</span>
<span class="c1"># Resolve attack</span>
<span class="bp">self</span><span class="o">.</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">40</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">resolve_attack</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="s2">&quot;test&quot;</span><span class="p">,</span> <span class="n">attack_value</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">defense_value</span><span class="o">=</span><span class="mi">10</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">resolve_attack</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="n">attack_type</span><span class="o">=</span><span class="s2">&quot;test&quot;</span><span class="p">,</span> <span class="n">attack_value</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">defense_value</span><span class="o">=</span><span class="mi">10</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</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">40</span><span class="p">)</span>
<span class="c1"># Combat cleanup</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">Combat_attribute</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_attribute</span><span class="p">)</span>
<span class="c1"># Is in combat</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="n">tb_range</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="c1"># Set up turn handler script for further tests</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">location</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="n">tb_range</span><span class="o">.</span><span class="n">TBRangeTurnHandler</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">turnhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_TurnHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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="bp">self</span><span class="o">.</span><span class="n">turnhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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"># Set the turn handler&#39;s interval very high to keep it from repeating during tests.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">turnhandler</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="mi">10000</span>
<span class="c1"># Force turn order</span>
<span class="bp">self</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="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">]</span>
<span class="bp">self</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">turn</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># Test is turn</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_range</span><span class="o">.</span><span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="c1"># Spend actions</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</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">1</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="c1"># Initialize for combat</span>
@ -403,7 +406,7 @@
<span class="c1"># Start turn</span>
<span class="bp">self</span><span class="o">.</span><span class="n">defender</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="bp">self</span><span class="o">.</span><span class="n">turnhandler</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">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</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">2</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">defender</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="mi">2</span><span class="p">)</span>
<span class="c1"># Next turn</span>
<span class="bp">self</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="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">]</span>
<span class="bp">self</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">turn</span> <span class="o">=</span> <span class="mi">0</span>
@ -422,13 +425,13 @@
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</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">turn</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">assertTrue</span><span class="p">(</span><span class="bp">self</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="o">==</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">joiner</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">])</span>
<span class="c1"># Now, test for approach/withdraw functions</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_range</span><span class="o">.</span><span class="n">get_range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</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">assertTrue</span><span class="p">(</span><span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1"># Approach</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">approach</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_range</span><span class="o">.</span><span class="n">get_range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">approach</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="c1"># Withdraw</span>
<span class="n">tb_range</span><span class="o">.</span><span class="n">withdraw</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_range</span><span class="o">.</span><span class="n">get_range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span></div></div>
<span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">withdraw</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_range</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="TestTurnBattleItemsFunc"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tests.html#evennia.contrib.game_systems.turnbattle.tests.TestTurnBattleItemsFunc">[docs]</a><span class="k">class</span> <span class="nc">TestTurnBattleItemsFunc</span><span class="p">(</span><span class="n">BaseEvenniaTest</span><span class="p">):</span>
@ -460,45 +463,46 @@
<span class="c1"># Test functions in tb_items.</span>
<div class="viewcode-block" id="TestTurnBattleItemsFunc.test_tbitemsfunc"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tests.html#evennia.contrib.game_systems.turnbattle.tests.TestTurnBattleItemsFunc.test_tbitemsfunc">[docs]</a> <span class="k">def</span> <span class="nf">test_tbitemsfunc</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># Initiative roll</span>
<span class="n">initiative</span> <span class="o">=</span> <span class="n">tb_items</span><span class="o">.</span><span class="n">roll_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="n">initiative</span> <span class="o">=</span> <span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">roll_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">initiative</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">initiative</span> <span class="o">&lt;=</span> <span class="mi">1000</span><span class="p">)</span>
<span class="c1"># Attack roll</span>
<span class="n">attack_roll</span> <span class="o">=</span> <span class="n">tb_items</span><span class="o">.</span><span class="n">get_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">attack_roll</span> <span class="o">=</span> <span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">attack_roll</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">attack_roll</span> <span class="o">&lt;=</span> <span class="mi">100</span><span class="p">)</span>
<span class="c1"># Defense roll</span>
<span class="n">defense_roll</span> <span class="o">=</span> <span class="n">tb_items</span><span class="o">.</span><span class="n">get_defense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">defense_roll</span> <span class="o">=</span> <span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_defense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">defense_roll</span> <span class="o">==</span> <span class="mi">50</span><span class="p">)</span>
<span class="c1"># Damage roll</span>
<span class="n">damage_roll</span> <span class="o">=</span> <span class="n">tb_items</span><span class="o">.</span><span class="n">get_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">damage_roll</span> <span class="o">=</span> <span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">damage_roll</span> <span class="o">&gt;=</span> <span class="mi">15</span> <span class="ow">and</span> <span class="n">damage_roll</span> <span class="o">&lt;=</span> <span class="mi">25</span><span class="p">)</span>
<span class="c1"># Apply damage</span>
<span class="bp">self</span><span class="o">.</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">10</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">apply_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">apply_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</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">7</span><span class="p">)</span>
<span class="c1"># Resolve attack</span>
<span class="bp">self</span><span class="o">.</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">40</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">resolve_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="n">attack_value</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">defense_value</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">resolve_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="n">attack_value</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span>
<span class="n">defense_value</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</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">40</span><span class="p">)</span>
<span class="c1"># Combat cleanup</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">Combat_attribute</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_attribute</span><span class="p">)</span>
<span class="c1"># Is in combat</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="n">tb_items</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="c1"># Set up turn handler script for further tests</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">location</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="n">tb_items</span><span class="o">.</span><span class="n">TBItemsTurnHandler</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">turnhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_TurnHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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="bp">self</span><span class="o">.</span><span class="n">turnhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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"># Set the turn handler&#39;s interval very high to keep it from repeating during tests.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">turnhandler</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="mi">10000</span>
<span class="c1"># Force turn order</span>
<span class="bp">self</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="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">]</span>
<span class="bp">self</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">turn</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># Test is turn</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_items</span><span class="o">.</span><span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="c1"># Spend actions</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</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">1</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="c1"># Initialize for combat</span>
@ -529,29 +533,29 @@
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</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="o">==</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">joiner</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">])</span>
<span class="c1"># Now time to test item stuff.</span>
<span class="c1"># Spend item use</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">spend_item_use</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">spend_item_use</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">item_uses</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span>
<span class="c1"># Use item</span>
<span class="bp">self</span><span class="o">.</span><span class="n">user</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">2</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">use_item</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">use_item</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">hp</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">)</span>
<span class="c1"># Add contition</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">add_condition</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="s2">&quot;Test&quot;</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">add_condition</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="s2">&quot;Test&quot;</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">conditions</span> <span class="o">==</span> <span class="p">{</span><span class="s2">&quot;Test&quot;</span><span class="p">:</span> <span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">]})</span>
<span class="c1"># Condition tickdown</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">condition_tickdown</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">conditions</span> <span class="o">==</span> <span class="p">{</span><span class="s2">&quot;Test&quot;</span><span class="p">:</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">]})</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">condition_tickdown</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</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">user</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">conditions</span><span class="p">,</span> <span class="p">{</span><span class="s2">&quot;Test&quot;</span><span class="p">:</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">]})</span>
<span class="c1"># Test item functions now!</span>
<span class="c1"># Item heal</span>
<span class="bp">self</span><span class="o">.</span><span class="n">user</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">2</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">itemfunc_heal</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">itemfunc_heal</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="c1"># Item add condition</span>
<span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">conditions</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">itemfunc_add_condition</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">itemfunc_add_condition</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">conditions</span> <span class="o">==</span> <span class="p">{</span><span class="s2">&quot;Regeneration&quot;</span><span class="p">:</span> <span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">]})</span>
<span class="c1"># Item cure condition</span>
<span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">conditions</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;Poisoned&quot;</span><span class="p">:</span> <span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">]}</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">itemfunc_cure_condition</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="n">tb_items</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">itemfunc_cure_condition</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">test_healpotion</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">conditions</span> <span class="o">==</span> <span class="p">{})</span></div></div>
@ -578,45 +582,46 @@
<span class="c1"># Test combat functions in tb_magic.</span>
<div class="viewcode-block" id="TestTurnBattleMagicFunc.test_tbbasicfunc"><a class="viewcode-back" href="../../../../../api/evennia.contrib.game_systems.turnbattle.tests.html#evennia.contrib.game_systems.turnbattle.tests.TestTurnBattleMagicFunc.test_tbbasicfunc">[docs]</a> <span class="k">def</span> <span class="nf">test_tbbasicfunc</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># Initiative roll</span>
<span class="n">initiative</span> <span class="o">=</span> <span class="n">tb_magic</span><span class="o">.</span><span class="n">roll_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="n">initiative</span> <span class="o">=</span> <span class="n">tb_magic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">roll_init</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">initiative</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">initiative</span> <span class="o">&lt;=</span> <span class="mi">1000</span><span class="p">)</span>
<span class="c1"># Attack roll</span>
<span class="n">attack_roll</span> <span class="o">=</span> <span class="n">tb_magic</span><span class="o">.</span><span class="n">get_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">attack_roll</span> <span class="o">=</span> <span class="n">tb_magic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">attack_roll</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">attack_roll</span> <span class="o">&lt;=</span> <span class="mi">100</span><span class="p">)</span>
<span class="c1"># Defense roll</span>
<span class="n">defense_roll</span> <span class="o">=</span> <span class="n">tb_magic</span><span class="o">.</span><span class="n">get_defense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">defense_roll</span> <span class="o">=</span> <span class="n">tb_magic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_defense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">defense_roll</span> <span class="o">==</span> <span class="mi">50</span><span class="p">)</span>
<span class="c1"># Damage roll</span>
<span class="n">damage_roll</span> <span class="o">=</span> <span class="n">tb_magic</span><span class="o">.</span><span class="n">get_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="n">damage_roll</span> <span class="o">=</span> <span class="n">tb_magic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">get_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">damage_roll</span> <span class="o">&gt;=</span> <span class="mi">15</span> <span class="ow">and</span> <span class="n">damage_roll</span> <span class="o">&lt;=</span> <span class="mi">25</span><span class="p">)</span>
<span class="c1"># Apply damage</span>
<span class="bp">self</span><span class="o">.</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">10</span>
<span class="n">tb_magic</span><span class="o">.</span><span class="n">apply_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">tb_magic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">apply_damage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</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">7</span><span class="p">)</span>
<span class="c1"># Resolve attack</span>
<span class="bp">self</span><span class="o">.</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">40</span>
<span class="n">tb_magic</span><span class="o">.</span><span class="n">resolve_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="n">attack_value</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">defense_value</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="n">tb_magic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">resolve_attack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">,</span> <span class="n">attack_value</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span>
<span class="n">defense_value</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</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">40</span><span class="p">)</span>
<span class="c1"># Combat cleanup</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">Combat_attribute</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">tb_magic</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="n">tb_magic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">combat_cleanup</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_attribute</span><span class="p">)</span>
<span class="c1"># Is in combat</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="n">tb_magic</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="n">tb_magic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">is_in_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="c1"># Set up turn handler script for further tests</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">location</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="n">tb_magic</span><span class="o">.</span><span class="n">TBMagicTurnHandler</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">turnhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_TurnHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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="bp">self</span><span class="o">.</span><span class="n">turnhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combat_turnHandler</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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"># Set the turn handler&#39;s interval very high to keep it from repeating during tests.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">turnhandler</span><span class="o">.</span><span class="n">interval</span> <span class="o">=</span> <span class="mi">10000</span>
<span class="c1"># Force turn order</span>
<span class="bp">self</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="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">defender</span><span class="p">]</span>
<span class="bp">self</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">turn</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c1"># Test is turn</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_magic</span><span class="o">.</span><span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">tb_magic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">is_turn</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</span><span class="p">))</span>
<span class="c1"># Spend actions</span>
<span class="bp">self</span><span class="o">.</span><span class="n">attacker</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">1</span>
<span class="n">tb_magic</span><span class="o">.</span><span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="n">tb_magic</span><span class="o">.</span><span class="n">COMBAT_RULES</span><span class="o">.</span><span class="n">spend_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">attacker</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;Test&quot;</span><span class="p">)</span>
<span class="c1"># Initialize for combat</span>
@ -679,7 +684,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -669,7 +669,6 @@
<h3>Versions</h3>
<ul>
<li><a href="extended_room.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -179,7 +179,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -270,7 +270,6 @@
<h3>Versions</h3>
<ul>
<li><a href="simpledoor.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -105,7 +105,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -250,7 +250,6 @@
<h3>Versions</h3>
<ul>
<li><a href="slow_exit.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -103,7 +103,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -213,7 +213,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -850,7 +850,6 @@
<h3>Versions</h3>
<ul>
<li><a href="wilderness.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -550,7 +550,6 @@
<h3>Versions</h3>
<ul>
<li><a href="commands.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -367,7 +367,6 @@
<h3>Versions</h3>
<ul>
<li><a href="example.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -500,7 +500,6 @@
<h3>Versions</h3>
<ul>
<li><a href="launchcmd.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1374,7 +1374,6 @@
<h3>Versions</h3>
<ul>
<li><a href="tests.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -131,7 +131,6 @@
<h3>Versions</h3>
<ul>
<li><a href="utils.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

View file

@ -1021,7 +1021,6 @@
<h3>Versions</h3>
<ul>
<li><a href="xymap.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>

Some files were not shown because too many files have changed in this diff Show more