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") | ||||
| end | ||||
| 
 | ||||
| --g_things.loadOtb("/items.otb") | ||||
| --g_map.loadOtbm("/forgotten.otbm") | ||||
| g_things.loadOtb("/items.otb") | ||||
| g_map.loadOtbm("/forgotten.otbm") | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -31,3 +31,10 @@ function Player:isPartySharedExperienceActive() | |||
|           shield == ShieldBlueNoSharedExpBlink or | ||||
|           shield == ShieldBlueNoSharedExp) | ||||
| 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 ~= g_game.getCharacterName() then | ||||
|         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 | ||||
|         menu:addSeparator() | ||||
|       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('Exclude from private chat'), function() g_game.excludeFromOwnChannel(creatureName) end) -- [TODO] must be removed after message's popup labels been implemented | ||||
|           end | ||||
|           menu:addOption(tr('Add to VIP list'), function() g_game.addVip(creatureName) end) | ||||
|           if (not Player:hasVip(creatureName)) then | ||||
|             menu:addOption(tr('Add to VIP list'), function() g_game.addVip(creatureName) end) | ||||
|           end | ||||
| 
 | ||||
|           local localPlayerShield = localPlayer:asCreature():getShield() | ||||
|           local creatureShield = creatureThing:getShield() | ||||
|  |  | |||
|  | @ -60,7 +60,7 @@ void BinaryTree::seek(uint pos) | |||
| 
 | ||||
