evennia/docs/1.0-dev/api/evennia.contrib.traits.html
2020-11-14 11:55:52 +01:00

920 lines
No EOL
66 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.contrib.traits &#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>
<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-this"><a href="">evennia.contrib.traits</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="module-evennia.contrib.traits">
<span id="evennia-contrib-traits"></span><h1>evennia.contrib.traits<a class="headerlink" href="#module-evennia.contrib.traits" title="Permalink to this headline"></a></h1>
<p>Traits</p>
<p>Whitenoise 2014, Ainneve contributors,
Griatch 2020</p>
<p>A <strong>Trait</strong> represents a modifiable property on (usually) a Character. They can
be used to represent everything from attributes (str, agi etc) to skills
(hunting 10, swords 14 etc) and dynamically changing things like HP, XP etc.</p>
<p>Traits use Evennia Attributes under the hood, making them persistent (they survive
a server reload/reboot).</p>
<div class="section" id="adding-traits-to-a-typeclass">
<h2>Adding Traits to a typeclass<a class="headerlink" href="#adding-traits-to-a-typeclass" title="Permalink to this headline"></a></h2>
<p>To access and manipulate traits on an object, its Typeclass needs to have a
<strong>TraitHandler</strong> assigned it. Usually, the handler is made available as <strong>.traits</strong>
(in the same way as <strong>.tags</strong> or <strong>.attributes</strong>).</p>
<p>Heres an example for adding the TraitHandler to the base Object class:</p>
<blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># mygame/typeclasses/objects.py</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="k">import</span> <span class="n">DefaultObject</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="k">import</span> <span class="n">lazy_property</span>
<span class="kn">from</span> <span class="nn">evennia.contrib.traits</span> <span class="k">import</span> <span class="n">TraitHandler</span>
<span class="c1"># ...</span>
<span class="k">class</span> <span class="nc">Object</span><span class="p">(</span><span class="n">DefaultObject</span><span class="p">):</span>
<span class="o">...</span>
<span class="nd">@lazy_property</span>
<span class="k">def</span> <span class="nf">traits</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># this adds the handler as .traits</span>
<span class="k">return</span> <span class="n">TraitHandler</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>After a reload you can now try adding some example traits:</p>
</div>
<div class="section" id="using-traits">
<h2>Using traits<a class="headerlink" href="#using-traits" title="Permalink to this headline"></a></h2>
<p>A trait is added to the traithandler, after which one can access it
as a property on the handler (similarly to how you can do .db.attrname for Attributes
in Evennia).</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># this is an example using the &quot;static&quot; trait, described below</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;hunting&quot;</span><span class="p">,</span> <span class="s2">&quot;Hunting Skill&quot;</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="s2">&quot;static&quot;</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="mi">4</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span> <span class="o">+=</span> <span class="mi">5</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="mi">9</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;hp&quot;</span><span class="p">,</span> <span class="s2">&quot;Health&quot;</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="s2">&quot;gauge&quot;</span><span class="p">,</span> <span class="nb">min</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">value</span>
<span class="mi">100</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span> <span class="o">-=</span> <span class="mi">200</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">value</span>
<span class="mi">0</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">value</span>
<span class="mi">100</span>
<span class="c1"># you can also access property with getitem</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="p">[</span><span class="s2">&quot;value&quot;</span><span class="p">]</span>
<span class="mi">100</span>
<span class="c1"># you can store arbitrary data persistently as well</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">effect</span> <span class="o">=</span> <span class="s2">&quot;poisoned!&quot;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">effect</span>
<span class="s2">&quot;poisoned!&quot;</span>
</pre></div>
</div>
<p>When adding the trait, you supply the name of the property (<strong>hunting</strong>) along
with a more human-friendly name (“Hunting Skill”). The latter will show if you
print the trait etc. The <strong>trait_type</strong> is important, this specifies which type
of trait this is.</p>
</div>
<div class="section" id="trait-types">
<h2>Trait types<a class="headerlink" href="#trait-types" title="Permalink to this headline"></a></h2>
<p>All default traits have a read-only <strong>.value</strong> property that shows the relevant or
current value of the trait. Exactly what this means depends on the type of trait.</p>
<p>Traits can also be combined to do arithmetic with their .value, if both have a
compatible type.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">trait1</span> <span class="o">+</span> <span class="n">trait2</span>
<span class="go">54</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">trait1</span><span class="o">.</span><span class="n">value</span>
<span class="go">3</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">trait1</span> <span class="o">+</span> <span class="mi">2</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">trait1</span><span class="o">.</span><span class="n">value</span>
<span class="go">5</span>
</pre></div>
</div>
<p>Two numerical traits can also be compared (bigger-than etc), which is useful in
all sorts of rule-resolution.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">trait1</span> <span class="o">&gt;</span> <span class="n">trait2</span><span class="p">:</span>
<span class="c1"># do stuff</span>
</pre></div>
</div>
</div>
<div class="section" id="static-trait">
<h2>Static trait<a class="headerlink" href="#static-trait" title="Permalink to this headline"></a></h2>
<p><strong>value = base + mod</strong></p>
<p>The static trait has a <strong>base</strong> value and an optional <strong>mod</strong>-ifier. A typical use
of a static trait would be a Strength stat or Skill value. That is, something
that varies slowly or not at all, and which may be modified in-place.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;str&quot;</span><span class="p">,</span> <span class="s2">&quot;Strength&quot;</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="s2">&quot;static&quot;</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">mod</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">mytrait</span><span class="o">.</span><span class="n">value</span>
<span class="go">12 # base + mod</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">mytrait</span><span class="o">.</span><span class="n">base</span> <span class="o">+=</span> <span class="mi">2</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">mytrait</span><span class="o">.</span><span class="n">mod</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">mytrait</span><span class="o">.</span><span class="n">value</span>
<span class="go">15</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">mytrait</span><span class="o">.</span><span class="n">mod</span> <span class="o">=</span> <span class="mi">0</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">mytrait</span><span class="o">.</span><span class="n">value</span>
<span class="go">12</span>
</pre></div>
</div>
<div class="section" id="counter">
<h3>Counter<a class="headerlink" href="#counter" title="Permalink to this headline"></a></h3>
<blockquote>
<div><dl class="simple">
<dt>min/unset base base+mod max/unset</dt><dd><dl class="simple">
<dt><a href="#id1"><span class="problematic" id="id2">|--------------|</span></a>——–<a href="#id3"><span class="problematic" id="id4">|---------X--------X------------|</span></a></dt><dd><dl class="simple">
<dt>current value</dt><dd><p>= current
+ mod</p>
</dd>
</dl>
</dd>
</dl>
</dd>
</dl>
</div></blockquote>
<p>A counter describes a value that can move from a base. The <strong>current</strong> property
is the thing usually modified. It starts at the <strong>base</strong>. One can also add a modifier,
which will both be added to the base and to current (forming .value).
The min/max of the range are optional, a boundary set to None will remove it.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;hunting&quot;</span><span class="p">,</span> <span class="s2">&quot;Hunting Skill&quot;</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="s2">&quot;counter&quot;</span><span class="p">,</span>
<span class="go"> base=10, mod=1, min=0, max=100)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="go">11 # current starts at base + mod</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">current</span> <span class="o">+=</span> <span class="mi">10</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="go">21</span>
<span class="go"># reset back to base+mod by deleting current</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">del</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">current</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="go">11</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">max</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># removing upper bound</span>
</pre></div>
</div>
<p>Counters have some extra properties:</p>
<p><strong>descs</strong> is a dict {upper_bound:text_description}. This allows for easily
storing a more human-friendly description of the current value in the
interval. Here is an example for skill values between 0 and 10:</p>
<blockquote>
<div><p>{0: “unskilled”, 1: “neophyte”, 5: “trained”, 7: “expert”, 9: “master”}</p>
</div></blockquote>
<p>The keys must be supplied from smallest to largest. Any values below the lowest and above the
highest description will be considered to be included in the closest description slot.
By calling <strong>.desc()</strong> on the Counter, will you get the text matching the current <strong>value</strong>
value.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># (could also have passed descs= to traits.add())</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">descs</span> <span class="o">=</span> <span class="p">{</span>
<span class="mi">0</span><span class="p">:</span> <span class="s2">&quot;unskilled&quot;</span><span class="p">,</span> <span class="mi">10</span><span class="p">:</span> <span class="s2">&quot;neophyte&quot;</span><span class="p">,</span> <span class="mi">50</span><span class="p">:</span> <span class="s2">&quot;trained&quot;</span><span class="p">,</span> <span class="mi">70</span><span class="p">:</span> <span class="s2">&quot;expert&quot;</span><span class="p">,</span> <span class="mi">90</span><span class="p">:</span> <span class="s2">&quot;master&quot;</span><span class="p">}</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="mi">11</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">desc</span><span class="p">()</span>
<span class="s2">&quot;neophyte&quot;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">current</span> <span class="o">+=</span> <span class="mi">60</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="mi">71</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">desc</span><span class="p">()</span>
<span class="s2">&quot;expert&quot;</span>
</pre></div>
</div>
<div class="section" id="rate">
<h4>.rate<a class="headerlink" href="#rate" title="Permalink to this headline"></a></h4>
<p>The <strong>rate</strong> property defaults to 0. If set to a value different from 0, it
allows the trait to change value dynamically. This could be used for example
for an attribute that was temporarily lowered but will gradually (or abruptly)
recover after a certain time. The rate is given as change of the <strong>current</strong>
per-second, and the .value will still be restrained by min/max boundaries, if
those are set.</p>
<p>It is also possible to set a “.ratetarget”, for the auto-change to stop at
(rather than at the min/max boundaries). This allows the value to return to
a previous value.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="go">71</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">ratetarget</span> <span class="o">=</span> <span class="mi">71</span>
<span class="go"># debuff hunting for some reason</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">current</span> <span class="o">-=</span> <span class="mi">30</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="go">41</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">rate</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># 1/s increase</span>
<span class="go"># Waiting 5s</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="go">46</span>
<span class="go"># Waiting 8s</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="go">54</span>
<span class="go"># Waiting 100s</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">value</span>
<span class="go">71 # we have stopped at the ratetarget</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">rate</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># disable auto-change</span>
</pre></div>
</div>
<p>Note that if rate is a non-integer, the resulting .value (at least until it
reaches the boundary) will likely also come out a float. If you expect an
integer, you must run run int() on the result yourself.</p>
</div>
<div class="section" id="percentage">
<h4>.percentage()<a class="headerlink" href="#percentage" title="Permalink to this headline"></a></h4>
<p>If both min and max are defined, the <strong>.percentage()</strong> method of the trait will
return the value as a percentage.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hunting</span><span class="o">.</span><span class="n">percentage</span><span class="p">()</span>
<span class="go">&quot;71.0%&quot;</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="gauge">
<h3>Gauge<a class="headerlink" href="#gauge" title="Permalink to this headline"></a></h3>
<p>This emulates a [fuel-] gauge that empties from a base+mod value.</p>
<blockquote>
<div><dl>
<dt>min/0 max=base+mod</dt><dd><dl>
<dt><a href="#id5"><span class="problematic" id="id6">|-----------------------X---------------------------|</span></a></dt><dd><blockquote>
<div><p>value</p>
</div></blockquote>
<p>= current</p>
</dd>
</dl>
</dd>
</dl>
</div></blockquote>
<p>The current value will start from a full gauge. The .max property is
read-only and is set by .base + .mod. So contrary to a Counter, the modifier
only applies to the max value of the gauge and not the current value. The
minimum bound defaults to 0. This trait is useful for showing resources that
can deplete, like health, stamina and the like.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;hp&quot;</span><span class="p">,</span> <span class="s2">&quot;Health&quot;</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="s2">&quot;gauge&quot;</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">value</span> <span class="c1"># (or .current)</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">mod</span> <span class="o">=</span> <span class="mi">10</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">value</span>
<span class="go">110</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">current</span> <span class="o">-=</span> <span class="mi">30</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="o">.</span><span class="n">value</span>
<span class="go">80</span>
</pre></div>
</div>
<p>Same as Counters, Gauges can also have <strong>descs</strong> to describe the interval and can also
have <strong>rate</strong> and <strong>ratetarget</strong> to auto-update the value. The rate is particularly useful
for gauges, for everything from poison slowly draining your health, to resting gradually
increasing it. You can also use the <strong>.percentage()</strong> function to show the current value
as a percentage.</p>
</div>
<div class="section" id="trait">
<h3>Trait<a class="headerlink" href="#trait" title="Permalink to this headline"></a></h3>
<p>A single value of any type.</p>
<p>This is the base Trait, meant to inherit from if you want to make your own
trait-types (see below). Its .value can be anything (that can be stored in an Attribute)
and if its a integer/float you can do arithmetic with it, but otherwise it
acts just like a glorified Attribute.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;mytrait&quot;</span><span class="p">,</span> <span class="s2">&quot;My Trait&quot;</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="s2">&quot;trait&quot;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">30</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">mytrait</span><span class="o">.</span><span class="n">value</span>
<span class="go">30</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">mytrait</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="s2">&quot;stringvalue&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">mytrait</span><span class="o">.</span><span class="n">value</span>
<span class="go">&quot;stringvalue&quot;</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="expanding-with-your-own-traits">
<h2>Expanding with your own Traits<a class="headerlink" href="#expanding-with-your-own-traits" title="Permalink to this headline"></a></h2>
<p>A Trait is a class inhering from <strong>evennia.contrib.traits.Trait</strong> (or
from one of the existing Trait classes).</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># in a file, say, &#39;mygame/world/traits.py&#39;</span>
<span class="kn">from</span> <span class="nn">evennia.contrib.traits</span> <span class="k">import</span> <span class="n">Trait</span>
<span class="k">class</span> <span class="nc">RageTrait</span><span class="p">(</span><span class="n">Trait</span><span class="p">):</span>
<span class="n">trait_type</span> <span class="o">=</span> <span class="s2">&quot;rage&quot;</span>
<span class="n">default_keys</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;rage&quot;</span><span class="p">:</span> <span class="mi">0</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Above is an example custom-trait-class “rage” that stores a property “rage” on
itself, with a default value of 0. This has all the
functionality of a Trait - for example, if you do del on the <strong>rage</strong> property, it will be
set back to its default (0). If you wanted to customize what it does, you
just add <strong>rage</strong> property get/setters/deleters on the class.</p>
<p>To add your custom RageTrait to Evennia, add the following to your settings file
(assuming your class is in mygame/world/traits.py):</p>
<blockquote>
<div><p>TRAIT_CLASS_PATHS = [“world.traits.RageTrait”]</p>
</div></blockquote>
<p>Reload the server and you should now be able to use your trait:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;mood&quot;</span><span class="p">,</span> <span class="s2">&quot;A dark mood&quot;</span><span class="p">,</span> <span class="n">rage</span><span class="o">=</span><span class="mi">30</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">mood</span><span class="o">.</span><span class="n">rage</span>
<span class="go">30</span>
</pre></div>
</div>
<hr class="docutils" />
<dl class="py exception">
<dt id="evennia.contrib.traits.TraitException">
<em class="property">exception </em><code class="sig-prename descclassname">evennia.contrib.traits.</code><code class="sig-name descname">TraitException</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">msg</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#TraitException"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.TraitException" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">RuntimeError</span></code></p>
<p>Base exception class raised by <strong>Trait</strong> objects.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>msg</strong> (<em>str</em>) informative error message</p>
</dd>
</dl>
<dl class="py method">
<dt id="evennia.contrib.traits.TraitException.__init__">
<code class="sig-name descname">__init__</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">msg</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#TraitException.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.TraitException.__init__" title="Permalink to this definition"></a></dt>
<dd><p>Initialize self. See help(type(self)) for accurate signature.</p>
</dd></dl>
</dd></dl>
<dl class="py class">
<dt id="evennia.contrib.traits.MandatoryTraitKey">
<em class="property">class </em><code class="sig-prename descclassname">evennia.contrib.traits.</code><code class="sig-name descname">MandatoryTraitKey</code><a class="reference internal" href="../_modules/evennia/contrib/traits.html#MandatoryTraitKey"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.MandatoryTraitKey" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>This represents a required key that must be
supplied when a Trait is initialized. Its used
by Trait classes when defining their required keys.</p>
</dd></dl>
<dl class="py class">
<dt id="evennia.contrib.traits.TraitHandler">
<em class="property">class </em><code class="sig-prename descclassname">evennia.contrib.traits.</code><code class="sig-name descname">TraitHandler</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">obj</span></em>, <em class="sig-param"><span class="n">db_attribute_key</span><span class="o">=</span><span class="default_value">'traits'</span></em>, <em class="sig-param"><span class="n">db_attribute_category</span><span class="o">=</span><span class="default_value">'traits'</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#TraitHandler"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.TraitHandler" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>Factory class that instantiates Trait objects.</p>
<dl class="py method">
<dt id="evennia.contrib.traits.TraitHandler.__init__">
<code class="sig-name descname">__init__</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">obj</span></em>, <em class="sig-param"><span class="n">db_attribute_key</span><span class="o">=</span><span class="default_value">'traits'</span></em>, <em class="sig-param"><span class="n">db_attribute_category</span><span class="o">=</span><span class="default_value">'traits'</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#TraitHandler.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.TraitHandler.__init__" title="Permalink to this definition"></a></dt>
<dd><p>Initialize the handler and set up its internal Attribute-based storage.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>obj</strong> (<em>Object</em>) Parent Object typeclass for this TraitHandler</p></li>
<li><p><strong>db_attribute_key</strong> (<em>str</em>) Name of the DB attribute for trait data storage</p></li>
</ul>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.TraitHandler.all">
<em class="property">property </em><code class="sig-name descname">all</code><a class="headerlink" href="#evennia.contrib.traits.TraitHandler.all" title="Permalink to this definition"></a></dt>
<dd><p>Get all trait keys in this handler.</p>
<dl class="field-list simple">
<dt class="field-odd">Returns</dt>
<dd class="field-odd"><p><em>list</em> All Trait keys.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.TraitHandler.get">
<code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">trait_key</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#TraitHandler.get"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.TraitHandler.get" title="Permalink to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>trait_key</strong> (<em>str</em>) key from the traits dict containing config data.</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>(<strong>Trait</strong> or <strong>None</strong>) named Trait class or None if trait key
is not found in traits collection.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.TraitHandler.add">
<code class="sig-name descname">add</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">trait_key</span></em>, <em class="sig-param"><span class="n">name</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">trait_type</span><span class="o">=</span><span class="default_value">'static'</span></em>, <em class="sig-param"><span class="n">force</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="o">**</span><span class="n">trait_properties</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#TraitHandler.add"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.TraitHandler.add" title="Permalink to this definition"></a></dt>
<dd><p>Create a new Trait and add it to the handler.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>trait_key</strong> (<em>str</em>) This is the name of the property that will be made
available on this handler (example hp).</p></li>
<li><p><strong>name</strong> (<em>str</em><em>, </em><em>optional</em>) Name of the Trait, like “Health”. If
not given, will use <strong>trait_key</strong> starting with a capital letter.</p></li>
<li><p><strong>trait_type</strong> (<em>str</em><em>, </em><em>optional</em>) One of static, counter or gauge.</p></li>
<li><p><strong>force_add</strong> (<em>bool</em>) If set, create a new Trait even if a Trait with
the same <strong>trait_key</strong> already exists.</p></li>
<li><p><strong>trait_properties</strong> (<em>dict</em>) These will all be use to initialize
the new trait. See the <strong>properties</strong> class variable on each
Trait class to see which are required.</p></li>
</ul>
</dd>
<dt class="field-even">Raises</dt>
<dd class="field-even"><p><a class="reference internal" href="#evennia.contrib.traits.TraitException" title="evennia.contrib.traits.TraitException"><strong>TraitException</strong></a> If specifying invalid values for the given Trait,
the <strong>trait_type</strong> is not recognized, or an existing trait
already exists (and <strong>force</strong> is unset).</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.TraitHandler.remove">
<code class="sig-name descname">remove</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">trait_key</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#TraitHandler.remove"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.TraitHandler.remove" title="Permalink to this definition"></a></dt>
<dd><p>Remove a Trait from the handlers parent object.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>trait_key</strong> (<em>str</em>) The name of the trait to remove.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.TraitHandler.clear">
<code class="sig-name descname">clear</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#TraitHandler.clear"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.TraitHandler.clear" title="Permalink to this definition"></a></dt>
<dd><p>Remove all Traits from the handlers parent object.</p>
</dd></dl>
</dd></dl>
<dl class="py class">
<dt id="evennia.contrib.traits.Trait">
<em class="property">class </em><code class="sig-prename descclassname">evennia.contrib.traits.</code><code class="sig-name descname">Trait</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">trait_data</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#Trait"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.Trait" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
<p>Represents an object or Character trait. This simple base is just
storing anything in its value property, so its pretty much just a
different wrapper to an Attribute. It does no type-checking of what is
stored.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>See module docstring for configuration details.</p>
</div>
<p>value</p>
<dl class="py attribute">
<dt id="evennia.contrib.traits.Trait.trait_type">
<code class="sig-name descname">trait_type</code><em class="property"> = 'trait'</em><a class="headerlink" href="#evennia.contrib.traits.Trait.trait_type" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt id="evennia.contrib.traits.Trait.default_keys">
<code class="sig-name descname">default_keys</code><em class="property"> = {'value': None}</em><a class="headerlink" href="#evennia.contrib.traits.Trait.default_keys" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt id="evennia.contrib.traits.Trait.allow_extra_properties">
<code class="sig-name descname">allow_extra_properties</code><em class="property"> = True</em><a class="headerlink" href="#evennia.contrib.traits.Trait.allow_extra_properties" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.Trait.__init__">
<code class="sig-name descname">__init__</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">trait_data</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#Trait.__init__"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.Trait.__init__" title="Permalink to this definition"></a></dt>
<dd><p>This both initializes and validates the Trait on creation. It must
raise exception if validation fails. The TraitHandler will call this
when the trait is furst added, to make sure it validates before
storing.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>trait_data</strong> (<em>any</em>) Any pickle-able values to store with this trait.
This must contain any cls.default_keys that do not have a default
value in cls.data_default_values. Any extra kwargs will be made
available as extra properties on the Trait, assuming the class
variable <strong>allow_extra_properties</strong> is set.</p>
</dd>
<dt class="field-even">Raises</dt>
<dd class="field-even"><p><a class="reference internal" href="#evennia.contrib.traits.TraitException" title="evennia.contrib.traits.TraitException"><strong>TraitException</strong></a> If input-validation failed.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.Trait.validate_input">
<em class="property">static </em><code class="sig-name descname">validate_input</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">cls</span></em>, <em class="sig-param"><span class="n">trait_data</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#Trait.validate_input"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.Trait.validate_input" title="Permalink to this definition"></a></dt>
<dd><p>Validate input</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>trait_data</strong> (<em>dict</em><em> or </em><em>_SaverDict</em>) Data to be used for
initialization of this trait.</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p><p><em>dict</em> </p>
<dl class="simple">
<dt>Validated data, possibly complemented with default</dt><dd><p>values from default_keys.</p>
</dd>
</dl>
</p>
</dd>
<dt class="field-odd">Raises</dt>
<dd class="field-odd"><p><a class="reference internal" href="#evennia.contrib.traits.TraitException" title="evennia.contrib.traits.TraitException"><strong>TraitException</strong></a> If finding unset keys without a default.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.Trait.name">
<em class="property">property </em><code class="sig-name descname">name</code><a class="headerlink" href="#evennia.contrib.traits.Trait.name" title="Permalink to this definition"></a></dt>
<dd><p>Display name for the trait.</p>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.Trait.key">
<em class="property">property </em><code class="sig-name descname">key</code><a class="headerlink" href="#evennia.contrib.traits.Trait.key" title="Permalink to this definition"></a></dt>
<dd><p>Display name for the trait.</p>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.Trait.value">
<em class="property">property </em><code class="sig-name descname">value</code><a class="headerlink" href="#evennia.contrib.traits.Trait.value" title="Permalink to this definition"></a></dt>
<dd><p>Store a value</p>
</dd></dl>
</dd></dl>
<dl class="py class">
<dt id="evennia.contrib.traits.StaticTrait">
<em class="property">class </em><code class="sig-prename descclassname">evennia.contrib.traits.</code><code class="sig-name descname">StaticTrait</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">trait_data</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#StaticTrait"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.StaticTrait" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <a class="reference internal" href="#evennia.contrib.traits.Trait" title="evennia.contrib.traits.Trait"><code class="xref py py-class docutils literal notranslate"><span class="pre">evennia.contrib.traits.Trait</span></code></a></p>
<p>Static Trait. This is a single value with a modifier,
with no concept of a current value.</p>
<p>value = base + mod</p>
<dl class="py attribute">
<dt id="evennia.contrib.traits.StaticTrait.trait_type">
<code class="sig-name descname">trait_type</code><em class="property"> = 'static'</em><a class="headerlink" href="#evennia.contrib.traits.StaticTrait.trait_type" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt id="evennia.contrib.traits.StaticTrait.default_keys">
<code class="sig-name descname">default_keys</code><em class="property"> = {'base': 0, 'mod': 0}</em><a class="headerlink" href="#evennia.contrib.traits.StaticTrait.default_keys" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.StaticTrait.mod">
<em class="property">property </em><code class="sig-name descname">mod</code><a class="headerlink" href="#evennia.contrib.traits.StaticTrait.mod" title="Permalink to this definition"></a></dt>
<dd><p>The traits modifier.</p>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.StaticTrait.value">
<em class="property">property </em><code class="sig-name descname">value</code><a class="headerlink" href="#evennia.contrib.traits.StaticTrait.value" title="Permalink to this definition"></a></dt>
<dd><p>The value of the Trait</p>
</dd></dl>
</dd></dl>
<dl class="py class">
<dt id="evennia.contrib.traits.CounterTrait">
<em class="property">class </em><code class="sig-prename descclassname">evennia.contrib.traits.</code><code class="sig-name descname">CounterTrait</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">trait_data</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#CounterTrait"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.CounterTrait" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <a class="reference internal" href="#evennia.contrib.traits.Trait" title="evennia.contrib.traits.Trait"><code class="xref py py-class docutils literal notranslate"><span class="pre">evennia.contrib.traits.Trait</span></code></a></p>
<p>Counter Trait.</p>
<p>This includes modifications and min/max limits as well as the notion of a
current value. The value can also be reset to the base value.</p>
<dl class="simple">
<dt>min/unset base base+mod max/unset</dt><dd><dl class="simple">
<dt><a href="#id7"><span class="problematic" id="id8">|--------------|</span></a>——–<a href="#id9"><span class="problematic" id="id10">|---------X--------X------------|</span></a></dt><dd><dl class="simple">
<dt>current value</dt><dd><p>= current
+ mod</p>
</dd>
</dl>
</dd>
</dl>
</dd>
</dl>
<ul>
<li><p>value = current + mod, starts at base + mod</p></li>
<li><p>if min or max is None, there is no upper/lower bound (default)</p></li>
<li><p>if max is set to “base”, max will be equal ot base+mod</p></li>
<li><p>descs are used to optionally describe each value interval.
The desc of the current <strong>value</strong> value can then be retrieved
with .desc(). The property is set as {lower_bound_inclusive:desc}
and should be given smallest-to-biggest. For example, for
a skill rating between 0 and 10:</p>
<blockquote>
<div><dl class="simple">
<dt>{0: “unskilled”,</dt><dd><p>1: “neophyte”,
5: “traited”,
7: “expert”,
9: “master”}</p>
</dd>
</dl>
</div></blockquote>
</li>
<li><p>rate/ratetarget are optional settings to include a rate-of-change
of the current value. This is calculated on-demand and allows for
describing a value that is gradually growing smaller/bigger. The
increase will stop when either reaching a boundary (if set) or
ratetarget. Setting the rate to 0 (default) stops any change.</p></li>
</ul>
<dl class="py attribute">
<dt id="evennia.contrib.traits.CounterTrait.trait_type">
<code class="sig-name descname">trait_type</code><em class="property"> = 'counter'</em><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.trait_type" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt id="evennia.contrib.traits.CounterTrait.default_keys">
<code class="sig-name descname">default_keys</code><em class="property"> = {'base': 0, 'descs': None, 'max': None, 'min': None, 'mod': 0, 'rate': 0, 'ratetarget': None}</em><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.default_keys" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.validate_input">
<em class="property">static </em><code class="sig-name descname">validate_input</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">cls</span></em>, <em class="sig-param"><span class="n">trait_data</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#CounterTrait.validate_input"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.validate_input" title="Permalink to this definition"></a></dt>
<dd><p>Add extra validation for descs</p>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.base">
<em class="property">property </em><code class="sig-name descname">base</code><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.base" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.mod">
<em class="property">property </em><code class="sig-name descname">mod</code><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.mod" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.min">
<em class="property">property </em><code class="sig-name descname">min</code><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.min" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.max">
<em class="property">property </em><code class="sig-name descname">max</code><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.max" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.current">
<em class="property">property </em><code class="sig-name descname">current</code><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.current" title="Permalink to this definition"></a></dt>
<dd><p>The <strong>current</strong> value of the <strong>Trait</strong>. This does not have .mod added.</p>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.value">
<em class="property">property </em><code class="sig-name descname">value</code><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.value" title="Permalink to this definition"></a></dt>
<dd><p>The value of the Trait (current + mod)</p>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.ratetarget">
<em class="property">property </em><code class="sig-name descname">ratetarget</code><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.ratetarget" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.percent">
<code class="sig-name descname">percent</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">formatting</span><span class="o">=</span><span class="default_value">'{:3.1f}%'</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#CounterTrait.percent"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.percent" title="Permalink to this definition"></a></dt>
<dd><p>Return the current value as a percentage.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>formatting</strong> (<em>str</em><em>, </em><em>optional</em>) Should contain a
format-tag which will receive the value. If
this is set to None, the raw float will be
returned.</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p><p><em>float or str</em> </p>
<dl class="simple">
<dt>Depending of if a <strong>formatting</strong> string</dt><dd><p>is supplied or not.</p>
</dd>
</dl>
</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.reset">
<code class="sig-name descname">reset</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#CounterTrait.reset"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.reset" title="Permalink to this definition"></a></dt>
<dd><p>Resets <strong>current</strong> property equal to <strong>base</strong> value.</p>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.CounterTrait.desc">
<code class="sig-name descname">desc</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#CounterTrait.desc"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.CounterTrait.desc" title="Permalink to this definition"></a></dt>
<dd><p>Retrieve descriptions of the current value, if available.</p>
<p>This must be a mapping {upper_bound_inclusive: text},
ordered from small to big. Any value above the highest
upper bound will be included as being in the highest bound.
rely on Python3.7+ dicts retaining ordering to let this
describe the interval.</p>
<dl class="field-list simple">
<dt class="field-odd">Returns</dt>
<dd class="field-odd"><p><p><em>str</em> </p>
<dl class="simple">
<dt>The description describing the <strong>value</strong> value.</dt><dd><p>If not found, returns the empty string.</p>
</dd>
</dl>
</p>
</dd>
</dl>
</dd></dl>
</dd></dl>
<dl class="py class">
<dt id="evennia.contrib.traits.GaugeTrait">
<em class="property">class </em><code class="sig-prename descclassname">evennia.contrib.traits.</code><code class="sig-name descname">GaugeTrait</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">trait_data</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#GaugeTrait"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <a class="reference internal" href="#evennia.contrib.traits.CounterTrait" title="evennia.contrib.traits.CounterTrait"><code class="xref py py-class docutils literal notranslate"><span class="pre">evennia.contrib.traits.CounterTrait</span></code></a></p>
<p>Gauge Trait.</p>
<p>This emulates a gauge-meter that empties from a base+mod value.</p>
<dl>
<dt>min/0 max=base+mod</dt><dd><dl>
<dt><a href="#id11"><span class="problematic" id="id12">|-----------------------X---------------------------|</span></a></dt><dd><blockquote>
<div><p>value</p>
</div></blockquote>
<p>= current</p>
</dd>
</dl>
</dd>
</dl>
<ul>
<li><p>min defaults to 0</p></li>
<li><p>max value is always base + mad</p></li>
<li><p>.max is an alias of .base</p></li>
<li><p>value = current and varies from min to max.</p></li>
<li><dl>
<dt>descs is a mapping {upper_bound_inclusive: desc}. These</dt><dd><p>are checked with .desc() and can be retrieve a text
description for a given current value.</p>
<p>For example, this could be used to describe health
values between 0 and 100:</p>
<blockquote>
<div><dl class="simple">
<dt>{0: “Dead”</dt><dd><p>10: “Badly hurt”,
30: “Bleeding”,
50: “Hurting”,
90: “Healthy”}</p>
</dd>
</dl>
</div></blockquote>
</dd>
</dl>
</li>
</ul>
<dl class="py attribute">
<dt id="evennia.contrib.traits.GaugeTrait.trait_type">
<code class="sig-name descname">trait_type</code><em class="property"> = 'gauge'</em><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait.trait_type" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt id="evennia.contrib.traits.GaugeTrait.default_keys">
<code class="sig-name descname">default_keys</code><em class="property"> = {'base': 0, 'descs': None, 'min': 0, 'mod': 0, 'rate': 0, 'ratetarget': None}</em><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait.default_keys" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.GaugeTrait.base">
<em class="property">property </em><code class="sig-name descname">base</code><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait.base" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.GaugeTrait.mod">
<em class="property">property </em><code class="sig-name descname">mod</code><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait.mod" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.GaugeTrait.min">
<em class="property">property </em><code class="sig-name descname">min</code><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait.min" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.GaugeTrait.max">
<em class="property">property </em><code class="sig-name descname">max</code><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait.max" title="Permalink to this definition"></a></dt>
<dd><p>The max is always base + mod.</p>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.GaugeTrait.current">
<em class="property">property </em><code class="sig-name descname">current</code><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait.current" title="Permalink to this definition"></a></dt>
<dd><p>The <strong>current</strong> value of the gauge.</p>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.GaugeTrait.value">
<em class="property">property </em><code class="sig-name descname">value</code><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait.value" title="Permalink to this definition"></a></dt>
<dd><p>The value of the trait</p>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.GaugeTrait.percent">
<code class="sig-name descname">percent</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">formatting</span><span class="o">=</span><span class="default_value">'{:3.1f}%'</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#GaugeTrait.percent"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait.percent" title="Permalink to this definition"></a></dt>
<dd><p>Return the current value as a percentage.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>formatting</strong> (<em>str</em><em>, </em><em>optional</em>) Should contain a
format-tag which will receive the value. If
this is set to None, the raw float will be
returned.</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p><p><em>float or str</em> </p>
<dl class="simple">
<dt>Depending of if a <strong>formatting</strong> string</dt><dd><p>is supplied or not.</p>
</dd>
</dl>
</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt id="evennia.contrib.traits.GaugeTrait.reset">
<code class="sig-name descname">reset</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/evennia/contrib/traits.html#GaugeTrait.reset"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#evennia.contrib.traits.GaugeTrait.reset" title="Permalink to this definition"></a></dt>
<dd><p>Fills the gauge to its maximum allowed by base + mod</p>
</dd></dl>
</dd></dl>
</div>
</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>
<p><h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">evennia.contrib.traits</a><ul>
<li><a class="reference internal" href="#adding-traits-to-a-typeclass">Adding Traits to a typeclass</a></li>
<li><a class="reference internal" href="#using-traits">Using traits</a></li>
<li><a class="reference internal" href="#trait-types">Trait types</a></li>
<li><a class="reference internal" href="#static-trait">Static trait</a><ul>
<li><a class="reference internal" href="#counter">Counter</a><ul>
<li><a class="reference internal" href="#rate">.rate</a></li>
<li><a class="reference internal" href="#percentage">.percentage()</a></li>
</ul>
</li>
<li><a class="reference internal" href="#gauge">Gauge</a></li>
<li><a class="reference internal" href="#trait">Trait</a></li>
</ul>
</li>
<li><a class="reference internal" href="#expanding-with-your-own-traits">Expanding with your own Traits</a></li>
</ul>
</li>
</ul>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/api/evennia.contrib.traits.rst.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div>
<h3>Versions</h3>
<ul>
<li><a href="evennia.contrib.traits.html">1.0-dev (develop branch)</a></li>
<li><a href="../../0.9.5/index.html">0.9.5 (master 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-this"><a href="">evennia.contrib.traits</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>