evennia/docs/2.x/Howtos/Howto-Add-Object-Weight.html
2023-12-20 18:20:52 +01:00

252 lines
No EOL
19 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Give objects weight &#8212; Evennia 2.x documentation</title>
<link rel="stylesheet" href="../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="NPCs that listen to what is said" href="Tutorial-NPC-Listening.html" />
<link rel="prev" title="Return custom errors on missing Exits" href="Howto-Default-Exit-Errors.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Tutorial-NPC-Listening.html" title="NPCs that listen to what is said"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="Howto-Default-Exit-Errors.html" title="Return custom errors on missing Exits"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Howtos-Overview.html" accesskey="U">Tutorials and Howtos</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Give objects weight</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<h3><a href="../index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Give objects weight</a><ul>
<li><a class="reference internal" href="#limit-inventory-by-weight-carried">Limit inventory by weight carried</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="Howto-Default-Exit-Errors.html"
title="previous chapter">Return custom errors on missing Exits</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="Tutorial-NPC-Listening.html"
title="next chapter">NPCs that listen to what is said</a></p>
<div role="note" aria-label="source link">
<!--h3>This Page</h3-->
<ul class="this-page-menu">
<li><a href="../_sources/Howtos/Howto-Add-Object-Weight.md.txt"
rel="nofollow">Show Page Source</a></li>
</ul>
</div><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<section class="tex2jax_ignore mathjax_ignore" id="give-objects-weight">
<h1>Give objects weight<a class="headerlink" href="#give-objects-weight" title="Permalink to this headline"></a></h1>
<p>All in-game objets you can touch usually has some weight. What weight does varies from game to game. Commonly it limits how much you can carry. A heavy stone may also hurt you more than a ballon, if it falls on you. If you want to get fancy, a pressure plate may only trigger if the one stepping on it is heavy enough.</p>
<div class="highlight-python notranslate"><div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
<span class="normal"> 2</span>
<span class="normal"> 3</span>
<span class="normal"> 4</span>
<span class="normal"> 5</span>
<span class="normal"> 6</span>
<span class="normal"> 7</span>
<span class="normal"> 8</span>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span>
<span class="normal">13</span>
<span class="normal">14</span>
<span class="normal">15</span>
<span class="normal">16</span></pre></div></td><td class="code"><div><pre><span></span><span class="c1"># inside your mygame/typeclasses/objects.py</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultObject</span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">AttributeProperty</span>
<span class="hll"><span class="k">class</span> <span class="nc">ObjectParent</span><span class="p">:</span>
</span>
<span class="hll"> <span class="n">weight</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">autocreate</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span>
<span class="hll"> <span class="nd">@property</span>
</span> <span class="k">def</span> <span class="nf">total_weight</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="hll"> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">weight</span> <span class="o">+</span> <span class="nb">sum</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">total_weight</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">contents</span><span class="p">)</span>
</span>
<span class="k">class</span> <span class="nc">Object</span><span class="p">(</span><span class="n">ObjectParent</span><span class="p">,</span> <span class="n">DefaultObject</span><span class="p">):</span>
<span class="c1"># ...</span>
</pre></div></td></tr></table></div>
</div>
<aside class="sidebar">
<p class="sidebar-title">Why not mass? </p>
<p>Yes, we know weight varies with gravity. Mass is more scientifically correct. But mass is less commonly used in RPGs, so we stick to weight here. Just know if if your sci-fi characters can vacation on the Moon (1/6 gravity of Earth) you should consider using <code class="docutils literal notranslate"><span class="pre">mass</span></code> everywhere and calculate the current weight on the fly.</p>
</aside>
<ul class="simple">
<li><p><strong>Line 6</strong>: We use the <code class="docutils literal notranslate"><span class="pre">ObjectParent</span></code> mixin. Since this mixin is used for <code class="docutils literal notranslate"><span class="pre">Characters</span></code>, <code class="docutils literal notranslate"><span class="pre">Exits</span></code> and <code class="docutils literal notranslate"><span class="pre">Rooms</span></code> as well as for <code class="docutils literal notranslate"><span class="pre">Object</span></code>, it means all of those will automatically <em>also</em> have weight!</p></li>
<li><p><strong>Line 8</strong>: We use an <a class="reference internal" href="../Components/Attributes.html#using-attributeproperty"><span class="std std-doc">AttributeProperty</span></a> to set up the default weight of 1 (whatever that is). Setting <code class="docutils literal notranslate"><span class="pre">autocreate=False</span></code> means no actual <code class="docutils literal notranslate"><span class="pre">Attribute</span></code> will be created until the weight is actually changed from the default of 1. See the <code class="docutils literal notranslate"><span class="pre">AttributeProperty</span></code> documentation for caveats with this.</p></li>
<li><p><strong>Line 10 and 11</strong>: Using the <code class="docutils literal notranslate"><span class="pre">&#64;property</span></code> decorator on <code class="docutils literal notranslate"><span class="pre">total_weight</span></code> means that we will be able to call <code class="docutils literal notranslate"><span class="pre">obj.total_weight</span></code> instead of <code class="docutils literal notranslate"><span class="pre">obj.total_weight()</span></code> later.</p></li>
<li><p><strong>Line 12</strong>: We sum up all weights from everything “in” this object, by looping over <code class="docutils literal notranslate"><span class="pre">self.contents</span></code>. Since <em>all</em> objects will have weight now, this should always work!</p></li>
</ul>
<p>Lets check out the weight of some trusty boxes</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&gt;</span> <span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">box1</span>
<span class="o">&gt;</span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">&quot;box1&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">weight</span>
<span class="mi">1</span>
<span class="o">&gt;</span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">&quot;box1&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">total_weight</span>
<span class="mi">1</span>
</pre></div>
</div>
<p>Lets put another box into the first one.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&gt;</span> <span class="n">create</span><span class="o">/</span><span class="n">drop</span> <span class="n">box2</span>
<span class="o">&gt;</span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">&quot;box2&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">total_weight</span>
<span class="mi">1</span>
<span class="o">&gt;</span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">&quot;box2&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">location</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">&quot;box1&quot;</span><span class="p">)</span>
<span class="o">&gt;</span> <span class="n">py</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">box1</span><span class="p">)</span><span class="o">.</span><span class="n">total_weight</span>
<span class="mi">2</span>
</pre></div>
</div>
<section id="limit-inventory-by-weight-carried">
<h2>Limit inventory by weight carried<a class="headerlink" href="#limit-inventory-by-weight-carried" title="Permalink to this headline"></a></h2>
<p>To limit how much you can carry, you first need to know your own strength</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/typeclasses/characters.py </span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">AttributeProperty</span>
<span class="c1"># ... </span>
<span class="k">class</span> <span class="nc">Character</span><span class="p">(</span><span class="n">ObjectParent</span><span class="p">,</span> <span class="n">DefaultCharacter</span><span class="p">):</span>
<span class="n">carrying_capacity</span> <span class="o">=</span> <span class="n">AttributeProperty</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">autocreate</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">carried_weight</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">total_weight</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">weight</span>
</pre></div>
</div>
<p>Here we make sure to add another <code class="docutils literal notranslate"><span class="pre">AttributeProperty</span></code> telling us how much to carry. In a real game, this may be based on how strong the Character is. When we consider how much weight we already carry, we should not include <em>our own</em> weight, so we subtract that.</p>
<p>To honor this limit, well need to override the default <code class="docutils literal notranslate"><span class="pre">get</span></code> command.</p>
<aside class="sidebar">
<p class="sidebar-title">Overriding default commands</p>
<p>In this example, we implement the beginning of the <code class="docutils literal notranslate"><span class="pre">CmdGet</span></code> and then call the full <code class="docutils literal notranslate"><span class="pre">CmdGet()</span></code> at the end. This is not very efficient, because the parent <code class="docutils literal notranslate"><span class="pre">CmdGet</span></code> will again have to do the <code class="docutils literal notranslate"><span class="pre">caller.search()</span></code> again. To be more efficient, you will likely want to copy the entirety of the <code class="docutils literal notranslate"><span class="pre">CmdGet</span></code> code into your own version and modify it.</p>
</aside>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/commands/command.py </span>
<span class="c1"># ... </span>
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">default_cmds</span>
<span class="c1"># ... </span>
<span class="k">class</span> <span class="nc">WeightAwareCmdGet</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CmdGet</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">caller</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Get what?&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">weight</span> <span class="o">+</span> <span class="n">caller</span><span class="o">.</span><span class="n">carried_weight</span>
<span class="o">&gt;</span> <span class="n">caller</span><span class="o">.</span><span class="n">carrying_capacity</span><span class="p">):</span>
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;You can&#39;t carry that much!&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">func</span><span class="p">()</span>
</pre></div>
</div>
<p>Here we add an extra check for the weight of the thing we are trying to pick up, then we call the normal <code class="docutils literal notranslate"><span class="pre">CmdGet</span></code> with <code class="docutils literal notranslate"><span class="pre">super().func()</span></code>.</p>
</section>
</section>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="Tutorial-NPC-Listening.html" title="NPCs that listen to what is said"
>next</a> |</li>
<li class="right" >
<a href="Howto-Default-Exit-Errors.html" title="Return custom errors on missing Exits"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="Howtos-Overview.html" >Tutorials and Howtos</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Give objects weight</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2023, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>