<pclass="last">You are reading an old version of the Evennia documentation. <ahref="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
<p>This will introduce an NPC able to sell things. In practice this means that when you interact with them you’ll get shown a <em>menu</em> of choices. Evennia provides the <aclass="reference internal"href="../Components/EvMenu.html"><spanclass="doc std std-doc">EvMenu</span></a> utility to easily create in-game menus.</p>
<p>We will store all the merchant’s wares in their inventory. This means that they may stand in an actual shop room, at a market or wander the road. We will also use ‘gold’ as an example currency.<br/>
To enter the shop, you’ll just need to stand in the same room and use the <codeclass="docutils literal notranslate"><spanclass="pre">buy/shop</span></code> command.</p>
<sectionid="making-the-merchant-class">
<h2>Making the merchant class<aclass="headerlink"href="#making-the-merchant-class"title="Permalink to this headline">¶</a></h2>
<p>The merchant will respond to you giving the <codeclass="docutils literal notranslate"><spanclass="pre">shop</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">buy</span></code> command in their presence.</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># in for example mygame/typeclasses/merchants.py </span>
<p>We could also have put the commands in a separate module, but for compactness, we put it all with the merchant typeclass.</p>
<p>Note that we make the merchant an <codeclass="docutils literal notranslate"><spanclass="pre">Object</span></code>! Since we don’t give them any other commands, it makes little sense to let them be a <codeclass="docutils literal notranslate"><spanclass="pre">Character</span></code>.</p>
<p>We make a very simple <codeclass="docutils literal notranslate"><spanclass="pre">shop</span></code>/<codeclass="docutils literal notranslate"><spanclass="pre">buy</span></code> Command and make sure to add it on the merchant in its own cmdset.</p>
<p>We initialize <codeclass="docutils literal notranslate"><spanclass="pre">EvMenu</span></code> on the <codeclass="docutils literal notranslate"><spanclass="pre">shopper</span></code> but we haven’t created any <codeclass="docutils literal notranslate"><spanclass="pre">menunodes</span></code> yet, so this will not actually do much at this point. It’s important that we we pass <codeclass="docutils literal notranslate"><spanclass="pre">shopname</span></code>, <codeclass="docutils literal notranslate"><spanclass="pre">shopkeeper</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">wares</span></code> into the menu, it means they will be made available as properties on the EvMenu instance - we will be able to access them from inside the menu.</p>
</section>
<sectionid="coding-the-shopping-menu">
<h2>Coding the shopping menu<aclass="headerlink"href="#coding-the-shopping-menu"title="Permalink to this headline">¶</a></h2>
<p><aclass="reference internal"href="../Components/EvMenu.html"><spanclass="doc std std-doc">EvMenu</span></a> splits the menu into <em>nodes</em> represented by Python functions. Each node represents a stop in the menu where the user has to make a choice.</p>
<p>For simplicity, we’ll code the shop interface above the <codeclass="docutils literal notranslate"><spanclass="pre">NPCMerchant</span></code> class in the same module.</p>
<p>The start node of the shop named “ye Old Sword shop!” will look like this if there are only 3 wares to sell:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>*** Welcome to ye Old Sword shop! ***
Things for sale (choose 1-3 to inspect, quit to exit):
<spanclass="n">text</span><spanclass="o">=</span><spanclass="sa">f</span><spanclass="s2">"*** Welcome to </span><spanclass="si">{</span><spanclass="n">shopname</span><spanclass="si">}</span><spanclass="s2">! ***</span><spanclass="se">\n</span><spanclass="s2">"</span>
<spanclass="n">text</span><spanclass="o">+=</span><spanclass="sa">f</span><spanclass="s2">" Things for sale (choose 1-</span><spanclass="si">{</span><spanclass="nb">len</span><spanclass="p">(</span><spanclass="n">wares</span><spanclass="p">)</span><spanclass="si">}</span><spanclass="s2"> to inspect); quit to exit:"</span>
<spanclass="k">else</span><spanclass="p">:</span>
<spanclass="n">text</span><spanclass="o">+=</span><spanclass="s2">" There is nothing for sale; quit to exit."</span>
<p>Inside the node we can access the menu on the caller as <codeclass="docutils literal notranslate"><spanclass="pre">caller.ndb._evmenu</span></code>. The extra keywords we passed into <codeclass="docutils literal notranslate"><spanclass="pre">EvMenu</span></code> are available on this menu instance. Armed with this we can easily present a shop interface. Each option will become a numbered choice on this screen.</p>
<p>Note how we pass the <codeclass="docutils literal notranslate"><spanclass="pre">ware</span></code> with each option and label it <codeclass="docutils literal notranslate"><spanclass="pre">selected_ware</span></code>. This will be accessible in the next node’s <codeclass="docutils literal notranslate"><spanclass="pre">**kwargs</span></code> argument</p>
<p>If a player choose one of the wares, they should be able to inspect it. Here’s how it should look if they selected <codeclass="docutils literal notranslate"><spanclass="pre">1</span></code> in ye Old Sword shop:</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>You pay 5 gold and purchase A rusty sword!
</pre></div>
</div>
<p>or</p>
<divclass="highlight-default notranslate"><divclass="highlight"><pre><span></span>You cannot afford 5 gold for A rusty sword!
</pre></div>
</div>
<p>Either way you should end up back at the top level of the shopping menu again and can continue browsing or quit the menu with <codeclass="docutils literal notranslate"><spanclass="pre">quit</span></code>.</p>
<p>Here’s how it looks in code:</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># in mygame/typeclasses/merchants.py </span>
<spanclass="c1"># right after the other node</span>
<spanclass="s2">"desc"</span><spanclass="p">:</span><spanclass="sa">f</span><spanclass="s2">"Buy </span><spanclass="si">{</span><spanclass="n">ware</span><spanclass="o">.</span><spanclass="n">key</span><spanclass="si">}</span><spanclass="s2"> for </span><spanclass="si">{</span><spanclass="n">gold_val</span><spanclass="si">}</span><spanclass="s2"> gold"</span><spanclass="p">,</span>
<p>In this node we grab the <codeclass="docutils literal notranslate"><spanclass="pre">selected_ware</span></code> from <codeclass="docutils literal notranslate"><spanclass="pre">kwargs</span></code> - this we pased along from the option on the previous node. We display its description and value. If the user buys, we reroute through the <codeclass="docutils literal notranslate"><spanclass="pre">_buy_item</span></code> helper function (this is not a node, it’s just a callable that must return the name of the next node to go to.). In <codeclass="docutils literal notranslate"><spanclass="pre">_buy_item</span></code> we check if the buyer can affort the ware, and if it can we move it to their inventory. Either way, this method returns <codeclass="docutils literal notranslate"><spanclass="pre">shop_front</span></code> as the next node.</p>
<p>We have been referring to two nodes here: <codeclass="docutils literal notranslate"><spanclass="pre">"shopfront"</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">"inspect_and_buy"</span></code> , we should map them to the code in the menu. Scroll down to the <codeclass="docutils literal notranslate"><spanclass="pre">NPCMerchant</span></code> class in the same module and find that unfinished <codeclass="docutils literal notranslate"><spanclass="pre">open_shop</span></code> method again:</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># in /mygame/typeclasses/merchants.py</span>
<spanclass="o">></span><spanclass="nb">set</span><spanclass="n">rowboat</span><spanclass="o">/</span><spanclass="n">desc</span><spanclass="o">=</span><spanclass="n">It</span><spanclass="s1">'s not going anywhere fast.</span>
</pre></div>
</div>
<p>Note that a builder without any access to Python code can now set up a personalized merchant with just in-game commands. With the shop all set up, we just need to be in the same room to start consuming!</p>
<pclass="last">You are reading an old version of the Evennia documentation. <ahref="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.