XML saving and minor fixes + code refactoring.

Signed-off-by: otfallen <f.fallen45@gmail.com>
This commit is contained in:
otfallen 2012-09-14 21:38:21 +00:00
parent 1ecaca82b7
commit eb7a11158a
14 changed files with 437 additions and 170 deletions

View File

@ -66,6 +66,7 @@ void Application::registerLuaFunctions()
g_lua.bindGlobalFunction("iptostring", [](int v) { return stdext::ip_to_string(v); }); g_lua.bindGlobalFunction("iptostring", [](int v) { return stdext::ip_to_string(v); });
g_lua.bindGlobalFunction("stringtoip", [](const std::string& v) { return stdext::string_to_ip(v); }); g_lua.bindGlobalFunction("stringtoip", [](const std::string& v) { return stdext::string_to_ip(v); });
g_lua.bindGlobalFunction("listSubnetAddresses", [](uint32 a, uint8 b) { return stdext::listSubnetAddresses(a, b); }); g_lua.bindGlobalFunction("listSubnetAddresses", [](uint32 a, uint8 b) { return stdext::listSubnetAddresses(a, b); });
g_lua.bindGlobalFunction("ucwords", [](std::string s) { return stdext::ucwords(s); });
// Application // Application
g_lua.registerSingletonClass("g_app"); g_lua.registerSingletonClass("g_app");
@ -154,6 +155,7 @@ void Application::registerLuaFunctions()
g_lua.bindSingletonFunction("g_resources", "searchAndAddPackages", &ResourceManager::searchAndAddPackages, &g_resources); g_lua.bindSingletonFunction("g_resources", "searchAndAddPackages", &ResourceManager::searchAndAddPackages, &g_resources);
g_lua.bindSingletonFunction("g_resources", "removeSearchPath", &ResourceManager::removeSearchPath, &g_resources); g_lua.bindSingletonFunction("g_resources", "removeSearchPath", &ResourceManager::removeSearchPath, &g_resources);
g_lua.bindSingletonFunction("g_resources", "fileExists", &ResourceManager::fileExists, &g_resources); g_lua.bindSingletonFunction("g_resources", "fileExists", &ResourceManager::fileExists, &g_resources);
g_lua.bindSingletonFunction("g_resources", "directoryExists", &ResourceManager::directoryExists, &g_resources);
g_lua.bindSingletonFunction("g_resources", "getRealDir", &ResourceManager::getRealDir, &g_resources); g_lua.bindSingletonFunction("g_resources", "getRealDir", &ResourceManager::getRealDir, &g_resources);
g_lua.bindSingletonFunction("g_resources", "getWorkDir", &ResourceManager::getWorkDir, &g_resources); g_lua.bindSingletonFunction("g_resources", "getWorkDir", &ResourceManager::getWorkDir, &g_resources);
g_lua.bindSingletonFunction("g_resources", "getSearchPaths", &ResourceManager::getSearchPaths, &g_resources); g_lua.bindSingletonFunction("g_resources", "getSearchPaths", &ResourceManager::getSearchPaths, &g_resources);

View File

@ -43,6 +43,7 @@ distribution.
#include <framework/const.h> #include <framework/const.h>
#include <otclient/position.h> #include <otclient/position.h>
#include <framework/stdext/cast.h> #include <framework/stdext/cast.h>
#include <framework/stdext/string.h>
// Help out windows: // Help out windows:
#if defined( _DEBUG ) && !defined( DEBUG ) #if defined( _DEBUG ) && !defined( DEBUG )
@ -51,7 +52,7 @@ distribution.
#ifdef TIXML_USE_STL #ifdef TIXML_USE_STL
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#define TIXML_STRING std::string #define TIXML_STRING std::string
#else #else
@ -1005,6 +1006,7 @@ public:
std::string Attribute( const std::string& name, double* d ) const; std::string Attribute( const std::string& name, double* d ) const;
void SetAttribute( const std::string& name, const std::string& _value ); void SetAttribute( const std::string& name, const std::string& _value );
void SetAttribute( const std::string& name, int _value) { SetAttribute(name, stdext::to_string(_value)); }
void RemoveAttribute( const std::string& name ); void RemoveAttribute( const std::string& name );

View File

@ -22,22 +22,138 @@
#include "creatures.h" #include "creatures.h"
#include "creature.h" #include "creature.h"
#include "map.h"
#include <framework/xml/tinyxml.h> #include <framework/xml/tinyxml.h>
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
Creatures g_creatures; CreatureManager g_creatures;
void Spawn::load(TiXmlElement* node)
{
Position centerPos = node->readPos("center");
setCenterPos(centerPos);
setRadius(node->readType<int32>("radius"));
CreatureTypePtr cType(nullptr);
for(TiXmlElement* cNode = node->FirstChildElement(); cNode; cNode = cNode->NextSiblingElement()) {
if(cNode->ValueStr() != "monster" && cNode->ValueStr() != "npc")
stdext::throw_exception(stdext::format("invalid spawn-subnode %s", cNode->ValueStr()));
std::string cName = cNode->Attribute("name");
stdext::tolower(cName);
stdext::trim(cName);
if (!(cType = g_creatures.getCreatureByName(cName)))
continue;
cType->setSpawnTime(cNode->readType<int>("spawntime"));
Otc::Direction dir = Otc::North;
int16 dir_ = cNode->readType<int16>("direction");
if(dir_ >= Otc::East && dir_ <= Otc::West)
dir = (Otc::Direction)dir_;
cType->setDirection(dir);
centerPos.x += cNode->readType<int>("x");
centerPos.y += cNode->readType<int>("y");
centerPos.z = cNode->readType<int>("z");
__addCreature(centerPos, cType);
}
}
void Spawn::save(TiXmlElement*& node)
{
node = new TiXmlElement("spawn");
const Position& c = getCenterPos();
node->SetAttribute("centerx", c.x);
node->SetAttribute("centery", c.y);
node->SetAttribute("centerz", c.z);
node->SetAttribute("radius", getRadius());
TiXmlElement* creatureNode = nullptr;
for(const auto& pair : m_creatures) {
if(!(creatureNode = new TiXmlElement("monster")))
stdext::throw_exception("oom?");
const CreatureTypePtr& creature = pair.second;
creatureNode->SetAttribute("name", creature->getName());
creatureNode->SetAttribute("spawntime", creature->getSpawnTime());
creatureNode->SetAttribute("direction", creature->getDirection());
const Position& placePos = pair.first;
assert(placePos.isValid());
creatureNode->SetAttribute("x", placePos.x);
creatureNode->SetAttribute("y", placePos.y);
creatureNode->SetAttribute("z", placePos.z);
node->LinkEndChild(creatureNode);
}
}
void Spawn::addCreature(const Position& placePos, const CreatureTypePtr& cType)
{
const Position& centerPos = getCenterPos();
int m_radius = getRadius();
if(m_radius != -1 && placePos.x < centerPos.x - m_radius &&
placePos.x > centerPos.x + m_radius && placePos.y < centerPos.y - m_radius &&
placePos.y > centerPos.y + m_radius)
stdext::throw_exception(stdext::format("cannot place creature, out of range %s %s %d - increment radius.",
stdext::to_string(placePos), stdext::to_string(centerPos), m_radius));
return __addCreature(placePos, cType);
}
void Spawn::__addCreature(const Position& centerPos, const CreatureTypePtr& cType)
{
g_map.addThing(cType->cast(), centerPos, 4);
m_creatures.insert(std::make_pair(centerPos, cType));
}
void Spawn::removeCreature(const Position& pos)
{
auto iterator = m_creatures.find(pos);
if(iterator != m_creatures.end())
__removeCreature(iterator);
}
void Spawn::__removeCreature(std::unordered_map<Position, CreatureTypePtr, PositionHasher>::iterator iter)
{
assert(iter->first.isValid());
assert(g_map.removeThingByPos(iter->first, 4));
m_creatures.erase(iter);
}
CreaturePtr CreatureType::cast() CreaturePtr CreatureType::cast()
{ {
CreaturePtr ret(new Creature); CreaturePtr ret(new Creature);
ret->setName(getName());
std::string cName = getName();
stdext::ucwords(cName);
ret->setName(cName);
ret->setDirection(getDirection());
ret->setOutfit(getOutfit()); ret->setOutfit(getOutfit());
return ret; return ret;
} }
void Creatures::loadMonsters(const std::string& file) CreatureManager::CreatureManager()
{
m_nullCreature = CreatureTypePtr(new CreatureType);
}
void CreatureManager::clearSpawns()
{
for(auto it : m_spawns)
it->clear();
m_spawns.clear();
}
void CreatureManager::loadMonsters(const std::string& file)
{ {
TiXmlDocument doc; TiXmlDocument doc;
doc.Parse(g_resources.loadFile(file).c_str()); doc.Parse(g_resources.loadFile(file).c_str());
@ -60,12 +176,12 @@ void Creatures::loadMonsters(const std::string& file)
m_loaded = true; m_loaded = true;
} }
void Creatures::loadSingleCreature(const std::string& file) void CreatureManager::loadSingleCreature(const std::string& file)
{ {
loadCreatureBuffer(g_resources.loadFile(file)); loadCreatureBuffer(g_resources.loadFile(file));
} }
void Creatures::loadNpcs(const std::string& folder) void CreatureManager::loadNpcs(const std::string& folder)
{ {
boost::filesystem::path npcPath(boost::filesystem::current_path().generic_string() + folder); boost::filesystem::path npcPath(boost::filesystem::current_path().generic_string() + folder);
if(!boost::filesystem::exists(npcPath)) if(!boost::filesystem::exists(npcPath))
@ -83,7 +199,61 @@ void Creatures::loadNpcs(const std::string& folder)
} }
} }
void Creatures::loadCreatureBuffer(const std::string &buffer) void CreatureManager::loadSpawns(const std::string& fileName)
{
if(!isLoaded()) {
g_logger.fatal("creatures aren't loaded yet to load spawns.");
return;
}
if(m_spawnLoaded) {
g_logger.warning("attempt to reload spawns.");
return;
}
TiXmlDocument doc;
doc.Parse(g_resources.loadFile(fileName).c_str());
if(doc.Error())
stdext::throw_exception(stdext::format("cannot load spawns xml file '%s: '%s'", fileName, doc.ErrorDesc()));
TiXmlElement* root = doc.FirstChildElement();
if(!root || root->ValueStr() != "spawns")
stdext::throw_exception("malformed spawns file");
for(TiXmlElement* node = root->FirstChildElement(); node; node = node->NextSiblingElement()) {
if(node->ValueTStr() != "spawn")
stdext::throw_exception("invalid spawn node");
SpawnPtr spawn(new Spawn);
spawn->load(node);
m_spawns.push_back(spawn);
}
doc.Clear();
m_spawnLoaded = true;
}
void CreatureManager::saveSpawns(const std::string& fileName)
{
TiXmlDocument doc;
doc.SetTabSize(2);
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
doc.LinkEndChild(decl);
TiXmlElement* root = new TiXmlElement("spawns");
doc.LinkEndChild(root);
for(auto spawn : m_spawns) {
TiXmlElement* elem;
spawn->save(elem);
root->LinkEndChild(elem);
}
if(!doc.SaveFile(fileName))
stdext::throw_exception(stdext::format("failed to save spawns XML: %s", doc.ErrorDesc()));
}
void CreatureManager::loadCreatureBuffer(const std::string& buffer)
{ {
TiXmlDocument doc; TiXmlDocument doc;
doc.Parse(buffer.c_str()); doc.Parse(buffer.c_str());
@ -103,24 +273,24 @@ void Creatures::loadCreatureBuffer(const std::string &buffer)
if(attrib->ValueStr() != "look") if(attrib->ValueStr() != "look")
continue; continue;
if(m_loadCreatureBuffer(attrib, newType)) m_loadCreatureBuffer(attrib, newType);
break; break;
} }
doc.Clear(); doc.Clear();
} }
bool Creatures::m_loadCreatureBuffer(TiXmlElement* attrib, const CreatureTypePtr& m) void CreatureManager::m_loadCreatureBuffer(TiXmlElement* attrib, const CreatureTypePtr& m)
{ {
if(std::find(m_creatures.begin(), m_creatures.end(), m) != m_creatures.end()) if(std::find(m_creatures.begin(), m_creatures.end(), m) != m_creatures.end())
return true; return;
Outfit out; Outfit out;
out.setCategory(ThingCategoryCreature); out.setCategory(ThingCategoryCreature);
if(!attrib->Attribute("type").empty()) if(!attrib->Attribute("type").empty())
out.setId(attrib->readType<int32>("type")); out.setId(attrib->readType<int32>("type"));
else else
out.setAuxId(attrib->readType<int32>("typeex")); out.setId(attrib->readType<int32>("typeex"));
{ {
out.setHead(attrib->readType<int>(("head"))); out.setHead(attrib->readType<int>(("head")));
@ -133,25 +303,30 @@ bool Creatures::m_loadCreatureBuffer(TiXmlElement* attrib, const CreatureTypePtr
m->setOutfit(out); m->setOutfit(out);
m_creatures.push_back(m); m_creatures.push_back(m);
return true;
} }
CreatureTypePtr Creatures::getCreatureByName(std::string name) const CreatureTypePtr& CreatureManager::getCreatureByName(std::string name)
{ {
stdext::tolower(name); stdext::tolower(name);
stdext::trim(name); stdext::trim(name);
auto it = std::find_if(m_creatures.begin(), m_creatures.end(), auto it = std::find_if(m_creatures.begin(), m_creatures.end(),
[=] (const CreatureTypePtr& m) -> bool { return m->getName() == name; }); [=] (const CreatureTypePtr& m) -> bool { return m->getName() == name; });
return it != m_creatures.end() ? *it : nullptr; if(it != m_creatures.end())
return *it;
g_logger.warning(stdext::format("could not find creature with name: %s", name));
return m_nullCreature;
} }
CreatureTypePtr Creatures::getCreatureByLook(int look) const CreatureTypePtr& CreatureManager::getCreatureByLook(int look)
{ {
auto findFun = [=] (const CreatureTypePtr& c) -> bool auto findFun = [=] (const CreatureTypePtr& c) -> bool
{ {
const Outfit& o = c->getOutfit(); const Outfit& o = c->getOutfit();
return o.getId() == look || o.getAuxId() == look; return o.getId() == look;
}; };
auto it = std::find_if(m_creatures.begin(), m_creatures.end(), findFun); auto it = std::find_if(m_creatures.begin(), m_creatures.end(), findFun);
return it != m_creatures.end() ? *it : nullptr; if(it != m_creatures.end())
return *it;
g_logger.warning(stdext::format("could not find creature with looktype: %d", look));
return m_nullCreature;
} }

View File

@ -32,7 +32,43 @@ enum CreatureAttr : uint8
CreatureAttrPosition = 0, CreatureAttrPosition = 0,
CreatureAttrName = 1, CreatureAttrName = 1,
CreatureAttrOutfit = 2, CreatureAttrOutfit = 2,
CreatureAttrSpawnTime = 3 CreatureAttrSpawnTime = 3,
CreatureAttrDir = 4
};
enum SpawnAttr : uint8
{
SpawnAttrRadius = 0,
SpawnAttrCenter = 1,
SpawnAttrPos = 2
};
class Spawn : public LuaObject
{
public:
Spawn() { }
Spawn(int32 radius) { setRadius(radius); }
void setRadius(int32 r) { m_attribs.set(SpawnAttrRadius, r) ;}
int32 getRadius() { return m_attribs.get<int32>(SpawnAttrRadius); }
void setCenterPos(const Position& pos) { m_attribs.set(SpawnAttrCenter, pos); }
Position getCenterPos() { return m_attribs.get<Position>(SpawnAttrPos); }
void addCreature(const Position& placePos, const CreatureTypePtr& cType);
void removeCreature(const Position& pos);
void clear() { m_creatures.clear(); }
protected:
void load(TiXmlElement* node);
void save(TiXmlElement*& node);
void __addCreature(const Position& centerPos, const CreatureTypePtr& cType);
void __removeCreature(std::unordered_map<Position, CreatureTypePtr, PositionHasher>::iterator iter);
private:
stdext::dynamic_storage<uint8> m_attribs;
std::unordered_map<Position, CreatureTypePtr, PositionHasher> m_creatures;
friend class CreatureManager;
}; };
class CreatureType : public LuaObject class CreatureType : public LuaObject
@ -41,46 +77,57 @@ public:
CreatureType() { } CreatureType() { }
CreatureType(const std::string& name) { setName(name); } CreatureType(const std::string& name) { setName(name); }
void setSpawnTime(int spawnTime) { m_attribs.set(CreatureAttrSpawnTime, spawnTime); } void setSpawnTime(int32 spawnTime) { m_attribs.set(CreatureAttrSpawnTime, spawnTime); }
int getSpawnTime() { return m_attribs.get<int>(CreatureAttrSpawnTime); } int32 getSpawnTime() { return m_attribs.get<int32>(CreatureAttrSpawnTime); }
void setName(const std::string& name) { m_attribs.set(CreatureAttrName, name); } void setName(const std::string& name) { m_attribs.set(CreatureAttrName, name); dump << "set"<<getName(); }
std::string getName() { return m_attribs.get<std::string>(CreatureAttrName); } std::string getName() { return m_attribs.get<std::string>(CreatureAttrName); }
void setOutfit(const Outfit& o) { m_attribs.set(CreatureAttrOutfit, o); } void setOutfit(const Outfit& o) { m_attribs.set(CreatureAttrOutfit, o); }
Outfit getOutfit() { return m_attribs.get<Outfit>(CreatureAttrOutfit); } Outfit getOutfit() { return m_attribs.get<Outfit>(CreatureAttrOutfit); }
void setDirection(Otc::Direction dir) { m_attribs.set(CreatureAttrDir, dir); }
Otc::Direction getDirection() { return m_attribs.get<Otc::Direction>(CreatureAttrDir); }
CreaturePtr cast(); CreaturePtr cast();
private: private:
stdext::dynamic_storage<uint8> m_attribs; stdext::dynamic_storage<uint8> m_attribs;
}; };
class Creatures class CreatureManager
{ {
public: public:
CreatureManager();
void clear() { m_creatures.clear(); } void clear() { m_creatures.clear(); }
void clearSpawns();
void loadMonsters(const std::string& file); void loadMonsters(const std::string& file);
void loadSingleCreature(const std::string& file); void loadSingleCreature(const std::string& file);
void loadNpcs(const std::string& folder); void loadNpcs(const std::string& folder);
void loadCreatureBuffer(const std::string& buffer); void loadCreatureBuffer(const std::string& buffer);
void loadSpawns(const std::string& fileName);
void saveSpawns(const std::string& fileName);
CreatureTypePtr getCreatureByName(std::string name); const CreatureTypePtr& getCreatureByName(std::string name);
CreatureTypePtr getCreatureByLook(int look); const CreatureTypePtr& getCreatureByLook(int look);
bool isLoaded() const { return m_loaded; } bool isLoaded() { return m_loaded; }
bool isSpawnLoaded() { return m_spawnLoaded; }
const std::vector<CreatureTypePtr>& getCreatures() { return m_creatures; } const std::vector<CreatureTypePtr>& getCreatures() { return m_creatures; }
const std::vector<SpawnPtr>& getSpawns() { return m_spawns; }
protected: protected:
bool m_loadCreatureBuffer(TiXmlElement* elem, const CreatureTypePtr& m); void m_loadCreatureBuffer(TiXmlElement* elem, const CreatureTypePtr& m);
private: private:
std::vector<CreatureTypePtr> m_creatures; std::vector<CreatureTypePtr> m_creatures;
stdext::boolean<false> m_loaded; std::vector<SpawnPtr> m_spawns;
stdext::boolean<false> m_loaded, m_spawnLoaded;
CreatureTypePtr m_nullCreature;
}; };
extern Creatures g_creatures; extern CreatureManager g_creatures;
#endif #endif

View File

@ -49,6 +49,7 @@ class ItemType;
class House; class House;
class Town; class Town;
class CreatureType; class CreatureType;
class Spawn;
typedef stdext::shared_object_ptr<MapView> MapViewPtr; typedef stdext::shared_object_ptr<MapView> MapViewPtr;
typedef stdext::shared_object_ptr<Tile> TilePtr; typedef stdext::shared_object_ptr<Tile> TilePtr;
@ -69,6 +70,7 @@ typedef stdext::shared_object_ptr<ItemType> ItemTypePtr;
typedef stdext::shared_object_ptr<House> HousePtr; typedef stdext::shared_object_ptr<House> HousePtr;
typedef stdext::shared_object_ptr<Town> TownPtr; typedef stdext::shared_object_ptr<Town> TownPtr;
typedef stdext::shared_object_ptr<CreatureType> CreatureTypePtr; typedef stdext::shared_object_ptr<CreatureType> CreatureTypePtr;
typedef stdext::shared_object_ptr<Spawn> SpawnPtr;
typedef std::vector<ThingPtr> ThingList; typedef std::vector<ThingPtr> ThingList;
typedef std::vector<ThingTypePtr> ThingTypeList; typedef std::vector<ThingTypePtr> ThingTypeList;

View File

@ -24,8 +24,16 @@
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
HouseManager g_houses;
House::House()
{
m_nullTile = TilePtr(new Tile(Position()));
}
House::House(uint32 hId, const std::string &name, const Position &pos) House::House(uint32 hId, const std::string &name, const Position &pos)
{ {
m_nullTile = TilePtr(new Tile(Position()));
setId(hId); setId(hId);
setName(name); setName(name);
if(pos.isValid()) if(pos.isValid())
@ -38,39 +46,73 @@ void House::setTile(const TilePtr& tile)
m_tiles.insert(std::make_pair(tile->getPosition(), tile)); m_tiles.insert(std::make_pair(tile->getPosition(), tile));
} }
const TilePtr& House::getTile(const Position& position)
{
TileMap::const_iterator iter = m_tiles.find(position);
if(iter != m_tiles.end())
return iter->second;
return m_nullTile;
}
void House::load(const TiXmlElement *elem) void House::load(const TiXmlElement *elem)
{ {
std::string name = elem->Attribute("name"); std::string name = elem->Attribute("name");
if(name.empty()) if(name.empty())
name = stdext::format("Unnamed house #%lu", getId()); name = stdext::format("Unnamed house #%lu", getId());
setName(name);
setRent(elem->readType<uint32>("rent")); setRent(elem->readType<uint32>("rent"));
setSize(elem->readType<uint32>("size")); setSize(elem->readType<uint32>("size"));
setTownId(elem->readType<uint32>("townid")); setTownId(elem->readType<uint32>("townid"));
m_isGuildHall = elem->readType<bool>("rent"); m_isGuildHall = elem->readType<bool>("guildhall");
setEntry(elem->readPos("entry")); setEntry(elem->readPos("entry"));
} }
void Houses::addHouse(const HousePtr& house) void House::save(TiXmlElement*& elem)
{
#define s(x) stdext::to_string((x)) // ugly macro again... to save "typing".
elem = new TiXmlElement("house");
elem->SetAttribute("name", getName());
elem->SetAttribute("houseid", s(getId()));
Position entry = getEntry();
elem->SetAttribute("entryx", s(entry.x));
elem->SetAttribute("entryy", s(entry.y));
elem->SetAttribute("entryz", s(entry.z));
elem->SetAttribute("rent", s(getRent()));
elem->SetAttribute("townid", s(getTownId()));
elem->SetAttribute("size", s(getSize()));
elem->SetAttribute("guildhall", s(m_isGuildHall));
}
HouseManager::HouseManager()
{
m_nullHouse = HousePtr(new House);
}
void HouseManager::addHouse(const HousePtr& house)
{ {
if(findHouse(house->getId()) == m_houses.end()) if(findHouse(house->getId()) == m_houses.end())
m_houses.push_back(house); m_houses.push_back(house);
} }
void Houses::removeHouse(uint32 houseId) void HouseManager::removeHouse(uint32 houseId)
{ {
auto it = findHouse(houseId); auto it = findHouse(houseId);
if(it != m_houses.end()) if(it != m_houses.end())
m_houses.erase(it); m_houses.erase(it);
} }
HousePtr Houses::getHouse(uint32 houseId) const HousePtr& HouseManager::getHouse(uint32 houseId)
{ {
auto it = findHouse(houseId); auto it = std::find_if(m_houses.begin(), m_houses.end(),
return it != m_houses.end() ? *it : nullptr; [=] (const HousePtr& house) -> bool { return house->getId() == houseId; });
return it != m_houses.end() ? *it : m_nullHouse;
} }
void Houses::load(const std::string& fileName) void HouseManager::load(const std::string& fileName)
{ {
TiXmlDocument doc; TiXmlDocument doc;
doc.Parse(g_resources.loadFile(fileName).c_str()); doc.Parse(g_resources.loadFile(fileName).c_str());
@ -94,9 +136,29 @@ void Houses::load(const std::string& fileName)
} }
} }
HouseList::iterator Houses::findHouse(uint32 houseId) void HouseManager::save(const std::string& fileName)
{
TiXmlDocument doc;
doc.SetTabSize(2);
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
doc.LinkEndChild(decl);
TiXmlElement* root = new TiXmlElement("houses");
doc.LinkEndChild(root);
for(auto house : m_houses) {
TiXmlElement *elem;
house->save(elem);
root->LinkEndChild(elem);
}
if(!doc.SaveFile(fileName))
stdext::throw_exception(stdext::format("failed to save houses XML: %s", doc.ErrorDesc()));
}
HouseList::iterator HouseManager::findHouse(uint32 houseId)
{ {
return std::find_if(m_houses.begin(), m_houses.end(), return std::find_if(m_houses.begin(), m_houses.end(),
[=] (const HousePtr& house) -> bool { return house->getId() == houseId; }); [=] (const HousePtr& house) -> bool { return house->getId() == houseId; });
} }

View File

@ -41,50 +41,65 @@ enum HouseAttr : uint8
class House : public LuaObject class House : public LuaObject
{ {
public: public:
House() { } House();
House(uint32 hId, const std::string& name = "", const Position& pos=Position()); House(uint32 hId, const std::string& name = "", const Position& pos=Position());
~House() { m_tiles.clear(); } ~House() { m_tiles.clear(); m_nullTile = nullptr; }
void setTile(const TilePtr& tile); void setTile(const TilePtr& tile);
void setId(uint32 hId) { m_attribs.set(HouseAttrId, hId); } const TilePtr& getTile(const Position& pos);
void setName(const std::string& name) { m_attribs.set(HouseAttrName, name); }
void setTownId(uint32 tid) { m_attribs.set(HouseAttrTown, tid); }
void setSize(uint32 s) { m_attribs.set(HouseAttrSize, s); }
void setRent(uint32 r) { m_attribs.set(HouseAttrRent, r); }
void setEntry(const Position& p) { m_attribs.set(HouseAttrEntry, p); }
uint32 getId() { return m_attribs.get<uint32>(HouseAttrId); } void setName(const std::string& name) { m_attribs.set(HouseAttrName, name); }
std::string getName() { return m_attribs.get<std::string>(HouseAttrName); } std::string getName() { return m_attribs.get<std::string>(HouseAttrName); }
uint32 getRent() { return m_attribs.get<uint32>(HouseAttrRent); }
void setId(uint32 hId) { m_attribs.set(HouseAttrId, hId); }
uint32 getId() { return m_attribs.get<uint32>(HouseAttrId); }
void setTownId(uint32 tid) { m_attribs.set(HouseAttrTown, tid); }
uint32 getTownId() { return m_attribs.get<uint32>(HouseAttrTown); }
void setSize(uint32 s) { m_attribs.set(HouseAttrSize, s); }
uint32 getSize() { return m_attribs.get<uint32>(HouseAttrSize); } uint32 getSize() { return m_attribs.get<uint32>(HouseAttrSize); }
void setRent(uint32 r) { m_attribs.set(HouseAttrRent, r); }
uint32 getRent() { return m_attribs.get<uint32>(HouseAttrRent); }
void setEntry(const Position& p) { m_attribs.set(HouseAttrEntry, p); }
Position getEntry() { return m_attribs.get<Position>(HouseAttrEntry); }
protected: protected:
void load(const TiXmlElement* elem); void load(const TiXmlElement* elem);
void save(TiXmlElement &elem) { } // TODO void save(TiXmlElement*& elem);
private: private:
stdext::packed_storage<uint8> m_attribs; stdext::packed_storage<uint8> m_attribs;
TileMap m_tiles; TileMap m_tiles;
TilePtr m_nullTile;
stdext::boolean<false> m_isGuildHall; stdext::boolean<false> m_isGuildHall;
friend class Houses; friend class HouseManager;
}; };
class Houses { class HouseManager {
public: public:
void clear() { m_houses.clear(); } HouseManager();
void addHouse(const HousePtr& house); void addHouse(const HousePtr& house);
void removeHouse(uint32 houseId); void removeHouse(uint32 houseId);
void load(const std::string& fileName); HouseList getHouseList() { return m_houses; }
const HousePtr& getHouse(uint32 houseId);
void clear() { m_houses.clear(); m_nullHouse = nullptr; }
HouseList houseList() const { return m_houses; } void load(const std::string& fileName);
HousePtr getHouse(uint32 houseId); void save(const std::string& fileName);
private: private:
HouseList m_houses; HouseList m_houses;
HousePtr m_nullHouse;
protected: protected:
HouseList::iterator findHouse(uint32 houseId); HouseList::iterator findHouse(uint32 houseId);
}; };
extern HouseManager g_houses;
#endif #endif

View File

@ -64,18 +64,20 @@ void OTClient::registerLuaFunctions()
g_lua.bindSingletonFunction("g_things", "findThingTypeByAttr", &ThingTypeManager::findThingTypeByAttr, &g_things); g_lua.bindSingletonFunction("g_things", "findThingTypeByAttr", &ThingTypeManager::findThingTypeByAttr, &g_things);
g_lua.bindSingletonFunction("g_things", "findItemTypeByCategory", &ThingTypeManager::findItemTypeByCategory, &g_things); g_lua.bindSingletonFunction("g_things", "findItemTypeByCategory", &ThingTypeManager::findItemTypeByCategory, &g_things);
#if 0
g_lua.registerSingletonClass("g_houses"); g_lua.registerSingletonClass("g_houses");
g_lua.bindSingletonFunction("g_houses", "load", &Houses::load, &g_houses); g_lua.bindSingletonFunction("g_houses", "clear", &HouseManager::clear, &g_houses);
g_lua.bindSingletonFunction("g_houses", "getHouse", &Houses::getHouse, &g_houses); g_lua.bindSingletonFunction("g_houses", "load", &HouseManager::load, &g_houses);
g_lua.bindSingletonFunction("g_houses", "addHouse", &Houses::addHouse, &g_houses); g_lua.bindSingletonFunction("g_houses", "save", &HouseManager::save, &g_houses);
g_lua.bindSingletonFunction("g_houses", "removeHouse", &Houses::removeHouse, &g_houses); g_lua.bindSingletonFunction("g_houses", "getHouse", &HouseManager::getHouse, &g_houses);
g_lua.bindSingletonFunction("g_houses", "addHouse", &HouseManager::addHouse, &g_houses);
g_lua.bindSingletonFunction("g_houses", "removeHouse", &HouseManager::removeHouse, &g_houses);
g_lua.bindSingletonFunction("g_houses", "getHouseList", &HouseManager::getHouseList, &g_houses);
g_lua.registerSingletonClass("g_towns"); g_lua.registerSingletonClass("g_towns");
g_lua.bindSingletonFunction("g_towns", "getTown", &Towns::getTown, &g_towns); g_lua.bindSingletonFunction("g_towns", "getTown", &TownManager::getTown, &g_towns);
g_lua.bindSingletonFunction("g_towns", "addTown", &Towns::addTown, &g_towns); g_lua.bindSingletonFunction("g_towns", "addTown", &TownManager::addTown, &g_towns);
g_lua.bindSingletonFunction("g_towns", "removeTown", &Towns::removeTown, &g_towns); g_lua.bindSingletonFunction("g_towns", "removeTown", &TownManager::removeTown, &g_towns);
#endif g_lua.bindSingletonFunction("g_towns", "getTowns", &TownManager::getTowns, &g_towns);
g_lua.registerSingletonClass("g_sprites"); g_lua.registerSingletonClass("g_sprites");
g_lua.bindSingletonFunction("g_sprites", "loadSpr", &SpriteManager::loadSpr, &g_sprites); g_lua.bindSingletonFunction("g_sprites", "loadSpr", &SpriteManager::loadSpr, &g_sprites);
@ -104,19 +106,25 @@ void OTClient::registerLuaFunctions()
g_lua.bindSingletonFunction("g_map", "findPath", &Map::findPath, &g_map); g_lua.bindSingletonFunction("g_map", "findPath", &Map::findPath, &g_map);
g_lua.bindSingletonFunction("g_map", "loadOtbm", &Map::loadOtbm, &g_map); g_lua.bindSingletonFunction("g_map", "loadOtbm", &Map::loadOtbm, &g_map);
g_lua.bindSingletonFunction("g_map", "saveOtbm", &Map::saveOtbm, &g_map); g_lua.bindSingletonFunction("g_map", "saveOtbm", &Map::saveOtbm, &g_map);
g_lua.bindSingletonFunction("g_map", "loadSpawns", &Map::loadSpawns, &g_map);
g_lua.bindSingletonFunction("g_map", "loadOtcm", &Map::loadOtcm, &g_map); g_lua.bindSingletonFunction("g_map", "loadOtcm", &Map::loadOtcm, &g_map);
g_lua.bindSingletonFunction("g_map", "saveOtcm", &Map::saveOtcm, &g_map); g_lua.bindSingletonFunction("g_map", "saveOtcm", &Map::saveOtcm, &g_map);
g_lua.bindSingletonFunction("g_map", "getTown", &Map::getTown, &g_map); g_lua.bindSingletonFunction("g_map", "getHouseFile", &Map::getHouseFile, &g_map);
g_lua.bindSingletonFunction("g_map", "getHouse", &Map::getHouse, &g_map); g_lua.bindSingletonFunction("g_map", "getSpawnFile", &Map::getSpawnFile, &g_map);
g_lua.registerSingletonClass("g_creatures"); g_lua.registerSingletonClass("g_creatures");
g_lua.bindSingletonFunction("g_creatures", "getCreatures", &Creatures::getCreatures, &g_creatures); g_lua.bindSingletonFunction("g_creatures", "getCreatures", &CreatureManager::getCreatures, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "getCreatureByName", &Creatures::getCreatureByName, &g_creatures); g_lua.bindSingletonFunction("g_creatures", "getSpawns", &CreatureManager::getSpawns, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "getCreatureByLook", &Creatures::getCreatureByLook, &g_creatures); g_lua.bindSingletonFunction("g_creatures", "getCreatureByName", &CreatureManager::getCreatureByName, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "loadMonsters", &Creatures::loadMonsters, &g_creatures); g_lua.bindSingletonFunction("g_creatures", "getCreatureByLook", &CreatureManager::getCreatureByLook, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "loadNpcs", &Creatures::loadNpcs, &g_creatures); g_lua.bindSingletonFunction("g_creatures", "loadMonsters", &CreatureManager::loadMonsters, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "loadSingleCreature", &Creatures::loadSingleCreature, &g_creatures); g_lua.bindSingletonFunction("g_creatures", "loadNpcs", &CreatureManager::loadNpcs, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "loadSingleCreature", &CreatureManager::loadSingleCreature, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "loadSpawns", &CreatureManager::loadSpawns, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "saveSpawns", &CreatureManager::saveSpawns, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "isLoaded", &CreatureManager::isLoaded, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "isSpawnLoaded", &CreatureManager::isSpawnLoaded, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "clear", &CreatureManager::clear, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "clearSpawns", &CreatureManager::clearSpawns, &g_creatures);
g_lua.registerSingletonClass("g_game"); g_lua.registerSingletonClass("g_game");
g_lua.bindSingletonFunction("g_game", "loginWorld", &Game::loginWorld, &g_game); g_lua.bindSingletonFunction("g_game", "loginWorld", &Game::loginWorld, &g_game);
@ -294,9 +302,26 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassStaticFunction<House>("create", []{ return HousePtr(new House); }); g_lua.bindClassStaticFunction<House>("create", []{ return HousePtr(new House); });
g_lua.bindClassMemberFunction<House>("setId", &House::setId); g_lua.bindClassMemberFunction<House>("setId", &House::setId);
g_lua.bindClassMemberFunction<House>("setName", &House::setName); g_lua.bindClassMemberFunction<House>("setName", &House::setName);
g_lua.bindClassMemberFunction<House>("getName", &House::getName);
g_lua.bindClassMemberFunction<House>("setTownId", &House::setTownId);
g_lua.bindClassMemberFunction<House>("getTownId", &House::getTownId);
g_lua.bindClassMemberFunction<House>("setTile", &House::setTile); g_lua.bindClassMemberFunction<House>("setTile", &House::setTile);
g_lua.bindClassMemberFunction<House>("addTile", &House::setTile); // alternative method g_lua.bindClassMemberFunction<House>("getTile", &House::getTile);
g_lua.bindClassMemberFunction<House>("setEntry", &House::setEntry); g_lua.bindClassMemberFunction<House>("setEntry", &House::setEntry);
g_lua.bindClassMemberFunction<House>("getEntry", &House::getEntry);
g_lua.bindClassMemberFunction<House>("setSize", &House::setSize);
g_lua.bindClassMemberFunction<House>("getSize", &House::getSize);
g_lua.bindClassMemberFunction<House>("setRent", &House::setRent);
g_lua.bindClassMemberFunction<House>("getRent", &House::getRent);
g_lua.registerClass<Spawn>();
g_lua.bindClassStaticFunction<Spawn>("create", []{ return SpawnPtr(new Spawn); });
g_lua.bindClassMemberFunction<Spawn>("setRadius", &Spawn::setRadius);
g_lua.bindClassMemberFunction<Spawn>("getRadius", &Spawn::getRadius);
g_lua.bindClassMemberFunction<Spawn>("setCenterPos", &Spawn::setCenterPos);
g_lua.bindClassMemberFunction<Spawn>("getCenterPos", &Spawn::getCenterPos);
g_lua.bindClassMemberFunction<Spawn>("addCreature", &Spawn::addCreature);
g_lua.bindClassMemberFunction<Spawn>("removeCreature", &Spawn::removeCreature);
g_lua.registerClass<Town>(); g_lua.registerClass<Town>();
g_lua.bindClassStaticFunction<Town>("create", []{ return TownPtr(new Town); }); g_lua.bindClassStaticFunction<Town>("create", []{ return TownPtr(new Town); });

View File

@ -67,9 +67,9 @@ void Map::clean()
m_waypoints.clear(); m_waypoints.clear();
m_towns.clear(); g_towns.clear();
m_houses.clear(); g_houses.clear();
g_creatures.clear(); g_creatures.clearSpawns();
m_tilesRect = Rect(65534, 65534, 0, 0); m_tilesRect = Rect(65534, 65534, 0, 0);
} }

View File

@ -135,9 +135,6 @@ public:
void loadOtbm(const std::string& fileName, const UIWidgetPtr& pbar = 0); void loadOtbm(const std::string& fileName, const UIWidgetPtr& pbar = 0);
void saveOtbm(const std::string& fileName, const UIWidgetPtr& pbar = 0); void saveOtbm(const std::string& fileName, const UIWidgetPtr& pbar = 0);
void loadSpawns(const std::string& fileName);
void saveSpawns(const std::string&);
// otbm attributes (description, size, etc.) // otbm attributes (description, size, etc.)
void setHouseFile(const std::string& file) { m_attribs.set(OTBM_ATTR_HOUSE_FILE, file); } void setHouseFile(const std::string& file) { m_attribs.set(OTBM_ATTR_HOUSE_FILE, file); }
void setSpawnFile(const std::string& file) { m_attribs.set(OTBM_ATTR_SPAWN_FILE, file); } void setSpawnFile(const std::string& file) { m_attribs.set(OTBM_ATTR_SPAWN_FILE, file); }
@ -176,11 +173,6 @@ public:
std::vector<CreaturePtr> getSpectatorsInRange(const Position& centerPos, bool multiFloor, int xRange, int yRange); std::vector<CreaturePtr> getSpectatorsInRange(const Position& centerPos, bool multiFloor, int xRange, int yRange);
std::vector<CreaturePtr> getSpectatorsInRangeEx(const Position& centerPos, bool multiFloor, int minXRange, int maxXRange, int minYRange, int maxYRange); std::vector<CreaturePtr> getSpectatorsInRangeEx(const Position& centerPos, bool multiFloor, int minXRange, int maxXRange, int minYRange, int maxYRange);
// town/house/monster related
TownPtr getTown(uint32 tid) { return m_towns.getTown(tid); }
HousePtr getHouse(uint32 hid) { return m_houses.getHouse(hid); }
CreatureTypePtr getCreature(const std::string &name) { return g_creatures.getCreatureByName(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);
@ -205,6 +197,7 @@ private:
std::unordered_map<uint, TileBlock> m_tileBlocks[Otc::MAX_Z+1]; std::unordered_map<uint, TileBlock> m_tileBlocks[Otc::MAX_Z+1];
std::unordered_map<uint32, CreaturePtr> m_knownCreatures; std::unordered_map<uint32, CreaturePtr> m_knownCreatures;
std::unordered_map<Position, CreatureTypePtr, PositionHasher> m_creatureTypes;
std::array<std::vector<MissilePtr>, Otc::MAX_Z+1> m_floorMissiles; std::array<std::vector<MissilePtr>, Otc::MAX_Z+1> m_floorMissiles;
std::vector<AnimatedTextPtr> m_animatedTexts; std::vector<AnimatedTextPtr> m_animatedTexts;
std::vector<StaticTextPtr> m_staticTexts; std::vector<StaticTextPtr> m_staticTexts;
@ -216,8 +209,6 @@ private:
Rect m_tilesRect; Rect m_tilesRect;
stdext::packed_storage<uint8> m_attribs; stdext::packed_storage<uint8> m_attribs;
Houses m_houses;
Towns m_towns;
static TilePtr m_nulltile; static TilePtr m_nulltile;
}; };

View File

@ -109,9 +109,9 @@ void Map::loadOtbm(const std::string& fileName, const UIWidgetPtr& pbar)
if(type == OTBM_HOUSETILE) { if(type == OTBM_HOUSETILE) {
uint32 hId = nodeTile->getU32(); uint32 hId = nodeTile->getU32();
TilePtr tile = getOrCreateTile(pos); TilePtr tile = getOrCreateTile(pos);
if(!(house = m_houses.getHouse(hId))) { if(!(house = g_houses.getHouse(hId))) {
house = HousePtr(new House(hId)); house = HousePtr(new House(hId));
m_houses.addHouse(house); g_houses.addHouse(house);
} }
house->setTile(tile); house->setTile(tile);
} }
@ -189,9 +189,9 @@ void Map::loadOtbm(const std::string& fileName, const UIWidgetPtr& pbar)
uint32 townId = nodeTown->getU32(); uint32 townId = nodeTown->getU32();
std::string townName = nodeTown->getString(); std::string townName = nodeTown->getString();
Position townCoords = nodeTown->getPosition(); Position townCoords = nodeTown->getPosition();
if(!(town = m_towns.getTown(townId))) { if(!(town = g_towns.getTown(townId))) {
town = TownPtr(new Town(townId, townName, townCoords)); town = TownPtr(new Town(townId, townName, townCoords));
m_towns.addTown(town); g_towns.addTown(town);
} }
} }
} else if(mapDataType == OTBM_WAYPOINTS && headerVersion > 1) { } else if(mapDataType == OTBM_WAYPOINTS && headerVersion > 1) {
@ -208,7 +208,6 @@ void Map::loadOtbm(const std::string& fileName, const UIWidgetPtr& pbar)
stdext::throw_exception(stdext::format("Unknown map data node %d", (int)mapDataType)); stdext::throw_exception(stdext::format("Unknown map data node %d", (int)mapDataType));
} }
g_logger.debug("OTBM read successfully.");
fin->close(); fin->close();
} }
@ -358,7 +357,7 @@ void Map::saveOtbm(const std::string &fileName, const UIWidgetPtr&/* pbar*/)
root->endNode(); // OTBM_TILE_AREA root->endNode(); // OTBM_TILE_AREA
root->startNode(OTBM_TOWNS); root->startNode(OTBM_TOWNS);
for(const TownPtr& town : m_towns.getTowns()) { for(const TownPtr& town : g_towns.getTowns()) {
root->addU32(town->getId()); root->addU32(town->getId());
root->addString(town->getName()); root->addString(town->getName());
root->addPos(town->getPos()); root->addPos(town->getPos());
@ -382,70 +381,6 @@ void Map::saveOtbm(const std::string &fileName, const UIWidgetPtr&/* pbar*/)
fin->close(); fin->close();
} }
void Map::loadSpawns(const std::string &fileName)
{
if(!g_creatures.isLoaded()) {
g_logger.error("cannot load spawns; monsters/nps aren't loaded.");
return;
}
TiXmlDocument doc;
doc.Parse(g_resources.loadFile(fileName).c_str());
if(doc.Error())
stdext::throw_exception(stdext::format("cannot load spawns xml file '%s: '%s'", fileName, doc.ErrorDesc()));
TiXmlElement* root = doc.FirstChildElement();
if(!root || root->ValueStr() != "spawns")
stdext::throw_exception("malformed spawns file");
CreatureTypePtr cType(nullptr);
for(TiXmlElement* node = root->FirstChildElement(); node; node = node->NextSiblingElement()) {
if(node->ValueTStr() != "spawn")
stdext::throw_exception("invalid spawn node");
Position centerPos = node->readPos("center");
for(TiXmlElement* cNode = node->FirstChildElement(); cNode; cNode = cNode->NextSiblingElement()) {
if(cNode->ValueStr() != "monster" && cNode->ValueStr() != "npc")
stdext::throw_exception(stdext::format("invalid spawn-subnode %s", cNode->ValueStr()));
std::string cName = cNode->Attribute("name");
stdext::tolower(cName);
stdext::trim(cName);
if (!(cType = g_creatures.getCreatureByName(cName)))
continue;
cType->setSpawnTime(cNode->readType<int>("spawntime"));
CreaturePtr creature(new Creature);
creature->setOutfit(cType->getOutfit());
stdext::ucwords(cName);
creature->setName(cName);
centerPos.x += cNode->readType<int>("x");
centerPos.y += cNode->readType<int>("y");
centerPos.z = cNode->readType<int>("z");
addThing(creature, centerPos, 4);
}
}
}
void Map::saveSpawns(const std::string& fileName)
{
#if 0
TiXmlDocument doc;
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
doc.LinkEndChild(decl);
TiXmlElement* root = new TiXmlElement("spawns");
doc.LinkEndChild(root);
TiXmlElement* spawn = NULL;
#endif
}
bool Map::loadOtcm(const std::string& fileName) bool Map::loadOtcm(const std::string& fileName)
{ {
try { try {

View File

@ -22,6 +22,8 @@
#include "towns.h" #include "towns.h"
TownManager g_towns;
Town::Town(uint32 tid, const std::string& name, const Position& pos) Town::Town(uint32 tid, const std::string& name, const Position& pos)
: m_id(tid), m_name(name) : m_id(tid), m_name(name)
{ {
@ -29,29 +31,34 @@ Town::Town(uint32 tid, const std::string& name, const Position& pos)
m_pos = pos; m_pos = pos;
} }
TownManager::TownManager()
{
m_nullTown = TownPtr(new Town);
}
void Towns::addTown(const TownPtr &town) void TownManager::addTown(const TownPtr &town)
{ {
if(findTown(town->getId()) == m_towns.end()) if(findTown(town->getId()) == m_towns.end())
m_towns.push_back(town); m_towns.push_back(town);
} }
void Towns::removeTown(uint32 townId) void TownManager::removeTown(uint32 townId)
{ {
auto it = findTown(townId); auto it = findTown(townId);
if(it != m_towns.end()) if(it != m_towns.end())
m_towns.erase(it); m_towns.erase(it);
} }
TownPtr Towns::getTown(uint32 townId) const TownPtr& TownManager::getTown(uint32 townId)
{ {
auto it = findTown(townId); auto it = std::find_if(m_towns.begin(), m_towns.end(),
[=] (const TownPtr& town) -> bool { return town->getId() == townId; });
if(it != m_towns.end()) if(it != m_towns.end())
return *it; return *it;
return nullptr; return m_nullTown;
} }
TownList::iterator Towns::findTown(uint32 townId) TownList::iterator TownManager::findTown(uint32 townId)
{ {
return std::find_if(m_towns.begin(), m_towns.end(), return std::find_if(m_towns.begin(), m_towns.end(),
[=] (const TownPtr& town) -> bool { return town->getId() == townId; }); [=] (const TownPtr& town) -> bool { return town->getId() == townId; });

View File

@ -26,7 +26,6 @@
#include "declarations.h" #include "declarations.h"
#include <framework/luaengine/luaobject.h> #include <framework/luaengine/luaobject.h>
class Town : public LuaObject class Town : public LuaObject
{ {
public: public:
@ -47,22 +46,26 @@ private:
Position m_pos; // temple pos Position m_pos; // temple pos
}; };
class Towns class TownManager
{ {
public: public:
void addTown(const TownPtr &town); TownManager();
void addTown(const TownPtr& town);
void removeTown(uint32 townId); void removeTown(uint32 townId);
const TownPtr& getTown(uint32 townId);
TownPtr getTown(uint32 townId);
TownList getTowns() { return m_towns; } TownList getTowns() { return m_towns; }
void clear() { m_towns.clear(); m_nullTown = nullptr; }
void clear() { m_towns.clear(); }
private: private:
TownList m_towns; TownList m_towns;
TownPtr m_nullTown;
protected: protected:
TownList::iterator findTown(uint32 townId); TownList::iterator findTown(uint32 townId);
}; };
extern TownManager g_towns;
#endif #endif

View File

@ -30,6 +30,7 @@
class UICreature : public UIWidget class UICreature : public UIWidget
{ {
public: public:
UICreature() { m_color = Color::white; }
void drawSelf(Fw::DrawPane drawPane); void drawSelf(Fw::DrawPane drawPane);
void setCreature(const CreaturePtr& creature) { m_creature = creature; } void setCreature(const CreaturePtr& creature) { m_creature = creature; }