[cyphesis-cpp] 02/02: Imported Upstream version 0.6.2

Olek Wojnar olek-guest at moszumanska.debian.org
Tue Aug 30 05:20:13 UTC 2016


This is an automated email from the git hooks/post-receive script.

olek-guest pushed a commit to branch upstream
in repository cyphesis-cpp.

commit 531d69622260d6e2d5b599aa5441d23c4c98799f
Author: Olek Wojnar <olek-dev at wojnar.org>
Date:   Mon Aug 29 23:01:17 2016 -0400

    Imported Upstream version 0.6.2
---
 ChangeLog                                   |  12 ++
 NEWS                                        |   4 +
 configure                                   |  20 +-
 configure.ac                                |   2 +-
 cyphesis.spec                               |   2 +-
 data/buildings.xml                          |   6 +-
 rulesets/Character.cpp                      |  17 +-
 rulesets/Character.h                        |   7 +
 rulesets/Makefile.am                        |   3 +-
 rulesets/Makefile.in                        |   7 +-
 rulesets/SpawnerProperty.cpp                | 274 ++++++++++++++++++++++++++++
 rulesets/SpawnerProperty.h                  | 132 ++++++++++++++
 rulesets/basic/mind/goals/humanoid/mason.py |   6 +-
 rulesets/mason/world/tasks/Pioneering.py    |   6 +-
 server/CorePropertyManager.cpp              |   3 +
 server/buildid.cpp                          |   2 +-
 tests/Accountintegration.cpp                |  27 +++
 tests/CorePropertyManagertest.cpp           |  27 +++
 tests/Makefile.am                           |   7 +
 tests/Makefile.in                           |  50 +++--
 tests/SpawnerPropertytest.cpp               |  73 ++++++++
 21 files changed, 641 insertions(+), 46 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index fbfb8c4..ee42ca3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2013-10-25  Erik Ogenvik  <erik at ogenvik.org>
+
+	* NEWS: Update NEWS announcement for release.
+
+	* Release 0.6.2
+
+2013-10-25  Erik Ogenvik  <erik at ogenvik.org>
+
+	* Fixed Segfault when character wielding entity was destroyed.
+
+	* New spawner property
+
 2013-09-21  Erik Ogenvik  <erik at ogenvik.org>
 
 	* NEWS: Update NEWS announcement for release.
diff --git a/NEWS b/NEWS
index 4b47d7a..44da847 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+2013-10-25  Erik Ogenvik  <erik at ogenvik.org>
+
+	* Version 0.6.2 released.
+
 2013-09-21  Erik Ogenvik  <erik at ogenvik.org>
 
 	* Version 0.6.1 released.
diff --git a/configure b/configure
index 69c5f52..dc142c6 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for cyphesis 0.6.1.
+# Generated by GNU Autoconf 2.68 for cyphesis 0.6.2.
 #
 # Report bugs to <erik at ogenvik.org>.
 #
@@ -560,8 +560,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='cyphesis'
 PACKAGE_TARNAME='cyphesis'
-PACKAGE_VERSION='0.6.1'
-PACKAGE_STRING='cyphesis 0.6.1'
+PACKAGE_VERSION='0.6.2'
+PACKAGE_STRING='cyphesis 0.6.2'
 PACKAGE_BUGREPORT='erik at ogenvik.org'
 PACKAGE_URL=''
 
@@ -1337,7 +1337,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures cyphesis 0.6.1 to adapt to many kinds of systems.
+\`configure' configures cyphesis 0.6.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1407,7 +1407,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cyphesis 0.6.1:";;
+     short | recursive ) echo "Configuration of cyphesis 0.6.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1548,7 +1548,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cyphesis configure 0.6.1
+cyphesis configure 0.6.2
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -1992,7 +1992,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by cyphesis $as_me 0.6.1, which was
+It was created by cyphesis $as_me 0.6.2, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -2926,7 +2926,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cyphesis'
- VERSION='0.6.1'
+ VERSION='0.6.2'
 
 
 # Some tools Automake needs.
@@ -8243,7 +8243,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by cyphesis $as_me 0.6.1, which was
+This file was extended by cyphesis $as_me 0.6.2, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8309,7 +8309,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-cyphesis config.status 0.6.1
+cyphesis config.status 0.6.2
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 1732f4e..a66f149 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
 dnl Initialise autoconf
 
-AC_INIT([cyphesis],[0.6.1],[erik at ogenvik.org])
+AC_INIT([cyphesis],[0.6.2],[erik at ogenvik.org])
 AC_CONFIG_SRCDIR([server/server.cpp])
 AC_CONFIG_HEADERS([config.h])
 
diff --git a/cyphesis.spec b/cyphesis.spec
index 1505449..0d5f22b 100644
--- a/cyphesis.spec
+++ b/cyphesis.spec
@@ -1,5 +1,5 @@
 %define name cyphesis
-%define version 0.6.1
+%define version 0.6.2
 %define release 1
 
 Summary: A simple personal server for the WorldForge project
diff --git a/data/buildings.xml b/data/buildings.xml
index 66c35e6..dd68ca2 100644
--- a/data/buildings.xml
+++ b/data/buildings.xml
@@ -712,7 +712,7 @@
         <string name="visibility">public</string>
       </map>
     </map>
-    <string name="id">palissade_circle</string>
+    <string name="id">palisade_circle</string>
     <string name="objtype">class</string>
     <list name="parents">
       <string>structure</string>
@@ -733,7 +733,7 @@
         <string name="visibility">public</string>
       </map>
     </map>
-    <string name="id">palissade_entry</string>
+    <string name="id">palisade_entry</string>
     <string name="objtype">class</string>
     <list name="parents">
       <string>structure</string>
@@ -754,7 +754,7 @@
         <string name="visibility">public</string>
       </map>
     </map>
-    <string name="id">palissade_unit</string>
+    <string name="id">palisade_unit</string>
     <string name="objtype">class</string>
     <list name="parents">
       <string>structure</string>
diff --git a/rulesets/Character.cpp b/rulesets/Character.cpp
index edce122..7eff7ec 100644
--- a/rulesets/Character.cpp
+++ b/rulesets/Character.cpp
@@ -269,6 +269,9 @@ Character::Character(const std::string & id, long intId) :
 
 Character::~Character()
 {
+    if (m_rightHandWieldConnection.connected()) {
+        m_rightHandWieldConnection.disconnect();
+    }
     delete &m_movement;
     delete m_mind;
     delete m_externalMind;
@@ -698,9 +701,9 @@ void Character::WieldOperation(const Operation & op, OpVector & res)
 
         // FIXME Make sure we stop wielding if the container changes,
         // but connections are cleared, and don't build up.
-        // if (m_rightHandWieldConnection.connected()) {
-            // m_rightHandWieldConnection.disconnect();
-        // }
+        if (m_rightHandWieldConnection.connected()) {
+            m_rightHandWieldConnection.disconnect();
+        }
 
         Update update;
         update->setTo(getId());
@@ -753,16 +756,16 @@ void Character::WieldOperation(const Operation & op, OpVector & res)
         EntityProperty * rhw = requirePropertyClass<EntityProperty>(RIGHT_HAND_WIELD);
         // FIXME Make sure we don't stay linked to the previous wielded
         // tool.
-        // if (m_rightHandWieldConnection.connected()) {
-            // m_rightHandWieldConnection.disconnect();
-        // }
+        if (m_rightHandWieldConnection.connected()) {
+            m_rightHandWieldConnection.disconnect();
+        }
 
         // The value is ignored by the update handler, but should be the
         // right type.
         rhw->data() = EntityRef(item);
         rhw->setFlags(flag_unsent);
 
-        item->containered.connect(sigc::hide<0>(sigc::mem_fun(this, &Character::wieldDropped)));
+        m_rightHandWieldConnection = item->containered.connect(sigc::hide<0>(sigc::mem_fun(this, &Character::wieldDropped)));
 
         debug(std::cout << "Wielding " << item->getId() << std::endl << std::flush;);
     }
diff --git a/rulesets/Character.h b/rulesets/Character.h
index 4f499a2..eccade8 100644
--- a/rulesets/Character.h
+++ b/rulesets/Character.h
@@ -20,6 +20,7 @@
 #define RULESETS_CHARACTER_H
 
 #include "Thing.h"
+#include <sigc++/connection.h>
 
 class BaseMind;
 class ExternalMind;
@@ -89,6 +90,12 @@ class Character : public Thing {
     /// \brief Weight gained from excess energy by metabolism per tick
     static const double weightGain;
 
+    /// \brief Holds a connection to the containered signal of any wielded entity.
+    ///
+    /// FIXME This is a hack, to be removed once we've migrated to using Outfit
+    /// for wielded entities.
+    sigc::connection m_rightHandWieldConnection;
+
     void filterExternalOperation(const Operation &);
     void metabolise(OpVector &, double ammount = 1); 
     void wieldDropped();
diff --git a/rulesets/Makefile.am b/rulesets/Makefile.am
index 511f67c..7038dbc 100644
--- a/rulesets/Makefile.am
+++ b/rulesets/Makefile.am
@@ -59,7 +59,8 @@ librulesetentity_a_SOURCES = \
 			     Task.cpp Task.h \
 			     ArithmeticScript.cpp ArithmeticScript.h \
 			     ArithmeticFactory.cpp ArithmeticFactory.h \
-			     SuspendedProperty.cpp SuspendedProperty.h
+			     SuspendedProperty.cpp SuspendedProperty.h \
+			     SpawnerProperty.cpp SpawnerProperty.h
 
 
 librulesetmind_a_SOURCES = BaseMind.cpp BaseMind.h \
diff --git a/rulesets/Makefile.in b/rulesets/Makefile.in
index 64d38be..a297407 100644
--- a/rulesets/Makefile.in
+++ b/rulesets/Makefile.in
@@ -103,7 +103,8 @@ am_librulesetentity_a_OBJECTS = Entity.$(OBJEXT) Thing.$(OBJEXT) \
 	ExternalProperty.$(OBJEXT) BiomassProperty.$(OBJEXT) \
 	BurnSpeedProperty.$(OBJEXT) DecaysProperty.$(OBJEXT) \
 	Task.$(OBJEXT) ArithmeticScript.$(OBJEXT) \
-	ArithmeticFactory.$(OBJEXT) SuspendedProperty.$(OBJEXT)
+	ArithmeticFactory.$(OBJEXT) SuspendedProperty.$(OBJEXT) \
+	SpawnerProperty.$(OBJEXT)
 librulesetentity_a_OBJECTS = $(am_librulesetentity_a_OBJECTS)
 librulesetmind_a_AR = $(AR) $(ARFLAGS)
 librulesetmind_a_LIBADD =
@@ -396,7 +397,8 @@ librulesetentity_a_SOURCES = \
 			     Task.cpp Task.h \
 			     ArithmeticScript.cpp ArithmeticScript.h \
 			     ArithmeticFactory.cpp ArithmeticFactory.h \
-			     SuspendedProperty.cpp SuspendedProperty.h
+			     SuspendedProperty.cpp SuspendedProperty.h \
+			     SpawnerProperty.cpp SpawnerProperty.h
 
 librulesetmind_a_SOURCES = BaseMind.cpp BaseMind.h \
 			   MindFactory.cpp MindFactory.h \
@@ -556,6 +558,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Script.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/SolidProperty.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/SpawnProperty.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/SpawnerProperty.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Stackable.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/StatisticsProperty.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/StatusProperty.Po at am__quote@
diff --git a/rulesets/SpawnerProperty.cpp b/rulesets/SpawnerProperty.cpp
new file mode 100644
index 0000000..6b5c654
--- /dev/null
+++ b/rulesets/SpawnerProperty.cpp
@@ -0,0 +1,274 @@
+/*
+ Copyright (C) 2013 Erik Ogenvik
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SpawnerProperty.h"
+#include "LocatedEntity.h"
+
+#include "common/Tick.h"
+#include "common/TypeNode.h"
+#include "common/const.h"
+#include "common/BaseWorld.h"
+#include "common/Inheritance.h"
+
+#include <Atlas/Objects/Anonymous.h>
+#include <Atlas/Objects/Operation.h>
+
+#include <wfmath/MersenneTwister.h>
+#include <wfmath/quaternion.h>
+#include <wfmath/const.h>
+#include <wfmath/atlasconv.h>
+
+static const bool debug_flag = false;
+
+using Atlas::Message::Element;
+using Atlas::Message::MapType;
+using Atlas::Message::ListType;
+using Atlas::Message::FloatType;
+using Atlas::Objects::Entity::Anonymous;
+using Atlas::Objects::Operation::Create;
+using Atlas::Objects::Operation::Tick;
+using Atlas::Objects::Factories;
+using Atlas::Objects::smart_dynamic_cast;
+
+SpawnerProperty::SpawnerProperty() :
+        m_radius(0.0f), m_minamount(0), m_interval(0), m_mode_external(true)
+{
+}
+
+SpawnerProperty::~SpawnerProperty()
+{
+}
+
+void SpawnerProperty::install(LocatedEntity * owner, const std::string & name)
+{
+    owner->installDelegate(Atlas::Objects::Operation::TICK_NO, name);
+
+    //Start the tick process by sending an initial tick.
+    Anonymous tick_arg;
+    tick_arg->setName("spawner");
+    Tick t;
+    t->setArgs1(tick_arg);
+    t->setFutureSeconds(consts::basic_tick * 5.0f);
+    t->setTo(owner->getId());
+    BaseWorld::instance().message(t, *owner);
+}
+
+void SpawnerProperty::apply(LocatedEntity * ent)
+{
+    auto radius_iter = m_data.find("radius");
+    if (radius_iter != m_data.end() && radius_iter->second.isNum()) {
+        m_radius = radius_iter->second.Float();
+    } else {
+        m_radius = 0.0f;
+    }
+
+    auto amount_iter = m_data.find("minamount");
+    if (amount_iter != m_data.end() && amount_iter->second.isInt()) {
+        m_minamount = amount_iter->second.Int();
+    } else {
+        m_minamount = 0;
+    }
+
+    auto type_iter = m_data.find("type");
+    if (type_iter != m_data.end() && type_iter->second.isString()) {
+        m_type = type_iter->second.String();
+    } else {
+        m_type = "";
+    }
+
+    auto entity_iter = m_data.find("entity");
+    if (entity_iter != m_data.end() && entity_iter->second.isMap()) {
+        m_entity = entity_iter->second.asMap();
+    } else {
+        m_entity.clear();
+    }
+
+    auto interval_iter = m_data.find("interval");
+    if (interval_iter != m_data.end() && interval_iter->second.isNum()) {
+        m_interval = interval_iter->second.asNum();
+    } else {
+        m_interval = 0;
+    }
+
+    auto internal_iter = m_data.find("internal");
+    if (internal_iter != m_data.end() && internal_iter->second.isInt()) {
+        m_mode_external = internal_iter->second.asInt() != 1;
+    } else {
+        m_mode_external = true;
+    }
+}
+
+HandlerResult SpawnerProperty::operation(LocatedEntity * e,
+        const Operation & op, OpVector & res)
+{
+    return tick_handler(e, op, res);
+}
+
+SpawnerProperty * SpawnerProperty::copy() const
+{
+    return new SpawnerProperty(*this);
+}
+
+HandlerResult SpawnerProperty::tick_handler(LocatedEntity * e,
+        const Operation & op, OpVector & res)
+{
+    if (!op->getArgs().empty()) {
+        auto& arg = op->getArgs().front();
+        if (arg->getName() == "spawner") {
+            //This is our tick
+            handleTick(e, op, res);
+            return OPERATION_BLOCKED;
+        }
+    }
+    return OPERATION_IGNORED;
+}
+
+void SpawnerProperty::handleTick(LocatedEntity * e, const Operation & op,
+        OpVector & res)
+{
+    Anonymous tick_arg;
+    tick_arg->setName("spawner");
+    Tick t;
+    t->setArgs1(tick_arg);
+    t->setTo(e->getId());
+    if (m_interval == 0) {
+        t->setFutureSeconds(consts::basic_tick * 10);
+    } else {
+        t->setFutureSeconds(m_interval);
+    }
+    res.push_back(t);
+
+    if (m_type.empty()) {
+        return;
+    }
+
+    if (m_minamount <= 0) {
+        return;
+    }
+
+    auto type = Inheritance::instance().getType(m_type);
+    if (type == nullptr) {
+        return;
+    }
+
+    auto parentLoc = e->m_location.m_loc;
+    float squared_radius = m_radius * m_radius;
+    LocatedEntity* container_entity = parentLoc;
+    if (m_mode_external) {
+        if (!parentLoc) {
+            //If there's no parent entity we should just ignore.
+            return;
+        }
+    } else {
+        container_entity = e;
+        //if it's internal we'll skip checking the radius
+        squared_radius = 0;
+    }
+
+    //Check if there are enough entities (with an optional radius)
+    int counter = 0;
+    if (container_entity->m_contains) {
+        for (auto& entity : *container_entity->m_contains) {
+            if (entity->getType() == type) {
+                if (squared_radius == 0
+                        || WFMath::SquaredDistance(e->m_location.m_pos,
+                                entity->m_location.m_pos) <= squared_radius) {
+                    counter++;
+                    if (counter >= m_minamount) {
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    //If we've come here there's not enough entities of the requested
+    //type within the radius; spawn a new one
+    createNewEntity(e, op, res, container_entity->getId());
+
+    return;
+
+}
+
+void SpawnerProperty::createNewEntity(LocatedEntity * e, const Operation & op,
+        OpVector & res, const std::string& locId)
+{
+    Anonymous create_arg;
+    if (!m_entity.empty()) {
+        create_arg = smart_dynamic_cast<Anonymous>(
+                Factories::instance()->createObject(m_entity));
+        if (!create_arg.isValid()) {
+            log(ERROR,
+                    "Could not parse 'entity' data on spawner into Entity instance.");
+            return;
+        }
+    } else {
+        create_arg->setParents(std::list<std::string>(1, m_type));
+    }
+    create_arg->setLoc(locId);
+
+    WFMath::MTRand& rand = WFMath::MTRand::instance;
+    if (m_mode_external) {
+        //randomize position and rotation
+        float angle = rand.randf(WFMath::numeric_constants<float>::pi() * 2);
+        //place it between 0 and 2 meters away
+        float distance = rand.randf(2.0f);
+        //if we're solid we should make sure it's not within our own radius
+        if (e->m_location.isSolid()) {
+            distance += e->m_location.radius();
+        }
+        //and finally make sure that it's not beyond the radius for checking
+        if (m_radius != 0.0f) {
+            distance = std::min(m_radius, distance);
+        }
+
+
+        float x = (distance * std::cos(angle));
+        float y = (distance * std::sin(angle));
+
+        ::addToEntity(
+                WFMath::Point<3>(e->m_location.pos()).shift(
+                        WFMath::Vector<3>(x, y, 0)), create_arg->modifyPos());
+    } else {
+        //If it's an internal spawner, spawn anywhere within the bounding box.
+        const BBox bbox = e->m_location.m_bBox;
+        if (bbox.isValid()) {
+            float x = rand.rand(bbox.highCorner().x() - bbox.lowCorner().x())
+                    + bbox.lowCorner().x();
+            float y = rand.rand(bbox.highCorner().y() - bbox.lowCorner().y())
+                    + bbox.lowCorner().y();
+            ::addToEntity(WFMath::Point<3>(x, y, 0), create_arg->modifyPos());
+        }
+    }
+    float rotation = rand.randf(WFMath::numeric_constants<float>::pi() * 2);
+    WFMath::Quaternion orientation(WFMath::Vector<3>(0, 0, 1), rotation);
+    create_arg->setAttr("orientation", orientation.toAtlas());
+
+    Create create;
+    create->setTo(e->m_location.m_loc->getId());
+    create->setArgs1(create_arg);
+    res.push_back(create);
+
+    log(NOTICE, String::compose("Spawner belonging to entity %1 creating new"
+            " entity of type %2", e->getId(), m_type));
+}
+
diff --git a/rulesets/SpawnerProperty.h b/rulesets/SpawnerProperty.h
new file mode 100644
index 0000000..2a97cfb
--- /dev/null
+++ b/rulesets/SpawnerProperty.h
@@ -0,0 +1,132 @@
+/*
+ Cyphesis Online RPG Server and AI Engine
+ Copyright (C) 2013 Erik Ogenvik
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef RULESETS_SPAWNERPROPERTY_H_
+#define RULESETS_SPAWNERPROPERTY_H_
+
+#include "common/Property.h"
+
+/// \brief Class to handle automatic spawning behaviour.
+///
+/// When this property is attached to an entity it causes that entity to become
+/// a "spawner". This makes it create new entities when it determines they are
+/// needed. This allows for game play mechanics where some items or creatures
+/// always are available.
+/// The default is to create the entities in the parent entity, unless the
+/// attribute "internal" is set to 1. Then entities will be spawned as children
+/// of the entity to which the property is attached.
+///
+/// This property is of "map" type.
+/// These values are available:
+/// type: a string specifying the type of entity to create
+/// minamount: the desired minimum amount of entities (optionally within a radius)
+///            if the actual number of entities dips below new ones are created
+/// radius: an optional radius around the entity to consider when checking minamount
+/// entity: an optional entity declaration, to be sent as argument in a Create op
+/// interval: an optional numeric value specifying the interval, in seconds, between
+///           ticks. If omitted, a default value will be used.
+/// internal: optional. If set to 1, entities will be spawned as children of the
+///            entity to which the property belong.
+/// \ingroup PropertyClasses
+class SpawnerProperty : public Property<Atlas::Message::MapType>
+{
+    public:
+        explicit SpawnerProperty();
+        virtual ~SpawnerProperty();
+
+        virtual void install(LocatedEntity *, const std::string &);
+        virtual void apply(LocatedEntity *);
+        virtual HandlerResult operation(LocatedEntity *,
+                                        const Operation &,
+                                        OpVector &);
+        virtual SpawnerProperty * copy() const;
+
+
+        HandlerResult tick_handler(LocatedEntity * e,
+                                  const Operation & op,
+                                  OpVector & res);
+
+    private:
+        /**
+         * @brief An optional radius to check within.
+         */
+        float m_radius;
+
+        /**
+         * @brief The minimum amount of entities.
+         */
+        int m_minamount;
+
+        /**
+         * @brief The type of entity.
+         */
+        std::string m_type;
+
+        /**
+         * @brief An optional entity definition.
+         *
+         * This can be anything which can be created through a Create op, but
+         * most probably either an entity or an archetype.
+         *
+         * If absent, an entity of the m_type will be created automatically.
+         */
+        Atlas::Message::MapType m_entity;
+
+        /**
+         * @brief The tick interval.
+         *
+         * If set to 0 a default value will be used.
+         */
+        int m_interval;
+
+        /**
+         * @brief Specifies if creation mode is "external".
+         *
+         * It not, it's "internal".
+         * "external" means that entities will be created in the parent entity.
+         * "internal" means that they will be created as children of this entity.
+         * The default is "external".
+         */
+        bool m_mode_external;
+
+        Atlas::Objects::Operation::RootOperation createTickOp();
+
+        /**
+         * Handle one of our own ticks.
+         * @param e
+         * @param op
+         * @param res
+         */
+        void handleTick(LocatedEntity * e,
+                const Operation & op,
+                OpVector & res);
+
+        /**
+         * Create a new entity.
+         * @param e
+         * @param op
+         * @param res
+         * @param locId
+         */
+        void createNewEntity(LocatedEntity * e,
+                const Operation & op,
+                OpVector & res, const std::string& locId);
+};
+
+#endif /* RULESETS_SPAWNERPROPERTY_H_ */
diff --git a/rulesets/basic/mind/goals/humanoid/mason.py b/rulesets/basic/mind/goals/humanoid/mason.py
index afa81b8..1672597 100644
--- a/rulesets/basic/mind/goals/humanoid/mason.py
+++ b/rulesets/basic/mind/goals/humanoid/mason.py
@@ -23,17 +23,17 @@ class keep_livestock(keep):
 
 class welcome(DynamicGoal):
     """Welcome entities of a given type that are created nearby."""
-    def __init__(self, message, player, desc="welcome new players"):
+    def __init__(self, message, type, desc="welcome new players"):
         DynamicGoal.__init__(self,
                              trigger="sight_create",
                              desc=desc)
-        self.player=player
+        self.type=type
         self.message=message
     def event(self, me, original_op, op):
         obj = me.map.update(op[0], op.getSeconds())
         if original_op.from_==me.id:
             self.add_thing(obj)
-        if obj.type[0]==self.player:
+        if obj.type[0]==self.type:
             return Operation("talk", Entity(say=self.message))
 
 class help(Goal):
diff --git a/rulesets/mason/world/tasks/Pioneering.py b/rulesets/mason/world/tasks/Pioneering.py
index 2293bd6..8ab7e40 100644
--- a/rulesets/mason/world/tasks/Pioneering.py
+++ b/rulesets/mason/world/tasks/Pioneering.py
@@ -81,7 +81,7 @@ class Pioneering(server.Task):
                 res.append(create)
 
             if wcount == 0 and lcount == 2:
-                create=Operation("create", Entity(name = "palissade_unit", type = "palissade_unit", location = chunk_loc), to = self.target())
+                create=Operation("create", Entity(name = "palisade_unit", type = "palisade_unit", location = chunk_loc), to = self.target())
                 res.append(create)
 
             #if wcount == 2 and lcount == 1:
@@ -94,7 +94,7 @@ class Pioneering(server.Task):
                 res.append(create)
 
             if wcount == 0 and lcount == 3:
-                create=Operation("create", Entity(name = "palissade_entry", type = "palissade_entry", location = chunk_loc), to = self.target())
+                create=Operation("create", Entity(name = "palisade_entry", type = "palisade_entry", location = chunk_loc), to = self.target())
                 res.append(create)
 
         if rcount == 3 :
@@ -107,7 +107,7 @@ class Pioneering(server.Task):
  #               res.append(create)
 
             if wcount == 0 and lcount == 5:
-                create=Operation("create", Entity(name = "palissade_circle", type = "palissade_circle", location = chunk_loc), to = self.target())
+                create=Operation("create", Entity(name = "palisade_circle", type = "palisade_circle", location = chunk_loc), to = self.target())
                 res.append(create)
 
         # Consume the materials according to the recipe
diff --git a/server/CorePropertyManager.cpp b/server/CorePropertyManager.cpp
index eb8aeee..78aba11 100644
--- a/server/CorePropertyManager.cpp
+++ b/server/CorePropertyManager.cpp
@@ -41,6 +41,7 @@
 #include "rulesets/SuspendedProperty.h"
 #include "rulesets/TasksProperty.h"
 #include "rulesets/EntityProperty.h"
+#include "rulesets/SpawnerProperty.h"
 
 #include "common/Eat.h"
 #include "common/Burn.h"
@@ -118,6 +119,8 @@ CorePropertyManager::CorePropertyManager()
     installProperty<SuspendedProperty>("suspended", "int");
     installProperty<TasksProperty>("tasks", "map");
     installProperty<EntityProperty>("right_hand_wield", "string");
+    installProperty<SpawnerProperty>("spawner", "map");
+
 
 
 }
diff --git a/server/buildid.cpp b/server/buildid.cpp
index 47323dd..931392c 100644
--- a/server/buildid.cpp
+++ b/server/buildid.cpp
@@ -7,5 +7,5 @@ namespace consts {
 
   const char * buildTime = __TIME__;
   const char * buildDate = __DATE__;
-  const int buildId = 2523;
+  const int buildId = 2524;
 }
diff --git a/tests/Accountintegration.cpp b/tests/Accountintegration.cpp
index 6df7f27..54953c7 100644
--- a/tests/Accountintegration.cpp
+++ b/tests/Accountintegration.cpp
@@ -389,6 +389,7 @@ LocatedEntity * TestWorld::addNewEntity(const std::string &,
 #include "rulesets/TransientProperty.h"
 #include "rulesets/VisibilityProperty.h"
 #include "rulesets/SuspendedProperty.h"
+#include "rulesets/SpawnerProperty.h"
 
 #include "common/const.h"
 #include "common/globals.h"
@@ -1345,6 +1346,32 @@ void SuspendedProperty::apply(LocatedEntity * owner)
 {
 }
 
+SpawnerProperty::SpawnerProperty()
+{
+}
+
+SpawnerProperty::~SpawnerProperty()
+{
+}
+
+SpawnerProperty * SpawnerProperty::copy() const
+{
+    return 0;
+}
+
+void SpawnerProperty::apply(LocatedEntity * owner)
+{
+}
+
+void SpawnerProperty::install(LocatedEntity * ent, const std::string & name)
+{
+}
+
+HandlerResult SpawnerProperty::operation(LocatedEntity *, const Operation &, OpVector &)
+{
+    return OPERATION_IGNORED;
+}
+
 Pedestrian::~Pedestrian()
 {
 }
diff --git a/tests/CorePropertyManagertest.cpp b/tests/CorePropertyManagertest.cpp
index 9d778ed..ca6e660 100644
--- a/tests/CorePropertyManagertest.cpp
+++ b/tests/CorePropertyManagertest.cpp
@@ -228,6 +228,7 @@ LocatedEntity * TestWorld::addNewEntity(const std::string &,
 #include "rulesets/TerrainProperty.h"
 #include "rulesets/TransientProperty.h"
 #include "rulesets/VisibilityProperty.h"
+#include "rulesets/SpawnerProperty.h"
 
 #include "common/const.h"
 #include "common/globals.h"
@@ -1737,6 +1738,32 @@ void SuspendedProperty::apply(LocatedEntity * owner)
 {
 }
 
+SpawnerProperty::SpawnerProperty()
+{
+}
+
+SpawnerProperty::~SpawnerProperty()
+{
+}
+
+SpawnerProperty * SpawnerProperty::copy() const
+{
+    return 0;
+}
+
+void SpawnerProperty::apply(LocatedEntity * owner)
+{
+}
+
+void SpawnerProperty::install(LocatedEntity * ent, const std::string & name)
+{
+}
+
+HandlerResult SpawnerProperty::operation(LocatedEntity *, const Operation &, OpVector &)
+{
+    return OPERATION_IGNORED;
+}
+
 Pedestrian::~Pedestrian()
 {
 }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5e085e1..6f84014 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -40,6 +40,7 @@ RULESETS_TESTS = LocatedEntitytest Entitytest Planttest \
                  ExternalPropertytest BurnSpeedPropertytest \
                  BiomassPropertytest DecaysPropertytest \
                  Domaintest BulletDomaintest AtlasPropertiestest \
+                 SpawnerPropertytest \
                  BaseMindtest MemEntitytest MemMaptest Movementtest \
                  Pedestriantest \
                  ExternalMindtest \
@@ -615,6 +616,12 @@ SpawnPropertytest_LDADD = \
         $(top_builddir)/rulesets/SpawnProperty.o \
         $(top_builddir)/common/Property.o
 
+SpawnerPropertytest_SOURCES = SpawnerPropertytest.cpp \
+        PropertyCoverage.cpp PropertyCoverage.h
+SpawnerPropertytest_LDADD = \
+        $(top_builddir)/rulesets/SpawnerProperty.o \
+        $(top_builddir)/common/Property.o
+
 VisibilityPropertytest_SOURCES = VisibilityPropertytest.cpp \
         PropertyCoverage.cpp PropertyCoverage.h
 VisibilityPropertytest_LDADD = \
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 7925103..a62c18f 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -122,18 +122,18 @@ am__EXEEXT_6 = LocatedEntitytest$(EXEEXT) Entitytest$(EXEEXT) \
 	ExternalPropertytest$(EXEEXT) BurnSpeedPropertytest$(EXEEXT) \
 	BiomassPropertytest$(EXEEXT) DecaysPropertytest$(EXEEXT) \
 	Domaintest$(EXEEXT) BulletDomaintest$(EXEEXT) \
-	AtlasPropertiestest$(EXEEXT) BaseMindtest$(EXEEXT) \
-	MemEntitytest$(EXEEXT) MemMaptest$(EXEEXT) \
-	Movementtest$(EXEEXT) Pedestriantest$(EXEEXT) \
-	ExternalMindtest$(EXEEXT) Python_APItest$(EXEEXT) \
-	Py_Quaterniontest$(EXEEXT) Py_Vector3Dtest$(EXEEXT) \
-	Py_Point3Dtest$(EXEEXT) Py_BBoxtest$(EXEEXT) \
-	Py_Locationtest$(EXEEXT) Py_RootEntitytest$(EXEEXT) \
-	Py_Operationtest$(EXEEXT) Py_Oplisttest$(EXEEXT) \
-	Py_Thingtest$(EXEEXT) Py_Maptest$(EXEEXT) Py_Tasktest$(EXEEXT) \
-	Py_Worldtest$(EXEEXT) Py_Messagetest$(EXEEXT) \
-	Py_WorldTimetest$(EXEEXT) Py_Propertytest$(EXEEXT) \
-	Py_TerrainPropertytest$(EXEEXT) \
+	AtlasPropertiestest$(EXEEXT) SpawnerPropertytest$(EXEEXT) \
+	BaseMindtest$(EXEEXT) MemEntitytest$(EXEEXT) \
+	MemMaptest$(EXEEXT) Movementtest$(EXEEXT) \
+	Pedestriantest$(EXEEXT) ExternalMindtest$(EXEEXT) \
+	Python_APItest$(EXEEXT) Py_Quaterniontest$(EXEEXT) \
+	Py_Vector3Dtest$(EXEEXT) Py_Point3Dtest$(EXEEXT) \
+	Py_BBoxtest$(EXEEXT) Py_Locationtest$(EXEEXT) \
+	Py_RootEntitytest$(EXEEXT) Py_Operationtest$(EXEEXT) \
+	Py_Oplisttest$(EXEEXT) Py_Thingtest$(EXEEXT) \
+	Py_Maptest$(EXEEXT) Py_Tasktest$(EXEEXT) Py_Worldtest$(EXEEXT) \
+	Py_Messagetest$(EXEEXT) Py_WorldTimetest$(EXEEXT) \
+	Py_Propertytest$(EXEEXT) Py_TerrainPropertytest$(EXEEXT) \
 	Py_TerrainModPropertytest$(EXEEXT) Py_Shapetest$(EXEEXT) \
 	PythonWrappertest$(EXEEXT) PythonEntityScripttest$(EXEEXT) \
 	MindFactorytest$(EXEEXT) PythonContexttest$(EXEEXT) \
@@ -1199,6 +1199,12 @@ SpawnPropertytest_OBJECTS = $(am_SpawnPropertytest_OBJECTS)
 SpawnPropertytest_DEPENDENCIES =  \
 	$(top_builddir)/rulesets/SpawnProperty.o \
 	$(top_builddir)/common/Property.o
+am_SpawnerPropertytest_OBJECTS = SpawnerPropertytest.$(OBJEXT) \
+	PropertyCoverage.$(OBJEXT)
+SpawnerPropertytest_OBJECTS = $(am_SpawnerPropertytest_OBJECTS)
+SpawnerPropertytest_DEPENDENCIES =  \
+	$(top_builddir)/rulesets/SpawnerProperty.o \
+	$(top_builddir)/common/Property.o
 am_Spawntest_OBJECTS = Spawntest.$(OBJEXT)
 Spawntest_OBJECTS = $(am_Spawntest_OBJECTS)
 Spawntest_DEPENDENCIES = $(top_builddir)/server/Spawn.o
@@ -1668,7 +1674,8 @@ SOURCES = $(AccountConnectionCharacterintegration_SOURCES) \
 	$(Setuptest_SOURCES) $(Shakertest_SOURCES) \
 	$(Shapetest_SOURCES) $(SolidPropertytest_SOURCES) \
 	$(SpawnEntitytest_SOURCES) $(SpawnPropertytest_SOURCES) \
-	$(Spawntest_SOURCES) $(Stackabletest_SOURCES) \
+	$(SpawnerPropertytest_SOURCES) $(Spawntest_SOURCES) \
+	$(Stackabletest_SOURCES) \
 	$(StatisticsPropertyintegration_SOURCES) \
 	$(StatisticsPropertytest_SOURCES) \
 	$(StatusPropertytest_SOURCES) $(StorageManagertest_SOURCES) \
@@ -1800,7 +1807,8 @@ DIST_SOURCES = $(AccountConnectionCharacterintegration_SOURCES) \
 	$(Setuptest_SOURCES) $(Shakertest_SOURCES) \
 	$(Shapetest_SOURCES) $(SolidPropertytest_SOURCES) \
 	$(SpawnEntitytest_SOURCES) $(SpawnPropertytest_SOURCES) \
-	$(Spawntest_SOURCES) $(Stackabletest_SOURCES) \
+	$(SpawnerPropertytest_SOURCES) $(Spawntest_SOURCES) \
+	$(Stackabletest_SOURCES) \
 	$(StatisticsPropertyintegration_SOURCES) \
 	$(StatisticsPropertytest_SOURCES) \
 	$(StatusPropertytest_SOURCES) $(StorageManagertest_SOURCES) \
@@ -2157,6 +2165,7 @@ RULESETS_TESTS = LocatedEntitytest Entitytest Planttest \
                  ExternalPropertytest BurnSpeedPropertytest \
                  BiomassPropertytest DecaysPropertytest \
                  Domaintest BulletDomaintest AtlasPropertiestest \
+                 SpawnerPropertytest \
                  BaseMindtest MemEntitytest MemMaptest Movementtest \
                  Pedestriantest \
                  ExternalMindtest \
@@ -2712,6 +2721,13 @@ SpawnPropertytest_LDADD = \
         $(top_builddir)/rulesets/SpawnProperty.o \
         $(top_builddir)/common/Property.o
 
+SpawnerPropertytest_SOURCES = SpawnerPropertytest.cpp \
+        PropertyCoverage.cpp PropertyCoverage.h
+
+SpawnerPropertytest_LDADD = \
+        $(top_builddir)/rulesets/SpawnerProperty.o \
+        $(top_builddir)/common/Property.o
+
 VisibilityPropertytest_SOURCES = VisibilityPropertytest.cpp \
         PropertyCoverage.cpp PropertyCoverage.h
 
@@ -4234,6 +4250,9 @@ SpawnEntitytest$(EXEEXT): $(SpawnEntitytest_OBJECTS) $(SpawnEntitytest_DEPENDENC
 SpawnPropertytest$(EXEEXT): $(SpawnPropertytest_OBJECTS) $(SpawnPropertytest_DEPENDENCIES) $(EXTRA_SpawnPropertytest_DEPENDENCIES) 
 	@rm -f SpawnPropertytest$(EXEEXT)
 	$(AM_V_CXXLD)$(CXXLINK) $(SpawnPropertytest_OBJECTS) $(SpawnPropertytest_LDADD) $(LIBS)
+SpawnerPropertytest$(EXEEXT): $(SpawnerPropertytest_OBJECTS) $(SpawnerPropertytest_DEPENDENCIES) $(EXTRA_SpawnerPropertytest_DEPENDENCIES) 
+	@rm -f SpawnerPropertytest$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(SpawnerPropertytest_OBJECTS) $(SpawnerPropertytest_LDADD) $(LIBS)
 Spawntest$(EXEEXT): $(Spawntest_OBJECTS) $(Spawntest_DEPENDENCIES) $(EXTRA_Spawntest_DEPENDENCIES) 
 	@rm -f Spawntest$(EXEEXT)
 	$(AM_V_CXXLD)$(CXXLINK) $(Spawntest_OBJECTS) $(Spawntest_LDADD) $(LIBS)
@@ -4617,6 +4636,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/SolidPropertytest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/SpawnEntitytest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/SpawnPropertytest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/SpawnerPropertytest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Spawntest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Stackabletest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/StatisticsPropertyintegration.Po at am__quote@
@@ -5097,6 +5117,8 @@ BulletDomaintest.log: BulletDomaintest$(EXEEXT)
 	@p='BulletDomaintest$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 AtlasPropertiestest.log: AtlasPropertiestest$(EXEEXT)
 	@p='AtlasPropertiestest$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+SpawnerPropertytest.log: SpawnerPropertytest$(EXEEXT)
+	@p='SpawnerPropertytest$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 BaseMindtest.log: BaseMindtest$(EXEEXT)
 	@p='BaseMindtest$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 MemEntitytest.log: MemEntitytest$(EXEEXT)
diff --git a/tests/SpawnerPropertytest.cpp b/tests/SpawnerPropertytest.cpp
new file mode 100644
index 0000000..b6acfef
--- /dev/null
+++ b/tests/SpawnerPropertytest.cpp
@@ -0,0 +1,73 @@
+// Cyphesis Online RPG Server and AI Engine
+// Copyright (C) 2013 Erik Ogenvik
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#ifndef DEBUG
+#define DEBUG
+#endif
+
+#include "PropertyCoverage.h"
+
+#include "rulesets/SpawnerProperty.h"
+#include "common/Inheritance.h"
+
+int main()
+{
+    SpawnerProperty * ap = new SpawnerProperty;
+
+    PropertyChecker<SpawnerProperty> pc(ap);
+
+    pc.basicCoverage();
+
+    return 0;
+}
+
+#include "TestWorld.h"
+
+void TestWorld::message(const Operation & op, LocatedEntity & ent)
+{
+}
+
+LocatedEntity * TestWorld::addNewEntity(const std::string &,
+                                 const Atlas::Objects::Entity::RootEntity &)
+{
+    return 0;
+}
+
+
+// stubs
+
+Inheritance& Inheritance::instance() {
+    return *(Inheritance*)(nullptr);
+}
+
+const TypeNode * Inheritance::getType(const std::string & parent)
+{
+    return nullptr;
+}
+
+void addToEntity(const Point3D & p, std::vector<double> & vd)
+{
+}
+
+
+namespace Atlas { namespace Objects { namespace Operation {
+int TICK_NO = -1;
+} } }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/cyphesis-cpp.git



More information about the Pkg-games-commits mailing list