Updated HTML docs

This commit is contained in:
Griatch 2021-10-05 22:35:41 +02:00
parent 40b2ba0cee
commit cad698493d
87 changed files with 1496 additions and 635 deletions

View file

@ -167,7 +167,7 @@
<span class="c1"># the user might be trying to identify the command</span>
<span class="c1"># with a #num-command style syntax. We expect the regex to</span>
<span class="c1"># contain the groups &quot;number&quot; and &quot;name&quot;.</span>
<span class="n">mindex</span><span class="p">,</span> <span class="n">new_raw_string</span> <span class="o">=</span> <span class="p">(</span><span class="n">num_ref_match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">&quot;number&quot;</span><span class="p">),</span> <span class="n">num_ref_match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">))</span>
<span class="n">mindex</span><span class="p">,</span> <span class="n">new_raw_string</span> <span class="o">=</span> <span class="p">(</span><span class="n">num_ref_match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">&quot;number&quot;</span><span class="p">),</span> <span class="n">num_ref_match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="n">num_ref_match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s2">&quot;args&quot;</span><span class="p">))</span>
<span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">mindex</span><span class="p">),</span> <span class="n">new_raw_string</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span></div>

View file

@ -68,6 +68,7 @@
<span class="n">COMMAND_DEFAULT_CLASS</span> <span class="o">=</span> <span class="n">class_from_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">COMMAND_DEFAULT_CLASS</span><span class="p">)</span>
<span class="n">_TASK_HANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">_BROADCAST_SERVER_RESTART_MESSAGES</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">BROADCAST_SERVER_RESTART_MESSAGES</span>
<span class="c1"># delayed imports</span>
<span class="n">_RESOURCE</span> <span class="o">=</span> <span class="kc">None</span>
@ -111,7 +112,8 @@
<span class="n">reason</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="n">reason</span> <span class="o">=</span> <span class="s2">&quot;(Reason: </span><span class="si">%s</span><span class="s2">) &quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s2">&quot;.&quot;</span><span class="p">)</span>
<span class="n">SESSIONS</span><span class="o">.</span><span class="n">announce_all</span><span class="p">(</span><span class="s2">&quot; Server restart initiated </span><span class="si">%s</span><span class="s2">...&quot;</span> <span class="o">%</span> <span class="n">reason</span><span class="p">)</span>
<span class="k">if</span> <span class="n">_BROADCAST_SERVER_RESTART_MESSAGES</span><span class="p">:</span>
<span class="n">SESSIONS</span><span class="o">.</span><span class="n">announce_all</span><span class="p">(</span><span class="s2">&quot; Server restart initiated </span><span class="si">%s</span><span class="s2">...&quot;</span> <span class="o">%</span> <span class="n">reason</span><span class="p">)</span>
<span class="n">SESSIONS</span><span class="o">.</span><span class="n">portal_restart_server</span><span class="p">()</span></div></div>

View file

