mirror of
https://github.com/evennia/evennia.git
synced 2026-03-18 13:56:30 +01:00
258 lines
No EOL
18 KiB
HTML
258 lines
No EOL
18 KiB
HTML
|
||
<!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>Return custom errors on missing Exits — 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="Give objects weight" href="Howto-Add-Object-Weight.html" />
|
||
<link rel="prev" title="Commands that take time to finish" href="Howto-Command-Duration.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="Howto-Add-Object-Weight.html" title="Give objects weight"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="Howto-Command-Duration.html" title="Commands that take time to finish"
|
||
accesskey="P">previous</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="Howtos-Overview.html" accesskey="U">Tutorials and How-To’s</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Return custom errors on missing Exits</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="#">Return custom errors on missing Exits</a><ul>
|
||
<li><a class="reference internal" href="#why-not-a-single-command">Why not a single command?</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="Howto-Command-Duration.html"
|
||
title="previous chapter">Commands that take time to finish</a></p>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="Howto-Add-Object-Weight.html"
|
||
title="next chapter">Give objects weight</a></p>
|
||
<div role="note" aria-label="source link">
|
||
<!--h3>This Page</h3-->
|
||
<ul class="this-page-menu">
|
||
<li><a href="../_sources/Howtos/Howto-Default-Exit-Errors.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>
|
||
<h3>Doc Versions</h3>
|
||
<ul>
|
||
|
||
<li><a href="Howto-Default-Exit-Errors.html">2.x (main branch)</a></li>
|
||
<ul>
|
||
<li><a href="../1.3.0/index.html">1.3.0 (v1.3.0 branch)</a></li>
|
||
|
||
<li><a href="../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
||
|
||
|
||
</ul>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section class="tex2jax_ignore mathjax_ignore" id="return-custom-errors-on-missing-exits">
|
||
<h1>Return custom errors on missing Exits<a class="headerlink" href="#return-custom-errors-on-missing-exits" title="Permalink to this headline">¶</a></h1>
|
||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> north
|
||
Ouch! You bump into a wall!
|
||
> out
|
||
But you are already outside ...?
|
||
</pre></div>
|
||
</div>
|
||
<p>Evennia allows for exits to have any name. The command “kitchen” is a valid exit name as well as “jump out the window” or “north”. An exit actually consists of two parts: an <a class="reference internal" href="../Components/Objects.html"><span class="doc std std-doc">Exit Object</span></a> and
|
||
an <a class="reference internal" href="../Components/Commands.html"><span class="doc std std-doc">Exit Command</span></a> stored on said exit object. The command has the same key and aliases as the
|
||
exit-object, which is why you can see the exit in the room and just write its name to traverse it.</p>
|
||
<p>So if you try to enter the name of a non-existing exit, Evennia treats is the same way as if you were trying to use a non-existing command:</p>
|
||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> > jump out the window
|
||
Command 'jump out the window' is not available. Type "help" for help.
|
||
</pre></div>
|
||
</div>
|
||
<p>Many games don’t need this type of freedom. They define only the cardinal directions as valid exit names ( Evennia’s <code class="docutils literal notranslate"><span class="pre">tunnel</span></code> command also offers this functionality). In this case, the error starts to look less logical:</p>
|
||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> > west
|
||
Command 'west' is not available. Maybe you meant "set" or "reset"?
|
||
</pre></div>
|
||
</div>
|
||
<p>Since we for our particular game <em>know</em> that west is an exit direction, it would be better if the error message just told us that we couldn’t go there.</p>
|
||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> > west
|
||
You cannot move west.
|
||
</pre></div>
|
||
</div>
|
||
<p>The way to do this is to give Evennia an <em>alternative</em> Command to use when no Exit-Command is found in the room. See <a class="reference internal" href="Beginner-Tutorial/Part1/Beginner-Tutorial-Adding-Commands.html"><span class="doc std std-doc">Adding Commands</span></a> for more info about the process of adding new Commands to Evennia.</p>
|
||
<p>In this example we will just echo an error message, but you could do everything (maybe you lose health if you bump into a wall?)</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># for example in a file mygame/commands/movecommands.py</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">default_cmds</span><span class="p">,</span> <span class="n">CmdSet</span>
|
||
|
||
<span class="k">class</span> <span class="nc">CmdExitError</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">MuxCommand</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""Parent class for all exit-errors."""</span>
|
||
<span class="n">locks</span> <span class="o">=</span> <span class="s2">"cmd:all()"</span>
|
||
<span class="n">arg_regex</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">"\s|$"</span>
|
||
<span class="n">auto_help</span> <span class="o">=</span> <span class="kc">False</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="w"> </span><span class="sd">"""Returns error based on key"""</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="sa">f</span><span class="s2">"You cannot move </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="si">}</span><span class="s2">."</span><span class="p">)</span>
|
||
|
||
<span class="k">class</span> <span class="nc">CmdExitErrorNorth</span><span class="p">(</span><span class="n">CmdExitError</span><span class="p">):</span>
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"north"</span>
|
||
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"n"</span><span class="p">]</span>
|
||
|
||
<span class="k">class</span> <span class="nc">CmdExitErrorEast</span><span class="p">(</span><span class="n">CmdExitError</span><span class="p">):</span>
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"east"</span>
|
||
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"e"</span><span class="p">]</span>
|
||
|
||
<span class="k">class</span> <span class="nc">CmdExitErrorSouth</span><span class="p">(</span><span class="n">CmdExitError</span><span class="p">):</span>
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"south"</span>
|
||
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"s"</span><span class="p">]</span>
|
||
|
||
<span class="k">class</span> <span class="nc">CmdExitErrorWest</span><span class="p">(</span><span class="n">CmdExitError</span><span class="p">):</span>
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"west"</span>
|
||
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"w"</span><span class="p">]</span>
|
||
|
||
<span class="c1"># you could add each command on its own to the default cmdset,</span>
|
||
<span class="c1"># but putting them all in a cmdset here allows you to</span>
|
||
<span class="c1"># just add this and makes it easier to expand with more </span>
|
||
<span class="c1"># exit-errors in the future</span>
|
||
|
||
<span class="k">class</span> <span class="nc">MovementFailCmdSet</span><span class="p">(</span><span class="n">CmdSet</span><span class="p">):</span>
|
||
<span class="k">def</span> <span class="nf">at_cmdset_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdExitErrorNorth</span><span class="p">())</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdExitErrorEast</span><span class="p">())</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdExitErrorWest</span><span class="p">())</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdExitErrorSouth</span><span class="p">())</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>We pack our commands in a new little cmdset; if we add this to our <code class="docutils literal notranslate"><span class="pre">CharacterCmdSet</span></code>, we can just add more errors to <code class="docutils literal notranslate"><span class="pre">MovementFailCmdSet</span></code> later without having to change code in two places.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/commands/default_cmdsets.py</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">commands</span> <span class="kn">import</span> <span class="n">movecommands</span>
|
||
|
||
<span class="c1"># [...]</span>
|
||
<span class="k">class</span> <span class="nc">CharacterCmdSet</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CharacterCmdSet</span><span class="p">):</span>
|
||
<span class="c1"># [...]</span>
|
||
<span class="k">def</span> <span class="nf">at_cmdset_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="c1"># [...]</span>
|
||
<span class="c1"># this adds all the commands at once</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">movecommands</span><span class="o">.</span><span class="n">MovementFailCmdSet</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">reload</span></code> the server. What happens henceforth is that if you are in a room with an Exitobject (let’s say it’s “north”), the proper Exit-command will <em>overload</em> your error command (also named “north”). But if you enter a direction without having a matching exit for it, you will fall back to your default error commands:</p>
|
||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> > east
|
||
You cannot move east.
|
||
</pre></div>
|
||
</div>
|
||
<p>Further expansions by the exit system (including manipulating the way the Exit command itself is created) can be done by modifying the <a class="reference internal" href="../Components/Typeclasses.html"><span class="doc std std-doc">Exit typeclass</span></a> directly.</p>
|
||
<section id="why-not-a-single-command">
|
||
<h2>Why not a single command?<a class="headerlink" href="#why-not-a-single-command" title="Permalink to this headline">¶</a></h2>
|
||
<p>So why didn’t we create a single error command above? Something like this:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CmdExitError</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">MuxCommand</span><span class="p">):</span>
|
||
<span class="s2">"Handles all exit-errors."</span>
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"error_cmd"</span>
|
||
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"north"</span><span class="p">,</span> <span class="s2">"n"</span><span class="p">,</span>
|
||
<span class="s2">"east"</span><span class="p">,</span> <span class="s2">"e"</span><span class="p">,</span>
|
||
<span class="s2">"south"</span><span class="p">,</span> <span class="s2">"s"</span><span class="p">,</span>
|
||
<span class="s2">"west"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">]</span>
|
||
<span class="c1">#[...]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This would <em>not</em> work the way we want. Understanding why is important.</p>
|
||
<p>Evennia’s <a class="reference internal" href="../Components/Commands.html"><span class="doc std std-doc">command system</span></a> compares commands by key and/or aliases. If <em>any</em> key or alias match, the two commands are considered <em>identical</em>. When the cmdsets merge, priority will then decide which of these ‘identical’ commandss replace which.</p>
|
||
<p>So the above example would work fine as long as there were <em>no Exits at all</em> in the room. But when we enter a room with an exit “north”, its Exit-command (which has a higher priority) will override the single <code class="docutils literal notranslate"><span class="pre">CmdExitError</span></code> with its alias ‘north’. So the <code class="docutils literal notranslate"><span class="pre">CmdExitError</span></code> will be gone and while “north” will work, we’ll again get the normal “Command not recognized” error for the other directions.</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="Howto-Add-Object-Weight.html" title="Give objects weight"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="Howto-Command-Duration.html" title="Commands that take time to finish"
|
||
>previous</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 2.x</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="Howtos-Overview.html" >Tutorials and How-To’s</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Return custom errors on missing Exits</a></li>
|
||
</ul>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="footer" role="contentinfo">
|
||
© Copyright 2023, The Evennia developer community.
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||
</div>
|
||
</body>
|
||
</html> |