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 // Convert string to lower case
inline std::string tolower(const std::string& str) inline std::string tolower(const std::string& str)
{ {
std::string _str = str; std::string cpy = str;
boost::algorithm::to_lower(_str); boost::algorithm::to_lower(cpy);
return _str; return cpy;
} }
// Convert string to upper case // Convert string to upper case
inline std::string toupper(const std::string& str) inline std::string toupper(const std::string& str)
{ {
std::string _str = str; std::string cpy = str;
boost::algorithm::to_upper(_str); boost::algorithm::to_upper(cpy);
return _str; 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 // utility for printing messages into stdout

View File

@ -433,15 +433,9 @@ const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
return 0; return 0;
} }
void TiXmlElement::RemoveAttribute(const std::string &name)
void TiXmlElement::RemoveAttribute( const char * name )
{ {
#ifdef TIXML_USE_STL TiXmlAttribute* node = attributeSet.Find(name);
TIXML_STRING str( name );
TiXmlAttribute* node = attributeSet.Find( str );
#else
TiXmlAttribute* node = attributeSet.Find( name );
#endif
if ( node ) if ( node )
{ {
attributeSet.Remove( node ); attributeSet.Remove( node );
@ -521,24 +515,12 @@ const TiXmlDocument* TiXmlNode::GetDocument() const
return 0; 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 ) TiXmlElement::TiXmlElement( const std::string& _value )
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{ {
firstChild = lastChild = 0; firstChild = lastChild = 0;
value = _value; value = _value;
} }
#endif
TiXmlElement::TiXmlElement( const TiXmlElement& copy) TiXmlElement::TiXmlElement( const TiXmlElement& copy)
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) : TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
@ -573,207 +555,42 @@ void TiXmlElement::ClearThis()
} }
} }
std::string TiXmlElement::Attribute( const std::string& name ) const
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
{ {
const TiXmlAttribute* attrib = attributeSet.Find( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( attrib ) if ( attrib )
return &attrib->ValueStr(); return attrib->ValueStr();
return 0; return std::string();
}
#endif
const char* TiXmlElement::Attribute( const char* name, int* i ) const
{
int p = readType<int>(name);
if(i)
*i = p;
return Attribute(name);
} }
std::string TiXmlElement::Attribute( const std::string& name, int* i ) const
#ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
{ {
const TiXmlAttribute* attrib = attributeSet.Find( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
const std::string* result = 0; std::string result;
if ( attrib ) { if ( attrib ) {
result = &attrib->ValueStr(); result = attrib->ValueStr();
if ( i ) { if ( i ) {
attrib->QueryIntValue( i ); attrib->QueryIntValue( i );
} }
} }
return result; return result;
} }
#endif
const char* TiXmlElement::Attribute(const char *name, double *d) const std::string TiXmlElement::Attribute( const std::string& 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
{ {
const TiXmlAttribute* attrib = attributeSet.Find( name ); const TiXmlAttribute* attrib = attributeSet.Find( name );
const std::string* result = 0; std::string result = 0;
if ( attrib ) { if ( attrib ) {
result = &attrib->ValueStr(); result = attrib->ValueStr();
if ( d ) { if ( d ) {
attrib->QueryDoubleValue( d ); attrib->QueryDoubleValue( d );
} }
} }
return result; 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 ) void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
{ {
TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name ); TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
@ -781,7 +598,6 @@ void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _v
attrib->SetValue( _value ); attrib->SetValue( _value );
} }
} }
#endif
void TiXmlElement::Print( FILE* cfile, int depth ) const void TiXmlElement::Print( FILE* cfile, int depth ) const

View File

@ -40,7 +40,7 @@ distribution.
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <framework/global.h> #include <framework/const.h>
#include <otclient/position.h> #include <otclient/position.h>
#include <framework/stdext/cast.h> #include <framework/stdext/cast.h>
@ -945,43 +945,21 @@ private:
class TiXmlElement : public TiXmlNode class TiXmlElement : public TiXmlNode
{ {
public: public:
/// Construct an element.
TiXmlElement (const char * in_value);
#ifdef TIXML_USE_STL
/// std::string constructor.
TiXmlElement( const std::string& _value ); TiXmlElement( const std::string& _value );
#endif
TiXmlElement( const TiXmlElement& ); TiXmlElement( const TiXmlElement& );
TiXmlElement& operator=( const TiXmlElement& base ); TiXmlElement& operator=( const TiXmlElement& base );
virtual ~TiXmlElement(); 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> 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 Position readPos(const std::string& base = std::string()) const
{ {
@ -992,43 +970,6 @@ public:
{ {
return Point(readType<int>("x"), readType<int>("y")); 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 /** Template form of the attribute query which will try to read the
attribute into the specified type. Very easy, very powerful, but attribute into the specified type. Very easy, very powerful, but
@ -1059,44 +1000,14 @@ public:
*outValue = node->ValueStr(); *outValue = node->ValueStr();
return TIXML_SUCCESS; return TIXML_SUCCESS;
} }
#endif
/** Sets an attribute of name to a given value. The attribute std::string Attribute( const std::string& name ) const;
will be created if it does not exist, or changed if it does. std::string Attribute( const std::string& name, int* i ) const;
*/ std::string Attribute( const std::string& name, double* d ) const;
void SetAttribute( const char* name, const char * _value );
#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 ); 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 void RemoveAttribute( const std::string& name );
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
const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element.
TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } TiXmlAttribute* FirstAttribute() { return attributeSet.First(); }

View File

@ -48,6 +48,7 @@ class ThingTypeDat;
class ThingTypeOtb; class ThingTypeOtb;
class House; class House;
class Town; class Town;
class MonsterType;
typedef std::shared_ptr<MapView> MapViewPtr; typedef std::shared_ptr<MapView> MapViewPtr;
typedef std::shared_ptr<Tile> TilePtr; 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<ThingTypeOtb> ThingTypeOtbPtr;
typedef std::shared_ptr<House> HousePtr; typedef std::shared_ptr<House> HousePtr;
typedef std::shared_ptr<Town> TownPtr; typedef std::shared_ptr<Town> TownPtr;
typedef std::shared_ptr<MonsterType> MonsterTypePtr;
typedef std::vector<ThingPtr> ThingList; typedef std::vector<ThingPtr> ThingList;
typedef std::vector<ThingTypeDatPtr> ThingTypeDatList; 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>("getPos", &Town::getPos);
g_lua.bindClassMemberFunction<Town>("getTemplePos", &Town::getPos); // alternative method 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.registerClass<Creature, Thing>();
g_lua.bindClassStaticFunction<Creature>("create", []{ return CreaturePtr(new Creature); }); g_lua.bindClassStaticFunction<Creature>("create", []{ return CreaturePtr(new Creature); });
g_lua.bindClassMemberFunction<Creature>("getId", &Creature::getId); g_lua.bindClassMemberFunction<Creature>("getId", &Creature::getId);

View File

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

View File

@ -27,41 +27,39 @@
void Monsters::loadMonsters(const std::string& file) void Monsters::loadMonsters(const std::string& file)
{ {
TiXmlDocument doc(file); TiXmlDocument doc(file);
if(!doc.LoadFile()) if(!doc.LoadFile())
stdext::throw_exception(stdext::format("cannot open monsters file '%s'", file)); stdext::throw_exception(stdext::format("cannot open monsters file '%s'", file));
TiXmlElement* root = doc.FirstChildElement(); TiXmlElement* root = doc.FirstChildElement();
if(!root || root->ValueStr() != "monsters") if(!root || root->ValueStr() != "monsters")
stdext::throw_exception("malformed monsters xml file"); stdext::throw_exception("malformed monsters xml file");
for(TiXmlElement* monster = root->FirstChildElement(); root; root = root->NextSiblingElement()) { for(TiXmlElement* monster = root->FirstChildElement(); root; root = root->NextSiblingElement()) {
MonsterPtr newMonster(new Monster); MonsterTypePtr newMonster(new MonsterType(monster->Attribute("name")));
newMonster->setName(monster->Attribute("name"));
loadSingleMonster(file.substr(0, file.find_last_of('/')) + '/' + monster->Attribute("file"), newMonster); loadSingleMonster(file.substr(0, file.find_last_of('/')) + '/' + monster->Attribute("file"), newMonster);
} }
doc.Clear(); doc.Clear();
m_loaded = true; 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()) if (!m || std::find(m_monsters.begin(), m_monsters.end(), m) != m_monsters.end())
stdext::throw_exception("reloading monsters is not supported yet."); stdext::throw_exception("reloading monsters is not supported yet.");
TiXmlDocument doc(file); TiXmlDocument doc(file);
if(!doc.LoadFile()) if(!doc.LoadFile())
stdext::throw_exception(stdext::format("cannot load single monster file '%s'", file)); stdext::throw_exception(stdext::format("cannot load single monster file '%s'", file));
TiXmlElement* root = doc.FirstChildElement(); TiXmlElement* root = doc.FirstChildElement();
if(!root || root->ValueStr() != "monster") if(!root || root->ValueStr() != "monster")
stdext::throw_exception(stdext::format("malformed monster xml file: %s", file)); stdext::throw_exception(stdext::format("malformed monster xml file: %s", file));
for(TiXmlElement* attrib = root->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) { for(TiXmlElement* attrib = root->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
if(attrib->ValueStr() == "look") { if(attrib->ValueStr() == "look") {
Outfit out; Outfit out;
int type = attrib->readType<int>("type"); int type = attrib->readType<int>("type");
if (type <= 0) if (type <= 0)
@ -85,16 +83,16 @@ void Monsters::loadSingleMonster(const std::string& file, const MonsterPtr& m)
m_monsters.push_back(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(), 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; 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(), 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; return it != m_monsters.end() ? *it : nullptr;
} }

View File

@ -24,6 +24,29 @@
#define MONSTERS_H #define MONSTERS_H
#include "declarations.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 class Monsters
{ {
@ -31,14 +54,14 @@ public:
void clear() { m_monsters.clear(); } void clear() { m_monsters.clear(); }
void loadMonsters(const std::string& file); 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); MonsterTypePtr getMonster(const std::string& name);
MonsterPtr getMonsterByPos(const Position& pos); MonsterTypePtr getMonsterByPos(const Position& pos);
bool isLoaded() const { return m_loaded; } bool isLoaded() const { return m_loaded; }
private: private:
std::vector<MonsterPtr> m_monsters; std::vector<MonsterTypePtr> m_monsters;
bool m_loaded; bool m_loaded;
}; };