@ -317,8 +317,8 @@
<span class="c1"># {&quot;vv&quot;: [&quot;ea&quot;, &quot;oh&quot;, ...], ...}</span>
<span class="n">grammar2phonemes</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
<span class="k">for</span> <span class="n">phoneme</span> <span class="ow">in</span> <span class="n">phonemes</span><span class="o">.</span><span class="n">split</span><span class="p">():</span>
<span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\W&quot;</span><span class="p">,</span> <span class="n">phoneme</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">LanguageError</span><span class="p">(</span><span class="s2">&quot;The phoneme &#39;</span><span class="si">%s</span><span class="s2">&#39; contains an invalid character&quot;</span> <span class="o">%</span> <span class="n">phoneme</span><span class="p">)</span>
<span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\W&quot;</span><span class="p">,</span> <span class="n">phoneme</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">U</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">LanguageError</span><span class="p">(</span><span class="s2">&quot;The phoneme &#39;</span><span class="si">%s</span><span class="s2">&#39; contains an invalid character.&quot;</span> <span class="o">%</span> <span class="n">phoneme</span><span class="p">)</span>
<span class="n">gram</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s2">&quot;v&quot;</span> <span class="k">if</span> <span class="n">char</span> <span class="ow">in</span> <span class="n">vowels</span> <span class="k">else</span> <span class="s2">&quot;c&quot;</span> <span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="n">phoneme</span><span class="p">])</span>
<span class="n">grammar2phonemes</span><span class="p">[</span><span class="n">gram</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">phoneme</span><span class="p">)</span>
@ -514,7 +514,7 @@
<span class="sd"> Args:</span>
<span class="sd"> text (str): Text to obfuscate.</span>
<span class="sd"> level (real, optional): A value from 0.0-1.0 determining</span>
<span class="sd"> the level of obfuscation where 0 means no jobfuscation</span>
<span class="sd"> the level of obfuscation where 0 means no obfuscation</span>
<span class="sd"> (string returned unchanged) and 1.0 means the entire</span>
<span class="sd"> string is obfuscated.</span>
<span class="sd"> language (str, optional): The identifier of a language</span>

View file

@ -69,7 +69,7 @@
<span class="sd"> /alias to reference objects in the room. You can use any</span>
<span class="sd"> number of sdesc sub-parts to differentiate a local sdesc, or</span>
<span class="sd"> use /1-sdesc etc to differentiate them. The emote also</span>
<span class="sd"> identifies nested says.</span>
<span class="sd"> identifies nested says and separates case.</span>
<span class="sd"> - sdesc obscuration of real character names for use in emotes</span>
<span class="sd"> and in any referencing such as object.search(). This relies</span>
<span class="sd"> on an SdescHandler `sdesc` being set on the Character and</span>
@ -102,13 +102,18 @@
<span class="sd">by the player of the tall man, so that people looking at him can tell</span>
<span class="sd">at a glance what is going on.</span>
<span class="sd">&gt; emote /me looks at /tall and says &quot;Hello!&quot;</span>
<span class="sd">&gt; emote /me looks at /Tall and says &quot;Hello!&quot;</span>
<span class="sd">I see:</span>
<span class="sd"> Griatch looks at Tall man and says &quot;Hello&quot;.</span>
<span class="sd">Tall man (assuming his name is Tom) sees:</span>
<span class="sd"> The godlike figure looks at Tom and says &quot;Hello&quot;.</span>
<span class="sd">Note that by default, the case of the tag matters, so `/tall` will</span>
<span class="sd">lead to &#39;tall man&#39; while `/Tall` will become &#39;Tall man&#39; and /TALL</span>
<span class="sd">becomes /TALL MAN. If you don&#39;t want this behavior, you can pass</span>
<span class="sd">case_sensitive=False to the `send_emote` function.</span>
<span class="sd">Verbose Installation Instructions:</span>
<span class="sd"> 1. In typeclasses/character.py:</span>
@ -131,9 +136,9 @@
<span class="sd"> Inherit `ContribRPObject`:</span>
<span class="sd"> Change `class Object(DefaultObject):` to</span>
<span class="sd"> `class Object(ContribRPObject):`</span>
<span class="sd"> 4. Reload the server (@reload or from console: &quot;evennia reload&quot;)</span>
<span class="sd"> 4. Reload the server (`reload` or from console: &quot;evennia reload&quot;)</span>
<span class="sd"> 5. Force typeclass updates as required. Example for your character:</span>
<span class="sd"> @type/reset/force me = typeclasses.characters.Character</span>
<span class="sd"> `type/reset/force me = typeclasses.characters.Character`</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">re</span>
@ -188,8 +193,9 @@
<span class="n">_RE_LEFT_BRACKETS</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\{+&quot;</span><span class="p">,</span> <span class="n">_RE_FLAGS</span><span class="p">)</span>
<span class="n">_RE_RIGHT_BRACKETS</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\}+&quot;</span><span class="p">,</span> <span class="n">_RE_FLAGS</span><span class="p">)</span>
<span class="c1"># Reference markers are used internally when distributing the emote to</span>
<span class="c1"># all that can see it. They are never seen by players and are on the form {#dbref}.</span>
<span class="n">_RE_REF</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\{+\#([0-9]+)\}+&quot;</span><span class="p">)</span>
<span class="c1"># all that can see it. They are never seen by players and are on the form {#dbref&lt;char&gt;}</span>
<span class="c1"># with the &lt;char&gt; indicating case of the original reference query (like ^ for uppercase)</span>
<span class="n">_RE_REF</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\{+\#([0-9]+[\^\~tv]{0,1})\}+&quot;</span><span class="p">)</span>
<span class="c1"># This regex is used to quickly reference one self in an emote.</span>
<span class="n">_RE_SELF_REF</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;/me|@&quot;</span><span class="p">,</span> <span class="n">_RE_FLAGS</span><span class="p">)</span>
@ -375,7 +381,7 @@
<span class="k">return</span> <span class="n">emote</span><span class="p">,</span> <span class="n">mapping</span></div>
<div class="viewcode-block" id="parse_sdescs_and_recogs"><a class="viewcode-back" href="../../../api/evennia.contrib.rpsystem.html#evennia.contrib.rpsystem.parse_sdescs_and_recogs">[docs]</a><span class="k">def</span> <span class="nf">parse_sdescs_and_recogs</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">candidates</span><span class="p">,</span> <span class="n">string</span><span class="p">,</span> <span class="n">search_mode</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<div class="viewcode-block" id="parse_sdescs_and_recogs"><a class="viewcode-back" href="../../../api/evennia.contrib.rpsystem.html#evennia.contrib.rpsystem.parse_sdescs_and_recogs">[docs]</a><span class="k">def</span> <span class="nf">parse_sdescs_and_recogs</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">candidates</span><span class="p">,</span> <span class="n">string</span><span class="p">,</span> <span class="n">search_mode</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">case_sensitive</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Read a raw emote and parse it into an intermediary</span>
<span class="sd"> format for distributing to all observers.</span>
@ -388,6 +394,11 @@
<span class="sd"> string (str): The string (like an emote) we want to analyze for keywords.</span>
<span class="sd"> search_mode (bool, optional): If `True`, the &quot;emote&quot; is a query string</span>
<span class="sd"> we want to analyze. If so, the return value is changed.</span>
<span class="sd"> case_sensitive (bool, optional); If set, the case of /refs matter, so that</span>
<span class="sd"> /tall will come out as &#39;tall man&#39; while /Tall will become &#39;Tall man&#39;.</span>
<span class="sd"> This allows for more grammatically correct emotes at the cost of being</span>
<span class="sd"> a little more to learn for players. If disabled, the original sdesc case</span>
<span class="sd"> is always kept and are inserted as-is.</span>
<span class="sd"> Returns:</span>
<span class="sd"> (emote, mapping) (tuple): If `search_mode` is `False`</span>
@ -494,10 +505,32 @@
<span class="k">elif</span> <span class="n">nmatches</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_EMOTE_NOMATCH_ERROR</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">ref</span><span class="o">=</span><span class="n">marker_match</span><span class="o">.</span><span class="n">group</span><span class="p">()))</span>
<span class="k">elif</span> <span class="n">nmatches</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;#</span><span class="si">%i</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">obj</span><span class="o">.</span><span class="n">id</span>
<span class="c1"># a unique match - parse into intermediary representation</span>
<span class="n">case</span> <span class="o">=</span> <span class="s1">&#39;~&#39;</span> <span class="c1"># retain original case of sdesc</span>
<span class="k">if</span> <span class="n">case_sensitive</span><span class="p">:</span>
<span class="c1"># case sensitive mode</span>
<span class="c1"># internal flags for the case used for the original /query</span>
<span class="c1"># - t for titled input (like /Name)</span>
<span class="c1"># - ^ for all upercase input (likle /NAME)</span>
<span class="c1"># - v for lower-case input (like /name)</span>
<span class="c1"># - ~ for mixed case input (like /nAmE)</span>
<span class="n">matchtext</span> <span class="o">=</span> <span class="n">marker_match</span><span class="o">.</span><span class="n">group</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_RE_SELF_REF</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">matchtext</span><span class="p">):</span>
<span class="c1"># self-refs are kept as-is, others are parsed by case</span>
<span class="n">matchtext</span> <span class="o">=</span> <span class="n">marker_match</span><span class="o">.</span><span class="n">group</span><span class="p">()</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="n">_PREFIX</span><span class="p">)</span>
<span class="k">if</span> <span class="n">matchtext</span><span class="o">.</span><span class="n">istitle</span><span class="p">():</span>
<span class="n">case</span> <span class="o">=</span> <span class="s1">&#39;t&#39;</span>
<span class="k">elif</span> <span class="n">matchtext</span><span class="o">.</span><span class="n">isupper</span><span class="p">():</span>
<span class="n">case</span> <span class="o">=</span> <span class="s1">&#39;^&#39;</span>
<span class="k">elif</span> <span class="n">matchtext</span><span class="o">.</span><span class="n">islower</span><span class="p">():</span>
<span class="n">case</span> <span class="o">=</span> <span class="s1">&#39;v&#39;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;#</span><span class="si">%i%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">case</span><span class="p">)</span>
<span class="n">string</span> <span class="o">=</span> <span class="n">string</span><span class="p">[:</span><span class="n">istart0</span><span class="p">]</span> <span class="o">+</span> <span class="s2">&quot;{</span><span class="si">%s</span><span class="s2">}&quot;</span> <span class="o">%</span> <span class="n">key</span> <span class="o">+</span> <span class="n">string</span><span class="p">[</span><span class="n">istart</span> <span class="o">+</span> <span class="n">maxscore</span><span class="p">:]</span>
<span class="n">mapping</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># multimatch error</span>
<span class="n">refname</span> <span class="o">=</span> <span class="n">marker_match</span><span class="o">.</span><span class="n">group</span><span class="p">()</span>
<span class="n">reflist</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;</span><span class="si">%s%s%s</span><span class="s2"> (</span><span class="si">%s%s</span><span class="s2">)&quot;</span>
@ -549,30 +582,42 @@
<span class="sd"> - None: No auto-add at anonymous emote</span>
<span class="sd"> - &#39;last&#39;: Add sender to the end of emote as [sender]</span>
<span class="sd"> - &#39;first&#39;: Prepend sender to start of emote.</span>
<span class="sd"> Kwargs:</span>
<span class="sd"> case_sensitive (bool): Defaults to True, but can be unset</span>
<span class="sd"> here. When enabled, /tall will lead to a lowercase</span>
<span class="sd"> &#39;tall man&#39; while /Tall will lead to &#39;Tall man&#39; and</span>
<span class="sd"> /TALL will lead to &#39;TALL MAN&#39;. If disabled, the sdesc&#39;s</span>
<span class="sd"> case will always be used, regardless of the /ref case used.</span>
<span class="sd"> any: Other kwargs will be passed on into the receiver&#39;s process_sdesc and</span>
<span class="sd"> process_recog methods, and can thus be used to customize those.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">case_sensitive</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;case_sensitive&quot;</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">emote</span><span class="p">,</span> <span class="n">obj_mapping</span> <span class="o">=</span> <span class="n">parse_sdescs_and_recogs</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">receivers</span><span class="p">,</span> <span class="n">emote</span><span class="p">)</span>
<span class="n">emote</span><span class="p">,</span> <span class="n">obj_mapping</span> <span class="o">=</span> <span class="n">parse_sdescs_and_recogs</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">receivers</span><span class="p">,</span> <span class="n">emote</span><span class="p">,</span>
<span class="n">case_sensitive</span><span class="o">=</span><span class="n">case_sensitive</span><span class="p">)</span>
<span class="n">emote</span><span class="p">,</span> <span class="n">language_mapping</span> <span class="o">=</span> <span class="n">parse_language</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">emote</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="n">EmoteError</span><span class="p">,</span> <span class="n">LanguageError</span><span class="p">)</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="c1"># handle all error messages, don&#39;t hide actual coding errors</span>
<span class="n">sender</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">err</span><span class="p">))</span>
<span class="k">return</span>
<span class="n">skey</span> <span class="o">=</span> <span class="s2">&quot;#</span><span class="si">%i</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">sender</span><span class="o">.</span><span class="n">id</span>
<span class="c1"># we escape the object mappings since we&#39;ll do the language ones first</span>
<span class="c1"># (the text could have nested object mappings).</span>
<span class="n">emote</span> <span class="o">=</span> <span class="n">_RE_REF</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;{{#\1}}&quot;</span><span class="p">,</span> <span class="n">emote</span><span class="p">)</span>
<span class="c1"># if anonymous_add is passed as a kwarg, collect and remove it from kwargs</span>
<span class="k">if</span> <span class="s1">&#39;anonymous_add&#39;</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
<span class="n">anonymous_add</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;anonymous_add&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">anonymous_add</span> <span class="ow">and</span> <span class="ow">not</span> <span class="s2">&quot;#</span><span class="si">%i</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">sender</span><span class="o">.</span><span class="n">id</span> <span class="ow">in</span> <span class="n">obj_mapping</span><span class="p">:</span>
<span class="k">if</span> <span class="n">anonymous_add</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="mi">1</span> <span class="k">for</span> <span class="n">tag</span> <span class="ow">in</span> <span class="n">obj_mapping</span> <span class="k">if</span> <span class="n">tag</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">skey</span><span class="p">)):</span>
<span class="c1"># no self-reference in the emote - add to the end</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;#</span><span class="si">%i</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">sender</span><span class="o">.</span><span class="n">id</span>
<span class="n">obj_mapping</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">sender</span>
<span class="n">obj_mapping</span><span class="p">[</span><span class="n">skey</span><span class="p">]</span> <span class="o">=</span> <span class="n">sender</span>
<span class="k">if</span> <span class="n">anonymous_add</span> <span class="o">==</span> <span class="s2">&quot;first&quot;</span><span class="p">:</span>
<span class="n">possessive</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span> <span class="k">if</span> <span class="n">emote</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;&#39;&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="s2">&quot; &quot;</span>
<span class="n">emote</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s%s%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="s2">&quot;{{</span><span class="si">%s</span><span class="s2">}}&quot;</span> <span class="o">%</span> <span class="n">key</span><span class="p">,</span> <span class="n">possessive</span><span class="p">,</span> <span class="n">emote</span><span class="p">)</span>
<span class="n">emote</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s%s%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="s2">&quot;{{</span><span class="si">%s</span><span class="s2">}}&quot;</span> <span class="o">%</span> <span class="n">skey</span><span class="p">,</span> <span class="n">possessive</span><span class="p">,</span> <span class="n">emote</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">emote</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> [</span><span class="si">%s</span><span class="s2">]&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">emote</span><span class="p">,</span> <span class="s2">&quot;{{</span><span class="si">%s</span><span class="s2">}}&quot;</span> <span class="o">%</span> <span class="n">key</span><span class="p">)</span>
<span class="n">emote</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> [</span><span class="si">%s</span><span class="s2">]&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">emote</span><span class="p">,</span> <span class="s2">&quot;{{</span><span class="si">%s</span><span class="s2">}}&quot;</span> <span class="o">%</span> <span class="n">skey</span><span class="p">)</span>
<span class="c1"># broadcast emote to everyone</span>
<span class="k">for</span> <span class="n">receiver</span> <span class="ow">in</span> <span class="n">receivers</span><span class="p">:</span>
@ -586,7 +631,7 @@
<span class="c1"># color says</span>
<span class="n">receiver_lang_mapping</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">process_language</span><span class="p">(</span><span class="n">saytext</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">langname</span><span class="p">)</span>
<span class="c1"># map the language {##num} markers. This will convert the escaped sdesc markers on</span>
<span class="c1"># the form {{#num}} to {#num} markers ready to sdescmat in the next step.</span>
<span class="c1"># the form {{#num}} to {#num} markers ready to sdesc-map in the next step.</span>
<span class="n">sendemote</span> <span class="o">=</span> <span class="n">emote</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">receiver_lang_mapping</span><span class="p">)</span>
<span class="c1"># handle sdesc mappings. we make a temporary copy that we can modify</span>
@ -603,22 +648,27 @@
<span class="k">try</span><span class="p">:</span>
<span class="n">recog_get</span> <span class="o">=</span> <span class="n">receiver</span><span class="o">.</span><span class="n">recog</span><span class="o">.</span><span class="n">get</span>
<span class="n">receiver_sdesc_mapping</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
<span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">process_recog</span><span class="p">(</span><span class="n">recog_get</span><span class="p">(</span><span class="n">obj</span><span class="p">),</span> <span class="n">obj</span><span class="p">))</span> <span class="k">for</span> <span class="n">ref</span><span class="p">,</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">obj_mapping</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="p">(</span><span class="n">ref</span><span class="p">,</span> <span class="n">process_recog</span><span class="p">(</span><span class="n">recog_get</span><span class="p">(</span><span class="n">obj</span><span class="p">),</span> <span class="n">obj</span><span class="p">,</span> <span class="n">ref</span><span class="o">=</span><span class="n">ref</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">))</span>
<span class="k">for</span> <span class="n">ref</span><span class="p">,</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">obj_mapping</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="p">)</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="n">receiver_sdesc_mapping</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
<span class="p">(</span>
<span class="n">ref</span><span class="p">,</span>
<span class="n">process_sdesc</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">sdesc</span><span class="o">.</span><span class="n">get</span><span class="p">(),</span> <span class="n">obj</span><span class="p">)</span>
<span class="n">process_sdesc</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">sdesc</span><span class="o">.</span><span class="n">get</span><span class="p">(),</span> <span class="n">obj</span><span class="p">,</span> <span class="n">ref</span><span class="o">=</span><span class="n">ref</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s2">&quot;sdesc&quot;</span><span class="p">)</span>
<span class="k">else</span> <span class="n">process_sdesc</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">obj</span><span class="p">),</span>
<span class="k">else</span> <span class="n">process_sdesc</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">ref</span><span class="o">=</span><span class="n">ref</span><span class="p">),</span>
<span class="p">)</span>
<span class="k">for</span> <span class="n">ref</span><span class="p">,</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">obj_mapping</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="p">)</span>
<span class="c1"># make sure receiver always sees their real name</span>
<span class="n">rkey</span> <span class="o">=</span> <span class="s2">&quot;#</span><span class="si">%i</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">receiver</span><span class="o">.</span><span class="n">id</span>
<span class="k">if</span> <span class="n">rkey</span> <span class="ow">in</span> <span class="n">receiver_sdesc_mapping</span><span class="p">:</span>
<span class="n">receiver_sdesc_mapping</span><span class="p">[</span><span class="n">rkey</span><span class="p">]</span> <span class="o">=</span> <span class="n">process_sdesc</span><span class="p">(</span><span class="n">receiver</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">receiver</span><span class="p">)</span>
<span class="n">rkey_start</span> <span class="o">=</span> <span class="s2">&quot;#</span><span class="si">%i</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">receiver</span><span class="o">.</span><span class="n">id</span>
<span class="n">rkey_keep_case</span> <span class="o">=</span> <span class="n">rkey_start</span> <span class="o">+</span> <span class="s1">&#39;~&#39;</span> <span class="c1"># signifies keeping the case</span>
<span class="k">for</span> <span class="n">rkey</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">receiver_sdesc_mapping</span> <span class="k">if</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">rkey_start</span><span class="p">)):</span>
<span class="c1"># we could have #%i^, #%it etc depending on input case - we want the</span>
<span class="c1"># self-reference to retain case.</span>
<span class="n">receiver_sdesc_mapping</span><span class="p">[</span><span class="n">rkey</span><span class="p">]</span> <span class="o">=</span> <span class="n">process_sdesc</span><span class="p">(</span>
<span class="n">receiver</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">receiver</span><span class="p">,</span> <span class="n">ref</span><span class="o">=</span><span class="n">rkey_keep_case</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="c1"># do the template replacement of the sdesc/recog {#num} markers</span>
<span class="n">receiver</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">sendemote</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">receiver_sdesc_mapping</span><span class="p">),</span> <span class="n">from_obj</span><span class="o">=</span><span class="n">sender</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
@ -629,7 +679,7 @@
<span class="c1"># ------------------------------------------------------------</span>
<div class="viewcode-block" id="SdescHandler"><a class="viewcode-back" href="../../../api/evennia.contrib.rpsystem.html#evennia.contrib.rpsystem.SdescHandler">[docs]</a><span class="k">class</span> <span class="nc">SdescHandler</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<div class="viewcode-block" id="SdescHandler"><a class="viewcode-back" href="../../../api/evennia.contrib.rpsystem.html#evennia.contrib.rpsystem.SdescHandler">[docs]</a><span class="k">class</span> <span class="nc">SdescHandler</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This Handler wraps all operations with sdescs. We</span>
<span class="sd"> need to use this since we do a lot preparations on</span>
@ -732,7 +782,7 @@
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">sdesc_regex</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">sdesc</span></div></div>
<div class="viewcode-block" id="RecogHandler"><a class="viewcode-back" href="../../../api/evennia.contrib.rpsystem.html#evennia.contrib.rpsystem.RecogHandler">[docs]</a><span class="k">class</span> <span class="nc">RecogHandler</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<div class="viewcode-block" id="RecogHandler"><a class="viewcode-back" href="../../../api/evennia.contrib.rpsystem.html#evennia.contrib.rpsystem.RecogHandler">[docs]</a><span class="k">class</span> <span class="nc">RecogHandler</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This handler manages the recognition mapping</span>
<span class="sd"> of an Object.</span>
@ -1632,11 +1682,33 @@
<span class="sd"> you are viewing yourself (and sdesc is your key).</span>
<span class="sd"> This is not used by default.</span>
<span class="sd"> Kwargs:</span>
<span class="sd"> ref (str): The reference marker found in string to replace.</span>
<span class="sd"> This is on the form #{num}{case}, like &#39;#12^&#39;, where</span>
<span class="sd"> the number is a processing location in the string and the</span>
<span class="sd"> case symbol indicates the case of the original tag input</span>
<span class="sd"> - `t` - input was Titled, like /Tall</span>
<span class="sd"> - `^` - input was all uppercase, like /TALL</span>
<span class="sd"> - `v` - input was all lowercase, like /tall</span>
<span class="sd"> - `~` - input case should be kept, or was mixed-case</span>
<span class="sd"> Returns:</span>
<span class="sd"> sdesc (str): The processed sdesc ready</span>
<span class="sd"> for display.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">sdesc</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">ref</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;ref&#39;</span><span class="p">,</span> <span class="s1">&#39;~&#39;</span><span class="p">)</span> <span class="c1"># ~ to keep sdesc unchanged</span>
<span class="k">if</span> <span class="s1">&#39;t&#39;</span> <span class="ow">in</span> <span class="n">ref</span><span class="p">:</span>
<span class="c1"># we only want to capitalize the first letter if there are many words</span>
<span class="n">sdesc</span> <span class="o">=</span> <span class="n">sdesc</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="n">sdesc</span> <span class="o">=</span> <span class="n">sdesc</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span> <span class="o">+</span> <span class="n">sdesc</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sdesc</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="n">sdesc</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
<span class="k">elif</span> <span class="s1">&#39;^&#39;</span> <span class="ow">in</span> <span class="n">ref</span><span class="p">:</span>
<span class="n">sdesc</span> <span class="o">=</span> <span class="n">sdesc</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
<span class="k">elif</span> <span class="s1">&#39;v&#39;</span> <span class="ow">in</span> <span class="n">ref</span><span class="p">:</span>
<span class="n">sdesc</span> <span class="o">=</span> <span class="n">sdesc</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="k">return</span> <span class="s2">&quot;|b</span><span class="si">%s</span><span class="s2">|n&quot;</span> <span class="o">%</span> <span class="n">sdesc</span></div>
<div class="viewcode-block" id="ContribRPCharacter.process_recog"><a class="viewcode-back" href="../../../api/evennia.contrib.rpsystem.html#evennia.contrib.rpsystem.ContribRPCharacter.process_recog">[docs]</a> <span class="k">def</span> <span class="nf">process_recog</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">recog</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
@ -1648,12 +1720,14 @@
<span class="sd"> translated from the original sdesc at this point.</span>
<span class="sd"> obj (Object): The object the recog:ed string belongs to.</span>
<span class="sd"> This is not used by default.</span>
<span class="sd"> Kwargs:</span>
<span class="sd"> ref (str): See process_sdesc.</span>
<span class="sd"> Returns:</span>
<span class="sd"> recog (str): The modified recog string.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">process_sdesc</span><span class="p">(</span><span class="n">recog</span><span class="p">,</span> <span class="n">obj</span><span class="p">)</span></div>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">process_sdesc</span><span class="p">(</span><span class="n">recog</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="ContribRPCharacter.process_language"><a class="viewcode-back" href="../../../api/evennia.contrib.rpsystem.html#evennia.contrib.rpsystem.ContribRPCharacter.process_language">[docs]</a> <span class="k">def</span> <span class="nf">process_language</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">speaker</span><span class="p">,</span> <span class="n">language</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>

View file

@ -52,8 +52,7 @@
<span class="kn">from</span> <span class="nn">anything</span> <span class="kn">import</span> <span class="n">Something</span>
<span class="kn">from</span> <span class="nn">mock</span> <span class="kn">import</span> <span class="n">MagicMock</span><span class="p">,</span> <span class="n">patch</span>
<span class="kn">from</span> <span class="nn">django.test</span> <span class="kn">import</span> <span class="n">TestCase</span>
<span class="kn">from</span> <span class="nn">django.test</span> <span class="kn">import</span> <span class="n">override_settings</span>
<span class="kn">from</span> <span class="nn">evennia.utils.test_resources</span> <span class="kn">import</span> <span class="n">EvenniaTest</span>
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">lazy_property</span>
<span class="kn">from</span> <span class="nn">evennia.contrib</span> <span class="kn">import</span> <span class="n">traits</span>
@ -945,6 +944,51 @@
<span class="bp">self</span><span class="o">.</span><span class="n">assertGreaterEqual</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">st</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertGreaterEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">st</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertGreaterEqual</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">st</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="DummyCharacter"><a class="viewcode-back" href="../../../api/evennia.contrib.test_traits.html#evennia.contrib.test_traits.DummyCharacter">[docs]</a><span class="k">class</span> <span class="nc">DummyCharacter</span><span class="p">(</span><span class="n">_MockObj</span><span class="p">):</span>
<span class="n">strength</span> <span class="o">=</span> <span class="n">traits</span><span class="o">.</span><span class="n">TraitProperty</span><span class="p">(</span><span class="s2">&quot;Strength&quot;</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="s2">&quot;static&quot;</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">mod</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
<span class="n">hunting</span> <span class="o">=</span> <span class="n">traits</span><span class="o">.</span><span class="n">TraitProperty</span><span class="p">(</span><span class="s2">&quot;Hunting skill&quot;</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="s2">&quot;counter&quot;</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">mod</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
<span class="n">health</span> <span class="o">=</span> <span class="n">traits</span><span class="o">.</span><span class="n">TraitProperty</span><span class="p">(</span><span class="s2">&quot;Health value&quot;</span><span class="p">,</span> <span class="n">trait_type</span><span class="o">=</span><span class="s2">&quot;gauge&quot;</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span></div>
<div class="viewcode-block" id="TestTraitFields"><a class="viewcode-back" href="../../../api/evennia.contrib.test_traits.html#evennia.contrib.test_traits.TestTraitFields">[docs]</a><span class="k">class</span> <span class="nc">TestTraitFields</span><span class="p">(</span><span class="n">TestCase</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Test the TraitField class.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="TestTraitFields.test_traitfields"><a class="viewcode-back" href="../../../api/evennia.contrib.test_traits.html#evennia.contrib.test_traits.TestTraitFields.test_traitfields">[docs]</a> <span class="nd">@patch</span><span class="p">(</span><span class="s2">&quot;evennia.contrib.traits._TRAIT_CLASS_PATHS&quot;</span><span class="p">,</span> <span class="n">new</span><span class="o">=</span><span class="n">_TEST_TRAIT_CLASS_PATHS</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_traitfields</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">DummyCharacter</span><span class="p">()</span>
<span class="n">obj2</span> <span class="o">=</span> <span class="n">DummyCharacter</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">strength</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">assertEqual</span><span class="p">(</span><span class="mi">11</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">hunting</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">assertEqual</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">health</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">strength</span><span class="o">.</span><span class="n">base</span> <span class="o">+=</span> <span class="mi">5</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">17</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">strength</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
<span class="n">obj</span><span class="o">.</span><span class="n">strength</span><span class="o">.</span><span class="n">berserk</span> <span class="o">=</span> <span class="kc">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">strength</span><span class="o">.</span><span class="n">berserk</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">health</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">hp</span><span class="p">)</span>
<span class="c1"># the traithandler still works</span>
<span class="n">obj</span><span class="o">.</span><span class="n">traits</span><span class="o">.</span><span class="n">health</span><span class="o">.</span><span class="n">current</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">99</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">health</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
<span class="c1"># making sure Descriptors are separate</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="n">obj2</span><span class="o">.</span><span class="n">strength</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">assertEqual</span><span class="p">(</span><span class="mi">17</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">strength</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
<span class="n">obj2</span><span class="o">.</span><span class="n">strength</span><span class="o">.</span><span class="n">base</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">obj</span><span class="o">.</span><span class="n">strength</span><span class="o">.</span><span class="n">base</span> <span class="o">+=</span> <span class="mi">3</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="mi">13</span><span class="p">,</span> <span class="n">obj2</span><span class="o">.</span><span class="n">strength</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">assertEqual</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">strength</span><span class="o">.</span><span class="n">value</span><span class="p">)</span></div></div>
</pre></div>
<div class="clearer"></div>

View file

@ -56,71 +56,128 @@
<span class="sd">## Adding Traits to a typeclass</span>
<span class="sd">To access and manipulate traits on an entity, its Typeclass needs to have a</span>
<span class="sd">`TraitHandler` assigned it. Usually, the handler is made available as `.traits`</span>
<span class="sd">(in the same way as `.tags` or `.attributes`). It&#39;s recommended to do this</span>
<span class="sd">using Evennia&#39;s `lazy_property` (which basically just means it&#39;s not</span>
<span class="sd">initialized until it&#39;s actually accessed).</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&#39;t need to</span>
<span class="sd">define it explicitly. You can combine both styles if you like.</span>
<span class="sd">Here&#39;s an example for adding the TraitHandler to the base Object class:</span>
<span class="sd">### Traits with TraitHandler</span>
<span class="sd">Here&#39;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 DefaultObject</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 Object(DefaultObject):</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">```</span>
<span class="sd">## Using traits</span>
<span class="sd"> def at_object_creation(self):</span>
<span class="sd"> # (or wherever you want)</span>
<span class="sd"> self.traits.add(&quot;str&quot;, &quot;Strength&quot;, trait_type=&quot;static&quot;, base=10, mod=2)</span>
<span class="sd"> self.traits.add(&quot;hp&quot;, &quot;Health&quot;, trait_type=&quot;gauge&quot;, min=0, max=100)</span>
<span class="sd"> self.traits.add(&quot;hunting&quot;, &quot;Hunting Skill&quot;, trait_type=&quot;counter&quot;,</span>
<span class="sd"> base=10, mod=1, min=0, max=100)</span>
<span class="sd">A trait is added to the traithandler, after which one can access it</span>
<span class="sd">as a property on the handler (similarly to how you can do .db.attrname for Attributes</span>
<span class="sd">in Evennia).</span>
<span class="sd">```python</span>
<span class="sd"># this is an example using the &quot;static&quot; trait, described below</span>
<span class="sd">&gt;&gt;&gt; obj.traits.add(&quot;hunting&quot;, &quot;Hunting Skill&quot;, trait_type=&quot;static&quot;, base=4)</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">4</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value += 5</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">9</span>
<span class="sd">&gt;&gt;&gt; obj.traits.add(&quot;hp&quot;, &quot;Health&quot;, trait_type=&quot;gauge&quot;, min=0, max=100)</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.value</span>
<span class="sd">100</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp -= 200</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.value</span>
<span class="sd">0</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.reset()</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.value</span>
<span class="sd">100</span>
<span class="sd"># you can also access property with getitem</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp[&quot;value&quot;]</span>
<span class="sd">100</span>
<span class="sd"># you can store arbitrary data persistently as well</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.effect = &quot;poisoned!&quot;</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.effect</span>
<span class="sd">&quot;poisoned!&quot;</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 (&quot;Hunting Skill&quot;). 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.</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&#39;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(&quot;Strength&quot;, trait_type=&quot;static&quot;, base=10, mod=2)</span>
<span class="sd"> health = TraitProperty(&quot;Health&quot;, trait_type=&quot;gauge&quot;, min=0, base=100, mod=2)</span>
<span class="sd"> hunting = TraitProperty(&quot;Hunting Skill&quot;, trait_type=&quot;counter&quot;, base=10, mod=1, min=0, max=100)</span>
<span class="sd">```</span>
<span class="sd">&gt; Note that the property-name will become the name of the trait and you don&#39;t supply `trait_key`</span>
<span class="sd">&gt; separately.</span>
<span class="sd">&gt; The `.traits` TraitHandler will still be created (it&#39;s used under the</span>
<span class="sd">&gt; hood. But it will only be created when the TraitProperty has been accessed at least once,</span>
<span class="sd">&gt; so be careful if mixing the two styles. If you want to make sure `.traits` is always available,</span>
<span class="sd">&gt; add the `TraitHandler` manually like shown earlier - the `TraitProperty` will by default use</span>
<span class="sd">&gt; 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">&gt; obj.traits.strength.value</span>
<span class="sd">12 # base + mod</span>
<span class="sd">&gt; obj.traits.strength.base += 5</span>
<span class="sd">obj.traits.strength.value</span>
<span class="sd">17</span>
<span class="sd">&gt; obj.traits.hp.value</span>
<span class="sd">102 # base + mod</span>
<span class="sd">&gt; obj.traits.hp.base -= 200</span>
<span class="sd">&gt; obj.traits.hp.value</span>
<span class="sd">0 # min of 0</span>
<span class="sd">&gt; obj.traits.hp.reset()</span>
<span class="sd">&gt; 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">&gt; obj.traits.hp[&quot;value&quot;]</span>
<span class="sd">100</span>
<span class="sd"># you can store arbitrary data persistently for easy reference</span>
<span class="sd">&gt; obj.traits.hp.effect = &quot;poisoned!&quot;</span>
<span class="sd">&gt; obj.traits.hp.effect</span>
<span class="sd">&quot;poisoned!&quot;</span>
<span class="sd"># with TraitProperties:</span>
<span class="sd">&gt; obj.hunting.value</span>
<span class="sd">12</span>
<span class="sd">&gt; obj.strength.value += 5</span>
<span class="sd">&gt; obj.strength.value</span>
<span class="sd">17</span>
<span class="sd">```</span>
<span class="sd">## Trait types</span>
@ -131,12 +188,14 @@
<span class="sd">compatible type.</span>
<span class="sd">```python</span>
<span class="sd">&gt;&gt;&gt; trait1 + trait2</span>
<span class="sd">&gt; trait1 + trait2</span>
<span class="sd">54</span>
<span class="sd">&gt;&gt;&gt; trait1.value</span>
<span class="sd">&gt; trait1.value</span>
<span class="sd">3</span>
<span class="sd">&gt;&gt;&gt; trait1 + 2</span>
<span class="sd">&gt;&gt;&gt; trait1.value</span>
<span class="sd">&gt; trait1 + 2</span>
<span class="sd">&gt; trait1.value</span>
<span class="sd">5</span>
<span class="sd">```</span>
@ -159,15 +218,17 @@
<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">&gt;&gt;&gt; obj.traits.add(&quot;str&quot;, &quot;Strength&quot;, trait_type=&quot;static&quot;, base=10, mod=2)</span>
<span class="sd">&gt;&gt;&gt; obj.traits.mytrait.value</span>
<span class="sd">&gt; obj.traits.add(&quot;str&quot;, &quot;Strength&quot;, trait_type=&quot;static&quot;, base=10, mod=2)</span>
<span class="sd">&gt; obj.traits.mytrait.value</span>
<span class="sd">12 # base + mod</span>
<span class="sd">&gt;&gt;&gt; obj.traits.mytrait.base += 2</span>
<span class="sd">&gt;&gt;&gt; obj.traits.mytrait.mod += 1</span>
<span class="sd">&gt;&gt;&gt; obj.traits.mytrait.value</span>
<span class="sd">&gt; obj.traits.mytrait.base += 2</span>
<span class="sd">&gt; obj.traits.mytrait.mod += 1</span>
<span class="sd">&gt; obj.traits.mytrait.value</span>
<span class="sd">15</span>
<span class="sd">&gt;&gt;&gt; obj.traits.mytrait.mod = 0</span>
<span class="sd">&gt;&gt;&gt; obj.traits.mytrait.value</span>
<span class="sd">&gt; obj.traits.mytrait.mod = 0</span>
<span class="sd">&gt; obj.traits.mytrait.value</span>
<span class="sd">12</span>
<span class="sd">```</span>
@ -177,9 +238,9 @@
<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"> 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>
@ -188,18 +249,24 @@
<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">&gt;&gt;&gt; obj.traits.add(&quot;hunting&quot;, &quot;Hunting Skill&quot;, trait_type=&quot;counter&quot;,</span>
<span class="sd">&gt; obj.traits.add(&quot;hunting&quot;, &quot;Hunting Skill&quot;, trait_type=&quot;counter&quot;,</span>
<span class="sd"> base=10, mod=1, min=0, max=100)</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">&gt; obj.traits.hunting.value</span>
<span class="sd">11 # current starts at base + mod</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.current += 10</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">&gt; obj.traits.hunting.current += 10</span>
<span class="sd">&gt; 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">&gt;&gt;&gt; del obj.traits.hunting.current</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">&gt; del obj.traits.hunting.current</span>
<span class="sd">&gt; obj.traits.hunting.value</span>
<span class="sd">11</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.max = None # removing upper bound</span>
<span class="sd">&gt; 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>
@ -216,21 +283,22 @@
<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, will you get the text matching the current `value`</span>
<span class="sd">value.</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">&gt;&gt;&gt; obj.traits.hunting.descs = {</span>
<span class="sd">&gt; obj.traits.hunting.descs = {</span>
<span class="sd"> 0: &quot;unskilled&quot;, 10: &quot;neophyte&quot;, 50: &quot;trained&quot;, 70: &quot;expert&quot;, 90: &quot;master&quot;}</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">&gt; obj.traits.hunting.value</span>
<span class="sd">11</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.desc()</span>
<span class="sd">&gt; obj.traits.hunting.desc()</span>
<span class="sd">&quot;neophyte&quot;</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.current += 60</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">&gt; obj.traits.hunting.current += 60</span>
<span class="sd">&gt; obj.traits.hunting.value</span>
<span class="sd">71</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.desc()</span>
<span class="sd">&gt; obj.traits.hunting.desc()</span>
<span class="sd">&quot;expert&quot;</span>
<span class="sd">```</span>
@ -250,30 +318,37 @@
<span class="sd">```python</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">&gt; obj.traits.hunting.value</span>
<span class="sd">71</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.ratetarget = 71</span>
<span class="sd">&gt; obj.traits.hunting.ratetarget = 71</span>
<span class="sd"># debuff hunting for some reason</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.current -= 30</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">&gt; obj.traits.hunting.current -= 30</span>
<span class="sd">&gt; obj.traits.hunting.value</span>
<span class="sd">41</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.rate = 1 # 1/s increase</span>
<span class="sd">&gt; obj.traits.hunting.rate = 1 # 1/s increase</span>
<span class="sd"># Waiting 5s</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">&gt; obj.traits.hunting.value</span>
<span class="sd">46</span>
<span class="sd"># Waiting 8s</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">&gt; obj.traits.hunting.value</span>
<span class="sd">54</span>
<span class="sd"># Waiting 100s</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.value</span>
<span class="sd">&gt; obj.traits.hunting.value</span>
<span class="sd">71 # we have stopped at the ratetarget</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.rate = 0 # disable auto-change</span>
<span class="sd">&gt; obj.traits.hunting.rate = 0 # disable auto-change</span>
<span class="sd">```</span>
<span class="sd">Note that if `.rate` is a non-integer, the resulting `.value` (at least until it</span>
<span class="sd">reaches a boundary or rate-target) will also come out a float (so you can get a</span>
<span class="sd">very exact value at the current time). If you expect an integer, you must run</span>
<span class="sd">`int()` (or something like `round()`) on the result yourself.</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>
@ -281,9 +356,10 @@
<span class="sd">return the value as a percentage.</span>
<span class="sd">```python</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.percent()</span>
<span class="sd">&gt; obj.traits.hunting.percent()</span>
<span class="sd">&quot;71.0%&quot;</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hunting.percent(formatting=None)</span>
<span class="sd">&gt; obj.traits.hunting.percent(formatting=None)</span>
<span class="sd">71.0</span>
<span class="sd">```</span>
@ -301,20 +377,22 @@
<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">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">&gt;&gt;&gt; obj.traits.add(&quot;hp&quot;, &quot;Health&quot;, trait_type=&quot;gauge&quot;, base=100)</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.value # (or .current)</span>
<span class="sd">&gt; obj.traits.add(&quot;hp&quot;, &quot;Health&quot;, trait_type=&quot;gauge&quot;, base=100)</span>
<span class="sd">&gt; obj.traits.hp.value # (or .current)</span>
<span class="sd">100</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.mod = 10</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.value</span>
<span class="sd">&gt; obj.traits.hp.mod = 10</span>
<span class="sd">&gt; obj.traits.hp.value</span>
<span class="sd">110</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.current -= 30</span>
<span class="sd">&gt;&gt;&gt; obj.traits.hp.value</span>
<span class="sd">&gt; obj.traits.hp.current -= 30</span>
<span class="sd">&gt; obj.traits.hp.value</span>
<span class="sd">80</span>
<span class="sd">```</span>
@ -322,7 +400,7 @@
<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">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>
@ -333,18 +411,21 @@
<span class="sd">This is the &#39;base&#39; Trait, meant to inherit from if you want to invent</span>
<span class="sd">trait-types from scratch (most of the time you&#39;ll probably inherit from some of</span>
<span class="sd">the more advanced trait-type classes though). A `Trait`s `.value` can be</span>
<span class="sd">anything (that can be stored in an Attribute) and if it&#39;s a integer/float you</span>
<span class="sd">can do arithmetic with it, but otherwise it acts just like a glorified</span>
<span class="sd">Attribute.</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&#39;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">&gt;&gt;&gt; obj.traits.add(&quot;mytrait&quot;, &quot;My Trait&quot;, trait_type=&quot;trait&quot;, value=30)</span>
<span class="sd">&gt;&gt;&gt; obj.traits.mytrait.value</span>
<span class="sd">&gt; obj.traits.add(&quot;mytrait&quot;, &quot;My Trait&quot;, trait_type=&quot;trait&quot;, value=30)</span>
<span class="sd">&gt; obj.traits.mytrait.value</span>
<span class="sd">30</span>
<span class="sd">&gt;&gt;&gt; obj.traits.mytrait.value = &quot;stringvalue&quot;</span>
<span class="sd">&gt;&gt;&gt; obj.traits.mytrait.value</span>
<span class="sd">&gt; obj.traits.mytrait.value = &quot;stringvalue&quot;</span>
<span class="sd">&gt; obj.traits.mytrait.value</span>
<span class="sd">&quot;stringvalue&quot;</span>
<span class="sd">```</span>
@ -371,7 +452,7 @@
<span class="sd"> def sedate(self):</span>
<span class="sd"> self.mod = 0</span>
<span class="sd"> </span>
<span class="sd">```</span>
@ -389,10 +470,15 @@
<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">&gt;&gt;&gt; obj.traits.add(&quot;mood&quot;, &quot;A dark mood&quot;, rage=30, trait_type=&#39;rage&#39;)</span>
<span class="sd">&gt;&gt;&gt; obj.traits.mood.rage</span>
<span class="sd">&gt; obj.traits.add(&quot;mood&quot;, &quot;A dark mood&quot;, rage=30, trait_type=&#39;rage&#39;)</span>
<span class="sd">&gt; 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(&quot;A dark mood&quot;, rage=30, trait_type=&#39;rage&#39;)</span>
<span class="sd">```</span>
<span class="sd">----</span>
@ -477,12 +563,22 @@
<span class="sd"> This represents a required key that must be</span>
<span class="sd"> supplied when a Trait is initialized. It&#39;s used</span>
<span class="sd"> by Trait classes when defining their required keys.</span>
<span class="sd"> &quot;&quot;&quot;</span></div>
<span class="sd"> &quot;&quot;&quot;</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">&quot;&quot;&quot;</span>
<span class="sd"> Factory class that instantiates Trait objects.</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"> &quot;&quot;&quot;</span>
@ -492,12 +588,14 @@
<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_key (str): Name of the DB attribute for trait data storage.</span>
<span class="sd"> db_attribute_category (str): Name of DB attribute&#39;s category to trait data storage.</span>
<span class="sd"> &quot;&quot;&quot;</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>
@ -602,7 +700,7 @@
<span class="sd"> name (str, optional): Name of the Trait, like &quot;Health&quot;. 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 &#39;static&#39;, &#39;counter&#39; or &#39;gauge&#39;.</span>
<span class="sd"> force_add (bool): If set, create a new Trait even if a Trait with</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>
@ -657,6 +755,100 @@
<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">&quot;&quot;&quot;</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(&quot;str&quot;, &quot;Strength&quot;, trait_type=&quot;static&quot;, base=10, mod=2)</span>
<span class="sd"> hunting = TraitProperty(self, &quot;hunting&quot;, &quot;Hunting Skill&quot;, trait_type=&quot;counter&quot;,</span>
<span class="sd"> base=10, mod=1, max=100)</span>
<span class="sd"> health = TraitProperty(&quot;health&quot;, &quot;Health&quot;, trait_type=&quot;gauge&quot;, min=0, base=100)</span>
<span class="sd"> &quot;&quot;&quot;</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">&quot;&quot;&quot;</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 &quot;Health&quot;. 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 &#39;static&#39;, &#39;counter&#39; or &#39;gauge&#39;.</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"> &quot;&quot;&quot;</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">&quot;traithandler_name&quot;</span><span class="p">,</span> <span class="s2">&quot;traits&quot;</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">&quot;name&quot;</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span> <span class="s2">&quot;trait_type&quot;</span><span class="p">:</span> <span class="n">trait_type</span><span class="p">,</span> <span class="s2">&quot;force&quot;</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">&quot;&quot;&quot;</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"> &quot;&quot;&quot;</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">&quot;&quot;&quot;</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&#39;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"> &quot;&quot;&quot;</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">&quot;&quot;&quot;</span>
<span class="sd"> We don&#39;t set data directly, it&#39;s all rerouted to the trait.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<span class="c1"># Parent Trait class</span>
@ -991,7 +1183,7 @@
<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">&quot;&quot;&quot;</span>
<span class="sd"> Static Trait. This is a single value with a modifier,</span>
<span class="sd"> with no concept of a &#39;current&#39; value.</span>
<span class="sd"> with no concept of a &#39;current&#39; value or min/max etc.</span>
<span class="sd"> value = base + mod</span>
@ -1006,6 +1198,16 @@
<span class="k">return</span> <span class="s2">&quot;</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">)&quot;</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">&quot;base&quot;</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">&quot;base&quot;</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">&quot;base&quot;</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">&quot;base&quot;</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>
@ -1126,7 +1328,6 @@
<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">&quot;&quot;&quot;Start timer if we are not at a boundary.&quot;&quot;&quot;</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">&quot;last_update&quot;</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</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">&quot;ratetarget&quot;</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">&quot;last_update&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
@ -1155,6 +1356,8 @@
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">&quot;current&quot;</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>
@ -1359,6 +1562,9 @@
<span class="bp">self</span><span class="o">.</span><span class="n">_data</span><span class="p">[</span><span class="s2">&quot;current&quot;</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>
@ -1416,13 +1622,13 @@
<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">&quot;The .max property is not settable &quot;</span> <span class="s2">&quot;on GaugeTraits. Set .base instead.&quot;</span>
<span class="s2">&quot;The .max property is not settable on GaugeTraits. Set .mod and .base instead.&quot;</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">&quot;The .max property cannot be reset &quot;</span> <span class="s2">&quot;on GaugeTraits. Reset .mod and .base instead.&quot;</span>
<span class="s2">&quot;The .max property cannot be reset on GaugeTraits. Reset .mod and .base instead.&quot;</span>
<span class="p">)</span>
<span class="nd">@property</span>

View file

@ -1111,12 +1111,13 @@
<span class="n">Xmax</span><span class="p">,</span> <span class="n">Ymax</span> <span class="o">=</span> <span class="n">gridsize</span>
<span class="n">grid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_grid</span><span class="p">(</span><span class="n">Xmax</span><span class="p">,</span> <span class="n">Ymax</span><span class="p">)</span>
<span class="n">mapobj</span> <span class="o">=</span> <span class="n">xymap</span><span class="o">.</span><span class="n">XYMap</span><span class="p">({</span><span class="s1">&#39;map&#39;</span><span class="p">:</span> <span class="n">grid</span><span class="p">},</span> <span class="n">Z</span><span class="o">=</span><span class="s2">&quot;testmap&quot;</span><span class="p">)</span>
<span class="n">t0</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
<span class="c1"># t0 = time()</span>
<span class="n">mapobj</span><span class="o">.</span><span class="n">parse</span><span class="p">()</span>
<span class="c1"># cProfile.runctx(&#39;mapobj.parse()&#39;, globals(), locals())</span>
<span class="n">t1</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertLess</span><span class="p">(</span><span class="n">t1</span> <span class="o">-</span> <span class="n">t0</span><span class="p">,</span> <span class="n">max_time</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;Map creation of (</span><span class="si">{</span><span class="n">Xmax</span><span class="si">}</span><span class="s2">x</span><span class="si">{</span><span class="n">Ymax</span><span class="si">}</span><span class="s2">) grid slower &quot;</span>
<span class="sa">f</span><span class="s2">&quot;than expected </span><span class="si">{</span><span class="n">max_time</span><span class="si">}</span><span class="s2">s.&quot;</span><span class="p">)</span>
<span class="c1"># t1 = time()</span>
<span class="c1"># if (t1 - t0 &gt; max_time):</span>
<span class="c1"># print(f&quot;Map creation of ({Xmax}x{Ymax}) grid slower &quot;</span>
<span class="c1"># f&quot;than expected {max_time}s.&quot;)</span>
<span class="nd">@parameterized</span><span class="o">.</span><span class="n">expand</span><span class="p">([</span>
<span class="p">((</span><span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">),</span> <span class="mi">10</span><span class="o">**-</span><span class="mi">3</span><span class="p">),</span>
@ -1132,9 +1133,9 @@
<span class="n">mapobj</span> <span class="o">=</span> <span class="n">xymap</span><span class="o">.</span><span class="n">XYMap</span><span class="p">({</span><span class="s1">&#39;map&#39;</span><span class="p">:</span> <span class="n">grid</span><span class="p">},</span> <span class="n">Z</span><span class="o">=</span><span class="s2">&quot;testmap&quot;</span><span class="p">)</span>
<span class="n">mapobj</span><span class="o">.</span><span class="n">parse</span><span class="p">()</span>
<span class="n">t0</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
<span class="c1"># t0 = time()</span>
<span class="n">mapobj</span><span class="o">.</span><span class="n">calculate_path_matrix</span><span class="p">()</span>
<span class="n">t1</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
<span class="c1"># t1 = time()</span>
<span class="c1"># print(f&quot;pathfinder matrix for grid {Xmax}x{Ymax}: {t1 - t0}s&quot;)</span>
<span class="c1"># get the maximum distance and 9 other random points in the grid</span>
@ -1143,12 +1144,13 @@
<span class="n">start_end_points</span><span class="o">.</span><span class="n">append</span><span class="p">(((</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">Xmax</span><span class="p">),</span> <span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">Ymax</span><span class="p">)),</span>
<span class="p">(</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">Xmax</span><span class="p">),</span> <span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">Ymax</span><span class="p">))))</span>
<span class="n">t0</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
<span class="c1"># t0 = time()</span>
<span class="k">for</span> <span class="n">startcoord</span><span class="p">,</span> <span class="n">endcoord</span> <span class="ow">in</span> <span class="n">start_end_points</span><span class="p">:</span>
<span class="n">mapobj</span><span class="o">.</span><span class="n">get_shortest_path</span><span class="p">(</span><span class="n">startcoord</span><span class="p">,</span> <span class="n">endcoord</span><span class="p">)</span>
<span class="n">t1</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertLess</span><span class="p">((</span><span class="n">t1</span> <span class="o">-</span> <span class="n">t0</span><span class="p">)</span> <span class="o">/</span> <span class="mi">10</span><span class="p">,</span> <span class="n">max_time</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;Pathfinding for (</span><span class="si">{</span><span class="n">Xmax</span><span class="si">}</span><span class="s2">x</span><span class="si">{</span><span class="n">Ymax</span><span class="si">}</span><span class="s2">) grid slower &quot;</span>
<span class="sa">f</span><span class="s2">&quot;than expected </span><span class="si">{</span><span class="n">max_time</span><span class="si">}</span><span class="s2">s.&quot;</span><span class="p">)</span>
<span class="c1"># t1 = time()</span>
<span class="c1"># if (t1 - t0) / 10 &gt; max_time:</span>
<span class="c1"># print(f&quot;Pathfinding for ({Xmax}x{Ymax}) grid slower &quot;</span>
<span class="c1"># f&quot;than expected {max_time}s.&quot;)</span>
<span class="nd">@parameterized</span><span class="o">.</span><span class="n">expand</span><span class="p">([</span>
<span class="p">((</span><span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">),</span> <span class="mi">4</span><span class="p">,</span> <span class="mf">0.01</span><span class="p">),</span>
@ -1165,9 +1167,9 @@
<span class="n">mapobj</span> <span class="o">=</span> <span class="n">xymap</span><span class="o">.</span><span class="n">XYMap</span><span class="p">({</span><span class="s1">&#39;map&#39;</span><span class="p">:</span> <span class="n">grid</span><span class="p">},</span> <span class="n">Z</span><span class="o">=</span><span class="s2">&quot;testmap&quot;</span><span class="p">)</span>
<span class="n">mapobj</span><span class="o">.</span><span class="n">parse</span><span class="p">()</span>
<span class="n">t0</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
<span class="c1"># t0 = time()</span>
<span class="n">mapobj</span><span class="o">.</span><span class="n">calculate_path_matrix</span><span class="p">()</span>
<span class="n">t1</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
<span class="c1"># t1 = time()</span>
<span class="c1"># print(f&quot;pathfinder matrix for grid {Xmax}x{Ymax}: {t1 - t0}s&quot;)</span>
<span class="c1"># get random center points in grid and a range of targets to visualize the</span>
@ -1177,14 +1179,14 @@
<span class="n">start_end_points</span><span class="o">.</span><span class="n">append</span><span class="p">(((</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">Xmax</span><span class="p">),</span> <span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">Ymax</span><span class="p">)),</span>
<span class="p">(</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">Xmax</span><span class="p">),</span> <span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">Ymax</span><span class="p">))))</span>
<span class="n">t0</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
<span class="c1"># t0 = time()</span>
<span class="k">for</span> <span class="n">coord</span><span class="p">,</span> <span class="n">target</span> <span class="ow">in</span> <span class="n">start_end_points</span><span class="p">:</span>
<span class="n">mapobj</span><span class="o">.</span><span class="n">get_visual_range</span><span class="p">(</span><span class="n">coord</span><span class="p">,</span> <span class="n">dist</span><span class="o">=</span><span class="n">dist</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;nodes&#39;</span><span class="p">,</span>
<span class="n">character</span><span class="o">=</span><span class="s1">&#39;@&#39;</span><span class="p">,</span> <span class="n">target</span><span class="o">=</span><span class="n">target</span><span class="p">)</span>
<span class="n">t1</span> <span class="o">=</span> <span class="n">time</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertLess</span><span class="p">((</span><span class="n">t1</span> <span class="o">-</span> <span class="n">t0</span><span class="p">)</span> <span class="o">/</span> <span class="mi">10</span><span class="p">,</span> <span class="n">max_time</span><span class="p">,</span>
<span class="sa">f</span><span class="s2">&quot;Visual Range calculation for (</span><span class="si">{</span><span class="n">Xmax</span><span class="si">}</span><span class="s2">x</span><span class="si">{</span><span class="n">Ymax</span><span class="si">}</span><span class="s2">) grid &quot;</span>
<span class="sa">f</span><span class="s2">&quot;slower than expected </span><span class="si">{</span><span class="n">max_time</span><span class="si">}</span><span class="s2">s.&quot;</span><span class="p">)</span></div>
<span class="n">character</span><span class="o">=</span><span class="s1">&#39;@&#39;</span><span class="p">,</span> <span class="n">target</span><span class="o">=</span><span class="n">target</span><span class="p">)</span></div>
<span class="c1"># t1 = time()</span>
<span class="c1"># if (t1 - t0) / 10 &gt; max_time:</span>
<span class="c1"># print(f&quot;Visual Range calculation for ({Xmax}x{Ymax}) grid &quot;</span>
<span class="c1"># f&quot;slower than expected {max_time}s.&quot;)</span>
<div class="viewcode-block" id="TestXYZGrid"><a class="viewcode-back" href="../../../../api/evennia.contrib.xyzgrid.tests.html#evennia.contrib.xyzgrid.tests.TestXYZGrid">[docs]</a><span class="k">class</span> <span class="nc">TestXYZGrid</span><span class="p">(</span><span class="n">EvenniaTest</span><span class="p">):</span>

View file

@ -60,8 +60,10 @@
<span class="kn">import</span> <span class="nn">uuid</span>
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
<span class="kn">from</span> <span class="nn">django.core</span> <span class="kn">import</span> <span class="n">exceptions</span> <span class="k">as</span> <span class="n">django_exceptions</span>
<span class="kn">from</span> <span class="nn">evennia.prototypes</span> <span class="kn">import</span> <span class="n">spawner</span>
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">make_iter</span>
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">MAPSCAN</span><span class="p">,</span> <span class="n">REVERSE_DIRECTIONS</span><span class="p">,</span> <span class="n">MapParserError</span><span class="p">,</span> <span class="n">BIGVAL</span>
<span class="n">NodeTypeclass</span> <span class="o">=</span> <span class="kc">None</span>
@ -351,7 +353,7 @@
<span class="k">try</span><span class="p">:</span>
<span class="n">nodeobj</span> <span class="o">=</span> <span class="n">NodeTypeclass</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_xyz</span><span class="p">(</span><span class="n">xyz</span><span class="o">=</span><span class="n">xyz</span><span class="p">)</span>
<span class="k">except</span> <span class="n">NodeTypeclass</span><span class="o">.</span><span class="n">DoesNotExist</span><span class="p">:</span>
<span class="k">except</span> <span class="n">django_exceptions</span><span class="o">.</span><span class="n">ObjectDoesNotExist</span><span class="p">:</span>
<span class="c1"># create a new entity with proper coordinates etc</span>
<span class="n">tclass</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">prototype</span><span class="p">[</span><span class="s1">&#39;typeclass&#39;</span><span class="p">]</span>
<span class="n">tclass</span> <span class="o">=</span> <span class="p">(</span><span class="sa">f</span><span class="s1">&#39; (</span><span class="si">{</span><span class="n">tclass</span><span class="si">}</span><span class="s1">)&#39;</span>
@ -475,7 +477,7 @@
<span class="k">try</span><span class="p">:</span>
<span class="n">nodeobj</span> <span class="o">=</span> <span class="n">NodeTypeclass</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_xyz</span><span class="p">(</span><span class="n">xyz</span><span class="o">=</span><span class="n">xyz</span><span class="p">)</span>
<span class="k">except</span> <span class="n">NodeTypeclass</span><span class="o">.</span><span class="n">DoesNotExist</span><span class="p">:</span>
<span class="k">except</span> <span class="n">django_exceptions</span><span class="o">.</span><span class="n">ObjectDoesNotExist</span><span class="p">:</span>
<span class="c1"># no object exists</span>
<span class="k">pass</span>
<span class="k">else</span><span class="p">:</span>

View file

@ -86,7 +86,22 @@
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">prototype</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;prototype&quot;</span><span class="p">,</span> <span class="p">{})</span>
<span class="n">prot_value</span> <span class="o">=</span> <span class="n">prototype</span><span class="p">[</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span>
<span class="n">fieldname</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">prot_value</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">fieldname</span> <span class="ow">in</span> <span class="n">prototype</span><span class="p">:</span>
<span class="n">prot_value</span> <span class="o">=</span> <span class="n">prototype</span><span class="p">[</span><span class="n">fieldname</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># check if it&#39;s an attribute</span>
<span class="k">for</span> <span class="n">attrtuple</span> <span class="ow">in</span> <span class="n">prototype</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;attrs&#39;</span><span class="p">,</span> <span class="p">[]):</span>
<span class="k">if</span> <span class="n">attrtuple</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="n">fieldname</span><span class="p">:</span>
<span class="n">prot_value</span> <span class="o">=</span> <span class="n">attrtuple</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="k">break</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">fieldname</span><span class="si">}</span><span class="s2"> not found in prototype</span><span class="se">\n</span><span class="si">{</span><span class="n">prototype</span><span class="si">}</span><span class="se">\n</span><span class="s2">&quot;</span>
<span class="s2">&quot;(neither as prototype-field or as an Attribute&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">callable</span><span class="p">(</span><span class="n">prot_value</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Error in prototype</span><span class="se">\n</span><span class="si">{</span><span class="n">prototype</span><span class="si">}</span><span class="se">\n</span><span class="s2">$protkey can only reference static &quot;</span>
<span class="sa">f</span><span class="s2">&quot;values/attributes (found </span><span class="si">{</span><span class="n">prot_value</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">funcparser</span><span class="o">.</span><span class="n">funcparser_callable_eval</span><span class="p">(</span><span class="n">prot_value</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">except</span> <span class="n">funcparser</span><span class="o">.</span><span class="n">ParsingError</span><span class="p">:</span>

View file

@ -558,6 +558,10 @@
<span class="sd"> be found as a match.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># prototype keys are always in lowecase</span>
<span class="k">if</span> <span class="n">key</span><span class="p">:</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">key</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="c1"># search module prototypes</span>
<span class="n">mod_matches</span> <span class="o">=</span> <span class="p">{}</span>

View file

@ -979,41 +979,45 @@
<span class="s2">&quot;key&quot;</span><span class="p">,</span>
<span class="s2">&quot;Spawned-</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="nb">bytes</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()),</span> <span class="s2">&quot;utf-8&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()[:</span><span class="mi">6</span><span class="p">]),</span>
<span class="p">)</span>
<span class="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_key&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
<span class="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_key&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">)</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">prot</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;location&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_location&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">value_to_obj</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
<span class="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_location&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span>
<span class="n">val</span><span class="p">,</span> <span class="n">value_to_obj</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">)</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">prot</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;home&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="k">if</span> <span class="n">val</span><span class="p">:</span>
<span class="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_home&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">value_to_obj</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
<span class="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_home&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">value_to_obj</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span>
<span class="n">prototype</span><span class="o">=</span><span class="n">prototype</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="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_home&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span>
<span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_HOME</span><span class="p">,</span> <span class="n">value_to_obj</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
<span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_HOME</span><span class="p">,</span> <span class="n">value_to_obj</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ObjectDB</span><span class="o">.</span><span class="n">DoesNotExist</span><span class="p">:</span>
<span class="c1"># settings.DEFAULT_HOME not existing is common for unittests</span>
<span class="k">pass</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">prot</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;destination&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_destination&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">value_to_obj</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
<span class="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_destination&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">value_to_obj</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span>
<span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">)</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">prot</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;typeclass&quot;</span><span class="p">,</span> <span class="n">settings</span><span class="o">.</span><span class="n">BASE_OBJECT_TYPECLASS</span><span class="p">)</span>
<span class="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_typeclass_path&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
<span class="n">create_kwargs</span><span class="p">[</span><span class="s2">&quot;db_typeclass_path&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span>
<span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">)</span>
<span class="c1"># extract calls to handlers</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">prot</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;permissions&quot;</span><span class="p">,</span> <span class="p">[])</span>
<span class="n">permission_string</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">make_iter</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
<span class="n">permission_string</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">make_iter</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">)</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">prot</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;locks&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">lock_string</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
<span class="n">lock_string</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">)</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">prot</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;aliases&quot;</span><span class="p">,</span> <span class="p">[])</span>
<span class="n">alias_string</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">make_iter</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
<span class="n">alias_string</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">make_iter</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">)</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">prot</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;tags&quot;</span><span class="p">,</span> <span class="p">[])</span>
<span class="n">tags</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="p">(</span><span class="n">tag</span><span class="p">,</span> <span class="n">category</span><span class="p">,</span> <span class="o">*</span><span class="n">data</span><span class="p">)</span> <span class="ow">in</span> <span class="n">val</span><span class="p">:</span>
<span class="n">tags</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">init_spawn_value</span><span class="p">(</span><span class="n">tag</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">),</span> <span class="n">category</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="n">data</span> <span class="k">else</span> <span class="kc">None</span><span class="p">))</span>
<span class="n">tags</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">init_spawn_value</span><span class="p">(</span><span class="n">tag</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">),</span>
<span class="n">category</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">data</span> <span class="k">else</span> <span class="kc">None</span><span class="p">))</span>
<span class="n">prototype_key</span> <span class="o">=</span> <span class="n">prototype</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;prototype_key&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="k">if</span> <span class="n">prototype_key</span><span class="p">:</span>
@ -1021,11 +1025,12 @@
<span class="n">tags</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">prototype_key</span><span class="p">,</span> <span class="n">PROTOTYPE_TAG_CATEGORY</span><span class="p">))</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">prot</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;exec&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">execs</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">make_iter</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span>
<span class="n">execs</span> <span class="o">=</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">make_iter</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">)</span>
<span class="c1"># extract ndb assignments</span>
<span class="n">nattributes</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
<span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;_&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)[</span><span class="mi">1</span><span class="p">],</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">value_to_obj</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">))</span>
<span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;_&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)[</span><span class="mi">1</span><span class="p">],</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="n">value_to_obj</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span>
<span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">))</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">prot</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="k">if</span> <span class="n">key</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;ndb_&quot;</span><span class="p">)</span>
<span class="p">)</span>
@ -1034,8 +1039,9 @@
<span class="n">val</span> <span class="o">=</span> <span class="n">make_iter</span><span class="p">(</span><span class="n">prot</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;attrs&quot;</span><span class="p">,</span> <span class="p">[]))</span>
<span class="n">attributes</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="p">(</span><span class="n">attrname</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="o">*</span><span class="n">rest</span><span class="p">)</span> <span class="ow">in</span> <span class="n">val</span><span class="p">:</span>
<span class="n">attributes</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">attrname</span><span class="p">,</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">),</span>
<span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">rest</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span> <span class="n">rest</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="kc">None</span><span class="p">))</span>
<span class="n">attributes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="p">(</span><span class="n">attrname</span><span class="p">,</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">),</span>
<span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">rest</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span> <span class="n">rest</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="kc">None</span><span class="p">))</span>
<span class="n">simple_attributes</span> <span class="o">=</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="p">(</span>
@ -1046,7 +1052,8 @@
<span class="k">continue</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">simple_attributes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">value_to_obj_or_any</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">),</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">init_spawn_value</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">value_to_obj_or_any</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span>
<span class="n">prototype</span><span class="o">=</span><span class="n">prototype</span><span class="p">),</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">attributes</span> <span class="o">=</span> <span class="n">attributes</span> <span class="o">+</span> <span class="n">simple_attributes</span>

View file

@ -73,6 +73,7 @@
<span class="kn">from</span> <span class="nn">django.utils.translation</span> <span class="kn">import</span> <span class="n">gettext</span> <span class="k">as</span> <span class="n">_</span>
<span class="n">_FUNCPARSER_PARSE_OUTGOING_MESSAGES_ENABLED</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">FUNCPARSER_PARSE_OUTGOING_MESSAGES_ENABLED</span>
<span class="n">_BROADCAST_SERVER_RESTART_MESSAGES</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">BROADCAST_SERVER_RESTART_MESSAGES</span>
<span class="c1"># delayed imports</span>
<span class="n">_AccountDB</span> <span class="o">=</span> <span class="kc">None</span>
@ -439,7 +440,8 @@
<span class="c1"># tell the server hook we synced</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">at_post_portal_sync</span><span class="p">(</span><span class="n">mode</span><span class="p">)</span>
<span class="c1"># announce the reconnection</span>
<span class="bp">self</span><span class="o">.</span><span class="n">announce_all</span><span class="p">(</span><span class="n">_</span><span class="p">(</span><span class="s2">&quot; ... Server restarted.&quot;</span><span class="p">))</span></div>
<span class="k">if</span> <span class="n">_BROADCAST_SERVER_RESTART_MESSAGES</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">announce_all</span><span class="p">(</span><span class="n">_</span><span class="p">(</span><span class="s2">&quot; ... Server restarted.&quot;</span><span class="p">))</span> </div>
<div class="viewcode-block" id="ServerSessionHandler.portal_disconnect"><a class="viewcode-back" href="../../../api/evennia.server.sessionhandler.html#evennia.server.sessionhandler.ServerSessionHandler.portal_disconnect">[docs]</a> <span class="k">def</span> <span class="nf">portal_disconnect</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">session</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>

View file

@ -1158,7 +1158,7 @@
<span class="sd"> Notes:</span>
<span class="sd"> Beyond those table-specific keywords, the non-overlapping keywords</span>
<span class="sd"> of `EcCell.__init__` are also available. These will be passed down</span>
<span class="sd"> of `EvCell.__init__` are also available. These will be passed down</span>
<span class="sd"> to every cell in the table.</span>
<span class="sd"> &quot;&quot;&quot;</span>
@ -1520,31 +1520,13 @@
<span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">height</span><span class="p">,</span> <span class="n">chmin</span> <span class="o">+</span> <span class="n">locked_height</span><span class="p">)</span>
<span class="p">)</span>
<span class="c1"># now we add all the extra height up to the desired table-height.</span>
<span class="c1"># We do this so that the tallest cells gets expanded first (and</span>
<span class="c1"># thus avoid getting cropped)</span>
<span class="n">even</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">height</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">correction</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="n">correction</span> <span class="o">&lt;</span> <span class="n">excess</span><span class="p">:</span>
<span class="c1"># expand the cells with the most rows first</span>
<span class="k">if</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">correction</span> <span class="o">&lt;</span> <span class="n">nrowmax</span> <span class="ow">and</span> <span class="n">nrowmax</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1"># avoid adding to header first round (looks bad on very small tables)</span>
<span class="n">ci</span> <span class="o">=</span> <span class="n">cheights</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="n">cheights</span><span class="p">[</span><span class="mi">1</span><span class="p">:]))</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">ci</span> <span class="o">=</span> <span class="n">cheights</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="n">cheights</span><span class="p">))</span>
<span class="k">if</span> <span class="n">ci</span> <span class="ow">in</span> <span class="n">locked_cols</span><span class="p">:</span>
<span class="c1"># locked row, make sure it&#39;s not picked again</span>
<span class="n">cheights</span><span class="p">[</span><span class="n">ci</span><span class="p">]</span> <span class="o">-=</span> <span class="mi">9999</span>
<span class="n">cheights_min</span><span class="p">[</span><span class="n">ci</span><span class="p">]</span> <span class="o">=</span> <span class="n">locked_cols</span><span class="p">[</span><span class="n">ci</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">cheights_min</span><span class="p">[</span><span class="n">ci</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="c1"># change balance</span>
<span class="k">if</span> <span class="n">ci</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">header</span><span class="p">:</span>
<span class="c1"># it doesn&#39;t look very good if header expands too fast</span>
<span class="n">cheights</span><span class="p">[</span><span class="n">ci</span><span class="p">]</span> <span class="o">-=</span> <span class="mi">2</span> <span class="k">if</span> <span class="n">even</span> <span class="k">else</span> <span class="mi">3</span>
<span class="n">cheights</span><span class="p">[</span><span class="n">ci</span><span class="p">]</span> <span class="o">-=</span> <span class="mi">2</span> <span class="k">if</span> <span class="n">even</span> <span class="k">else</span> <span class="mi">1</span>
<span class="n">correction</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="c1"># Add all the excess at the end of the table</span>
<span class="c1"># Note: Older solutions tried to balance individual</span>
<span class="c1"># rows&#39; vsize. This could lead to empty rows that</span>
<span class="c1"># looked like a bug. This solution instead</span>
<span class="c1"># adds empty rows at the end which is less sophisticated</span>
<span class="c1"># but much more visually consistent.</span>
<span class="n">cheights_min</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="n">excess</span>
<span class="n">cheights</span> <span class="o">=</span> <span class="n">cheights_min</span>
<span class="c1"># we must tell cells to crop instead of expanding</span>
@ -1603,7 +1585,7 @@
<span class="sd"> to the end.</span>
<span class="sd"> Args:</span>
<span class="sd"> args (`EvColum` or multiple strings): Either a single EvColumn instance or</span>
<span class="sd"> args (`EvColumn` or multiple strings): Either a single EvColumn instance or</span>
<span class="sd"> a number of data string arguments to be used to create a new column.</span>
<span class="sd"> header (str, optional): The header text for the column</span>
<span class="sd"> xpos (int, optional): Index position in table *before* which</span>

View file

@ -450,7 +450,16 @@
<span class="sd"> lines (list): lines from our _file attribute.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">[</span><span class="n">line</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;utf-8&quot;</span><span class="p">)</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_file</span><span class="o">.</span><span class="n">readlines</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)]</span></div></div>
<span class="n">lines</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_file</span><span class="o">.</span><span class="n">readlines</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;utf-8&quot;</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">UnicodeDecodeError</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">line</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">lines</span></div></div>
<span class="n">_LOG_FILE_HANDLES</span> <span class="o">=</span> <span class="p">{}</span> <span class="c1"># holds open log handles</span>

View file

@ -2090,7 +2090,7 @@
<span class="n">_missing</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span>
<div class="viewcode-block" id="lazy_property"><a class="viewcode-back" href="../../../api/evennia.utils.utils.html#evennia.contrib.tutorial_examples.red_button.lazy_property">[docs]</a><span class="k">class</span> <span class="nc">lazy_property</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<div class="viewcode-block" id="lazy_property"><a class="viewcode-back" href="../../../api/evennia.utils.utils.html#evennia.contrib.tutorial_examples.red_button.lazy_property">[docs]</a><span class="k">class</span> <span class="nc">lazy_property</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Delays loading of property until first access. Credit goes to the</span>
<span class="sd"> Implementation in the werkzeug suite:</span>

View file

@ -175,8 +175,12 @@
<span class="k">for</span> <span class="n">log</span> <span class="ow">in</span> <span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">tail_log_file</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_num_lines</span><span class="p">)):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">log</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">time</span><span class="p">,</span> <span class="n">msg</span> <span class="o">=</span> <span class="n">log</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; [-] &quot;</span><span class="p">)</span>
<span class="n">time_key</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;:&quot;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">time</span><span class="p">,</span> <span class="n">msg</span> <span class="o">=</span> <span class="n">log</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; [-] &quot;</span><span class="p">)</span>
<span class="n">time_key</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;:&quot;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="c1"># malformed log line. Skip.</span>
<span class="k">continue</span>
<span class="n">bucket</span><span class="o">.</span><span class="n">append</span><span class="p">({</span><span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="n">time_key</span><span class="p">,</span> <span class="s2">&quot;timestamp&quot;</span><span class="p">:</span> <span class="n">time</span><span class="p">,</span> <span class="s2">&quot;message&quot;</span><span class="p">:</span> <span class="n">msg</span><span class="p">})</span>