| uint8 BinaryTree::getU8() | ||||
| { | ||||
|     if(m_pos+1 > m_buffer.size()) | ||||
|     if (m_pos+1 > m_buffer.size()) | ||||
|         stdext::throw_exception("BinaryTree: getU8 failed"); | ||||
|     uint8 v = m_buffer[m_pos]; | ||||
|     m_pos += 1; | ||||
|  | @ -69,7 +69,7 @@ uint8 BinaryTree::getU8() | |||
| 
 | ||||
| uint16 BinaryTree::getU16() | ||||
| { | ||||
|     if(m_pos+2 > m_buffer.size()) | ||||
|     if (m_pos+2 > m_buffer.size()) | ||||
|         stdext::throw_exception("BinaryTree: getU16 failed"); | ||||
|     uint16 v = stdext::readLE16(&m_buffer[m_pos]); | ||||
|     m_pos += 2; | ||||
|  | @ -78,7 +78,7 @@ uint16 BinaryTree::getU16() | |||
| 
 | ||||
| uint32 BinaryTree::getU32() | ||||
| { | ||||
|     if(m_pos+4 > m_buffer.size()) | ||||
|     if (m_pos+4 > m_buffer.size()) | ||||
|         stdext::throw_exception("BinaryTree: getU32 failed"); | ||||
|     uint32 v = stdext::readLE32(&m_buffer[m_pos]); | ||||
|     m_pos += 4; | ||||
|  | @ -87,8 +87,8 @@ uint32 BinaryTree::getU32() | |||
| 
 | ||||
| uint64 BinaryTree::getU64() | ||||
| { | ||||
|     if(m_pos+8 > m_buffer.size()) | ||||
|         stdext::throw_exception("BinaryTree: getu64 failed"); | ||||
|     if (m_pos+8 > m_buffer.size()) | ||||
|         stdext::throw_exception("BinaryTree: getU64 failed"); | ||||
|     uint64 v = stdext::readLE64(&m_buffer[m_pos]); | ||||
|     m_pos += 8; | ||||
|     return v; | ||||
|  | @ -98,7 +98,10 @@ std::string BinaryTree::getString() | |||
| { | ||||
|     uint16 len = getU16(); | ||||
|     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); | ||||
|     m_pos += len; | ||||
|  |  | |||
|  | @ -63,4 +63,8 @@ | |||
| // boost utilities
 | ||||
| #include <boost/algorithm/string.hpp> | ||||
| 
 | ||||
| // tiny XML
 | ||||
| #define TIXML_USE_STL | ||||
| #include <framework/thirdparty/tinyxml.h> | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -74,6 +74,10 @@ SET(otclient_SOURCES ${otclient_SOURCES} | |||
|     ${CMAKE_CURRENT_LIST_DIR}/core/thingtypeotb.h | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/core/tile.cpp | ||||
|     ${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 | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/luascript/luavaluecasts.cpp | ||||
|  |  | |||
|  | @ -43,6 +43,8 @@ class AnimatedText; | |||
| class StaticText; | ||||
| class ThingTypeDat; | ||||
| class ThingTypeOtb; | ||||
| class House; | ||||
| class Town; | ||||
| 
 | ||||
| typedef std::shared_ptr<MapView> MapViewPtr; | ||||
| 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<ThingTypeDat> ThingTypeDatPtr; | ||||
| 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<ThingTypeDatPtr> ThingTypeDatList; | ||||
| typedef std::vector<ThingTypeOtbPtr> ThingTypeOtbList; | ||||
| typedef std::vector<HousePtr> HouseList; | ||||
| typedef std::vector<TownPtr> TownList; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -45,14 +45,14 @@ Item::Item() : | |||
| 
 | ||||
| ItemPtr Item::create(int id) | ||||
| { | ||||
|     ItemPtr item = ItemPtr(new Item); | ||||
|     ItemPtr item(new Item); | ||||
|     item->setId(id); | ||||
|     return item; | ||||
| } | ||||
| 
 | ||||
| ItemPtr Item::createFromOtb(int id) | ||||
| { | ||||
|     ItemPtr item = ItemPtr(new Item); | ||||
|     ItemPtr item(new Item); | ||||
|     item->setOtbId(id); | ||||
|     return item; | ||||
| } | ||||
|  | @ -204,70 +204,71 @@ bool Item::isValid() | |||
|     return g_things.isValidDatId(m_id, DatItemCategory); | ||||
| } | ||||
| 
 | ||||
| bool Item::unserializeAttr(const BinaryTreePtr &fin) | ||||
| void Item::unserializeItem(const BinaryTreePtr &in) | ||||
| { | ||||
|     uint8 attrType; | ||||
|     while ((attrType = fin->getU8()) != 0) | ||||
|         readAttr((AttrTypes_t)attrType, fin); | ||||
|     // Yet another TODO.
 | ||||
|     while (in->canRead()) { | ||||
|         uint8 attrType = in->getU8(); | ||||
|         if (attrType == 0) | ||||
|             break; | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void Item::readAttr(AttrTypes_t attrType, const BinaryTreePtr &fin) | ||||
| { | ||||
|     switch (attrType) { | ||||
|     case ATTR_COUNT: | ||||
|         setSubType(fin->getU8()); | ||||
|         break; | ||||
|     case ATTR_ACTION_ID: | ||||
|         setActionId(fin->getU16()); | ||||
|         break; | ||||
|     case ATTR_UNIQUE_ID: | ||||
|         setUniqueId(fin->getU16()); | ||||
|         break; | ||||
|     case ATTR_NAME: | ||||
|         setName(fin->getString()); | ||||
|         break; | ||||
|     case ATTR_ARTICLE: | ||||
|         fin->getString(); | ||||
|     case ATTR_ATTACK: // \/ not needed.
 | ||||
|     case ATTR_EXTRAATTACK: | ||||
|     case ATTR_DEFENSE: | ||||
|     case ATTR_EXTRADEFENSE: | ||||
|     case ATTR_ARMOR: | ||||
|     case ATTR_ATTACKSPEED: | ||||
|     case ATTR_HPPITCHANCE: | ||||
|     case ATTR_DURATION: | ||||
|         fin->getU32(); | ||||
|         break; | ||||
|     case ATTR_SCRIPTPROTECTED: | ||||
|     case ATTR_DUALWIELD: | ||||
|     case ATTR_DECAYING_STATE: | ||||
|     case ATTR_HPPOUSEDOORID: | ||||
|         fin->getU8(); | ||||
|         break; | ||||
|     case ATTR_TEXT: | ||||
|         setText(fin->getString()); | ||||
|         break; | ||||
|     case ATTR_WRITTENDATE: | ||||
|         fin->getU32(); | ||||
|         break; | ||||
|     case ATTR_WRITTENBY: | ||||
|         fin->getString(); | ||||
|         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: | ||||
|         break; | ||||
|         switch ((AttrTypes_t)attrType) { | ||||
|             case ATTR_COUNT: | ||||
|                 setSubType(in->getU8()); | ||||
|                 break; | ||||
|             case ATTR_CHARGES: | ||||
|                 setSubType(in->getU16()); | ||||
|                 break; | ||||
|             case ATTR_ACTION_ID: | ||||
|                 setActionId(in->getU16()); | ||||
|                 break; | ||||
|             case ATTR_UNIQUE_ID: | ||||
|                 setUniqueId(in->getU16()); | ||||
|                 break; | ||||
|             case ATTR_NAME: | ||||
|                 setName(in->getString()); | ||||
|                 break; | ||||
|             case ATTR_ARTICLE: // ?
 | ||||
|             case ATTR_WRITTENBY: | ||||
|             case ATTR_DESC: | ||||
|                 in->getString(); | ||||
|                 break; | ||||
|             case ATTR_ATTACK: | ||||
|             case ATTR_EXTRAATTACK: | ||||
|             case ATTR_DEFENSE: | ||||
|             case ATTR_EXTRADEFENSE: | ||||
|             case ATTR_ARMOR: | ||||
|             case ATTR_ATTACKSPEED: | ||||
|             case ATTR_HITCHANCE: | ||||
|             case ATTR_DURATION: | ||||
|             case ATTR_WRITTENDATE: | ||||
|             case ATTR_SLEEPERGUID: | ||||
|             case ATTR_SLEEPSTART: | ||||
|             case ATTR_CONTAINER_ITEMS: | ||||
|             case ATTR_ATTRIBUTE_MAP: | ||||
|                 in->skip(4); | ||||
|                 break; | ||||
|             case ATTR_SCRIPTPROTECTED: | ||||
|             case ATTR_DUALWIELD: | ||||
|             case ATTR_DECAYING_STATE: | ||||
|             case ATTR_HOUSEDOORID: | ||||
|             case ATTR_RUNE_CHARGES: | ||||
|                 in->skip(1); | ||||
|                 break; | ||||
|             case ATTR_TEXT: | ||||
|                 setText(in->getString()); | ||||
|                 break; | ||||
|             case ATTR_DEPOT_ID: | ||||
|                 in->skip(2); // trolol
 | ||||
|                 break; | ||||
|             case ATTR_TELE_DEST: | ||||
|             { | ||||
|                 Position pos(in->getU16(), in->getU16(), in->getU8()); | ||||
|                 break; | ||||
|             } | ||||
|             default: | ||||
|                 stdext::throw_exception(stdext::format("invalid item attribute %d", (int)attrType)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,8 +29,6 @@ | |||
| 
 | ||||
| enum AttrTypes_t { | ||||
|     ATTR_END = 0, | ||||
|     //ATTR_DESCRIPTION = 1,
 | ||||
|     //ATTR_EXT_FILE = 2,
 | ||||
|     ATTR_TILE_FLAGS = 3, | ||||
|     ATTR_ACTION_ID = 4, | ||||
|     ATTR_UNIQUE_ID = 5, | ||||
|  | @ -39,10 +37,8 @@ enum AttrTypes_t { | |||
|     ATTR_TELE_DEST = 8, | ||||
|     ATTR_ITEM = 9, | ||||
|     ATTR_DEPOT_ID = 10, | ||||
|     //ATTR_EXT_SPAWN_FILE = 11,
 | ||||
|     ATTR_RUNE_CHARGES = 12, | ||||
|     //ATTR_EXT_HPPOUSE_FILE = 13,
 | ||||
|     ATTR_HPPOUSEDOORID = 14, | ||||
|     ATTR_HOUSEDOORID = 14, | ||||
|     ATTR_COUNT = 15, | ||||
|     ATTR_DURATION = 16, | ||||
|     ATTR_DECAYING_STATE = 17, | ||||
|  | @ -60,7 +56,7 @@ enum AttrTypes_t { | |||
|     ATTR_EXTRADEFENSE = 36, | ||||
|     ATTR_ARMOR = 37, | ||||
|     ATTR_ATTACKSPEED = 38, | ||||
|     ATTR_HPPITCHANCE = 39, | ||||
|     ATTR_HITCHANCE = 39, | ||||
|     ATTR_SHOOTRANGE = 40, | ||||
|     ATTR_ARTICLE = 41, | ||||
|     ATTR_SCRIPTPROTECTED = 42, | ||||
|  | @ -100,10 +96,7 @@ public: | |||
|     ItemPtr asItem() { return std::static_pointer_cast<Item>(shared_from_this()); } | ||||
|     bool isItem() { return true; } | ||||
| 
 | ||||
|     // TODO: These should be abstract and declared in i.e containers, doors, etc.
 | ||||
|     bool unserializeAttr(const BinaryTreePtr &fin); | ||||
|     bool unserializeItemNode(const BinaryTreePtr &fin) { return unserializeAttr(fin); } | ||||
|     void readAttr(AttrTypes_t attrType, const BinaryTreePtr &fin); | ||||
|     void unserializeItem(const BinaryTreePtr &in); | ||||
|     bool isMoveable(); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -27,12 +27,14 @@ | |||
| #include "item.h" | ||||
| #include "missile.h" | ||||
| #include "statictext.h" | ||||
| #include "houses.h" | ||||
| #include "towns.h" | ||||
| 
 | ||||
| #include <framework/core/eventdispatcher.h> | ||||
| #include "mapview.h" | ||||
| #include <framework/core/resourcemanager.h> | ||||
| #include <framework/core/filestream.h> | ||||
| #include <framework/core/binarytree.h> | ||||
| #include <framework/core/binarytree.h>	 | ||||
| 
 | ||||
| Map g_map; | ||||
| 
 | ||||
|  | @ -59,67 +61,61 @@ void Map::notificateTileUpdateToMapViews(const Position& 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); | ||||
|     if (!fin) { | ||||
|         g_logger.error(stdext::format("Unable to load map '%s'", fileName)); | ||||
|         return false; | ||||
|     } | ||||
|     if (!fin) | ||||
|         stdext::throw_exception(stdext::format("Unable to load map '%s'", fileName)); | ||||
| 
 | ||||
|     if (!g_things.isOtbLoaded()/* || !g_things.isXmlLoaded()*/) { | ||||
|         g_logger.error("OTB and XML are not loaded yet to load a map."); | ||||
|         return false; | ||||
|     } | ||||
|     fin->cache(); | ||||
|     if (!g_things.isOtbLoaded()) | ||||
|         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(); | ||||
|     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(); | ||||
|     dump << headerVersion; | ||||
|     if (!headerVersion || headerVersion > 3) { | ||||
|         g_logger.error("Unknown OTBM version detected."); | ||||
|         return false; | ||||
|     } | ||||
|     if (!headerVersion || headerVersion > 3) | ||||
|         stdext::throw_exception(stdext::format("Unknown OTBM version detected: %u.", headerVersion)); | ||||
| 
 | ||||
|     uint16 w = root->getU16(), h = root->getU16(); | ||||
|     dump << "Map size: " << w << "x" << h; | ||||
| 
 | ||||
|     root->skip(1); // ??
 | ||||
|     uint32 headerMajorItems = root->getU8(); | ||||
|     dump << headerMajorItems; | ||||
|     dump << "major: " << g_things.getOtbMajorVersion(); | ||||
|     if (headerMajorItems < 3) { | ||||
|         g_logger.error("This map needs to be upgraded."); | ||||
|         return false; | ||||
|     } | ||||
|     if (headerMajorItems < 3) | ||||
|         stdext::throw_exception(stdext::format("This map needs to be upgraded. read %d what it's supposed to be: %u", | ||||
|                                                headerMajorItems, g_things.getOtbMajorVersion())); | ||||
| 
 | ||||
|     if (headerMajorItems > g_things.getOtbMajorVersion()) { | ||||
|         g_logger.error("This map was saved with different OTB version."); | ||||
|         return false; | ||||
|     } | ||||
|     if (headerMajorItems > g_things.getOtbMajorVersion()) | ||||
|         stdext::throw_exception(stdext::format("This map was saved with different OTB version. read %d what it's supposed to be: %d", | ||||
|                                                headerMajorItems, g_things.getOtbMajorVersion())); | ||||
| 
 | ||||
|     root->skip(1); /// ??
 | ||||
|     uint32 headerMinorItems =  root->getU8(); | ||||
|     dump << headerMinorItems; | ||||
|     dump << "minor: " << g_things.getOtbMinorVersion(); | ||||
|     root->skip(3); | ||||
|     uint32 headerMinorItems =  root->getU32(); | ||||
|     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]; | ||||
|     if (node->getU8() != OTBM_MAP_DATA) { | ||||
|         g_logger.error("Could not read data node."); | ||||
|         return false; | ||||
|     } | ||||
|     if (node->getU8() != OTBM_MAP_DATA) | ||||
|         stdext::throw_exception("Could not read root data node"); | ||||
| 
 | ||||
|     std::string tmp; | ||||
|     uint8 attribute; | ||||
|     Boolean<true> first; | ||||
|     while (node->canRead()) { | ||||
|         attribute = node->getU8(); | ||||
|         tmp = node->getString(); | ||||
|         uint8 attribute = node->getU8(); | ||||
|         std::string tmp = node->getString(); | ||||
|         switch (attribute) { | ||||
|         case OTBM_ATTR_DESCRIPTION: | ||||
|             if (!m_description.empty()) | ||||
|                 m_description += "\n" + tmp; | ||||
|             else | ||||
|             if (first) { | ||||
|                 first = false; | ||||
|                 m_description = tmp; | ||||
|             } else { | ||||
|                 m_description += "\n" + tmp; | ||||
|             } | ||||
|             break; | ||||
|         case OTBM_ATTR_SPAWN_FILE: | ||||
|             m_spawnFile = fileName.substr(0, fileName.rfind('/') + 1) + tmp; | ||||
|  | @ -128,151 +124,130 @@ bool Map::loadOtbm(const std::string& fileName) | |||
|             m_houseFile = fileName.substr(0, fileName.rfind('/') + 1) + tmp; | ||||
|             break; | ||||
|         default: | ||||
|             g_logger.error(stdext::format("Invalid attribute '%c'", attribute)); | ||||
|             break; | ||||
|             stdext::throw_exception(stdext::format("Invalid attribute '%c'", attribute)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     dump << m_description; | ||||
|     dump << m_houseFile; | ||||
|     dump << m_spawnFile; | ||||
| 
 | ||||
|     for (const BinaryTreePtr &nodeMapData : node->getChildren()) { | ||||
|         uint8 mapDataType = nodeMapData->getU8(); | ||||
|         dump << "mapData: " << (int)mapDataType; | ||||
|         if (mapDataType == OTBM_TILE_AREA) { | ||||
|             dump << "Tile: reading pos..."; | ||||
|             uint16 baseX = nodeMapData->getU16(), baseY = nodeMapData->getU16(); | ||||
|             uint8 pz = nodeMapData->getU8(); | ||||
| 
 | ||||
|             for (const BinaryTreePtr &nodeTile : nodeMapData->getChildren()) { | ||||
|                 uint8 type = nodeTile->getU8(); | ||||
|                 if (type == OTBM_TILE || type == OTBM_HOUSETILE) { | ||||
|                     TilePtr tile = 0; | ||||
|                     ItemPtr ground = 0; | ||||
|                     TilePtr tile = nullptr; | ||||
|                     ItemPtr ground = nullptr; | ||||
|                     HousePtr house = nullptr; | ||||
|                     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); | ||||
| 
 | ||||
|                     // TODO: Houses.
 | ||||
|                     if (type ==  OTBM_HOUSETILE) { | ||||
|                         uint32 hId = nodeTile->getU32(); | ||||
| 
 | ||||
|                         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()) { | ||||
|                         tileAttr = nodeTile->getU8(); | ||||
|                         uint8 tileAttr = nodeTile->getU8(); | ||||
|                         switch (tileAttr) { | ||||
|                         case OTBM_ATTR_TILE_FLAGS: { | ||||
|                             uint32 _flags = nodeTile->getU32(); | ||||
|                             case OTBM_ATTR_TILE_FLAGS: { | ||||
|                                 uint32 _flags = nodeTile->getU32(); | ||||
|                                 if ((_flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE) | ||||
|                                     flags |= TILESTATE_PROTECTIONZONE; | ||||
|                                 else if ((_flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE) | ||||
|                                     flags |= TILESTATE_OPTIONALZONE; | ||||
|                                 else if ((_flags & TILESTATE_HARDCOREZONE) == TILESTATE_HARDCOREZONE) | ||||
|                                     flags |= TILESTATE_HARDCOREZONE; | ||||
| 
 | ||||
|                             if ((_flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE) | ||||
|                                 flags |= TILESTATE_PROTECTIONZONE; | ||||
|                             else if ((_flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE) | ||||
|                                 flags |= TILESTATE_OPTIONALZONE; | ||||
|                             else if ((_flags & TILESTATE_HPPARDCOREZONE) == TILESTATE_HPPARDCOREZONE) | ||||
|                                 flags |= TILESTATE_HPPARDCOREZONE; | ||||
|                                 if ((_flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT) | ||||
|                                     flags |= TILESTATE_NOLOGOUT; | ||||
| 
 | ||||
|                             if ((_flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT) | ||||
|                                 flags |= TILESTATE_NOLOGOUT; | ||||
|                                 if ((_flags & TILESTATE_REFRESH) == TILESTATE_REFRESH) | ||||
|                                     flags |= TILESTATE_REFRESH; | ||||
| 
 | ||||
|                             if ((_flags & TILESTATE_REFRESH) == 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; | ||||
|                                 break; | ||||
|                             } | ||||
| 
 | ||||
|                             if (tile) { | ||||
|                                 tile->addThing(item); | ||||
|                             } else if (item->isGround()) { | ||||
|                                 ground = item; | ||||
|                             } else { | ||||
|                                 tile = createTile(pos); | ||||
|                                 tile->addThing(ground); | ||||
|                                 tile->addThing(item); | ||||
|                             case OTBM_ATTR_ITEM: { | ||||
|                                 ItemPtr item = Item::createFromOtb(nodeTile->getU16()); | ||||
|                                 if (tile) | ||||
|                                     tile->addThing(item); | ||||
|                                 else if (item->isGround()) | ||||
|                                     ground = item; | ||||
|                                 else { | ||||
|                                     tile = createTile(pos, ground); | ||||
|                                     tile->addThing(item); | ||||
|                                 } | ||||
|                                 break; | ||||
|                             } | ||||
|                         } 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); | ||||
|                                 } | ||||
|                             item->unserializeItem(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 { | ||||
|                                 g_logger.error(stdext::format("failed to unserialize item with %d at pos %d %d %d", item->getId(), | ||||
|                                                               px, py, pz)); | ||||
|                                 return false; | ||||
|                                 tile = createTile(pos, ground); | ||||
|                                 tile->addThing(item); | ||||
|                             } | ||||
|                         } else { | ||||
|                             g_logger.error(stdext::format("Unknown item node type %d", type)); | ||||
|                             return false; | ||||
|                         } | ||||
|                         } else | ||||
|                             stdext::throw_exception("Unknown item node"); | ||||
|                     } | ||||
| 
 | ||||
|                     if (!tile) { | ||||
|                         tile = createTile(pos); | ||||
|                         tile->addThing(ground); | ||||
|                     } | ||||
|                     if (!tile) | ||||
|                         tile = createTile(pos, ground); | ||||
| 
 | ||||
|                     tile->setFlags((tileflags_t)flags); | ||||
|                 } else { | ||||
|                     g_logger.error(stdext::format("Unknown tile node type %d", type)); | ||||
|                     return false; | ||||
|                 } | ||||
|                 } else | ||||
|                     stdext::throw_exception(stdext::format("Unknown tile node type %d", type)); | ||||
|             } | ||||
|         } else if (mapDataType == OTBM_TOWNS) { | ||||
|             TownPtr town = nullptr; | ||||
|             for (const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) { | ||||
|                 if (nodeTown->getU8() == OTBM_TOWN) { | ||||
|                     uint32 townId = nodeTown->getU32(); | ||||
|                     std::string townName = nodeTown->getString(); | ||||
| 
 | ||||
|                     Position townCoords(nodeTown->getU16(), nodeTown->getU16(), nodeTown->getU8()); | ||||
|                     if (!(town = g_towns.getTown(townId))) | ||||
|                         town = TownPtr(new Town(townId, townName, townCoords)); | ||||
|                 } else | ||||
|                     return false; | ||||
|                     stdext::throw_exception("invalid town node"); | ||||
|             } | ||||
|         } else if (mapDataType == OTBM_WAYPOINTS && headerVersion > 1) { | ||||
|             for (const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) { | ||||
|                 if (nodeWaypoint->getU8() == OTBM_WAYPOINT) { | ||||
|                     std::string name = nodeWaypoint->getString(); | ||||
|                     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 | ||||
|             return false; | ||||
|             stdext::throw_exception("Unknown map data node"); | ||||
|     } | ||||
| 
 | ||||
|     // TODO: Load house & spawns.
 | ||||
|     return true; | ||||
|     g_logger.debug("OTBM read successfully."); | ||||
|     fin->close(); | ||||
|     /// TODO read XML Stuff (houses & spawns).
 | ||||
| } | ||||
| 
 | ||||
| bool Map::loadOtcm(const std::string& fileName) | ||||
|  | @ -300,7 +275,7 @@ bool Map::loadOtcm(const std::string& fileName) | |||
|                 fin->getString(); // world name
 | ||||
| 
 | ||||
|                 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; | ||||
|             } | ||||
|  | @ -417,6 +392,7 @@ void Map::clean() | |||
| { | ||||
|     cleanDynamicThings(); | ||||
|     m_tiles.clear(); | ||||
|     m_waypoints.clear(); | ||||
| } | ||||
| 
 | ||||
| void Map::cleanDynamicThings() | ||||
|  | @ -538,9 +514,12 @@ bool Map::removeThingByPos(const Position& pos, int stackPos) | |||
|     return false; | ||||
| } | ||||
| 
 | ||||
| TilePtr Map::createTile(const Position& pos) | ||||
| TilePtr Map::createTile(const Position& pos, const ItemPtr &g) | ||||
| { | ||||
|     TilePtr tile = TilePtr(new Tile(pos)); | ||||
|     if (g) | ||||
|         tile->addThing(g); | ||||
| 
 | ||||
|     m_tiles[pos] = tile; | ||||
|     return tile; | ||||
| } | ||||
|  |  | |||
|  | @ -42,7 +42,7 @@ enum OTBM_AttrTypes_t | |||
|     OTBM_ATTR_SPAWN_FILE = 11, | ||||
|     OTBM_ATTR_RUNE_CHARGES = 12, | ||||
|     OTBM_ATTR_HOUSE_FILE = 13, | ||||
|     OTBM_ATTR_HPPOUSEDOORID = 14, | ||||
|     OTBM_ATTR_HOUSEDOORID = 14, | ||||
|     OTBM_ATTR_COUNT = 15, | ||||
|     OTBM_ATTR_DURATION = 16, | ||||
|     OTBM_ATTR_DECAYING_STATE = 17, | ||||
|  | @ -77,7 +77,7 @@ enum OTBM_NodeTypes_t | |||
| 
 | ||||
| enum { | ||||
|     OTCM_SIGNATURE = 0x4D43544F, | ||||
|     OTCM_VERSION = 1, | ||||
|     OTCM_VERSION = 1 | ||||
| }; | ||||
| 
 | ||||
| //@bindsingleton g_map
 | ||||
|  | @ -93,7 +93,7 @@ public: | |||
|     bool loadOtcm(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 clean(); | ||||
|  | @ -106,7 +106,7 @@ public: | |||
|     bool removeThingByPos(const Position& pos, int stackPos); | ||||
| 
 | ||||
|     // tile related
 | ||||
|     TilePtr createTile(const Position& pos); | ||||
|     TilePtr createTile(const Position& pos, const ItemPtr &g = nullptr); | ||||
|     const TilePtr& getTile(const Position& pos); | ||||
|     TilePtr getOrCreateTile(const Position& pos); | ||||
|     void cleanTile(const Position& pos); | ||||
|  | @ -146,6 +146,7 @@ private: | |||
|     std::vector<AnimatedTextPtr> m_animatedTexts; | ||||
|     std::vector<StaticTextPtr> m_staticTexts; | ||||
|     std::vector<MapViewPtr> m_mapViews; | ||||
|     std::unordered_map<Position, std::string, PositionHasher> m_waypoints; | ||||
| 
 | ||||
|     Light m_light; | ||||
|     Position m_centralPosition; | ||||
|  |  | |||
|  | @ -30,9 +30,6 @@ | |||
| #include <framework/core/filestream.h> | ||||
| #include <framework/core/binarytree.h> | ||||
| 
 | ||||
| #define TIXML_USE_STL // use STL strings instead.
 | ||||
| #include <framework/thirdparty/tinyxml.h> | ||||
| 
 | ||||
| ThingTypeManager g_things; | ||||
| 
 | ||||
| void ThingTypeManager::init() | ||||
|  | @ -112,9 +109,11 @@ bool ThingTypeManager::loadOtb(const std::string& file) | |||
|         root->getU32(); // build number
 | ||||
|         root->skip(128); // description
 | ||||
| 
 | ||||
|         m_otbTypes.resize(root->getChildren().size(), m_nullOtbType); | ||||
|         for(const BinaryTreePtr& node : root->getChildren()) { | ||||
|             ThingTypeOtbPtr otbType(new ThingTypeOtb); | ||||
|             otbType->unserialize(node); | ||||
|             addOtbType(otbType); | ||||
|         } | ||||
| 
 | ||||
|         m_otbLoaded = true; | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ enum tileflags_t | |||
|     TILESTATE_TRASHED = 1 << 1, | ||||
|     TILESTATE_OPTIONALZONE = 1 << 2, | ||||
|     TILESTATE_NOLOGOUT = 1 << 3, | ||||
|     TILESTATE_HPPARDCOREZONE = 1 << 4, | ||||
|     TILESTATE_HARDCOREZONE = 1 << 4, | ||||
|     TILESTATE_REFRESH = 1 << 5, | ||||
| 
 | ||||
|     // internal usage
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Kamil
						Kamil