Merge fallen changes
This commit is contained in:
commit
70115e391d
8
init.lua
8
init.lua
|
@ -5,7 +5,7 @@
|
||||||
g_logger.setLogFile(g_resources.getWorkDir() .. g_app.getCompactName() .. ".log")
|
g_logger.setLogFile(g_resources.getWorkDir() .. g_app.getCompactName() .. ".log")
|
||||||
|
|
||||||
-- print first terminal message
|
-- print first terminal message
|
||||||
g_logger.info(g_app.getName() .. ' ' .. g_app.getVersion() .. ' rev ' .. g_app.getBuildRevision() .. ' (' .. g_app.getBuildCommit() .. ') built on ' .. g_app.getBuildDate())
|
g_logger.info(g_app.getName() .. ' ' .. g_app.getVersion() .. ' rev ' .. g_app.getBuildRevision() .. ' (' .. g_app.getBuildCommit() .. ') built on ' .. g_app.getBuildDate() .. ' for arch ' .. g_app.getBuildArch())
|
||||||
|
|
||||||
--add base folder to search path
|
--add base folder to search path
|
||||||
g_resources.addToSearchPath(g_resources.getWorkDir())
|
g_resources.addToSearchPath(g_resources.getWorkDir())
|
||||||
|
@ -27,15 +27,15 @@ g_configs.load("/config.otml")
|
||||||
g_modules.discoverModules()
|
g_modules.discoverModules()
|
||||||
|
|
||||||
-- core modules 0-99
|
-- core modules 0-99
|
||||||
g_modules.autoLoadModules(99);
|
g_modules.autoLoadModules(99)
|
||||||
g_modules.ensureModuleLoaded("corelib")
|
g_modules.ensureModuleLoaded("corelib")
|
||||||
|
|
||||||
-- client modules 100-499
|
-- client modules 100-499
|
||||||
g_modules.autoLoadModules(499);
|
g_modules.autoLoadModules(499)
|
||||||
g_modules.ensureModuleLoaded("client")
|
g_modules.ensureModuleLoaded("client")
|
||||||
|
|
||||||
-- game modules 500-999
|
-- game modules 500-999
|
||||||
g_modules.autoLoadModules(999);
|
g_modules.autoLoadModules(999)
|
||||||
g_modules.ensureModuleLoaded("game")
|
g_modules.ensureModuleLoaded("game")
|
||||||
|
|
||||||
-- addons 1000-9999
|
-- addons 1000-9999
|
||||||
|
|
|
@ -51,4 +51,5 @@ function Player:hasVip(creatureName)
|
||||||
if (vip[1] == creatureName) then return true end
|
if (vip[1] == creatureName) then return true end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ set(framework_SOURCES ${framework_SOURCES}
|
||||||
option(CRASH_HANDLER "Generate crash reports" ON)
|
option(CRASH_HANDLER "Generate crash reports" ON)
|
||||||
option(LUAJIT "Use lua jit" OFF)
|
option(LUAJIT "Use lua jit" OFF)
|
||||||
option(USE_STATIC_LIBS "Don't use shared libraries (dlls)" ON)
|
option(USE_STATIC_LIBS "Don't use shared libraries (dlls)" ON)
|
||||||
set(BUILD_COMMIT "custom" CACHE "Git commit string (intended for releases)" STRING)
|
set(BUILD_COMMIT "devel" CACHE "Git commit string (intended for releases)" STRING)
|
||||||
set(BUILD_REVISION "0" CACHE "Git revision string (intended for releases)" STRING)
|
set(BUILD_REVISION "0" CACHE "Git revision string (intended for releases)" STRING)
|
||||||
|
|
||||||
# default build type
|
# default build type
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
#define BUILD_COMPILER "gcc " __VERSION__
|
#define BUILD_COMPILER "gcc " __VERSION__
|
||||||
#define BUILD_DATE __DATE__
|
#define BUILD_DATE __DATE__
|
||||||
|
|
||||||
#ifndef BUILD_COMMIT
|
#ifndef BUILD_COMMIT
|
||||||
#define BUILD_COMMIT "custom"
|
#define BUILD_COMMIT "devel"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BUILD_REVISION
|
#ifndef BUILD_REVISION
|
||||||
|
@ -41,6 +41,16 @@
|
||||||
#define BUILD_TYPE "unknown"
|
#define BUILD_TYPE "unknown"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef BUILD_ARCH
|
||||||
|
#if defined(__amd64) || defined(_M_X64)
|
||||||
|
#define BUILD_ARCH "x64"
|
||||||
|
#elif defined(__i386) || defined(_M_IX86) || defined(_X86_)
|
||||||
|
#define BUILD_ARCH "X86"
|
||||||
|
#else
|
||||||
|
#define BUILD_ARCH "unknown"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Fw
|
namespace Fw
|
||||||
{
|
{
|
||||||
constexpr float pi = 3.14159265;
|
constexpr float pi = 3.14159265;
|
||||||
|
@ -207,7 +217,7 @@ namespace Fw
|
||||||
AnchorLeft,
|
AnchorLeft,
|
||||||
AnchorRight,
|
AnchorRight,
|
||||||
AnchorVerticalCenter,
|
AnchorVerticalCenter,
|
||||||
AnchorHorizontalCenter,
|
AnchorHorizontalCenter
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FocusReason {
|
enum FocusReason {
|
||||||
|
|
|
@ -57,6 +57,7 @@ public:
|
||||||
std::string getBuildRevision() { return BUILD_REVISION; }
|
std::string getBuildRevision() { return BUILD_REVISION; }
|
||||||
std::string getBuildCommit() { return BUILD_COMMIT; }
|
std::string getBuildCommit() { return BUILD_COMMIT; }
|
||||||
std::string getBuildType() { return BUILD_TYPE; }
|
std::string getBuildType() { return BUILD_TYPE; }
|
||||||
|
std::string getBuildArch() { return BUILD_ARCH; }
|
||||||
std::string getStartupOptions() { return m_startupOptions; }
|
std::string getStartupOptions() { return m_startupOptions; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -60,7 +60,7 @@ void BinaryTree::seek(uint pos)
|
||||||
|
|
||||||
uint8 BinaryTree::getU8()
|
uint8 BinaryTree::getU8()
|
||||||
{
|
{
|
||||||
if(m_pos+1 > m_buffer.size())
|
if (m_pos+1 > m_buffer.size())
|
||||||
stdext::throw_exception("BinaryTree: getU8 failed");
|
stdext::throw_exception("BinaryTree: getU8 failed");
|
||||||
uint8 v = m_buffer[m_pos];
|
uint8 v = m_buffer[m_pos];
|
||||||
m_pos += 1;
|
m_pos += 1;
|
||||||
|
@ -69,7 +69,7 @@ uint8 BinaryTree::getU8()
|
||||||
|
|
||||||
uint16 BinaryTree::getU16()
|
uint16 BinaryTree::getU16()
|
||||||
{
|
{
|
||||||
if(m_pos+2 > m_buffer.size())
|
if (m_pos+2 > m_buffer.size())
|
||||||
stdext::throw_exception("BinaryTree: getU16 failed");
|
stdext::throw_exception("BinaryTree: getU16 failed");
|
||||||
uint16 v = stdext::readLE16(&m_buffer[m_pos]);
|
uint16 v = stdext::readLE16(&m_buffer[m_pos]);
|
||||||
m_pos += 2;
|
m_pos += 2;
|
||||||
|
@ -78,7 +78,7 @@ uint16 BinaryTree::getU16()
|
||||||
|
|
||||||
uint32 BinaryTree::getU32()
|
uint32 BinaryTree::getU32()
|
||||||
{
|
{
|
||||||
if(m_pos+4 > m_buffer.size())
|
if (m_pos+4 > m_buffer.size())
|
||||||
stdext::throw_exception("BinaryTree: getU32 failed");
|
stdext::throw_exception("BinaryTree: getU32 failed");
|
||||||
uint32 v = stdext::readLE32(&m_buffer[m_pos]);
|
uint32 v = stdext::readLE32(&m_buffer[m_pos]);
|
||||||
m_pos += 4;
|
m_pos += 4;
|
||||||
|
@ -87,8 +87,8 @@ uint32 BinaryTree::getU32()
|
||||||
|
|
||||||
uint64 BinaryTree::getU64()
|
uint64 BinaryTree::getU64()
|
||||||
{
|
{
|
||||||
if(m_pos+8 > m_buffer.size())
|
if (m_pos+8 > m_buffer.size())
|
||||||
stdext::throw_exception("BinaryTree: getu64 failed");
|
stdext::throw_exception("BinaryTree: getU64 failed");
|
||||||
uint64 v = stdext::readLE64(&m_buffer[m_pos]);
|
uint64 v = stdext::readLE64(&m_buffer[m_pos]);
|
||||||
m_pos += 8;
|
m_pos += 8;
|
||||||
return v;
|
return v;
|
||||||
|
@ -98,7 +98,10 @@ std::string BinaryTree::getString()
|
||||||
{
|
{
|
||||||
uint16 len = getU16();
|
uint16 len = getU16();
|
||||||
if (len == 0 || len > 8192)
|
if (len == 0 || len > 8192)
|
||||||
stdext::throw_exception("failed to get string from binary tree - invalid size read.");
|
stdext::throw_exception("BinaryTree: getString failed: invalid or too large string length");
|
||||||
|
|
||||||
|
if (m_pos+len > m_buffer.size())
|
||||||
|
stdext::throw_exception("BinaryTree: getString failed: string length exceeded buffer size.");
|
||||||
|
|
||||||
std::string ret((char *)&m_buffer[m_pos], len);
|
std::string ret((char *)&m_buffer[m_pos], len);
|
||||||
m_pos += len;
|
m_pos += len;
|
||||||
|
|
|
@ -59,6 +59,8 @@ public:
|
||||||
void addU32(uint32 v);
|
void addU32(uint32 v);
|
||||||
void addU64(uint64 v);
|
void addU64(uint64 v);
|
||||||
void addString(const std::string& v);
|
void addString(const std::string& v);
|
||||||
|
void startNode(uint8 nodeType) { addU8(0xFE); addU8(nodeType); }
|
||||||
|
void endNode() { addU8(0xFF); }
|
||||||
|
|
||||||
FileStreamPtr asFileStream() { return std::static_pointer_cast<FileStream>(shared_from_this()); }
|
FileStreamPtr asFileStream() { return std::static_pointer_cast<FileStream>(shared_from_this()); }
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ void Application::registerLuaFunctions()
|
||||||
g_lua.bindSingletonFunction("g_app", "getBuildRevision", &Application::getBuildRevision, static_cast<Application*>(&g_app));
|
g_lua.bindSingletonFunction("g_app", "getBuildRevision", &Application::getBuildRevision, static_cast<Application*>(&g_app));
|
||||||
g_lua.bindSingletonFunction("g_app", "getBuildCommit", &Application::getBuildCommit, static_cast<Application*>(&g_app));
|
g_lua.bindSingletonFunction("g_app", "getBuildCommit", &Application::getBuildCommit, static_cast<Application*>(&g_app));
|
||||||
g_lua.bindSingletonFunction("g_app", "getBuildType", &Application::getBuildType, static_cast<Application*>(&g_app));
|
g_lua.bindSingletonFunction("g_app", "getBuildType", &Application::getBuildType, static_cast<Application*>(&g_app));
|
||||||
|
g_lua.bindSingletonFunction("g_app", "getBuildArch", &Application::getBuildArch, static_cast<Application*>(&g_app));
|
||||||
g_lua.bindSingletonFunction("g_app", "exit", &Application::exit, static_cast<Application*>(&g_app));
|
g_lua.bindSingletonFunction("g_app", "exit", &Application::exit, static_cast<Application*>(&g_app));
|
||||||
|
|
||||||
// Crypt
|
// Crypt
|
||||||
|
|
|
@ -75,6 +75,10 @@ set(otclient_SOURCES ${otclient_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/thingtypeotb.h
|
${CMAKE_CURRENT_LIST_DIR}/thingtypeotb.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/tile.cpp
|
${CMAKE_CURRENT_LIST_DIR}/tile.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/tile.h
|
${CMAKE_CURRENT_LIST_DIR}/tile.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/houses.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/houses.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/towns.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/towns.h
|
||||||
|
|
||||||
# lua
|
# lua
|
||||||
${CMAKE_CURRENT_LIST_DIR}/luavaluecasts.cpp
|
${CMAKE_CURRENT_LIST_DIR}/luavaluecasts.cpp
|
||||||
|
|
|
@ -46,6 +46,8 @@ class AnimatedText;
|
||||||
class StaticText;
|
class StaticText;
|
||||||
class ThingTypeDat;
|
class ThingTypeDat;
|
||||||
class ThingTypeOtb;
|
class ThingTypeOtb;
|
||||||
|
class House;
|
||||||
|
class Town;
|
||||||
|
|
||||||
typedef std::shared_ptr<MapView> MapViewPtr;
|
typedef std::shared_ptr<MapView> MapViewPtr;
|
||||||
typedef std::shared_ptr<Tile> TilePtr;
|
typedef std::shared_ptr<Tile> TilePtr;
|
||||||
|
@ -63,10 +65,14 @@ typedef std::shared_ptr<AnimatedText> AnimatedTextPtr;
|
||||||
typedef std::shared_ptr<StaticText> StaticTextPtr;
|
typedef std::shared_ptr<StaticText> StaticTextPtr;
|
||||||
typedef std::shared_ptr<ThingTypeDat> ThingTypeDatPtr;
|
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<Town> TownPtr;
|
||||||
|
|
||||||
typedef std::vector<ThingPtr> ThingList;
|
typedef std::vector<ThingPtr> ThingList;
|
||||||
typedef std::vector<ThingTypeDatPtr> ThingTypeDatList;
|
typedef std::vector<ThingTypeDatPtr> ThingTypeDatList;
|
||||||
typedef std::vector<ThingTypeOtbPtr> ThingTypeOtbList;
|
typedef std::vector<ThingTypeOtbPtr> ThingTypeOtbList;
|
||||||
|
typedef std::vector<HousePtr> HouseList;
|
||||||
|
typedef std::vector<TownPtr> TownList;
|
||||||
|
|
||||||
// net
|
// net
|
||||||
class ProtocolLogin;
|
class ProtocolLogin;
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "map.h"
|
||||||
|
|
||||||
|
Houses g_houses;
|
||||||
|
|
||||||
|
House::House(uint32 hId, const std::string &name, const Position &pos)
|
||||||
|
: m_id(hId), m_name(name)
|
||||||
|
{
|
||||||
|
if (pos.isValid())
|
||||||
|
m_doors.insert(std::make_pair(0, pos)); // first door
|
||||||
|
}
|
||||||
|
|
||||||
|
void House::addDoor(uint16 doorId, const Position& pos)
|
||||||
|
{
|
||||||
|
if (m_doors.find(doorId) == m_doors.end())
|
||||||
|
m_doors.insert(std::make_pair(doorId, pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
void House::setTile(const TilePtr& tile)
|
||||||
|
{
|
||||||
|
tile->setFlags(TILESTATE_HOUSE);
|
||||||
|
if (std::find(m_tiles.begin(), m_tiles.end(), tile) == m_tiles.end())
|
||||||
|
m_tiles.push_back(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define fugly_get(attrib, type) stdext::unsafe_cast<type>(elem->Attribute((attrib)))
|
||||||
|
|
||||||
|
void House::load(const TiXmlElement *elem)
|
||||||
|
{
|
||||||
|
std::string name = elem->Attribute("name");
|
||||||
|
if (name.empty())
|
||||||
|
name = stdext::format("UnNamed house #%u", getId());
|
||||||
|
|
||||||
|
uint32 rent = fugly_get("rent", uint32);
|
||||||
|
m_rent = rent;
|
||||||
|
|
||||||
|
uint32 townId = fugly_get("townid", uint32);
|
||||||
|
if (!g_map.getTown(townId))
|
||||||
|
stdext::throw_exception(stdext::format("invalid town id for house %d", townId));
|
||||||
|
|
||||||
|
uint32 size = fugly_get("size", uint32);
|
||||||
|
if (size == 0)
|
||||||
|
size = 1;
|
||||||
|
|
||||||
|
m_size = size;
|
||||||
|
m_isGuildHall = fugly_get("guildhall", bool);
|
||||||
|
addDoor(0, Position(fugly_get("entryx", uint16), fugly_get("entryy", uint16),
|
||||||
|
fugly_get("entryz", uint8)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Houses::addHouse(const HousePtr& house)
|
||||||
|
{
|
||||||
|
if (findHouse(house->getId()) == m_houses.end())
|
||||||
|
m_houses.push_back(house);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Houses::removeHouse(uint32 houseId)
|
||||||
|
{
|
||||||
|
auto it = findHouse(houseId);
|
||||||
|
if (it != m_houses.end())
|
||||||
|
m_houses.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
HousePtr Houses::getHouse(uint32 houseId)
|
||||||
|
{
|
||||||
|
auto it = findHouse(houseId);
|
||||||
|
if (it != m_houses.end())
|
||||||
|
return *it;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Houses::load(const std::string& fileName)
|
||||||
|
{
|
||||||
|
TiXmlDocument doc(fileName.c_str());
|
||||||
|
if (!doc.LoadFile())
|
||||||
|
stdext::throw_exception(stdext::format("failed to load '%s' (House XML)", fileName));
|
||||||
|
|
||||||
|
TiXmlElement *root = doc.FirstChildElement();
|
||||||
|
if (!root || root->ValueTStr() != "houses")
|
||||||
|
stdext::throw_exception("invalid root tag name");
|
||||||
|
|
||||||
|
for (TiXmlElement *elem = root->FirstChildElement(); elem; elem = elem->NextSiblingElement()) {
|
||||||
|
if (elem->ValueTStr() != "house")
|
||||||
|
stdext::throw_exception("invalid house tag.");
|
||||||
|
|
||||||
|
uint32 houseId = fugly_get("houseid", uint32);
|
||||||
|
HousePtr house = getHouse(houseId);
|
||||||
|
if (!house)
|
||||||
|
house = HousePtr(new House(houseId)), addHouse(house);
|
||||||
|
|
||||||
|
house->load(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
stdext::throw_exception("This has not been fully implemented yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
HouseList::iterator Houses::findHouse(uint32 houseId)
|
||||||
|
{
|
||||||
|
return std::find_if(m_houses.begin(), m_houses.end(),
|
||||||
|
[=] (const HousePtr& house) -> bool { return house->getId() == houseId; });
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HOUSES_H
|
||||||
|
#define HOUSES_H
|
||||||
|
|
||||||
|
#include "declarations.h"
|
||||||
|
#include "tile.h"
|
||||||
|
|
||||||
|
#include <framework/luaengine/luaobject.h>
|
||||||
|
|
||||||
|
class House : public LuaObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
House() { }
|
||||||
|
House(uint32 hId, const std::string& name = "", const Position& pos=Position());
|
||||||
|
~House() { m_tiles.clear(); m_doors.clear(); }
|
||||||
|
|
||||||
|
void setId(uint32 hId) { m_id = hId; }
|
||||||
|
void setName(const std::string& name) { m_name = name; }
|
||||||
|
void addDoor(uint16 doorId, const Position& pos);
|
||||||
|
void setTile(const TilePtr& tile);
|
||||||
|
|
||||||
|
uint32 getId() const { return m_id; }
|
||||||
|
std::string getName() const { return m_name; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void load(const TiXmlElement* elem);
|
||||||
|
void save(TiXmlElement &elem) { } // TODO
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 m_id, m_size, m_rent;
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
std::map<uint16, Position> m_doors;
|
||||||
|
std::vector<TilePtr> m_tiles;
|
||||||
|
Boolean<false> m_isGuildHall;
|
||||||
|
|
||||||
|
friend class Houses;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Houses {
|
||||||
|
public:
|
||||||
|
void addHouse(const HousePtr& house);
|
||||||
|
void removeHouse(uint32 houseId);
|
||||||
|
void load(const std::string& fileName);
|
||||||
|
|
||||||
|
HouseList houseList() const { return m_houses; }
|
||||||
|
HousePtr getHouse(uint32 houseId);
|
||||||
|
|
||||||
|
// Fix to segfault on exit.
|
||||||
|
void clear() { m_houses.clear(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
HouseList m_houses;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HouseList::iterator findHouse(uint32 houseId);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,6 +26,9 @@
|
||||||
#include "thing.h"
|
#include "thing.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include "shadermanager.h"
|
#include "shadermanager.h"
|
||||||
|
#include "container.h"
|
||||||
|
#include "map.h"
|
||||||
|
#include "houses.h"
|
||||||
|
|
||||||
#include <framework/core/clock.h>
|
#include <framework/core/clock.h>
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
|
@ -45,14 +48,14 @@ Item::Item() :
|
||||||
|
|
||||||
ItemPtr Item::create(int id)
|
ItemPtr Item::create(int id)
|
||||||
{
|
{
|
||||||
ItemPtr item = ItemPtr(new Item);
|
ItemPtr item(new Item);
|
||||||
item->setId(id);
|
item->setId(id);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemPtr Item::createFromOtb(int id)
|
ItemPtr Item::createFromOtb(int id)
|
||||||
{
|
{
|
||||||
ItemPtr item = ItemPtr(new Item);
|
ItemPtr item(new Item);
|
||||||
item->setOtbId(id);
|
item->setOtbId(id);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -204,70 +207,80 @@ bool Item::isValid()
|
||||||
return g_things.isValidDatId(m_id, DatItemCategory);
|
return g_things.isValidDatId(m_id, DatItemCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Item::unserializeAttr(const BinaryTreePtr &fin)
|
void Item::unserializeItem(const BinaryTreePtr &in)
|
||||||
{
|
{
|
||||||
uint8 attrType;
|
while (in->canRead()) {
|
||||||
while ((attrType = fin->getU8()) != 0)
|
uint8 attrType = in->getU8();
|
||||||
readAttr((AttrTypes_t)attrType, fin);
|
if (attrType == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
return true;
|
// fugly switch yes?
|
||||||
}
|
switch ((AttrTypes_t)attrType) {
|
||||||
|
case ATTR_COUNT:
|
||||||
void Item::readAttr(AttrTypes_t attrType, const BinaryTreePtr &fin)
|
setSubType(in->getU8());
|
||||||
{
|
break;
|
||||||
switch (attrType) {
|
case ATTR_CHARGES:
|
||||||
case ATTR_COUNT:
|
setSubType(in->getU16());
|
||||||
setSubType(fin->getU8());
|
break;
|
||||||
break;
|
case ATTR_ACTION_ID:
|
||||||
case ATTR_ACTION_ID:
|
setActionId(in->getU16());
|
||||||
setActionId(fin->getU16());
|
break;
|
||||||
break;
|
case ATTR_UNIQUE_ID:
|
||||||
case ATTR_UNIQUE_ID:
|
setUniqueId(in->getU16());
|
||||||
setUniqueId(fin->getU16());
|
break;
|
||||||
break;
|
case ATTR_NAME:
|
||||||
case ATTR_NAME:
|
setName(in->getString());
|
||||||
setName(fin->getString());
|
break;
|
||||||
break;
|
case ATTR_TEXT:
|
||||||
case ATTR_ARTICLE:
|
setText(in->getString());
|
||||||
fin->getString();
|
break;
|
||||||
case ATTR_ATTACK: // \/ not needed.
|
case ATTR_DESC:
|
||||||
case ATTR_EXTRAATTACK:
|
m_description = in->getString();
|
||||||
case ATTR_DEFENSE:
|
break;
|
||||||
case ATTR_EXTRADEFENSE:
|
case ATTR_CONTAINER_ITEMS:
|
||||||
case ATTR_ARMOR:
|
m_isContainer = true;
|
||||||
case ATTR_ATTACKSPEED:
|
in->skip(4);
|
||||||
case ATTR_HPPITCHANCE:
|
break;
|
||||||
case ATTR_DURATION:
|
case ATTR_HOUSEDOORID:
|
||||||
fin->getU32();
|
m_isDoor = true;
|
||||||
break;
|
m_doorId = in->getU8();
|
||||||
case ATTR_SCRIPTPROTECTED:
|
break;
|
||||||
case ATTR_DUALWIELD:
|
case ATTR_DEPOT_ID:
|
||||||
case ATTR_DECAYING_STATE:
|
m_depotId = in->getU16();
|
||||||
case ATTR_HPPOUSEDOORID:
|
break;
|
||||||
fin->getU8();
|
case ATTR_TELE_DEST: {
|
||||||
break;
|
m_teleportDestination.x = in->getU16();
|
||||||
case ATTR_TEXT:
|
m_teleportDestination.y = in->getU16();
|
||||||
setText(fin->getString());
|
m_teleportDestination.z = in->getU8();
|
||||||
break;
|
break;
|
||||||
case ATTR_WRITTENDATE:
|
}
|
||||||
fin->getU32();
|
case ATTR_ARTICLE:
|
||||||
break;
|
case ATTR_WRITTENBY:
|
||||||
case ATTR_WRITTENBY:
|
in->getString();
|
||||||
fin->getString();
|
break;
|
||||||
break;
|
case ATTR_ATTACK:
|
||||||
case ATTR_DESC:
|
case ATTR_EXTRAATTACK:
|
||||||
setDescription(fin->getString());
|
case ATTR_DEFENSE:
|
||||||
break;
|
case ATTR_EXTRADEFENSE:
|
||||||
case ATTR_RUNE_CHARGES:
|
case ATTR_ARMOR:
|
||||||
fin->getU8();
|
case ATTR_ATTACKSPEED:
|
||||||
break;
|
case ATTR_HITCHANCE:
|
||||||
case ATTR_TELE_DEST: // Teleport should read that.
|
case ATTR_DURATION:
|
||||||
case ATTR_SLEEPERGUID: // Bed should read that.
|
case ATTR_WRITTENDATE:
|
||||||
case ATTR_SLEEPSTART:
|
case ATTR_SLEEPERGUID:
|
||||||
case ATTR_CONTAINER_ITEMS:
|
case ATTR_SLEEPSTART:
|
||||||
case ATTR_ATTRIBUTE_MAP:
|
case ATTR_ATTRIBUTE_MAP:
|
||||||
default:
|
in->skip(4);
|
||||||
break;
|
break;
|
||||||
|
case ATTR_SCRIPTPROTECTED:
|
||||||
|
case ATTR_DUALWIELD:
|
||||||
|
case ATTR_DECAYING_STATE:
|
||||||
|
case ATTR_RUNE_CHARGES:
|
||||||
|
in->skip(1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
stdext::throw_exception(stdext::format("invalid item attribute %d", (int)attrType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,9 @@
|
||||||
#include "thing.h"
|
#include "thing.h"
|
||||||
#include "thingtypeotb.h"
|
#include "thingtypeotb.h"
|
||||||
|
|
||||||
enum AttrTypes_t {
|
enum AttrTypes_t
|
||||||
|
{
|
||||||
ATTR_END = 0,
|
ATTR_END = 0,
|
||||||
//ATTR_DESCRIPTION = 1,
|
|
||||||
//ATTR_EXT_FILE = 2,
|
|
||||||
ATTR_TILE_FLAGS = 3,
|
ATTR_TILE_FLAGS = 3,
|
||||||
ATTR_ACTION_ID = 4,
|
ATTR_ACTION_ID = 4,
|
||||||
ATTR_UNIQUE_ID = 5,
|
ATTR_UNIQUE_ID = 5,
|
||||||
|
@ -39,10 +38,8 @@ enum AttrTypes_t {
|
||||||
ATTR_TELE_DEST = 8,
|
ATTR_TELE_DEST = 8,
|
||||||
ATTR_ITEM = 9,
|
ATTR_ITEM = 9,
|
||||||
ATTR_DEPOT_ID = 10,
|
ATTR_DEPOT_ID = 10,
|
||||||
//ATTR_EXT_SPAWN_FILE = 11,
|
|
||||||
ATTR_RUNE_CHARGES = 12,
|
ATTR_RUNE_CHARGES = 12,
|
||||||
//ATTR_EXT_HPPOUSE_FILE = 13,
|
ATTR_HOUSEDOORID = 14,
|
||||||
ATTR_HPPOUSEDOORID = 14,
|
|
||||||
ATTR_COUNT = 15,
|
ATTR_COUNT = 15,
|
||||||
ATTR_DURATION = 16,
|
ATTR_DURATION = 16,
|
||||||
ATTR_DECAYING_STATE = 17,
|
ATTR_DECAYING_STATE = 17,
|
||||||
|
@ -60,7 +57,7 @@ enum AttrTypes_t {
|
||||||
ATTR_EXTRADEFENSE = 36,
|
ATTR_EXTRADEFENSE = 36,
|
||||||
ATTR_ARMOR = 37,
|
ATTR_ARMOR = 37,
|
||||||
ATTR_ATTACKSPEED = 38,
|
ATTR_ATTACKSPEED = 38,
|
||||||
ATTR_HPPITCHANCE = 39,
|
ATTR_HITCHANCE = 39,
|
||||||
ATTR_SHOOTRANGE = 40,
|
ATTR_SHOOTRANGE = 40,
|
||||||
ATTR_ARTICLE = 41,
|
ATTR_ARTICLE = 41,
|
||||||
ATTR_SCRIPTPROTECTED = 42,
|
ATTR_SCRIPTPROTECTED = 42,
|
||||||
|
@ -86,6 +83,7 @@ public:
|
||||||
void setSubType(int subType) { m_countOrSubType = subType; }
|
void setSubType(int subType) { m_countOrSubType = subType; }
|
||||||
void setActionId(int actionId) { m_actionId = actionId; }
|
void setActionId(int actionId) { m_actionId = actionId; }
|
||||||
void setUniqueId(int uniqueId) { m_uniqueId = uniqueId; }
|
void setUniqueId(int uniqueId) { m_uniqueId = uniqueId; }
|
||||||
|
void setDoorId(int doorId) { m_doorId = doorId; }
|
||||||
void setName(const std::string &name) { m_name = name; }
|
void setName(const std::string &name) { m_name = name; }
|
||||||
void setText(const std::string &text) { m_text = text; }
|
void setText(const std::string &text) { m_text = text; }
|
||||||
void setDescription(const std::string &description) { m_description = description; }
|
void setDescription(const std::string &description) { m_description = description; }
|
||||||
|
@ -95,24 +93,30 @@ public:
|
||||||
int getCount() { return m_countOrSubType; }
|
int getCount() { return m_countOrSubType; }
|
||||||
uint32 getId() { return m_id; }
|
uint32 getId() { return m_id; }
|
||||||
std::string getName() { return m_name; }
|
std::string getName() { return m_name; }
|
||||||
|
uint8 getDoorId() { return m_doorId; }
|
||||||
bool isValid();
|
bool isValid();
|
||||||
|
|
||||||
ItemPtr asItem() { return std::static_pointer_cast<Item>(shared_from_this()); }
|
ItemPtr asItem() { return std::static_pointer_cast<Item>(shared_from_this()); }
|
||||||
bool isItem() { return true; }
|
bool isItem() { return true; }
|
||||||
|
|
||||||
// TODO: These should be abstract and declared in i.e containers, doors, etc.
|
void unserializeItem(const BinaryTreePtr &in);
|
||||||
bool unserializeAttr(const BinaryTreePtr &fin);
|
|
||||||
bool unserializeItemNode(const BinaryTreePtr &fin) { return unserializeAttr(fin); }
|
|
||||||
void readAttr(AttrTypes_t attrType, const BinaryTreePtr &fin);
|
|
||||||
bool isMoveable();
|
bool isMoveable();
|
||||||
|
bool isContainer() { return m_isContainer; }
|
||||||
|
bool isDoor() { return m_isDoor; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16 m_id;
|
uint16 m_id;
|
||||||
uint8 m_countOrSubType;
|
uint8 m_countOrSubType;
|
||||||
uint32 m_actionId, m_uniqueId;
|
uint32 m_actionId, m_uniqueId;
|
||||||
|
uint16 m_depotId;
|
||||||
|
uint8 m_doorId;
|
||||||
|
Boolean<false> m_isContainer;
|
||||||
|
Boolean<false> m_isDoor;
|
||||||
|
|
||||||
std::string m_name, m_text, m_description;
|
std::string m_name, m_text, m_description;
|
||||||
PainterShaderProgramPtr m_shaderProgram;
|
PainterShaderProgramPtr m_shaderProgram;
|
||||||
ThingTypeOtbPtr m_otbType;
|
ThingTypeOtbPtr m_otbType;
|
||||||
|
Position m_teleportDestination;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "luavaluecasts.h"
|
#include "luavaluecasts.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
#include "houses.h"
|
||||||
|
#include "towns.h"
|
||||||
#include "container.h"
|
#include "container.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "effect.h"
|
#include "effect.h"
|
||||||
|
@ -53,6 +55,19 @@ void OTClient::registerLuaFunctions()
|
||||||
g_lua.bindSingletonFunction("g_things", "loadXml", &ThingTypeManager::loadXml, &g_things);
|
g_lua.bindSingletonFunction("g_things", "loadXml", &ThingTypeManager::loadXml, &g_things);
|
||||||
g_lua.bindSingletonFunction("g_things", "getDatSignature", &ThingTypeManager::getDatSignature, &g_things);
|
g_lua.bindSingletonFunction("g_things", "getDatSignature", &ThingTypeManager::getDatSignature, &g_things);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
g_lua.registerSingletonClass("g_houses");
|
||||||
|
g_lua.bindSingletonFunction("g_houses", "load", &Houses::load, &g_houses);
|
||||||
|
g_lua.bindSingletonFunction("g_houses", "getHouse", &Houses::getHouse, &g_houses);
|
||||||
|
g_lua.bindSingletonFunction("g_houses", "addHouse", &Houses::addHouse, &g_houses);
|
||||||
|
g_lua.bindSingletonFunction("g_houses", "removeHouse", &Houses::removeHouse, &g_houses);
|
||||||
|
|
||||||
|
g_lua.registerSingletonClass("g_towns");
|
||||||
|
g_lua.bindSingletonFunction("g_towns", "getTown", &Towns::getTown, &g_towns);
|
||||||
|
g_lua.bindSingletonFunction("g_towns", "addTown", &Towns::addTown, &g_towns);
|
||||||
|
g_lua.bindSingletonFunction("g_towns", "removeTown", &Towns::removeTown, &g_towns);
|
||||||
|
#endif
|
||||||
|
|
||||||
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);
|
||||||
g_lua.bindSingletonFunction("g_sprites", "unload", &SpriteManager::unload, &g_sprites);
|
g_lua.bindSingletonFunction("g_sprites", "unload", &SpriteManager::unload, &g_sprites);
|
||||||
|
@ -81,6 +96,8 @@ void OTClient::registerLuaFunctions()
|
||||||
//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", "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", "getHouse", &Map::getHouse, &g_map);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -255,6 +272,26 @@ void OTClient::registerLuaFunctions()
|
||||||
g_lua.bindClassMemberFunction<Thing>("isFullGround", &Thing::isFullGround);
|
g_lua.bindClassMemberFunction<Thing>("isFullGround", &Thing::isFullGround);
|
||||||
g_lua.bindClassMemberFunction<Thing>("getParentContainer", &Thing::getParentContainer);
|
g_lua.bindClassMemberFunction<Thing>("getParentContainer", &Thing::getParentContainer);
|
||||||
|
|
||||||
|
g_lua.registerClass<House>();
|
||||||
|
g_lua.bindClassStaticFunction<House>("create", []{ return HousePtr(new House); });
|
||||||
|
g_lua.bindClassMemberFunction<House>("setId", &House::setId);
|
||||||
|
g_lua.bindClassMemberFunction<House>("setName", &House::setName);
|
||||||
|
g_lua.bindClassMemberFunction<House>("addDoor", &House::addDoor);
|
||||||
|
g_lua.bindClassMemberFunction<House>("addDoorPos", &House::addDoor); // alternative method
|
||||||
|
g_lua.bindClassMemberFunction<House>("setTile", &House::setTile);
|
||||||
|
g_lua.bindClassMemberFunction<House>("addTile", &House::addDoor); // alternative method
|
||||||
|
|
||||||
|
g_lua.registerClass<Town>();
|
||||||
|
g_lua.bindClassStaticFunction<Town>("create", []{ return TownPtr(new Town); });
|
||||||
|
g_lua.bindClassMemberFunction<Town>("setId", &Town::setId);
|
||||||
|
g_lua.bindClassMemberFunction<Town>("setName", &Town::setName);
|
||||||
|
g_lua.bindClassMemberFunction<Town>("setPos", &Town::setPos);
|
||||||
|
g_lua.bindClassMemberFunction<Town>("setTemplePos", &Town::setPos); // alternative method
|
||||||
|
g_lua.bindClassMemberFunction<Town>("getId", &Town::getId);
|
||||||
|
g_lua.bindClassMemberFunction<Town>("getName", &Town::getName);
|
||||||
|
g_lua.bindClassMemberFunction<Town>("getPos", &Town::getPos);
|
||||||
|
g_lua.bindClassMemberFunction<Town>("getTemplePos", &Town::getPos); // alternative method
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <framework/core/resourcemanager.h>
|
#include <framework/core/resourcemanager.h>
|
||||||
#include <framework/core/filestream.h>
|
#include <framework/core/filestream.h>
|
||||||
#include <framework/core/binarytree.h>
|
#include <framework/core/binarytree.h>
|
||||||
|
#include <framework/core/application.h>
|
||||||
|
|
||||||
Map g_map;
|
Map g_map;
|
||||||
|
|
||||||
|
@ -59,67 +60,59 @@ void Map::notificateTileUpdateToMapViews(const Position& pos)
|
||||||
mapView->onTileUpdate(pos);
|
mapView->onTileUpdate(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::loadOtbm(const std::string& fileName)
|
void Map::loadOtbm(const std::string& fileName)
|
||||||
{
|
{
|
||||||
FileStreamPtr fin = g_resources.openFile(fileName);
|
FileStreamPtr fin = g_resources.openFile(fileName);
|
||||||
if (!fin) {
|
if (!fin)
|
||||||
g_logger.error(stdext::format("Unable to load map '%s'", fileName));
|
stdext::throw_exception(stdext::format("Unable to load map '%s'", fileName));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_things.isOtbLoaded()/* || !g_things.isXmlLoaded()*/) {
|
fin->cache();
|
||||||
g_logger.error("OTB and XML are not loaded yet to load a map.");
|
if (!g_things.isOtbLoaded())
|
||||||
return false;
|
stdext::throw_exception("OTB isn't loaded yet to load a map.");
|
||||||
}
|
|
||||||
|
if (fin->getU32())
|
||||||
|
stdext::throw_exception("Unknown file version detected");
|
||||||
|
|
||||||
assert(fin->getU32() == 0);
|
|
||||||
BinaryTreePtr root = fin->getBinaryTree();
|
BinaryTreePtr root = fin->getBinaryTree();
|
||||||
root->skip(1); // Not sure, what exactly that is... perhaps node type?
|
if (root->getU8())
|
||||||
uint32 headerVersion = root->getU32();
|
stdext::throw_exception("could not read root property!");
|
||||||
dump << headerVersion;
|
|
||||||
if (!headerVersion || headerVersion > 3) {
|
uint32 headerVersion = root->getU32();
|
||||||
g_logger.error("Unknown OTBM version detected.");
|
if (!headerVersion || headerVersion > 3)
|
||||||
return false;
|
stdext::throw_exception(stdext::format("Unknown OTBM version detected: %u.", headerVersion));
|
||||||
}
|
|
||||||
|
m_width = root->getU16();
|
||||||
|
m_height = root->getU16();
|
||||||
|
dump << "Map size: " << m_width << "x" << m_height;
|
||||||
|
|
||||||
root->skip(1); // ??
|
|
||||||
uint32 headerMajorItems = root->getU8();
|
uint32 headerMajorItems = root->getU8();
|
||||||
dump << headerMajorItems;
|
|
||||||
dump << "major: " << g_things.getOtbMajorVersion();
|
|
||||||
if (headerMajorItems < 3) {
|
if (headerMajorItems < 3) {
|
||||||
g_logger.error("This map needs to be upgraded.");
|
stdext::throw_exception(stdext::format("This map needs to be upgraded. read %d what it's supposed to be: %u",
|
||||||
return false;
|
headerMajorItems, g_things.getOtbMajorVersion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerMajorItems > g_things.getOtbMajorVersion()) {
|
if (headerMajorItems > g_things.getOtbMajorVersion()) {
|
||||||
g_logger.error("This map was saved with different OTB version.");
|
stdext::throw_exception(stdext::format("This map was saved with different OTB version. read %d what it's supposed to be: %d",
|
||||||
return false;
|
headerMajorItems, g_things.getOtbMajorVersion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
root->skip(1); /// ??
|
root->skip(3);
|
||||||
uint32 headerMinorItems = root->getU8();
|
uint32 headerMinorItems = root->getU32();
|
||||||
dump << headerMinorItems;
|
if (headerMinorItems > g_things.getOtbMinorVersion()) {
|
||||||
dump << "minor: " << g_things.getOtbMinorVersion();
|
g_logger.warning(stdext::format("This map needs an updated OTB. read %d what it's supposed to be: %d",
|
||||||
if (headerMinorItems > g_things.getOtbMinorVersion())
|
headerMinorItems, g_things.getOtbMinorVersion()));
|
||||||
g_logger.warning("This map needs an updated OTB.");
|
}
|
||||||
|
|
||||||
BinaryTreePtr node = root->getChildren()[0];
|
BinaryTreePtr node = root->getChildren()[0];
|
||||||
if (node->getU8() != OTBM_MAP_DATA) {
|
if (node->getU8() != OTBM_MAP_DATA)
|
||||||
g_logger.error("Could not read data node.");
|
stdext::throw_exception("Could not read root data node");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string tmp;
|
|
||||||
uint8 attribute;
|
|
||||||
while (node->canRead()) {
|
while (node->canRead()) {
|
||||||
attribute = node->getU8();
|
uint8 attribute = node->getU8();
|
||||||
tmp = node->getString();
|
std::string tmp = node->getString();
|
||||||
switch (attribute) {
|
switch (attribute) {
|
||||||
case OTBM_ATTR_DESCRIPTION:
|
case OTBM_ATTR_DESCRIPTION:
|
||||||
if (!m_description.empty())
|
m_description += tmp + "\n";
|
||||||
m_description += "\n" + tmp;
|
|
||||||
else
|
|
||||||
m_description = tmp;
|
|
||||||
break;
|
break;
|
||||||
case OTBM_ATTR_SPAWN_FILE:
|
case OTBM_ATTR_SPAWN_FILE:
|
||||||
m_spawnFile = fileName.substr(0, fileName.rfind('/') + 1) + tmp;
|
m_spawnFile = fileName.substr(0, fileName.rfind('/') + 1) + tmp;
|
||||||
|
@ -128,151 +121,260 @@ bool Map::loadOtbm(const std::string& fileName)
|
||||||
m_houseFile = fileName.substr(0, fileName.rfind('/') + 1) + tmp;
|
m_houseFile = fileName.substr(0, fileName.rfind('/') + 1) + tmp;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_logger.error(stdext::format("Invalid attribute '%c'", attribute));
|
stdext::throw_exception(stdext::format("Invalid attribute '%c'", attribute));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dump << m_description;
|
|
||||||
dump << m_houseFile;
|
|
||||||
dump << m_spawnFile;
|
|
||||||
|
|
||||||
for (const BinaryTreePtr &nodeMapData : node->getChildren()) {
|
for (const BinaryTreePtr &nodeMapData : node->getChildren()) {
|
||||||
uint8 mapDataType = nodeMapData->getU8();
|
uint8 mapDataType = nodeMapData->getU8();
|
||||||
dump << "mapData: " << (int)mapDataType;
|
|
||||||
if (mapDataType == OTBM_TILE_AREA) {
|
if (mapDataType == OTBM_TILE_AREA) {
|
||||||
dump << "Tile: reading pos...";
|
|
||||||
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)
|
||||||
TilePtr tile = 0;
|
stdext::throw_exception(stdext::format("invalid node tile type %d", (int)type));
|
||||||
ItemPtr ground = 0;
|
|
||||||
uint32 flags = 0;
|
|
||||||
|
|
||||||
uint16 px = baseX + nodeTile->getU16(), py = baseY + nodeTile->getU16();
|
TilePtr tile = nullptr;
|
||||||
Position pos(px, py, pz);
|
ItemPtr ground = nullptr;
|
||||||
|
HousePtr house = nullptr;
|
||||||
|
uint32 flags = TILESTATE_NONE;
|
||||||
|
|
||||||
// TODO: Houses.
|
uint16 px = baseX + nodeTile->getU8(), py = baseY + nodeTile->getU8();
|
||||||
if (type == OTBM_HOUSETILE) {
|
Position pos(px, py, pz);
|
||||||
uint32 hId = nodeTile->getU32();
|
|
||||||
|
|
||||||
tile = createTile(pos);
|
if (type == OTBM_HOUSETILE) {
|
||||||
// TODO: add it to house.
|
uint32 hId = nodeTile->getU32();
|
||||||
|
tile = createTile(pos);
|
||||||
|
if (!(house = m_houses.getHouse(hId))) {
|
||||||
|
house = HousePtr(new House(hId));
|
||||||
|
m_houses.addHouse(house);
|
||||||
}
|
}
|
||||||
|
house->setTile(tile);
|
||||||
|
}
|
||||||
|
|
||||||
uint8 tileAttr;
|
while (nodeTile->canRead()) {
|
||||||
while (nodeTile->canRead()) {
|
uint8 tileAttr = nodeTile->getU8();
|
||||||
tileAttr = nodeTile->getU8();
|
switch (tileAttr) {
|
||||||
switch (tileAttr) {
|
|
||||||
case OTBM_ATTR_TILE_FLAGS: {
|
case OTBM_ATTR_TILE_FLAGS: {
|
||||||
uint32 _flags = nodeTile->getU32();
|
uint32 _flags = nodeTile->getU32();
|
||||||
|
|
||||||
if ((_flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE)
|
if ((_flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE)
|
||||||
flags |= TILESTATE_PROTECTIONZONE;
|
flags |= TILESTATE_PROTECTIONZONE;
|
||||||
else if ((_flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE)
|
else if ((_flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE)
|
||||||
flags |= TILESTATE_OPTIONALZONE;
|
flags |= TILESTATE_OPTIONALZONE;
|
||||||
else if ((_flags & TILESTATE_HPPARDCOREZONE) == TILESTATE_HPPARDCOREZONE)
|
else if ((_flags & TILESTATE_HARDCOREZONE) == TILESTATE_HARDCOREZONE)
|
||||||
flags |= TILESTATE_HPPARDCOREZONE;
|
flags |= TILESTATE_HARDCOREZONE;
|
||||||
|
|
||||||
if ((_flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT)
|
if ((_flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT)
|
||||||
flags |= TILESTATE_NOLOGOUT;
|
flags |= TILESTATE_NOLOGOUT;
|
||||||
|
|
||||||
if ((_flags & TILESTATE_REFRESH) == TILESTATE_REFRESH)
|
if ((_flags & TILESTATE_REFRESH) == TILESTATE_REFRESH)
|
||||||
flags |= TILESTATE_REFRESH;
|
flags |= TILESTATE_REFRESH;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} case OTBM_ATTR_ITEM: {
|
}
|
||||||
|
case OTBM_ATTR_ITEM: {
|
||||||
ItemPtr item = Item::createFromOtb(nodeTile->getU16());
|
ItemPtr item = Item::createFromOtb(nodeTile->getU16());
|
||||||
if (!item) {
|
if (tile)
|
||||||
g_logger.error(stdext::format("failed to create new item at tile pos %d, %d, %d", px, py, pz));
|
addThing(item, pos, 255);
|
||||||
return false;
|
else if (item->isGround())
|
||||||
}
|
|
||||||
|
|
||||||
if (tile) {
|
|
||||||
tile->addThing(item);
|
|
||||||
} else if (item->isGround()) {
|
|
||||||
ground = item;
|
ground = item;
|
||||||
} else {
|
else
|
||||||
tile = createTile(pos);
|
tile = createTileEx(pos, ground, item);
|
||||||
tile->addThing(ground);
|
break;
|
||||||
tile->addThing(item);
|
|
||||||
}
|
|
||||||
} default: {
|
|
||||||
g_logger.error(stdext::format("invalid tile attribute at pos %d, %d, %d", px, py, pz));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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()) {
|
|
||||||
if (nodeItem->getU8() == OTBM_ITEM) {
|
|
||||||
ItemPtr item = Item::createFromOtb(nodeItem->getU16());
|
|
||||||
if (!item) {
|
|
||||||
g_logger.error(stdext::format("failed to create new item at pos %d, %d, %d", px, py, pz));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item->unserializeItemNode(nodeItem)) {
|
|
||||||
if (/* house && */item->isMoveable()) {
|
|
||||||
g_logger.warning(stdext::format("Moveable item found in house: %d at pos %d %d %d", item->getId(),
|
|
||||||
px, py, pz));
|
|
||||||
item = nullptr;
|
|
||||||
} else if (tile) {
|
|
||||||
tile->addThing(item);
|
|
||||||
} else if (item->isGround()) {
|
|
||||||
ground = item;
|
|
||||||
} else {
|
|
||||||
tile = createTile(pos);
|
|
||||||
tile->addThing(ground);
|
|
||||||
tile->addThing(item);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g_logger.error(stdext::format("failed to unserialize item with %d at pos %d %d %d", item->getId(),
|
|
||||||
px, py, pz));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g_logger.error(stdext::format("Unknown item node type %d", type));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tile) {
|
|
||||||
tile = createTile(pos);
|
|
||||||
tile->addThing(ground);
|
|
||||||
}
|
|
||||||
|
|
||||||
tile->setFlags((tileflags_t)flags);
|
|
||||||
} else {
|
|
||||||
g_logger.error(stdext::format("Unknown tile node type %d", type));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const BinaryTreePtr &nodeItem : nodeTile->getChildren()) {
|
||||||
|
if (nodeItem->getU8() != OTBM_ITEM)
|
||||||
|
stdext::throw_exception("invalid item node");
|
||||||
|
|
||||||
|
ItemPtr item = Item::createFromOtb(nodeItem->getU16());
|
||||||
|
item->unserializeItem(nodeItem);
|
||||||
|
if (item->isContainer()) {
|
||||||
|
// This is a temporary way for reading container items.
|
||||||
|
MapContainerPtr mapContainer(new MapContainer);
|
||||||
|
for (const BinaryTreePtr &insideItem : nodeItem->getChildren()) {
|
||||||
|
if (insideItem->getU8() != OTBM_ITEM)
|
||||||
|
stdext::throw_exception("invalid container item node");
|
||||||
|
|
||||||
|
ItemPtr newItem = Item::createFromOtb(insideItem->getU16());
|
||||||
|
newItem->unserializeItem(insideItem);
|
||||||
|
mapContainer->add(newItem);
|
||||||
|
}
|
||||||
|
m_containers.push_back(mapContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (house) {
|
||||||
|
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;
|
||||||
|
} else if (item->isDoor())
|
||||||
|
house->addDoor(item->getDoorId(), pos);
|
||||||
|
} else if (tile)
|
||||||
|
addThing(item, pos, 255);
|
||||||
|
else if (item->isGround())
|
||||||
|
ground = item;
|
||||||
|
else
|
||||||
|
tile = createTileEx(pos, ground, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tile)
|
||||||
|
tile = createTileEx(pos, ground);
|
||||||
|
|
||||||
|
tile->setFlags((tileflags_t)flags);
|
||||||
}
|
}
|
||||||
} else if (mapDataType == OTBM_TOWNS) {
|
} 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) {
|
if (nodeTown->getU8() != OTBM_TOWN)
|
||||||
uint32 townId = nodeTown->getU32();
|
stdext::throw_exception("invalid town node.");
|
||||||
std::string townName = nodeTown->getString();
|
|
||||||
|
|
||||||
Position townCoords(nodeTown->getU16(), nodeTown->getU16(), nodeTown->getU8());
|
uint32 townId = nodeTown->getU32();
|
||||||
} else
|
std::string townName = nodeTown->getString();
|
||||||
return false;
|
Position townCoords(nodeTown->getU16(), nodeTown->getU16(), nodeTown->getU8());
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} 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)
|
||||||
std::string name = nodeWaypoint->getString();
|
stdext::throw_exception("invalid waypoint node.");
|
||||||
Position waypointPos(nodeWaypoint->getU16(), nodeWaypoint->getU16(), nodeWaypoint->getU8());
|
|
||||||
}
|
std::string name = nodeWaypoint->getString();
|
||||||
|
Position waypointPos(nodeWaypoint->getU16(), nodeWaypoint->getU16(), nodeWaypoint->getU8());
|
||||||
|
if (waypointPos.isValid() && !name.empty() && m_waypoints.find(waypointPos) == m_waypoints.end())
|
||||||
|
m_waypoints.insert(std::make_pair(waypointPos, name));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
return false;
|
stdext::throw_exception("Unknown map data node");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Load house & spawns.
|
g_logger.debug("OTBM read successfully.");
|
||||||
return true;
|
fin->close();
|
||||||
|
/// TODO read XML Stuff (houses & spawns).
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::saveOtbm(const std::string &fileName)
|
||||||
|
{
|
||||||
|
// TODO: Continue sleepy work.
|
||||||
|
#if 0
|
||||||
|
/// TODO: Use binary trees for this
|
||||||
|
FileStreamPtr fin = g_resources.openFile(fileName);
|
||||||
|
if(!fin)
|
||||||
|
stdext::throw_exception(stdext::format("failed to open file '%s'", fileName));
|
||||||
|
|
||||||
|
std::string dir;
|
||||||
|
if (fileName.find_last_of('/') <= 0)
|
||||||
|
dir = g_resources.getWorkDir();
|
||||||
|
else
|
||||||
|
dir = fileName.substr(0, fileName.find_last_of('/'));
|
||||||
|
|
||||||
|
if (m_houseFile.empty())
|
||||||
|
m_houseFile = "houses.xml";
|
||||||
|
if (m_spawnFile.empty())
|
||||||
|
m_spawnFile = "spawns.xml";
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (!m_houses->save(dir + "/" + m_houseFile))
|
||||||
|
;
|
||||||
|
if (!m_spawns->save(dir + "/" + m_spawnFile))
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32 ver;
|
||||||
|
if (g_things.getOtbMajorVersion() < 2)
|
||||||
|
ver =0;
|
||||||
|
else if (g_things.getOtbMajorVersion() < 10)
|
||||||
|
ver = 1;
|
||||||
|
else
|
||||||
|
ver = 2;
|
||||||
|
|
||||||
|
fin->addU32(0x00); // file version
|
||||||
|
{
|
||||||
|
fin->startNode(0x00); // root
|
||||||
|
fin->addU32(ver);
|
||||||
|
fin->addU16(m_width); // some random width.
|
||||||
|
fin->addU16(m_height); // some random height.
|
||||||
|
|
||||||
|
fin->addU32(g_things.getOtbMajorVersion());
|
||||||
|
fin->addU32(g_things.getOtbMinorVersion());
|
||||||
|
|
||||||
|
fin->startNode(OTBM_MAP_DATA); // map data node
|
||||||
|
{
|
||||||
|
// own description.
|
||||||
|
fin->addU8(OTBM_ATTR_DESCRIPTION);
|
||||||
|
fin->addString(m_description);
|
||||||
|
|
||||||
|
// special one
|
||||||
|
fin->addU8(OTBM_ATTR_DESCRIPTION);
|
||||||
|
fin->addString(stdext::format("Saved with %s v%d", g_app.getName(), stdext::unsafe_cast<int>(g_app.getVersion())));
|
||||||
|
|
||||||
|
// spawn file.
|
||||||
|
fin->addU8(OTBM_ATTR_SPAWN_FILE);
|
||||||
|
fin->addString(m_spawnFile);
|
||||||
|
|
||||||
|
// house file.
|
||||||
|
if (ver > 1) {
|
||||||
|
fin->addU8(OTBM_ATTR_HOUSE_FILE);
|
||||||
|
fin->addString(m_houseFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
Position pos(-1, -1, -1);
|
||||||
|
Boolean<true> first;
|
||||||
|
for (auto& pair : m_tiles) {
|
||||||
|
TilePtr tile = pair.second;
|
||||||
|
if(!tile || tile->isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Position tilePos = pair.first;
|
||||||
|
if (tilePos.x < pos.x || tilePos.x >= pos.x + 256 ||
|
||||||
|
tilePos.y < pos.y || tilePos.y >= pos.y + 256 ||
|
||||||
|
tilePos.z != pos.z) {
|
||||||
|
if (!first)
|
||||||
|
fin->endNode();
|
||||||
|
|
||||||
|
pos.x = tilePos.x & 0xFF00;
|
||||||
|
pos.y = tilePos.y & 0xFF00;
|
||||||
|
pos.z = tilePos.z;
|
||||||
|
fin->addU16(pos.x);
|
||||||
|
fin->addU16(pos.y);
|
||||||
|
fin->addU8(pos.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: hOUSES.
|
||||||
|
fin->startNode(OTBM_TILE);
|
||||||
|
fin->addU8(tilePos.x);
|
||||||
|
fin->addU8(tilePos.y);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// TODO: hOUSES again.
|
||||||
|
if (is house tile)
|
||||||
|
add u32 house id...;
|
||||||
|
#endif
|
||||||
|
if (tile->flags()) {
|
||||||
|
fin->addU8(OTBM_ATTR_TILE_FLAGS);
|
||||||
|
fin->addU32(tile->flags());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::loadOtcm(const std::string& fileName)
|
bool Map::loadOtcm(const std::string& fileName)
|
||||||
|
@ -300,7 +402,7 @@ bool Map::loadOtcm(const std::string& fileName)
|
||||||
fin->getString(); // world name
|
fin->getString(); // world name
|
||||||
|
|
||||||
if(datSignature != g_things.getDatSignature())
|
if(datSignature != g_things.getDatSignature())
|
||||||
g_logger.warning("otcm map loaded is was created with a different dat signature");
|
g_logger.warning("otcm map loaded was created with a different dat signature");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -417,6 +519,11 @@ void Map::clean()
|
||||||
{
|
{
|
||||||
cleanDynamicThings();
|
cleanDynamicThings();
|
||||||
m_tiles.clear();
|
m_tiles.clear();
|
||||||
|
m_waypoints.clear();
|
||||||
|
|
||||||
|
// This is a fix to a segfault on exit.
|
||||||
|
m_towns.clear();
|
||||||
|
m_houses.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::cleanDynamicThings()
|
void Map::cleanDynamicThings()
|
||||||
|
@ -538,6 +645,17 @@ bool Map::removeThingByPos(const Position& pos, int stackPos)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... Items>
|
||||||
|
TilePtr Map::createTileEx(const Position& pos, const Items&... items)
|
||||||
|
{
|
||||||
|
TilePtr tile = getOrCreateTile(pos);
|
||||||
|
auto vec = {items...};
|
||||||
|
for (auto it : vec)
|
||||||
|
addThing(it, pos, 255);
|
||||||
|
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
|
|
||||||
TilePtr Map::createTile(const Position& pos)
|
TilePtr Map::createTile(const Position& pos)
|
||||||
{
|
{
|
||||||
TilePtr tile = TilePtr(new Tile(pos));
|
TilePtr tile = TilePtr(new Tile(pos));
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#define MAP_H
|
#define MAP_H
|
||||||
|
|
||||||
#include "creature.h"
|
#include "creature.h"
|
||||||
|
#include "houses.h"
|
||||||
|
#include "towns.h"
|
||||||
#include "animatedtext.h"
|
#include "animatedtext.h"
|
||||||
#include <framework/core/clock.h>
|
#include <framework/core/clock.h>
|
||||||
|
|
||||||
|
@ -42,7 +44,7 @@ enum OTBM_AttrTypes_t
|
||||||
OTBM_ATTR_SPAWN_FILE = 11,
|
OTBM_ATTR_SPAWN_FILE = 11,
|
||||||
OTBM_ATTR_RUNE_CHARGES = 12,
|
OTBM_ATTR_RUNE_CHARGES = 12,
|
||||||
OTBM_ATTR_HOUSE_FILE = 13,
|
OTBM_ATTR_HOUSE_FILE = 13,
|
||||||
OTBM_ATTR_HPPOUSEDOORID = 14,
|
OTBM_ATTR_HOUSEDOORID = 14,
|
||||||
OTBM_ATTR_COUNT = 15,
|
OTBM_ATTR_COUNT = 15,
|
||||||
OTBM_ATTR_DURATION = 16,
|
OTBM_ATTR_DURATION = 16,
|
||||||
OTBM_ATTR_DECAYING_STATE = 17,
|
OTBM_ATTR_DECAYING_STATE = 17,
|
||||||
|
@ -77,9 +79,26 @@ enum OTBM_NodeTypes_t
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OTCM_SIGNATURE = 0x4D43544F,
|
OTCM_SIGNATURE = 0x4D43544F,
|
||||||
OTCM_VERSION = 1,
|
OTCM_VERSION = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Temporary way for reading container items
|
||||||
|
struct MapContainer {
|
||||||
|
private:
|
||||||
|
std::vector<ItemPtr> m_items;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void add(const ItemPtr& item) { m_items.push_back(item); }
|
||||||
|
ItemPtr operator[](uint idx) { return getItem(idx); }
|
||||||
|
ItemPtr getItem(int index) {
|
||||||
|
if (index < 0 || index > (int)m_items.size())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return m_items[index];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
typedef std::shared_ptr<MapContainer> MapContainerPtr;
|
||||||
|
|
||||||
//@bindsingleton g_map
|
//@bindsingleton g_map
|
||||||
class Map
|
class Map
|
||||||
{
|
{
|
||||||
|
@ -93,8 +112,8 @@ public:
|
||||||
bool loadOtcm(const std::string& fileName);
|
bool loadOtcm(const std::string& fileName);
|
||||||
void saveOtcm(const std::string& fileName);
|
void saveOtcm(const std::string& fileName);
|
||||||
|
|
||||||
bool loadOtbm(const std::string& fileName);
|
void loadOtbm(const std::string& fileName);
|
||||||
//void saveOtbm(const std::string& fileName);
|
void saveOtbm(const std::string& fileName);
|
||||||
|
|
||||||
void clean();
|
void clean();
|
||||||
void cleanDynamicThings();
|
void cleanDynamicThings();
|
||||||
|
@ -106,6 +125,8 @@ public:
|
||||||
bool removeThingByPos(const Position& pos, int stackPos);
|
bool removeThingByPos(const Position& pos, int stackPos);
|
||||||
|
|
||||||
// tile related
|
// tile related
|
||||||
|
template <typename... Items>
|
||||||
|
TilePtr createTileEx(const Position& pos, const Items&... items);
|
||||||
TilePtr createTile(const Position& pos);
|
TilePtr createTile(const Position& pos);
|
||||||
const TilePtr& getTile(const Position& pos);
|
const TilePtr& getTile(const Position& pos);
|
||||||
TilePtr getOrCreateTile(const Position& pos);
|
TilePtr getOrCreateTile(const Position& pos);
|
||||||
|
@ -120,6 +141,10 @@ 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 related
|
||||||
|
TownPtr getTown(uint32 tid) { return m_towns.getTown(tid); }
|
||||||
|
HousePtr getHouse(uint32 hid) { return m_houses.getHouse(hid); }
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -146,11 +171,18 @@ private:
|
||||||
std::vector<AnimatedTextPtr> m_animatedTexts;
|
std::vector<AnimatedTextPtr> m_animatedTexts;
|
||||||
std::vector<StaticTextPtr> m_staticTexts;
|
std::vector<StaticTextPtr> m_staticTexts;
|
||||||
std::vector<MapViewPtr> m_mapViews;
|
std::vector<MapViewPtr> m_mapViews;
|
||||||
|
std::unordered_map<Position, std::string, PositionHasher> m_waypoints;
|
||||||
|
std::vector<MapContainerPtr> m_containers;
|
||||||
|
|
||||||
Light m_light;
|
Light m_light;
|
||||||
Position m_centralPosition;
|
Position m_centralPosition;
|
||||||
|
|
||||||
std::string m_description, m_spawnFile, m_houseFile;
|
std::string m_description, m_spawnFile, m_houseFile;
|
||||||
|
|
||||||
|
Houses m_houses;
|
||||||
|
Towns m_towns;
|
||||||
|
|
||||||
|
uint16 m_width, m_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Map g_map;
|
extern Map g_map;
|
||||||
|
|
|
@ -88,149 +88,89 @@ bool ThingTypeManager::loadDat(const std::string& file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThingTypeManager::loadOtb(const std::string& file)
|
void ThingTypeManager::loadOtb(const std::string& file)
|
||||||
{
|
{
|
||||||
try {
|
FileStreamPtr fin = g_resources.openFile(file);
|
||||||
FileStreamPtr fin = g_resources.openFile(file);
|
|
||||||
|
|
||||||
uint signature = fin->getU32();
|
uint signature = fin->getU32();
|
||||||
if(signature != 0)
|
if(signature != 0)
|
||||||
stdext::throw_exception("invalid otb file");
|
stdext::throw_exception("invalid otb file");
|
||||||
|
|
||||||
BinaryTreePtr root = fin->getBinaryTree();
|
BinaryTreePtr root = fin->getBinaryTree();
|
||||||
|
|
||||||
signature = root->getU32();
|
signature = root->getU32();
|
||||||
if(signature != 0)
|
if(signature != 0)
|
||||||
stdext::throw_exception("invalid otb file");
|
stdext::throw_exception("invalid otb file");
|
||||||
|
|
||||||
root->getU32(); // flags
|
root->getU32(); // flags
|
||||||
|
|
||||||
m_otbMajorVersion = root->getU32();
|
m_otbMajorVersion = root->getU32();
|
||||||
m_otbMinorVersion = root->getU32();
|
m_otbMinorVersion = root->getU32();
|
||||||
root->getU32(); // build number
|
root->getU32(); // build number
|
||||||
root->skip(128); // description
|
root->skip(128); // description
|
||||||
|
|
||||||
for(const BinaryTreePtr& node : root->getChildren()) {
|
m_otbTypes.resize(root->getChildren().size(), m_nullOtbType);
|
||||||
ThingTypeOtbPtr otbType(new ThingTypeOtb);
|
for(const BinaryTreePtr& node : root->getChildren()) {
|
||||||
otbType->unserialize(node);
|
ThingTypeOtbPtr otbType(new ThingTypeOtb);
|
||||||
}
|
otbType->unserialize(node);
|
||||||
|
addOtbType(otbType);
|
||||||
m_otbLoaded = true;
|
|
||||||
return true;
|
|
||||||
} catch(stdext::exception& e) {
|
|
||||||
g_logger.error(stdext::format("failed to load otb '%s': %s", file, e.what()));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_otbLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThingTypeManager::loadXml(const std::string& file)
|
void ThingTypeManager::loadXml(const std::string& file)
|
||||||
{
|
{
|
||||||
/*
|
TiXmlDocument doc(file.c_str());
|
||||||
try {
|
if (!doc.LoadFile())
|
||||||
TiXmlDocument doc(file.c_str());
|
stdext::throw_exception(stdext::format("failed to load xml '%s'", file));
|
||||||
if (!doc.LoadFile()) {
|
|
||||||
g_logger.error(stdext::format("failed to load xml '%s'", file));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TiXmlElement* root = doc.FirstChildElement();
|
TiXmlElement* root = doc.FirstChildElement();
|
||||||
if (!root) {
|
if (!root || root->ValueTStr() != "items")
|
||||||
g_logger.error("invalid xml root");
|
stdext::throw_exception("invalid root tag name");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root->ValueTStr() != "items") {
|
ThingTypeOtbPtr otbType = nullptr;
|
||||||
g_logger.error("invalid xml tag name, should be 'items'");
|
for (TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) {
|
||||||
return false;
|
if (element->ValueTStr() != "item")
|
||||||
}
|
continue;
|
||||||
|
|
||||||
for (TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) {
|
std::string name = element->Attribute("id");
|
||||||
if (element->ValueTStr() != "item")
|
if (name.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::string name = element->Attribute("id");
|
uint16 id = stdext::unsafe_cast<uint16>(element->Attribute("id"));
|
||||||
if (name.empty())
|
if (!(otbType = getOtbType(id))) {
|
||||||
continue;
|
// try reading fromId toId
|
||||||
|
uint16 from = stdext::unsafe_cast<uint16>(element->Attribute("fromId"));
|
||||||
|
uint16 to = stdext::unsafe_cast<uint16>(element->Attribute("toid"));
|
||||||
|
|
||||||
uint16 id = stdext::unsafe_cast<uint16>(element->Attribute("id"));
|
for (uint16 __id = from; __id < to; ++__id) {
|
||||||
uint16 idEx = 0;
|
if (!(otbType = getOtbType(__id)))
|
||||||
if (!id) {
|
|
||||||
bool found = false;
|
|
||||||
// fallback into reading fromid and toid
|
|
||||||
uint16 fromid = stdext::unsafe_cast<uint16>(element->Attribute("fromid"));
|
|
||||||
uint16 toid = stdext::unsafe_cast<uint16>(element->Attribute("toid"));
|
|
||||||
ThingTypeOtbPtr iType;
|
|
||||||
for (int __id = fromid; __id < toid; ++__id) {
|
|
||||||
if (!(iType = getType(__id)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
iType->name = name;
|
|
||||||
idEx = iType->id == fromid ? fromid : toid;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
otbType->setHasRange();
|
||||||
|
otbType->setFromServerId(from);
|
||||||
|
otbType->setToServerId(to);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThingTypeOtbPtr otbType = getType(id);
|
// perform last check
|
||||||
if (!otbType) {
|
if (!otbType) {
|
||||||
otbType = ThingTypeOtbPtr(new ItemData);
|
stdext::throw_exception(stdext::format("failed to find item with server id %d - tried reading fromid to id",
|
||||||
otbType->id = idEx ? idEx : id;
|
id));
|
||||||
otbType->name = name;
|
|
||||||
addType(otbType->id, otbType);
|
|
||||||
}
|
|
||||||
|
|
||||||
otbType->name = name;
|
|
||||||
|
|
||||||
for (TiXmlElement *attr = element->FirstChildElement(); attr; attr = attr->NextSiblingElement()) {
|
|
||||||
if (attr->ValueTStr() != "attribute")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
std::string key = attr->Attribute("key");
|
|
||||||
std::string value = attr->Attribute("value");
|
|
||||||
if (key == "type") {
|
|
||||||
if (value == "magicfield")
|
|
||||||
otbType->category = IsMagicField;
|
|
||||||
else if (value == "key")
|
|
||||||
otbType->category = IsKey;
|
|
||||||
else if (value == "depot")
|
|
||||||
otbType->isDepot = true;
|
|
||||||
else if (value == "teleport")
|
|
||||||
otbType->category = IsTeleport;
|
|
||||||
else if (value == "bed")
|
|
||||||
otbType->isBed = true;
|
|
||||||
else if (value == "door")
|
|
||||||
otbType->category = IsDoor;
|
|
||||||
} else if (key == "name") {
|
|
||||||
otbType->name = value;
|
|
||||||
} else if (key == "description") {
|
|
||||||
otbType->description = value;
|
|
||||||
} else if (key == "weight") {
|
|
||||||
otbType->weight = stdext::unsafe_cast<double>(stdext::unsafe_cast<double>(value) / 100.f);
|
|
||||||
} else if (key == "containerSize") {
|
|
||||||
int containerSize = stdext::unsafe_cast<int>(value);
|
|
||||||
if (containerSize)
|
|
||||||
otbType->containerSize = containerSize;
|
|
||||||
otbType->category = IsContainer;
|
|
||||||
} else if (key == "writeable") {
|
|
||||||
if (!value.empty())
|
|
||||||
otbType->category = IsWritable;
|
|
||||||
} else if (key == "maxTextLen") {
|
|
||||||
otbType->maxTextLength = stdext::unsafe_cast<int>(value);
|
|
||||||
} else if (key == "charges") {
|
|
||||||
otbType->charges = stdext::unsafe_cast<int>(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.Clear();
|
for (TiXmlElement *attr = element->FirstChildElement(); attr; attr = attr->NextSiblingElement()) {
|
||||||
} catch(stdext::exception& e) {
|
if (attr->ValueTStr() != "attribute")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
otbType->unserializeXML(attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
*/
|
doc.Clear();
|
||||||
return false;
|
m_xmlLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThingTypeManager::addOtbType(const ThingTypeOtbPtr& otbType)
|
void ThingTypeManager::addOtbType(const ThingTypeOtbPtr& otbType)
|
||||||
|
|
|
@ -36,8 +36,8 @@ public:
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
bool loadDat(const std::string& file);
|
bool loadDat(const std::string& file);
|
||||||
bool loadOtb(const std::string& file);
|
void loadOtb(const std::string& file);
|
||||||
bool loadXml(const std::string& file);
|
void loadXml(const std::string& file);
|
||||||
|
|
||||||
void addOtbType(const ThingTypeOtbPtr& otbType);
|
void addOtbType(const ThingTypeOtbPtr& otbType);
|
||||||
const ThingTypeOtbPtr& findOtbForClientId(uint16 id);
|
const ThingTypeOtbPtr& findOtbForClientId(uint16 id);
|
||||||
|
|
|
@ -62,3 +62,14 @@ void ThingTypeOtb::unserialize(const BinaryTreePtr& node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThingTypeOtb::unserializeXML(const TiXmlElement* elem)
|
||||||
|
{
|
||||||
|
std::string key = elem->Attribute("key");
|
||||||
|
std::string value = elem->Attribute("value");
|
||||||
|
|
||||||
|
if (key == "name")
|
||||||
|
setName(value);
|
||||||
|
else if (key == "description")
|
||||||
|
setDesc(value);
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include <framework/core/declarations.h>
|
#include <framework/core/declarations.h>
|
||||||
#include <framework/luaengine/luaobject.h>
|
#include <framework/luaengine/luaobject.h>
|
||||||
|
#include <framework/xml/tinyxml.h>
|
||||||
|
|
||||||
|
|
||||||
enum OtbCategory {
|
enum OtbCategory {
|
||||||
OtbInvalidCateogry = 0,
|
OtbInvalidCateogry = 0,
|
||||||
|
@ -85,19 +87,30 @@ public:
|
||||||
ThingTypeOtb();
|
ThingTypeOtb();
|
||||||
|
|
||||||
void unserialize(const BinaryTreePtr& node);
|
void unserialize(const BinaryTreePtr& node);
|
||||||
void unserializeXML();
|
void unserializeXML(const TiXmlElement* elem);
|
||||||
|
|
||||||
uint16 getServerId() { return m_serverId; }
|
uint16 getServerId() { return m_serverId; }
|
||||||
uint16 getClientId() { return m_clientId; }
|
uint16 getClientId() { return m_clientId; }
|
||||||
OtbCategory getCategory() { return m_category; }
|
OtbCategory getCategory() { return m_category; }
|
||||||
|
|
||||||
bool isNull() { return m_null; }
|
bool isNull() { return m_null; }
|
||||||
|
bool hasRange() { return m_hasRange; }
|
||||||
|
|
||||||
|
void setHasRange() { m_hasRange = true; }
|
||||||
|
void setFromServerId(uint16 from) { m_fromId = from; }
|
||||||
|
void setToServerId(uint16 to) { m_toId = to; }
|
||||||
|
void setName(const std::string& name) { m_name = name; }
|
||||||
|
void setDesc(const std::string& desc) { m_desc = desc; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16 m_serverId;
|
uint16 m_serverId;
|
||||||
uint16 m_clientId;
|
uint16 m_clientId;
|
||||||
|
uint16 m_fromId, m_toId;
|
||||||
|
|
||||||
|
std::string m_name, m_desc;
|
||||||
OtbCategory m_category;
|
OtbCategory m_category;
|
||||||
Boolean<true> m_null;
|
Boolean<true> m_null;
|
||||||
|
Boolean<false> m_hasRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,7 +33,7 @@ enum tileflags_t
|
||||||
TILESTATE_TRASHED = 1 << 1,
|
TILESTATE_TRASHED = 1 << 1,
|
||||||
TILESTATE_OPTIONALZONE = 1 << 2,
|
TILESTATE_OPTIONALZONE = 1 << 2,
|
||||||
TILESTATE_NOLOGOUT = 1 << 3,
|
TILESTATE_NOLOGOUT = 1 << 3,
|
||||||
TILESTATE_HPPARDCOREZONE = 1 << 4,
|
TILESTATE_HARDCOREZONE = 1 << 4,
|
||||||
TILESTATE_REFRESH = 1 << 5,
|
TILESTATE_REFRESH = 1 << 5,
|
||||||
|
|
||||||
// internal usage
|
// internal usage
|
||||||
|
@ -100,6 +100,7 @@ public:
|
||||||
|
|
||||||
TilePtr asTile() { return std::static_pointer_cast<Tile>(shared_from_this()); }
|
TilePtr asTile() { return std::static_pointer_cast<Tile>(shared_from_this()); }
|
||||||
void setFlags(tileflags_t flags) { m_flags |= (uint32)flags; }
|
void setFlags(tileflags_t flags) { m_flags |= (uint32)flags; }
|
||||||
|
uint32 flags() { return m_flags; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update();
|
void update();
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "towns.h"
|
||||||
|
|
||||||
|
Towns g_towns;
|
||||||
|
|
||||||
|
Town::Town(uint32 tid, const std::string& name, const Position& pos)
|
||||||
|
: m_id(tid), m_name(name)
|
||||||
|
{
|
||||||
|
if (pos.isValid())
|
||||||
|
m_pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Towns::addTown(const TownPtr &town)
|
||||||
|
{
|
||||||
|
if (findTown(town->getId()) == m_towns.end())
|
||||||
|
m_towns.push_back(town);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Towns::removeTown(uint32 townId)
|
||||||
|
{
|
||||||
|
auto it = findTown(townId);
|
||||||
|
if (it != m_towns.end())
|
||||||
|
m_towns.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
TownPtr Towns::getTown(uint32 townId)
|
||||||
|
{
|
||||||
|
auto it = findTown(townId);
|
||||||
|
if (it != m_towns.end())
|
||||||
|
return *it;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
TownList::iterator Towns::findTown(uint32 townId)
|
||||||
|
{
|
||||||
|
return std::find_if(m_towns.begin(), m_towns.end(),
|
||||||
|
[=] (const TownPtr& town) -> bool { return town->getId() == townId; });
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TOWNS_H
|
||||||
|
#define TOWNS_H
|
||||||
|
|
||||||
|
#include "declarations.h"
|
||||||
|
#include <framework/luaengine/luaobject.h>
|
||||||
|
|
||||||
|
|
||||||
|
class Town : public LuaObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Town() { }
|
||||||
|
Town(uint32 tid, const std::string& name, const Position& pos=Position());
|
||||||
|
|
||||||
|
void setId(uint32 tid) { m_id = tid; }
|
||||||
|
void setName(const std::string& name) { m_name = name; }
|
||||||
|
void setPos(const Position& pos) { m_pos = pos; }
|
||||||
|
|
||||||
|
uint32 getId() { return m_id; }
|
||||||
|
std::string getName() { return m_name; }
|
||||||
|
Position getPos() { return m_pos; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 m_id;
|
||||||
|
std::string m_name;
|
||||||
|
Position m_pos; // temple pos
|
||||||
|
};
|
||||||
|
|
||||||
|
class Towns
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void addTown(const TownPtr &town);
|
||||||
|
void removeTown(uint32 townId);
|
||||||
|
|
||||||
|
TownPtr getTown(uint32 townId);
|
||||||
|
TownList getTowns() { return m_towns; }
|
||||||
|
|
||||||
|
// Fix to segfault on exit
|
||||||
|
void clear() { m_towns.clear(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
TownList m_towns;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TownList::iterator findTown(uint32 townId);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue