mirror of
https://github.com/evennia/evennia.git
synced 2026-03-26 09:46:32 +01:00
1740 lines
No EOL
170 KiB
HTML
1740 lines
No EOL
170 KiB
HTML
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>evennia.contrib.traits — 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> »</li>
|
|
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> »</li>
|
|
<li class="nav-item nav-item-2"><a href="../../evennia.html" accesskey="U">evennia</a> »</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">
|
|
|
|
<h1>Source code for evennia.contrib.traits</h1><div class="highlight"><pre>
|
|
<span></span><span class="sd">"""</span>
|
|
<span class="sd">Traits</span>
|
|
|
|
<span class="sd">Whitenoise 2014, Ainneve contributors,</span>
|
|
<span class="sd">Griatch 2020</span>
|
|
|
|
|
|
<span class="sd">A `Trait` represents a modifiable property on (usually) a Character. They can</span>
|
|
<span class="sd">be used to represent everything from attributes (str, agi etc) to skills</span>
|
|
<span class="sd">(hunting 10, swords 14 etc) and dynamically changing things like HP, XP etc.</span>
|
|
|
|
<span class="sd">Traits use Evennia Attributes under the hood, making them persistent (they survive</span>
|
|
<span class="sd">a server reload/reboot).</span>
|
|
|
|
<span class="sd">## Adding Traits to a typeclass</span>
|
|
|
|
<span class="sd">There are two ways to set up Traits on a typeclass. The first sets up the `TraitHandler`</span>
|
|
<span class="sd">as a property `.traits` on your class and you then access traits as e.g. `.traits.strength`.</span>
|
|
<span class="sd">The other alternative uses a `TraitProperty`, which makes the trait available directly</span>
|
|
<span class="sd">as e.g. `.strength`. This solution also uses the `TraitHandler`, but you don't need to</span>
|
|
<span class="sd">define it explicitly. You can combine both styles if you like.</span>
|
|
|
|
<span class="sd">### Traits with TraitHandler</span>
|
|
|
|
<span class="sd">Here's an example for adding the TraitHandler to the Character class:</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd"># mygame/typeclasses/objects.py</span>
|
|
|
|
<span class="sd">from evennia import DefaultCharacter</span>
|
|
<span class="sd">from evennia.utils import lazy_property</span>
|
|
<span class="sd">from evennia.contrib.traits import TraitHandler</span>
|
|
|
|
<span class="sd"># ...</span>
|
|
|
|
<span class="sd">class Character(DefaultCharacter):</span>
|
|
<span class="sd"> ...</span>
|
|
<span class="sd"> @lazy_property</span>
|
|
<span class="sd"> def traits(self):</span>
|
|
<span class="sd"> # this adds the handler as .traits</span>
|
|
<span class="sd"> return TraitHandler(self)</span>
|
|
|
|
|
|
<span class="sd"> def at_object_creation(self):</span>
|
|
<span class="sd"> # (or wherever you want)</span>
|
|
<span class="sd"> self.traits.add("str", "Strength", trait_type="static", base=10, mod=2)</span>
|
|
<span class="sd"> self.traits.add("hp", "Health", trait_type="gauge", min=0, max=100)</span>
|
|
<span class="sd"> self.traits.add("hunting", "Hunting Skill", trait_type="counter",</span>
|
|
<span class="sd"> base=10, mod=1, min=0, max=100)</span>
|
|
|
|
|
|
<span class="sd">```</span>
|
|
<span class="sd">When adding the trait, you supply the name of the property (`hunting`) along</span>
|
|
<span class="sd">with a more human-friendly name ("Hunting Skill"). The latter will show if you</span>
|
|
<span class="sd">print the trait etc. The `trait_type` is important, this specifies which type</span>
|
|
<span class="sd">of trait this is (see below).</span>
|
|
|
|
<span class="sd">### TraitProperties</span>
|
|
|
|
<span class="sd">Using `TraitProperties` makes the trait available directly on the class, much like Django model</span>
|
|
<span class="sd">fields. The drawback is that you must make sure that the name of your Traits don't collide with any</span>
|
|
<span class="sd">other properties/methods on your class.</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd"># mygame/typeclasses/objects.py</span>
|
|
|
|
<span class="sd">from evennia import DefaultObject</span>
|
|
<span class="sd">from evennia.utils import lazy_property</span>
|
|
<span class="sd">from evennia.contrib.traits import TraitProperty</span>
|
|
|
|
<span class="sd"># ...</span>
|
|
|
|
<span class="sd">class Object(DefaultObject):</span>
|
|
<span class="sd"> ...</span>
|
|
<span class="sd"> strength = TraitProperty("Strength", trait_type="static", base=10, mod=2)</span>
|
|
<span class="sd"> health = TraitProperty("Health", trait_type="gauge", min=0, base=100, mod=2)</span>
|
|
<span class="sd"> hunting = TraitProperty("Hunting Skill", trait_type="counter", base=10, mod=1, min=0, max=100)</span>
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">> Note that the property-name will become the name of the trait and you don't supply `trait_key`</span>
|
|
<span class="sd">> separately.</span>
|
|
|
|
<span class="sd">> The `.traits` TraitHandler will still be created (it's used under the</span>
|
|
<span class="sd">> hood. But it will only be created when the TraitProperty has been accessed at least once,</span>
|
|
<span class="sd">> so be careful if mixing the two styles. If you want to make sure `.traits` is always available,</span>
|
|
<span class="sd">> add the `TraitHandler` manually like shown earlier - the `TraitProperty` will by default use</span>
|
|
<span class="sd">> the same handler (`.traits`).</span>
|
|
|
|
<span class="sd">## Using traits</span>
|
|
|
|
<span class="sd">A trait is added to the traithandler (if you use `TraitProperty` the handler is just created under</span>
|
|
<span class="sd">the hood) after which one can access it as a property on the handler (similarly to how you can do</span>
|
|
<span class="sd">.db.attrname for Attributes in Evennia).</span>
|
|
|
|
<span class="sd">All traits have a _read-only_ field `.value`. This is only used to read out results, you never</span>
|
|
<span class="sd">manipulate it directly (if you try, it will just remain unchanged). The `.value` is calculated based</span>
|
|
<span class="sd">on combining fields, like `.base` and `.mod` - which fields are available and how they relate to</span>
|
|
<span class="sd">each other depends on the trait type.</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd">> obj.traits.strength.value</span>
|
|
<span class="sd">12 # base + mod</span>
|
|
|
|
<span class="sd">> obj.traits.strength.base += 5</span>
|
|
<span class="sd">obj.traits.strength.value</span>
|
|
<span class="sd">17</span>
|
|
|
|
<span class="sd">> obj.traits.hp.value</span>
|
|
<span class="sd">102 # base + mod</span>
|
|
|
|
<span class="sd">> obj.traits.hp.base -= 200</span>
|
|
<span class="sd">> obj.traits.hp.value</span>
|
|
<span class="sd">0 # min of 0</span>
|
|
|
|
<span class="sd">> obj.traits.hp.reset()</span>
|
|
<span class="sd">> obj.traits.hp.value</span>
|
|
<span class="sd">100</span>
|
|
|
|
<span class="sd"># you can also access properties like a dict</span>
|
|
<span class="sd">> obj.traits.hp["value"]</span>
|
|
<span class="sd">100</span>
|
|
|
|
<span class="sd"># you can store arbitrary data persistently for easy reference</span>
|
|
<span class="sd">> obj.traits.hp.effect = "poisoned!"</span>
|
|
<span class="sd">> obj.traits.hp.effect</span>
|
|
<span class="sd">"poisoned!"</span>
|
|
|
|
<span class="sd"># with TraitProperties:</span>
|
|
|
|
<span class="sd">> obj.hunting.value</span>
|
|
<span class="sd">12</span>
|
|
|
|
<span class="sd">> obj.strength.value += 5</span>
|
|
<span class="sd">> obj.strength.value</span>
|
|
<span class="sd">17</span>
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">## Trait types</span>
|
|
|
|
<span class="sd">All default traits have a read-only `.value` property that shows the relevant or</span>
|
|
<span class="sd">'current' value of the trait. Exactly what this means depends on the type of trait.</span>
|
|
|
|
<span class="sd">Traits can also be combined to do arithmetic with their .value, if both have a</span>
|
|
<span class="sd">compatible type.</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd">> trait1 + trait2</span>
|
|
<span class="sd">54</span>
|
|
|
|
<span class="sd">> trait1.value</span>
|
|
<span class="sd">3</span>
|
|
|
|
<span class="sd">> trait1 + 2</span>
|
|
<span class="sd">> trait1.value</span>
|
|
<span class="sd">5</span>
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">Two numerical traits can also be compared (bigger-than etc), which is useful in</span>
|
|
<span class="sd">all sorts of rule-resolution.</span>
|
|
|
|
<span class="sd">```python</span>
|
|
|
|
<span class="sd">if trait1 > trait2:</span>
|
|
<span class="sd"> # do stuff</span>
|
|
|
|
<span class="sd">```</span>
|
|
<span class="sd">## Static trait</span>
|
|
|
|
<span class="sd">`value = base + mod`</span>
|
|
|
|
<span class="sd">The static trait has a `base` value and an optional `mod`-ifier. A typical use</span>
|
|
<span class="sd">of a static trait would be a Strength stat or Skill value. That is, something</span>
|
|
<span class="sd">that varies slowly or not at all, and which may be modified in-place.</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd">> obj.traits.add("str", "Strength", trait_type="static", base=10, mod=2)</span>
|
|
<span class="sd">> obj.traits.mytrait.value</span>
|
|
|
|
<span class="sd">12 # base + mod</span>
|
|
<span class="sd">> obj.traits.mytrait.base += 2</span>
|
|
<span class="sd">> obj.traits.mytrait.mod += 1</span>
|
|
<span class="sd">> obj.traits.mytrait.value</span>
|
|
<span class="sd">15</span>
|
|
|
|
<span class="sd">> obj.traits.mytrait.mod = 0</span>
|
|
<span class="sd">> obj.traits.mytrait.value</span>
|
|
<span class="sd">12</span>
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">### Counter</span>
|
|
<span class="sd">::</span>
|
|
|
|
<span class="sd"> min/unset base base+mod max/unset</span>
|
|
<span class="sd"> |--------------|--------|---------X--------X------------|</span>
|
|
<span class="sd"> current value</span>
|
|
<span class="sd"> = current</span>
|
|
<span class="sd"> + mod</span>
|
|
|
|
<span class="sd">A counter describes a value that can move from a base. The `.current` property</span>
|
|
<span class="sd">is the thing usually modified. It starts at the `.base`. One can also add a</span>
|
|
<span class="sd">modifier, which will both be added to the base and to current (forming</span>
|
|
<span class="sd">`.value`). The min/max of the range are optional, a boundary set to None will</span>
|
|
<span class="sd">remove it. A suggested use for a Counter Trait would be to track skill values.</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd">> obj.traits.add("hunting", "Hunting Skill", trait_type="counter",</span>
|
|
<span class="sd"> base=10, mod=1, min=0, max=100)</span>
|
|
<span class="sd">> obj.traits.hunting.value</span>
|
|
<span class="sd">11 # current starts at base + mod</span>
|
|
|
|
<span class="sd">> obj.traits.hunting.current += 10</span>
|
|
<span class="sd">> obj.traits.hunting.value</span>
|
|
<span class="sd">21</span>
|
|
|
|
<span class="sd"># reset back to base+mod by deleting current</span>
|
|
<span class="sd">> del obj.traits.hunting.current</span>
|
|
<span class="sd">> obj.traits.hunting.value</span>
|
|
<span class="sd">11</span>
|
|
<span class="sd">> obj.traits.hunting.max = None # removing upper bound</span>
|
|
|
|
<span class="sd"># for TraitProperties, pass the args/kwargs of traits.add() to the</span>
|
|
<span class="sd"># TraitProperty constructor instead.</span>
|
|
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">Counters have some extra properties:</span>
|
|
|
|
<span class="sd">#### .descs</span>
|
|
|
|
<span class="sd">The `descs` property is a dict {upper_bound:text_description}. This allows for easily</span>
|
|
<span class="sd">storing a more human-friendly description of the current value in the</span>
|
|
<span class="sd">interval. Here is an example for skill values between 0 and 10:</span>
|
|
<span class="sd">::</span>
|
|
|
|
<span class="sd"> {0: "unskilled", 1: "neophyte", 5: "trained", 7: "expert", 9: "master"}</span>
|
|
|
|
<span class="sd">The keys must be supplied from smallest to largest. Any values below the lowest and above the</span>
|
|
<span class="sd">highest description will be considered to be included in the closest description slot.</span>
|
|
<span class="sd">By calling `.desc()` on the Counter, you will get the text matching the current `value`.</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd"># (could also have passed descs= to traits.add())</span>
|
|
<span class="sd">> obj.traits.hunting.descs = {</span>
|
|
<span class="sd"> 0: "unskilled", 10: "neophyte", 50: "trained", 70: "expert", 90: "master"}</span>
|
|
<span class="sd">> obj.traits.hunting.value</span>
|
|
<span class="sd">11</span>
|
|
|
|
<span class="sd">> obj.traits.hunting.desc()</span>
|
|
<span class="sd">"neophyte"</span>
|
|
<span class="sd">> obj.traits.hunting.current += 60</span>
|
|
<span class="sd">> obj.traits.hunting.value</span>
|
|
<span class="sd">71</span>
|
|
|
|
<span class="sd">> obj.traits.hunting.desc()</span>
|
|
<span class="sd">"expert"</span>
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">#### .rate</span>
|
|
|
|
<span class="sd">The `rate` property defaults to 0. If set to a value different from 0, it</span>
|
|
<span class="sd">allows the trait to change value dynamically. This could be used for example</span>
|
|
<span class="sd">for an attribute that was temporarily lowered but will gradually (or abruptly)</span>
|
|
<span class="sd">recover after a certain time. The rate is given as change of the current</span>
|
|
<span class="sd">`.value` per-second, and this will still be restrained by min/max boundaries,</span>
|
|
<span class="sd">if those are set.</span>
|
|
|
|
<span class="sd">It is also possible to set a `.ratetarget`, for the auto-change to stop at</span>
|
|
<span class="sd">(rather than at the min/max boundaries). This allows the value to return to</span>
|
|
<span class="sd">a previous value.</span>
|
|
|
|
<span class="sd">```python</span>
|
|
|
|
<span class="sd">> obj.traits.hunting.value</span>
|
|
<span class="sd">71</span>
|
|
|
|
<span class="sd">> obj.traits.hunting.ratetarget = 71</span>
|
|
<span class="sd"># debuff hunting for some reason</span>
|
|
<span class="sd">> obj.traits.hunting.current -= 30</span>
|
|
<span class="sd">> obj.traits.hunting.value</span>
|
|
<span class="sd">41</span>
|
|
|
|
<span class="sd">> obj.traits.hunting.rate = 1 # 1/s increase</span>
|
|
<span class="sd"># Waiting 5s</span>
|
|
<span class="sd">> obj.traits.hunting.value</span>
|
|
<span class="sd">46</span>
|
|
|
|
<span class="sd"># Waiting 8s</span>
|
|
<span class="sd">> obj.traits.hunting.value</span>
|
|
<span class="sd">54</span>
|
|
|
|
<span class="sd"># Waiting 100s</span>
|
|
<span class="sd">> obj.traits.hunting.value</span>
|
|
<span class="sd">71 # we have stopped at the ratetarget</span>
|
|
|
|
<span class="sd">> obj.traits.hunting.rate = 0 # disable auto-change</span>
|
|
|
|
|
|
<span class="sd">```</span>
|
|
<span class="sd">Note that when retrieving the `current`, the result will always be of the same</span>
|
|
<span class="sd">type as the `.base` even `rate` is a non-integer value. So if `base` is an `int`</span>
|
|
<span class="sd">(default)`, the `current` value will also be rounded the closest full integer.</span>
|
|
<span class="sd">If you want to see the exact `current` value, set `base` to a float - you</span>
|
|
<span class="sd">will then need to use `round()` yourself on the result if you want integers.</span>
|
|
|
|
<span class="sd">#### .percent()</span>
|
|
|
|
<span class="sd">If both min and max are defined, the `.percent()` method of the trait will</span>
|
|
<span class="sd">return the value as a percentage.</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd">> obj.traits.hunting.percent()</span>
|
|
<span class="sd">"71.0%"</span>
|
|
|
|
<span class="sd">> obj.traits.hunting.percent(formatting=None)</span>
|
|
<span class="sd">71.0</span>
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">### Gauge</span>
|
|
|
|
<span class="sd">This emulates a [fuel-] gauge that empties from a base+mod value.</span>
|
|
<span class="sd">::</span>
|
|
|
|
<span class="sd"> min/0 max=base+mod</span>
|
|
<span class="sd"> |-----------------------X---------------------------|</span>
|
|
<span class="sd"> value</span>
|
|
<span class="sd"> = current</span>
|
|
|
|
<span class="sd">The `.current` value will start from a full gauge. The .max property is</span>
|
|
<span class="sd">read-only and is set by `.base` + `.mod`. So contrary to a `Counter`, the</span>
|
|
<span class="sd">`.mod` modifier only applies to the max value of the gauge and not the current</span>
|
|
<span class="sd">value. The minimum bound defaults to 0 if not set explicitly.</span>
|
|
|
|
<span class="sd">This trait is useful for showing commonly depletable resources like health,</span>
|
|
<span class="sd">stamina and the like.</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd">> obj.traits.add("hp", "Health", trait_type="gauge", base=100)</span>
|
|
<span class="sd">> obj.traits.hp.value # (or .current)</span>
|
|
<span class="sd">100</span>
|
|
|
|
<span class="sd">> obj.traits.hp.mod = 10</span>
|
|
<span class="sd">> obj.traits.hp.value</span>
|
|
<span class="sd">110</span>
|
|
|
|
<span class="sd">> obj.traits.hp.current -= 30</span>
|
|
<span class="sd">> obj.traits.hp.value</span>
|
|
<span class="sd">80</span>
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">The Gauge trait is subclass of the Counter, so you have access to the same</span>
|
|
<span class="sd">methods and properties where they make sense. So gauges can also have a</span>
|
|
<span class="sd">`.descs` dict to describe the intervals in text, and can use `.percent()` to</span>
|
|
<span class="sd">get how filled it is as a percentage etc.</span>
|
|
|
|
<span class="sd">The `.rate` is particularly relevant for gauges - useful for everything</span>
|
|
<span class="sd">from poison slowly draining your health, to resting gradually increasing it.</span>
|
|
|
|
<span class="sd">### Trait</span>
|
|
|
|
<span class="sd">A single value of any type.</span>
|
|
|
|
<span class="sd">This is the 'base' Trait, meant to inherit from if you want to invent</span>
|
|
<span class="sd">trait-types from scratch (most of the time you'll probably inherit from some of</span>
|
|
<span class="sd">the more advanced trait-type classes though).</span>
|
|
|
|
<span class="sd">Unlike other Trait-types, the single `.value` property of the base `Trait` can</span>
|
|
<span class="sd">be editied. The value can hold any data that can be stored in an Attribute. If</span>
|
|
<span class="sd">it's an integer/float you can do arithmetic with it, but otherwise this acts just</span>
|
|
<span class="sd">like a glorified Attribute.</span>
|
|
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd">> obj.traits.add("mytrait", "My Trait", trait_type="trait", value=30)</span>
|
|
<span class="sd">> obj.traits.mytrait.value</span>
|
|
<span class="sd">30</span>
|
|
|
|
<span class="sd">> obj.traits.mytrait.value = "stringvalue"</span>
|
|
<span class="sd">> obj.traits.mytrait.value</span>
|
|
<span class="sd">"stringvalue"</span>
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">## Expanding with your own Traits</span>
|
|
|
|
<span class="sd">A Trait is a class inhering from `evennia.contrib.traits.Trait` (or from one of</span>
|
|
<span class="sd">the existing Trait classes).</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd"># in a file, say, 'mygame/world/traits.py'</span>
|
|
|
|
<span class="sd">from evennia.contrib.traits import StaticTrait</span>
|
|
|
|
<span class="sd">class RageTrait(StaticTrait):</span>
|
|
|
|
<span class="sd"> trait_type = "rage"</span>
|
|
<span class="sd"> default_keys = {</span>
|
|
<span class="sd"> "rage": 0</span>
|
|
<span class="sd"> }</span>
|
|
|
|
<span class="sd"> def berserk(self):</span>
|
|
<span class="sd"> self.mod = 100</span>
|
|
|
|
<span class="sd"> def sedate(self):</span>
|
|
<span class="sd"> self.mod = 0</span>
|
|
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">Above is an example custom-trait-class "rage" that stores a property "rage" on</span>
|
|
<span class="sd">itself, with a default value of 0. This has all the functionality of a Trait -</span>
|
|
<span class="sd">for example, if you do del on the `rage` property, it will be set back to its</span>
|
|
<span class="sd">default (0). Above we also added some helper methods.</span>
|
|
|
|
<span class="sd">To add your custom RageTrait to Evennia, add the following to your settings file</span>
|
|
<span class="sd">(assuming your class is in mygame/world/traits.py):</span>
|
|
<span class="sd">::</span>
|
|
|
|
<span class="sd"> TRAIT_CLASS_PATHS = ["world.traits.RageTrait"]</span>
|
|
|
|
<span class="sd">Reload the server and you should now be able to use your trait:</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd">> obj.traits.add("mood", "A dark mood", rage=30, trait_type='rage')</span>
|
|
<span class="sd">> obj.traits.mood.rage</span>
|
|
<span class="sd">30</span>
|
|
|
|
<span class="sd"># as TraitProperty</span>
|
|
|
|
<span class="sd">class Character(DefaultCharacter):</span>
|
|
<span class="sd"> rage = TraitProperty("A dark mood", rage=30, trait_type='rage')</span>
|
|
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">----</span>
|
|
|
|
<span class="sd">"""</span>
|
|
|
|
|
|
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">time</span>
|
|
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
|
|
<span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">total_ordering</span>
|
|
<span class="kn">from</span> <span class="nn">evennia.utils.dbserialize</span> <span class="kn">import</span> <span class="n">_SaverDict</span>
|
|
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">logger</span>
|
|
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">inherits_from</span><span class="p">,</span> <span class="n">class_from_module</span><span class="p">,</span> <span class="n">list_to_string</span><span class="p">,</span> <span class="n">percent</span>
|
|
|
|
|
|
<span class="c1"># Available Trait classes.</span>
|
|
<span class="c1"># This way the user can easily supply their own. Each</span>
|
|
<span class="c1"># class should have a class-property `trait_type` to</span>
|
|
<span class="c1"># identify the Trait class. The default ones are "static",</span>
|
|
<span class="c1"># "counter" and "gauge".</span>
|
|
|
|
<span class="n">_TRAIT_CLASS_PATHS</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="s2">"evennia.contrib.traits.Trait"</span><span class="p">,</span>
|
|
<span class="s2">"evennia.contrib.traits.StaticTrait"</span><span class="p">,</span>
|
|
<span class="s2">"evennia.contrib.traits.CounterTrait"</span><span class="p">,</span>
|
|
<span class="s2">"evennia.contrib.traits.GaugeTrait"</span><span class="p">,</span>
|
|
<span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s2">"TRAIT_CLASS_PATHS"</span><span class="p">):</span>
|
|
<span class="n">_TRAIT_CLASS_PATHS</span> <span class="o">+=</span> <span class="n">settings</span><span class="o">.</span><span class="n">TRAIT_CLASS_PATHS</span>
|
|
|
|
<span class="c1"># delay trait-class import to avoid circular import</span>
|
|
<span class="n">_TRAIT_CLASSES</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
|
|
<span class="k">def</span> <span class="nf">_delayed_import_trait_classes</span><span class="p">():</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Import classes based on the given paths. Note that</span>
|
|
<span class="sd"> imports from settings are last in the list, so if they</span>
|
|
<span class="sd"> have the same trait_type set, they will replace the</span>
|
|
<span class="sd"> default.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">global</span> <span class="n">_TRAIT_CLASSES</span>
|
|
<span class="k">if</span> <span class="n">_TRAIT_CLASSES</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">_TRAIT_CLASSES</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">for</span> <span class="n">classpath</span> <span class="ow">in</span> <span class="n">_TRAIT_CLASS_PATHS</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="n">class_from_module</span><span class="p">(</span><span class="n">classpath</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
|
|
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Could not import Trait from </span><span class="si">{</span><span class="n">classpath</span><span class="si">}</span><span class="s2">."</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s2">"trait_type"</span><span class="p">):</span>
|
|
<span class="n">trait_type</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">trait_type</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">trait_type</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">__name___</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="n">_TRAIT_CLASSES</span><span class="p">[</span><span class="n">trait_type</span><span class="p">]</span> <span class="o">=</span> <span class="bp">cls</span>
|
|
|
|
|
|
<span class="n">_GA</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__getattribute__</span>
|
|
<span class="n">_SA</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__setattr__</span>
|
|
<span class="n">_DA</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__delattr__</span>
|
|
|
|
<span class="c1"># this is the default we offer in TraitHandler.add</span>
|
|
<span class="n">DEFAULT_TRAIT_TYPE</span> <span class="o">=</span> <span class="s2">"static"</span>
|
|
|
|
|
|
<div class="viewcode-block" id="TraitException"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.TraitException">[docs]</a><span class="k">class</span> <span class="nc">TraitException</span><span class="p">(</span><span class="ne">RuntimeError</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Base exception class raised by `Trait` objects.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> msg (str): informative error message</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<div class="viewcode-block" id="TraitException.__init__"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.TraitException.__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">msg</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span></div></div>
|
|
|
|
|
|
<div class="viewcode-block" id="MandatoryTraitKey"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.MandatoryTraitKey">[docs]</a><span class="k">class</span> <span class="nc">MandatoryTraitKey</span><span class="p">:</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> This represents a required key that must be</span>
|
|
<span class="sd"> supplied when a Trait is initialized. It's used</span>
|
|
<span class="sd"> by Trait classes when defining their required keys.</span>
|
|
|
|
<span class="sd"> """</span></div>
|
|
|
|
<div class="viewcode-block" id="TraitHandler"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.TraitHandler">[docs]</a><span class="k">class</span> <span class="nc">TraitHandler</span><span class="p">:</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Factory class that instantiates Trait objects. Must be assigned as a property</span>
|
|
<span class="sd"> on the class, usually with `lazy_property`.</span>
|
|
|
|
<span class="sd"> Example:</span>
|
|
<span class="sd"> ::</span>
|
|
<span class="sd"> class Object(DefaultObject):</span>
|
|
<span class="sd"> ...</span>
|
|
<span class="sd"> @lazy_property</span>
|
|
<span class="sd"> def traits(self):</span>
|
|
<span class="sd"> # this adds the handler as .traits</span>
|
|
<span class="sd"> return TraitHandler(self)</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<div class="viewcode-block" id="TraitHandler.__init__"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.TraitHandler.__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">obj</span><span class="p">,</span> <span class="n">db_attribute_key</span><span class="o">=</span><span class="s2">"traits"</span><span class="p">,</span> <span class="n">db_attribute_category</span><span class="o">=</span><span class="s2">"traits"</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Initialize the handler and set up its internal Attribute-based storage.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> obj (Object): Parent Object typeclass for this TraitHandler</span>
|
|
<span class="sd"> db_attribute_key (str): Name of the DB attribute for trait data storage.</span>
|
|
<span class="sd"> db_attribute_category (str): Name of DB attribute's category to trait data storage.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># load the available classes, if necessary</span>
|
|
<span class="n">_delayed_import_trait_classes</span><span class="p">()</span>
|
|
|
|
<span class="c1"># initialize any</span>
|
|
<span class="c1"># Note that .trait_data retains the connection to the database, meaning every</span>
|
|
<span class="c1"># update we do to .trait_data automatically syncs with database.</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">db_attribute_key</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="n">db_attribute_category</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># no existing storage; initialize it, we then have to fetch it again</span>
|
|
<span class="c1"># to retain the db connection</span>
|
|
<span class="n">obj</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">db_attribute_key</span><span class="p">,</span> <span class="p">{},</span> <span class="n">category</span><span class="o">=</span><span class="n">db_attribute_category</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">db_attribute_key</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="n">db_attribute_category</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_cache</span> <span class="o">=</span> <span class="p">{}</span></div>
|
|
|
|
<span class="k">def</span> <span class="fm">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Return number of Traits registered with the handler"""</span>
|
|
<span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span><span class="p">)</span>
|
|
|
|
<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">trait_key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Returns error message if trait objects are assigned directly.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> trait_key (str): The Trait-key, like "hp".</span>
|
|
<span class="sd"> value (any): Data to store.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">trait_key</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"trait_data"</span><span class="p">,</span> <span class="s2">"_cache"</span><span class="p">):</span>
|
|
<span class="n">_SA</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trait_key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">trait_cls</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_trait_class</span><span class="p">(</span><span class="n">trait_key</span><span class="o">=</span><span class="n">trait_key</span><span class="p">)</span>
|
|
<span class="n">valid_keys</span> <span class="o">=</span> <span class="n">list_to_string</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">trait_cls</span><span class="o">.</span><span class="n">default_keys</span><span class="o">.</span><span class="n">keys</span><span class="p">()),</span> <span class="n">endsep</span><span class="o">=</span><span class="s2">"or"</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="n">TraitException</span><span class="p">(</span>
|
|
<span class="s2">"Trait object not settable directly. "</span> <span class="sa">f</span><span class="s2">"Assign to </span><span class="si">{</span><span class="n">trait_key</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="n">valid_keys</span><span class="si">}</span><span class="s2">."</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trait_key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="sd">"""Returns error message if trait objects are assigned directly."""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__setattr__</span><span class="p">(</span><span class="n">trait_key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trait_key</span><span class="p">):</span>
|
|
<span class="sd">"""Returns Trait instances accessed as attributes."""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">trait_key</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trait_key</span><span class="p">):</span>
|
|
<span class="sd">"""Returns `Trait` instances accessed as dict keys."""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">trait_key</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s2">"TraitHandler (</span><span class="si">{num}</span><span class="s2"> Trait(s) stored): </span><span class="si">{keys}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="n">num</span><span class="o">=</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="n">keys</span><span class="o">=</span><span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">all</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_get_trait_class</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">trait_key</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Helper to retrieve Trait class based on type (like "static")</span>
|
|
<span class="sd"> or trait-key (like "hp").</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">trait_type</span> <span class="ow">and</span> <span class="n">trait_key</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">trait_type</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span><span class="p">[</span><span class="n">trait_key</span><span class="p">][</span><span class="s2">"trait_type"</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">TraitException</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Trait class for Trait </span><span class="si">{</span><span class="n">trait_key</span><span class="si">}</span><span class="s2"> could not be found."</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">_TRAIT_CLASSES</span><span class="p">[</span><span class="n">trait_type</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">TraitException</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Trait class for </span><span class="si">{</span><span class="n">trait_type</span><span class="si">}</span><span class="s2"> could not be found."</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">all</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Get all trait keys in this handler.</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> list: All Trait keys.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
|
|
|
<div class="viewcode-block" id="TraitHandler.get"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.TraitHandler.get">[docs]</a> <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trait_key</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> trait_key (str): key from the traits dict containing config data.</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> (`Trait` or `None`): named Trait class or None if trait key</span>
|
|
<span class="sd"> is not found in traits collection.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">trait</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">trait_key</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">trait</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">trait_key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span><span class="p">:</span>
|
|
<span class="n">trait_type</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span><span class="p">[</span><span class="n">trait_key</span><span class="p">][</span><span class="s2">"trait_type"</span><span class="p">]</span>
|
|
<span class="n">trait_cls</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_trait_class</span><span class="p">(</span><span class="n">trait_type</span><span class="p">)</span>
|
|
<span class="n">trait</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="p">[</span><span class="n">trait_key</span><span class="p">]</span> <span class="o">=</span> <span class="n">trait_cls</span><span class="p">(</span><span class="n">_GA</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"trait_data"</span><span class="p">)[</span><span class="n">trait_key</span><span class="p">])</span>
|
|
<span class="k">return</span> <span class="n">trait</span></div>
|
|
|
|
<div class="viewcode-block" id="TraitHandler.add"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.TraitHandler.add">[docs]</a> <span class="k">def</span> <span class="nf">add</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">trait_key</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="n">DEFAULT_TRAIT_TYPE</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="o">**</span><span class="n">trait_properties</span>
|
|
<span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Create a new Trait and add it to the handler.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> trait_key (str): This is the name of the property that will be made</span>
|
|
<span class="sd"> available on this handler (example 'hp').</span>
|
|
<span class="sd"> name (str, optional): Name of the Trait, like "Health". If</span>
|
|
<span class="sd"> not given, will use `trait_key` starting with a capital letter.</span>
|
|
<span class="sd"> trait_type (str, optional): One of 'static', 'counter' or 'gauge'.</span>
|
|
<span class="sd"> force (bool): If set, create a new Trait even if a Trait with</span>
|
|
<span class="sd"> the same `trait_key` already exists.</span>
|
|
<span class="sd"> trait_properties (dict): These will all be use to initialize</span>
|
|
<span class="sd"> the new trait. See the `properties` class variable on each</span>
|
|
<span class="sd"> Trait class to see which are required.</span>
|
|
|
|
<span class="sd"> Raises:</span>
|
|
<span class="sd"> TraitException: If specifying invalid values for the given Trait,</span>
|
|
<span class="sd"> the `trait_type` is not recognized, or an existing trait</span>
|
|
<span class="sd"> already exists (and `force` is unset).</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="c1"># from evennia import set_trace;set_trace()</span>
|
|
|
|
<span class="k">if</span> <span class="n">trait_key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">force</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">trait_key</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">TraitException</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Trait '</span><span class="si">{</span><span class="n">trait_key</span><span class="si">}</span><span class="s2">' already exists."</span><span class="p">)</span>
|
|
|
|
<span class="n">trait_class</span> <span class="o">=</span> <span class="n">_TRAIT_CLASSES</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">trait_type</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">trait_class</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">TraitException</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Trait-type '</span><span class="si">{</span><span class="n">trait_type</span><span class="si">}</span><span class="s2">' is invalid."</span><span class="p">)</span>
|
|
|
|
<span class="n">trait_properties</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">trait_key</span><span class="o">.</span><span class="n">title</span><span class="p">()</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">name</span> <span class="k">else</span> <span class="n">name</span>
|
|
<span class="n">trait_properties</span><span class="p">[</span><span class="s2">"trait_type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">trait_type</span>
|
|
|
|
<span class="c1"># this will raise exception if input is insufficient</span>
|
|
<span class="n">trait_properties</span> <span class="o">=</span> <span class="n">trait_class</span><span class="o">.</span><span class="n">validate_input</span><span class="p">(</span><span class="n">trait_class</span><span class="p">,</span> <span class="n">trait_properties</span><span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span><span class="p">[</span><span class="n">trait_key</span><span class="p">]</span> <span class="o">=</span> <span class="n">trait_properties</span></div>
|
|
|
|
<div class="viewcode-block" id="TraitHandler.remove"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.TraitHandler.remove">[docs]</a> <span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trait_key</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Remove a Trait from the handler's parent object.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> trait_key (str): The name of the trait to remove.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">trait_key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">TraitException</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Trait '</span><span class="si">{</span><span class="n">trait_key</span><span class="si">}</span><span class="s2">' not found."</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">trait_key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="p">:</span>
|
|
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="p">[</span><span class="n">trait_key</span><span class="p">]</span>
|
|
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">trait_data</span><span class="p">[</span><span class="n">trait_key</span><span class="p">]</span></div>
|
|
|
|
<div class="viewcode-block" id="TraitHandler.clear"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.TraitHandler.clear">[docs]</a> <span class="k">def</span> <span class="nf">clear</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Remove all Traits from the handler's parent object.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">for</span> <span class="n">trait_key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">all</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">trait_key</span><span class="p">)</span></div></div>
|
|
|
|
|
|
<div class="viewcode-block" id="TraitProperty"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.TraitProperty">[docs]</a><span class="k">class</span> <span class="nc">TraitProperty</span><span class="p">:</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Optional extra: Allows for applying traits as individual properties directly on the parent class</span>
|
|
<span class="sd"> instead for properties on the `.traits` handler. So with this you could access data e.g. as</span>
|
|
<span class="sd"> `character.hp.value` instead of `character.traits.hp.value`. This still uses the traitshandler</span>
|
|
<span class="sd"> under the hood.</span>
|
|
|
|
<span class="sd"> Example:</span>
|
|
<span class="sd"> ::</span>
|
|
<span class="sd"> from evennia.utils import lazy_property</span>
|
|
<span class="sd"> from evennia.contrib.traits import TraitProperty</span>
|
|
|
|
<span class="sd"> class Character(DefaultCharacter):</span>
|
|
|
|
<span class="sd"> strength = TraitProperty("str", "Strength", trait_type="static", base=10, mod=2)</span>
|
|
<span class="sd"> hunting = TraitProperty(self, "hunting", "Hunting Skill", trait_type="counter",</span>
|
|
<span class="sd"> base=10, mod=1, max=100)</span>
|
|
<span class="sd"> health = TraitProperty("health", "Health", trait_type="gauge", min=0, base=100)</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<div class="viewcode-block" id="TraitProperty.__init__"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.TraitProperty.__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="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="n">DEFAULT_TRAIT_TYPE</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="o">**</span><span class="n">trait_properties</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Initialize a TraitField. Mimics TraitHandler.add input except no `trait_key`.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> name (str, optional): Name of the Trait, like "Health". If</span>
|
|
<span class="sd"> not given, will use `trait_key` starting with a capital letter.</span>
|
|
<span class="sd"> trait_type (str, optional): One of 'static', 'counter' or 'gauge'.</span>
|
|
<span class="sd"> force (bool): If set, create a new Trait even if a Trait with</span>
|
|
<span class="sd"> the same `trait_key` already exists.</span>
|
|
<span class="sd"> Kwargs:</span>
|
|
<span class="sd"> traithandler_name (str): If given, this is used as the name of the TraitHandler created</span>
|
|
<span class="sd"> behind the scenes. If not set, this will be a property `traits` on the class.</span>
|
|
<span class="sd"> any: All other trait_properties are the same as for adding a new trait of the given type</span>
|
|
<span class="sd"> using the normal TraitHandler.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_traithandler_name</span> <span class="o">=</span> <span class="n">trait_properties</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">"traithandler_name"</span><span class="p">,</span> <span class="s2">"traits"</span><span class="p">)</span>
|
|
|
|
<span class="n">trait_properties</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s2">"name"</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span> <span class="s2">"trait_type"</span><span class="p">:</span> <span class="n">trait_type</span><span class="p">,</span> <span class="s2">"force"</span><span class="p">:</span> <span class="n">force</span><span class="p">})</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_trait_properties</span> <span class="o">=</span> <span class="n">trait_properties</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_cache</span> <span class="o">=</span> <span class="p">{}</span></div>
|
|
|
|
<span class="k">def</span> <span class="nf">__set_name__</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="n">name</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> This is called the very first time the Descriptor is assigned to the</span>
|
|
<span class="sd"> class; we store it so we can create new instances with this later.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_trait_key</span> <span class="o">=</span> <span class="n">name</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__get__</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="n">owner</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Descriptor definition. This is called when the trait-name is aqcuired on the</span>
|
|
<span class="sd"> instance and reroutes to fetching the actual Trait from the connected</span>
|
|
<span class="sd"> TraitHandler (the connection is set up on-demand).</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> Trait: The trait this property represents.</span>
|
|
|
|
<span class="sd"> Notes:</span>
|
|
<span class="sd"> We have one descriptor on the class, but we don't want each instance to share the</span>
|
|
<span class="sd"> state (self) of that descriptor. So we must make sure to cache the trait per-instance</span>
|
|
<span class="sd"> or we would end up with cross-use between instances.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">instance</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">traithandler</span> <span class="o">=</span> <span class="nb">getattr</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">_traithandler_name</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="c1"># traithandler not found; create a new on-demand</span>
|
|
<span class="n">traithandler</span> <span class="o">=</span> <span class="n">TraitHandler</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
|
|
<span class="nb">setattr</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">_traithandler_name</span><span class="p">,</span> <span class="n">traithandler</span><span class="p">)</span>
|
|
|
|
<span class="c1"># this will either get the trait from attribute or make a new one</span>
|
|
<span class="n">trait</span> <span class="o">=</span> <span class="n">traithandler</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_trait_key</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">trait</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># initialize the trait</span>
|
|
<span class="n">traithandler</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">_trait_key</span><span class="p">,</span>
|
|
<span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">_trait_properties</span>
|
|
<span class="p">)</span>
|
|
<span class="n">trait</span> <span class="o">=</span> <span class="n">traithandler</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_trait_key</span><span class="p">)</span> <span class="c1"># caches it in the traithandler</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="p">[</span><span class="n">instance</span><span class="p">]</span> <span class="o">=</span> <span class="n">trait</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="p">[</span><span class="n">instance</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__set__</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="n">value</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> We don't set data directly, it's all rerouted to the trait.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">pass</span></div>
|
|
|
|
<span class="c1"># Parent Trait class</span>
|
|
|
|
|
|
<div class="viewcode-block" id="Trait"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.Trait">[docs]</a><span class="nd">@total_ordering</span>
|
|
<span class="k">class</span> <span class="nc">Trait</span><span class="p">:</span>
|
|
<span class="sd">"""Represents an object or Character trait. This simple base is just</span>
|
|
<span class="sd"> storing anything in it's 'value' property, so it's pretty much just a</span>
|
|
<span class="sd"> different wrapper to an Attribute. It does no type-checking of what is</span>
|
|
<span class="sd"> stored.</span>
|
|
|
|
<span class="sd"> Note:</span>
|
|
<span class="sd"> See module docstring for configuration details.</span>
|
|
|
|
<span class="sd"> value</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="c1"># this is the name used to refer to this trait when adding</span>
|
|
<span class="c1"># a new trait in the TraitHandler</span>
|
|
<span class="n">trait_type</span> <span class="o">=</span> <span class="s2">"trait"</span>
|
|
|
|
<span class="c1"># Property kwargs settable when creating a Trait of this type. This is a</span>
|
|
<span class="c1"># dict of key: default. To indicate a mandatory kwarg and raise an error if</span>
|
|
<span class="c1"># not given, set the default value to the `traits.MandatoryTraitKey` class.</span>
|
|
<span class="c1"># Apart from the keys given here, "name" and "trait_type" will also always</span>
|
|
<span class="c1"># have to be a apart of the data.</span>
|
|
<span class="n">default_keys</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"value"</span><span class="p">:</span> <span class="kc">None</span><span class="p">}</span>
|
|
|
|
<span class="c1"># enable to set/retrieve other arbitrary properties on the Trait</span>
|
|
<span class="c1"># and have them treated like data to store.</span>
|
|
<span class="n">allow_extra_properties</span> <span class="o">=</span> <span class="kc">True</span>
|
|
|
|
<div class="viewcode-block" id="Trait.__init__"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.Trait.__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">trait_data</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> This both initializes and validates the Trait on creation. It must</span>
|
|
<span class="sd"> raise exception if validation fails. The TraitHandler will call this</span>
|
|
<span class="sd"> when the trait is furst added, to make sure it validates before</span>
|
|
<span class="sd"> storing.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> trait_data (any): Any pickle-able values to store with this trait.</span>
|
|
<span class="sd"> This must contain any cls.default_keys that do not have a default</span>
|
|
<span class="sd"> value in cls.data_default_values. Any extra kwargs will be made</span>
|
|
<span class="sd"> available as extra properties on the Trait, assuming the class</span>
|
|
<span class="sd"> variable `allow_extra_properties` is set.</span>
|
|
|
|
<span class="sd"> Raises:</span>
|
|
<span class="sd"> TraitException: If input-validation failed.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="n">validate_input</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="n">trait_data</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">trait_data</span><span class="p">,</span> <span class="n">_SaverDict</span><span class="p">):</span>
|
|
<span class="n">logger</span><span class="o">.</span><span class="n">log_warn</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Non-persistent Trait data (type(trait_data)) "</span>
|
|
<span class="sa">f</span><span class="s2">"loaded for </span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">."</span>
|
|
<span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="Trait.validate_input"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.Trait.validate_input">[docs]</a> <span class="nd">@staticmethod</span>
|
|
<span class="k">def</span> <span class="nf">validate_input</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">trait_data</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Validate input</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> trait_data (dict or _SaverDict): Data to be used for</span>
|
|
<span class="sd"> initialization of this trait.</span>
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> dict: Validated data, possibly complemented with default</span>
|
|
<span class="sd"> values from default_keys.</span>
|
|
<span class="sd"> Raises:</span>
|
|
<span class="sd"> TraitException: If finding unset keys without a default.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_raise_err</span><span class="p">(</span><span class="n">unset_required</span><span class="p">):</span>
|
|
<span class="sd">"""Helper method to format exception."""</span>
|
|
<span class="k">raise</span> <span class="n">TraitException</span><span class="p">(</span>
|
|
<span class="s2">"Trait </span><span class="si">{}</span><span class="s2"> could not be created - misses required keys </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">trait_type</span><span class="p">,</span> <span class="n">list_to_string</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">unset_required</span><span class="p">),</span> <span class="n">addquote</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="n">inp</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">trait_data</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
|
|
|
|
<span class="c1"># separate check for name/trait_type, those are always required.</span>
|
|
<span class="n">req</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">"name"</span><span class="p">,</span> <span class="s2">"trait_type"</span><span class="p">))</span>
|
|
<span class="n">unsets</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">inp</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">req</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">unsets</span><span class="p">:</span>
|
|
<span class="n">_raise_err</span><span class="p">(</span><span class="n">unsets</span><span class="p">)</span>
|
|
|
|
<span class="c1"># check other keys, these likely have defaults to fall back to</span>
|
|
<span class="n">req</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">default_keys</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
|
|
<span class="n">unsets</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">inp</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">req</span><span class="p">))</span>
|
|
<span class="n">unset_defaults</span> <span class="o">=</span> <span class="p">{</span><span class="n">key</span><span class="p">:</span> <span class="bp">cls</span><span class="o">.</span><span class="n">default_keys</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">unsets</span><span class="p">}</span>
|
|
|
|
<span class="k">if</span> <span class="n">MandatoryTraitKey</span> <span class="ow">in</span> <span class="n">unset_defaults</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
|
|
<span class="c1"># we have one or more unset keys that was mandatory</span>
|
|
<span class="n">_raise_err</span><span class="p">([</span><span class="n">key</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">unset_defaults</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="n">MandatoryTraitKey</span><span class="p">])</span>
|
|
<span class="c1"># apply the default values</span>
|
|
<span class="n">trait_data</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">unset_defaults</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">cls</span><span class="o">.</span><span class="n">allow_extra_properties</span><span class="p">:</span>
|
|
<span class="c1"># don't allow any extra properties - remove the extra data</span>
|
|
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="n">key</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">inp</span><span class="o">.</span><span class="n">difference</span><span class="p">(</span><span class="n">req</span><span class="p">)</span> <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"name"</span><span class="p">,</span> <span class="s2">"trait_type"</span><span class="p">)):</span>
|
|
<span class="k">del</span> <span class="n">trait_data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
|
|
|
<span class="k">return</span> <span class="n">trait_data</span></div>
|
|
|
|
<span class="c1"># Grant access to properties on this Trait.</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
|
|
<span class="sd">"""Access extra parameters as dict keys."""</span>
|
|
<span class="k">try</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="n">key</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="sd">"""Set extra parameters as dict keys."""</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="fm">__setattr__</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__delitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
|
|
<span class="sd">"""Delete extra parameters as dict keys."""</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="fm">__delattr__</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
|
|
<span class="sd">"""Access extra parameters as attributes."""</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"default_keys"</span><span class="p">,</span> <span class="s2">"data_default"</span><span class="p">,</span> <span class="s2">"trait_type"</span><span class="p">,</span> <span class="s2">"allow_extra_properties"</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">_GA</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">{!r}</span><span class="s2"> </span><span class="si">{}</span><span class="s2"> (</span><span class="si">{}</span><span class="s2">) has no property </span><span class="si">{!r}</span><span class="s2">."</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">_data</span><span class="p">[</span><span class="s2">"name"</span><span class="p">],</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">trait_type</span><span class="p">,</span> <span class="n">key</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<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">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
<span class="sd">"""Set extra parameters as attributes.</span>
|
|
|
|
<span class="sd"> Arbitrary attributes set on a Trait object will be</span>
|
|
<span class="sd"> stored in the 'extra' key of the `_data` attribute.</span>
|
|
|
|
<span class="sd"> This behavior is enabled by setting the instance</span>
|
|
<span class="sd"> variable `_locked` to True.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">propobj</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="vm">__class__</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">propobj</span><span class="p">,</span> <span class="nb">property</span><span class="p">):</span>
|
|
<span class="c1"># we have a custom property named as this key, find and use its setter</span>
|
|
<span class="k">if</span> <span class="n">propobj</span><span class="o">.</span><span class="n">fset</span><span class="p">:</span>
|
|
<span class="n">propobj</span><span class="o">.</span><span class="n">fset</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="k">return</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># this is some other value</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"_data"</span><span class="p">,):</span>
|
|
<span class="n">_SA</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
|
<span class="k">return</span>
|
|
<span class="k">if</span> <span class="n">_GA</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"allow_extra_properties"</span><span class="p">):</span>
|
|
<span class="n">_GA</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"_data"</span><span class="p">)[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="k">return</span>
|
|
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Can't set attribute </span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2"> on "</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">trait_type</span><span class="si">}</span><span class="s2"> Trait."</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">key</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Delete or reset parameters.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> key (str): property-key to delete.</span>
|
|
<span class="sd"> Raises:</span>
|
|
<span class="sd"> TraitException: If trying to delete a data-key</span>
|
|
<span class="sd"> without a default value to reset to.</span>
|
|
<span class="sd"> Notes:</span>
|
|
<span class="sd"> This will outright delete extra keys (if allow_extra_properties is</span>
|
|
<span class="sd"> set). Keys in self.default_keys with a default value will be</span>
|
|
<span class="sd"> reset to default. A data_key with a default of MandatoryDefaultKey</span>
|
|
<span class="sd"> will raise a TraitException. Unfound matches will be silently ignored.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_keys</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_keys</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">==</span> <span class="n">MandatoryTraitKey</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="n">TraitException</span><span class="p">(</span>
|
|
<span class="s2">"Trait-Key </span><span class="si">{key}</span><span class="s2"> cannot be deleted: It's a mandatory property "</span>
|
|
<span class="s2">"with no default value to fall back to."</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># set to default</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_keys</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># check if we have a custom deleter</span>
|
|
<span class="n">_DA</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="c1"># delete normally</span>
|
|
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># check if we have custom deleter, otherwise ignore</span>
|
|
<span class="n">_DA</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Debug-friendly representation of this Trait."""</span>
|
|
<span class="k">return</span> <span class="s2">"</span><span class="si">{}</span><span class="s2">({{</span><span class="si">{}</span><span class="s2">}})"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
|
<span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
|
|
<span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
|
|
<span class="p">[</span>
|
|
<span class="s2">"'</span><span class="si">{}</span><span class="s2">': </span><span class="si">{!r}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="n">k</span><span class="p">])</span>
|
|
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_keys</span>
|
|
<span class="k">if</span> <span class="n">k</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span>
|
|
<span class="p">]</span>
|
|
<span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="sa">f</span><span class="s2">"<Trait </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s1">'value'</span><span class="p">]</span><span class="si">}</span><span class="s2">>"</span>
|
|
|
|
<span class="c1"># access properties</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Display name for the trait."""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span>
|
|
|
|
<span class="n">key</span> <span class="o">=</span> <span class="n">name</span>
|
|
|
|
<span class="c1"># Numeric operations</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="sd">"""Support equality comparison between Traits or Trait and numeric.</span>
|
|
|
|
<span class="sd"> Note:</span>
|
|
<span class="sd"> This class uses the @functools.total_ordering() decorator to</span>
|
|
<span class="sd"> complete the rich comparison implementation, therefore only</span>
|
|
<span class="sd"> `__eq__` and `__lt__` are implemented.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Trait</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="n">other</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__lt__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="sd">"""Support less than comparison between `Trait`s or `Trait` and numeric."""</span>
|
|
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Trait</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o"><</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o"><</span> <span class="n">other</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__pos__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Access `value` property through unary `+` operator."""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="sd">"""Support addition between `Trait`s or `Trait` and numeric"""</span>
|
|
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Trait</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">+</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">+</span> <span class="n">other</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__sub__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="sd">"""Support subtraction between `Trait`s or `Trait` and numeric"""</span>
|
|
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Trait</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">-</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">-</span> <span class="n">other</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__mul__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="sd">"""Support multiplication between `Trait`s or `Trait` and numeric"""</span>
|
|
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Trait</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">*</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">*</span> <span class="n">other</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__floordiv__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="sd">"""Support floor division between `Trait`s or `Trait` and numeric"""</span>
|
|
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Trait</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">//</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">//</span> <span class="n">other</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="c1"># commutative property</span>
|
|
<span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
|
|
<span class="fm">__rmul__</span> <span class="o">=</span> <span class="fm">__mul__</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__rsub__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="sd">"""Support subtraction between `Trait`s or `Trait` and numeric"""</span>
|
|
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Trait</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">other</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__rfloordiv__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="sd">"""Support floor division between `Trait`s or `Trait` and numeric"""</span>
|
|
<span class="k">if</span> <span class="n">inherits_from</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Trait</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">other</span><span class="o">.</span><span class="n">value</span> <span class="o">//</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">float</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">other</span> <span class="o">//</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
|
|
|
<span class="c1"># Public members</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">value</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Store a value"""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"value"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@value</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">value</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="sd">"""Get value"""</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"value"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span></div>
|
|
|
|
|
|
<span class="c1"># Implementation of the respective Trait types</span>
|
|
|
|
|
|
<div class="viewcode-block" id="StaticTrait"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.StaticTrait">[docs]</a><span class="k">class</span> <span class="nc">StaticTrait</span><span class="p">(</span><span class="n">Trait</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Static Trait. This is a single value with a modifier,</span>
|
|
<span class="sd"> with no concept of a 'current' value or min/max etc.</span>
|
|
|
|
<span class="sd"> value = base + mod</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">trait_type</span> <span class="o">=</span> <span class="s2">"static"</span>
|
|
|
|
<span class="n">default_keys</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"base"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"mod"</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">status</span> <span class="o">=</span> <span class="s2">"</span><span class="si">{value:11}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="s2">"</span><span class="si">{name:12}</span><span class="s2"> </span><span class="si">{status}</span><span class="s2"> (</span><span class="si">{mod:+3}</span><span class="s2">)"</span><span class="o">.</span><span class="n">format</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">name</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="n">status</span><span class="p">,</span> <span class="n">mod</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mod</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Helpers</span>
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">base</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"base"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@base</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">base</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="k">if</span> <span class="n">value</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">_data</span><span class="p">[</span><span class="s2">"base"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_keys</span><span class="p">[</span><span class="s2">"base"</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"base"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">mod</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""The trait's modifier."""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"mod"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@mod</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">mod</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">amount</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">amount</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"mod"</span><span class="p">]</span> <span class="o">=</span> <span class="n">amount</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">value</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="s2">"The value of the Trait"</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span></div>
|
|
|
|
|
|
<div class="viewcode-block" id="CounterTrait"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.CounterTrait">[docs]</a><span class="k">class</span> <span class="nc">CounterTrait</span><span class="p">(</span><span class="n">Trait</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Counter Trait.</span>
|
|
|
|
<span class="sd"> This includes modifications and min/max limits as well as the notion of a</span>
|
|
<span class="sd"> current value. The value can also be reset to the base value.</span>
|
|
|
|
<span class="sd"> min/unset base base+mod max/unset</span>
|
|
<span class="sd"> |--------------|--------|---------X--------X------------|</span>
|
|
<span class="sd"> current value</span>
|
|
<span class="sd"> = current</span>
|
|
<span class="sd"> + mod</span>
|
|
|
|
<span class="sd"> - value = current + mod, starts at base + mod</span>
|
|
<span class="sd"> - if min or max is None, there is no upper/lower bound (default)</span>
|
|
<span class="sd"> - if max is set to "base", max will be equal ot base+mod</span>
|
|
<span class="sd"> - descs are used to optionally describe each value interval.</span>
|
|
<span class="sd"> The desc of the current `value` value can then be retrieved</span>
|
|
<span class="sd"> with .desc(). The property is set as {lower_bound_inclusive:desc}</span>
|
|
<span class="sd"> and should be given smallest-to-biggest. For example, for</span>
|
|
<span class="sd"> a skill rating between 0 and 10:</span>
|
|
<span class="sd"> {0: "unskilled",</span>
|
|
<span class="sd"> 1: "neophyte",</span>
|
|
<span class="sd"> 5: "traited",</span>
|
|
<span class="sd"> 7: "expert",</span>
|
|
<span class="sd"> 9: "master"}</span>
|
|
<span class="sd"> - rate/ratetarget are optional settings to include a rate-of-change</span>
|
|
<span class="sd"> of the current value. This is calculated on-demand and allows for</span>
|
|
<span class="sd"> describing a value that is gradually growing smaller/bigger. The</span>
|
|
<span class="sd"> increase will stop when either reaching a boundary (if set) or</span>
|
|
<span class="sd"> ratetarget. Setting the rate to 0 (default) stops any change.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">trait_type</span> <span class="o">=</span> <span class="s2">"counter"</span>
|
|
|
|
<span class="c1"># current starts equal to base.</span>
|
|
<span class="n">default_keys</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"base"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"mod"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"min"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="s2">"max"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="s2">"descs"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="s2">"rate"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"ratetarget"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
|
|
<div class="viewcode-block" id="CounterTrait.validate_input"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.CounterTrait.validate_input">[docs]</a> <span class="nd">@staticmethod</span>
|
|
<span class="k">def</span> <span class="nf">validate_input</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">trait_data</span><span class="p">):</span>
|
|
<span class="sd">"""Add extra validation for descs"""</span>
|
|
<span class="n">trait_data</span> <span class="o">=</span> <span class="n">Trait</span><span class="o">.</span><span class="n">validate_input</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">trait_data</span><span class="p">)</span>
|
|
<span class="c1"># validate descs</span>
|
|
<span class="n">descs</span> <span class="o">=</span> <span class="n">trait_data</span><span class="p">[</span><span class="s2">"descs"</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">descs</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span>
|
|
<span class="ow">not</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">))</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">))</span>
|
|
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">descs</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
|
<span class="p">):</span>
|
|
<span class="k">raise</span> <span class="n">TraitException</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Trait descs must be defined on the "</span>
|
|
<span class="sa">f</span><span class="s2">"form </span><span class="se">{{</span><span class="s2">number:str</span><span class="se">}}</span><span class="s2"> (instead found </span><span class="si">{</span><span class="n">descs</span><span class="si">}</span><span class="s2">)."</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># set up rate</span>
|
|
<span class="k">if</span> <span class="n">trait_data</span><span class="p">[</span><span class="s2">"rate"</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="n">trait_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">trait_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">return</span> <span class="n">trait_data</span></div>
|
|
|
|
<span class="c1"># Helpers</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_within_boundaries</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="sd">"""Check if given value is within boundaries"""</span>
|
|
<span class="k">return</span> <span class="ow">not</span> <span class="p">(</span>
|
|
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o"><=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">)</span>
|
|
<span class="ow">or</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">>=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_enforce_boundaries</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="sd">"""Ensures that incoming value falls within boundaries"""</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o"><=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">>=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span>
|
|
<span class="k">return</span> <span class="n">value</span>
|
|
|
|
<span class="c1"># timer component</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_passed_ratetarget</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="sd">"""Check if we passed the ratetarget in either direction."""</span>
|
|
<span class="n">ratetarget</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"ratetarget"</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="n">ratetarget</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="p">(</span>
|
|
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rate</span> <span class="o"><</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">value</span> <span class="o"><=</span> <span class="n">ratetarget</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rate</span> <span class="o">></span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">>=</span> <span class="n">ratetarget</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_stop_timer</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Stop rate-timer component."""</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rate</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</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">_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_check_and_start_timer</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="sd">"""Start timer if we are not at a boundary."""</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rate</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_within_boundaries</span><span class="p">(</span><span class="n">value</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">_passed_ratetarget</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="c1"># we are not at a boundary [anymore].</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="n">value</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_update_current</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">current</span><span class="p">):</span>
|
|
<span class="sd">"""Update current value by scaling with rate and time passed."""</span>
|
|
<span class="n">rate</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rate</span>
|
|
<span class="k">if</span> <span class="n">rate</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
|
|
<span class="n">tdiff</span> <span class="o">=</span> <span class="n">now</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span>
|
|
<span class="n">current</span> <span class="o">+=</span> <span class="n">rate</span> <span class="o">*</span> <span class="n">tdiff</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">current</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span>
|
|
|
|
<span class="c1"># we must make sure so we don't overstep our bounds</span>
|
|
<span class="c1"># even if .mod is included</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_passed_ratetarget</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="n">current</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"ratetarget"</span><span class="p">]</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_stop_timer</span><span class="p">()</span>
|
|
<span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_within_boundaries</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="n">current</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_enforce_boundaries</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_stop_timer</span><span class="p">()</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span> <span class="o">=</span> <span class="n">now</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"current"</span><span class="p">]</span> <span class="o">=</span> <span class="n">current</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">base</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">round</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">current</span>
|
|
|
|
<span class="c1"># properties</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">base</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"base"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@base</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">base</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="k">if</span> <span class="n">value</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">_data</span><span class="p">[</span><span class="s2">"base"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_keys</span><span class="p">[</span><span class="s2">"base"</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span> <span class="o">></span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"base"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">mod</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"mod"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@mod</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">mod</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="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># unsetting the boundary to default</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"mod"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_keys</span><span class="p">[</span><span class="s2">"mod"</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span> <span class="o">></span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"mod"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">min</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"min"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@min</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">min</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="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># unsetting the boundary</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"min"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max</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">_data</span><span class="p">[</span><span class="s2">"min"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">min</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">base</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">max</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"max"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@max</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">max</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="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># unsetting the boundary</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"max"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</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">_data</span><span class="p">[</span><span class="s2">"max"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">max</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">base</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">current</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""The `current` value of the `Trait`. This does not have .mod added."""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_update_current</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"current"</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span><span class="p">))</span>
|
|
|
|
<span class="nd">@current</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">current</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="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"current"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_check_and_start_timer</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_enforce_boundaries</span><span class="p">(</span><span class="n">value</span><span class="p">))</span>
|
|
|
|
<span class="nd">@current</span><span class="o">.</span><span class="n">deleter</span>
|
|
<span class="k">def</span> <span class="nf">current</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""reset back to base"""</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"current"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">value</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="s2">"The value of the Trait (current + mod)"</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_enforce_boundaries</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">current</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">ratetarget</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"ratetarget"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@ratetarget</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">ratetarget</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">_data</span><span class="p">[</span><span class="s2">"ratetarget"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_enforce_boundaries</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">_check_and_start_timer</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
|
|
|
|
<div class="viewcode-block" id="CounterTrait.percent"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.CounterTrait.percent">[docs]</a> <span class="k">def</span> <span class="nf">percent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">formatting</span><span class="o">=</span><span class="s2">"</span><span class="si">{:3.1f}</span><span class="s2">%"</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Return the current value as a percentage.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> formatting (str, optional): Should contain a</span>
|
|
<span class="sd"> format-tag which will receive the value. If</span>
|
|
<span class="sd"> this is set to None, the raw float will be</span>
|
|
<span class="sd"> returned.</span>
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> float or str: Depending of if a `formatting` string</span>
|
|
<span class="sd"> is supplied or not.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">percent</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="p">,</span> <span class="n">formatting</span><span class="o">=</span><span class="n">formatting</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="CounterTrait.reset"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.CounterTrait.reset">[docs]</a> <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Resets `current` property equal to `base` value."""</span>
|
|
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">current</span></div>
|
|
|
|
<div class="viewcode-block" id="CounterTrait.desc"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.CounterTrait.desc">[docs]</a> <span class="k">def</span> <span class="nf">desc</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Retrieve descriptions of the current value, if available.</span>
|
|
|
|
<span class="sd"> This must be a mapping {upper_bound_inclusive: text},</span>
|
|
<span class="sd"> ordered from small to big. Any value above the highest</span>
|
|
<span class="sd"> upper bound will be included as being in the highest bound.</span>
|
|
<span class="sd"> rely on Python3.7+ dicts retaining ordering to let this</span>
|
|
<span class="sd"> describe the interval.</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> str: The description describing the `value` value.</span>
|
|
<span class="sd"> If not found, returns the empty string.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">descs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"descs"</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">descs</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="s2">""</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
|
|
<span class="c1"># we rely on Python3.7+ dicts retaining ordering</span>
|
|
<span class="n">highest</span> <span class="o">=</span> <span class="s2">""</span>
|
|
<span class="k">for</span> <span class="n">bound</span><span class="p">,</span> <span class="n">txt</span> <span class="ow">in</span> <span class="n">descs</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="n">highest</span> <span class="o">=</span> <span class="n">txt</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="o"><=</span> <span class="n">bound</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">txt</span>
|
|
<span class="c1"># if we get here we are above the highest bound so</span>
|
|
<span class="c1"># we return the latest bound specified.</span>
|
|
<span class="k">return</span> <span class="n">highest</span></div></div>
|
|
|
|
|
|
<div class="viewcode-block" id="GaugeTrait"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.GaugeTrait">[docs]</a><span class="k">class</span> <span class="nc">GaugeTrait</span><span class="p">(</span><span class="n">CounterTrait</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Gauge Trait.</span>
|
|
|
|
<span class="sd"> This emulates a gauge-meter that empties from a base+mod value.</span>
|
|
|
|
<span class="sd"> min/0 max=base+mod</span>
|
|
<span class="sd"> |-----------------------X---------------------------|</span>
|
|
<span class="sd"> value</span>
|
|
<span class="sd"> = current</span>
|
|
|
|
<span class="sd"> - min defaults to 0</span>
|
|
<span class="sd"> - max value is always base + mad</span>
|
|
<span class="sd"> - .max is an alias of .base</span>
|
|
<span class="sd"> - value = current and varies from min to max.</span>
|
|
<span class="sd"> - descs is a mapping {upper_bound_inclusive: desc}. These</span>
|
|
<span class="sd"> are checked with .desc() and can be retrieve a text</span>
|
|
<span class="sd"> description for a given current value.</span>
|
|
|
|
<span class="sd"> For example, this could be used to describe health</span>
|
|
<span class="sd"> values between 0 and 100:</span>
|
|
<span class="sd"> {0: "Dead"</span>
|
|
<span class="sd"> 10: "Badly hurt",</span>
|
|
<span class="sd"> 30: "Bleeding",</span>
|
|
<span class="sd"> 50: "Hurting",</span>
|
|
<span class="sd"> 90: "Healthy"}</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">trait_type</span> <span class="o">=</span> <span class="s2">"gauge"</span>
|
|
|
|
<span class="c1"># same as Counter, here for easy reference</span>
|
|
<span class="c1"># current starts out equal to base</span>
|
|
<span class="n">default_keys</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"base"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"mod"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"min"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"descs"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="s2">"rate"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"ratetarget"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_update_current</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">current</span><span class="p">):</span>
|
|
<span class="sd">"""Update current value by scaling with rate and time passed."""</span>
|
|
<span class="n">rate</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rate</span>
|
|
<span class="k">if</span> <span class="n">rate</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
|
|
<span class="n">tdiff</span> <span class="o">=</span> <span class="n">now</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span>
|
|
<span class="n">current</span> <span class="o">+=</span> <span class="n">rate</span> <span class="o">*</span> <span class="n">tdiff</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="n">current</span>
|
|
|
|
<span class="c1"># we don't worry about .mod for gauges</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_passed_ratetarget</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="n">current</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"ratetarget"</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_stop_timer</span><span class="p">()</span>
|
|
<span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_within_boundaries</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="n">current</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_enforce_boundaries</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">_stop_timer</span><span class="p">()</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"last_update"</span><span class="p">]</span> <span class="o">=</span> <span class="n">now</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"current"</span><span class="p">]</span> <span class="o">=</span> <span class="n">current</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">base</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">round</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">current</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_enforce_boundaries</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="sd">"""Ensures that incoming value falls within trait's range."""</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o"><=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span>
|
|
<span class="k">return</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mod</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">status</span> <span class="o">=</span> <span class="s2">"</span><span class="si">{value:4}</span><span class="s2"> / </span><span class="si">{base:4}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">base</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="s2">"</span><span class="si">{name:12}</span><span class="s2"> </span><span class="si">{status}</span><span class="s2"> (</span><span class="si">{mod:+3}</span><span class="s2">)"</span><span class="o">.</span><span class="n">format</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">name</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="n">status</span><span class="p">,</span> <span class="n">mod</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mod</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">base</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"base"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@base</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">base</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="sd">"""Limit so base+mod can never go below min."""</span>
|
|
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"base"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">mod</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"mod"</span><span class="p">]</span>
|
|
|
|
<span class="nd">@mod</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">mod</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="sd">"""Limit so base+mod can never go below min."""</span>
|
|
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">:</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"mod"</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">min</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">val</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"min"</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_keys</span><span class="p">[</span><span class="s2">"min"</span><span class="p">]</span> <span class="k">if</span> <span class="n">val</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">val</span>
|
|
|
|
<span class="nd">@min</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">min</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="sd">"""Limit so min can never be greater than base+mod."""</span>
|
|
<span class="k">if</span> <span class="n">value</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">_data</span><span class="p">[</span><span class="s2">"min"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_keys</span><span class="p">[</span><span class="s2">"min"</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"min"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">min</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">base</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">max</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="s2">"The max is always base + mod."</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span>
|
|
|
|
<span class="nd">@max</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">max</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="k">raise</span> <span class="n">TraitException</span><span class="p">(</span>
|
|
<span class="s2">"The .max property is not settable on GaugeTraits. Set .mod and .base instead."</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="nd">@max</span><span class="o">.</span><span class="n">deleter</span>
|
|
<span class="k">def</span> <span class="nf">max</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="n">TraitException</span><span class="p">(</span>
|
|
<span class="s2">"The .max property cannot be reset on GaugeTraits. Reset .mod and .base instead."</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">current</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""The `current` value of the gauge."""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_update_current</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_enforce_boundaries</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"current"</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span><span class="p">))</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="nd">@current</span><span class="o">.</span><span class="n">setter</span>
|
|
<span class="k">def</span> <span class="nf">current</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="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"current"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_check_and_start_timer</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_enforce_boundaries</span><span class="p">(</span><span class="n">value</span><span class="p">))</span>
|
|
|
|
<span class="nd">@current</span><span class="o">.</span><span class="n">deleter</span>
|
|
<span class="k">def</span> <span class="nf">current</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="s2">"Resets current back to 'full'"</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">"current"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">base</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">mod</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">value</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="s2">"The value of the trait"</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">current</span>
|
|
|
|
<div class="viewcode-block" id="GaugeTrait.percent"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.GaugeTrait.percent">[docs]</a> <span class="k">def</span> <span class="nf">percent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">formatting</span><span class="o">=</span><span class="s2">"</span><span class="si">{:3.1f}</span><span class="s2">%"</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Return the current value as a percentage.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> formatting (str, optional): Should contain a</span>
|
|
<span class="sd"> format-tag which will receive the value. If</span>
|
|
<span class="sd"> this is set to None, the raw float will be</span>
|
|
<span class="sd"> returned.</span>
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> float or str: Depending of if a `formatting` string</span>
|
|
<span class="sd"> is supplied or not.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">percent</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">current</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="p">,</span> <span class="n">formatting</span><span class="o">=</span><span class="n">formatting</span><span class="p">)</span></div>
|
|
|
|
<div class="viewcode-block" id="GaugeTrait.reset"><a class="viewcode-back" href="../../../api/evennia.contrib.traits.html#evennia.contrib.traits.GaugeTrait.reset">[docs]</a> <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Fills the gauge to its maximum allowed by base + mod</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">current</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="traits.html">1.0-dev (develop branch)</a></li>
|
|
<li><a href="../../../../0.95/index.html">0.95 (v0.9.5 branch)</a></li>
|
|
</ul>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="clearer"></div>
|
|
</div>
|
|
<div class="related" role="navigation" aria-label="related navigation">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../../../genindex.html" title="General Index"
|
|
>index</a></li>
|
|
<li class="right" >
|
|
<a href="../../../py-modindex.html" title="Python Module Index"
|
|
>modules</a> |</li>
|
|
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia 1.0-dev</a> »</li>
|
|
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> »</li>
|
|
<li class="nav-item nav-item-2"><a href="../../evennia.html" >evennia</a> »</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">
|
|
© Copyright 2020, The Evennia developer community.
|
|
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
|
</div>
|
|
</body>
|
|
</html> |