Fixed bug with adding Vip from console or map, who is already on viplist.
This commit is contained in:
parent
c8d9833444
commit
8f492f7e06
4
init.lua
4
init.lua
|
@ -45,7 +45,7 @@ if g_resources.fileExists("/otclientrc.lua") then
|
||||||
dofile("/otclientrc.lua")
|
dofile("/otclientrc.lua")
|
||||||
end
|
end
|
||||||
|
|
||||||
--g_things.loadOtb("/items.otb")
|
g_things.loadOtb("/items.otb")
|
||||||
--g_map.loadOtbm("/forgotten.otbm")
|
g_map.loadOtbm("/forgotten.otbm")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,3 +31,10 @@ function Player:isPartySharedExperienceActive()
|
||||||
shield == ShieldBlueNoSharedExpBlink or
|
shield == ShieldBlueNoSharedExpBlink or
|
||||||
shield == ShieldBlueNoSharedExp)
|
shield == ShieldBlueNoSharedExp)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Player:hasVip(creatureName)
|
||||||
|
for id, vip in pairs(g_game.getVips()) do
|
||||||
|
if (vip[1] == creatureName) then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
|
@ -403,7 +403,9 @@ function Console.popupMenu(mousePos, mouseButton, creatureName, text)
|
||||||
if creatureName then
|
if creatureName then
|
||||||
if creatureName ~= g_game.getCharacterName() then
|
if creatureName ~= g_game.getCharacterName() then
|
||||||
menu:addOption(tr('Message to ' .. creatureName), function () g_game.openPrivateChannel(creatureName) end)
|
menu:addOption(tr('Message to ' .. creatureName), function () g_game.openPrivateChannel(creatureName) end)
|
||||||
menu:addOption(tr('Add to VIP list'), function () g_game.addVip(creatureName) end) --TODO not show if creature already in vip
|
if (not Player:hasVip(creatureName)) then
|
||||||
|
menu:addOption(tr('Add to VIP list'), function () g_game.addVip(creatureName) end)
|
||||||
|
end
|
||||||
-- TODO ignore creatureName
|
-- TODO ignore creatureName
|
||||||
menu:addSeparator()
|
menu:addSeparator()
|
||||||
end
|
end
|
||||||
|
|
|
@ -263,7 +263,9 @@ function GameInterface.createThingMenu(menuPosition, lookThing, useThing, creatu
|
||||||
menu:addOption(tr('Invite to private chat'), function() g_game.inviteToOwnChannel(creatureName) end)
|
menu:addOption(tr('Invite to private chat'), function() g_game.inviteToOwnChannel(creatureName) end)
|
||||||
menu:addOption(tr('Exclude from private chat'), function() g_game.excludeFromOwnChannel(creatureName) end) -- [TODO] must be removed after message's popup labels been implemented
|
menu:addOption(tr('Exclude from private chat'), function() g_game.excludeFromOwnChannel(creatureName) end) -- [TODO] must be removed after message's popup labels been implemented
|
||||||
end
|
end
|
||||||
|
if (not Player:hasVip(creatureName)) then
|
||||||
menu:addOption(tr('Add to VIP list'), function() g_game.addVip(creatureName) end)
|
menu:addOption(tr('Add to VIP list'), function() g_game.addVip(creatureName) end)
|
||||||
|
end
|
||||||
|
|
||||||
local localPlayerShield = localPlayer:asCreature():getShield()
|
local localPlayerShield = localPlayer:asCreature():getShield()
|
||||||
local creatureShield = creatureThing:getShield()
|
local creatureShield = creatureThing:getShield()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -63,4 +63,8 @@
|
||||||
// boost utilities
|
// boost utilities
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
// tiny XML
|
||||||
|
#define TIXML_USE_STL
|
||||||
|
#include <framework/thirdparty/tinyxml.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -74,6 +74,10 @@ SET(otclient_SOURCES ${otclient_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/thingtypeotb.h
|
${CMAKE_CURRENT_LIST_DIR}/core/thingtypeotb.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/tile.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/tile.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/tile.h
|
${CMAKE_CURRENT_LIST_DIR}/core/tile.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/core/houses.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/core/houses.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/core/towns.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/core/towns.h
|
||||||
|
|
||||||
# lua
|
# lua
|
||||||
${CMAKE_CURRENT_LIST_DIR}/luascript/luavaluecasts.cpp
|
${CMAKE_CURRENT_LIST_DIR}/luascript/luavaluecasts.cpp
|
||||||
|
|
|
@ -43,6 +43,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;
|
||||||
|
@ -60,9 +62,13 @@ 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;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,14 +45,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 +204,71 @@ 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;
|
// Yet another TODO.
|
||||||
while ((attrType = fin->getU8()) != 0)
|
while (in->canRead()) {
|
||||||
readAttr((AttrTypes_t)attrType, fin);
|
uint8 attrType = in->getU8();
|
||||||
|
if (attrType == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
return true;
|
switch ((AttrTypes_t)attrType) {
|
||||||
}
|
|
||||||
|
|
||||||
void Item::readAttr(AttrTypes_t attrType, const BinaryTreePtr &fin)
|
|
||||||
{
|
|
||||||
switch (attrType) {
|
|
||||||
case ATTR_COUNT:
|
case ATTR_COUNT:
|
||||||
setSubType(fin->getU8());
|
setSubType(in->getU8());
|
||||||
|
break;
|
||||||
|
case ATTR_CHARGES:
|
||||||
|
setSubType(in->getU16());
|
||||||
break;
|
break;
|
||||||
case ATTR_ACTION_ID:
|
case ATTR_ACTION_ID:
|
||||||
setActionId(fin->getU16());
|
setActionId(in->getU16());
|
||||||
break;
|
break;
|
||||||
case ATTR_UNIQUE_ID:
|
case ATTR_UNIQUE_ID:
|
||||||
setUniqueId(fin->getU16());
|
setUniqueId(in->getU16());
|
||||||
break;
|
break;
|
||||||
case ATTR_NAME:
|
case ATTR_NAME:
|
||||||
setName(fin->getString());
|
setName(in->getString());
|
||||||
break;
|
break;
|
||||||
case ATTR_ARTICLE:
|
case ATTR_ARTICLE: // ?
|
||||||
fin->getString();
|
case ATTR_WRITTENBY:
|
||||||
case ATTR_ATTACK: // \/ not needed.
|
case ATTR_DESC:
|
||||||
|
in->getString();
|
||||||
|
break;
|
||||||
|
case ATTR_ATTACK:
|
||||||
case ATTR_EXTRAATTACK:
|
case ATTR_EXTRAATTACK:
|
||||||
case ATTR_DEFENSE:
|
case ATTR_DEFENSE:
|
||||||
case ATTR_EXTRADEFENSE:
|
case ATTR_EXTRADEFENSE:
|
||||||
case ATTR_ARMOR:
|
case ATTR_ARMOR:
|
||||||
case ATTR_ATTACKSPEED:
|
case ATTR_ATTACKSPEED:
|
||||||
case ATTR_HPPITCHANCE:
|
case ATTR_HITCHANCE:
|
||||||
case ATTR_DURATION:
|
case ATTR_DURATION:
|
||||||
fin->getU32();
|
case ATTR_WRITTENDATE:
|
||||||
|
case ATTR_SLEEPERGUID:
|
||||||
|
case ATTR_SLEEPSTART:
|
||||||
|
case ATTR_CONTAINER_ITEMS:
|
||||||
|
case ATTR_ATTRIBUTE_MAP:
|
||||||
|
in->skip(4);
|
||||||
break;
|
break;
|
||||||
case ATTR_SCRIPTPROTECTED:
|
case ATTR_SCRIPTPROTECTED:
|
||||||
case ATTR_DUALWIELD:
|
case ATTR_DUALWIELD:
|
||||||
case ATTR_DECAYING_STATE:
|
case ATTR_DECAYING_STATE:
|
||||||
case ATTR_HPPOUSEDOORID:
|
case ATTR_HOUSEDOORID:
|
||||||
fin->getU8();
|
case ATTR_RUNE_CHARGES:
|
||||||
|
in->skip(1);
|
||||||
break;
|
break;
|
||||||
case ATTR_TEXT:
|
case ATTR_TEXT:
|
||||||
setText(fin->getString());
|
setText(in->getString());
|
||||||
break;
|
break;
|
||||||
case ATTR_WRITTENDATE:
|
case ATTR_DEPOT_ID:
|
||||||
fin->getU32();
|
in->skip(2); // trolol
|
||||||
break;
|
break;
|
||||||
case ATTR_WRITTENBY:
|
case ATTR_TELE_DEST:
|
||||||
fin->getString();
|
{
|
||||||
|
Position pos(in->getU16(), in->getU16(), in->getU8());
|
||||||
break;
|
break;
|
||||||
case ATTR_DESC:
|
}
|
||||||
setDescription(fin->getString());
|
|
||||||
break;
|
|
||||||
case ATTR_RUNE_CHARGES:
|
|
||||||
fin->getU8();
|
|
||||||
break;
|
|
||||||
case ATTR_TELE_DEST: // Teleport should read that.
|
|
||||||
case ATTR_SLEEPERGUID: // Bed should read that.
|
|
||||||
case ATTR_SLEEPSTART:
|
|
||||||
case ATTR_CONTAINER_ITEMS:
|
|
||||||
case ATTR_ATTRIBUTE_MAP:
|
|
||||||
default:
|
default:
|
||||||
break;
|
stdext::throw_exception(stdext::format("invalid item attribute %d", (int)attrType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@
|
||||||
|
|
||||||
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 +37,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 +56,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,
|
||||||
|
@ -100,10 +96,7 @@ public:
|
||||||
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();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "missile.h"
|
#include "missile.h"
|
||||||
#include "statictext.h"
|
#include "statictext.h"
|
||||||
|
#include "houses.h"
|
||||||
|
#include "towns.h"
|
||||||
|
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
#include "mapview.h"
|
#include "mapview.h"
|
||||||
|
@ -59,67 +61,61 @@ 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, bool /*display*/)
|
||||||
{
|
{
|
||||||
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() != 0)
|
||||||
|
stdext::throw_exception("could not read root property!");
|
||||||
|
|
||||||
uint32 headerVersion = root->getU32();
|
uint32 headerVersion = root->getU32();
|
||||||
dump << headerVersion;
|
if (!headerVersion || headerVersion > 3)
|
||||||
if (!headerVersion || headerVersion > 3) {
|
stdext::throw_exception(stdext::format("Unknown OTBM version detected: %u.", headerVersion));
|
||||||
g_logger.error("Unknown OTBM version detected.");
|
|
||||||
return false;
|
uint16 w = root->getU16(), h = root->getU16();
|
||||||
}
|
dump << "Map size: " << w << "x" << h;
|
||||||
|
|
||||||
root->skip(1); // ??
|
|
||||||
uint32 headerMajorItems = root->getU8();
|
uint32 headerMajorItems = root->getU8();
|
||||||
dump << headerMajorItems;
|
if (headerMajorItems < 3)
|
||||||
dump << "major: " << g_things.getOtbMajorVersion();
|
stdext::throw_exception(stdext::format("This map needs to be upgraded. read %d what it's supposed to be: %u",
|
||||||
if (headerMajorItems < 3) {
|
headerMajorItems, g_things.getOtbMajorVersion()));
|
||||||
g_logger.error("This map needs to be upgraded.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
dump << "minor: " << g_things.getOtbMinorVersion();
|
|
||||||
if (headerMinorItems > g_things.getOtbMinorVersion())
|
if (headerMinorItems > g_things.getOtbMinorVersion())
|
||||||
g_logger.warning("This map needs an updated OTB.");
|
g_logger.warning(stdext::format("This map needs an updated OTB. read %d what it's supposed to be: %d",
|
||||||
|
headerMinorItems, g_things.getOtbMinorVersion()));
|
||||||
|
|
||||||
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;
|
Boolean<true> first;
|
||||||
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())
|
if (first) {
|
||||||
m_description += "\n" + tmp;
|
first = false;
|
||||||
else
|
|
||||||
m_description = tmp;
|
m_description = tmp;
|
||||||
|
} else {
|
||||||
|
m_description += "\n" + 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,94 +124,78 @@ 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;
|
TilePtr tile = nullptr;
|
||||||
ItemPtr ground = 0;
|
ItemPtr ground = nullptr;
|
||||||
|
HousePtr house = nullptr;
|
||||||
uint32 flags = 0;
|
uint32 flags = 0;
|
||||||
|
|
||||||
uint16 px = baseX + nodeTile->getU16(), py = baseY + nodeTile->getU16();
|
uint16 px = baseX + nodeTile->getU8(), py = baseY + nodeTile->getU8();
|
||||||
Position pos(px, py, pz);
|
Position pos(px, py, pz);
|
||||||
|
|
||||||
// TODO: Houses.
|
|
||||||
if (type == OTBM_HOUSETILE) {
|
if (type == OTBM_HOUSETILE) {
|
||||||
uint32 hId = nodeTile->getU32();
|
uint32 hId = nodeTile->getU32();
|
||||||
|
|
||||||
tile = createTile(pos);
|
tile = createTile(pos);
|
||||||
// TODO: add it to house.
|
if (!(house = g_houses.getHouse(hId)))
|
||||||
|
house = HousePtr(new House(hId));
|
||||||
|
house->setTile(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 tileAttr;
|
|
||||||
while (nodeTile->canRead()) {
|
while (nodeTile->canRead()) {
|
||||||
tileAttr = nodeTile->getU8();
|
uint8 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;
|
|
||||||
} case OTBM_ATTR_ITEM: {
|
|
||||||
ItemPtr item = Item::createFromOtb(nodeTile->getU16());
|
|
||||||
if (!item) {
|
|
||||||
g_logger.error(stdext::format("failed to create new item at tile pos %d, %d, %d", px, py, pz));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile) {
|
break;
|
||||||
|
}
|
||||||
|
case OTBM_ATTR_ITEM: {
|
||||||
|
ItemPtr item = Item::createFromOtb(nodeTile->getU16());
|
||||||
|
if (tile)
|
||||||
tile->addThing(item);
|
tile->addThing(item);
|
||||||
} else if (item->isGround()) {
|
else if (item->isGround())
|
||||||
ground = item;
|
ground = item;
|
||||||
} else {
|
else {
|
||||||
tile = createTile(pos);
|
tile = createTile(pos, ground);
|
||||||
tile->addThing(ground);
|
|
||||||
tile->addThing(item);
|
tile->addThing(item);
|
||||||
}
|
}
|
||||||
} default: {
|
break;
|
||||||
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()) {
|
for (const BinaryTreePtr &nodeItem : nodeTile->getChildren()) {
|
||||||
if (nodeItem->getU8() == OTBM_ITEM) {
|
if (nodeItem->getU8() == OTBM_ITEM) {
|
||||||
ItemPtr item = Item::createFromOtb(nodeItem->getU16());
|
ItemPtr item = Item::createFromOtb(nodeItem->getU16());
|
||||||
if (!item) {
|
item->unserializeItem(nodeItem);
|
||||||
g_logger.error(stdext::format("failed to create new item at pos %d, %d, %d", px, py, pz));
|
if (house && item->isMoveable()) {
|
||||||
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(),
|
g_logger.warning(stdext::format("Moveable item found in house: %d at pos %d %d %d", item->getId(),
|
||||||
px, py, pz));
|
px, py, pz));
|
||||||
item = nullptr;
|
item = nullptr;
|
||||||
|
@ -224,55 +204,50 @@ bool Map::loadOtbm(const std::string& fileName)
|
||||||
} else if (item->isGround()) {
|
} else if (item->isGround()) {
|
||||||
ground = item;
|
ground = item;
|
||||||
} else {
|
} else {
|
||||||
tile = createTile(pos);
|
tile = createTile(pos, ground);
|
||||||
tile->addThing(ground);
|
|
||||||
tile->addThing(item);
|
tile->addThing(item);
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
g_logger.error(stdext::format("failed to unserialize item with %d at pos %d %d %d", item->getId(),
|
stdext::throw_exception("Unknown item node");
|
||||||
px, py, pz));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g_logger.error(stdext::format("Unknown item node type %d", type));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tile) {
|
if (!tile)
|
||||||
tile = createTile(pos);
|
tile = createTile(pos, ground);
|
||||||
tile->addThing(ground);
|
|
||||||
}
|
|
||||||
|
|
||||||
tile->setFlags((tileflags_t)flags);
|
tile->setFlags((tileflags_t)flags);
|
||||||
} else {
|
} else
|
||||||
g_logger.error(stdext::format("Unknown tile node type %d", type));
|
stdext::throw_exception(stdext::format("Unknown tile node type %d", type));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} 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();
|
uint32 townId = nodeTown->getU32();
|
||||||
std::string townName = nodeTown->getString();
|
std::string townName = nodeTown->getString();
|
||||||
|
|
||||||
Position townCoords(nodeTown->getU16(), nodeTown->getU16(), nodeTown->getU8());
|
Position townCoords(nodeTown->getU16(), nodeTown->getU16(), nodeTown->getU8());
|
||||||
|
if (!(town = g_towns.getTown(townId)))
|
||||||
|
town = TownPtr(new Town(townId, townName, townCoords));
|
||||||
} else
|
} else
|
||||||
return false;
|
stdext::throw_exception("invalid town node");
|
||||||
}
|
}
|
||||||
} 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();
|
std::string name = nodeWaypoint->getString();
|
||||||
Position waypointPos(nodeWaypoint->getU16(), nodeWaypoint->getU16(), nodeWaypoint->getU8());
|
Position waypointPos(nodeWaypoint->getU16(), nodeWaypoint->getU16(), nodeWaypoint->getU8());
|
||||||
}
|
if (waypointPos.isValid() && !name.empty())
|
||||||
|
m_waypoints.insert(std::make_pair(waypointPos, name));
|
||||||
|
|
||||||
|
} else
|
||||||
|
stdext::throw_exception("invalid waypoint node");
|
||||||
}
|
}
|
||||||
} 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).
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::loadOtcm(const std::string& fileName)
|
bool Map::loadOtcm(const std::string& fileName)
|
||||||
|
@ -300,7 +275,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 +392,7 @@ void Map::clean()
|
||||||
{
|
{
|
||||||
cleanDynamicThings();
|
cleanDynamicThings();
|
||||||
m_tiles.clear();
|
m_tiles.clear();
|
||||||
|
m_waypoints.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::cleanDynamicThings()
|
void Map::cleanDynamicThings()
|
||||||
|
@ -538,9 +514,12 @@ bool Map::removeThingByPos(const Position& pos, int stackPos)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TilePtr Map::createTile(const Position& pos)
|
TilePtr Map::createTile(const Position& pos, const ItemPtr &g)
|
||||||
{
|
{
|
||||||
TilePtr tile = TilePtr(new Tile(pos));
|
TilePtr tile = TilePtr(new Tile(pos));
|
||||||
|
if (g)
|
||||||
|
tile->addThing(g);
|
||||||
|
|
||||||
m_tiles[pos] = tile;
|
m_tiles[pos] = tile;
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,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,7 +77,7 @@ enum OTBM_NodeTypes_t
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OTCM_SIGNATURE = 0x4D43544F,
|
OTCM_SIGNATURE = 0x4D43544F,
|
||||||
OTCM_VERSION = 1,
|
OTCM_VERSION = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
//@bindsingleton g_map
|
//@bindsingleton g_map
|
||||||
|
@ -93,7 +93,7 @@ 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, bool display = false/* temporary*/);
|
||||||
//void saveOtbm(const std::string& fileName);
|
//void saveOtbm(const std::string& fileName);
|
||||||
|
|
||||||
void clean();
|
void clean();
|
||||||
|
@ -106,7 +106,7 @@ public:
|
||||||
bool removeThingByPos(const Position& pos, int stackPos);
|
bool removeThingByPos(const Position& pos, int stackPos);
|
||||||
|
|
||||||
// tile related
|
// tile related
|
||||||
TilePtr createTile(const Position& pos);
|
TilePtr createTile(const Position& pos, const ItemPtr &g = nullptr);
|
||||||
const TilePtr& getTile(const Position& pos);
|
const TilePtr& getTile(const Position& pos);
|
||||||
TilePtr getOrCreateTile(const Position& pos);
|
TilePtr getOrCreateTile(const Position& pos);
|
||||||
void cleanTile(const Position& pos);
|
void cleanTile(const Position& pos);
|
||||||
|
@ -146,6 +146,7 @@ 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;
|
||||||
|
|
||||||
Light m_light;
|
Light m_light;
|
||||||
Position m_centralPosition;
|
Position m_centralPosition;
|
||||||
|
|
|
@ -30,9 +30,6 @@
|
||||||
#include <framework/core/filestream.h>
|
#include <framework/core/filestream.h>
|
||||||
#include <framework/core/binarytree.h>
|
#include <framework/core/binarytree.h>
|
||||||
|
|
||||||
#define TIXML_USE_STL // use STL strings instead.
|
|
||||||
#include <framework/thirdparty/tinyxml.h>
|
|
||||||
|
|
||||||
ThingTypeManager g_things;
|
ThingTypeManager g_things;
|
||||||
|
|
||||||
void ThingTypeManager::init()
|
void ThingTypeManager::init()
|
||||||
|
@ -112,9 +109,11 @@ bool ThingTypeManager::loadOtb(const std::string& file)
|
||||||
root->getU32(); // build number
|
root->getU32(); // build number
|
||||||
root->skip(128); // description
|
root->skip(128); // description
|
||||||
|
|
||||||
|
m_otbTypes.resize(root->getChildren().size(), m_nullOtbType);
|
||||||
for(const BinaryTreePtr& node : root->getChildren()) {
|
for(const BinaryTreePtr& node : root->getChildren()) {
|
||||||
ThingTypeOtbPtr otbType(new ThingTypeOtb);
|
ThingTypeOtbPtr otbType(new ThingTypeOtb);
|
||||||
otbType->unserialize(node);
|
otbType->unserialize(node);
|
||||||
|
addOtbType(otbType);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_otbLoaded = true;
|
m_otbLoaded = true;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue