rewrite xml stuff #2 - will be testing the monsters xml code soon

This commit is contained in:
niczkx 2012-07-18 08:04:27 +02:00 committed by Eduardo Bart
parent b7b88dd117
commit c8d1d5ecf2
9 changed files with 117 additions and 355 deletions

View File

@ -216,17 +216,25 @@ inline std::string utf8StringToLatin1(uchar *utf8) {
// Convert string to lower case
inline std::string tolower(const std::string& str)
{
std::string _str = str;
boost::algorithm::to_lower(_str);
return _str;
std::string cpy = str;
boost::algorithm::to_lower(cpy);
return cpy;
}
// Convert string to upper case
inline std::string toupper(const std::string& str)
{
std::string _str = str;
boost::algorithm::to_upper(_str);
return _str;
std::string cpy = str;
boost::algorithm::to_upper(cpy);
return cpy;
}
// Trim string
inline std::string trim(const std::string& str)
{
std::string cpy = str;
boost::algorithm::trim(cpy);
return cpy;
}
// utility for printing messages into stdout

View File

@ -433,15 +433,9 @@ const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
return 0;
}
void TiXmlElement::RemoveAttribute( const char * name )
void TiXmlElement::RemoveAttribute(const std::string &name)
{
#ifdef TIXML_USE_STL
TIXML_STRING str( name );
TiXmlAttribute* node = attributeSet.Find( str );
#else
TiXmlAttribute* node = attributeSet.Find( name );
#endif
TiXmlAttribute* node = attributeSet.Find(name);
if ( node )
{
attributeSet.Remove( node );
@ -521,24 +515,12 @@ const TiXmlDocument* TiXmlNode::GetDocument() const
return 0;
}
TiXmlElement::TiXmlElement (const char * _value)
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
firstChild = lastChild = 0;
value = _value;
}
#ifdef TIXML_USE_STL
TiXmlElement::TiXmlElement( const std::string& _value )
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
firstChild = lastChild = 0;
value = _value;
}
#endif
TiXmlElement::TiXmlElement( const TiXmlElement& copy)
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
@ -573,207 +555,42 @@ void TiXmlElement::ClearThis()
}
}
const char* TiXmlElement::Attribute( const char* name ) const
{
const TiXmlAttribute* node = attributeSet.Find( name );
if ( node )
return node->Value();
return 0;
}
#ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name ) const
std::string TiXmlElement::Attribute( const std::string& name ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( attrib )
return &attrib->ValueStr();
return 0;
}
#endif
const char* TiXmlElement::Attribute( const char* name, int* i ) const
{
int p = readType<int>(name);
if(i)
*i = p;
return Attribute(name);
return attrib->ValueStr();
return std::string();
}
#ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
std::string TiXmlElement::Attribute( const std::string& name, int* i ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
const std::string* result = 0;
std::string result;
if ( attrib ) {
result = &attrib->ValueStr();
result = attrib->ValueStr();
if ( i ) {
attrib->QueryIntValue( i );
}
}
return result;
}
#endif
const char* TiXmlElement::Attribute(const char *name, double *d) const
{
double p = readType<double>(name);
if(d)
*d = p;
return Attribute(name);
}
#ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
std::string TiXmlElement::Attribute( const std::string& name, double* d ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
const std::string* result = 0;
std::string result = 0;
if ( attrib ) {
result = &attrib->ValueStr();
result = attrib->ValueStr();
if ( d ) {
attrib->QueryDoubleValue( d );
}
}
return result;
}
#endif
int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !attrib )
return TIXML_NO_ATTRIBUTE;
return attrib->QueryIntValue( ival );
}
int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* value ) const
{
const TiXmlAttribute* node = attributeSet.Find( name );
if ( !node )
return TIXML_NO_ATTRIBUTE;
int ival = 0;
int result = node->QueryIntValue( &ival );
*value = (unsigned)ival;
return result;
}
int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const
{
const TiXmlAttribute* node = attributeSet.Find( name );
if ( !node )
return TIXML_NO_ATTRIBUTE;
int result = TIXML_WRONG_TYPE;
if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) )
{
*bval = true;
result = TIXML_SUCCESS;
}
else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) )
{
*bval = false;
result = TIXML_SUCCESS;
}
return result;
}
#ifdef TIXML_USE_STL
int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !attrib )
return TIXML_NO_ATTRIBUTE;
return attrib->QueryIntValue( ival );
}
#endif
int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !attrib )
return TIXML_NO_ATTRIBUTE;
return attrib->QueryDoubleValue( dval );
}
#ifdef TIXML_USE_STL
int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !attrib )
return TIXML_NO_ATTRIBUTE;
return attrib->QueryDoubleValue( dval );
}
#endif
void TiXmlElement::SetAttribute( const char * name, int val )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetIntValue( val );
}
}
#ifdef TIXML_USE_STL
void TiXmlElement::SetAttribute( const std::string& name, int val )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetIntValue( val );
}
}
#endif
void TiXmlElement::SetDoubleAttribute( const char * name, double val )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetDoubleValue( val );
}
}
#ifdef TIXML_USE_STL
void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetDoubleValue( val );
}
}
#endif
void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
if ( attrib ) {
attrib->SetValue( cvalue );
}
}
#ifdef TIXML_USE_STL
void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
@ -781,7 +598,6 @@ void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _v
attrib->SetValue( _value );
}
}
#endif
void TiXmlElement::Print( FILE* cfile, int depth ) const

View File

@ -40,7 +40,7 @@ distribution.
#include <string.h>
#include <assert.h>
#include <framework/global.h>
#include <framework/const.h>
#include <otclient/position.h>
#include <framework/stdext/cast.h>
@ -945,43 +945,21 @@ private:
class TiXmlElement : public TiXmlNode
{
public:
/// Construct an element.
TiXmlElement (const char * in_value);
#ifdef TIXML_USE_STL
/// std::string constructor.
TiXmlElement( const std::string& _value );
#endif
TiXmlElement( const TiXmlElement& );
TiXmlElement& operator=( const TiXmlElement& base );
virtual ~TiXmlElement();
/** Given an attribute name, Attribute() returns the value
for the attribute of that name, or null if none exists.
*/
const char* Attribute( const char* name ) const;
/** Given an attribute name, Attribute() returns the value
for the attribute of that name, or null if none exists.
If the attribute exists and can be converted to an integer,
the integer value will be put in the return 'i', if 'i'
is non-null.
*/
const char* Attribute( const char* name, int* i ) const;
/** Given an attribute name, Attribute() returns the value
for the attribute of that name, or null if none exists.
If the attribute exists and can be converted to an double,
the double value will be put in the return 'd', if 'd'
is non-null.
*/
const char* Attribute( const char* name, double* d ) const;
template<typename T = std::string>
inline T readType(const std::string& str) const { return stdext::unsafe_cast<T>(Attribute(str)); }
inline T readType(const std::string& str) const
{
T ret;
int r = QueryValueAttribute(str, &ret);
if(r == TIXML_NO_ATTRIBUTE || r == TIXML_WRONG_TYPE)
return T();
return ret;
}
Position readPos(const std::string& base = std::string()) const
{
@ -992,43 +970,6 @@ public:
{
return Point(readType<int>("x"), readType<int>("y"));
}
/** QueryIntAttribute examines the attribute - it is an alternative to the
Attribute() method with richer error checking.
If the attribute is an integer, it is stored in 'value' and
the call returns TIXML_SUCCESS. If it is not
an integer, it returns TIXML_WRONG_TYPE. If the attribute
does not exist, then TIXML_NO_ATTRIBUTE is returned.
*/
int QueryIntAttribute( const char* name, int* _value ) const;
/// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute().
int QueryUnsignedAttribute( const char* name, unsigned* _value ) const;
/** QueryBoolAttribute examines the attribute - see QueryIntAttribute().
Note that '1', 'true', or 'yes' are considered true, while '0', 'false'
and 'no' are considered false.
*/
int QueryBoolAttribute( const char* name, bool* _value ) const;
/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
int QueryDoubleAttribute( const char* name, double* _value ) const;
/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
int QueryFloatAttribute( const char* name, float* _value ) const {
double d;
int result = QueryDoubleAttribute( name, &d );
if ( result == TIXML_SUCCESS ) {
*_value = (float)d;
}
return result;
}
#ifdef TIXML_USE_STL
/// QueryStringAttribute examines the attribute - see QueryIntAttribute().
int QueryStringAttribute( const char* name, std::string* _value ) const {
const char* cstr = Attribute( name );
if ( cstr ) {
*_value = std::string( cstr );
return TIXML_SUCCESS;
}
return TIXML_NO_ATTRIBUTE;
}
/** Template form of the attribute query which will try to read the
attribute into the specified type. Very easy, very powerful, but
@ -1059,44 +1000,14 @@ public:
*outValue = node->ValueStr();
return TIXML_SUCCESS;
}
#endif
/** Sets an attribute of name to a given value. The attribute
will be created if it does not exist, or changed if it does.
*/
void SetAttribute( const char* name, const char * _value );
std::string Attribute( const std::string& name ) const;
std::string Attribute( const std::string& name, int* i ) const;
std::string Attribute( const std::string& name, double* d ) const;
#ifdef TIXML_USE_STL
const std::string* Attribute( const std::string& name ) const;
const std::string* Attribute( const std::string& name, int* i ) const;
const std::string* Attribute( const std::string& name, double* d ) const;
int QueryIntAttribute( const std::string& name, int* _value ) const;
int QueryDoubleAttribute( const std::string& name, double* _value ) const;
/// STL std::string form.
void SetAttribute( const std::string& name, const std::string& _value );
///< STL std::string form.
void SetAttribute( const std::string& name, int _value );
///< STL std::string form.
void SetDoubleAttribute( const std::string& name, double value );
#endif
/** Sets an attribute of name to a given value. The attribute
will be created if it does not exist, or changed if it does.
*/
void SetAttribute( const char * name, int value );
/** Sets an attribute of name to a given value. The attribute
will be created if it does not exist, or changed if it does.
*/
void SetDoubleAttribute( const char * name, double value );
/** Deletes an attribute with the given name.
*/
void RemoveAttribute( const char * name );
#ifdef TIXML_USE_STL
void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form.
#endif
void RemoveAttribute( const std::string& name );
const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element.
TiXmlAttribute* FirstAttribute() { return attributeSet.First(); }

View File

@ -48,6 +48,7 @@ class ThingTypeDat;
class ThingTypeOtb;
class House;
class Town;
class MonsterType;
typedef std::shared_ptr<MapView> MapViewPtr;
typedef std::shared_ptr<Tile> TilePtr;
@ -67,6 +68,7 @@ typedef std::shared_ptr<ThingTypeDat> ThingTypeDatPtr;
typedef std::shared_ptr<ThingTypeOtb> ThingTypeOtbPtr;
typedef std::shared_ptr<House> HousePtr;
typedef std::shared_ptr<Town> TownPtr;
typedef std::shared_ptr<MonsterType> MonsterTypePtr;
typedef std::vector<ThingPtr> ThingList;
typedef std::vector<ThingTypeDatPtr> ThingTypeDatList;

View File

@ -296,6 +296,15 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<Town>("getPos", &Town::getPos);
g_lua.bindClassMemberFunction<Town>("getTemplePos", &Town::getPos); // alternative method
g_lua.registerClass<MonsterType>();
g_lua.bindClassStaticFunction<MonsterType>("create", []{ return MonsterTypePtr(new MonsterType); });
g_lua.bindClassMemberFunction<MonsterType>("setPos", &MonsterType::setPos);
g_lua.bindClassMemberFunction<MonsterType>("setName", &MonsterType::setName);
g_lua.bindClassMemberFunction<MonsterType>("setOutfit", &MonsterType::setOutfit);
g_lua.bindClassMemberFunction<MonsterType>("getPos", &MonsterType::getPos);
g_lua.bindClassMemberFunction<MonsterType>("getName", &MonsterType::getName);
g_lua.bindClassMemberFunction<MonsterType>("getOutfit", &MonsterType::getOutfit);
g_lua.registerClass<Creature, Thing>();
g_lua.bindClassStaticFunction<Creature>("create", []{ return CreaturePtr(new Creature); });
g_lua.bindClassMemberFunction<Creature>("getId", &Creature::getId);

View File

@ -100,7 +100,7 @@ void Map::loadOtbm(const std::string& fileName)
root->skip(3);
uint32 headerMinorItems = root->getU32();
if(headerMinorItems > g_things.getOtbMinorVersion()) {
g_logger.warning(stdext::format("This map needs an updated OTB. read %d what it's supposed to be: %d",
g_logger.warning(stdext::format("This map needs an updated OTB. read %d what it's supposed to be: %d or less",
headerMinorItems, g_things.getOtbMinorVersion()));
}
@ -126,18 +126,17 @@ void Map::loadOtbm(const std::string& fileName)
}
}
for (const BinaryTreePtr &nodeMapData : node->getChildren()) {
for(const BinaryTreePtr &nodeMapData : node->getChildren()) {
uint8 mapDataType = nodeMapData->getU8();
if(mapDataType == OTBM_TILE_AREA) {
uint16 baseX = nodeMapData->getU16(), baseY = nodeMapData->getU16();
uint8 pz = nodeMapData->getU8();
for (const BinaryTreePtr &nodeTile : nodeMapData->getChildren()) {
for(const BinaryTreePtr &nodeTile : nodeMapData->getChildren()) {
uint8 type = nodeTile->getU8();
if(type != OTBM_TILE && type != OTBM_HOUSETILE)
stdext::throw_exception(stdext::format("invalid node tile type %d", (int)type));
ItemPtr ground = nullptr;
HousePtr house = nullptr;
uint32 flags = TILESTATE_NONE;
@ -154,7 +153,7 @@ void Map::loadOtbm(const std::string& fileName)
house->setTile(tile);
}
while (nodeTile->canRead()) {
while(nodeTile->canRead()) {
uint8 tileAttr = nodeTile->getU8();
switch (tileAttr) {
case OTBM_ATTR_TILE_FLAGS: {
@ -178,13 +177,14 @@ void Map::loadOtbm(const std::string& fileName)
addThing(Item::createFromOtb(nodeTile->getU16()), pos);
break;
}
default:
default: {
stdext::throw_exception(stdext::format("invalid tile attribute %d at pos %d, %d, %d",
(int)tileAttr, px, py, pz));
}
}
}
for (const BinaryTreePtr &nodeItem : nodeTile->getChildren()) {
for(const BinaryTreePtr &nodeItem : nodeTile->getChildren()) {
if(nodeItem->getU8() != OTBM_ITEM)
stdext::throw_exception("invalid item node");
@ -194,7 +194,7 @@ void Map::loadOtbm(const std::string& fileName)
if(item->isContainer()) {
// This is a temporary way for reading container items.
MapContainerPtr mapContainer(new MapContainer);
for (const BinaryTreePtr &insideItem : nodeItem->getChildren()) {
for(const BinaryTreePtr &insideItem : nodeItem->getChildren()) {
if(insideItem->getU8() != OTBM_ITEM)
stdext::throw_exception("invalid container item node");
@ -209,7 +209,7 @@ void Map::loadOtbm(const std::string& fileName)
if(item->isMoveable()) {
g_logger.warning(stdext::format("Movable item found in house: %d at pos %d %d %d - escaping...", item->getId(),
px, py, pz));
item = nullptr;
item.reset();
} else if(item->isDoor())
house->addDoor(item->getDoorId(), pos);
}
@ -222,7 +222,7 @@ void Map::loadOtbm(const std::string& fileName)
}
} else if(mapDataType == OTBM_TOWNS) {
TownPtr town = nullptr;
for (const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) {
for(const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) {
if(nodeTown->getU8() != OTBM_TOWN)
stdext::throw_exception("invalid town node.");
@ -232,15 +232,10 @@ void Map::loadOtbm(const std::string& fileName)
if(!(town = m_towns.getTown(townId))) {
town = TownPtr(new Town(townId, townName, townCoords));
m_towns.addTown(town);
} else {
// override data
town->setName(townName);
town->setPos(townCoords);
town->setId(townId);
}
} // a map editor cannot be that dumb and write duplicate towns
}
} else if(mapDataType == OTBM_WAYPOINTS && headerVersion > 1) {
for (const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) {
for(const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) {
if(nodeWaypoint->getU8() != OTBM_WAYPOINT)
stdext::throw_exception("invalid waypoint node.");
@ -399,13 +394,13 @@ void Map::loadSpawns(const std::string &fileName)
stdext::throw_exception("invalid spawn-subnode");
std::string mName = mType->Attribute("name");
MonsterPtr m = m_monsters.getMonster(mName);
MonsterTypePtr m = m_monsters.getMonster(mName);
if (!m)
stdext::throw_exception(stdext::format("unkown monster %s", mName));
Point off = mType->readPoint();
Position mPos(centerPos.x + off.x, centerPos.y + off.y, centerPos.z);
addThing(m, mPos, -1);
m->setPos(mPos);
}
}
}
@ -1029,7 +1024,7 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
return ret;
}
MonsterPtr Map::getMonster(const std::string& name)
MonsterTypePtr Map::getMonster(const std::string& name)
{
return m_monsters.getMonster(stdext::tolower(name));
return m_monsters.getMonster(stdext::trim(stdext::tolower(name)));
}

View File

@ -151,7 +151,7 @@ public:
// town/house/monster related
TownPtr getTown(uint32 tid) { return m_towns.getTown(tid); }
HousePtr getHouse(uint32 hid) { return m_houses.getHouse(hid); }
MonsterPtr getMonster(const std::string &name);
MonsterTypePtr getMonster(const std::string &name);
void setLight(const Light& light) { m_light = light; }
void setCentralPosition(const Position& centralPosition);

View File

@ -36,9 +36,7 @@ void Monsters::loadMonsters(const std::string& file)
stdext::throw_exception("malformed monsters xml file");
for(TiXmlElement* monster = root->FirstChildElement(); root; root = root->NextSiblingElement()) {
MonsterPtr newMonster(new Monster);
newMonster->setName(monster->Attribute("name"));
MonsterTypePtr newMonster(new MonsterType(monster->Attribute("name")));
loadSingleMonster(file.substr(0, file.find_last_of('/')) + '/' + monster->Attribute("file"), newMonster);
}
@ -46,7 +44,7 @@ void Monsters::loadMonsters(const std::string& file)
m_loaded = true;
}
void Monsters::loadSingleMonster(const std::string& file, const MonsterPtr& m)
void Monsters::loadSingleMonster(const std::string& file, const MonsterTypePtr& m)
{
if (!m || std::find(m_monsters.begin(), m_monsters.end(), m) != m_monsters.end())
stdext::throw_exception("reloading monsters is not supported yet.");
@ -85,16 +83,16 @@ void Monsters::loadSingleMonster(const std::string& file, const MonsterPtr& m)
m_monsters.push_back(m);
}
MonsterPtr Monsters::getMonster(const std::string& name)
MonsterTypePtr Monsters::getMonster(const std::string& name)
{
auto it = std::find_if(m_monsters.begin(), m_monsters.end(),
[=] (const MonsterPtr& m) -> bool { return m->getName() == name; });
[=] (const MonsterTypePtr& m) -> bool { return m->getName() == name; });
return it != m_monsters.end() ? *it : nullptr;
}
MonsterPtr Monsters::getMonsterByPos(const Position& pos)
MonsterTypePtr Monsters::getMonsterByPos(const Position& pos)
{
auto it = std::find_if(m_monsters.begin(), m_monsters.end(),
[=] (const MonsterPtr& m) -> bool { return m->getPosition() == pos; });
[=] (const MonsterTypePtr& m) -> bool { return m->getPos() == pos; });
return it != m_monsters.end() ? *it : nullptr;
}

View File

@ -24,6 +24,29 @@
#define MONSTERS_H
#include "declarations.h"
#include <framework/luaengine/luaobject.h>
#include "outfit.h"
class MonsterType : public LuaObject
{
public:
MonsterType() { }
MonsterType(const std::string& name)
: m_name(name) { }
void setPos(const Position& pos) { m_pos = pos; }
void setName(const std::string& name) { m_name = name; }
void setOutfit(const Outfit& o) { m_outfit = o; }
std::string getName() { return m_name; }
Position getPos() { return m_pos; }
Outfit getOutfit() { return m_outfit; }
private:
Position m_pos;
std::string m_name;
Outfit m_outfit;
};
class Monsters
{
@ -31,14 +54,14 @@ public:
void clear() { m_monsters.clear(); }
void loadMonsters(const std::string& file);
void loadSingleMonster(const std::string& file, const MonsterPtr& m = nullptr);
void loadSingleMonster(const std::string& file, const MonsterTypePtr& m = nullptr);
MonsterPtr getMonster(const std::string& name);
MonsterPtr getMonsterByPos(const Position& pos);
MonsterTypePtr getMonster(const std::string& name);
MonsterTypePtr getMonsterByPos(const Position& pos);
bool isLoaded() const { return m_loaded; }
private:
std::vector<MonsterPtr> m_monsters;
std::vector<MonsterTypePtr> m_monsters;
bool m_loaded;
};