// Cyphesis Online RPG Server and AI Engine
// Copyright (C) 2000,2001 Alistair Riddoch
//
// 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
// $Id: Persistor.cpp,v 1.39 2007-12-03 23:18:52 alriddoch Exp $
#include "Persistor.h"
#include "Persistor_impl.h"
#include "rulesets/Entity.h"
#include "rulesets/Thing.h"
#include "rulesets/Character.h"
#include "rulesets/Creator.h"
#include "rulesets/Plant.h"
#include "rulesets/Stackable.h"
#include "rulesets/Structure.h"
#include "rulesets/World.h"
#include "common/Database.h"
#include "common/terrain_utils.h"
using Atlas::Message::MapType;
template<>
Persistor<Entity>::Persistor(bool temp) : m_class("entity")
{
if (temp) { return; }
MapType desc;
desc["class"] = " ";
desc["type"] = " ";
// desc["loc"] = " ";
desc["loc"] = 0;
desc["cont"] = 0;
desc["px"] = 1.0;
desc["py"] = 1.0;
desc["pz"] = 1.0;
desc["ox"] = 1.0;
desc["oy"] = 1.0;
desc["oz"] = 1.0;
desc["ow"] = 1.0;
desc["hasBox"] = 0xb001;
desc["bnx"] = 1.0;
desc["bny"] = 1.0;
desc["bnz"] = 1.0;
desc["bfx"] = 1.0;
desc["bfy"] = 1.0;
desc["bfz"] = 1.0;
desc["status"] = 1.0;
desc["name"] = " ";
desc["mass"] = 1.0;
desc["seq"] = 0;
desc["attributes"] = "";
Database::instance()->registerEntityTable(m_class, desc);
}
template<>
Persistor<Thing>::Persistor(bool temp) : m_class("thing")
{
if (temp) { return; }
MapType desc;
// FIXME Sort out attributes
Database::instance()->registerEntityTable(m_class, desc, "entity");
}
template<>
Persistor<Line>::Persistor(bool temp) : m_class("line")
{
if (temp) { return; }
MapType desc;
// FIXME Sort out attributes
Database::instance()->registerEntityTable(m_class, desc, "thing");
}
template<>
Persistor<Area>::Persistor(bool temp) : m_class("area")
{
if (temp) { return; }
MapType desc;
// FIXME Sort out attributes
Database::instance()->registerEntityTable(m_class, desc, "thing");
}
template<>
Persistor<Character>::Persistor(bool temp) : m_class("character")
{
if (temp) { return; }
MapType desc;
// FIXME Sort out attributes
desc["sex"] = " ";
desc["drunkness"] = 1.0;
desc["food"] = 1.0;
desc["right_hand_wield"] = " ";
Database::instance()->registerEntityTable(m_class, desc, "thing");
}
template<>
Persistor<Creator>::Persistor(bool temp) : m_class("creator")
{
if (temp) { return; }
// Creator entities are not persisted
}
template<>
Persistor<Plant>::Persistor(bool temp) : m_class("plant")
{
if (temp) { return; }
MapType desc;
// FIXME Sort out attributes
desc["fruits"] = 1;
desc["fruitName"] = " ";
desc["fruitChance"] = 1;
desc["sizeAdult"] = 1.0;
Database::instance()->registerEntityTable(m_class, desc, "thing");
}
template<>
Persistor<Stackable>::Persistor(bool temp) : m_class("stackable")
{
if (temp) { return; }
MapType desc;
// FIXME Sort out attributes
desc["num"] = 1;
Database::instance()->registerEntityTable(m_class, desc, "thing");
}
template<>
Persistor<Structure>::Persistor(bool temp) : m_class("structure")
{
if (temp) { return; }
MapType desc;
// FIXME Sort out attributes
Database::instance()->registerEntityTable(m_class, desc, "thing");
}
template<>
Persistor<World>::Persistor(bool temp) : m_class("world")
{
if (temp) { return; }
MapType desc;
// FIXME Sort out attributes
Database::instance()->registerEntityTable(m_class, desc, "entity");
desc.clear();
desc["height"] = 0.1f;
Database::instance()->registerArrayTable("terrain", 2, desc);
}
template<>
void Persistor<Character>::update(Character * t)
{
std::string columns;
uCharacter(*t, columns);
uEntity(*t, columns);
Database::instance()->updateEntityRow(m_class, t->getId(), columns);
t->clearUpdateFlags();
}
template<>
void Persistor<Creator>::update(Creator * t)
{
// Creator entities are not persisted
// Is this really needed? Probably not, as its never called.
}
template<>
void Persistor<Plant>::update(Plant * t)
{
std::string columns;
uPlant(*t, columns);
uEntity(*t, columns);
Database::instance()->updateEntityRow(m_class, t->getId(), columns);
t->clearUpdateFlags();
}
template<>
void Persistor<World>::update(World * t)
{
if (t->getUpdateFlags() & ~a_terrain) {
std::string columns;
uEntity(*t, columns);
Database::instance()->updateEntityRow(m_class, t->getId(), columns);
}
if (t->getUpdateFlags() & a_terrain) {
updateStoredTerrain(t->getId(), t->terrain(), t->modifiedTerrain(),
t->createdTerrain());
t->clearTerrainFlags();
}
t->clearUpdateFlags();
}
template<>
void Persistor<Character>::hookup(Character & t)
{
t.updated.connect(sigc::bind(sigc::mem_fun(this,
&Persistor<Character>::update),
&t));
t.destroyed.connect(sigc::bind(sigc::mem_fun(this,
&Persistor<Character>::remove),
&t));
}
template<>
void Persistor<Character>::persist(Character & t)
{
hookup(t);
std::string columns;
std::string values;
cEntity(t, columns, values);
cCharacter(t, columns, values);
Database::instance()->createEntityRow(m_class, t.getId(), columns, values);
}
template<>
void Persistor<Plant>::persist(Plant & p)
{
hookup(p);
std::string columns;
std::string values;
cEntity(p, columns, values);
cPlant(p, columns, values);
Database::instance()->createEntityRow(m_class, p.getId(), columns, values);
}
template<>
void Persistor<Creator>::persist(Creator & t)
{
// Creator entities are not persisted
}
template<>
void Persistor<World>::hookup(World & t)
{
t.updated.connect(sigc::bind(sigc::mem_fun(this, &Persistor<World>::update),
&t));
// The game world should never be destroyed, so we don't connect
// it to a remove function.
}
template<>
void Persistor<World>::cEntity(Entity & t, std::string & c, std::string & v)
{
const char * cs = ", ";
const char * sq = "'";
if (!c.empty()) {
c += cs;
}
c += "class, type, cont, px, py, pz, ox, oy, oz, ow, hasBox, bnx, bny, bnz, bfx, bfy, bfz, status, name, mass, seq, attributes";
std::stringstream q;
q << sq << m_class << sq << cs
<< sq << t.getType() << sq << cs
<< t.m_contains.size() << cs
<< t.m_location.pos().x() << cs
<< t.m_location.pos().y() << cs
<< t.m_location.pos().z() << cs;
if (t.m_location.orientation().isValid()) {
q << t.m_location.orientation().vector().x() << cs
<< t.m_location.orientation().vector().y() << cs
<< t.m_location.orientation().vector().z() << cs
<< t.m_location.orientation().scalar() << cs;
} else {
q << "0, 0, 0, 1, ";
}
if (t.m_location.bBox().isValid()) {
q << "'t', "
<< t.m_location.bBox().lowCorner().x() << cs
<< t.m_location.bBox().lowCorner().y() << cs
<< t.m_location.bBox().lowCorner().z() << cs
<< t.m_location.bBox().highCorner().x() << cs
<< t.m_location.bBox().highCorner().y() << cs
<< t.m_location.bBox().highCorner().z() << cs;
} else {
q << "'f', 0, 0, 0, 0, 0, 0, ";
}
q << t.getSeq() << cs;
if (t.getAttributes().empty()) {
q << "''";
} else {
std::string aString;
Database::instance()->encodeObject(t.getAttributes(), aString);
q << "'" << aString << "'";
}
if (!v.empty()) {
v += cs;
}
v += q.str();
}
template<>
void Persistor<World>::persist(World & t)
{
hookup(t);
std::string columns;
std::string values;
cEntity(t, columns, values);
Database::instance()->createEntityRow(m_class, t.getId(), columns, values);
storeTerrain(t.getId(), t.terrain());
}
template class Persistor<Entity>;
template class Persistor<Thing>;
template class Persistor<Character>;
template class Persistor<Creator>;
template class Persistor<Plant>;
template class Persistor<Stackable>;
template class Persistor<Structure>;
template class Persistor<World>;
syntax highlighted by Code2HTML, v. 0.9.1