mirror of
https://github.com/evennia/evennia.git
synced 2026-03-24 00:36:30 +01:00
Updated HTML docs.
This commit is contained in:
parent
324a3b2537
commit
e535f5782a
2388 changed files with 54506 additions and 24460 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,326 +0,0 @@
|
|||
|
||||
<!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>Continuous Integration - TeamCity (linux) — Evennia 1.0 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="Setting up PyCharm with Evennia" href="Setting-up-PyCharm.html" />
|
||||
<link rel="prev" title="Continuous integration with Travis" href="Continuous-Integration-Travis.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="Setting-up-PyCharm.html" title="Setting up PyCharm with Evennia"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Continuous-Integration-Travis.html" title="Continuous integration with Travis"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="Continuous-Integration.html" accesskey="U">Continuous Integration (CI)</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Continuous Integration - TeamCity (linux)</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="#">Continuous Integration - TeamCity (linux)</a><ul>
|
||||
<li><a class="reference internal" href="#prerequisites">Prerequisites</a></li>
|
||||
<li><a class="reference internal" href="#a-quick-overview">A Quick Overview</a></li>
|
||||
<li><a class="reference internal" href="#template-setup">Template Setup</a><ul>
|
||||
<li><a class="reference internal" href="#creating-the-project">Creating the Project</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="Continuous-Integration-Travis.html"
|
||||
title="previous chapter">Continuous integration with Travis</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="Setting-up-PyCharm.html"
|
||||
title="next chapter">Setting up PyCharm with Evennia</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Continuous-Integration-TeamCity.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="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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Continuous-Integration-TeamCity.html">1.0 (develop branch)</a></li>
|
||||
<ul>
|
||||
<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="continuous-integration-teamcity-linux">
|
||||
<h1>Continuous Integration - TeamCity (linux)<a class="headerlink" href="#continuous-integration-teamcity-linux" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This sets up a TeamCity build integration environment on Linux.</p>
|
||||
<section id="prerequisites">
|
||||
<h2>Prerequisites<a class="headerlink" href="#prerequisites" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li><p>Follow <a class="reference external" href="https://www.jetbrains.com/teamcity/">TeamCity</a> ‘s in-depth
|
||||
<a class="reference external" href="https://confluence.jetbrains.com/display/TCD8/Installing+and+Configuring+the+TeamCity+Server">Setup Guide</a>.</p></li>
|
||||
<li><p>You need to use <a class="reference internal" href="Version-Control.html"><span class="doc std std-doc">Version Control</span></a>.</p></li>
|
||||
</ul>
|
||||
<p>After meeting the preparation steps for your specific environment, log on to your teamcity interface
|
||||
at <code class="docutils literal notranslate"><span class="pre">http://<your</span> <span class="pre">server>:8111/</span></code>.</p>
|
||||
<p>Create a new project named “Evennia” and in it construct a new template called <code class="docutils literal notranslate"><span class="pre">continuous-integration</span></code>.</p>
|
||||
</section>
|
||||
<section id="a-quick-overview">
|
||||
<h2>A Quick Overview<a class="headerlink" href="#a-quick-overview" title="Permalink to this headline">¶</a></h2>
|
||||
<p><em>Templates</em> are fancy objects in TeamCity that allow an administrator to define build steps that are
|
||||
shared between one or more build projects. Assigning a VCS Root (Source Control) is unnecessary at
|
||||
this stage, primarily you’ll be worrying about the build steps and your default parameters (both
|
||||
visible on the tabs to the left.)</p>
|
||||
</section>
|
||||
<section id="template-setup">
|
||||
<h2>Template Setup<a class="headerlink" href="#template-setup" title="Permalink to this headline">¶</a></h2>
|
||||
<p>In this template, you’ll be outlining the steps necessary to build your specific game. (A number of
|
||||
sample scripts are provided under this section below!) Click Build Steps and prepare your general
|
||||
flow. For this example, we will be doing a few basic example steps:</p>
|
||||
<ul class="simple">
|
||||
<li><p>Transforming the <a class="reference external" href="http://Settings.py">Settings.py</a> file - We do this to update ports or other information that make your production
|
||||
environment unique from your development environment.</p></li>
|
||||
<li><p>Making migrations and migrating the game database.</p></li>
|
||||
<li><p>Publishing the game files.</p></li>
|
||||
<li><p>Reloading the server.</p></li>
|
||||
</ul>
|
||||
<p>For each step we’ll being use the “Command Line Runner” (a fancy name for a shell script executor).</p>
|
||||
<p>Create a build step with the name: “Transform Configuration” and add the script:</p>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
|
||||
<span class="c1"># Replaces the game configuration with one </span>
|
||||
<span class="c1"># appropriate for this deployment.</span>
|
||||
|
||||
<span class="nv">CONFIG</span><span class="o">=</span><span class="s2">"%system.teamcity.build.checkoutDir%/server/conf/settings.py"</span>
|
||||
<span class="nv">MYCONF</span><span class="o">=</span><span class="s2">"%system.teamcity.build.checkoutDir%/server/conf/my.cnf"</span>
|
||||
|
||||
sed<span class="w"> </span>-e<span class="w"> </span><span class="s1">'s/TELNET_PORTS = [4000]/TELNET_PORTS = [%game.ports%]/g'</span><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span><span class="w"> </span>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>.tmp<span class="w"> </span><span class="o">&&</span><span class="w"> </span>mv
|
||||
<span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>.tmp<span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
sed<span class="w"> </span>-e<span class="w"> </span><span class="s1">'s/WEBSERVER_PORTS = [(4001, 4002)]/WEBSERVER_PORTS = [%game.webports%]/g'</span><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span><span class="w"> </span>>
|
||||
<span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>.tmp<span class="w"> </span><span class="o">&&</span><span class="w"> </span>mv<span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>.tmp<span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># settings.py MySQL DB configuration</span>
|
||||
<span class="nb">echo</span><span class="w"> </span>Configuring<span class="w"> </span>Game<span class="w"> </span>Database...
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">""</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">"######################################################################"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">"# MySQL Database Configuration"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">"######################################################################"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">"DATABASES = {"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">" 'default': {"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">" 'ENGINE': 'django.db.backends.mysql',"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">" 'OPTIONS': {"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">" 'read_default_file': 'server/conf/my.cnf',"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">" },"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">" }"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">"}"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$CONFIG</span><span class="s2">"</span>
|
||||
|
||||
<span class="c1"># Create the My.CNF file.</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">"[client]"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$MYCONF</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">"database = %mysql.db%"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$MYCONF</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">"user = %mysql.user%"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$MYCONF</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">"password = %mysql.pass%"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$MYCONF</span><span class="s2">"</span>
|
||||
<span class="nb">echo</span><span class="w"> </span><span class="s2">"default-character-set = utf8"</span><span class="w"> </span>>><span class="w"> </span><span class="s2">"</span><span class="nv">$MYCONF</span><span class="s2">"</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you look at the parameters side of the page after saving this script, you’ll notice that some new
|
||||
parameters have been populated for you. This is because we’ve included new teamcity configuration
|
||||
parameters that are populated when the build itself is ran. When creating projects that inherit this
|
||||
template, we’ll be able to fill in or override those parameters for project-specific configuration.</p>
|
||||
<p>Go ahead and create another build step called “Make Database Migration”
|
||||
If you’re using Sqlite3 for your game (default database), it’s prudent to change working directory on this
|
||||
step to your game dir.</p>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
|
||||
<span class="c1"># Update the DB migration</span>
|
||||
|
||||
<span class="nv">LOGDIR</span><span class="o">=</span><span class="s2">"server/logs"</span>
|
||||
|
||||
.<span class="w"> </span>%evenv.dir%/bin/activate
|
||||
|
||||
<span class="c1"># Check that the logs directory exists.</span>
|
||||
<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>!<span class="w"> </span>-d<span class="w"> </span><span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
|
||||
<span class="w"> </span><span class="c1"># Control will enter here if $LOGDIR doesn't exist.</span>
|
||||
<span class="w"> </span>mkdir<span class="w"> </span><span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span>
|
||||
<span class="k">fi</span>
|
||||
|
||||
evennia<span class="w"> </span>makemigrations
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Create yet another build step, this time named: “Execute Database Migration”:
|
||||
If you’re using Sqlite3 for your game (default database), it’s prudent to change working directory on this
|
||||
step to your game dir.</p>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
|
||||
<span class="c1"># Apply the database migration.</span>
|
||||
<span class="w"> </span>
|
||||
<span class="nv">LOGDIR</span><span class="o">=</span><span class="s2">"server/logs"</span>
|
||||
<span class="w"> </span>
|
||||
.<span class="w"> </span>%evenv.dir%/bin/activate
|
||||
<span class="w"> </span>
|
||||
<span class="c1"># Check that the logs directory exists.</span>
|
||||
<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>!<span class="w"> </span>-d<span class="w"> </span><span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
|
||||
<span class="w"> </span><span class="c1"># Control will enter here if $LOGDIR doesn't exist.</span>
|
||||
<span class="w"> </span>mkdir<span class="w"> </span><span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span>
|
||||
<span class="k">fi</span>
|
||||
<span class="w"> </span>
|
||||
evennia<span class="w"> </span>migrate
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Our next build step is where we actually publish our build. Up until now, all work on game has been
|
||||
done in a ‘work’ directory on TeamCity’s build agent. From that directory we will now copy our files
|
||||
to where our game actually exists on the local server.</p>
|
||||
<p>Create a new build step called “Publish Build”. If you’re using SQlite3 on your game, be sure to order this step ABOVE
|
||||
the Database Migration steps. The build order will matter!</p>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
|
||||
<span class="c1"># Publishes the build to the proper build directory.</span>
|
||||
<span class="w"> </span>
|
||||
<span class="nv">DIRECTORY</span><span class="o">=</span><span class="s2">"<game_dir>"</span>
|
||||
<span class="w"> </span>
|
||||
<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>!<span class="w"> </span>-d<span class="w"> </span><span class="s2">"</span><span class="nv">$DIRECTORY</span><span class="s2">"</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
|
||||
<span class="w"> </span><span class="c1"># Control will enter here if $DIRECTORY doesn't exist.</span>
|
||||
<span class="w"> </span>mkdir<span class="w"> </span><span class="s2">"</span><span class="nv">$DIRECTORY</span><span class="s2">"</span>
|
||||
<span class="k">fi</span>
|
||||
<span class="w"> </span>
|
||||
<span class="c1"># Copy all the files.</span>
|
||||
cp<span class="w"> </span>-ruv<span class="w"> </span>%teamcity.build.checkoutDir%/*<span class="w"> </span><span class="s2">"</span><span class="nv">$DIRECTORY</span><span class="s2">"</span>
|
||||
chmod<span class="w"> </span>-R<span class="w"> </span><span class="m">775</span><span class="w"> </span><span class="s2">"</span><span class="nv">$DIRECTORY</span><span class="s2">"</span>
|
||||
<span class="w"> </span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Finally the last script will reload our game for us.</p>
|
||||
<p>Create a new script called “Reload Game”:
|
||||
The working directory on this build step will be: <code class="docutils literal notranslate"><span class="pre">%game.dir%</span></code></p>
|
||||
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/bin/bash</span>
|
||||
<span class="c1"># Apply the database migration.</span>
|
||||
|
||||
<span class="nv">LOGDIR</span><span class="o">=</span><span class="s2">"server/logs"</span>
|
||||
<span class="nv">PIDDIR</span><span class="o">=</span><span class="s2">"server/server.pid"</span>
|
||||
|
||||
.<span class="w"> </span>%evenv.dir%/bin/activate
|
||||
|
||||
<span class="c1"># Check that the logs directory exists.</span>
|
||||
<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>!<span class="w"> </span>-d<span class="w"> </span><span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
|
||||
<span class="w"> </span><span class="c1"># Control will enter here if $LOGDIR doesn't exist.</span>
|
||||
<span class="w"> </span>mkdir<span class="w"> </span><span class="s2">"</span><span class="nv">$LOGDIR</span><span class="s2">"</span>
|
||||
<span class="k">fi</span>
|
||||
|
||||
<span class="c1"># Check that the server is running.</span>
|
||||
<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>-d<span class="w"> </span><span class="s2">"</span><span class="nv">$PIDDIR</span><span class="s2">"</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
|
||||
<span class="w"> </span><span class="c1"># Control will enter here if the game is running.</span>
|
||||
<span class="w"> </span>evennia<span class="w"> </span>reload
|
||||
<span class="k">fi</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now the template is ready for use! It would be useful this time to revisit the parameters page and
|
||||
set the evenv parameter to the directory where your virtualenv exists: IE “/srv/mush/evenv”.</p>
|
||||
<section id="creating-the-project">
|
||||
<h3>Creating the Project<a class="headerlink" href="#creating-the-project" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Now it’s time for the last few steps to set up a CI environment.</p>
|
||||
<ul class="simple">
|
||||
<li><p>Return to the Evennia Project overview/administration page.</p></li>
|
||||
<li><p>Create a new Sub-Project called “Production”. This will be the category that holds our actual game.</p></li>
|
||||
<li><p>Create a new Build Configuration in Production with the name of your MUSH. Base this configuration off of the
|
||||
continuous-integration template we made earlier.</p></li>
|
||||
<li><p>In the build configuration, enter VCS roots and create a new VCS root that points to the
|
||||
branch/version control that you are using.</p></li>
|
||||
<li><p>Go to the parameters page and fill in the undefined parameters for your specific configuration.</p></li>
|
||||
<li><p>If you wish for the CI to run every time a commit is made, go to the VCS triggers and add one for
|
||||
“On Every Commit”.</p></li>
|
||||
</ul>
|
||||
<p>And you’re done! At this point, you can return to the project overview page and queue a new build
|
||||
for your game. If everything was set up correctly, the build will complete successfully. Additional
|
||||
build steps could be added or removed at this point, adding some features like Unit Testing or more!</p>
|
||||
</section>
|
||||
</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="Setting-up-PyCharm.html" title="Setting up PyCharm with Evennia"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Continuous-Integration-Travis.html" title="Continuous integration with Travis"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="Continuous-Integration.html" >Continuous Integration (CI)</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Continuous Integration - TeamCity (linux)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2022, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
|
||||
<!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>Continuous integration with Travis — Evennia 1.0 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="Continuous Integration - TeamCity (linux)" href="Continuous-Integration-TeamCity.html" />
|
||||
<link rel="prev" title="Continuous Integration (CI)" href="Continuous-Integration.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="Continuous-Integration-TeamCity.html" title="Continuous Integration - TeamCity (linux)"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Continuous-Integration.html" title="Continuous Integration (CI)"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="Continuous-Integration.html" accesskey="U">Continuous Integration (CI)</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Continuous integration with Travis</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>
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="Continuous-Integration.html"
|
||||
title="previous chapter">Continuous Integration (CI)</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="Continuous-Integration-TeamCity.html"
|
||||
title="next chapter">Continuous Integration - TeamCity (linux)</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Coding/Continuous-Integration-Travis.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="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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Continuous-Integration-Travis.html">1.0 (develop branch)</a></li>
|
||||
<ul>
|
||||
<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="continuous-integration-with-travis">
|
||||
<h1>Continuous integration with Travis<a class="headerlink" href="#continuous-integration-with-travis" title="Permalink to this headline">¶</a></h1>
|
||||
<p><a class="reference external" href="https://travis-ci.org/">Travis CI</a> is an online service for checking, validating and potentially
|
||||
deploying code automatically. It can check that every commit is building successfully after every
|
||||
commit to its Github repository.</p>
|
||||
<p>If your game is open source on Github you may use Travis for free.
|
||||
See [the Travis docs](<a class="reference external" href="https://docs.travis-ci.com/user/getting-">https://docs.travis-ci.com/user/getting-</a> started/) for how to get started.</p>
|
||||
<p>After logging in you will get to point Travis to your repository on github. One further thing you
|
||||
need to set up yourself is a Travis config file named <code class="docutils literal notranslate"><span class="pre">.travis.yml</span></code> (note the initial period <code class="docutils literal notranslate"><span class="pre">.</span></code>).
|
||||
This should be created in the root of your game directory. The idea with this file is that it
|
||||
describes what Travis needs to import and build in order to create an instance of Evennia from
|
||||
scratch and then run validation tests on it. Here is an example:</p>
|
||||
<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">python</span>
|
||||
<span class="nt">python</span><span class="p">:</span>
|
||||
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="s">"3.10"</span>
|
||||
<span class="nt">install</span><span class="p">:</span>
|
||||
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">git clone https://github.com/evennia/evennia.git</span>
|
||||
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">cd evennia</span>
|
||||
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pip install -e .</span>
|
||||
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">cd $TRAVIS_BUILD_DIR</span>
|
||||
<span class="nt">script</span><span class="p">:</span>
|
||||
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">evennia migrate</span>
|
||||
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">evennia test --settings settings.py .</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will tell travis how to download Evennia, install it, set up a database and then run
|
||||
your own test suite (inside the game dir). Use <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">test</span> <span class="pre">evennia</span></code> if you also want to
|
||||
run the Evennia full test suite.</p>
|
||||
<p>You need to add this file to git (<code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">add</span> <span class="pre">.travis.yml</span></code>) and then commit your changes before Travis
|
||||
will be able to see it.</p>
|
||||
<p>For properly testing your game you of course also need to write unittests.
|
||||
The <a class="reference internal" href="Unit-Testing.html"><span class="doc std std-doc">Unit testing</span></a> doc page gives some ideas on how to set those up for Evennia.
|
||||
You should be able to refer to that for making tests fitting your game.</p>
|
||||
</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="Continuous-Integration-TeamCity.html" title="Continuous Integration - TeamCity (linux)"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Continuous-Integration.html" title="Continuous Integration (CI)"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="Continuous-Integration.html" >Continuous Integration (CI)</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Continuous integration with Travis</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2022, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,206 +0,0 @@
|
|||
|
||||
<!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>Dice roller — Evennia 1.0 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="Health Bar" href="Contrib-Health-Bar.html" />
|
||||
<link rel="prev" title="Character Creator" href="Contrib-Character-Creator.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="Contrib-Health-Bar.html" title="Health Bar"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Contrib-Character-Creator.html" title="Character Creator"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" accesskey="U">Contribs</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Dice roller</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="#">Dice roller</a><ul>
|
||||
<li><a class="reference internal" href="#installation">Installation:</a></li>
|
||||
<li><a class="reference internal" href="#usage">Usage:</a><ul>
|
||||
<li><a class="reference internal" href="#rolling-dice-from-code">Rolling dice from code</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="Contrib-Character-Creator.html"
|
||||
title="previous chapter">Character Creator</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="Contrib-Health-Bar.html"
|
||||
title="next chapter">Health Bar</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Contribs/Contrib-Dice.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="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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Contrib-Dice.html">1.0 (develop branch)</a></li>
|
||||
<ul>
|
||||
<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="dice-roller">
|
||||
<h1>Dice roller<a class="headerlink" href="#dice-roller" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Contribution by Griatch, 2012</p>
|
||||
<p>A dice roller for any number and side of dice. Adds in-game dice rolling
|
||||
(<code class="docutils literal notranslate"><span class="pre">roll</span> <span class="pre">2d10</span> <span class="pre">+</span> <span class="pre">1</span></code>) as well as conditionals (roll under/over/equal to a target)
|
||||
and functions for rolling dice in code. Command also supports hidden or secret
|
||||
rolls for use by a human game master.</p>
|
||||
<section id="installation">
|
||||
<h2>Installation:<a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Add the <code class="docutils literal notranslate"><span class="pre">CmdDice</span></code> command from this module to your character’s cmdset
|
||||
(and then restart the server):</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># in mygame/commands/default_cmdsets.py</span>
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.contrib.rpg</span> <span class="kn">import</span> <span class="n">dice</span> <span class="o"><---</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_object_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="c1"># ...</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">dice</span><span class="o">.</span><span class="n">CmdDice</span><span class="p">())</span> <span class="c1"># <---</span>
|
||||
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="usage">
|
||||
<h2>Usage:<a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> roll 1d100 + 2
|
||||
> roll 1d20
|
||||
> roll 1d20 - 4
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The result of the roll will be echoed to the room</p>
|
||||
<p>One can also specify a standard Python operator in order to specify
|
||||
eventual target numbers and get results in a fair and guaranteed
|
||||
unbiased way. For example:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> roll 2d6 + 2 < 8
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Rolling this will inform all parties if roll was indeed below 8 or not.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> roll/hidden
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Informs the room that the roll is being made without telling what the result
|
||||
was.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> roll/secret
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Is a hidden roll that does not inform the room it happened.</p>
|
||||
<section id="rolling-dice-from-code">
|
||||
<h3>Rolling dice from code<a class="headerlink" href="#rolling-dice-from-code" title="Permalink to this headline">¶</a></h3>
|
||||
<p>To roll dice in code, use the <code class="docutils literal notranslate"><span class="pre">roll</span></code> function from this module:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.contrib.rpg</span> <span class="kn">import</span> <span class="n">dice</span>
|
||||
<span class="n">dice</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="p">(</span><span class="s2">"+"</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> <span class="c1"># 3d10 + 2</span>
|
||||
|
||||
</pre></div>
|
||||
</div>
|
||||
<hr class="docutils" />
|
||||
<p><small>This document page is generated from <code class="docutils literal notranslate"><span class="pre">evennia/contrib/rpg/dice/README.md</span></code>. Changes to this
|
||||
file will be overwritten, so edit that file rather than this one.</small></p>
|
||||
</section>
|
||||
</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="Contrib-Health-Bar.html" title="Health Bar"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Contrib-Character-Creator.html" title="Character Creator"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" >Contribs</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Dice roller</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2022, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
|
||||
<!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>Extended Room — Evennia 1.0 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="Basic Map" href="Contrib-Ingame-Map-Display.html" />
|
||||
<link rel="prev" title="Turn based battle system framework" href="Contrib-Turnbattle.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="Contrib-Ingame-Map-Display.html" title="Basic Map"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Contrib-Turnbattle.html" title="Turn based battle system framework"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" accesskey="U">Contribs</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Extended Room</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="#">Extended Room</a><ul>
|
||||
<li><a class="reference internal" href="#installation-testing">Installation/testing:</a></li>
|
||||
<li><a class="reference internal" href="#features">Features</a><ul>
|
||||
<li><a class="reference internal" href="#time-changing-description-slots">Time-changing description slots</a></li>
|
||||
<li><a class="reference internal" href="#in-description-changing-tags">In-description changing tags</a></li>
|
||||
<li><a class="reference internal" href="#details">Details</a></li>
|
||||
<li><a class="reference internal" href="#extra-commands">Extra commands</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="Contrib-Turnbattle.html"
|
||||
title="previous chapter">Turn based battle system framework</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="Contrib-Ingame-Map-Display.html"
|
||||
title="next chapter">Basic Map</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../_sources/Contribs/Contrib-Extended-Room.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="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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Contrib-Extended-Room.html">1.0 (develop branch)</a></li>
|
||||
<ul>
|
||||
<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="extended-room">
|
||||
<h1>Extended Room<a class="headerlink" href="#extended-room" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Contribution - Griatch 2012, vincent-lg 2019</p>
|
||||
<p>This extends the normal <code class="docutils literal notranslate"><span class="pre">Room</span></code> typeclass to allow its description to change
|
||||
with time-of-day and/or season. It also adds ‘details’ for the player to look at
|
||||
in the room (without having to create a new in-game object for each). The room is
|
||||
supported by new <code class="docutils literal notranslate"><span class="pre">look</span></code> and <code class="docutils literal notranslate"><span class="pre">desc</span></code> commands.</p>
|
||||
<section id="installation-testing">
|
||||
<h2>Installation/testing:<a class="headerlink" href="#installation-testing" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Adding the <code class="docutils literal notranslate"><span class="pre">ExtendedRoomCmdset</span></code> to the default character cmdset will add all
|
||||
new commands for use.</p>
|
||||
<p>In more detail, in <code class="docutils literal notranslate"><span class="pre">mygame/commands/default_cmdsets.py</span></code>:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="o">...</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.contrib</span> <span class="kn">import</span> <span class="n">extended_room</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">Character_CmdSet</span><span class="p">):</span>
|
||||
<span class="o">...</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="o">...</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">ExtendedRoomCmdSet</span><span class="p">)</span> <span class="c1"># <---</span>
|
||||
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Then reload to make the new commands available. Note that they only work
|
||||
on rooms with the typeclass <code class="docutils literal notranslate"><span class="pre">ExtendedRoom</span></code>. Create new rooms with the right
|
||||
typeclass or use the <code class="docutils literal notranslate"><span class="pre">typeclass</span></code> command to swap existing rooms.</p>
|
||||
</section>
|
||||
<section id="features">
|
||||
<h2>Features<a class="headerlink" href="#features" title="Permalink to this headline">¶</a></h2>
|
||||
<section id="time-changing-description-slots">
|
||||
<h3>Time-changing description slots<a class="headerlink" href="#time-changing-description-slots" title="Permalink to this headline">¶</a></h3>
|
||||
<p>This allows to change the full description text the room shows
|
||||
depending on larger time variations. Four seasons (spring, summer,
|
||||
autumn and winter) are used by default. The season is calculated
|
||||
on-demand (no Script or timer needed) and updates the full text block.</p>
|
||||
<p>There is also a general description which is used as fallback if
|
||||
one or more of the seasonal descriptions are not set when their
|
||||
time comes.</p>
|
||||
<p>An updated <code class="docutils literal notranslate"><span class="pre">desc</span></code> command allows for setting seasonal descriptions.</p>
|
||||
<p>The room uses the <code class="docutils literal notranslate"><span class="pre">evennia.utils.gametime.GameTime</span></code> global script. This is
|
||||
started by default, but if you have deactivated it, you need to
|
||||
supply your own time keeping mechanism.</p>
|
||||
</section>
|
||||
<section id="in-description-changing-tags">
|
||||
<h3>In-description changing tags<a class="headerlink" href="#in-description-changing-tags" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Within each seasonal (or general) description text, you can also embed
|
||||
time-of-day dependent sections. Text inside such a tag will only show
|
||||
during that particular time of day. The tags looks like <code class="docutils literal notranslate"><span class="pre"><timeslot></span> <span class="pre">...</span> <span class="pre"></timeslot></span></code>. By default there are four timeslots per day - morning,
|
||||
afternoon, evening and night.</p>
|
||||
</section>
|
||||
<section id="details">
|
||||
<h3>Details<a class="headerlink" href="#details" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The Extended Room can be “detailed” with special keywords. This makes
|
||||
use of a special <code class="docutils literal notranslate"><span class="pre">Look</span></code> command. Details are “virtual” targets to look
|
||||
at, without there having to be a database object created for it. The
|
||||
Details are simply stored in a dictionary on the room and if the look
|
||||
command cannot find an object match for a <code class="docutils literal notranslate"><span class="pre">look</span> <span class="pre"><target></span></code> command it
|
||||
will also look through the available details at the current location
|
||||
if applicable. The <code class="docutils literal notranslate"><span class="pre">detail</span></code> command is used to change details.</p>
|
||||
</section>
|
||||
<section id="extra-commands">
|
||||
<h3>Extra commands<a class="headerlink" href="#extra-commands" title="Permalink to this headline">¶</a></h3>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">CmdExtendedRoomLook</span></code> - look command supporting room details</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">CmdExtendedRoomDesc</span></code> - desc command allowing to add seasonal descs,</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">CmdExtendedRoomDetail</span></code> - command allowing to manipulate details in this room
|
||||
as well as listing them</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">CmdExtendedRoomGameTime</span></code> - A simple <code class="docutils literal notranslate"><span class="pre">time</span></code> command, displaying the current
|
||||
time and season.</p></li>
|
||||
</ul>
|
||||
<hr class="docutils" />
|
||||
<p><small>This document page is generated from <code class="docutils literal notranslate"><span class="pre">evennia/contrib/grid/extended_room/README.md</span></code>. Changes to this
|
||||
file will be overwritten, so edit that file rather than this one.</small></p>
|
||||
</section>
|
||||
</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="Contrib-Ingame-Map-Display.html" title="Basic Map"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Contrib-Turnbattle.html" title="Turn based battle system framework"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="Contribs-Overview.html" >Contribs</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">Extended Room</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2022, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,440 +0,0 @@
|
|||
|
||||
<!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>1. Using commands and building stuff — Evennia 1.0 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="2. The Tutorial World" href="Beginner-Tutorial-Tutorial-World.html" />
|
||||
<link rel="prev" title="Part 1: What we have" href="Beginner-Tutorial-Part1-Overview.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="Beginner-Tutorial-Tutorial-World.html" title="2. The Tutorial World"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Beginner-Tutorial-Part1-Overview.html" title="Part 1: What we have"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="../../Howtos-Overview.html" >Tutorials and Howto’s</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="../Beginner-Tutorial-Overview.html" >Beginner Tutorial</a> »</li>
|
||||
<li class="nav-item nav-item-3"><a href="Beginner-Tutorial-Part1-Overview.html" accesskey="U">Part 1: What we have</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href=""><span class="section-number">1. </span>Using commands and building stuff</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="#">1. Using commands and building stuff</a><ul>
|
||||
<li><a class="reference internal" href="#getting-help">1.1. Getting help</a></li>
|
||||
<li><a class="reference internal" href="#looking-around">1.2. Looking around</a></li>
|
||||
<li><a class="reference internal" href="#stepping-down-from-godhood">1.3. Stepping Down From Godhood</a></li>
|
||||
<li><a class="reference internal" href="#creating-an-object">1.4. Creating an Object</a></li>
|
||||
<li><a class="reference internal" href="#get-a-personality">1.5. Get a Personality</a></li>
|
||||
<li><a class="reference internal" href="#pushing-your-buttons">1.6. Pushing Your Buttons</a></li>
|
||||
<li><a class="reference internal" href="#making-yourself-a-house">1.7. Making Yourself a House</a></li>
|
||||
<li><a class="reference internal" href="#reshuffling-the-world">1.8. Reshuffling the World</a></li>
|
||||
<li><a class="reference internal" href="#adding-a-help-entry">1.9. Adding a Help Entry</a></li>
|
||||
<li><a class="reference internal" href="#adding-a-world">1.10. Adding a World</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="Beginner-Tutorial-Part1-Overview.html"
|
||||
title="previous chapter">Part 1: What we have</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="Beginner-Tutorial-Tutorial-World.html"
|
||||
title="next chapter"><span class="section-number">2. </span>The Tutorial World</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../../../_sources/Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Building-Quickstart.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="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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Beginner-Tutorial-Building-Quickstart.html">1.0 (develop branch)</a></li>
|
||||
<ul>
|
||||
<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="using-commands-and-building-stuff">
|
||||
<h1><span class="section-number">1. </span>Using commands and building stuff<a class="headerlink" href="#using-commands-and-building-stuff" title="Permalink to this headline">¶</a></h1>
|
||||
<p>In this lesson, we will test out what we can do in-game out-of-the-box. Evennia ships with
|
||||
<a class="reference internal" href="../../../Components/Default-Commands.html"><span class="doc std std-doc">around 90 default commands</span></a>, and while you can override those as you please,
|
||||
the defaults can be quite useful.</p>
|
||||
<p>Connect and log into your new game and you will end up in the “Limbo” location. This
|
||||
is the only room in the game at this point. Let’s explore the commands a little.</p>
|
||||
<p>The default commands has syntax <a class="reference internal" href="../../../Coding/Default-Command-Syntax.html"><span class="doc std std-doc">similar to MUX</span></a>:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> command[/switch/switch...] [arguments ...]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>An example would be</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> create/drop box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>A <em>/switch</em> is a special, optional flag to the command to make it behave differently. It is always
|
||||
put directly after the command name, and begins with a forward slash (<code class="docutils literal notranslate"><span class="pre">/</span></code>). The <em>arguments</em> are one
|
||||
or more inputs to the commands. It’s common to use an equal sign (<code class="docutils literal notranslate"><span class="pre">=</span></code>) when assigning something to
|
||||
an object.</p>
|
||||
<blockquote>
|
||||
<div><p>Are you used to commands starting with @, like @create? That will work too. Evennia simply ignores
|
||||
the preceeding @.</p>
|
||||
</div></blockquote>
|
||||
<section id="getting-help">
|
||||
<h2><span class="section-number">1.1. </span>Getting help<a class="headerlink" href="#getting-help" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>help
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Will give you a list of all commands available to you. Use</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>help <commandname>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>to see the in-game help for that command.</p>
|
||||
</section>
|
||||
<section id="looking-around">
|
||||
<h2><span class="section-number">1.2. </span>Looking around<a class="headerlink" href="#looking-around" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The most common comman is</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>look
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will show you the description of the current location. <code class="docutils literal notranslate"><span class="pre">l</span></code> is an alias.</p>
|
||||
<p>When targeting objects in commands, you have two special labels you can use, <code class="docutils literal notranslate"><span class="pre">here</span></code> for the current
|
||||
room or <code class="docutils literal notranslate"><span class="pre">me</span></code>/<code class="docutils literal notranslate"><span class="pre">self</span></code> to point back to yourself. So</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>look me
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>will give you your own description. <code class="docutils literal notranslate"><span class="pre">look</span> <span class="pre">here</span></code> is, in this case, the same as plain <code class="docutils literal notranslate"><span class="pre">look</span></code>.</p>
|
||||
</section>
|
||||
<section id="stepping-down-from-godhood">
|
||||
<h2><span class="section-number">1.3. </span>Stepping Down From Godhood<a class="headerlink" href="#stepping-down-from-godhood" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If you just installed Evennia, your very first player account is called user #1, also known as the
|
||||
<em>superuser</em> or <em>god user</em>. This user is very powerful, so powerful that it will override many game
|
||||
restrictions (such as locks). This can be useful, but it also hides some functionality that you might
|
||||
want to test.</p>
|
||||
<p>To temporarily step down from your superuser position, you can use the <code class="docutils literal notranslate"><span class="pre">quell</span></code> command in-game:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>quell
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will make you start using the permission of your current character’s level instead of your
|
||||
superuser level. If you didn’t change any settings, your game Character should have an <em>Developer</em>
|
||||
level permission - high as can be without bypassing locks like the superuser does. This will work
|
||||
fine for the examples on this page. Use</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>unquell
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>to get superuser status again when you are done.</p>
|
||||
</section>
|
||||
<section id="creating-an-object">
|
||||
<h2><span class="section-number">1.4. </span>Creating an Object<a class="headerlink" href="#creating-an-object" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Basic objects can be anything – swords, flowers, and non-player characters. They are created using
|
||||
the <code class="docutils literal notranslate"><span class="pre">create</span></code> command:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>create box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This created a new ‘box’ (of the default object type) in your inventory. Use the command <code class="docutils literal notranslate"><span class="pre">inventory</span></code>
|
||||
(or <code class="docutils literal notranslate"><span class="pre">i</span></code>) to see it. Now, ‘box’ is a rather short name, let’s rename it and tack on a few aliases.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>name box = very large box;box;very;crate
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Warning</p>
|
||||
<p>MUD clients and semi-colon:
|
||||
Some traditional MUD clients use the semi-colon <code class="docutils literal notranslate"><span class="pre">;</span></code> to separate client inputs. If so,
|
||||
the above line will give an error. You need to change your client to use another command-separator
|
||||
or to put it in ‘verbatim’ mode. If you still have trouble, use the Evennia web client instead.</p>
|
||||
</div>
|
||||
<p>We now renamed the box to <em>very large box</em> (and this is what we will see when looking at it), but we
|
||||
will also recognize it by any of the other names we give - like <em>crate</em> or simply <em>box</em> as before.
|
||||
We could have given these aliases directly after the name in the <code class="docutils literal notranslate"><span class="pre">create</span></code> command. This is true for
|
||||
all creation commands - you can always tag on a list of <code class="docutils literal notranslate"><span class="pre">;</span></code>-separated aliases to the name of your
|
||||
new object. If you had wanted to not change the name itself, but to only add aliases, you could have
|
||||
used the <code class="docutils literal notranslate"><span class="pre">alias</span></code> command.</p>
|
||||
<p>We are currently carrying the box. Let’s drop it (there is also a shortcut to create and drop in
|
||||
one go by using the <code class="docutils literal notranslate"><span class="pre">/drop</span></code> switch, for example <code class="docutils literal notranslate"><span class="pre">create/drop</span> <span class="pre">box</span></code>).</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>drop box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Hey presto - there it is on the ground, in all its normality.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>examine box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will show some technical details about the box object. For now we will ignore what this
|
||||
information means.</p>
|
||||
<p>Try to <code class="docutils literal notranslate"><span class="pre">look</span></code> at the box to see the (default) description.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>look box
|
||||
You see nothing special.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The description you get is not very exciting. Let’s add some flavor.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>desc box = This is a large and very heavy box.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you try the <code class="docutils literal notranslate"><span class="pre">get</span></code> command, we will pick up the box. So far so good, but if we really want this to
|
||||
be a large and heavy box, people should <em>not</em> be able to run off with it that easily. To prevent
|
||||
this we need to lock it down. This is done by assigning a <em>Lock</em> to it. Make sure the box was
|
||||
dropped in the room, then try this:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>lock box = get:false()
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Locks represent a rather <a class="reference internal" href="../../../Components/Locks.html"><span class="doc std std-doc">big topic</span></a>, but for now that will do what we want. This will lock
|
||||
the box so noone can lift it. The exception is superusers, they override all locks and will pick it
|
||||
up anyway. Make sure you are quelling your superuser powers and try to get the box now:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>> get box
|
||||
You can't get that.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Think this default error message looks dull? The <code class="docutils literal notranslate"><span class="pre">get</span></code> command looks for an <a class="reference internal" href="../../../Components/Attributes.html"><span class="doc std std-doc">Attribute</span></a>
|
||||
named <code class="docutils literal notranslate"><span class="pre">get_err_msg</span></code> for returning a nicer error messageod (this can be seen from the default <code class="docutils literal notranslate"><span class="pre">get</span></code> command code). You set attributes using the <code class="docutils literal notranslate"><span class="pre">set</span></code> command:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>set box/get_err_msg = It's way too heavy for you to lift.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Try to get it now and you should see a nicer error message echoed back to you. To see what this
|
||||
message string is in the future, you can use ‘examine.’</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>examine box/get_err_msg
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Examine will return the value of attributes, including color codes. <code class="docutils literal notranslate"><span class="pre">examine</span> <span class="pre">here/desc</span></code> would return
|
||||
the raw description of your current room (including color codes), so that you can copy-and-paste to
|
||||
set its description to something else.</p>
|
||||
<p>You create new Commands (or modify existing ones) in Python outside the game. We will get to that
|
||||
later, in the <a class="reference internal" href="Beginner-Tutorial-Adding-Commands.html"><span class="doc std std-doc">Commands tutorial</span></a>.</p>
|
||||
</section>
|
||||
<section id="get-a-personality">
|
||||
<h2><span class="section-number">1.5. </span>Get a Personality<a class="headerlink" href="#get-a-personality" title="Permalink to this headline">¶</a></h2>
|
||||
<p><a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a> are powerful out-of-character objects useful for many “under the hood” things.
|
||||
One of their optional abilities is to do things on a timer. To try out a first script, let’s put one
|
||||
on ourselves. There is an example script in <code class="docutils literal notranslate"><span class="pre">evennia/contrib/tutorials/bodyfunctions/bodyfunctions.py</span></code>
|
||||
that is called <code class="docutils literal notranslate"><span class="pre">BodyFunctions</span></code>. To add this to us we will use the <code class="docutils literal notranslate"><span class="pre">script</span></code> command:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>script self = tutorials.bodyfunctions.BodyFunctions
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This string will tell Evennia to dig up the Python code at the place we indicate. It already knows
|
||||
to look in the <code class="docutils literal notranslate"><span class="pre">contrib/</span></code> folder, so we don’t have to give the full path.</p>
|
||||
<blockquote>
|
||||
<div><p>Note also how we use <code class="docutils literal notranslate"><span class="pre">.</span></code> instead of <code class="docutils literal notranslate"><span class="pre">/</span></code> (or <code class="docutils literal notranslate"><span class="pre">\</span></code> on Windows). This is a so-called “Python path”. In a Python-path,
|
||||
you separate the parts of the path with <code class="docutils literal notranslate"><span class="pre">.</span></code> and skip the <code class="docutils literal notranslate"><span class="pre">.py</span></code> file-ending. Importantly, it also allows you to point to
|
||||
Python code <em>inside</em> files, like the <code class="docutils literal notranslate"><span class="pre">BodyFunctions</span></code> class inside <code class="docutils literal notranslate"><span class="pre">bodyfunctions.py</span></code> (we’ll get to classes later).
|
||||
These “Python-paths” are used extensively throughout Evennia.</p>
|
||||
</div></blockquote>
|
||||
<p>Wait a while and you will notice yourself starting making random observations …</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>script self
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will show details about scripts on yourself (also <code class="docutils literal notranslate"><span class="pre">examine</span></code> works). You will see how long it is
|
||||
until it “fires” next. Don’t be alarmed if nothing happens when the countdown reaches zero - this
|
||||
particular script has a randomizer to determine if it will say something or not. So you will not see
|
||||
output every time it fires.</p>
|
||||
<p>When you are tired of your character’s “insights”, kill the script with</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>script/stop self = tutorials.bodyfunctions.BodyFunctions
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You create your own scripts in Python, outside the game; the path you give to <code class="docutils literal notranslate"><span class="pre">script</span></code> is literally
|
||||
the Python path to your script file. The <a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a> page explains more details.</p>
|
||||
</section>
|
||||
<section id="pushing-your-buttons">
|
||||
<h2><span class="section-number">1.6. </span>Pushing Your Buttons<a class="headerlink" href="#pushing-your-buttons" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If we get back to the box we made, there is only so much fun you can have with it at this point. It’s
|
||||
just a dumb generic object. If you renamed it to <code class="docutils literal notranslate"><span class="pre">stone</span></code> and changed its description, noone would be
|
||||
the wiser. However, with the combined use of custom <a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc std std-doc">Typeclasses</span></a>, <a class="reference internal" href="../../../Components/Scripts.html"><span class="doc std std-doc">Scripts</span></a>
|
||||
and object-based <a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">Commands</span></a>, you could expand it and other items to be as unique, complex
|
||||
and interactive as you want.</p>
|
||||
<p>Let’s take an example. So far we have only created objects that use the default object typeclass
|
||||
named simply <code class="docutils literal notranslate"><span class="pre">Object</span></code>. Let’s create an object that is a little more interesting. Under
|
||||
<code class="docutils literal notranslate"><span class="pre">evennia/contrib/tutorial_examples</span></code> there is a module <code class="docutils literal notranslate"><span class="pre">red_button.py</span></code>. It contains the enigmatic
|
||||
<code class="docutils literal notranslate"><span class="pre">RedButton</span></code> class.</p>
|
||||
<p>Let’s make us one of <em>those</em>!</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>create/drop button:tutorials.red_button.RedButton
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The same way we did with the Script Earler, we specify a “Python-path” to the Python code we want Evennia
|
||||
to use for creating the object. There you go - one red button.</p>
|
||||
<p>The RedButton is an example object intended to show off a few of Evennia’s features. You will find
|
||||
that the <a class="reference internal" href="../../../Components/Typeclasses.html"><span class="doc std std-doc">Typeclass</span></a> and <a class="reference internal" href="../../../Components/Commands.html"><span class="doc std std-doc">Commands</span></a> controlling it are
|
||||
inside <a class="reference internal" href="../../../api/evennia.contrib.tutorials.red_button.html"><span class="doc std std-doc">evennia/contrib/tutorials/red_button</span></a></p>
|
||||
<p>If you wait for a while (make sure you dropped it!) the button will blink invitingly.</p>
|
||||
<p>Why don’t you try to push it …?</p>
|
||||
<p>Surely a big red button is meant to be pushed.</p>
|
||||
<p>You know you want to.</p>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Warning</p>
|
||||
<p>Don’t press the invitingly blinking red button.</p>
|
||||
</div>
|
||||
</section>
|
||||
<section id="making-yourself-a-house">
|
||||
<h2><span class="section-number">1.7. </span>Making Yourself a House<a class="headerlink" href="#making-yourself-a-house" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The main command for shaping the game world is <code class="docutils literal notranslate"><span class="pre">dig</span></code>. For example, if you are standing in Limbo, you
|
||||
can dig a route to your new house location like this:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>dig house = large red door;door;in,to the outside;out
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will create a new room named ‘house’. Spaces at the start/end of names and aliases are ignored
|
||||
so you could put more air if you wanted. This call will directly create an exit from your current
|
||||
location named ‘large red door’ and a corresponding exit named ‘to the outside’ in the house room
|
||||
leading back to Limbo. We also define a few aliases to those exits, so people don’t have to write
|
||||
the full thing all the time.</p>
|
||||
<p>If you wanted to use normal compass directions (north, west, southwest etc), you could do that with
|
||||
<code class="docutils literal notranslate"><span class="pre">dig</span></code> too. But Evennia also has a limited version of <code class="docutils literal notranslate"><span class="pre">dig</span></code> that helps for compass directions (and
|
||||
also up/down and in/out). It’s called <code class="docutils literal notranslate"><span class="pre">tunnel</span></code>:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>tunnel sw = cliff
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will create a new room “cliff” with an exit “southwest” leading there and a path “northeast”
|
||||
leading back from the cliff to your current location.</p>
|
||||
<p>You can create new exits from where you are, using the <code class="docutils literal notranslate"><span class="pre">open</span></code> command:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>open north;n = house
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This opens an exit <code class="docutils literal notranslate"><span class="pre">north</span></code> (with an alias <code class="docutils literal notranslate"><span class="pre">n</span></code>) to the previously created room <code class="docutils literal notranslate"><span class="pre">house</span></code>.</p>
|
||||
<p>If you have many rooms named <code class="docutils literal notranslate"><span class="pre">house</span></code> you will get a list of matches and have to select which one you
|
||||
want to link to.</p>
|
||||
<p>Follow the north exit to your ‘house’ or <code class="docutils literal notranslate"><span class="pre">teleport</span></code> to it:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>north
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>teleport house
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>To manually open an exit back to Limbo (if you didn’t do so with the <code class="docutils literal notranslate"><span class="pre">dig</span></code> command):</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>open door = limbo
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>(You can also us the #dbref of limbo, which you can find by using <code class="docutils literal notranslate"><span class="pre">examine</span> <span class="pre">here</span></code> when in limbo).</p>
|
||||
</section>
|
||||
<section id="reshuffling-the-world">
|
||||
<h2><span class="section-number">1.8. </span>Reshuffling the World<a class="headerlink" href="#reshuffling-the-world" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You can find things using the <code class="docutils literal notranslate"><span class="pre">find</span></code> command. Assuming you are back at <code class="docutils literal notranslate"><span class="pre">Limbo</span></code>, let’s teleport the
|
||||
<em>large box</em> to our house.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>teleport box = house
|
||||
very large box is leaving Limbo, heading for house.
|
||||
Teleported very large box -> house.
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We can still find the box by using find:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>find box
|
||||
One Match(#1-#8):
|
||||
very large box(#8) - src.objects.objects.Object
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Knowing the <code class="docutils literal notranslate"><span class="pre">#dbref</span></code> of the box (#8 in this example), you can grab the box and get it back here
|
||||
without actually yourself going to <code class="docutils literal notranslate"><span class="pre">house</span></code> first:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>teleport #8 = here
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>As mentioned, <code class="docutils literal notranslate"><span class="pre">here</span></code> is an alias for ‘your current location’. The box should now be back in Limbo with you.</p>
|
||||
<p>We are getting tired of the box. Let’s destroy it.</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>destroy box
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>It will ask you for confirmation. Once you give it, the box will be gone.</p>
|
||||
<p>You can destroy many objects in one go by giving a comma-separated list of objects (or a range
|
||||
of #dbrefs, if they are not in the same location) to the command.</p>
|
||||
</section>
|
||||
<section id="adding-a-help-entry">
|
||||
<h2><span class="section-number">1.9. </span>Adding a Help Entry<a class="headerlink" href="#adding-a-help-entry" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The Command-help is something you modify in Python code. We’ll get to that when we get to how to
|
||||
add Commands. But you can also add regular help entries, for example to explain something about
|
||||
the history of your game world:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>sethelp History = At the dawn of time ...
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You will now find your new <code class="docutils literal notranslate"><span class="pre">History</span></code> entry in the <code class="docutils literal notranslate"><span class="pre">help</span></code> list and read your help-text with <code class="docutils literal notranslate"><span class="pre">help</span> <span class="pre">History</span></code>.</p>
|
||||
</section>
|
||||
<section id="adding-a-world">
|
||||
<h2><span class="section-number">1.10. </span>Adding a World<a class="headerlink" href="#adding-a-world" title="Permalink to this headline">¶</a></h2>
|
||||
<p>After this brief introduction to building and using in-game commands you may be ready to see a more fleshed-out
|
||||
example. Evennia comes with a tutorial world for you to explore. We will try that out in the next lesson.</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="Beginner-Tutorial-Tutorial-World.html" title="2. The Tutorial World"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Beginner-Tutorial-Part1-Overview.html" title="Part 1: What we have"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="../../Howtos-Overview.html" >Tutorials and Howto’s</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="../Beginner-Tutorial-Overview.html" >Beginner Tutorial</a> »</li>
|
||||
<li class="nav-item nav-item-3"><a href="Beginner-Tutorial-Part1-Overview.html" >Part 1: What we have</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href=""><span class="section-number">1. </span>Using commands and building stuff</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2022, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
|
||||
<!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>8. Non-Player-Characters (NPCs) — Evennia 1.0 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="9. Game Quests" href="Beginner-Tutorial-Quests.html" />
|
||||
<link rel="prev" title="7. In-game Rooms" href="Beginner-Tutorial-Rooms.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="Beginner-Tutorial-Quests.html" title="9. Game Quests"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Beginner-Tutorial-Rooms.html" title="7. In-game Rooms"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="../../Howtos-Overview.html" >Tutorials and Howto’s</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="../Beginner-Tutorial-Overview.html" >Beginner Tutorial</a> »</li>
|
||||
<li class="nav-item nav-item-3"><a href="Beginner-Tutorial-Part3-Overview.html" accesskey="U">Part 3: How we get there (example game)</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href=""><span class="section-number">8. </span>Non-Player-Characters (NPCs)</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>
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="Beginner-Tutorial-Rooms.html"
|
||||
title="previous chapter"><span class="section-number">7. </span>In-game Rooms</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="Beginner-Tutorial-Quests.html"
|
||||
title="next chapter"><span class="section-number">9. </span>Game Quests</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<!--h3>This Page</h3-->
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../../../_sources/Howtos/Beginner-Tutorial/Part3/Beginner-Tutorial-NPCs.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="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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="Beginner-Tutorial-NPCs.html">1.0 (develop branch)</a></li>
|
||||
<ul>
|
||||
<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="non-player-characters-npcs">
|
||||
<h1><span class="section-number">8. </span>Non-Player-Characters (NPCs)<a class="headerlink" href="#non-player-characters-npcs" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Warning</p>
|
||||
<p>This part of the Beginner tutorial is still being developed.</p>
|
||||
</div>
|
||||
</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="Beginner-Tutorial-Quests.html" title="9. Game Quests"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="Beginner-Tutorial-Rooms.html" title="7. In-game Rooms"
|
||||
>previous</a> |</li>
|
||||
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="../../Howtos-Overview.html" >Tutorials and Howto’s</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="../Beginner-Tutorial-Overview.html" >Beginner Tutorial</a> »</li>
|
||||
<li class="nav-item nav-item-3"><a href="Beginner-Tutorial-Part3-Overview.html" >Part 3: How we get there (example game)</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href=""><span class="section-number">8. </span>Non-Player-Characters (NPCs)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2022, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,696 +0,0 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>evennia.contrib.grid.extended_room.extended_room — Evennia 1.0 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" />
|
||||
</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 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="../../../../index.html" >Module code</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="../../../../evennia.html" accesskey="U">evennia</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">evennia.contrib.grid.extended_room.extended_room</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>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="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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="extended_room.html">1.0 (develop branch)</a></li>
|
||||
<ul>
|
||||
<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">
|
||||
|
||||
<h1>Source code for evennia.contrib.grid.extended_room.extended_room</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">Extended Room</span>
|
||||
|
||||
<span class="sd">Evennia Contribution - Griatch 2012, vincent-lg 2019</span>
|
||||
|
||||
<span class="sd">This is an extended Room typeclass for Evennia. It is supported</span>
|
||||
<span class="sd">by an extended `Look` command and an extended `desc` command, also</span>
|
||||
<span class="sd">in this module.</span>
|
||||
|
||||
|
||||
<span class="sd">Features:</span>
|
||||
|
||||
<span class="sd">1) Time-changing description slots</span>
|
||||
|
||||
<span class="sd">This allows to change the full description text the room shows</span>
|
||||
<span class="sd">depending on larger time variations. Four seasons (spring, summer,</span>
|
||||
<span class="sd">autumn and winter) are used by default. The season is calculated</span>
|
||||
<span class="sd">on-demand (no Script or timer needed) and updates the full text block.</span>
|
||||
|
||||
<span class="sd">There is also a general description which is used as fallback if</span>
|
||||
<span class="sd">one or more of the seasonal descriptions are not set when their</span>
|
||||
<span class="sd">time comes.</span>
|
||||
|
||||
<span class="sd">An updated `desc` command allows for setting seasonal descriptions.</span>
|
||||
|
||||
<span class="sd">The room uses the `evennia.utils.gametime.GameTime` global script. This is</span>
|
||||
<span class="sd">started by default, but if you have deactivated it, you need to</span>
|
||||
<span class="sd">supply your own time keeping mechanism.</span>
|
||||
|
||||
|
||||
<span class="sd">2) In-description changing tags</span>
|
||||
|
||||
<span class="sd">Within each seasonal (or general) description text, you can also embed</span>
|
||||
<span class="sd">time-of-day dependent sections. Text inside such a tag will only show</span>
|
||||
<span class="sd">during that particular time of day. The tags looks like `<timeslot> ...</span>
|
||||
<span class="sd"></timeslot>`. By default there are four timeslots per day - morning,</span>
|
||||
<span class="sd">afternoon, evening and night.</span>
|
||||
|
||||
|
||||
<span class="sd">3) Details</span>
|
||||
|
||||
<span class="sd">The Extended Room can be "detailed" with special keywords. This makes</span>
|
||||
<span class="sd">use of a special `Look` command. Details are "virtual" targets to look</span>
|
||||
<span class="sd">at, without there having to be a database object created for it. The</span>
|
||||
<span class="sd">Details are simply stored in a dictionary on the room and if the look</span>
|
||||
<span class="sd">command cannot find an object match for a `look <target>` command it</span>
|
||||
<span class="sd">will also look through the available details at the current location</span>
|
||||
<span class="sd">if applicable. The `detail` command is used to change details.</span>
|
||||
|
||||
|
||||
<span class="sd">4) Extra commands</span>
|
||||
|
||||
<span class="sd"> CmdExtendedRoomLook - look command supporting room details</span>
|
||||
<span class="sd"> CmdExtendedRoomDesc - desc command allowing to add seasonal descs,</span>
|
||||
<span class="sd"> CmdExtendedRoomDetail - command allowing to manipulate details in this room</span>
|
||||
<span class="sd"> as well as listing them</span>
|
||||
<span class="sd"> CmdExtendedRoomGameTime - A simple `time` command, displaying the current</span>
|
||||
<span class="sd"> time and season.</span>
|
||||
|
||||
|
||||
<span class="sd">Installation/testing:</span>
|
||||
|
||||
<span class="sd">Adding the `ExtendedRoomCmdset` to the default character cmdset will add all</span>
|
||||
<span class="sd">new commands for use.</span>
|
||||
|
||||
<span class="sd">In more detail, in mygame/commands/default_cmdsets.py:</span>
|
||||
|
||||
<span class="sd">```</span>
|
||||
<span class="sd">...</span>
|
||||
<span class="sd">from evennia.contrib import extended_room # <---</span>
|
||||
|
||||
<span class="sd">class CharacterCmdset(default_cmds.Character_CmdSet):</span>
|
||||
<span class="sd"> ...</span>
|
||||
<span class="sd"> def at_cmdset_creation(self):</span>
|
||||
<span class="sd"> ...</span>
|
||||
<span class="sd"> self.add(extended_room.ExtendedRoomCmdSet) # <---</span>
|
||||
|
||||
<span class="sd">```</span>
|
||||
|
||||
<span class="sd">Then reload to make the bew commands available. Note that they only work</span>
|
||||
<span class="sd">on rooms with the typeclass `ExtendedRoom`. Create new rooms with the right</span>
|
||||
<span class="sd">typeclass or use the `typeclass` command to swap existing rooms.</span>
|
||||
|
||||
<span class="sd">"""</span>
|
||||
|
||||
|
||||
<span class="kn">import</span> <span class="nn">datetime</span>
|
||||
<span class="kn">import</span> <span class="nn">re</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia</span> <span class="kn">import</span> <span class="n">CmdSet</span><span class="p">,</span> <span class="n">DefaultRoom</span><span class="p">,</span> <span class="n">default_cmds</span><span class="p">,</span> <span class="n">gametime</span><span class="p">,</span> <span class="n">utils</span>
|
||||
|
||||
<span class="c1"># error return function, needed by Extended Look command</span>
|
||||
<span class="n">_AT_SEARCH_RESULT</span> <span class="o">=</span> <span class="n">utils</span><span class="o">.</span><span class="n">variable_from_module</span><span class="p">(</span><span class="o">*</span><span class="n">settings</span><span class="o">.</span><span class="n">SEARCH_AT_RESULT</span><span class="o">.</span><span class="n">rsplit</span><span class="p">(</span><span class="s2">"."</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
|
||||
|
||||
<span class="c1"># regexes for in-desc replacements</span>
|
||||
<span class="n">RE_MORNING</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">"<morning>(.*?)</morning>"</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">IGNORECASE</span><span class="p">)</span>
|
||||
<span class="n">RE_AFTERNOON</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">"<afternoon>(.*?)</afternoon>"</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">IGNORECASE</span><span class="p">)</span>
|
||||
<span class="n">RE_EVENING</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">"<evening>(.*?)</evening>"</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">IGNORECASE</span><span class="p">)</span>
|
||||
<span class="n">RE_NIGHT</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">"<night>(.*?)</night>"</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">IGNORECASE</span><span class="p">)</span>
|
||||
<span class="c1"># this map is just a faster way to select the right regexes (the first</span>
|
||||
<span class="c1"># regex in each tuple will be parsed, the following will always be weeded out)</span>
|
||||
<span class="n">REGEXMAP</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"morning"</span><span class="p">:</span> <span class="p">(</span><span class="n">RE_MORNING</span><span class="p">,</span> <span class="n">RE_AFTERNOON</span><span class="p">,</span> <span class="n">RE_EVENING</span><span class="p">,</span> <span class="n">RE_NIGHT</span><span class="p">),</span>
|
||||
<span class="s2">"afternoon"</span><span class="p">:</span> <span class="p">(</span><span class="n">RE_AFTERNOON</span><span class="p">,</span> <span class="n">RE_MORNING</span><span class="p">,</span> <span class="n">RE_EVENING</span><span class="p">,</span> <span class="n">RE_NIGHT</span><span class="p">),</span>
|
||||
<span class="s2">"evening"</span><span class="p">:</span> <span class="p">(</span><span class="n">RE_EVENING</span><span class="p">,</span> <span class="n">RE_MORNING</span><span class="p">,</span> <span class="n">RE_AFTERNOON</span><span class="p">,</span> <span class="n">RE_NIGHT</span><span class="p">),</span>
|
||||
<span class="s2">"night"</span><span class="p">:</span> <span class="p">(</span><span class="n">RE_NIGHT</span><span class="p">,</span> <span class="n">RE_MORNING</span><span class="p">,</span> <span class="n">RE_AFTERNOON</span><span class="p">,</span> <span class="n">RE_EVENING</span><span class="p">),</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="c1"># set up the seasons and time slots. This assumes gametime started at the</span>
|
||||
<span class="c1"># beginning of the year (so month 1 is equivalent to January), and that</span>
|
||||
<span class="c1"># one CAN divide the game's year into four seasons in the first place ...</span>
|
||||
<span class="n">MONTHS_PER_YEAR</span> <span class="o">=</span> <span class="mi">12</span>
|
||||
<span class="n">SEASONAL_BOUNDARIES</span> <span class="o">=</span> <span class="p">(</span><span class="mi">3</span> <span class="o">/</span> <span class="mf">12.0</span><span class="p">,</span> <span class="mi">6</span> <span class="o">/</span> <span class="mf">12.0</span><span class="p">,</span> <span class="mi">9</span> <span class="o">/</span> <span class="mf">12.0</span><span class="p">)</span>
|
||||
<span class="n">HOURS_PER_DAY</span> <span class="o">=</span> <span class="mi">24</span>
|
||||
<span class="n">DAY_BOUNDARIES</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">6</span> <span class="o">/</span> <span class="mf">24.0</span><span class="p">,</span> <span class="mi">12</span> <span class="o">/</span> <span class="mf">24.0</span><span class="p">,</span> <span class="mi">18</span> <span class="o">/</span> <span class="mf">24.0</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="c1"># implements the Extended Room</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoom"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoom">[docs]</a><span class="k">class</span> <span class="nc">ExtendedRoom</span><span class="p">(</span><span class="n">DefaultRoom</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> This room implements a more advanced `look` functionality depending on</span>
|
||||
<span class="sd"> time. It also allows for "details", together with a slightly modified</span>
|
||||
<span class="sd"> look command.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoom.at_object_creation"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoom.at_object_creation">[docs]</a> <span class="k">def</span> <span class="nf">at_object_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""Called when room is first created only."""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">spring_desc</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">summer_desc</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">autumn_desc</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">winter_desc</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
<span class="c1"># the general desc is used as a fallback if a seasonal one is not set</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">general_desc</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
<span class="c1"># will be set dynamically. Can contain raw timeslot codes</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">raw_desc</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
<span class="c1"># this will be set dynamically at first look. Parsed for timeslot codes</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
<span class="c1"># these will be filled later</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_season</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_timeslot</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="c1"># detail storage</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">details</span> <span class="o">=</span> <span class="p">{}</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoom.get_time_and_season"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoom.get_time_and_season">[docs]</a> <span class="k">def</span> <span class="nf">get_time_and_season</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Calculate the current time and season ids.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># get the current time as parts of year and parts of day.</span>
|
||||
<span class="c1"># we assume a standard calendar here and use 24h format.</span>
|
||||
<span class="n">timestamp</span> <span class="o">=</span> <span class="n">gametime</span><span class="o">.</span><span class="n">gametime</span><span class="p">(</span><span class="n">absolute</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="c1"># note that fromtimestamp includes the effects of server time zone!</span>
|
||||
<span class="n">datestamp</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">timestamp</span><span class="p">)</span>
|
||||
<span class="n">season</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">datestamp</span><span class="o">.</span><span class="n">month</span><span class="p">)</span> <span class="o">/</span> <span class="n">MONTHS_PER_YEAR</span>
|
||||
<span class="n">timeslot</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">datestamp</span><span class="o">.</span><span class="n">hour</span><span class="p">)</span> <span class="o">/</span> <span class="n">HOURS_PER_DAY</span>
|
||||
|
||||
<span class="c1"># figure out which slots these represent</span>
|
||||
<span class="k">if</span> <span class="n">SEASONAL_BOUNDARIES</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o"><=</span> <span class="n">season</span> <span class="o"><</span> <span class="n">SEASONAL_BOUNDARIES</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
|
||||
<span class="n">curr_season</span> <span class="o">=</span> <span class="s2">"spring"</span>
|
||||
<span class="k">elif</span> <span class="n">SEASONAL_BOUNDARIES</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o"><=</span> <span class="n">season</span> <span class="o"><</span> <span class="n">SEASONAL_BOUNDARIES</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span>
|
||||
<span class="n">curr_season</span> <span class="o">=</span> <span class="s2">"summer"</span>
|
||||
<span class="k">elif</span> <span class="n">SEASONAL_BOUNDARIES</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o"><=</span> <span class="n">season</span> <span class="o"><</span> <span class="mf">1.0</span> <span class="o">+</span> <span class="n">SEASONAL_BOUNDARIES</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
|
||||
<span class="n">curr_season</span> <span class="o">=</span> <span class="s2">"autumn"</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">curr_season</span> <span class="o">=</span> <span class="s2">"winter"</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">DAY_BOUNDARIES</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o"><=</span> <span class="n">timeslot</span> <span class="o"><</span> <span class="n">DAY_BOUNDARIES</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
|
||||
<span class="n">curr_timeslot</span> <span class="o">=</span> <span class="s2">"night"</span>
|
||||
<span class="k">elif</span> <span class="n">DAY_BOUNDARIES</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o"><=</span> <span class="n">timeslot</span> <span class="o"><</span> <span class="n">DAY_BOUNDARIES</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span>
|
||||
<span class="n">curr_timeslot</span> <span class="o">=</span> <span class="s2">"morning"</span>
|
||||
<span class="k">elif</span> <span class="n">DAY_BOUNDARIES</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o"><=</span> <span class="n">timeslot</span> <span class="o"><</span> <span class="n">DAY_BOUNDARIES</span><span class="p">[</span><span class="mi">3</span><span class="p">]:</span>
|
||||
<span class="n">curr_timeslot</span> <span class="o">=</span> <span class="s2">"afternoon"</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">curr_timeslot</span> <span class="o">=</span> <span class="s2">"evening"</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">curr_season</span><span class="p">,</span> <span class="n">curr_timeslot</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoom.replace_timeslots"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoom.replace_timeslots">[docs]</a> <span class="k">def</span> <span class="nf">replace_timeslots</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">raw_desc</span><span class="p">,</span> <span class="n">curr_time</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Filter so that only time markers `<timeslot>...</timeslot>` of</span>
|
||||
<span class="sd"> the correct timeslot remains in the description.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> raw_desc (str): The unmodified description.</span>
|
||||
<span class="sd"> curr_time (str): A timeslot identifier.</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> description (str): A possibly moified description.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="n">raw_desc</span><span class="p">:</span>
|
||||
<span class="n">regextuple</span> <span class="o">=</span> <span class="n">REGEXMAP</span><span class="p">[</span><span class="n">curr_time</span><span class="p">]</span>
|
||||
<span class="n">raw_desc</span> <span class="o">=</span> <span class="n">regextuple</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s2">"\1"</span><span class="p">,</span> <span class="n">raw_desc</span><span class="p">)</span>
|
||||
<span class="n">raw_desc</span> <span class="o">=</span> <span class="n">regextuple</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">""</span><span class="p">,</span> <span class="n">raw_desc</span><span class="p">)</span>
|
||||
<span class="n">raw_desc</span> <span class="o">=</span> <span class="n">regextuple</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">""</span><span class="p">,</span> <span class="n">raw_desc</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">regextuple</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">""</span><span class="p">,</span> <span class="n">raw_desc</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">raw_desc</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoom.return_detail"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoom.return_detail">[docs]</a> <span class="k">def</span> <span class="nf">return_detail</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> This will attempt to match a "detail" to look for in the room.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> key (str): A detail identifier.</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> detail (str or None): A detail matching the given key.</span>
|
||||
|
||||
<span class="sd"> Notes:</span>
|
||||
<span class="sd"> A detail is a way to offer more things to look at in a room</span>
|
||||
<span class="sd"> without having to add new objects. For this to work, we</span>
|
||||
<span class="sd"> require a custom `look` command that allows for `look</span>
|
||||
<span class="sd"> <detail>` - the look command should defer to this method on</span>
|
||||
<span class="sd"> the current location (if it exists) before giving up on</span>
|
||||
<span class="sd"> finding the target.</span>
|
||||
|
||||
<span class="sd"> Details are not season-sensitive, but are parsed for timeslot</span>
|
||||
<span class="sd"> markers.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">detail</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">details</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="kc">None</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="c1"># this happens if no attribute details is set at all</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
<span class="k">if</span> <span class="n">detail</span><span class="p">:</span>
|
||||
<span class="n">season</span><span class="p">,</span> <span class="n">timeslot</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_time_and_season</span><span class="p">()</span>
|
||||
<span class="n">detail</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">replace_timeslots</span><span class="p">(</span><span class="n">detail</span><span class="p">,</span> <span class="n">timeslot</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">detail</span>
|
||||
<span class="k">return</span> <span class="kc">None</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoom.set_detail"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoom.set_detail">[docs]</a> <span class="k">def</span> <span class="nf">set_detail</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">detailkey</span><span class="p">,</span> <span class="n">description</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> This sets a new detail, using an Attribute "details".</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> detailkey (str): The detail identifier to add (for</span>
|
||||
<span class="sd"> aliases you need to add multiple keys to the</span>
|
||||
<span class="sd"> same description). Case-insensitive.</span>
|
||||
<span class="sd"> description (str): The text to return when looking</span>
|
||||
<span class="sd"> at the given detailkey.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">details</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">details</span><span class="p">[</span><span class="n">detailkey</span><span class="o">.</span><span class="n">lower</span><span class="p">()]</span> <span class="o">=</span> <span class="n">description</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">details</span> <span class="o">=</span> <span class="p">{</span><span class="n">detailkey</span><span class="o">.</span><span class="n">lower</span><span class="p">():</span> <span class="n">description</span><span class="p">}</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoom.del_detail"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoom.del_detail">[docs]</a> <span class="k">def</span> <span class="nf">del_detail</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">detailkey</span><span class="p">,</span> <span class="n">description</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Delete a detail.</span>
|
||||
|
||||
<span class="sd"> The description is ignored.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> detailkey (str): the detail to remove (case-insensitive).</span>
|
||||
<span class="sd"> description (str, ignored): the description.</span>
|
||||
|
||||
<span class="sd"> The description is only included for compliance but is completely</span>
|
||||
<span class="sd"> ignored. Note that this method doesn't raise any exception if</span>
|
||||
<span class="sd"> the detail doesn't exist in this room.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">details</span> <span class="ow">and</span> <span class="n">detailkey</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">details</span><span class="p">:</span>
|
||||
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">details</span><span class="p">[</span><span class="n">detailkey</span><span class="o">.</span><span class="n">lower</span><span class="p">()]</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoom.return_appearance"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoom.return_appearance">[docs]</a> <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="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> This is called when e.g. the look command wants to retrieve</span>
|
||||
<span class="sd"> the description of this object.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> looker (Object): The object looking at us.</span>
|
||||
<span class="sd"> **kwargs (dict): Arbitrary, optional arguments for users</span>
|
||||
<span class="sd"> overriding the call (unused by default).</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> description (str): Our description.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># ensures that our description is current based on time/season</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">update_current_description</span><span class="p">()</span>
|
||||
<span class="c1"># run the normal return_appearance method, now that desc is updated.</span>
|
||||
<span class="k">return</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="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoom.update_current_description"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoom.update_current_description">[docs]</a> <span class="k">def</span> <span class="nf">update_current_description</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> This will update the description of the room if the time or season</span>
|
||||
<span class="sd"> has changed since last checked.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">update</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="c1"># get current time and season</span>
|
||||
<span class="n">curr_season</span><span class="p">,</span> <span class="n">curr_timeslot</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_time_and_season</span><span class="p">()</span>
|
||||
<span class="c1"># compare with previously stored slots</span>
|
||||
<span class="n">last_season</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_season</span>
|
||||
<span class="n">last_timeslot</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_timeslot</span>
|
||||
<span class="k">if</span> <span class="n">curr_season</span> <span class="o">!=</span> <span class="n">last_season</span><span class="p">:</span>
|
||||
<span class="c1"># season changed. Load new desc, or a fallback.</span>
|
||||
<span class="n">new_raw_desc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"</span><span class="si">%s</span><span class="s2">_desc"</span> <span class="o">%</span> <span class="n">curr_season</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">new_raw_desc</span><span class="p">:</span>
|
||||
<span class="n">raw_desc</span> <span class="o">=</span> <span class="n">new_raw_desc</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># no seasonal desc set. Use fallback</span>
|
||||
<span class="n">raw_desc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">general_desc</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">desc</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">raw_desc</span> <span class="o">=</span> <span class="n">raw_desc</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_season</span> <span class="o">=</span> <span class="n">curr_season</span>
|
||||
<span class="n">update</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="k">if</span> <span class="n">curr_timeslot</span> <span class="o">!=</span> <span class="n">last_timeslot</span><span class="p">:</span>
|
||||
<span class="c1"># timeslot changed. Set update flag.</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_timeslot</span> <span class="o">=</span> <span class="n">curr_timeslot</span>
|
||||
<span class="n">update</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="k">if</span> <span class="n">update</span><span class="p">:</span>
|
||||
<span class="c1"># if anything changed we have to re-parse</span>
|
||||
<span class="c1"># the raw_desc for time markers</span>
|
||||
<span class="c1"># and re-save the description again.</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">replace_timeslots</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">raw_desc</span><span class="p">,</span> <span class="n">curr_timeslot</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<span class="c1"># Custom Look command supporting Room details. Add this to</span>
|
||||
<span class="c1"># the Default cmdset to use.</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="CmdExtendedRoomLook"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomLook">[docs]</a><span class="k">class</span> <span class="nc">CmdExtendedRoomLook</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CmdLook</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> look</span>
|
||||
|
||||
<span class="sd"> Usage:</span>
|
||||
<span class="sd"> look</span>
|
||||
<span class="sd"> look <obj></span>
|
||||
<span class="sd"> look <room detail></span>
|
||||
<span class="sd"> look *<account></span>
|
||||
|
||||
<span class="sd"> Observes your location, details at your location or objects in your vicinity.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<div class="viewcode-block" id="CmdExtendedRoomLook.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomLook.func">[docs]</a> <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">"""</span>
|
||||
<span class="sd"> Handle the looking - add fallback to details.</span>
|
||||
<span class="sd"> """</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="n">args</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
|
||||
<span class="k">if</span> <span class="n">args</span><span class="p">:</span>
|
||||
<span class="n">looking_at_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="n">args</span><span class="p">,</span>
|
||||
<span class="n">candidates</span><span class="o">=</span><span class="n">caller</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">contents</span> <span class="o">+</span> <span class="n">caller</span><span class="o">.</span><span class="n">contents</span><span class="p">,</span>
|
||||
<span class="n">use_nicks</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
||||
<span class="n">quiet</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">looking_at_obj</span><span class="p">:</span>
|
||||
<span class="c1"># no object found. Check if there is a matching</span>
|
||||
<span class="c1"># detail at location.</span>
|
||||
<span class="n">location</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">location</span>
|
||||
<span class="k">if</span> <span class="p">(</span>
|
||||
<span class="n">location</span>
|
||||
<span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">location</span><span class="p">,</span> <span class="s2">"return_detail"</span><span class="p">)</span>
|
||||
<span class="ow">and</span> <span class="nb">callable</span><span class="p">(</span><span class="n">location</span><span class="o">.</span><span class="n">return_detail</span><span class="p">)</span>
|
||||
<span class="p">):</span>
|
||||
<span class="n">detail</span> <span class="o">=</span> <span class="n">location</span><span class="o">.</span><span class="n">return_detail</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">detail</span><span class="p">:</span>
|
||||
<span class="c1"># we found a detail instead. Show that.</span>
|
||||
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">detail</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="c1"># no detail found. Trigger delayed error messages</span>
|
||||
<span class="n">_AT_SEARCH_RESULT</span><span class="p">(</span><span class="n">looking_at_obj</span><span class="p">,</span> <span class="n">caller</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">quiet</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># we need to extract the match manually.</span>
|
||||
<span class="n">looking_at_obj</span> <span class="o">=</span> <span class="n">utils</span><span class="o">.</span><span class="n">make_iter</span><span class="p">(</span><span class="n">looking_at_obj</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">looking_at_obj</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">location</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">looking_at_obj</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">"You have no location to look at!"</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">looking_at_obj</span><span class="p">,</span> <span class="s2">"return_appearance"</span><span class="p">):</span>
|
||||
<span class="c1"># this is likely due to us having an account instead</span>
|
||||
<span class="n">looking_at_obj</span> <span class="o">=</span> <span class="n">looking_at_obj</span><span class="o">.</span><span class="n">character</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">looking_at_obj</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">"view"</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">"Could not find '</span><span class="si">%s</span><span class="s2">'."</span> <span class="o">%</span> <span class="n">args</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="c1"># get object's appearance</span>
|
||||
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">looking_at_obj</span><span class="o">.</span><span class="n">return_appearance</span><span class="p">(</span><span class="n">caller</span><span class="p">))</span>
|
||||
<span class="c1"># the object's at_desc() method.</span>
|
||||
<span class="n">looking_at_obj</span><span class="o">.</span><span class="n">at_desc</span><span class="p">(</span><span class="n">looker</span><span class="o">=</span><span class="n">caller</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<span class="c1"># Custom build commands for setting seasonal descriptions</span>
|
||||
<span class="c1"># and detailing extended rooms.</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="CmdExtendedRoomDesc"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomDesc">[docs]</a><span class="k">class</span> <span class="nc">CmdExtendedRoomDesc</span><span class="p">(</span><span class="n">default_cmds</span><span class="o">.</span><span class="n">CmdDesc</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> `desc` - describe an object or room.</span>
|
||||
|
||||
<span class="sd"> Usage:</span>
|
||||
<span class="sd"> desc[/switch] [<obj> =] <description></span>
|
||||
|
||||
<span class="sd"> Switches for `desc`:</span>
|
||||
<span class="sd"> spring - set description for <season> in current room.</span>
|
||||
<span class="sd"> summer</span>
|
||||
<span class="sd"> autumn</span>
|
||||
<span class="sd"> winter</span>
|
||||
|
||||
<span class="sd"> Sets the "desc" attribute on an object. If an object is not given,</span>
|
||||
<span class="sd"> describe the current room.</span>
|
||||
|
||||
<span class="sd"> You can also embed special time markers in your room description, like this:</span>
|
||||
|
||||
<span class="sd"> ```</span>
|
||||
<span class="sd"> <night>In the darkness, the forest looks foreboding.</night>.</span>
|
||||
<span class="sd"> ```</span>
|
||||
|
||||
<span class="sd"> Text marked this way will only display when the server is truly at the given</span>
|
||||
<span class="sd"> timeslot. The available times are night, morning, afternoon and evening.</span>
|
||||
|
||||
<span class="sd"> Note that seasons and time-of-day slots only work on rooms in this</span>
|
||||
<span class="sd"> version of the `desc` command.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"describe"</span><span class="p">]</span>
|
||||
<span class="n">switch_options</span> <span class="o">=</span> <span class="p">()</span> <span class="c1"># Inherits from default_cmds.CmdDesc, but unused here</span>
|
||||
|
||||
<div class="viewcode-block" id="CmdExtendedRoomDesc.reset_times"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomDesc.reset_times">[docs]</a> <span class="k">def</span> <span class="nf">reset_times</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""By deleteting the caches we force a re-load."""</span>
|
||||
<span class="n">obj</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_season</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">obj</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_timeslot</span> <span class="o">=</span> <span class="kc">None</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CmdExtendedRoomDesc.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomDesc.func">[docs]</a> <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">"""Define extended command"""</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="n">location</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">location</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="k">if</span> <span class="n">location</span><span class="p">:</span>
|
||||
<span class="n">string</span> <span class="o">=</span> <span class="s2">"|wDescriptions on </span><span class="si">%s</span><span class="s2">|n:</span><span class="se">\n</span><span class="s2">"</span> <span class="o">%</span> <span class="n">location</span><span class="o">.</span><span class="n">key</span>
|
||||
<span class="n">string</span> <span class="o">+=</span> <span class="s2">" |wspring:|n </span><span class="si">%s</span><span class="se">\n</span><span class="s2">"</span> <span class="o">%</span> <span class="n">location</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">spring_desc</span>
|
||||
<span class="n">string</span> <span class="o">+=</span> <span class="s2">" |wsummer:|n </span><span class="si">%s</span><span class="se">\n</span><span class="s2">"</span> <span class="o">%</span> <span class="n">location</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">summer_desc</span>
|
||||
<span class="n">string</span> <span class="o">+=</span> <span class="s2">" |wautumn:|n </span><span class="si">%s</span><span class="se">\n</span><span class="s2">"</span> <span class="o">%</span> <span class="n">location</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">autumn_desc</span>
|
||||
<span class="n">string</span> <span class="o">+=</span> <span class="s2">" |wwinter:|n </span><span class="si">%s</span><span class="se">\n</span><span class="s2">"</span> <span class="o">%</span> <span class="n">location</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">winter_desc</span>
|
||||
<span class="n">string</span> <span class="o">+=</span> <span class="s2">" |wgeneral:|n </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">location</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">general_desc</span>
|
||||
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">"spring"</span><span class="p">,</span> <span class="s2">"summer"</span><span class="p">,</span> <span class="s2">"autumn"</span><span class="p">,</span> <span class="s2">"winter"</span><span class="p">):</span>
|
||||
<span class="c1"># a seasonal switch was given</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</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">"Seasonal descs only work with rooms, not objects."</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="n">switch</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">location</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">"No location was found!"</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="k">if</span> <span class="n">switch</span> <span class="o">==</span> <span class="s2">"spring"</span><span class="p">:</span>
|
||||
<span class="n">location</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">spring_desc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
|
||||
<span class="k">elif</span> <span class="n">switch</span> <span class="o">==</span> <span class="s2">"summer"</span><span class="p">:</span>
|
||||
<span class="n">location</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">summer_desc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
|
||||
<span class="k">elif</span> <span class="n">switch</span> <span class="o">==</span> <span class="s2">"autumn"</span><span class="p">:</span>
|
||||
<span class="n">location</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">autumn_desc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
|
||||
<span class="k">elif</span> <span class="n">switch</span> <span class="o">==</span> <span class="s2">"winter"</span><span class="p">:</span>
|
||||
<span class="n">location</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">winter_desc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
|
||||
<span class="c1"># clear flag to force an update</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">reset_times</span><span class="p">(</span><span class="n">location</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">"Seasonal description was set on </span><span class="si">%s</span><span class="s2">."</span> <span class="o">%</span> <span class="n">location</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># No seasonal desc set, maybe this is not an extended room</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">:</span>
|
||||
<span class="n">text</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</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">lhs</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="p">:</span>
|
||||
<span class="k">return</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">text</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
|
||||
<span class="n">obj</span> <span class="o">=</span> <span class="n">location</span>
|
||||
<span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="n">text</span> <span class="c1"># a compatibility fallback</span>
|
||||
<span class="k">if</span> <span class="n">obj</span><span class="o">.</span><span class="n">attributes</span><span class="o">.</span><span class="n">has</span><span class="p">(</span><span class="s2">"general_desc"</span><span class="p">):</span>
|
||||
<span class="n">obj</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">general_desc</span> <span class="o">=</span> <span class="n">text</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">reset_times</span><span class="p">(</span><span class="n">obj</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">"General description was set on </span><span class="si">%s</span><span class="s2">."</span> <span class="o">%</span> <span class="n">obj</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># this is not an ExtendedRoom.</span>
|
||||
<span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"The description was set on </span><span class="si">%s</span><span class="s2">."</span> <span class="o">%</span> <span class="n">obj</span><span class="o">.</span><span class="n">key</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="CmdExtendedRoomDetail"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomDetail">[docs]</a><span class="k">class</span> <span class="nc">CmdExtendedRoomDetail</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">"""</span>
|
||||
<span class="sd"> sets a detail on a room</span>
|
||||
|
||||
<span class="sd"> Usage:</span>
|
||||
<span class="sd"> @detail[/del] <key> [= <description>]</span>
|
||||
<span class="sd"> @detail <key>;<alias>;... = description</span>
|
||||
|
||||
<span class="sd"> Example:</span>
|
||||
<span class="sd"> @detail</span>
|
||||
<span class="sd"> @detail walls = The walls are covered in ...</span>
|
||||
<span class="sd"> @detail castle;ruin;tower = The distant ruin ...</span>
|
||||
<span class="sd"> @detail/del wall</span>
|
||||
<span class="sd"> @detail/del castle;ruin;tower</span>
|
||||
|
||||
<span class="sd"> This command allows to show the current room details if you enter it</span>
|
||||
<span class="sd"> without any argument. Otherwise, sets or deletes a detail on the current</span>
|
||||
<span class="sd"> room, if this room supports details like an extended room. To add new</span>
|
||||
<span class="sd"> detail, just use the @detail command, specifying the key, an equal sign</span>
|
||||
<span class="sd"> and the description. You can assign the same description to several</span>
|
||||
<span class="sd"> details using the alias syntax (replace key by alias1;alias2;alias3;...).</span>
|
||||
<span class="sd"> To remove one or several details, use the @detail/del switch.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"@detail"</span>
|
||||
<span class="n">locks</span> <span class="o">=</span> <span class="s2">"cmd:perm(Builder)"</span>
|
||||
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">"Building"</span>
|
||||
|
||||
<div class="viewcode-block" id="CmdExtendedRoomDetail.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomDetail.func">[docs]</a> <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">location</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="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">details</span> <span class="o">=</span> <span class="n">location</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">details</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">details</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"|rThe room </span><span class="si">{}</span><span class="s2"> doesn't have any detail set.|n"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">location</span><span class="p">))</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">details</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">([</span><span class="s2">"|y</span><span class="si">{}</span><span class="s2">|n: </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">desc</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">desc</span> <span class="ow">in</span> <span class="n">details</span><span class="o">.</span><span class="n">items</span><span class="p">()])</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Details on Room:</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">details</span><span class="p">))</span>
|
||||
<span class="k">return</span>
|
||||
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span> <span class="ow">and</span> <span class="s2">"del"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span><span class="p">:</span>
|
||||
<span class="n">detail</span> <span class="o">=</span> <span class="n">location</span><span class="o">.</span><span class="n">return_detail</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lhs</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">detail</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Detail '|y</span><span class="si">{}</span><span class="s2">|n' on Room:</span><span class="se">\n</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lhs</span><span class="p">,</span> <span class="n">detail</span><span class="p">))</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"Detail '</span><span class="si">{}</span><span class="s2">' not found."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lhs</span><span class="p">))</span>
|
||||
<span class="k">return</span>
|
||||
|
||||
<span class="n">method</span> <span class="o">=</span> <span class="s2">"set_detail"</span> <span class="k">if</span> <span class="s2">"del"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</span> <span class="k">else</span> <span class="s2">"del_detail"</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">location</span><span class="p">,</span> <span class="n">method</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">msg</span><span class="p">(</span><span class="s2">"Details cannot be set on </span><span class="si">%s</span><span class="s2">."</span> <span class="o">%</span> <span class="n">location</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">";"</span><span class="p">):</span>
|
||||
<span class="c1"># loop over all aliases, if any (if not, this will just be</span>
|
||||
<span class="c1"># the one key to loop over)</span>
|
||||
<span class="nb">getattr</span><span class="p">(</span><span class="n">location</span><span class="p">,</span> <span class="n">method</span><span class="p">)(</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="s2">"del"</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">switches</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">msg</span><span class="p">(</span><span class="s2">"Detail </span><span class="si">%s</span><span class="s2"> deleted, if it existed."</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">lhs</span><span class="p">)</span>
|
||||
<span class="k">else</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">msg</span><span class="p">(</span><span class="s2">"Detail set '</span><span class="si">%s</span><span class="s2">': '</span><span class="si">%s</span><span class="s2">'"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lhs</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">rhs</span><span class="p">))</span></div></div>
|
||||
|
||||
|
||||
<span class="c1"># Simple command to view the current time and season</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="CmdExtendedRoomGameTime"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomGameTime">[docs]</a><span class="k">class</span> <span class="nc">CmdExtendedRoomGameTime</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">"""</span>
|
||||
<span class="sd"> Check the game time</span>
|
||||
|
||||
<span class="sd"> Usage:</span>
|
||||
<span class="sd"> time</span>
|
||||
|
||||
<span class="sd"> Shows the current in-game time and season.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"time"</span>
|
||||
<span class="n">locks</span> <span class="o">=</span> <span class="s2">"cmd:all()"</span>
|
||||
<span class="n">help_category</span> <span class="o">=</span> <span class="s2">"General"</span>
|
||||
|
||||
<div class="viewcode-block" id="CmdExtendedRoomGameTime.func"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.CmdExtendedRoomGameTime.func">[docs]</a> <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">"""Reads time info from current room"""</span>
|
||||
<span class="n">location</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="k">if</span> <span class="ow">not</span> <span class="n">location</span> <span class="ow">or</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">location</span><span class="p">,</span> <span class="s2">"get_time_and_season"</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">msg</span><span class="p">(</span><span class="s2">"No location available - you are outside time."</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">season</span><span class="p">,</span> <span class="n">timeslot</span> <span class="o">=</span> <span class="n">location</span><span class="o">.</span><span class="n">get_time_and_season</span><span class="p">()</span>
|
||||
<span class="n">prep</span> <span class="o">=</span> <span class="s2">"a"</span>
|
||||
<span class="k">if</span> <span class="n">season</span> <span class="o">==</span> <span class="s2">"autumn"</span><span class="p">:</span>
|
||||
<span class="n">prep</span> <span class="o">=</span> <span class="s2">"an"</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="s2">"It's </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2"> day, in the </span><span class="si">%s</span><span class="s2">."</span> <span class="o">%</span> <span class="p">(</span><span class="n">prep</span><span class="p">,</span> <span class="n">season</span><span class="p">,</span> <span class="n">timeslot</span><span class="p">))</span></div></div>
|
||||
|
||||
|
||||
<span class="c1"># CmdSet for easily install all commands</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoomCmdSet"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoomCmdSet">[docs]</a><span class="k">class</span> <span class="nc">ExtendedRoomCmdSet</span><span class="p">(</span><span class="n">CmdSet</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Groups the extended-room commands.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<div class="viewcode-block" id="ExtendedRoomCmdSet.at_cmdset_creation"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.extended_room.html#evennia.contrib.grid.extended_room.extended_room.ExtendedRoomCmdSet.at_cmdset_creation">[docs]</a> <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">CmdExtendedRoomLook</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">CmdExtendedRoomDesc</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">CmdExtendedRoomDetail</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">CmdExtendedRoomGameTime</span><span class="p">)</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</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="nav-item nav-item-0"><a href="../../../../../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="../../../../index.html" >Module code</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="../../../../evennia.html" >evennia</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">evennia.contrib.grid.extended_room.extended_room</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2022, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,211 +0,0 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>evennia.contrib.grid.extended_room.tests — Evennia 1.0 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" />
|
||||
</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 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="../../../../index.html" >Module code</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="../../../../evennia.html" accesskey="U">evennia</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">evennia.contrib.grid.extended_room.tests</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>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="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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="tests.html">1.0 (develop branch)</a></li>
|
||||
<ul>
|
||||
<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">
|
||||
|
||||
<h1>Source code for evennia.contrib.grid.extended_room.tests</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">Testing of ExtendedRoom contrib</span>
|
||||
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">datetime</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
|
||||
<span class="kn">from</span> <span class="nn">mock</span> <span class="kn">import</span> <span class="n">Mock</span><span class="p">,</span> <span class="n">patch</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia.commands.default.tests</span> <span class="kn">import</span> <span class="n">BaseEvenniaCommandTest</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.objects.objects</span> <span class="kn">import</span> <span class="n">DefaultRoom</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">extended_room</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="ForceUTCDatetime"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.tests.html#evennia.contrib.grid.extended_room.tests.ForceUTCDatetime">[docs]</a><span class="k">class</span> <span class="nc">ForceUTCDatetime</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">):</span>
|
||||
|
||||
<span class="w"> </span><span class="sd">"""Force UTC datetime."""</span>
|
||||
|
||||
<div class="viewcode-block" id="ForceUTCDatetime.fromtimestamp"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.tests.html#evennia.contrib.grid.extended_room.tests.ForceUTCDatetime.fromtimestamp">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">fromtimestamp</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">timestamp</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""Force fromtimestamp to run with naive datetimes."""</span>
|
||||
<span class="k">return</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">utcfromtimestamp</span><span class="p">(</span><span class="n">timestamp</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="TestExtendedRoom"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.tests.html#evennia.contrib.grid.extended_room.tests.TestExtendedRoom">[docs]</a><span class="nd">@patch</span><span class="p">(</span><span class="s2">"evennia.contrib.grid.extended_room.extended_room.datetime.datetime"</span><span class="p">,</span> <span class="n">ForceUTCDatetime</span><span class="p">)</span>
|
||||
<span class="c1"># mock gametime to return April 9, 2064, at 21:06 (spring evening)</span>
|
||||
<span class="nd">@patch</span><span class="p">(</span><span class="s2">"evennia.utils.gametime.gametime"</span><span class="p">,</span> <span class="n">new</span><span class="o">=</span><span class="n">Mock</span><span class="p">(</span><span class="n">return_value</span><span class="o">=</span><span class="mi">2975000766</span><span class="p">))</span>
|
||||
<span class="k">class</span> <span class="nc">TestExtendedRoom</span><span class="p">(</span><span class="n">BaseEvenniaCommandTest</span><span class="p">):</span>
|
||||
<span class="n">room_typeclass</span> <span class="o">=</span> <span class="n">extended_room</span><span class="o">.</span><span class="n">ExtendedRoom</span>
|
||||
<span class="n">DETAIL_DESC</span> <span class="o">=</span> <span class="s2">"A test detail."</span>
|
||||
<span class="n">SPRING_DESC</span> <span class="o">=</span> <span class="s2">"A spring description."</span>
|
||||
<span class="n">OLD_DESC</span> <span class="o">=</span> <span class="s2">"Old description."</span>
|
||||
<span class="n">settings</span><span class="o">.</span><span class="n">TIME_ZONE</span> <span class="o">=</span> <span class="s2">"UTC"</span>
|
||||
|
||||
<div class="viewcode-block" id="TestExtendedRoom.setUp"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.tests.html#evennia.contrib.grid.extended_room.tests.TestExtendedRoom.setUp">[docs]</a> <span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">setUp</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_timeslot</span> <span class="o">=</span> <span class="s2">"afternoon"</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_season</span> <span class="o">=</span> <span class="s2">"winter"</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">details</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"testdetail"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">DETAIL_DESC</span><span class="p">}</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">spring_desc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">SPRING_DESC</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">desc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">OLD_DESC</span></div>
|
||||
|
||||
<div class="viewcode-block" id="TestExtendedRoom.test_return_appearance"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.tests.html#evennia.contrib.grid.extended_room.tests.TestExtendedRoom.test_return_appearance">[docs]</a> <span class="k">def</span> <span class="nf">test_return_appearance</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="c1"># get the appearance of a non-extended room for contrast purposes</span>
|
||||
<span class="n">old_desc</span> <span class="o">=</span> <span class="n">DefaultRoom</span><span class="o">.</span><span class="n">return_appearance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="p">)</span>
|
||||
<span class="c1"># the new appearance should be the old one, but with the desc switched</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
||||
<span class="n">old_desc</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">OLD_DESC</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">SPRING_DESC</span><span class="p">),</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="o">.</span><span class="n">return_appearance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">char1</span><span class="p">),</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="s2">"spring"</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_season</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="s2">"evening"</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="o">.</span><span class="n">ndb</span><span class="o">.</span><span class="n">last_timeslot</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="TestExtendedRoom.test_return_detail"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.tests.html#evennia.contrib.grid.extended_room.tests.TestExtendedRoom.test_return_detail">[docs]</a> <span class="k">def</span> <span class="nf">test_return_detail</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">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">DETAIL_DESC</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="o">.</span><span class="n">return_detail</span><span class="p">(</span><span class="s2">"testdetail"</span><span class="p">))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="TestExtendedRoom.test_cmdextendedlook"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.tests.html#evennia.contrib.grid.extended_room.tests.TestExtendedRoom.test_cmdextendedlook">[docs]</a> <span class="k">def</span> <span class="nf">test_cmdextendedlook</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">rid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">room1</span><span class="o">.</span><span class="n">id</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
|
||||
<span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomLook</span><span class="p">(),</span>
|
||||
<span class="s2">"here"</span><span class="p">,</span>
|
||||
<span class="s2">"Room(#</span><span class="si">{}</span><span class="s2">)</span><span class="se">\n</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rid</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">SPRING_DESC</span><span class="p">),</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomLook</span><span class="p">(),</span> <span class="s2">"testdetail"</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">DETAIL_DESC</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
|
||||
<span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomLook</span><span class="p">(),</span> <span class="s2">"nonexistent"</span><span class="p">,</span> <span class="s2">"Could not find 'nonexistent'."</span>
|
||||
<span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="TestExtendedRoom.test_cmdsetdetail"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.tests.html#evennia.contrib.grid.extended_room.tests.TestExtendedRoom.test_cmdsetdetail">[docs]</a> <span class="k">def</span> <span class="nf">test_cmdsetdetail</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">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"Details on Room"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
|
||||
<span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span>
|
||||
<span class="s2">"thingie = newdetail with spaces"</span><span class="p">,</span>
|
||||
<span class="s2">"Detail set 'thingie': 'newdetail with spaces'"</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span> <span class="s2">"thingie"</span><span class="p">,</span> <span class="s2">"Detail 'thingie' on Room:</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
|
||||
<span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span>
|
||||
<span class="s2">"/del thingie"</span><span class="p">,</span>
|
||||
<span class="s2">"Detail thingie deleted, if it existed."</span><span class="p">,</span>
|
||||
<span class="n">cmdstring</span><span class="o">=</span><span class="s2">"detail"</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span> <span class="s2">"thingie"</span><span class="p">,</span> <span class="s2">"Detail 'thingie' not found."</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># Test with aliases</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"Details on Room"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
|
||||
<span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span>
|
||||
<span class="s2">"thingie;other;stuff = newdetail with spaces"</span><span class="p">,</span>
|
||||
<span class="s2">"Detail set 'thingie;other;stuff': 'newdetail with spaces'"</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span> <span class="s2">"thingie"</span><span class="p">,</span> <span class="s2">"Detail 'thingie' on Room:</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span> <span class="s2">"other"</span><span class="p">,</span> <span class="s2">"Detail 'other' on Room:</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span> <span class="s2">"stuff"</span><span class="p">,</span> <span class="s2">"Detail 'stuff' on Room:</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span>
|
||||
<span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span>
|
||||
<span class="s2">"/del other;stuff"</span><span class="p">,</span>
|
||||
<span class="s2">"Detail other;stuff deleted, if it existed."</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span> <span class="s2">"other"</span><span class="p">,</span> <span class="s2">"Detail 'other' not found."</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomDetail</span><span class="p">(),</span> <span class="s2">"stuff"</span><span class="p">,</span> <span class="s2">"Detail 'stuff' not found."</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="TestExtendedRoom.test_cmdgametime"><a class="viewcode-back" href="../../../../../api/evennia.contrib.grid.extended_room.tests.html#evennia.contrib.grid.extended_room.tests.TestExtendedRoom.test_cmdgametime">[docs]</a> <span class="k">def</span> <span class="nf">test_cmdgametime</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">call</span><span class="p">(</span><span class="n">extended_room</span><span class="o">.</span><span class="n">CmdExtendedRoomGameTime</span><span class="p">(),</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"It's a spring day, in the evening."</span><span class="p">)</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</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="nav-item nav-item-0"><a href="../../../../../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="../../../../index.html" >Module code</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="../../../../evennia.html" >evennia</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">evennia.contrib.grid.extended_room.tests</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2022, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,415 +0,0 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>evennia.contrib.tutorials.evadventure.tests.test_combat — Evennia 1.0 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" />
|
||||
</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 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="../../../../../index.html" >Module code</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="../../../../../evennia.html" accesskey="U">evennia</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">evennia.contrib.tutorials.evadventure.tests.test_combat</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>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="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>Versions</h3>
|
||||
<ul>
|
||||
<li><a href="test_combat.html">1.0 (develop branch)</a></li>
|
||||
<ul>
|
||||
<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">
|
||||
|
||||
<h1>Source code for evennia.contrib.tutorials.evadventure.tests.test_combat</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">Test EvAdventure combat.</span>
|
||||
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">unittest.mock</span> <span class="kn">import</span> <span class="n">MagicMock</span><span class="p">,</span> <span class="n">patch</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">create</span>
|
||||
<span class="kn">from</span> <span class="nn">evennia.utils.test_resources</span> <span class="kn">import</span> <span class="n">BaseEvenniaTest</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">..</span> <span class="kn">import</span> <span class="n">combat_turnbased</span>
|
||||
<span class="kn">from</span> <span class="nn">..characters</span> <span class="kn">import</span> <span class="n">EvAdventureCharacter</span>
|
||||
<span class="kn">from</span> <span class="nn">..enums</span> <span class="kn">import</span> <span class="n">WieldLocation</span>
|
||||
<span class="kn">from</span> <span class="nn">..npcs</span> <span class="kn">import</span> <span class="n">EvAdventureMob</span>
|
||||
<span class="kn">from</span> <span class="nn">..objects</span> <span class="kn">import</span> <span class="n">EvAdventureConsumable</span><span class="p">,</span> <span class="n">EvAdventureRunestone</span><span class="p">,</span> <span class="n">EvAdventureWeapon</span>
|
||||
<span class="kn">from</span> <span class="nn">.mixins</span> <span class="kn">import</span> <span class="n">EvAdventureMixin</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest">[docs]</a><span class="k">class</span> <span class="nc">EvAdventureTurnbasedCombatHandlerTest</span><span class="p">(</span><span class="n">EvAdventureMixin</span><span class="p">,</span> <span class="n">BaseEvenniaTest</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Test methods on the turn-based combat handler.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">maxDiff</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="c1"># make sure to mock away all time-keeping elements</span>
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.setUp"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.setUp">[docs]</a> <span class="nd">@patch</span><span class="p">(</span>
|
||||
<span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased"</span>
|
||||
<span class="s2">".EvAdventureCombatHandler.interval"</span><span class="p">,</span>
|
||||
<span class="n">new</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="nd">@patch</span><span class="p">(</span>
|
||||
<span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased.delay"</span><span class="p">,</span>
|
||||
<span class="n">new</span><span class="o">=</span><span class="n">MagicMock</span><span class="p">(</span><span class="n">return_value</span><span class="o">=</span><span class="kc">None</span><span class="p">),</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">setUp</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">allow_combat</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">allow_death</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combatant</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">character</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">target</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span>
|
||||
<span class="n">EvAdventureMob</span><span class="p">,</span>
|
||||
<span class="n">key</span><span class="o">=</span><span class="s2">"testmonster"</span><span class="p">,</span>
|
||||
<span class="n">location</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="p">,</span>
|
||||
<span class="n">attributes</span><span class="o">=</span><span class="p">((</span><span class="s2">"is_idle"</span><span class="p">,</span> <span class="kc">True</span><span class="p">),),</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="c1"># this already starts turn 1</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span> <span class="o">=</span> <span class="n">combat_turnbased</span><span class="o">.</span><span class="n">join_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.tearDown"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.tearDown">[docs]</a> <span class="k">def</span> <span class="nf">tearDown</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">combathandler</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_remove_combatant"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_remove_combatant">[docs]</a> <span class="k">def</span> <span class="nf">test_remove_combatant</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">assertTrue</span><span class="p">(</span><span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combathandler</span><span class="p">))</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">remove_combatant</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">combatants</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">combathandler</span><span class="p">))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_start_turn"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_start_turn">[docs]</a> <span class="k">def</span> <span class="nf">test_start_turn</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">combathandler</span><span class="o">.</span><span class="n">_start_turn</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">turn</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">_start_turn</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">turn</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_end_of_turn__empty"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_end_of_turn__empty">[docs]</a> <span class="k">def</span> <span class="nf">test_end_of_turn__empty</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">combathandler</span><span class="o">.</span><span class="n">_end_turn</span><span class="p">()</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_add_combatant"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_add_combatant">[docs]</a> <span class="k">def</span> <span class="nf">test_add_combatant</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">combathandler</span><span class="o">.</span><span class="n">_init_menu</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span>
|
||||
<span class="n">combatant3</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">EvAdventureCharacter</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"testcharacter3"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">add_combatant</span><span class="p">(</span><span class="n">combatant3</span><span class="p">)</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">combatant3</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">combatants</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">_init_menu</span><span class="o">.</span><span class="n">assert_called_once</span><span class="p">()</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_start_combat"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_start_combat">[docs]</a> <span class="k">def</span> <span class="nf">test_start_combat</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">combathandler</span><span class="o">.</span><span class="n">_start_turn</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">start</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">start_combat</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">_start_turn</span><span class="o">.</span><span class="n">assert_called_once</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">start</span><span class="o">.</span><span class="n">assert_called_once</span><span class="p">()</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_combat_summary"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_combat_summary">[docs]</a> <span class="k">def</span> <span class="nf">test_combat_summary</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">get_combat_summary</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="s2">"You (4 / 4 health)"</span> <span class="ow">in</span> <span class="n">result</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="s2">"testmonster"</span> <span class="ow">in</span> <span class="n">result</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_msg"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_msg">[docs]</a> <span class="k">def</span> <span class="nf">test_msg</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">location</span><span class="o">.</span><span class="n">msg_contents</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"You hurt the target"</span><span class="p">,</span> <span class="n">combatant</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">msg_contents</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span>
|
||||
<span class="s2">"You hurt the target"</span><span class="p">,</span>
|
||||
<span class="n">from_obj</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">,</span>
|
||||
<span class="n">exclude</span><span class="o">=</span><span class="p">[],</span>
|
||||
<span class="n">mapping</span><span class="o">=</span><span class="p">{</span><span class="s2">"testchar"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">,</span> <span class="s2">"testmonster"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">},</span>
|
||||
<span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_gain_advantage"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_gain_advantage">[docs]</a> <span class="k">def</span> <span class="nf">test_gain_advantage</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">combathandler</span><span class="o">.</span><span class="n">gain_advantage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">advantage_matrix</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">][</span><span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">]))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_gain_disadvantage"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_gain_disadvantage">[docs]</a> <span class="k">def</span> <span class="nf">test_gain_disadvantage</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">combathandler</span><span class="o">.</span><span class="n">gain_disadvantage</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">disadvantage_matrix</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">][</span><span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">]))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_flee"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_flee">[docs]</a> <span class="k">def</span> <span class="nf">test_flee</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">combathandler</span><span class="o">.</span><span class="n">flee</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">fleeing_combatants</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_unflee"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_unflee">[docs]</a> <span class="k">def</span> <span class="nf">test_unflee</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">combathandler</span><span class="o">.</span><span class="n">unflee</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">fleeing_combatants</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_register_and_run_action"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_register_and_run_action">[docs]</a> <span class="k">def</span> <span class="nf">test_register_and_run_action</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">action_class</span> <span class="o">=</span> <span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionAttack</span>
|
||||
<span class="n">action</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">combatant_actions</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">][</span><span class="n">action_class</span><span class="o">.</span><span class="n">key</span><span class="p">]</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">register_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">,</span> <span class="n">action</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">action_queue</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">],</span> <span class="p">(</span><span class="n">action</span><span class="p">,</span> <span class="p">(),</span> <span class="p">{}))</span>
|
||||
|
||||
<span class="n">action</span><span class="o">.</span><span class="n">use</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">_end_turn</span><span class="p">()</span>
|
||||
<span class="n">action</span><span class="o">.</span><span class="n">use</span><span class="o">.</span><span class="n">assert_called_once</span><span class="p">()</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatHandlerTest.test_get_available_actions"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatHandlerTest.test_get_available_actions">[docs]</a> <span class="k">def</span> <span class="nf">test_get_available_actions</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">get_available_actions</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">result</span><span class="p">),</span> <span class="mi">7</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest">[docs]</a><span class="k">class</span> <span class="nc">EvAdventureTurnbasedCombatActionTest</span><span class="p">(</span><span class="n">EvAdventureMixin</span><span class="p">,</span> <span class="n">BaseEvenniaTest</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Test actions in turn_based combat.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.setUp"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.setUp">[docs]</a> <span class="nd">@patch</span><span class="p">(</span>
|
||||
<span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased"</span>
|
||||
<span class="s2">".EvAdventureCombatHandler.interval"</span><span class="p">,</span>
|
||||
<span class="n">new</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="nd">@patch</span><span class="p">(</span>
|
||||
<span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased.delay"</span><span class="p">,</span>
|
||||
<span class="n">new</span><span class="o">=</span><span class="n">MagicMock</span><span class="p">(</span><span class="n">return_value</span><span class="o">=</span><span class="kc">None</span><span class="p">),</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">setUp</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">allow_combat</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="o">.</span><span class="n">allow_death</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combatant</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">character</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combatant2</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">EvAdventureCharacter</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"testcharacter2"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">target</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span>
|
||||
<span class="n">EvAdventureMob</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"testmonster"</span><span class="p">,</span> <span class="n">attributes</span><span class="o">=</span><span class="p">((</span><span class="s2">"is_idle"</span><span class="p">,</span> <span class="kc">True</span><span class="p">),)</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="o">.</span><span class="n">hp</span> <span class="o">=</span> <span class="mi">4</span>
|
||||
|
||||
<span class="c1"># this already starts turn 1</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span> <span class="o">=</span> <span class="n">combat_turnbased</span><span class="o">.</span><span class="n">join_combat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_run_action</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">action</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">register_action</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">,</span> <span class="n">action</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">_end_turn</span><span class="p">()</span>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_do_nothing"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_do_nothing">[docs]</a> <span class="k">def</span> <span class="nf">test_do_nothing</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">combathandler</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionDoNothing</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">msg</span><span class="o">.</span><span class="n">assert_called</span><span class="p">()</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_attack__miss"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_attack__miss">[docs]</a> <span class="nd">@patch</span><span class="p">(</span><span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint"</span><span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">test_attack__miss</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mock_randint</span><span class="p">):</span>
|
||||
<span class="n">mock_randint</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">8</span> <span class="c1"># target has default armor 11, so 8+1 str will miss</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionAttack</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="o">.</span><span class="n">hp</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_attack__success__still_alive"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_attack__success__still_alive">[docs]</a> <span class="nd">@patch</span><span class="p">(</span><span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint"</span><span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">test_attack__success__still_alive</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mock_randint</span><span class="p">):</span>
|
||||
<span class="n">mock_randint</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">11</span> <span class="c1"># 11 + 1 str will hit beat armor 11</span>
|
||||
<span class="c1"># make sure target survives</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="o">.</span><span class="n">hp</span> <span class="o">=</span> <span class="mi">20</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionAttack</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="o">.</span><span class="n">hp</span><span class="p">,</span> <span class="mi">9</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_attack__success__kill"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_attack__success__kill">[docs]</a> <span class="nd">@patch</span><span class="p">(</span><span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint"</span><span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">test_attack__success__kill</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mock_randint</span><span class="p">):</span>
|
||||
<span class="n">mock_randint</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">11</span> <span class="c1"># 11 + 1 str will hit beat armor 11</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionAttack</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="o">.</span><span class="n">hp</span><span class="p">,</span> <span class="o">-</span><span class="mi">7</span><span class="p">)</span>
|
||||
<span class="c1"># after this the combat is over</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertIsNone</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">pk</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_stunt_fail"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_stunt_fail">[docs]</a> <span class="nd">@patch</span><span class="p">(</span><span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint"</span><span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">test_stunt_fail</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mock_randint</span><span class="p">):</span>
|
||||
<span class="n">mock_randint</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">8</span> <span class="c1"># fails 8+1 dex vs DEX 11 defence</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionStunt</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">advantage_matrix</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">],</span> <span class="p">{})</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">disadvantage_matrix</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">],</span> <span class="p">{})</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_stunt_advantage__success"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_stunt_advantage__success">[docs]</a> <span class="nd">@patch</span><span class="p">(</span><span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint"</span><span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">test_stunt_advantage__success</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mock_randint</span><span class="p">):</span>
|
||||
<span class="n">mock_randint</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">11</span> <span class="c1"># 11+1 dex vs DEX 11 defence is success</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionStunt</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
||||
<span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">advantage_matrix</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">][</span><span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">]),</span> <span class="kc">True</span>
|
||||
<span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_stunt_disadvantage__success"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_stunt_disadvantage__success">[docs]</a> <span class="nd">@patch</span><span class="p">(</span><span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint"</span><span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">test_stunt_disadvantage__success</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mock_randint</span><span class="p">):</span>
|
||||
<span class="n">mock_randint</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">11</span> <span class="c1"># 11+1 dex vs DEX 11 defence is success</span>
|
||||
<span class="n">action</span> <span class="o">=</span> <span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionStunt</span>
|
||||
<span class="n">action</span><span class="o">.</span><span class="n">give_advantage</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span>
|
||||
<span class="n">action</span><span class="p">,</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
||||
<span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">disadvantage_matrix</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">][</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">]),</span> <span class="kc">True</span>
|
||||
<span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_use_item"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_use_item">[docs]</a> <span class="k">def</span> <span class="nf">test_use_item</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Use up a potion during combat.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">item</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span>
|
||||
<span class="n">EvAdventureConsumable</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"Healing potion"</span><span class="p">,</span> <span class="n">attributes</span><span class="o">=</span><span class="p">[(</span><span class="s2">"uses"</span><span class="p">,</span> <span class="mi">2</span><span class="p">)]</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">item</span><span class="o">.</span><span class="n">uses</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionUseItem</span><span class="p">,</span> <span class="n">item</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">item</span><span class="o">.</span><span class="n">uses</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionUseItem</span><span class="p">,</span> <span class="n">item</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">item</span><span class="o">.</span><span class="n">pk</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="c1"># deleted, it was used up</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_swap_wielded_weapon_or_spell"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_swap_wielded_weapon_or_spell">[docs]</a> <span class="k">def</span> <span class="nf">test_swap_wielded_weapon_or_spell</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> First draw a weapon (from empty fists), then swap that out to another weapon, then</span>
|
||||
<span class="sd"> swap to a spell rune.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">sword</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">EvAdventureWeapon</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"sword"</span><span class="p">)</span>
|
||||
<span class="n">zweihander</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span>
|
||||
<span class="n">EvAdventureWeapon</span><span class="p">,</span>
|
||||
<span class="n">key</span><span class="o">=</span><span class="s2">"zweihander"</span><span class="p">,</span>
|
||||
<span class="n">attributes</span><span class="o">=</span><span class="p">((</span><span class="s2">"inventory_use_slot"</span><span class="p">,</span> <span class="n">WieldLocation</span><span class="o">.</span><span class="n">TWO_HANDS</span><span class="p">),),</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">runestone</span> <span class="o">=</span> <span class="n">create</span><span class="o">.</span><span class="n">create_object</span><span class="p">(</span><span class="n">EvAdventureRunestone</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="s2">"ice rune"</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># check hands are empty</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">weapon</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="s2">"Empty Fists"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">equipment</span><span class="o">.</span><span class="n">slots</span><span class="p">[</span><span class="n">WieldLocation</span><span class="o">.</span><span class="n">WEAPON_HAND</span><span class="p">],</span> <span class="kc">None</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">equipment</span><span class="o">.</span><span class="n">slots</span><span class="p">[</span><span class="n">WieldLocation</span><span class="o">.</span><span class="n">TWO_HANDS</span><span class="p">],</span> <span class="kc">None</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># swap to sword</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionSwapWieldedWeaponOrSpell</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">sword</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">weapon</span><span class="p">,</span> <span class="n">sword</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">equipment</span><span class="o">.</span><span class="n">slots</span><span class="p">[</span><span class="n">WieldLocation</span><span class="o">.</span><span class="n">WEAPON_HAND</span><span class="p">],</span> <span class="n">sword</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">equipment</span><span class="o">.</span><span class="n">slots</span><span class="p">[</span><span class="n">WieldLocation</span><span class="o">.</span><span class="n">TWO_HANDS</span><span class="p">],</span> <span class="kc">None</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># swap to zweihander (two-handed sword)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionSwapWieldedWeaponOrSpell</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">zweihander</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">weapon</span><span class="p">,</span> <span class="n">zweihander</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">equipment</span><span class="o">.</span><span class="n">slots</span><span class="p">[</span><span class="n">WieldLocation</span><span class="o">.</span><span class="n">WEAPON_HAND</span><span class="p">],</span> <span class="kc">None</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">equipment</span><span class="o">.</span><span class="n">slots</span><span class="p">[</span><span class="n">WieldLocation</span><span class="o">.</span><span class="n">TWO_HANDS</span><span class="p">],</span> <span class="n">zweihander</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># swap to runestone (also using two hands)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionSwapWieldedWeaponOrSpell</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">runestone</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">weapon</span><span class="p">,</span> <span class="n">runestone</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">equipment</span><span class="o">.</span><span class="n">slots</span><span class="p">[</span><span class="n">WieldLocation</span><span class="o">.</span><span class="n">WEAPON_HAND</span><span class="p">],</span> <span class="kc">None</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">equipment</span><span class="o">.</span><span class="n">slots</span><span class="p">[</span><span class="n">WieldLocation</span><span class="o">.</span><span class="n">TWO_HANDS</span><span class="p">],</span> <span class="n">runestone</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># swap back to normal one-handed sword</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionSwapWieldedWeaponOrSpell</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">sword</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">weapon</span><span class="p">,</span> <span class="n">sword</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">equipment</span><span class="o">.</span><span class="n">slots</span><span class="p">[</span><span class="n">WieldLocation</span><span class="o">.</span><span class="n">WEAPON_HAND</span><span class="p">],</span> <span class="n">sword</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="o">.</span><span class="n">equipment</span><span class="o">.</span><span class="n">slots</span><span class="p">[</span><span class="n">WieldLocation</span><span class="o">.</span><span class="n">TWO_HANDS</span><span class="p">],</span> <span class="kc">None</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_flee__success"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_flee__success">[docs]</a> <span class="k">def</span> <span class="nf">test_flee__success</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Test fleeing twice, leading to leaving combat.</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># first flee records the fleeing state</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionFlee</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">fleeing_combatants</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># second flee should remove combatant</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionFlee</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertIsNone</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">pk</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="EvAdventureTurnbasedCombatActionTest.test_flee__blocked"><a class="viewcode-back" href="../../../../../../api/evennia.contrib.tutorials.evadventure.tests.test_combat.html#evennia.contrib.tutorials.evadventure.tests.test_combat.EvAdventureTurnbasedCombatActionTest.test_flee__blocked">[docs]</a> <span class="nd">@patch</span><span class="p">(</span><span class="s2">"evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint"</span><span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">test_flee__blocked</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mock_randint</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">""" """</span>
|
||||
<span class="n">mock_randint</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="mi">11</span> <span class="c1"># means block will succeed</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_run_action</span><span class="p">(</span><span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionFlee</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">fleeing_combatants</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># other combatant blocks in the same turn</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">register_action</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combatant</span><span class="p">,</span> <span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionFlee</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="kc">None</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">register_action</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">,</span> <span class="n">combat_turnbased</span><span class="o">.</span><span class="n">CombatActionBlock</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">combatant</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">_end_turn</span><span class="p">()</span>
|
||||
<span class="c1"># the fleeing combatant should remain now</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">fleeing_combatants</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">combatant</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">combathandler</span><span class="o">.</span><span class="n">combatants</span><span class="p">)</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</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="nav-item nav-item-0"><a href="../../../../../../index.html">Evennia 1.0</a> »</li>
|
||||
<li class="nav-item nav-item-1"><a href="../../../../../index.html" >Module code</a> »</li>
|
||||
<li class="nav-item nav-item-2"><a href="../../../../../evennia.html" >evennia</a> »</li>
|
||||
<li class="nav-item nav-item-this"><a href="">evennia.contrib.tutorials.evadventure.tests.test_combat</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer" role="contentinfo">
|
||||
© Copyright 2022, The Evennia developer community.
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
# Continuous Integration - TeamCity (linux)
|
||||
|
||||
This sets up a TeamCity build integration environment on Linux.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Follow [TeamCity](https://www.jetbrains.com/teamcity/) 's in-depth
|
||||
[Setup Guide](https://confluence.jetbrains.com/display/TCD8/Installing+and+Configuring+the+TeamCity+Server).
|
||||
- You need to use [Version Control](./Version-Control.md).
|
||||
|
||||
After meeting the preparation steps for your specific environment, log on to your teamcity interface
|
||||
at `http://<your server>:8111/`.
|
||||
|
||||
Create a new project named "Evennia" and in it construct a new template called `continuous-integration`.
|
||||
|
||||
## A Quick Overview
|
||||
|
||||
_Templates_ are fancy objects in TeamCity that allow an administrator to define build steps that are
|
||||
shared between one or more build projects. Assigning a VCS Root (Source Control) is unnecessary at
|
||||
this stage, primarily you'll be worrying about the build steps and your default parameters (both
|
||||
visible on the tabs to the left.)
|
||||
|
||||
## Template Setup
|
||||
|
||||
In this template, you'll be outlining the steps necessary to build your specific game. (A number of
|
||||
sample scripts are provided under this section below!) Click Build Steps and prepare your general
|
||||
flow. For this example, we will be doing a few basic example steps:
|
||||
|
||||
* Transforming the Settings.py file - We do this to update ports or other information that make your production
|
||||
environment unique from your development environment.
|
||||
* Making migrations and migrating the game database.
|
||||
* Publishing the game files.
|
||||
* Reloading the server.
|
||||
|
||||
For each step we'll being use the "Command Line Runner" (a fancy name for a shell script executor).
|
||||
|
||||
Create a build step with the name: "Transform Configuration" and add the script:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Replaces the game configuration with one
|
||||
# appropriate for this deployment.
|
||||
|
||||
CONFIG="%system.teamcity.build.checkoutDir%/server/conf/settings.py"
|
||||
MYCONF="%system.teamcity.build.checkoutDir%/server/conf/my.cnf"
|
||||
|
||||
sed -e 's/TELNET_PORTS = [4000]/TELNET_PORTS = [%game.ports%]/g' "$CONFIG" > "$CONFIG".tmp && mv
|
||||
"$CONFIG".tmp "$CONFIG"
|
||||
sed -e 's/WEBSERVER_PORTS = [(4001, 4002)]/WEBSERVER_PORTS = [%game.webports%]/g' "$CONFIG" >
|
||||
"$CONFIG".tmp && mv "$CONFIG".tmp "$CONFIG"
|
||||
``````
|
||||
|
||||
```bash
|
||||
|
||||
# settings.py MySQL DB configuration
|
||||
echo Configuring Game Database...
|
||||
echo "" >> "$CONFIG"
|
||||
echo "######################################################################" >> "$CONFIG"
|
||||
echo "# MySQL Database Configuration" >> "$CONFIG"
|
||||
echo "######################################################################" >> "$CONFIG"
|
||||
|
||||
echo "DATABASES = {" >> "$CONFIG"
|
||||
echo " 'default': {" >> "$CONFIG"
|
||||
echo " 'ENGINE': 'django.db.backends.mysql'," >> "$CONFIG"
|
||||
echo " 'OPTIONS': {" >> "$CONFIG"
|
||||
echo " 'read_default_file': 'server/conf/my.cnf'," >> "$CONFIG"
|
||||
echo " }," >> "$CONFIG"
|
||||
echo " }" >> "$CONFIG"
|
||||
echo "}" >> "$CONFIG"
|
||||
|
||||
# Create the My.CNF file.
|
||||
echo "[client]" >> "$MYCONF"
|
||||
echo "database = %mysql.db%" >> "$MYCONF"
|
||||
echo "user = %mysql.user%" >> "$MYCONF"
|
||||
echo "password = %mysql.pass%" >> "$MYCONF"
|
||||
echo "default-character-set = utf8" >> "$MYCONF"
|
||||
|
||||
```
|
||||
|
||||
If you look at the parameters side of the page after saving this script, you'll notice that some new
|
||||
parameters have been populated for you. This is because we've included new teamcity configuration
|
||||
parameters that are populated when the build itself is ran. When creating projects that inherit this
|
||||
template, we'll be able to fill in or override those parameters for project-specific configuration.
|
||||
|
||||
Go ahead and create another build step called "Make Database Migration"
|
||||
If you're using Sqlite3 for your game (default database), it's prudent to change working directory on this
|
||||
step to your game dir.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Update the DB migration
|
||||
|
||||
LOGDIR="server/logs"
|
||||
|
||||
. %evenv.dir%/bin/activate
|
||||
|
||||
# Check that the logs directory exists.
|
||||
if [ ! -d "$LOGDIR" ]; then
|
||||
# Control will enter here if $LOGDIR doesn't exist.
|
||||
mkdir "$LOGDIR"
|
||||
fi
|
||||
|
||||
evennia makemigrations
|
||||
```
|
||||
|
||||
Create yet another build step, this time named: "Execute Database Migration":
|
||||
If you're using Sqlite3 for your game (default database), it's prudent to change working directory on this
|
||||
step to your game dir.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Apply the database migration.
|
||||
|
||||
LOGDIR="server/logs"
|
||||
|
||||
. %evenv.dir%/bin/activate
|
||||
|
||||
# Check that the logs directory exists.
|
||||
if [ ! -d "$LOGDIR" ]; then
|
||||
# Control will enter here if $LOGDIR doesn't exist.
|
||||
mkdir "$LOGDIR"
|
||||
fi
|
||||
|
||||
evennia migrate
|
||||
|
||||
```
|
||||
|
||||
Our next build step is where we actually publish our build. Up until now, all work on game has been
|
||||
done in a 'work' directory on TeamCity's build agent. From that directory we will now copy our files
|
||||
to where our game actually exists on the local server.
|
||||
|
||||
Create a new build step called "Publish Build". If you're using SQlite3 on your game, be sure to order this step ABOVE
|
||||
the Database Migration steps. The build order will matter!
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Publishes the build to the proper build directory.
|
||||
|
||||
DIRECTORY="<game_dir>"
|
||||
|
||||
if [ ! -d "$DIRECTORY" ]; then
|
||||
# Control will enter here if $DIRECTORY doesn't exist.
|
||||
mkdir "$DIRECTORY"
|
||||
fi
|
||||
|
||||
# Copy all the files.
|
||||
cp -ruv %teamcity.build.checkoutDir%/* "$DIRECTORY"
|
||||
chmod -R 775 "$DIRECTORY"
|
||||
|
||||
```
|
||||
|
||||
Finally the last script will reload our game for us.
|
||||
|
||||
Create a new script called "Reload Game":
|
||||
The working directory on this build step will be: `%game.dir%`
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Apply the database migration.
|
||||
|
||||
LOGDIR="server/logs"
|
||||
PIDDIR="server/server.pid"
|
||||
|
||||
. %evenv.dir%/bin/activate
|
||||
|
||||
# Check that the logs directory exists.
|
||||
if [ ! -d "$LOGDIR" ]; then
|
||||
# Control will enter here if $LOGDIR doesn't exist.
|
||||
mkdir "$LOGDIR"
|
||||
fi
|
||||
|
||||
# Check that the server is running.
|
||||
if [ -d "$PIDDIR" ]; then
|
||||
# Control will enter here if the game is running.
|
||||
evennia reload
|
||||
fi
|
||||
```
|
||||
|
||||
Now the template is ready for use! It would be useful this time to revisit the parameters page and
|
||||
set the evenv parameter to the directory where your virtualenv exists: IE "/srv/mush/evenv".
|
||||
|
||||
### Creating the Project
|
||||
|
||||
Now it's time for the last few steps to set up a CI environment.
|
||||
|
||||
* Return to the Evennia Project overview/administration page.
|
||||
* Create a new Sub-Project called "Production". This will be the category that holds our actual game.
|
||||
* Create a new Build Configuration in Production with the name of your MUSH. Base this configuration off of the
|
||||
continuous-integration template we made earlier.
|
||||
* In the build configuration, enter VCS roots and create a new VCS root that points to the
|
||||
branch/version control that you are using.
|
||||
* Go to the parameters page and fill in the undefined parameters for your specific configuration.
|
||||
* If you wish for the CI to run every time a commit is made, go to the VCS triggers and add one for
|
||||
"On Every Commit".
|
||||
|
||||
And you're done! At this point, you can return to the project overview page and queue a new build
|
||||
for your game. If everything was set up correctly, the build will complete successfully. Additional
|
||||
build steps could be added or removed at this point, adding some features like Unit Testing or more!
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
# Continuous integration with Travis
|
||||
|
||||
[Travis CI](https://travis-ci.org/) is an online service for checking, validating and potentially
|
||||
deploying code automatically. It can check that every commit is building successfully after every
|
||||
commit to its Github repository.
|
||||
|
||||
If your game is open source on Github you may use Travis for free.
|
||||
See [the Travis docs](https://docs.travis-ci.com/user/getting- started/) for how to get started.
|
||||
|
||||
After logging in you will get to point Travis to your repository on github. One further thing you
|
||||
need to set up yourself is a Travis config file named `.travis.yml` (note the initial period `.`).
|
||||
This should be created in the root of your game directory. The idea with this file is that it
|
||||
describes what Travis needs to import and build in order to create an instance of Evennia from
|
||||
scratch and then run validation tests on it. Here is an example:
|
||||
|
||||
``` yaml
|
||||
language: python
|
||||
python:
|
||||
- "3.10"
|
||||
install:
|
||||
- git clone https://github.com/evennia/evennia.git
|
||||
- cd evennia
|
||||
- pip install -e .
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
script:
|
||||
- evennia migrate
|
||||
- evennia test --settings settings.py .
|
||||
```
|
||||
|
||||
This will tell travis how to download Evennia, install it, set up a database and then run
|
||||
your own test suite (inside the game dir). Use `evennia test evennia` if you also want to
|
||||
run the Evennia full test suite.
|
||||
|
||||
You need to add this file to git (`git add .travis.yml`) and then commit your changes before Travis
|
||||
will be able to see it.
|
||||
|
||||
For properly testing your game you of course also need to write unittests.
|
||||
The [Unit testing](./Unit-Testing.md) doc page gives some ideas on how to set those up for Evennia.
|
||||
You should be able to refer to that for making tests fitting your game.
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
# Continuous Integration (CI)
|
||||
|
||||
[Continuous Integration (CI)](https://www.thoughtworks.com/continuous-integration) is a development practice that requires developers to integrate code into a shared repository. Each check-in is then verified by an automated build, allowing teams to detect problems early. This can be set up to safely deploy data to a production server only after tests have passed, for example.
|
||||
|
||||
For Evennia, continuous integration allows an automated build process to:
|
||||
|
||||
* Pull down a latest build from Source Control.
|
||||
* Run migrations on the backing SQL database.
|
||||
* Automate additional unique tasks for that project.
|
||||
* Run unit tests.
|
||||
* Publish those files to the server directory
|
||||
* Reload the game.
|
||||
|
||||
## Continuous-Integration guides
|
||||
|
||||
There are a lot of tools and services providing CI functionality. Here are a few that people have used with Evennia:
|
||||
|
||||
```{toctree}
|
||||
:maxdepth: 1
|
||||
|
||||
Continuous-Integration-Travis.md
|
||||
Continuous-Integration-TeamCity.md
|
||||
|
||||
```
|
||||
|
||||
- Evennia is itself making heavy use of [github actions]()
|
||||
|
||||
[This is an overview of other tools](https://www.atlassian.com/continuous-delivery/continuous-integration/tools) (external link).
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
# Soft Code
|
||||
|
||||
|
||||
Softcode is a very simple programming language that was created for in-game development on TinyMUD derivatives such as MUX, PennMUSH, TinyMUSH, and RhostMUSH. The idea is that by providing a stripped down, minimalistic language for in-game use, you can allow quick and easy building and game development to happen without having to learn C/C++. There is an added benefit of not having to have to hand out shell access to all developers, and permissions can be used to alleviate many security problems.
|
||||
|
||||
Writing and installing softcode is done through a MUD client. Thus it is not a formatted language.
|
||||
Each softcode function is a single line of varying size. Some functions can be a half of a page long
|
||||
or more which is obviously not very readable nor (easily) maintainable over time.
|
||||
|
||||
## Examples of Softcode
|
||||
|
||||
Here is a simple 'Hello World!' command:
|
||||
|
||||
```bash
|
||||
@set me=HELLO_WORLD.C:$hello:@pemit %#=Hello World!
|
||||
```
|
||||
|
||||
Pasting this into a MUX/MUSH and typing 'hello' will theoretically yield 'Hello World!', assuming
|
||||
certain flags are not set on your account object.
|
||||
|
||||
Setting attributes is done via `@set`. Softcode also allows the use of the ampersand (`&`) symbol.
|
||||
This shorter version looks like this:
|
||||
|
||||
```bash
|
||||
&HELLO_WORLD.C me=$hello:@pemit %#=Hello World!
|
||||
```
|
||||
|
||||
Perhaps I want to break the Hello World into an attribute which is retrieved when emitting:
|
||||
|
||||
```bash
|
||||
&HELLO_VALUE.D me=Hello World
|
||||
&HELLO_WORLD.C me=$hello:@pemit %#=[v(HELLO_VALUE.D)]
|
||||
```
|
||||
|
||||
The `v()` function returns the `HELLO_VALUE.D` attribute on the object that the command resides
|
||||
(`me`, which is yourself in this case). This should yield the same output as the first example.
|
||||
|
||||
If you are still curious about how Softcode works, take a look at some external resources:
|
||||
|
||||
- https://wiki.tinymux.org/index.php/Softcode
|
||||
- https://www.duh.com/discordia/mushman/man2x1
|
||||
|
||||
## Problems with Softcode
|
||||
|
||||
Softcode is excellent at what it was intended for: *simple things*. It is a great tool for making an interactive object, a room with ambiance, simple global commands, simple economies and coded systems. However, once you start to try to write something like a complex combat system or a higher end economy, you're likely to find yourself buried under a mountain of functions that span multiple objects across your entire code.
|
||||
|
||||
Not to mention, softcode is not an inherently fast language. It is not compiled, it is parsed with each calling of a function. While MUX and MUSH parsers have jumped light years ahead of where they once were they can still stutter under the weight of more complex systems if not designed properly.
|
||||
|
||||
## Changing Times
|
||||
|
||||
Now that starting text-based games is easy and an option for even the most technically inarticulate, new projects are a dime a dozen. People are starting new MUDs every day with varying levels of commitment and ability. Because of this shift from fewer, larger, well-staffed games to a bunch of small, one or two developer games, some of the benefit of softcode fades.
|
||||
|
||||
Softcode is great in that it allows a mid to large sized staff all work on the same game without stepping on one another's toes. As mentioned before, shell access is not necessary to develop a MUX or a MUSH. However, now that we are seeing a lot more small, one or two-man shops, the issue of shell access and stepping on each other's toes is a lot less.
|
||||
|
||||
## Our Solution
|
||||
|
||||
Evennia shuns in-game softcode for on-disk Python modules. Python is a popular, mature and
|
||||
professional programming language. You code it using the conveniences of modern text editors.
|
||||
Evennia developers have access to the entire library of Python modules out there in the wild - not
|
||||
to mention the vast online help resources available. Python code is not bound to one-line functions
|
||||
on objects but complex systems may be organized neatly into real source code modules, sub-modules, or even broken out into entire Python packages as desired.
|
||||
|
||||
So what is *not* included in Evennia is a MUX/MOO-like online player-coding system. Advanced coding in Evennia is primarily intended to be done outside the game, in full-fledged Python modules. Advanced building is best handled by extending Evennia's command system with your own sophisticated building commands. We feel that with a small development team you are better off using a professional source-control system (svn, git, bazaar, mercurial etc) anyway.
|
||||
|
||||
## Your Solution
|
||||
|
||||
Adding advanced and flexible building commands to your game is easy and will probably be enough to satisfy most creative builders. However, if you really, *really* want to offer online coding, there is of course nothing stopping you from adding that to Evennia, no matter our recommendations. You could even re-implement MUX' softcode in Python should you be very ambitious. The [in-game-python](../Contribs/Contrib-Ingame-Python.md) is an optional pseudo-softcode plugin aimed at developers wanting to script their game from inside it.
|
||||
|
|
@ -1,205 +0,0 @@
|
|||
# Objects
|
||||
|
||||
```
|
||||
┌──────┐ │ ┌───────┐ ┌───────┐ ┌──────┐
|
||||
│Client├─┼──►│Session├───►│Account├──►│Object│
|
||||
└──────┘ │ └───────┘ └───────┘ └──────┘
|
||||
^
|
||||
```
|
||||
|
||||
All in-game objects in Evennia, be it characters, chairs, monsters, rooms or hand grenades are
|
||||
represented by an Evennia *Object*. Objects form the core of Evennia and is probably what you'll
|
||||
spend most time working with. Objects are [Typeclassed](./Typeclasses.md) entities.
|
||||
|
||||
An Evennia Object is, by definition, a Python class that includes [evennia.objects.objects.DefaultObject](evennia.objects.objects.DefaultObject) among its parents. Evennia defines several subclasses of `DefaultObject` in the following inheritance tree:
|
||||
|
||||
```
|
||||
┌────────────┐
|
||||
Evennia│ │ObjectParent│
|
||||
library│ └──────▲─────┘
|
||||
┌─────────────┐ │ ┌──────┐ │
|
||||
│DefaultObject◄────────────────────┼────┤Object├──────┤
|
||||
└──────▲──────┘ │ └──────┘ │
|
||||
│ ┌────────────────┐ │ ┌─────────┐ │
|
||||
├────────┤DefaultCharacter◄─┼────┤Character├───┤
|
||||
│ └────────────────┘ │ └─────────┘ │
|
||||
│ ┌────────────────┐ │ ┌────┐ │
|
||||
├────────┤DefaultRoom ◄─┼────┤Room├────────┤
|
||||
│ └────────────────┘ │ └────┘ │
|
||||
│ ┌────────────────┐ │ ┌────┐ │
|
||||
└────────┤DefaultExit ◄─┼────┤Exit├────────┘
|
||||
└────────────────┘ │ └────┘
|
||||
│Game-dir
|
||||
```
|
||||
|
||||
Here, arrows indicate inheritance and point from-child-to-parent.
|
||||
|
||||
So, for example `DefaultObjet` is a child of `DefaultCharacter` (in the Evennia library), which is a parent of `Character` (in the game dir). The class in the game-dir is the one you should modify for your game.
|
||||
|
||||
> Note the `ObjectParent` class. This is an empty mix-in that all classes in the game-dir inherits from. It's where you put things you want _all_ these classes to have.
|
||||
|
||||
- [evennia.objects.objects.DefaultCharacter](evennia.objects.objects.DefaultCharacter) - the normal in-game Character, controlled by a player.
|
||||
- [evennia.objects.objects.DefaultRoom](evennia.objects.objects.DefaultRoom) - a location in the game world.
|
||||
- [evennia.objects.objects.DefaultExit](evennia.objects.objects.DefaultExit) - an entity that in a location (usually a Room). It represents a one-way connection to another location.
|
||||
|
||||
Here are the import paths for the relevant child classes in the game dir
|
||||
|
||||
- `mygame.typeclasses.objects.Object` (inherits from `DefaultObject`)
|
||||
- `mygame.typeclasses.characters.Character` (inherits from `DefaultCharacter`)
|
||||
- `mygame.typeclasses.rooms.Room` (inherits from `DefaultRoom`)
|
||||
- `mygame.typeclasses.exits.Exit` (inherits from `DefaultExit`)
|
||||
|
||||
## Working with Objects
|
||||
|
||||
You can easily add your own in-game behavior by either modifying one of the typeclasses in your game dir or by inheriting from them.
|
||||
|
||||
You can put your new typeclass directly in the relevant module, or you could organize your code in some other way. Here we assume we make a new module `mygame/typeclasses/flowers.py`:
|
||||
|
||||
```python
|
||||
# mygame/typeclasses/flowers.py
|
||||
|
||||
from typeclasses.objects import Object
|
||||
|
||||
class Rose(Object):
|
||||
"""
|
||||
This creates a simple rose object
|
||||
"""
|
||||
def at_object_creation(self):
|
||||
"this is called only once, when object is first created"
|
||||
# add a persistent attribute 'desc'
|
||||
# to object (silly example).
|
||||
self.db.desc = "This is a pretty rose with thorns."
|
||||
```
|
||||
|
||||
Now you just need to point to the class *Rose* with the `create` command to make a new rose:
|
||||
|
||||
create/drop MyRose:flowers.Rose
|
||||
|
||||
What the `create` command actually *does* is to use the [evennia.create_object](evennia.utils.create.create_object) function. You can do the same thing yourself in code:
|
||||
|
||||
```python
|
||||
from evennia import create_object
|
||||
new_rose = create_object("typeclasses.flowers.Rose", key="MyRose")
|
||||
```
|
||||
|
||||
(The `create` command will auto-append the most likely path to your typeclass, if you enter the
|
||||
call manually you have to give the full path to the class. The `create.create_object` function is
|
||||
powerful and should be used for all coded object creating (so this is what you use when defining
|
||||
your own building commands).
|
||||
|
||||
This particular Rose class doesn't really do much, all it does it make sure the attribute
|
||||
`desc`(which is what the `look` command looks for) is pre-set, which is pretty pointless since you
|
||||
will usually want to change this at build time (using the `desc` command or using the [Spawner](./Prototypes.md)).
|
||||
|
||||
### Properties and functions on Objects
|
||||
|
||||
Beyond the properties assigned to all [typeclassed](./Typeclasses.md) objects (see that page for a list
|
||||
of those), the Object also has the following custom properties:
|
||||
|
||||
- `aliases` - a handler that allows you to add and remove aliases from this object. Use `aliases.add()` to add a new alias and `aliases.remove()` to remove one.
|
||||
- `location` - a reference to the object currently containing this object.
|
||||
- `home` is a backup location. The main motivation is to have a safe place to move the object to if its `location` is destroyed. All objects should usually have a home location for safety.
|
||||
- `destination` - this holds a reference to another object this object links to in some way. Its main use is for [Exits](./Objects.md#exits), it's otherwise usually unset.
|
||||
- `nicks` - as opposed to aliases, a [Nick](./Nicks.md) holds a convenient nickname replacement for a real name, word or sequence, only valid for this object. This mainly makes sense if the Object is used as a game character - it can then store briefer shorts, example so as to quickly reference game commands or other characters. Use nicks.add(alias, realname) to add a new one.
|
||||
- `account` - this holds a reference to a connected [Account](./Accounts.md) controlling this object (if any). Note that this is set also if the controlling account is *not* currently online - to test if an account is online, use the `has_account` property instead.
|
||||
- `sessions` - if `account` field is set *and the account is online*, this is a list of all active sessions (server connections) to contact them through (it may be more than one if multiple connections are allowed in settings).
|
||||
- `has_account` - a shorthand for checking if an *online* account is currently connected to this object.
|
||||
- `contents` - this returns a list referencing all objects 'inside' this object (i,e. which has this object set as their `location`).
|
||||
- `exits` - this returns all objects inside this object that are *Exits*, that is, has the `destination` property set.
|
||||
|
||||
The last two properties are special:
|
||||
|
||||
- `cmdset` - this is a handler that stores all [command sets](./Command-Sets.md) defined on the object (if any).
|
||||
- `scripts` - this is a handler that manages [Scripts](./Scripts.md) attached to the object (if any).
|
||||
|
||||
The Object also has a host of useful utility functions. See the function headers in `src/objects/objects.py` for their arguments and more details.
|
||||
|
||||
- `msg()` - this function is used to send messages from the server to an account connected to this object.
|
||||
- `msg_contents()` - calls `msg` on all objects inside this object.
|
||||
- `search()` - this is a convenient shorthand to search for a specific object, at a given location or globally. It's mainly useful when defining commands (in which case the object executing the command is named `caller` and one can do `caller.search()` to find objects in the room to operate on).
|
||||
- `execute_cmd()` - Lets the object execute the given string as if it was given on the command line.
|
||||
- `move_to` - perform a full move of this object to a new location. This is the main move method and will call all relevant hooks, do all checks etc.
|
||||
- `clear_exits()` - will delete all [Exits](./Objects.md#exits) to *and* from this object.
|
||||
- `clear_contents()` - this will not delete anything, but rather move all contents (except Exits) to their designated `Home` locations.
|
||||
- `delete()` - deletes this object, first calling `clear_exits()` and `clear_contents()`.
|
||||
|
||||
The Object Typeclass defines many more *hook methods* beyond `at_object_creation`. Evennia calls these hooks at various points. When implementing your custom objects, you will inherit from the base parent and overload these hooks with your own custom code. See `evennia.objects.objects` for an updated list of all the available hooks or the [API for DefaultObject here](evennia.objects.objects.DefaultObject).
|
||||
|
||||
|
||||
## Characters
|
||||
|
||||
The [DefaultCharacters](evennia.objects.objects.DefaultCharacter) is the root class for player in-game entities. They are usually _puppeted_ by [Accounts](./Accounts.md).
|
||||
|
||||
When a new Account logs in to Evennia for the first time, a new `Character` object is created and the Account object is assigned to the `account` attribute (but Evennia supports [alternative connection-styles](../Concepts/Connection-Styles.md) if so desired).
|
||||
|
||||
A `Character` object must have a [Default Commandset](./Command-Sets.md) set on itself at creation, or the account will not be able to issue any commands!
|
||||
|
||||
If you want to change the default character created by the default commands, you can change it in settings:
|
||||
|
||||
BASE_CHARACTER_TYPECLASS = "typeclasses.characters.Character"
|
||||
|
||||
This deafult points at the empty class in `mygame/typeclasses/characters.py` , ready for you to modify as you please.
|
||||
|
||||
## Rooms
|
||||
|
||||
[Rooms](evennia.objects.objects.DefaultRoom) are the root containers of all other objects.
|
||||
|
||||
The only thing really separating a room from any other object is that they have no `location` of their own and that default commands like `dig` creates objects of this class - so if you want to expand your rooms with more functionality, just inherit from `evennia.DefaultRoom`.
|
||||
|
||||
To change the default room created by `dig`, `tunnel` and other commands, change it in settings:
|
||||
|
||||
BASE_ROOM_TYPECLASS = "typeclases.rooms.Room"
|
||||
|
||||
The empty class in `mygame/typeclasses/rooms.py` is a good place to start!
|
||||
|
||||
## Exits
|
||||
|
||||
*Exits* are objects connecting other objects (usually *Rooms*) together. An object named *North* or *in* might be an exit, as well as *door*, *portal* or *jump out the window*. An exit has two things that separate them from other objects. Firstly, their *destination* property is set and points to a valid object. This fact makes it easy and fast to locate exits in the database. Secondly, exits define a special [Transit Command](./Commands.md) on themselves when they are created. This command is named the same as the exit object and will, when called, handle the practicalities of moving the character to the Exits's *destination* - this allows you to just enter the name of the exit on its own to move around, just as you would expect.
|
||||
|
||||
The exit functionality is all defined on the Exit typeclass, so you could in principle completely change how exits work in your game (it's not recommended though, unless you really know what you are doing). Exits are [locked](./Locks.md) using an access_type called *traverse* and also make use of a few hook methods for giving feedback if the traversal fails. See `evennia.DefaultExit` for more info.
|
||||
|
||||
Exits are normally overridden on a case-by-case basis, but if you want to change the default exit createad by rooms like `dig` , `tunnel` or `open` you can change it in settings:
|
||||
|
||||
BASE_EXIT_TYPECLASS = "typeclasses.exits.Exit"
|
||||
|
||||
In `mygame/typeclasses/exits.py` there is an empty `Exit` class for you to modify.
|
||||
|
||||
### Exit details
|
||||
|
||||
The process of traversing an exit is as follows:
|
||||
|
||||
1. The traversing `obj` sends a command that matches the Exit-command name on the Exit object. The [cmdhandler](./Commands.md) detects this and triggers the command defined on the Exit. Traversal always involves the "source" (the current location) and the `destination` (this is stored on the Exit object).
|
||||
1. The Exit command checks the `traverse` lock on the Exit object
|
||||
1. The Exit command triggers `at_traverse(obj, destination)` on the Exit object.
|
||||
1. In `at_traverse`, `object.move_to(destination)` is triggered. This triggers the following hooks, in order:
|
||||
1. `obj.at_pre_move(destination)` - if this returns False, move is aborted.
|
||||
1. `origin.at_pre_leave(obj, destination)`
|
||||
1. `obj.announce_move_from(destination)`
|
||||
1. Move is performed by changing `obj.location` from source location to `destination`.
|
||||
1. `obj.announce_move_to(source)`
|
||||
1. `destination.at_object_receive(obj, source)`
|
||||
1. `obj.at_post_move(source)`
|
||||
1. On the Exit object, `at_post_traverse(obj, source)` is triggered.
|
||||
|
||||
If the move fails for whatever reason, the Exit will look for an Attribute `err_traverse` on itself and display this as an error message. If this is not found, the Exit will instead call `at_failed_traverse(obj)` on itself.
|
||||
|
||||
## Adding common functionality
|
||||
|
||||
`Object`, `Character`, `Room` and `Exit` also inherit from `mygame.typeclasses.objects.ObjectParent`.
|
||||
This is an empty 'mixin' class. Optionally, you can modify this class if you want to easily add some _common_ functionality to all your Objects, Characters, Rooms and Exits at once. You can still customize each subclass separately (see the Python docs on [multiple inheritance](https://docs.python.org/3/tutorial/classes.html#multiple-inheritance) for details).
|
||||
|
||||
Here is an example:
|
||||
|
||||
```python
|
||||
# in mygame/typeclasses/objects.py
|
||||
# ...
|
||||
|
||||
from evennia.objects.objects import DefaultObject
|
||||
|
||||
class ObjectParent:
|
||||
def at_pre_get(self, getter, **kwargs):
|
||||
# make all entities by default un-pickable
|
||||
return False
|
||||
```
|
||||
|
||||
Now all of `Object`, `Exit`. `Room` and `Character` default to not being able to be picked up using the `get` command.
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
# Tags
|
||||
|
||||
```{code-block}
|
||||
:caption: In game
|
||||
> tag obj = tagname
|
||||
```
|
||||
```{code-block} python
|
||||
:caption: In code, using .tags (TagHandler)
|
||||
|
||||
obj.tags.add("mytag", category="foo")
|
||||
obj.tags.get("mytag", category="foo")
|
||||
```
|
||||
|
||||
```{code-block} python
|
||||
:caption: In code, using TagProperty (auto-assign tag to all instances of the class)
|
||||
|
||||
from evennia import DefaultObject
|
||||
from evennia import TagProperty
|
||||
class Sword(DefaultObject):
|
||||
can_be_wielded = TagProperty(category='combat')
|
||||
has_sharp_edge = TagProperty(category='combat')
|
||||
|
||||
```
|
||||
|
||||
_Tags_ are short text lables one can 'hang' on objects in order to organize, group and quickly find out their properties. An Evennia entity can be tagged by any number of tags. They are more efficient than [Attributes](./Attributes.md) since on the database-side, Tags are _shared_ between all objects with that particular tag. A tag does not carry a value in itself; it either sits on the entity
|
||||
|
||||
Above, the tags inform us that the `Sword` is both sharp and can be wielded. If that's all they do, they could just be a normal Python flag. When tags become important is if there are a lot of objects with different combinations of tags. Maybe you have a magical spell that dulls _all_ sharp-edged objects in the castle - whether sword, dagger, spear or kitchen knife! You can then just grab all objects with the `has_sharp_edge` tag.
|
||||
Another example would be a weather script affecting all rooms tagged as `outdoors` or finding all characters tagged with `belongs_to_fighter_guild`.
|
||||
|
||||
In Evennia, Tags are technically also used to implement `Aliases` (alternative names for objects) and `Permissions` (simple strings for [Locks](./Locks.md) to check for).
|
||||
|
||||
## Working with Tags
|
||||
|
||||
### Properties of Tags (and Aliases and Permissions)
|
||||
|
||||
Tags are *unique*. This means that there is only ever one Tag object with a given key and category.
|
||||
|
||||
> Not specifying a category (default) gives the tag a category of `None`, which is also considered a
|
||||
unique key + category combination.
|
||||
|
||||
When Tags are assigned to game entities, these entities are actually sharing the same Tag. This
|
||||
means that Tags are not suitable for storing information about a single object - use an
|
||||
[Attribute](./Attributes.md) for this instead. Tags are a lot more limited than Attributes but this also
|
||||
makes them very quick to lookup in the database - this is the whole point.
|
||||
|
||||
Tags have the following properties, stored in the database:
|
||||
|
||||
- **key** - the name of the Tag. This is the main property to search for when looking up a Tag.
|
||||
- **category** - this category allows for retrieving only specific subsets of tags used for
|
||||
different purposes. You could have one category of tags for "zones", another for "outdoor
|
||||
locations", for example. If not given, the category will be `None`, which is also considered a
|
||||
separate, default, category.
|
||||
- **data** - this is an optional text field with information about the tag. Remember that Tags are
|
||||
shared between entities, so this field cannot hold any object-specific information. Usually it would
|
||||
be used to hold info about the group of entities the Tag is tagging - possibly used for contextual
|
||||
help like a tool tip. It is not used by default.
|
||||
|
||||
There are also two special properties. These should usually not need to be changed or set, it is
|
||||
used internally by Evennia to implement various other uses it makes of the `Tag` object:
|
||||
- **model** - this holds a *natural-key* description of the model object that this tag deals with,
|
||||
on the form *application.modelclass*, for example `objects.objectdb`. It used by the TagHandler of
|
||||
each entity type for correctly storing the data behind the scenes.
|
||||
- **tagtype** - this is a "top-level category" of sorts for the inbuilt children of Tags, namely
|
||||
*Aliases* and *Permissions*. The Taghandlers using this special field are especially intended to
|
||||
free up the *category* property for any use you desire.
|
||||
|
||||
### Adding/Removing Tags
|
||||
|
||||
You can tag any *typeclassed* object, namely [Objects](./Objects.md), [Accounts](./Accounts.md), [Scripts](./Scripts.md) and [Channels](./Channels.md). General tags are added by the *Taghandler*. The tag handler is accessed as a property `tags` on the relevant entity:
|
||||
|
||||
```python
|
||||
mychair.tags.add("furniture")
|
||||
mychair.tags.add("furniture", category="luxurious")
|
||||
myroom.tags.add("dungeon#01")
|
||||
myscript.tags.add("weather", category="climate")
|
||||
myaccount.tags.add("guestaccount")
|
||||
|
||||
mychair.tags.all() # returns a list of Tags
|
||||
mychair.tags.remove("furniture")
|
||||
mychair.tags.clear()
|
||||
```
|
||||
|
||||
Adding a new tag will either create a new Tag or re-use an already existing one. Note that there are
|
||||
_two_ "furniture" tags, one with a `None` category, and one with the "luxurious" category.
|
||||
|
||||
When using `remove`, the `Tag` is not deleted but are just disconnected from the tagged object. This
|
||||
makes for very quick operations. The `clear` method removes (disconnects) all Tags from the object.
|
||||
You can also use the default `@tag` command:
|
||||
|
||||
@tag mychair = furniture
|
||||
|
||||
This tags the chair with a 'furniture' Tag (the one with a `None` category).
|
||||
|
||||
### Searching for objects with a given tag
|
||||
|
||||
Usually tags are used as a quick way to find tagged database entities. You can retrieve all objects
|
||||
with a given Tag like this in code:
|
||||
|
||||
```python
|
||||
import evennia
|
||||
|
||||
# all methods return Querysets
|
||||
|
||||
# search for objects
|
||||
objs = evennia.search_tag("furniture")
|
||||
objs2 = evennia.search_tag("furniture", category="luxurious")
|
||||
dungeon = evennia.search_tag("dungeon#01")
|
||||
forest_rooms = evennia.search_tag(category="forest")
|
||||
forest_meadows = evennia.search_tag("meadow", category="forest")
|
||||
magic_meadows = evennia.search_tag("meadow", category="magical")
|
||||
|
||||
# search for scripts
|
||||
weather = evennia.search_tag_script("weather")
|
||||
climates = evennia.search_tag_script(category="climate")
|
||||
|
||||
# search for accounts
|
||||
accounts = evennia.search_tag_account("guestaccount")
|
||||
```
|
||||
|
||||
> Note that searching for just "furniture" will only return the objects tagged with the "furniture" tag that has a category of `None`. We must explicitly give the category to get the "luxurious" furniture.
|
||||
|
||||
Using any of the `search_tag` variants will all return [Django Querysets](https://docs.djangoproject.com/en/2.1/ref/models/querysets/), including if you only have one match. You can treat querysets as lists and iterate over them, or continue building search queries with them.
|
||||
|
||||
Remember when searching that not setting a category means setting it to `None` - this does *not*
|
||||
mean that category is undefined, rather `None` is considered the default, unnamed category.
|
||||
|
||||
```python
|
||||
import evennia
|
||||
|
||||
myobj1.tags.add("foo") # implies category=None
|
||||
myobj2.tags.add("foo", category="bar")
|
||||
|
||||
# this returns a queryset with *only* myobj1
|
||||
objs = evennia.search_tag("foo")
|
||||
|
||||
# these return a queryset with *only* myobj2
|
||||
objs = evennia.search_tag("foo", category="bar")
|
||||
# or
|
||||
objs = evennia.search_tag(category="bar")
|
||||
```
|
||||
|
||||
There is also an in-game command that deals with assigning and using ([Object-](./Objects.md)) tags:
|
||||
|
||||
tag/search furniture
|
||||
|
||||
## Aliases and Permissions
|
||||
|
||||
Aliases and Permissions are implemented using normal TagHandlers that simply save Tags with a
|
||||
different `tagtype`. These handlers are named `aliases` and `permissions` on all Objects. They are
|
||||
used in the same way as Tags above:
|
||||
|
||||
```python
|
||||
boy.aliases.add("rascal")
|
||||
boy.permissions.add("Builders")
|
||||
boy.permissions.remove("Builders")
|
||||
|
||||
all_aliases = boy.aliases.all()
|
||||
```
|
||||
|
||||
and so on. Similarly to how `@tag` works in-game, there is also the `@perm` command for assigning
|
||||
permissions and `@alias` command for aliases.
|
||||
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
# TickerHandler
|
||||
|
||||
|
||||
One way to implement a dynamic MUD is by using "tickers", also known as "heartbeats". A ticker is a
|
||||
timer that fires ("ticks") at a given interval. The tick triggers updates in various game systems.
|
||||
|
||||
## About Tickers
|
||||
|
||||
Tickers are very common or even unavoidable in other mud code bases. Certain code bases are even
|
||||
hard-coded to rely on the concept of the global 'tick'. Evennia has no such notion - the decision to
|
||||
use tickers is very much up to the need of your game and which requirements you have. The "ticker
|
||||
recipe" is just one way of cranking the wheels.
|
||||
|
||||
The most fine-grained way to manage the flow of time is of course to use [Scripts](./Scripts.md). Many
|
||||
types of operations (weather being the classic example) are however done on multiple objects in the
|
||||
same way at regular intervals, and for this, storing separate Scripts on each object is inefficient.
|
||||
The way to do this is to use a ticker with a "subscription model" - let objects sign up to be
|
||||
triggered at the same interval, unsubscribing when the updating is no longer desired.
|
||||
|
||||
Evennia offers an optimized implementation of the subscription model - the *TickerHandler*. This is
|
||||
a singleton global handler reachable from `evennia.TICKER_HANDLER`. You can assign any *callable* (a
|
||||
function or, more commonly, a method on a database object) to this handler. The TickerHandler will
|
||||
then call this callable at an interval you specify, and with the arguments you supply when adding
|
||||
it. This continues until the callable un-subscribes from the ticker. The handler survives a reboot
|
||||
and is highly optimized in resource usage.
|
||||
|
||||
Here is an example of importing `TICKER_HANDLER` and using it:
|
||||
|
||||
```python
|
||||
# we assume that obj has a hook "at_tick" defined on itself
|
||||
from evennia import TICKER_HANDLER as tickerhandler
|
||||
|
||||
tickerhandler.add(20, obj.at_tick)
|
||||
```
|
||||
|
||||
That's it - from now on, `obj.at_tick()` will be called every 20 seconds.
|
||||
|
||||
You can also import function and tick that:
|
||||
|
||||
```python
|
||||
from evennia import TICKER_HANDLER as tickerhandler
|
||||
from mymodule import myfunc
|
||||
|
||||
tickerhandler.add(30, myfunc)
|
||||
```
|
||||
|
||||
Removing (stopping) the ticker works as expected:
|
||||
|
||||
```python
|
||||
tickerhandler.remove(20, obj.at_tick)
|
||||
tickerhandler.remove(30, myfunc)
|
||||
```
|
||||
|
||||
Note that you have to also supply `interval` to identify which subscription to remove. This is
|
||||
because the TickerHandler maintains a pool of tickers and a given callable can subscribe to be
|
||||
ticked at any number of different intervals.
|
||||
|
||||
The full definition of the `tickerhandler.add` method is
|
||||
|
||||
```python
|
||||
tickerhandler.add(interval, callback,
|
||||
idstring="", persistent=True, *args, **kwargs)
|
||||
```
|
||||
|
||||
Here `*args` and `**kwargs` will be passed to `callback` every `interval` seconds. If `persistent`
|
||||
is `False`, this subscription will not survive a server reload.
|
||||
|
||||
Tickers are identified and stored by making a key of the callable itself, the ticker-interval, the
|
||||
`persistent` flag and the `idstring` (the latter being an empty string when not given explicitly).
|
||||
|
||||
Since the arguments are not included in the ticker's identification, the `idstring` must be used to
|
||||
have a specific callback triggered multiple times on the same interval but with different arguments:
|
||||
|
||||
```python
|
||||
tickerhandler.add(10, obj.update, "ticker1", True, 1, 2, 3)
|
||||
tickerhandler.add(10, obj.update, "ticker2", True, 4, 5)
|
||||
```
|
||||
|
||||
> Note that, when we want to send arguments to our callback within a ticker handler, we need to
|
||||
specify `idstring` and `persistent` before, unless we call our arguments as keywords, which would
|
||||
often be more readable:
|
||||
|
||||
```python
|
||||
tickerhandler.add(10, obj.update, caller=self, value=118)
|
||||
```
|
||||
|
||||
If you add a ticker with exactly the same combination of callback, interval and idstring, it will
|
||||
overload the existing ticker. This identification is also crucial for later removing (stopping) the
|
||||
subscription:
|
||||
|
||||
```python
|
||||
tickerhandler.remove(10, obj.update, idstring="ticker1")
|
||||
tickerhandler.remove(10, obj.update, idstring="ticker2")
|
||||
```
|
||||
|
||||
The `callable` can be on any form as long as it accepts the arguments you give to send to it in
|
||||
`TickerHandler.add`.
|
||||
|
||||
> Note that everything you supply to the TickerHandler will need to be pickled at some point to be
|
||||
saved into the database. Most of the time the handler will correctly store things like database
|
||||
objects, but the same restrictions as for [Attributes](./Attributes.md) apply to what the TickerHandler
|
||||
may store.
|
||||
|
||||
When testing, you can stop all tickers in the entire game with `tickerhandler.clear()`. You can also
|
||||
view the currently subscribed objects with `tickerhandler.all()`.
|
||||
|
||||
See the [Weather Tutorial](../Howtos/Tutorial-Weather-Effects.md) for an example of using the TickerHandler.
|
||||
|
||||
### When *not* to use TickerHandler
|
||||
|
||||
Using the TickerHandler may sound very useful but it is important to consider when not to use it.
|
||||
Even if you are used to habitually relying on tickers for everything in other code bases, stop and
|
||||
think about what you really need it for. This is the main point:
|
||||
|
||||
> You should *never* use a ticker to catch *changes*.
|
||||
|
||||
Think about it - you might have to run the ticker every second to react to the change fast enough.
|
||||
Most likely nothing will have changed at a given moment. So you are doing pointless calls (since
|
||||
skipping the call gives the same result as doing it). Making sure nothing's changed might even be
|
||||
computationally expensive depending on the complexity of your system. Not to mention that you might
|
||||
need to run the check *on every object in the database*. Every second. Just to maintain status quo
|
||||
...
|
||||
|
||||
Rather than checking over and over on the off-chance that something changed, consider a more
|
||||
proactive approach. Could you implement your rarely changing system to *itself* report when its
|
||||
status changes? It's almost always much cheaper/efficient if you can do things "on demand". Evennia
|
||||
itself uses hook methods for this very reason.
|
||||
|
||||
So, if you consider a ticker that will fire very often but which you expect to have no effect 99% of
|
||||
the time, consider handling things things some other way. A self-reporting on-demand solution is
|
||||
usually cheaper also for fast-updating properties. Also remember that some things may not need to be
|
||||
updated until someone actually is examining or using them - any interim changes happening up to that
|
||||
moment are pointless waste of computing time.
|
||||
|
||||
The main reason for needing a ticker is when you want things to happen to multiple objects at the
|
||||
same time without input from something else.
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
# Clickable links
|
||||
|
||||
Evennia supports clickable links for clients that supports it. This marks certain text so it can be
|
||||
clicked by a mouse and either trigger a given Evennia command, or open a URL in an external web
|
||||
browser. To support clickable links, Evennia requires the webclient or an third-party telnet client
|
||||
with [MXP](http://www.zuggsoft.com/zmud/mxp.htm) support (*Note: Evennia only supports clickable links, no other MXP features*).
|
||||
|
||||
- `|lc` to start the link, by defining the command to execute.
|
||||
- `|lu` to start the link, by defining the URL to open.
|
||||
- `|lt` to continue with the text to show to the user (the link text).
|
||||
- `|le` to end the link text and the link definition.
|
||||
|
||||
All elements must appear in exactly this order to make a valid link. For example,
|
||||
|
||||
```
|
||||
"If you go |lcnorth|ltto the north|le you will find a cottage."
|
||||
```
|
||||
|
||||
This will display as "If you go __to the north__ you will find a cottage." where clicking the link
|
||||
will execute the command `north`. If the client does not support clickable links, only the link text
|
||||
will be shown.
|
||||
|
||||
|
|
@ -1,264 +0,0 @@
|
|||
# New Models
|
||||
|
||||
*Note: This is considered an advanced topic.*
|
||||
|
||||
Evennia offers many convenient ways to store object data, such as via Attributes or Scripts. This is
|
||||
sufficient for most use cases. But if you aim to build a large stand-alone system, trying to squeeze
|
||||
your storage requirements into those may be more complex than you bargain for. Examples may be to
|
||||
store guild data for guild members to be able to change, tracking the flow of money across a game-
|
||||
wide economic system or implement other custom game systems that requires the storage of custom data
|
||||
in a quickly accessible way. Whereas [Tags](../Components/Tags.md) or [Scripts](../Components/Scripts.md) can handle many situations,
|
||||
sometimes things may be easier to handle by adding your own database model.
|
||||
|
||||
## Overview of database tables
|
||||
|
||||
SQL-type databases (which is what Evennia supports) are basically highly optimized systems for
|
||||
retrieving text stored in tables. A table may look like this
|
||||
|
||||
```
|
||||
id | db_key | db_typeclass_path | db_permissions ...
|
||||
------------------------------------------------------------------
|
||||
1 | Griatch | evennia.DefaultCharacter | Developers ...
|
||||
2 | Rock | evennia.DefaultObject | None ...
|
||||
```
|
||||
|
||||
Each line is considerably longer in your database. Each column is referred to as a "field" and every
|
||||
row is a separate object. You can check this out for yourself. If you use the default sqlite3
|
||||
database, go to your game folder and run
|
||||
|
||||
evennia dbshell
|
||||
|
||||
You will drop into the database shell. While there, try:
|
||||
|
||||
sqlite> .help # view help
|
||||
|
||||
sqlite> .tables # view all tables
|
||||
|
||||
# show the table field names for objects_objectdb
|
||||
sqlite> .schema objects_objectdb
|
||||
|
||||
# show the first row from the objects_objectdb table
|
||||
sqlite> select * from objects_objectdb limit 1;
|
||||
|
||||
sqlite> .exit
|
||||
|
||||
Evennia uses [Django](https://docs.djangoproject.com), which abstracts away the database SQL
|
||||
manipulation and allows you to search and manipulate your database entirely in Python. Each database
|
||||
table is in Django represented by a class commonly called a *model* since it describes the look of
|
||||
the table. In Evennia, Objects, Scripts, Channels etc are examples of Django models that we then
|
||||
extend and build on.
|
||||
|
||||
## Adding a new database table
|
||||
|
||||
Here is how you add your own database table/models:
|
||||
|
||||
1. In Django lingo, we will create a new "application" - a subsystem under the main Evennia program.
|
||||
For this example we'll call it "myapp". Run the following (you need to have a working Evennia
|
||||
running before you do this, so make sure you have run the steps in [Setup Quickstart](Getting-
|
||||
Started) first):
|
||||
|
||||
cd mygame/world
|
||||
evennia startapp myapp
|
||||
|
||||
1. A new folder `myapp` is created. "myapp" will also be the name (the "app label") from now on. We
|
||||
chose to put it in the `world/` subfolder here, but you could put it in the root of your `mygame` if
|
||||
that makes more sense.
|
||||
1. The `myapp` folder contains a few empty default files. What we are
|
||||
interested in for now is `models.py`. In `models.py` you define your model(s). Each model will be a
|
||||
table in the database. See the next section and don't continue until you have added the models you
|
||||
want.
|
||||
1. You now need to tell Evennia that the models of your app should be a part of your database
|
||||
scheme. Add this line to your `mygame/server/conf/settings.py`file (make sure to use the path where
|
||||
you put `myapp` and don't forget the comma at the end of the tuple):
|
||||
|
||||
```
|
||||
INSTALLED_APPS = INSTALLED_APPS + ("world.myapp", )
|
||||
```
|
||||
|
||||
1. From `mygame/`, run
|
||||
|
||||
evennia makemigrations myapp
|
||||
evennia migrate
|
||||
|
||||
This will add your new database table to the database. If you have put your game under version
|
||||
control (if not, [you should](../Coding/Version-Control.md)), don't forget to `git add myapp/*` to add all items
|
||||
to version control.
|
||||
|
||||
## Defining your models
|
||||
|
||||
A Django *model* is the Python representation of a database table. It can be handled like any other
|
||||
Python class. It defines *fields* on itself, objects of a special type. These become the "columns"
|
||||
of the database table. Finally, you create new instances of the model to add new rows to the
|
||||
database.
|
||||
|
||||
We won't describe all aspects of Django models here, for that we refer to the vast [Django
|
||||
documentation](https://docs.djangoproject.com/en/2.2/topics/db/models/) on the subject. Here is a
|
||||
(very) brief example:
|
||||
|
||||
```python
|
||||
from django.db import models
|
||||
|
||||
class MyDataStore(models.Model):
|
||||
"A simple model for storing some data"
|
||||
db_key = models.CharField(max_length=80, db_index=True)
|
||||
db_category = models.CharField(max_length=80, null=True, blank=True)
|
||||
db_text = models.TextField(null=True, blank=True)
|
||||
# we need this one if we want to be
|
||||
# able to store this in an Evennia Attribute!
|
||||
db_date_created = models.DateTimeField('date created', editable=False,
|
||||
auto_now_add=True, db_index=True)
|
||||
```
|
||||
|
||||
We create four fields: two character fields of limited length and one text field which has no
|
||||
maximum length. Finally we create a field containing the current time of us creating this object.
|
||||
|
||||
> The `db_date_created` field, with exactly this name, is *required* if you want to be able to store
|
||||
instances of your custom model in an Evennia [Attribute](../Components/Attributes.md). It will automatically be set
|
||||
upon creation and can after that not be changed. Having this field will allow you to do e.g.
|
||||
`obj.db.myinstance = mydatastore`. If you know you'll never store your model instances in Attributes
|
||||
the `db_date_created` field is optional.
|
||||
|
||||
You don't *have* to start field names with `db_`, this is an Evennia convention. It's nevertheless
|
||||
recommended that you do use `db_`, partly for clarity and consistency with Evennia (if you ever want
|
||||
to share your code) and partly for the case of you later deciding to use Evennia's
|
||||
`SharedMemoryModel` parent down the line.
|
||||
|
||||
The field keyword `db_index` creates a *database index* for this field, which allows quicker
|
||||
lookups, so it's recommended to put it on fields you know you'll often use in queries. The
|
||||
`null=True` and `blank=True` keywords means that these fields may be left empty or set to the empty
|
||||
string without the database complaining. There are many other field types and keywords to define
|
||||
them, see django docs for more info.
|
||||
|
||||
Similar to using [django-admin](https://docs.djangoproject.com/en/2.2/howto/legacy-databases/) you
|
||||
are able to do `evennia inspectdb` to get an automated listing of model information for an existing
|
||||
database. As is the case with any model generating tool you should only use this as a starting
|
||||
point for your models.
|
||||
|
||||
## Creating a new model instance
|
||||
|
||||
To create a new row in your table, you instantiate the model and then call its `save()` method:
|
||||
|
||||
```python
|
||||
from evennia.myapp import MyDataStore
|
||||
|
||||
new_datastore = MyDataStore(db_key="LargeSword",
|
||||
db_category="weapons",
|
||||
db_text="This is a huge weapon!")
|
||||
# this is required to actually create the row in the database!
|
||||
new_datastore.save()
|
||||
|
||||
```
|
||||
|
||||
Note that the `db_date_created` field of the model is not specified. Its flag `at_now_add=True`
|
||||
makes sure to set it to the current date when the object is created (it can also not be changed
|
||||
further after creation).
|
||||
|
||||
When you update an existing object with some new field value, remember that you have to save the
|
||||
object afterwards, otherwise the database will not update:
|
||||
|
||||
```python
|
||||
my_datastore.db_key = "Larger Sword"
|
||||
my_datastore.save()
|
||||
```
|
||||
|
||||
Evennia's normal models don't need to explicitly save, since they are based on `SharedMemoryModel`
|
||||
rather than the raw django model. This is covered in the next section.
|
||||
|
||||
## Using the `SharedMemoryModel` parent
|
||||
|
||||
Evennia doesn't base most of its models on the raw `django.db.models` but on the Evennia base model
|
||||
`evennia.utils.idmapper.models.SharedMemoryModel`. There are two main reasons for this:
|
||||
|
||||
1. Ease of updating fields without having to explicitly call `save()`
|
||||
2. On-object memory persistence and database caching
|
||||
|
||||
The first (and least important) point means that as long as you named your fields `db_*`, Evennia
|
||||
will automatically create field wrappers for them. This happens in the model's
|
||||
[Metaclass](http://en.wikibooks.org/wiki/Python_Programming/Metaclasses) so there is no speed
|
||||
penalty for this. The name of the wrapper will be the same name as the field, minus the `db_`
|
||||
prefix. So the `db_key` field will have a wrapper property named `key`. You can then do:
|
||||
|
||||
```python
|
||||
my_datastore.key = "Larger Sword"
|
||||
```
|
||||
|
||||
and don't have to explicitly call `save()` afterwards. The saving also happens in a more efficient
|
||||
way under the hood, updating only the field rather than the entire model using django optimizations.
|
||||
Note that if you were to manually add the property or method `key` to your model, this will be used
|
||||
instead of the automatic wrapper and allows you to fully customize access as needed.
|
||||
|
||||
To explain the second and more important point, consider the following example using the default
|
||||
Django model parent:
|
||||
|
||||
```python
|
||||
shield = MyDataStore.objects.get(db_key="SmallShield")
|
||||
shield.cracked = True # where cracked is not a database field
|
||||
```
|
||||
|
||||
And then later:
|
||||
|
||||
```python
|
||||
shield = MyDataStore.objects.get(db_key="SmallShield")
|
||||
print(shield.cracked) # error!
|
||||
```
|
||||
|
||||
The outcome of that last print statement is *undefined*! It could *maybe* randomly work but most
|
||||
likely you will get an `AttributeError` for not finding the `cracked` property. The reason is that
|
||||
`cracked` doesn't represent an actual field in the database. It was just added at run-time and thus
|
||||
Django don't care about it. When you retrieve your shield-match later there is *no* guarantee you
|
||||
will get back the *same Python instance* of the model where you defined `cracked`, even if you
|
||||
search for the same database object.
|
||||
|
||||
Evennia relies heavily on on-model handlers and other dynamically created properties. So rather than
|
||||
using the vanilla Django models, Evennia uses `SharedMemoryModel`, which levies something called
|
||||
*idmapper*. The idmapper caches model instances so that we will always get the *same* instance back
|
||||
after the first lookup of a given object. Using idmapper, the above example would work fine and you
|
||||
could retrieve your `cracked` property at any time - until you rebooted when all non-persistent data
|
||||
goes.
|
||||
|
||||
Using the idmapper is both more intuitive and more efficient *per object*; it leads to a lot less
|
||||
reading from disk. The drawback is that this system tends to be more memory hungry *overall*. So if
|
||||
you know that you'll *never* need to add new properties to running instances or know that you will
|
||||
create new objects all the time yet rarely access them again (like for a log system), you are
|
||||
probably better off making "plain" Django models rather than using `SharedMemoryModel` and its
|
||||
idmapper.
|
||||
|
||||
To use the idmapper and the field-wrapper functionality you just have to have your model classes
|
||||
inherit from `evennia.utils.idmapper.models.SharedMemoryModel` instead of from the default
|
||||
`django.db.models.Model`:
|
||||
|
||||
```python
|
||||
from evennia.utils.idmapper.models import SharedMemoryModel
|
||||
|
||||
class MyDataStore(SharedMemoryModel):
|
||||
# the rest is the same as before, but db_* is important; these will
|
||||
# later be settable as .key, .category, .text ...
|
||||
db_key = models.CharField(max_length=80, db_index=True)
|
||||
db_category = models.CharField(max_length=80, null=True, blank=True)
|
||||
db_text = models.TextField(null=True, blank=True)
|
||||
db_date_created = models.DateTimeField('date created', editable=False,
|
||||
auto_now_add=True, db_index=True)
|
||||
```
|
||||
|
||||
## Searching for your models
|
||||
|
||||
To search your new custom database table you need to use its database *manager* to build a *query*.
|
||||
Note that even if you use `SharedMemoryModel` as described in the previous section, you have to use
|
||||
the actual *field names* in the query, not the wrapper name (so `db_key` and not just `key`).
|
||||
|
||||
```python
|
||||
from world.myapp import MyDataStore
|
||||
|
||||
# get all datastore objects exactly matching a given key
|
||||
matches = MyDataStore.objects.filter(db_key="Larger Sword")
|
||||
# get all datastore objects with a key containing "sword"
|
||||
# and having the category "weapons" (both ignoring upper/lower case)
|
||||
matches2 = MyDataStore.objects.filter(db_key__icontains="sword",
|
||||
db_category__iequals="weapons")
|
||||
# show the matching data (e.g. inside a command)
|
||||
for match in matches2:
|
||||
self.caller.msg(match.db_text)
|
||||
```
|
||||
|
||||
See the [Django query documentation](https://docs.djangoproject.com/en/2.2/topics/db/queries/) for a
|
||||
lot more information about querying the database.
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
# Dice roller
|
||||
|
||||
Contribution by Griatch, 2012
|
||||
|
||||
A dice roller for any number and side of dice. Adds in-game dice rolling
|
||||
(`roll 2d10 + 1`) as well as conditionals (roll under/over/equal to a target)
|
||||
and functions for rolling dice in code. Command also supports hidden or secret
|
||||
rolls for use by a human game master.
|
||||
|
||||
|
||||
## Installation:
|
||||
|
||||
|
||||
Add the `CmdDice` command from this module to your character's cmdset
|
||||
(and then restart the server):
|
||||
|
||||
```python
|
||||
# in mygame/commands/default_cmdsets.py
|
||||
|
||||
# ...
|
||||
from evennia.contrib.rpg import dice <---
|
||||
|
||||
class CharacterCmdSet(default_cmds.CharacterCmdSet):
|
||||
# ...
|
||||
def at_object_creation(self):
|
||||
# ...
|
||||
self.add(dice.CmdDice()) # <---
|
||||
|
||||
```
|
||||
|
||||
## Usage:
|
||||
|
||||
> roll 1d100 + 2
|
||||
> roll 1d20
|
||||
> roll 1d20 - 4
|
||||
|
||||
The result of the roll will be echoed to the room
|
||||
|
||||
One can also specify a standard Python operator in order to specify
|
||||
eventual target numbers and get results in a fair and guaranteed
|
||||
unbiased way. For example:
|
||||
|
||||
> roll 2d6 + 2 < 8
|
||||
|
||||
Rolling this will inform all parties if roll was indeed below 8 or not.
|
||||
|
||||
> roll/hidden
|
||||
|
||||
Informs the room that the roll is being made without telling what the result
|
||||
was.
|
||||
|
||||
> roll/secret
|
||||
|
||||
Is a hidden roll that does not inform the room it happened.
|
||||
|
||||
### Rolling dice from code
|
||||
|
||||
To roll dice in code, use the `roll` function from this module:
|
||||
|
||||
```python
|
||||
|
||||
from evennia.contrib.rpg import dice
|
||||
dice.roll(3, 10, ("+", 2)) # 3d10 + 2
|
||||
|
||||
```
|
||||
|
||||
|
||||
----
|
||||
|
||||
<small>This document page is generated from `evennia/contrib/rpg/dice/README.md`. Changes to this
|
||||
file will be overwritten, so edit that file rather than this one.</small>
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
# Extended Room
|
||||
|
||||
Contribution - Griatch 2012, vincent-lg 2019
|
||||
|
||||
This extends the normal `Room` typeclass to allow its description to change
|
||||
with time-of-day and/or season. It also adds 'details' for the player to look at
|
||||
in the room (without having to create a new in-game object for each). The room is
|
||||
supported by new `look` and `desc` commands.
|
||||
|
||||
## Installation/testing:
|
||||
|
||||
Adding the `ExtendedRoomCmdset` to the default character cmdset will add all
|
||||
new commands for use.
|
||||
|
||||
In more detail, in `mygame/commands/default_cmdsets.py`:
|
||||
|
||||
```python
|
||||
...
|
||||
from evennia.contrib import extended_room # <---
|
||||
|
||||
class CharacterCmdset(default_cmds.Character_CmdSet):
|
||||
...
|
||||
def at_cmdset_creation(self):
|
||||
...
|
||||
self.add(extended_room.ExtendedRoomCmdSet) # <---
|
||||
|
||||
```
|
||||
|
||||
Then reload to make the new commands available. Note that they only work
|
||||
on rooms with the typeclass `ExtendedRoom`. Create new rooms with the right
|
||||
typeclass or use the `typeclass` command to swap existing rooms.
|
||||
|
||||
## Features
|
||||
|
||||
### Time-changing description slots
|
||||
|
||||
This allows to change the full description text the room shows
|
||||
depending on larger time variations. Four seasons (spring, summer,
|
||||
autumn and winter) are used by default. The season is calculated
|
||||
on-demand (no Script or timer needed) and updates the full text block.
|
||||
|
||||
There is also a general description which is used as fallback if
|
||||
one or more of the seasonal descriptions are not set when their
|
||||
time comes.
|
||||
|
||||
An updated `desc` command allows for setting seasonal descriptions.
|
||||
|
||||
The room uses the `evennia.utils.gametime.GameTime` global script. This is
|
||||
started by default, but if you have deactivated it, you need to
|
||||
supply your own time keeping mechanism.
|
||||
|
||||
### In-description changing tags
|
||||
|
||||
Within each seasonal (or general) description text, you can also embed
|
||||
time-of-day dependent sections. Text inside such a tag will only show
|
||||
during that particular time of day. The tags looks like `<timeslot> ...
|
||||
</timeslot>`. By default there are four timeslots per day - morning,
|
||||
afternoon, evening and night.
|
||||
|
||||
### Details
|
||||
|
||||
The Extended Room can be "detailed" with special keywords. This makes
|
||||
use of a special `Look` command. Details are "virtual" targets to look
|
||||
at, without there having to be a database object created for it. The
|
||||
Details are simply stored in a dictionary on the room and if the look
|
||||
command cannot find an object match for a `look <target>` command it
|
||||
will also look through the available details at the current location
|
||||
if applicable. The `detail` command is used to change details.
|
||||
|
||||
### Extra commands
|
||||
|
||||
- `CmdExtendedRoomLook` - look command supporting room details
|
||||
- `CmdExtendedRoomDesc` - desc command allowing to add seasonal descs,
|
||||
- `CmdExtendedRoomDetail` - command allowing to manipulate details in this room
|
||||
as well as listing them
|
||||
- `CmdExtendedRoomGameTime` - A simple `time` command, displaying the current
|
||||
time and season.
|
||||
|
||||
|
||||
----
|
||||
|
||||
<small>This document page is generated from `evennia/contrib/grid/extended_room/README.md`. Changes to this
|
||||
file will be overwritten, so edit that file rather than this one.</small>
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
# Evennia Multidescer
|
||||
|
||||
Contribution by Griatch 2016
|
||||
|
||||
A "multidescer" is a concept from the MUSH world. It allows for
|
||||
creating, managing and switching between multiple character
|
||||
descriptions and is a way for quickly managing your look (such as when
|
||||
changing clothes) in more free-form roleplaying systems. This will also
|
||||
work well together with the `rpsystem` contrib.
|
||||
|
||||
This multidescer will not
|
||||
require any changes to the Character class, rather it will use the `multidescs`
|
||||
Attribute (a list) and create it if it does not exist.
|
||||
|
||||
## Installation
|
||||
|
||||
Edit `mygame/commands/default_cmdsets.py` and add
|
||||
`from evennia.contrib.game_systems.multidescer import CmdMultiDesc` to the top.
|
||||
|
||||
Next, look up the `at_cmdset_create` method of the `CharacterCmdSet`
|
||||
class and add a line `self.add(CmdMultiDesc())` to the end
|
||||
of it.
|
||||
|
||||
Reload the server and you should have the +desc command available (it
|
||||
will replace the default `desc` command).
|
||||
|
||||
|
||||
----
|
||||
|
||||
<small>This document page is generated from `evennia/contrib/game_systems/multidescer/README.md`. Changes to this
|
||||
file will be overwritten, so edit that file rather than this one.</small>
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
# Beginner Tutorial
|
||||
|
||||
```{sidebar} Beginner Tutorial Parts
|
||||
- **[Introduction](./Beginner-Tutorial-Overview.md)**
|
||||
<br>Getting set up.
|
||||
- Part 1: [What we have](Part1/Beginner-Tutorial-Part1-Overview.md)
|
||||
<br>A tour of Evennia and how to use the tools, including an introduction to Python.
|
||||
- Part 2: [What we want](Part2/Beginner-Tutorial-Part2-Overview.md)
|
||||
<br>Planning our tutorial game and what to think about when planning your own in the future.
|
||||
- Part 3: [How we get there](Part3/Beginner-Tutorial-Part3-Overview.md)
|
||||
<br>Getting down to the meat of extending Evennia to make our game
|
||||
- Part 4: [Using what we created](Part4/Beginner-Tutorial-Part4-Overview.md)
|
||||
<br>Building a tech-demo and world content to go with our code
|
||||
- Part 5: [Showing the world](Part5/Beginner-Tutorial-Part5-Overview.md)
|
||||
<br>Taking our new game online and let players try it out
|
||||
```
|
||||
|
||||
Welcome to Evennia! This multi-part Beginner Tutorial will help you get off the ground.
|
||||
|
||||
You can pick what seems interesting, but if you follow through to the end you will have created a little online game of your own to play and share with others!
|
||||
|
||||
Use the menu on the right to get the index of each tutorial-part. Use the [next](Part1/Beginner-Tutorial-Part1-Overview.md) and [previous](../Howtos-Overview.md) links at the top/bottom right of the page to step between lessons.
|
||||
|
||||
## Things you need
|
||||
|
||||
- A Command line
|
||||
- A MUD client (or web browser)
|
||||
- A text-editor/IDE
|
||||
- Evennia installed and a game-dir initialized
|
||||
|
||||
### A Command line
|
||||
|
||||
You need to know how to find your Terminal/Console in your OS. The Evennia server can be controlled from in-game, but you _will_ need to use the command-line to get anywhere. Here are some starters:
|
||||
|
||||
- [Online Intro to the Command line for different OS:es](https://tutorial.djangogirls.org/en/intro_to_command_line/)
|
||||
|
||||
> Note that we usually only show forward-slashes `/` for file system paths. Windows users should mentally convert this to back-slashes `\` instead.
|
||||
|
||||
### A MUD client
|
||||
|
||||
You might already have a MUD-client you prefer. Check out the [grid of supported clients](../../Setup/Client-Support-Grid.md).
|
||||
If telnet's not your thing, you can also just use Evennia's web client in your browser.
|
||||
|
||||
> In this documentation we often use the terms 'MUD', 'MU' or 'MU*' interchangeably to represent all the historically different forms of text-based multiplayer game-styles, like MUD, MUX, MUSH, MUCK, MOO and others. Evennia can be used to create all those game-styles and more.
|
||||
|
||||
### A text Editor or IDE
|
||||
|
||||
You need a text-editor to edit Python source files. Most everything that can edit and output raw
|
||||
text works (so not Word).
|
||||
|
||||
- [Here's a blog post summing up some of the alternatives](https://www.elegantthemes.com/blog/resources/best-code-editors) - these things don't change much from year to year. Popular choices for Python are PyCharm, VSCode, Atom, Sublime Text and Notepad++. Evennia is to a very large degree coded in VIM, but that's not suitable for beginners.
|
||||
|
||||
```{important} Use spaces, not tabs
|
||||
```
|
||||
> Make sure to configure your editor so that pressing TAB inserts _4 spaces_ rather than a Tab-character. Since Python is whitespace-aware, this will make your life a lot easier.
|
||||
|
||||
### A fresh game dir?
|
||||
|
||||
You should make sure you have [installed Evennia](../../Setup/Installation.md). If you followed the instructions you will already have created a game-dir.
|
||||
|
||||
You could re-use that or make a new one only for this tutorial, it's up to you.
|
||||
|
||||
If you already have a game dir and want a separate one for the tutorial, use `evennia stop` to halt the running server and then [Initialize a new game dir](../../Setup/Installation.md#initialize-a-new-game) somewhere else (_not_ inside the previous game dir!). We refer to it everywhere as `mygame`, so you may want to do the same.
|
||||
|
||||
You should now be ready to move on to the [first lesson](Part1/Beginner-Tutorial-Part1-Overview.md)
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
Click here to expand a list of all Beginner-Tutorial sections (all parts).
|
||||
</summary>
|
||||
|
||||
```{toctree}
|
||||
|
||||
Part1/Beginner-Tutorial-Part1-Overview
|
||||
Part2/Beginner-Tutorial-Part2-Overview
|
||||
Part3/Beginner-Tutorial-Part3-Overview
|
||||
Part4/Beginner-Tutorial-Part4-Overview
|
||||
Part5/Beginner-Tutorial-Part5-Overview
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
|
@ -1,308 +0,0 @@
|
|||
# Using commands and building stuff
|
||||
|
||||
In this lesson, we will test out what we can do in-game out-of-the-box. Evennia ships with
|
||||
[around 90 default commands](../../../Components/Default-Commands.md), and while you can override those as you please,
|
||||
the defaults can be quite useful.
|
||||
|
||||
Connect and log into your new game and you will end up in the "Limbo" location. This
|
||||
is the only room in the game at this point. Let's explore the commands a little.
|
||||
|
||||
The default commands has syntax [similar to MUX](../../../Coding/Default-Command-Syntax.md):
|
||||
|
||||
command[/switch/switch...] [arguments ...]
|
||||
|
||||
An example would be
|
||||
|
||||
create/drop box
|
||||
|
||||
A _/switch_ is a special, optional flag to the command to make it behave differently. It is always
|
||||
put directly after the command name, and begins with a forward slash (`/`). The _arguments_ are one
|
||||
or more inputs to the commands. It's common to use an equal sign (`=`) when assigning something to
|
||||
an object.
|
||||
|
||||
> Are you used to commands starting with @, like @create? That will work too. Evennia simply ignores
|
||||
> the preceeding @.
|
||||
|
||||
## Getting help
|
||||
|
||||
help
|
||||
|
||||
Will give you a list of all commands available to you. Use
|
||||
|
||||
help <commandname>
|
||||
|
||||
to see the in-game help for that command.
|
||||
|
||||
## Looking around
|
||||
|
||||
The most common comman is
|
||||
|
||||
look
|
||||
|
||||
This will show you the description of the current location. `l` is an alias.
|
||||
|
||||
When targeting objects in commands, you have two special labels you can use, `here` for the current
|
||||
room or `me`/`self` to point back to yourself. So
|
||||
|
||||
look me
|
||||
|
||||
will give you your own description. `look here` is, in this case, the same as plain `look`.
|
||||
|
||||
|
||||
## Stepping Down From Godhood
|
||||
|
||||
If you just installed Evennia, your very first player account is called user #1, also known as the
|
||||
_superuser_ or _god user_. This user is very powerful, so powerful that it will override many game
|
||||
restrictions (such as locks). This can be useful, but it also hides some functionality that you might
|
||||
want to test.
|
||||
|
||||
To temporarily step down from your superuser position, you can use the `quell` command in-game:
|
||||
|
||||
quell
|
||||
|
||||
This will make you start using the permission of your current character's level instead of your
|
||||
superuser level. If you didn't change any settings, your game Character should have an _Developer_
|
||||
level permission - high as can be without bypassing locks like the superuser does. This will work
|
||||
fine for the examples on this page. Use
|
||||
|
||||
unquell
|
||||
|
||||
to get superuser status again when you are done.
|
||||
|
||||
## Creating an Object
|
||||
|
||||
Basic objects can be anything -- swords, flowers, and non-player characters. They are created using
|
||||
the `create` command:
|
||||
|
||||
create box
|
||||
|
||||
This created a new 'box' (of the default object type) in your inventory. Use the command `inventory`
|
||||
(or `i`) to see it. Now, 'box' is a rather short name, let's rename it and tack on a few aliases.
|
||||
|
||||
name box = very large box;box;very;crate
|
||||
|
||||
```{warning} MUD clients and semi-colon:
|
||||
Some traditional MUD clients use the semi-colon `;` to separate client inputs. If so,
|
||||
the above line will give an error. You need to change your client to use another command-separator
|
||||
or to put it in 'verbatim' mode. If you still have trouble, use the Evennia web client instead.
|
||||
|
||||
```
|
||||
|
||||
|
||||
We now renamed the box to _very large box_ (and this is what we will see when looking at it), but we
|
||||
will also recognize it by any of the other names we give - like _crate_ or simply _box_ as before.
|
||||
We could have given these aliases directly after the name in the `create` command. This is true for
|
||||
all creation commands - you can always tag on a list of `;`-separated aliases to the name of your
|
||||
new object. If you had wanted to not change the name itself, but to only add aliases, you could have
|
||||
used the `alias` command.
|
||||
|
||||
We are currently carrying the box. Let's drop it (there is also a shortcut to create and drop in
|
||||
one go by using the `/drop` switch, for example `create/drop box`).
|
||||
|
||||
drop box
|
||||
|
||||
Hey presto - there it is on the ground, in all its normality.
|
||||
|
||||
examine box
|
||||
|
||||
This will show some technical details about the box object. For now we will ignore what this
|
||||
information means.
|
||||
|
||||
Try to `look` at the box to see the (default) description.
|
||||
|
||||
look box
|
||||
You see nothing special.
|
||||
|
||||
The description you get is not very exciting. Let's add some flavor.
|
||||
|
||||
desc box = This is a large and very heavy box.
|
||||
|
||||
If you try the `get` command, we will pick up the box. So far so good, but if we really want this to
|
||||
be a large and heavy box, people should _not_ be able to run off with it that easily. To prevent
|
||||
this we need to lock it down. This is done by assigning a _Lock_ to it. Make sure the box was
|
||||
dropped in the room, then try this:
|
||||
|
||||
lock box = get:false()
|
||||
|
||||
Locks represent a rather [big topic](../../../Components/Locks.md), but for now that will do what we want. This will lock
|
||||
the box so noone can lift it. The exception is superusers, they override all locks and will pick it
|
||||
up anyway. Make sure you are quelling your superuser powers and try to get the box now:
|
||||
|
||||
> get box
|
||||
You can't get that.
|
||||
|
||||
Think this default error message looks dull? The `get` command looks for an [Attribute](../../../Components/Attributes.md)
|
||||
named `get_err_msg` for returning a nicer error messageod (this can be seen from the default `get` command code). You set attributes using the `set` command:
|
||||
|
||||
set box/get_err_msg = It's way too heavy for you to lift.
|
||||
|
||||
Try to get it now and you should see a nicer error message echoed back to you. To see what this
|
||||
message string is in the future, you can use 'examine.'
|
||||
|
||||
examine box/get_err_msg
|
||||
|
||||
Examine will return the value of attributes, including color codes. `examine here/desc` would return
|
||||
the raw description of your current room (including color codes), so that you can copy-and-paste to
|
||||
set its description to something else.
|
||||
|
||||
You create new Commands (or modify existing ones) in Python outside the game. We will get to that
|
||||
later, in the [Commands tutorial](./Beginner-Tutorial-Adding-Commands.md).
|
||||
|
||||
## Get a Personality
|
||||
|
||||
[Scripts](../../../Components/Scripts.md) are powerful out-of-character objects useful for many "under the hood" things.
|
||||
One of their optional abilities is to do things on a timer. To try out a first script, let's put one
|
||||
on ourselves. There is an example script in `evennia/contrib/tutorials/bodyfunctions/bodyfunctions.py`
|
||||
that is called `BodyFunctions`. To add this to us we will use the `script` command:
|
||||
|
||||
script self = tutorials.bodyfunctions.BodyFunctions
|
||||
|
||||
This string will tell Evennia to dig up the Python code at the place we indicate. It already knows
|
||||
to look in the `contrib/` folder, so we don't have to give the full path.
|
||||
|
||||
> Note also how we use `.` instead of `/` (or `\` on Windows). This is a so-called "Python path". In a Python-path,
|
||||
> you separate the parts of the path with `.` and skip the `.py` file-ending. Importantly, it also allows you to point to
|
||||
Python code _inside_ files, like the `BodyFunctions` class inside `bodyfunctions.py` (we'll get to classes later).
|
||||
These "Python-paths" are used extensively throughout Evennia.
|
||||
|
||||
Wait a while and you will notice yourself starting making random observations ...
|
||||
|
||||
script self
|
||||
|
||||
This will show details about scripts on yourself (also `examine` works). You will see how long it is
|
||||
until it "fires" next. Don't be alarmed if nothing happens when the countdown reaches zero - this
|
||||
particular script has a randomizer to determine if it will say something or not. So you will not see
|
||||
output every time it fires.
|
||||
|
||||
When you are tired of your character's "insights", kill the script with
|
||||
|
||||
script/stop self = tutorials.bodyfunctions.BodyFunctions
|
||||
|
||||
You create your own scripts in Python, outside the game; the path you give to `script` is literally
|
||||
the Python path to your script file. The [Scripts](../../../Components/Scripts.md) page explains more details.
|
||||
|
||||
## Pushing Your Buttons
|
||||
|
||||
If we get back to the box we made, there is only so much fun you can have with it at this point. It's
|
||||
just a dumb generic object. If you renamed it to `stone` and changed its description, noone would be
|
||||
the wiser. However, with the combined use of custom [Typeclasses](../../../Components/Typeclasses.md), [Scripts](../../../Components/Scripts.md)
|
||||
and object-based [Commands](../../../Components/Commands.md), you could expand it and other items to be as unique, complex
|
||||
and interactive as you want.
|
||||
|
||||
Let's take an example. So far we have only created objects that use the default object typeclass
|
||||
named simply `Object`. Let's create an object that is a little more interesting. Under
|
||||
`evennia/contrib/tutorial_examples` there is a module `red_button.py`. It contains the enigmatic
|
||||
`RedButton` class.
|
||||
|
||||
Let's make us one of _those_!
|
||||
|
||||
create/drop button:tutorials.red_button.RedButton
|
||||
|
||||
The same way we did with the Script Earler, we specify a "Python-path" to the Python code we want Evennia
|
||||
to use for creating the object. There you go - one red button.
|
||||
|
||||
The RedButton is an example object intended to show off a few of Evennia's features. You will find
|
||||
that the [Typeclass](../../../Components/Typeclasses.md) and [Commands](../../../Components/Commands.md) controlling it are
|
||||
inside [evennia/contrib/tutorials/red_button](../../../api/evennia.contrib.tutorials.red_button.md)
|
||||
|
||||
If you wait for a while (make sure you dropped it!) the button will blink invitingly.
|
||||
|
||||
Why don't you try to push it ...?
|
||||
|
||||
Surely a big red button is meant to be pushed.
|
||||
|
||||
You know you want to.
|
||||
|
||||
```{warning} Don't press the invitingly blinking red button.
|
||||
```
|
||||
|
||||
## Making Yourself a House
|
||||
|
||||
The main command for shaping the game world is `dig`. For example, if you are standing in Limbo, you
|
||||
can dig a route to your new house location like this:
|
||||
|
||||
dig house = large red door;door;in,to the outside;out
|
||||
|
||||
This will create a new room named 'house'. Spaces at the start/end of names and aliases are ignored
|
||||
so you could put more air if you wanted. This call will directly create an exit from your current
|
||||
location named 'large red door' and a corresponding exit named 'to the outside' in the house room
|
||||
leading back to Limbo. We also define a few aliases to those exits, so people don't have to write
|
||||
the full thing all the time.
|
||||
|
||||
If you wanted to use normal compass directions (north, west, southwest etc), you could do that with
|
||||
`dig` too. But Evennia also has a limited version of `dig` that helps for compass directions (and
|
||||
also up/down and in/out). It's called `tunnel`:
|
||||
|
||||
tunnel sw = cliff
|
||||
|
||||
This will create a new room "cliff" with an exit "southwest" leading there and a path "northeast"
|
||||
leading back from the cliff to your current location.
|
||||
|
||||
You can create new exits from where you are, using the `open` command:
|
||||
|
||||
open north;n = house
|
||||
|
||||
This opens an exit `north` (with an alias `n`) to the previously created room `house`.
|
||||
|
||||
If you have many rooms named `house` you will get a list of matches and have to select which one you
|
||||
want to link to.
|
||||
|
||||
Follow the north exit to your 'house' or `teleport` to it:
|
||||
|
||||
north
|
||||
|
||||
or:
|
||||
|
||||
teleport house
|
||||
|
||||
To manually open an exit back to Limbo (if you didn't do so with the `dig` command):
|
||||
|
||||
open door = limbo
|
||||
|
||||
(You can also us the #dbref of limbo, which you can find by using `examine here` when in limbo).
|
||||
|
||||
## Reshuffling the World
|
||||
|
||||
You can find things using the `find` command. Assuming you are back at `Limbo`, let's teleport the
|
||||
_large box_ to our house.
|
||||
|
||||
teleport box = house
|
||||
very large box is leaving Limbo, heading for house.
|
||||
Teleported very large box -> house.
|
||||
|
||||
We can still find the box by using find:
|
||||
|
||||
find box
|
||||
One Match(#1-#8):
|
||||
very large box(#8) - src.objects.objects.Object
|
||||
|
||||
Knowing the `#dbref` of the box (#8 in this example), you can grab the box and get it back here
|
||||
without actually yourself going to `house` first:
|
||||
|
||||
teleport #8 = here
|
||||
|
||||
As mentioned, `here` is an alias for 'your current location'. The box should now be back in Limbo with you.
|
||||
|
||||
We are getting tired of the box. Let's destroy it.
|
||||
|
||||
destroy box
|
||||
|
||||
It will ask you for confirmation. Once you give it, the box will be gone.
|
||||
|
||||
You can destroy many objects in one go by giving a comma-separated list of objects (or a range
|
||||
of #dbrefs, if they are not in the same location) to the command.
|
||||
|
||||
## Adding a Help Entry
|
||||
|
||||
The Command-help is something you modify in Python code. We'll get to that when we get to how to
|
||||
add Commands. But you can also add regular help entries, for example to explain something about
|
||||
the history of your game world:
|
||||
|
||||
sethelp History = At the dawn of time ...
|
||||
|
||||
You will now find your new `History` entry in the `help` list and read your help-text with `help History`.
|
||||
|
||||
## Adding a World
|
||||
|
||||
After this brief introduction to building and using in-game commands you may be ready to see a more fleshed-out
|
||||
example. Evennia comes with a tutorial world for you to explore. We will try that out in the next lesson.
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
# Overview of your new Game Dir
|
||||
|
||||
Until now we have 'run the game' a bit and started playing with Python inside Evennia.
|
||||
It is time to start to look at how things look 'outside of the game'.
|
||||
|
||||
Let's do a tour of your game-dir (we assume it's called `mygame`).
|
||||
|
||||
> When looking through files, ignore files ending with `.pyc` and the
|
||||
`__pycache__` folder if it exists. This is internal Python compilation files that you should never
|
||||
> need to touch. Files `__init__.py` is also often empty and can be ignored (they have to do with
|
||||
> Python package management).
|
||||
|
||||
You may have noticed when we were building things in-game that we would often refer to code through "python paths", such as
|
||||
|
||||
create/drop button:tutorial_examples.red_button.RedButton
|
||||
|
||||
This is a fundamental aspect of coding Evennia - _you create code and then you tell Evennia where that code is and when it should be used_. Above we told it to create a red button by pulling from specific code in the `contrib/` folder. The same principle is true everywhere. So it's important to know where code is and how you point to it correctly.
|
||||
|
||||
```{sidebar} Python-paths
|
||||
A 'python path' uses '.' instead of '/' or '`\\`' and skips the `.py` ending of files. It can also point to the code contents of python files. Since Evennia is already looking for code in your game dir, your python paths can start from there. So a path `/home/foo/devel/mygame/commands/command.py` would translate to a Python-path `commands.command`.
|
||||
```
|
||||
|
||||
|
||||
- `mygame/`
|
||||
- `commands/` - This holds all your custom commands (user-input handlers). You both add your own
|
||||
and override Evennia's defaults from here.
|
||||
- `server`/ - The structure of this folder should not change since Evennia expects it.
|
||||
- `conf/` - All server configuration files sits here. The most important file is `settings.py`.
|
||||
- `logs/` - Server log files are stored here. When you use `evennia --log` you are actually
|
||||
tailing the files in this directory.
|
||||
- `typeclasses/` - this holds empty templates describing all database-bound entities in the
|
||||
game, like Characters, Scripts, Accounts etc. Adding code here allows to customize and extend
|
||||
the defaults.
|
||||
- `web/` - This is where you override and extend the default templates, views and static files used
|
||||
for Evennia's web-presence, like the website and the HTML5 webclient.
|
||||
- `world/` - this is a "miscellaneous" folder holding everything related to the world you are
|
||||
building, such as build scripts and rules modules that don't fit with one of the other folders.
|
||||
|
||||
> The `server/` subfolder should remain the way it is - Evennia expects this. But you can change the structure of the rest of your game dir as best fits your preferences.
|
||||
> Maybe you don't want a single world/ folder but prefer many folders with different aspects of your world? A new folder 'rules' for your RPG rules? Group your commands with your objects instead of having them separate? This is fine. If you move things around you just need to update Evennia's default settings to point to the right places in the new structure.
|
||||
|
||||
## commands/
|
||||
|
||||
The `commands/` folder holds Python modules related to creating and extending the [Commands](../../../Components/Commands.md)
|
||||
of Evennia. These manifest in game like the server understanding input like `look` or `dig`.
|
||||
|
||||
```{sidebar} Classes
|
||||
|
||||
A `class` is template for creating object-instances of a particular type in Python. We will explain classes in more detail in the next lesson.
|
||||
|
||||
```
|
||||
- [command.py](github:evennia/game_template/commands/command.py) (Python-path: `commands.command`) - this contain the
|
||||
base _classes_ for designing new input commands, or override the defaults.
|
||||
- [default_cmdsets.py](github:evennia/game_template/commands/default_cmdsets.py) (Python path: `commands.default_commands`) -
|
||||
a cmdset (Command-Set) groups Commands together. Command-sets can be added and removed from objects on the fly,
|
||||
meaning a user could have a different set of commands (or versions of commands) available depending on their circumstance
|
||||
in the game. In order to add a new command to the game, it's common to import the new command-class
|
||||
from `command.py` and add it to one of the default cmdsets in this module.
|
||||
|
||||
## server/
|
||||
|
||||
This folder contains resource necessary for running Evennia. Contrary to the other folders, the structure
|
||||
of this should be kept the way it is.
|
||||
|
||||
- `evennia.db3` - you will only have this file if you are using the default SQLite3 database. This file
|
||||
contains the entire database. Just copy it to make a backup. For development you could also just
|
||||
make a copy once you have set up everything you need and just copy that back to 'reset' the state.
|
||||
If you delete this file you can easily recreate it by running `evennia migrate`.
|
||||
|
||||
### server/logs/
|
||||
|
||||
This holds the server logs. When you do `evennia --log`, the evennia program is in fact tailing and concatenating
|
||||
the `server.log` and `portal.log` files in this directory. The logs are rotated every week. Depending on your settings,
|
||||
other logs, like the webserver HTTP request log can also be found here.
|
||||
|
||||
### server/conf/
|
||||
|
||||
This contains all configuration files of the Evennia server. These are regular Python modules which
|
||||
means that they must be extended with valid Python. You can also add logic to them if you wanted to.
|
||||
|
||||
Common for the settings is that you generally will never them directly via their python-path; instead Evennia
|
||||
knows where they are and will read them to configure itself at startup.
|
||||
|
||||
- `settings.py` - this is by far the most important file. It's nearly empty by default, rather you
|
||||
are expected to copy&paste the changes you need from [evennia/default_settings.py](../../../Setup/Settings-Default.md).
|
||||
The default settings file is extensively documented. Importing/accessing the values in the settings file is done in a special way, like this:
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
To get to the setting `TELNET_PORT` in the settings file you'd then do
|
||||
|
||||
telnet_port = settings.TELNET_PORT
|
||||
|
||||
You cannot assign to the settings file dynamically; you must change the `settings.py` file directly to change a setting. See [Settings](../../../Setup/Settings.md) documentation for more details.
|
||||
- `secret_settings.py` - If you are making your code effort public, you may not want to share all settings online.
|
||||
There may be server-specific secrets or just fine-tuning for your game systems that you prefer be kept secret
|
||||
from the players. Put such settings in here, it will override values in `settings.py` and not be included in
|
||||
version control.
|
||||
- `at_initial_setup.py` - When Evennia starts up for the very first time, it does some basic tasks, like creating the
|
||||
superuser and Limbo room. Adding to this file allows to add more actions for it to for first-startup.
|
||||
- `at_search.py` - When searching for objects and either finding no match or more than one match, it will
|
||||
respond by giving a warning or offering the user to differentiate between the multiple matches. Modifying
|
||||
the code here will change this behavior to your liking.
|
||||
- `at_server_startstop.py` - This allows to inject code to execute every time the server starts, stops or reloads
|
||||
in different ways.
|
||||
- `connection_screens.py` - This allows for changing the connection screen you see when you first connect to your
|
||||
game.
|
||||
- `inlinefuncs.py` - _Inlinefuncs_ are optional and limited 'functions' that can be embedded in any strings being
|
||||
sent to a player. They are written as `$funcname(args)` and are used to customize the output
|
||||
depending on the user receiving it. For example sending people the text `"Let's meet at $realtime(13:00, GMT)!`
|
||||
would show every player seeing that string the time given in their own time zone. The functions added to this
|
||||
module will become new inlinefuncs in the game.
|
||||
- `inputfucs.py` - When a command like `look` is received by the server, it is handled by an _inputfunc_
|
||||
that redirects it to the cmdhandler system. But there could be other inputs coming from the clients, like
|
||||
button-presses or the request to update a health-bar. While most common cases are already covered, this is
|
||||
where one adds new functions to process new types of input.
|
||||
- `lockfuncs.py` - _Locks_ restrict access to things in-game. Lock funcs are used in a mini-language
|
||||
to defined more complex locks. For example you could have a lockfunc that checks if the user is carrying
|
||||
a given item, is bleeding or has a certain skill value. New functions added in this modules will
|
||||
become available for use in lock definitions.
|
||||
- `mssp.py` - Mud Server Status Protocol is a way for online MUD archives/listings (which you usually have
|
||||
to sign up for) to track which MUDs are currently online, how many players they have etc. While Evennia handles
|
||||
the dynamic information automatically, this is were you set up the meta-info about your game, such as its
|
||||
theme, if player-killing is allowed and so on. This is a more generic form of the Evennia Game directory.
|
||||
- `portal_services_plugins.py` - If you want to add new external connection protocols to Evennia, this is the place
|
||||
to add them.
|
||||
- `server_services_plugins.py` - This allows to override internal server connection protocols.
|
||||
- `web_plugins.py` - This allows to add plugins to the Evennia webserver as it starts.
|
||||
|
||||
### typeclasses/
|
||||
|
||||
The [Typeclasses](../../../Components/Typeclasses.md) of Evennia are Evennia-specific Python classes whose instances save themselves
|
||||
to the database. This allows a Character to remain in the same place and your updated strength stat to still
|
||||
be the same after a server reboot.
|
||||
|
||||
- [accounts.py](github:evennia/game_template/typeclasses/accounts.py) (Python-path: `typeclasses.accounts`) - An
|
||||
[Account](../../../Components/Accounts.md) represents the player connecting to the game. It holds information like email,
|
||||
password and other out-of-character details.
|
||||
- [channels.py](github:evennia/game_template/typeclasses/channels.py) (Python-path: `typeclasses.channels`) -
|
||||
[Channels](../../../Components/Channels.md) are used to manage in-game communication between players.
|
||||
- [objects.py](github:evennia/game_template/typeclasses/objects.py) (Python-path: `typeclasses.objects`) -
|
||||
[Objects](../../../Components/Objects.md) represent all things having a location within the game world.
|
||||
- [characters.py](github:evennia/game_template/typeclasses/characters.py) (Python-path: `typeclasses.characters`) -
|
||||
The [Character](../../../Components/Objects.md#characters) is a subclass of Objects, controlled by Accounts - they are the player's
|
||||
avatars in the game world.
|
||||
- [rooms.py](github:evennia/game_template/typeclasses/rooms.py) (Python-path: `typeclasses.rooms`) - A
|
||||
[Room](../../../Components/Objects.md#rooms) is also a subclass of Object; describing discrete locations. While the traditional
|
||||
term is 'room', such a location can be anything and on any scale that fits your game, from a forest glade,
|
||||
an entire planet or an actual dungeon room.
|
||||
- [exits.py](github:evennia/game_template/typeclasses/exits.py) (Python-path: `typeclasses.exits`) -
|
||||
[Exits](../../../Components/Objects.md#exits) is another subclass of Object. Exits link one Room to another.
|
||||
- [scripts.py](github:evennia/game_template/typeclasses/scripts.py) (Python-path: `typeclasses.scripts`) -
|
||||
[Scripts](../../../Components/Scripts.md) are 'out-of-character' objects. They have no location in-game and can serve as basis for
|
||||
anything that needs database persistence, such as combat, weather, or economic systems. They also have the ability to execute code repeatedly, on a timer.
|
||||
|
||||
### web/
|
||||
|
||||
This folder contains folders for overriding the default web-presence of Evennia with your own designs. Most of these folders are empty except for a README file or a subset of other empty folders. See [the Web overview](../../../Components/Components-Overview.md#web-components) for more details (we'll also get back to the web later in this beginner tutorial).
|
||||
|
||||
- `media/` - this empty folder is where you can place your own images or other media files you want the
|
||||
web server to serve. If you are releasing your game with a lot of media (especially if you want videos) you
|
||||
should consider re-pointing Evennia to use some external service to serve your media instead.
|
||||
- `static_overrides/` - 'static' files include fonts, CSS and JS. Within this folder you'll find sub-folders for
|
||||
overriding the static files for the `admin` (this is the Django web-admin), the `webclient` (this is thet
|
||||
HTML5 webclient) and the `website`. Adding files to this folder will replace same-named files in the
|
||||
default web presence.
|
||||
- `template_overrides/` - these are HTML files, for the `webclient` and the `website`. HTML files are written
|
||||
using [Jinja](https://jinja.palletsprojects.com/en/2.11.x/) templating, which means that one can override
|
||||
only particular parts of a default template without touching others.
|
||||
- `static/` - this is a work-directory for the web system and should _not_ be manually modified. Basically,
|
||||
Evennia will copy static data from `static_overrides` here when the server starts.
|
||||
- `urls.py` - this module links up the Python code to the URLs you go to in the browser.
|
||||
|
||||
### world/
|
||||
|
||||
This folder only contains some example files. It's meant to hold 'the rest' of your game implementation. Many
|
||||
people change and re-structure this in various ways to better fit their ideas.
|
||||
|
||||
- [batch_cmds.ev](github:evennia/game_template/world/batch_cmds.ev) - This is an `.ev` file, which is essentially
|
||||
just a list of Evennia commands to execute in sequence. This one is empty and ready to expand on. The
|
||||
[Tutorial World](./Beginner-Tutorial-Tutorial-World.md) was built with such a batch-file.
|
||||
- [prototypes.py](github:evennia/game_template/world/prototypes.py) - A [prototype](../../../Components/Prototypes.md) is a way to easily vary objects without changing their base typeclass. For example, one could use prototypes to tell that Two goblins, while both of the class 'Goblin' (so they follow the same code logic), should have different equipment, stats and looks.
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
# Part 1: What we have
|
||||
|
||||
```{sidebar} Beginner Tutorial Parts
|
||||
- [Introduction](../Beginner-Tutorial-Overview.md)
|
||||
<br>Getting set up.
|
||||
- Part 1: **[What we have](./Beginner-Tutorial-Part1-Overview.md)**
|
||||
<br>A tour of Evennia and how to use the tools, including an introduction to Python.
|
||||
- Part 2: [What we want](../Part2/Beginner-Tutorial-Part2-Overview.md)
|
||||
<br>Planning our tutorial game and what to think about when planning your own in the future.
|
||||
- Part 3: [How we get there](../Part3/Beginner-Tutorial-Part3-Overview.md)
|
||||
<br>Getting down to the meat of extending Evennia to make our game
|
||||
- Part 4: [Using what we created](../Part4/Beginner-Tutorial-Part4-Overview.md)
|
||||
<br>Building a tech-demo and world content to go with our code
|
||||
- Part 5: [Showing the world](../Part5/Beginner-Tutorial-Part5-Overview.md)
|
||||
<br>Taking our new game online and let players try it out
|
||||
```
|
||||
|
||||
In this first part we'll focus on what we get out of the box in Evennia - we'll get used to the tools,
|
||||
and how to find things we are looking for. We will also dive into some of things you'll
|
||||
need to know to fully utilize the system, including giving you a brief rundown of Python concepts. If you are
|
||||
an experienced Python programmer, some sections may feel a bit basic, but you will at least not have seen
|
||||
these concepts in the context of Evennia before.
|
||||
|
||||
## Lessons
|
||||
|
||||
```{toctree}
|
||||
:numbered:
|
||||
:maxdepth: 2
|
||||
|
||||
Beginner-Tutorial-Building-Quickstart
|
||||
Beginner-Tutorial-Tutorial-World
|
||||
Beginner-Tutorial-Python-basic-introduction
|
||||
Beginner-Tutorial-Gamedir-Overview
|
||||
Beginner-Tutorial-Python-classes-and-objects
|
||||
Beginner-Tutorial-Evennia-Library-Overview
|
||||
Beginner-Tutorial-Learning-Typeclasses
|
||||
Beginner-Tutorial-Adding-Commands
|
||||
Beginner-Tutorial-More-on-Commands
|
||||
Beginner-Tutorial-Creating-Things
|
||||
Beginner-Tutorial-Searching-Things
|
||||
Beginner-Tutorial-Django-queries
|
||||
Beginner-Tutorial-Making-A-Sittable-Object
|
||||
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue