Fixes to creatures

This commit is contained in:
otfallen 2012-09-20 23:23:10 +00:00
parent a40594752d
commit fe3a751ffa
3 changed files with 66 additions and 37 deletions

View File

@ -30,6 +30,17 @@
CreatureManager g_creatures; CreatureManager g_creatures;
static bool isInZone(const Position& pos/* placePos*/,
const Position& centerPos,
int radius)
{
if(radius == -1)
return true;
return ((pos.x >= centerPos.x - radius) && (pos.x <= centerPos.x + radius) &&
(pos.y >= centerPos.y - radius) && (pos.y <= centerPos.y + radius)
);
}
void Spawn::load(TiXmlElement* node) void Spawn::load(TiXmlElement* node)
{ {
Position centerPos = node->readPos("center"); Position centerPos = node->readPos("center");
@ -58,7 +69,7 @@ void Spawn::load(TiXmlElement* node)
centerPos.x += cNode->readType<int>("x"); centerPos.x += cNode->readType<int>("x");
centerPos.y += cNode->readType<int>("y"); centerPos.y += cNode->readType<int>("y");
centerPos.z = cNode->readType<int>("z"); centerPos.z = cNode->readType<int>("z");
__addCreature(centerPos, cType); addCreature(centerPos, cType);
} }
} }
@ -74,6 +85,7 @@ void Spawn::save(TiXmlElement*& node)
node->SetAttribute("radius", getRadius()); node->SetAttribute("radius", getRadius());
TiXmlElement* creatureNode = nullptr; TiXmlElement* creatureNode = nullptr;
for(const auto& pair : m_creatures) { for(const auto& pair : m_creatures) {
if(!(creatureNode = new TiXmlElement("monster"))) if(!(creatureNode = new TiXmlElement("monster")))
stdext::throw_exception("oom?"); stdext::throw_exception("oom?");
@ -99,33 +111,23 @@ void Spawn::addCreature(const Position& placePos, const CreatureTypePtr& cType)
{ {
const Position& centerPos = getCenterPos(); const Position& centerPos = getCenterPos();
int m_radius = getRadius(); int m_radius = getRadius();
if(m_radius != -1 && placePos.x < centerPos.x - m_radius && if(!isInZone(placePos, centerPos, m_radius))
placePos.x > centerPos.x + m_radius && placePos.y < centerPos.y - m_radius && stdext::throw_exception(stdext::format("cannot place creature at %s %s %d (increment radius)",
placePos.y > centerPos.y + m_radius) stdext::to_string(placePos), stdext::to_string(centerPos),
stdext::throw_exception(stdext::format("cannot place creature, out of range %s %s %d - increment radius.", m_radius
stdext::to_string(placePos), stdext::to_string(centerPos), m_radius)); ));
g_map.addThing(cType->cast(), placePos, 4);
return __addCreature(placePos, cType); m_creatures.insert(std::make_pair(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) void Spawn::removeCreature(const Position& pos)
{ {
auto iterator = m_creatures.find(pos); auto iterator = m_creatures.find(pos);
if(iterator != m_creatures.end()) if(iterator != m_creatures.end()) {
__removeCreature(iterator); assert(iterator->first.isValid());
assert(g_map.removeThingByPos(iterator->first, 4));
m_creatures.erase(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()
@ -148,8 +150,8 @@ CreatureManager::CreatureManager()
void CreatureManager::clearSpawns() void CreatureManager::clearSpawns()
{ {
for(auto it : m_spawns) for(auto pair : m_spawns)
it->clear(); pair.second->clear();
m_spawns.clear(); m_spawns.clear();
} }
@ -226,7 +228,7 @@ void CreatureManager::loadSpawns(const std::string& fileName)
SpawnPtr spawn(new Spawn); SpawnPtr spawn(new Spawn);
spawn->load(node); spawn->load(node);
m_spawns.push_back(spawn); m_spawns.insert(std::make_pair(spawn->getCenterPos(), spawn));
} }
doc.Clear(); doc.Clear();
m_spawnLoaded = true; m_spawnLoaded = true;
@ -243,9 +245,9 @@ void CreatureManager::saveSpawns(const std::string& fileName)
TiXmlElement* root = new TiXmlElement("spawns"); TiXmlElement* root = new TiXmlElement("spawns");
doc.LinkEndChild(root); doc.LinkEndChild(root);
for(auto spawn : m_spawns) { for(auto pair : m_spawns) {
TiXmlElement* elem; TiXmlElement* elem;
spawn->save(elem); pair.second->save(elem);
root->LinkEndChild(elem); root->LinkEndChild(elem);
} }
@ -322,7 +324,7 @@ 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; return o.getId() == look || o.getAuxId() == 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);
if(it != m_creatures.end()) if(it != m_creatures.end())
@ -330,3 +332,27 @@ const CreatureTypePtr& CreatureManager::getCreatureByLook(int look)
g_logger.warning(stdext::format("could not find creature with looktype: %d", look)); g_logger.warning(stdext::format("could not find creature with looktype: %d", look));
return m_nullCreature; return m_nullCreature;
} }
SpawnPtr CreatureManager::getSpawn(const Position& centerPos)
{
auto it = m_spawns.find(centerPos);
if(it != m_spawns.end())
return it->second;
g_logger.debug(stdext::format("failed to find spawn at center %s",stdext::to_string(centerPos)));
return nullptr;
}
SpawnPtr CreatureManager::addSpawn(const Position& centerPos, int radius)
{
auto iter = m_spawns.find(centerPos);
if(iter != m_spawns.end())
return iter->second;
SpawnPtr ret(new Spawn);
ret->setRadius(radius);
ret->setCenterPos(centerPos);
m_spawns.insert(std::make_pair(centerPos, ret));
return ret;
}

View File

@ -46,7 +46,7 @@ enum SpawnAttr : uint8
class Spawn : public LuaObject class Spawn : public LuaObject
{ {
public: public:
Spawn() { } Spawn() = default;
Spawn(int32 radius) { setRadius(radius); } Spawn(int32 radius) { setRadius(radius); }
void setRadius(int32 r) { m_attribs.set(SpawnAttrRadius, r) ;} void setRadius(int32 r) { m_attribs.set(SpawnAttrRadius, r) ;}
@ -62,8 +62,6 @@ public:
protected: protected:
void load(TiXmlElement* node); void load(TiXmlElement* node);
void save(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: private:
stdext::dynamic_storage<uint8> m_attribs; stdext::dynamic_storage<uint8> m_attribs;
@ -74,13 +72,13 @@ private:
class CreatureType : public LuaObject class CreatureType : public LuaObject
{ {
public: public:
CreatureType() { } CreatureType() = default;
CreatureType(const std::string& name) { setName(name); } CreatureType(const std::string& name) { setName(name); }
void setSpawnTime(int32 spawnTime) { m_attribs.set(CreatureAttrSpawnTime, spawnTime); } void setSpawnTime(int32 spawnTime) { m_attribs.set(CreatureAttrSpawnTime, spawnTime); }
int32 getSpawnTime() { return m_attribs.get<int32>(CreatureAttrSpawnTime); } int32 getSpawnTime() { return m_attribs.get<int32>(CreatureAttrSpawnTime); }
void setName(const std::string& name) { m_attribs.set(CreatureAttrName, name); dump << "set"<<getName(); } void setName(const std::string& name) { m_attribs.set(CreatureAttrName, name); }
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); }
@ -112,18 +110,20 @@ public:
const CreatureTypePtr& getCreatureByName(std::string name); const CreatureTypePtr& getCreatureByName(std::string name);
const CreatureTypePtr& getCreatureByLook(int look); const CreatureTypePtr& getCreatureByLook(int look);
SpawnPtr getSpawn(const Position& centerPos);
SpawnPtr addSpawn(const Position& centerPos, int radius);
bool isLoaded() { return m_loaded; } bool isLoaded() { return m_loaded; }
bool isSpawnLoaded() { return m_spawnLoaded; } 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:
void 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;
std::vector<SpawnPtr> m_spawns; std::unordered_map<Position, SpawnPtr, PositionHasher> m_spawns;
stdext::boolean<false> m_loaded, m_spawnLoaded; stdext::boolean<false> m_loaded, m_spawnLoaded;
CreatureTypePtr m_nullCreature; CreatureTypePtr m_nullCreature;
}; };

View File

@ -110,12 +110,14 @@ void OTClient::registerLuaFunctions()
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", "getHouseFile", &Map::getHouseFile, &g_map); g_lua.bindSingletonFunction("g_map", "getHouseFile", &Map::getHouseFile, &g_map);
g_lua.bindSingletonFunction("g_map", "getSpawnFile", &Map::getSpawnFile, &g_map); g_lua.bindSingletonFunction("g_map", "getSpawnFile", &Map::getSpawnFile, &g_map);
g_lua.bindSingletonFunction("g_map", "createTile", &Map::createTile, &g_map);
g_lua.registerSingletonClass("g_creatures"); g_lua.registerSingletonClass("g_creatures");
g_lua.bindSingletonFunction("g_creatures", "getCreatures", &CreatureManager::getCreatures, &g_creatures); g_lua.bindSingletonFunction("g_creatures", "getCreatures", &CreatureManager::getCreatures, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "getSpawns", &CreatureManager::getSpawns, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "getCreatureByName", &CreatureManager::getCreatureByName, &g_creatures); g_lua.bindSingletonFunction("g_creatures", "getCreatureByName", &CreatureManager::getCreatureByName, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "getCreatureByLook", &CreatureManager::getCreatureByLook, &g_creatures); g_lua.bindSingletonFunction("g_creatures", "getCreatureByLook", &CreatureManager::getCreatureByLook, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "getSpawn", &CreatureManager::getSpawn, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "addSpawn", &CreatureManager::addSpawn, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "loadMonsters", &CreatureManager::loadMonsters, &g_creatures); g_lua.bindSingletonFunction("g_creatures", "loadMonsters", &CreatureManager::loadMonsters, &g_creatures);
g_lua.bindSingletonFunction("g_creatures", "loadNpcs", &CreatureManager::loadNpcs, &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", "loadSingleCreature", &CreatureManager::loadSingleCreature, &g_creatures);
@ -376,6 +378,7 @@ void OTClient::registerLuaFunctions()
g_lua.registerClass<Item, Thing>(); g_lua.registerClass<Item, Thing>();
g_lua.bindClassStaticFunction<Item>("create", &Item::create); g_lua.bindClassStaticFunction<Item>("create", &Item::create);
g_lua.bindClassStaticFunction<Item>("createOtb", &Item::createFromOtb);
g_lua.bindClassMemberFunction<Item>("clone", &Item::clone); g_lua.bindClassMemberFunction<Item>("clone", &Item::clone);
g_lua.bindClassMemberFunction<Item>("setCount", &Item::setCount); g_lua.bindClassMemberFunction<Item>("setCount", &Item::setCount);
g_lua.bindClassMemberFunction<Item>("getCount", &Item::getCount); g_lua.bindClassMemberFunction<Item>("getCount", &Item::getCount);