mirror of
https://github.com/evennia/evennia.git
synced 2026-03-18 05:46:31 +01:00
582 lines
No EOL
63 KiB
HTML
582 lines
No EOL
63 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>Dynamic In Game Map — Evennia 0.9.5 documentation</title>
|
||
<link rel="stylesheet" href="_static/nature.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
|
||
<script src="_static/jquery.js"></script>
|
||
<script src="_static/underscore.js"></script>
|
||
<script src="_static/doctools.js"></script>
|
||
<script src="_static/language_data.js"></script>
|
||
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"processClass": "tex2jax_process|mathjax_process|math|output_area"}})</script>
|
||
<link rel="shortcut icon" href="_static/favicon.ico"/>
|
||
<link rel="index" title="Index" href="genindex.html" />
|
||
<link rel="search" title="Search" href="search.html" />
|
||
</head><body>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="index.html">Evennia 0.9.5</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Dynamic In Game Map</a></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section class="tex2jax_ignore mathjax_ignore" id="dynamic-in-game-map">
|
||
<h1>Dynamic In Game Map<a class="headerlink" href="#dynamic-in-game-map" title="Permalink to this headline">¶</a></h1>
|
||
<section id="introduction">
|
||
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
|
||
<p>An often desired feature in a MUD is to show an in-game map to help navigation. The <a class="reference internal" href="Static-In-Game-Map.html"><span class="doc std std-doc">Static in-game
|
||
map</span></a> tutorial solves this by creating a <em>static</em> map, meaning the map is pre-
|
||
drawn once and for all - the rooms are then created to match that map. When walking around, parts of
|
||
the static map is then cut out and displayed next to the room description.</p>
|
||
<p>In this tutorial we’ll instead do it the other way around; We will dynamically draw the map based on
|
||
the relationships we find between already existing rooms.</p>
|
||
</section>
|
||
<section id="the-grid-of-rooms">
|
||
<h2>The Grid of Rooms<a class="headerlink" href="#the-grid-of-rooms" title="Permalink to this headline">¶</a></h2>
|
||
<p>There are at least two requirements needed for this tutorial to work.</p>
|
||
<ol class="simple">
|
||
<li><p>The structure of your mud has to follow a logical layout. Evennia supports the layout of your
|
||
world to be ‘logically’ impossible with rooms looping to themselves or exits leading to the other
|
||
side of the map. Exits can also be named anything, from “jumping out the window” to “into the fifth
|
||
dimension”. This tutorial assumes you can only move in the cardinal directions (N, E, S and W).</p></li>
|
||
<li><p>Rooms must be connected and linked together for the map to be generated correctly. Vanilla
|
||
Evennia comes with a admin command <a class="reference internal" href="api/evennia.commands.default.building.html#evennia.commands.default.building.CmdTunnel" title="evennia.commands.default.building.CmdTunnel"><span class="xref myst py py-class">tunnel</span></a> that allows a
|
||
user to create rooms in the cardinal directions, but additional work is needed to assure that rooms
|
||
are connected. For example, if you <code class="docutils literal notranslate"><span class="pre">tunnel</span> <span class="pre">east</span></code> and then immediately do <code class="docutils literal notranslate"><span class="pre">tunnel</span> <span class="pre">west</span></code> you’ll find
|
||
that you have created two completely stand-alone rooms. So care is needed if you want to create a
|
||
“logical” layout. In this tutorial we assume you have such a grid of rooms that we can generate the
|
||
map from.</p></li>
|
||
</ol>
|
||
</section>
|
||
<section id="concept">
|
||
<h2>Concept<a class="headerlink" href="#concept" title="Permalink to this headline">¶</a></h2>
|
||
<p>Before getting into the code, it is beneficial to understand and conceptualize how this is going to
|
||
work. The idea is analogous to a worm that starts at your current position. It chooses a direction
|
||
and ‘walks’ outward from it, mapping its route as it goes. Once it has traveled a pre-set distance
|
||
it stops and starts over in another direction. An important note is that we want a system which is
|
||
easily callable and not too complicated. Therefore we will wrap this entire code into a custom
|
||
Python class (not a typeclass as this doesn’t use any core objects from evennia itself).</p>
|
||
<p>We are going to create something that displays like this when you type ‘look’:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">Hallway</span>
|
||
|
||
<span class="p">[</span><span class="o">.</span><span class="p">]</span> <span class="p">[</span><span class="o">.</span><span class="p">]</span>
|
||
<span class="p">[</span><span class="o">@</span><span class="p">][</span><span class="o">.</span><span class="p">][</span><span class="o">.</span><span class="p">][</span><span class="o">.</span><span class="p">][</span><span class="o">.</span><span class="p">]</span>
|
||
<span class="p">[</span><span class="o">.</span><span class="p">]</span> <span class="p">[</span><span class="o">.</span><span class="p">]</span> <span class="p">[</span><span class="o">.</span><span class="p">]</span>
|
||
|
||
<span class="n">The</span> <span class="n">distant</span> <span class="n">echoes</span> <span class="n">of</span> <span class="n">the</span> <span class="n">forgotten</span>
|
||
<span class="n">wail</span> <span class="n">throughout</span> <span class="n">the</span> <span class="n">empty</span> <span class="n">halls</span><span class="o">.</span>
|
||
|
||
<span class="n">Exits</span><span class="p">:</span> <span class="n">North</span><span class="p">,</span> <span class="n">East</span><span class="p">,</span> <span class="n">South</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Your current location is defined by <code class="docutils literal notranslate"><span class="pre">[@]</span></code> while the <code class="docutils literal notranslate"><span class="pre">[.]</span></code>s are other rooms that the “worm” has seen
|
||
since departing from your location.</p>
|
||
</section>
|
||
<section id="setting-up-the-map-display">
|
||
<h2>Setting up the Map Display<a class="headerlink" href="#setting-up-the-map-display" title="Permalink to this headline">¶</a></h2>
|
||
<p>First we must define the components for displaying the map. For the “worm” to know what symbol to
|
||
draw on the map we will have it check an Attribute on the room it visits called <code class="docutils literal notranslate"><span class="pre">sector_type</span></code>. For
|
||
this tutorial we understand two symbols - a normal room and the room with us in it. We also define a
|
||
fallback symbol for rooms without said Attribute - that way the map will still work even if we
|
||
didn’t prepare the room correctly. Assuming your game folder is named <code class="docutils literal notranslate"><span class="pre">mygame</span></code>, we create this code
|
||
in <code class="docutils literal notranslate"><span class="pre">mygame/world/map.py.</span></code></p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/map.py</span>
|
||
|
||
<span class="c1"># the symbol is identified with a key "sector_type" on the</span>
|
||
<span class="c1"># Room. Keys None and "you" must always exist.</span>
|
||
<span class="n">SYMBOLS</span> <span class="o">=</span> <span class="p">{</span> <span class="kc">None</span> <span class="p">:</span> <span class="s1">' . '</span><span class="p">,</span> <span class="c1"># for rooms without sector_type Attribute</span>
|
||
<span class="s1">'you'</span> <span class="p">:</span> <span class="s1">'[@]'</span><span class="p">,</span>
|
||
<span class="s1">'SECT_INSIDE'</span><span class="p">:</span> <span class="s1">'[.]'</span> <span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Since trying to access an unset Attribute returns <code class="docutils literal notranslate"><span class="pre">None</span></code>, this means rooms without the <code class="docutils literal notranslate"><span class="pre">sector_type</span></code>
|
||
Atttribute will show as <code class="docutils literal notranslate"><span class="pre">.</span></code>. Next we start building the custom class <code class="docutils literal notranslate"><span class="pre">Map</span></code>. It will hold all
|
||
methods we need.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/map.py</span>
|
||
|
||
<span class="k">class</span> <span class="nc">Map</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
||
|
||
<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">caller</span><span class="p">,</span> <span class="n">max_width</span><span class="o">=</span><span class="mi">9</span><span class="p">,</span> <span class="n">max_length</span><span class="o">=</span><span class="mi">9</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">max_width</span> <span class="o">=</span> <span class="n">max_width</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">max_length</span> <span class="o">=</span> <span class="n">max_length</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span> <span class="o">=</span> <span class="p">{}</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">=</span> <span class="kc">None</span>
|
||
</pre></div>
|
||
</div>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">self.caller</span></code> is normally your Character object, the one using the map.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">self.max_width/length</span></code> determine the max width and length of the map that will be generated. Note
|
||
that it’s important that these variables are set to <em>odd</em> numbers to make sure the display area has
|
||
a center point.</p></li>
|
||
<li><p><code class="docutils literal notranslate"> <span class="pre">self.worm_has_mapped</span></code> is building off the worm analogy above. This dictionary will store all
|
||
rooms the “worm” has mapped as well as its relative position within the grid. This is the most
|
||
important variable as it acts as a ‘checker’ and ‘address book’ that is able to tell us where the
|
||
worm has been and what it has mapped so far.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">self.curX/Y</span></code> are coordinates representing the worm’s current location on the grid.</p></li>
|
||
</ul>
|
||
<p>Before any sort of mapping can actually be done we need to create an empty display area and do some
|
||
sanity checks on it by using the following methods.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/map.py</span>
|
||
|
||
<span class="k">class</span> <span class="nc">Map</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
||
<span class="c1"># [... continued]</span>
|
||
|
||
<span class="k">def</span> <span class="nf">create_grid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="c1"># This method simply creates an empty grid/display area</span>
|
||
<span class="c1"># with the specified variables from __init__(self):</span>
|
||
<span class="n">board</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_width</span><span class="p">):</span>
|
||
<span class="n">board</span><span class="o">.</span><span class="n">append</span><span class="p">([])</span>
|
||
<span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_length</span><span class="p">):</span>
|
||
<span class="n">board</span><span class="p">[</span><span class="n">row</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">' '</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">board</span>
|
||
|
||
<span class="k">def</span> <span class="nf">check_grid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="c1"># this method simply checks the grid to make sure</span>
|
||
<span class="c1"># that both max_l and max_w are odd numbers.</span>
|
||
<span class="k">return</span> <span class="kc">True</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_length</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_width</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span>\
|
||
<span class="k">else</span> <span class="kc">False</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Before we can set our worm on its way, we need to know some of the computer science behind all this
|
||
called ‘Graph Traversing’. In Pseudo code what we are trying to accomplish is this:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># pseudo code</span>
|
||
|
||
<span class="k">def</span> <span class="nf">draw_room_on_map</span><span class="p">(</span><span class="n">room</span><span class="p">,</span> <span class="n">max_distance</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">(</span><span class="n">room</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="n">max_distance</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="k">return</span>
|
||
|
||
<span class="k">for</span> <span class="n">exit</span> <span class="ow">in</span> <span class="n">room</span><span class="o">.</span><span class="n">exits</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_drawn</span><span class="p">(</span><span class="n">exit</span><span class="o">.</span><span class="n">destination</span><span class="p">):</span>
|
||
<span class="c1"># skip drawing if we already visited the destination</span>
|
||
<span class="k">continue</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="c1"># first time here!</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">draw_room_on_map</span><span class="p">(</span><span class="n">exit</span><span class="o">.</span><span class="n">destination</span><span class="p">,</span> <span class="n">max_distance</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The beauty of Python is that our actual code of doing this doesn’t differ much if at all from this
|
||
Pseudo code example.</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">max_distance</span></code> is a variable indicating to our Worm how many rooms AWAY from your current location
|
||
will it map. Obviously the larger the number the more time it will take if your current location has
|
||
many many rooms around you.</p></li>
|
||
</ul>
|
||
<p>The first hurdle here is what value to use for ‘max_distance’. There is no reason for the worm to
|
||
travel further than what is actually displayed to you. For example, if your current location is
|
||
placed in the center of a display area of size <code class="docutils literal notranslate"><span class="pre">max_length</span> <span class="pre">=</span> <span class="pre">max_width</span> <span class="pre">=</span> <span class="pre">9</span></code>, then the worm need only
|
||
go <code class="docutils literal notranslate"><span class="pre">4</span></code> spaces in either direction:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="o">.</span><span class="p">][</span><span class="o">.</span><span class="p">][</span><span class="o">.</span><span class="p">][</span><span class="o">.</span><span class="p">][</span><span class="o">@</span><span class="p">][</span><span class="o">.</span><span class="p">][</span><span class="o">.</span><span class="p">][</span><span class="o">.</span><span class="p">][</span><span class="o">.</span><span class="p">]</span>
|
||
<span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The max_distance can be set dynamically based on the size of the display area. As your width/length
|
||
changes it becomes a simple algebraic linear relationship which is simply <code class="docutils literal notranslate"><span class="pre">max_distance</span> <span class="pre">=</span> <span class="pre">(min(max_width,</span> <span class="pre">max_length)</span> <span class="pre">-1)</span> <span class="pre">/</span> <span class="pre">2</span></code>.</p>
|
||
</section>
|
||
<section id="building-the-mapper">
|
||
<h2>Building the Mapper<a class="headerlink" href="#building-the-mapper" title="Permalink to this headline">¶</a></h2>
|
||
<p>Now we can start to fill our Map object with some methods. We are still missing a few methods that
|
||
are very important:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">self.draw(self,</span> <span class="pre">room)</span></code> - responsible for actually drawing room to grid.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">self.has_drawn(self,</span> <span class="pre">room)</span></code> - checks to see if the room has been mapped and worm has already been
|
||
here.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">self.median(self,</span> <span class="pre">number)</span></code> - a simple utility method that finds the median (middle point) from 0,
|
||
n</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">self.update_pos(self,</span> <span class="pre">room,</span> <span class="pre">exit_name)</span></code> - updates the worm’s physical position by reassigning
|
||
self.curX/Y. .accordingly</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">self.start_loc_on_grid(self)</span></code> - the very first initial draw on the grid representing your
|
||
location in the middle of the grid</p></li>
|
||
<li><p>‘self.show_map<code class="docutils literal notranslate"> <span class="pre">-</span> <span class="pre">after</span> <span class="pre">everything</span> <span class="pre">is</span> <span class="pre">done</span> <span class="pre">convert</span> <span class="pre">the</span> <span class="pre">map</span> <span class="pre">into</span> <span class="pre">a</span> <span class="pre">readable</span> <span class="pre">string</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">self.draw_room_on_map(self,</span> <span class="pre">room,</span> <span class="pre">max_distance)</span></code> - the main method that ties it all together.`</p></li>
|
||
</ul>
|
||
<p>Now that we know which methods we need, let’s refine our initial <code class="docutils literal notranslate"><span class="pre">__init__(self)</span></code> to pass some
|
||
conditional statements and set it up to start building the display.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1">#mygame/world/map.py</span>
|
||
|
||
<span class="k">class</span> <span class="nc">Map</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
||
|
||
<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">caller</span><span class="p">,</span> <span class="n">max_width</span><span class="o">=</span><span class="mi">9</span><span class="p">,</span> <span class="n">max_length</span><span class="o">=</span><span class="mi">9</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">max_width</span> <span class="o">=</span> <span class="n">max_width</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">max_length</span> <span class="o">=</span> <span class="n">max_length</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span> <span class="o">=</span> <span class="p">{}</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">=</span> <span class="kc">None</span>
|
||
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_grid</span><span class="p">():</span>
|
||
<span class="c1"># we have to store the grid into a variable</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">grid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_grid</span><span class="p">()</span>
|
||
<span class="c1"># we use the algebraic relationship</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">draw_room_on_map</span><span class="p">(</span><span class="n">caller</span><span class="o">.</span><span class="n">location</span><span class="p">,</span>
|
||
<span class="p">((</span><span class="nb">min</span><span class="p">(</span><span class="n">max_width</span><span class="p">,</span> <span class="n">max_length</span><span class="p">)</span> <span class="o">-</span><span class="mi">1</span> <span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span>
|
||
|
||
</pre></div>
|
||
</div>
|
||
<p>Here we check to see if the parameters for the grid are okay, then we create an empty canvas and map
|
||
our initial location as the first room!</p>
|
||
<p>As mentioned above, the code for the <code class="docutils literal notranslate"><span class="pre">self.draw_room_on_map()</span></code> is not much different than the Pseudo
|
||
code. The method is shown below:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/world/map.py, in the Map class</span>
|
||
|
||
<span class="k">def</span> <span class="nf">draw_room_on_map</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">max_distance</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">(</span><span class="n">room</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="n">max_distance</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="k">return</span>
|
||
|
||
<span class="k">for</span> <span class="n">exit</span> <span class="ow">in</span> <span class="n">room</span><span class="o">.</span><span class="n">exits</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="n">exit</span><span class="o">.</span><span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"north"</span><span class="p">,</span> <span class="s2">"east"</span><span class="p">,</span> <span class="s2">"west"</span><span class="p">,</span> <span class="s2">"south"</span><span class="p">):</span>
|
||
<span class="c1"># we only map in the cardinal directions. Mapping up/down would be</span>
|
||
<span class="c1"># an interesting learning project for someone who wanted to try it.</span>
|
||
<span class="k">continue</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_drawn</span><span class="p">(</span><span class="n">exit</span><span class="o">.</span><span class="n">destination</span><span class="p">):</span>
|
||
<span class="c1"># we've been to the destination already, skip ahead.</span>
|
||
<span class="k">continue</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">update_pos</span><span class="p">(</span><span class="n">room</span><span class="p">,</span> <span class="n">exit</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">draw_room_on_map</span><span class="p">(</span><span class="n">exit</span><span class="o">.</span><span class="n">destination</span><span class="p">,</span> <span class="n">max_distance</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The first thing the “worm” does is to draw your current location in <code class="docutils literal notranslate"><span class="pre">self.draw</span></code>. Lets define that…</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1">#in mygame/word/map.py, in the Map class</span>
|
||
|
||
<span class="k">def</span> <span class="nf">draw</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">):</span>
|
||
<span class="c1"># draw initial ch location on map first!</span>
|
||
<span class="k">if</span> <span class="n">room</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">location</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">start_loc_on_grid</span><span class="p">()</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span><span class="p">[</span><span class="n">room</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">curY</span><span class="p">]</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="c1"># map all other rooms</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span><span class="p">[</span><span class="n">room</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">curY</span><span class="p">]</span>
|
||
<span class="c1"># this will use the sector_type Attribute or None if not set.</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">grid</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">][</span><span class="bp">self</span><span class="o">.</span><span class="n">curY</span><span class="p">]</span> <span class="o">=</span> <span class="n">SYMBOLS</span><span class="p">[</span><span class="n">room</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">sector_type</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>In <code class="docutils literal notranslate"><span class="pre">self.start_loc_on_grid()</span></code>:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">median</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num</span><span class="p">):</span>
|
||
<span class="n">lst</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">num</span><span class="p">))</span>
|
||
<span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">lst</span><span class="p">)</span>
|
||
<span class="n">m</span> <span class="o">=</span> <span class="n">n</span> <span class="o">-</span><span class="mi">1</span>
|
||
<span class="k">return</span> <span class="p">(</span><span class="n">lst</span><span class="p">[</span><span class="n">n</span><span class="o">//</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="n">lst</span><span class="p">[</span><span class="n">m</span><span class="o">//</span><span class="mi">2</span><span class="p">])</span> <span class="o">/</span> <span class="mf">2.0</span>
|
||
|
||
<span class="k">def</span> <span class="nf">start_loc_on_grid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">median</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_width</span><span class="p">)</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">median</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_length</span><span class="p">)</span>
|
||
<span class="c1"># x and y are floats by default, can't index lists with float types</span>
|
||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="nb">int</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">grid</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">SYMBOLS</span><span class="p">[</span><span class="s1">'you'</span><span class="p">]</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="c1"># updating worms current location</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>After the system has drawn the current map it checks to see if the <code class="docutils literal notranslate"><span class="pre">max_distance</span></code> is <code class="docutils literal notranslate"><span class="pre">0</span></code> (since this
|
||
is the inital start phase it is not). Now we handle the iteration once we have each individual exit
|
||
in the room. The first thing it does is check if the room the Worm is in has been mapped already…
|
||
lets define that…</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">has_drawn</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">room</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span> <span class="k">else</span> <span class="kc">False</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>If <code class="docutils literal notranslate"><span class="pre">has_drawn</span></code> returns <code class="docutils literal notranslate"><span class="pre">False</span></code> that means the worm has found a room that hasn’t been mapped yet. It
|
||
will then ‘move’ there. The self.curX/Y sort of lags behind, so we have to make sure to track the
|
||
position of the worm; we do this in <code class="docutils literal notranslate"><span class="pre">self.update_pos()</span></code> below.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">update_pos</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">exit_name</span><span class="p">):</span>
|
||
<span class="c1"># this ensures the coordinates stays up to date</span>
|
||
<span class="c1"># to where the worm is currently at.</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">=</span> \
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span><span class="p">[</span><span class="n">room</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">worm_has_mapped</span><span class="p">[</span><span class="n">room</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>
|
||
|
||
<span class="c1"># now we have to actually move the pointer</span>
|
||
<span class="c1"># variables depending on which 'exit' it found</span>
|
||
<span class="k">if</span> <span class="n">exit_name</span> <span class="o">==</span> <span class="s1">'east'</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
<span class="k">elif</span> <span class="n">exit_name</span> <span class="o">==</span> <span class="s1">'west'</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">-=</span> <span class="mi">1</span>
|
||
<span class="k">elif</span> <span class="n">exit_name</span> <span class="o">==</span> <span class="s1">'north'</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span> <span class="o">-=</span> <span class="mi">1</span>
|
||
<span class="k">elif</span> <span class="n">exit_name</span> <span class="o">==</span> <span class="s1">'south'</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Once the system updates the position of the worm it feeds the new room back into the original
|
||
<code class="docutils literal notranslate"><span class="pre">draw_room_on_map()</span></code> and starts the process all over again…</p>
|
||
<p>That is essentially the entire thing. The final method is to bring it all together and make a nice
|
||
presentational string out of it using the <code class="docutils literal notranslate"><span class="pre">self.show_map()</span></code> method.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">show_map</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="n">map_string</span> <span class="o">=</span> <span class="s2">""</span>
|
||
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">grid</span><span class="p">:</span>
|
||
<span class="n">map_string</span> <span class="o">+=</span> <span class="s2">" "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
|
||
<span class="n">map_string</span> <span class="o">+=</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span>
|
||
|
||
<span class="k">return</span> <span class="n">map_string</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="using-the-map">
|
||
<h2>Using the Map<a class="headerlink" href="#using-the-map" title="Permalink to this headline">¶</a></h2>
|
||
<p>In order for the map to get triggered we store it on the Room typeclass. If we put it in
|
||
<code class="docutils literal notranslate"><span class="pre">return_appearance</span></code> we will get the map back every time we look at the room.</p>
|
||
<blockquote>
|
||
<div><p><code class="docutils literal notranslate"><span class="pre">return_appearance</span></code> is a default Evennia hook available on all objects; it is called e.g. by the
|
||
<code class="docutils literal notranslate"><span class="pre">look</span></code> command to get the description of something (the room in this case).</p>
|
||
</div></blockquote>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/typeclasses/rooms.py</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">DefaultRoom</span>
|
||
<span class="kn">from</span> <span class="nn">world.map</span> <span class="kn">import</span> <span class="n">Map</span>
|
||
|
||
<span class="k">class</span> <span class="nc">Room</span><span class="p">(</span><span class="n">DefaultRoom</span><span class="p">):</span>
|
||
|
||
<span class="k">def</span> <span class="nf">return_appearance</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">looker</span><span class="p">):</span>
|
||
<span class="c1"># [...]</span>
|
||
<span class="n">string</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%s</span><span class="se">\n</span><span class="s2">"</span> <span class="o">%</span> <span class="n">Map</span><span class="p">(</span><span class="n">looker</span><span class="p">)</span><span class="o">.</span><span class="n">show_map</span><span class="p">()</span>
|
||
<span class="c1"># Add all the normal stuff like room description,</span>
|
||
<span class="c1"># contents, exits etc.</span>
|
||
<span class="n">string</span> <span class="o">+=</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">return_appearance</span><span class="p">(</span><span class="n">looker</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">string</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Obviously this method of generating maps doesn’t take into account of any doors or exits that are
|
||
hidden… etc… but hopefully it serves as a good base to start with. Like previously mentioned, it
|
||
is very important to have a solid foundation on rooms before implementing this. You can try this on
|
||
vanilla evennia by using @tunnel and essentially you can just create a long straight/edgy non-
|
||
looping rooms that will show on your in-game map.</p>
|
||
<p>The above example will display the map above the room description. You could also use an
|
||
<a class="reference external" href="https://github.com/evennia/evennia/blob/master/evennia.utils.evtable">EvTable</a> to place description and map next to each other. Some other
|
||
things you can do is to have a <a class="reference internal" href="Commands.html"><span class="doc std std-doc">Command</span></a> that displays with a larger radius, maybe with a
|
||
legend and other features.</p>
|
||
<p>Below is the whole <code class="docutils literal notranslate"><span class="pre">map.py</span></code> for your reference. You need to update your <code class="docutils literal notranslate"><span class="pre">Room</span></code> typeclass (see above)
|
||
to actually call it. Remember that to see different symbols for a location you also need to set the
|
||
<code class="docutils literal notranslate"><span class="pre">sector_type</span></code> Attribute on the room to one of the keys in the <code class="docutils literal notranslate"><span class="pre">SYMBOLS</span></code> dictionary. So in this
|
||
example, to make a room be mapped as <code class="docutils literal notranslate"><span class="pre">[.]</span></code> you would set the room’s <code class="docutils literal notranslate"><span class="pre">sector_type</span></code> to
|
||
<code class="docutils literal notranslate"><span class="pre">"SECT_INSIDE"</span></code>. Try it out with <code class="docutils literal notranslate"><span class="pre">@set</span> <span class="pre">here/sector_type</span> <span class="pre">=</span> <span class="pre">"SECT_INSIDE"</span></code>. If you wanted all new
|
||
rooms to have a given sector symbol, you could change the default in the <code class="docutils literal notranslate"><span class="pre">SYMBOLS´</span> <span class="pre">dictionary</span> <span class="pre">below,</span> <span class="pre">or</span> <span class="pre">you</span> <span class="pre">could</span> <span class="pre">add</span> <span class="pre">the</span> <span class="pre">Attribute</span> <span class="pre">in</span> <span class="pre">the</span> <span class="pre">Room's</span> </code>at_object_creation` method.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1">#mygame/world/map.py</span>
|
||
|
||
<span class="c1"># These are keys set with the Attribute sector_type on the room.</span>
|
||
<span class="c1"># The keys None and "you" must always exist.</span>
|
||
<span class="n">SYMBOLS</span> <span class="o">=</span> <span class="p">{</span> <span class="kc">None</span> <span class="p">:</span> <span class="s1">' . '</span><span class="p">,</span> <span class="c1"># for rooms without a sector_type attr</span>
|
||
<span class="s1">'you'</span> <span class="p">:</span> <span class="s1">'[@]'</span><span class="p">,</span>
|
||
<span class="s1">'SECT_INSIDE'</span><span class="p">:</span> <span class="s1">'[.]'</span> <span class="p">}</span>
|
||
|
||
<span class="k">class</span> <span class="nc">Map</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
||
|
||
<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">caller</span><span class="p">,</span> <span class="n">max_width</span><span class="o">=</span><span class="mi">9</span><span class="p">,</span> <span class="n">max_length</span><span class="o">=</span><span class="mi">9</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span> <span class="o">=</span> <span class="n">caller</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">max_width</span> <span class="o">=</span> <span class="n">max_width</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">max_length</span> <span class="o">=</span> <span class="n">max_length</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span> <span class="o">=</span> <span class="p">{}</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">=</span> <span class="kc">None</span>
|
||
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_grid</span><span class="p">():</span>
|
||
<span class="c1"># we actually have to store the grid into a variable</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">grid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_grid</span><span class="p">()</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">draw_room_on_map</span><span class="p">(</span><span class="n">caller</span><span class="o">.</span><span class="n">location</span><span class="p">,</span>
|
||
<span class="p">((</span><span class="nb">min</span><span class="p">(</span><span class="n">max_width</span><span class="p">,</span> <span class="n">max_length</span><span class="p">)</span> <span class="o">-</span><span class="mi">1</span> <span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span>
|
||
|
||
<span class="k">def</span> <span class="nf">update_pos</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">exit_name</span><span class="p">):</span>
|
||
<span class="c1"># this ensures the pointer variables always</span>
|
||
<span class="c1"># stays up to date to where the worm is currently at.</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">=</span> \
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span><span class="p">[</span><span class="n">room</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">worm_has_mapped</span><span class="p">[</span><span class="n">room</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>
|
||
|
||
<span class="c1"># now we have to actually move the pointer</span>
|
||
<span class="c1"># variables depending on which 'exit' it found</span>
|
||
<span class="k">if</span> <span class="n">exit_name</span> <span class="o">==</span> <span class="s1">'east'</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
<span class="k">elif</span> <span class="n">exit_name</span> <span class="o">==</span> <span class="s1">'west'</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">-=</span> <span class="mi">1</span>
|
||
<span class="k">elif</span> <span class="n">exit_name</span> <span class="o">==</span> <span class="s1">'north'</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span> <span class="o">-=</span> <span class="mi">1</span>
|
||
<span class="k">elif</span> <span class="n">exit_name</span> <span class="o">==</span> <span class="s1">'south'</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
|
||
<span class="k">def</span> <span class="nf">draw_room_on_map</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">,</span> <span class="n">max_distance</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">draw</span><span class="p">(</span><span class="n">room</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="n">max_distance</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="k">return</span>
|
||
|
||
<span class="k">for</span> <span class="n">exit</span> <span class="ow">in</span> <span class="n">room</span><span class="o">.</span><span class="n">exits</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="n">exit</span><span class="o">.</span><span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"north"</span><span class="p">,</span> <span class="s2">"east"</span><span class="p">,</span> <span class="s2">"west"</span><span class="p">,</span> <span class="s2">"south"</span><span class="p">):</span>
|
||
<span class="c1"># we only map in the cardinal directions. Mapping up/down would be</span>
|
||
<span class="c1"># an interesting learning project for someone who wanted to try it.</span>
|
||
<span class="k">continue</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_drawn</span><span class="p">(</span><span class="n">exit</span><span class="o">.</span><span class="n">destination</span><span class="p">):</span>
|
||
<span class="c1"># we've been to the destination already, skip ahead.</span>
|
||
<span class="k">continue</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">update_pos</span><span class="p">(</span><span class="n">room</span><span class="p">,</span> <span class="n">exit</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">draw_room_on_map</span><span class="p">(</span><span class="n">exit</span><span class="o">.</span><span class="n">destination</span><span class="p">,</span> <span class="n">max_distance</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
|
||
|
||
<span class="k">def</span> <span class="nf">draw</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">):</span>
|
||
<span class="c1"># draw initial caller location on map first!</span>
|
||
<span class="k">if</span> <span class="n">room</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">location</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">start_loc_on_grid</span><span class="p">()</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span><span class="p">[</span><span class="n">room</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">curY</span><span class="p">]</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="c1"># map all other rooms</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span><span class="p">[</span><span class="n">room</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">curY</span><span class="p">]</span>
|
||
<span class="c1"># this will use the sector_type Attribute or None if not set.</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">grid</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">][</span><span class="bp">self</span><span class="o">.</span><span class="n">curY</span><span class="p">]</span> <span class="o">=</span> <span class="n">SYMBOLS</span><span class="p">[</span><span class="n">room</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">sector_type</span><span class="p">]</span>
|
||
|
||
<span class="k">def</span> <span class="nf">median</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num</span><span class="p">):</span>
|
||
<span class="n">lst</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">num</span><span class="p">))</span>
|
||
<span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">lst</span><span class="p">)</span>
|
||
<span class="n">m</span> <span class="o">=</span> <span class="n">n</span> <span class="o">-</span><span class="mi">1</span>
|
||
<span class="k">return</span> <span class="p">(</span><span class="n">lst</span><span class="p">[</span><span class="n">n</span><span class="o">//</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="n">lst</span><span class="p">[</span><span class="n">m</span><span class="o">//</span><span class="mi">2</span><span class="p">])</span> <span class="o">/</span> <span class="mf">2.0</span>
|
||
|
||
<span class="k">def</span> <span class="nf">start_loc_on_grid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">median</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_width</span><span class="p">)</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">median</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_length</span><span class="p">)</span>
|
||
<span class="c1"># x and y are floats by default, can't index lists with float types</span>
|
||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="nb">int</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">grid</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">=</span> <span class="n">SYMBOLS</span><span class="p">[</span><span class="s1">'you'</span><span class="p">]</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">curX</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">curY</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="c1"># updating worms current location</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">has_drawn</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">room</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">room</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">worm_has_mapped</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span> <span class="k">else</span> <span class="kc">False</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">create_grid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="c1"># This method simply creates an empty grid</span>
|
||
<span class="c1"># with the specified variables from __init__(self):</span>
|
||
<span class="n">board</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_width</span><span class="p">):</span>
|
||
<span class="n">board</span><span class="o">.</span><span class="n">append</span><span class="p">([])</span>
|
||
<span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max_length</span><span class="p">):</span>
|
||
<span class="n">board</span><span class="p">[</span><span class="n">row</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">' '</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">board</span>
|
||
|
||
<span class="k">def</span> <span class="nf">check_grid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="c1"># this method simply checks the grid to make sure</span>
|
||
<span class="c1"># both max_l and max_w are odd numbers</span>
|
||
<span class="k">return</span> <span class="kc">True</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_length</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">or</span> \
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">max_width</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span> <span class="k">else</span> <span class="kc">False</span>
|
||
|
||
<span class="k">def</span> <span class="nf">show_map</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="n">map_string</span> <span class="o">=</span> <span class="s2">""</span>
|
||
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">grid</span><span class="p">:</span>
|
||
<span class="n">map_string</span> <span class="o">+=</span> <span class="s2">" "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
|
||
<span class="n">map_string</span> <span class="o">+=</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span>
|
||
|
||
<span class="k">return</span> <span class="n">map_string</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="final-comments">
|
||
<h2>Final Comments<a class="headerlink" href="#final-comments" title="Permalink to this headline">¶</a></h2>
|
||
<p>The Dynamic map could be expanded with further capabilities. For example, it could mark exits or
|
||
allow NE, SE etc directions as well. It could have colors for different terrain types. One could
|
||
also look into up/down directions and figure out how to display that in a good way.</p>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
<div class="clearer"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<p class="logo"><a href="index.html">
|
||
<img class="logo" src="_static/evennia_logo.png" alt="Logo"/>
|
||
</a></p>
|
||
<div id="searchbox" style="display: none" role="search">
|
||
<h3 id="searchlabel">Quick search</h3>
|
||
<div class="searchformwrapper">
|
||
<form class="search" action="search.html" method="get">
|
||
<input type="text" name="q" aria-labelledby="searchlabel" />
|
||
<input type="submit" value="Go" />
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<script>$('#searchbox').show(0);</script>
|
||
<p><h3><a href="index.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Dynamic In Game Map</a><ul>
|
||
<li><a class="reference internal" href="#introduction">Introduction</a></li>
|
||
<li><a class="reference internal" href="#the-grid-of-rooms">The Grid of Rooms</a></li>
|
||
<li><a class="reference internal" href="#concept">Concept</a></li>
|
||
<li><a class="reference internal" href="#setting-up-the-map-display">Setting up the Map Display</a></li>
|
||
<li><a class="reference internal" href="#building-the-mapper">Building the Mapper</a></li>
|
||
<li><a class="reference internal" href="#using-the-map">Using the Map</a></li>
|
||
<li><a class="reference internal" href="#final-comments">Final Comments</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<div role="note" aria-label="source link">
|
||
<!--h3>This Page</h3-->
|
||
<ul class="this-page-menu">
|
||
<li><a href="_sources/Dynamic-In-Game-Map.md.txt"
|
||
rel="nofollow">Show Page Source</a></li>
|
||
</ul>
|
||
</div><h3>Links</h3>
|
||
<ul>
|
||
<li><a href="https://www.evennia.com">Home page</a> </li>
|
||
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
|
||
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
||
<li><a href="http://webchat.freenode.net/?channels=evennia&uio=MT1mYWxzZSY5PXRydWUmMTE9MTk1JjEyPXRydWUbb">IRC</a> -
|
||
<a href="https://discord.gg/NecFePw">Discord</a> -
|
||
<a href="https://groups.google.com/forum/#%21forum/evennia">Forums</a>
|
||
</li>
|
||
<li><a href="http://evennia.blogspot.com/">Evennia Dev blog</a> </li>
|
||
</ul>
|
||
<h3>Versions</h3>
|
||
<ul>
|
||
<li><a href="../1.0-dev/index.html">1.0-dev (develop branch)</a></li>
|
||
<li><a href="Dynamic-In-Game-Map.html">0.9.5 (v0.9.5 branch)</a></li>
|
||
</ul>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="genindex.html" title="General Index"
|
||
>index</a></li>
|
||
<li class="right" >
|
||
<a href="py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="index.html">Evennia 0.9.5</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Dynamic In Game Map</a></li>
|
||
</ul>
|
||
</div>
|
||
<div class="footer" role="contentinfo">
|
||
© Copyright 2020, The Evennia developer community.
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||
</div>
|
||
</body>
|
||
</html> |