[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