From f12ecd8404ed06e9dbbf5c719141556ed22a2d33 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 21 Jan 2014 11:10:02 +0100 Subject: [PATCH] Implemented a function to save .dat file --- src/client/luafunctions.cpp | 1 + src/client/thingtype.cpp | 89 ++++++++++++++++++++++++++++++++- src/client/thingtype.h | 3 ++ src/client/thingtypemanager.cpp | 34 +++++++++++++ src/client/thingtypemanager.h | 2 + 5 files changed, 128 insertions(+), 1 deletion(-) diff --git a/src/client/luafunctions.cpp b/src/client/luafunctions.cpp index 05282493..b1f7ac07 100644 --- a/src/client/luafunctions.cpp +++ b/src/client/luafunctions.cpp @@ -56,6 +56,7 @@ void Client::registerLuaFunctions() { g_lua.registerSingletonClass("g_things"); g_lua.bindSingletonFunction("g_things", "loadDat", &ThingTypeManager::loadDat, &g_things); + g_lua.bindSingletonFunction("g_things", "saveDat", &ThingTypeManager::saveDat, &g_things); g_lua.bindSingletonFunction("g_things", "loadOtb", &ThingTypeManager::loadOtb, &g_things); g_lua.bindSingletonFunction("g_things", "loadXml", &ThingTypeManager::loadXml, &g_things); g_lua.bindSingletonFunction("g_things", "loadOtml", &ThingTypeManager::loadOtml, &g_things); diff --git a/src/client/thingtype.cpp b/src/client/thingtype.cpp index 822b6b03..4b463274 100644 --- a/src/client/thingtype.cpp +++ b/src/client/thingtype.cpp @@ -38,6 +38,7 @@ ThingType::ThingType() m_id = 0; m_null = true; m_exactSize = 0; + m_realSize = 0; m_numPatternX = m_numPatternY = m_numPatternZ = 0; m_animationPhases = 0; m_layers = 0; @@ -45,6 +46,86 @@ ThingType::ThingType() m_opacity = 1.0f; } +void ThingType::serialize(const FileStreamPtr& fin) +{ + for(int i = 0; i < ThingLastAttr; ++i) { + if(!hasAttr((ThingAttr)i)) + continue; + + int attr = i; + if(g_game.getFeature(Otc::GameChargeableItems)) { + if(attr == ThingAttrChargeable) + attr = ThingAttrWritable; + else if(attr >= ThingAttrWritable) + attr += 1; + } + + if(g_game.getProtocolVersion() >= 1010) { + if(attr == ThingAttrNoMoveAnimation) + attr = 16; + else if(attr >= ThingAttrPickupable) + attr += 1; + } + + fin->addU8(attr); + switch(attr) { + case ThingAttrDisplacement: { + fin->addU16(m_displacement.x); + fin->addU16(m_displacement.y); + break; + } + case ThingAttrLight: { + Light light = m_attribs.get(attr); + fin->addU16(light.intensity); + fin->addU16(light.color); + break; + } + case ThingAttrMarket: { + MarketData market = m_attribs.get(attr); + fin->addU16(market.category); + fin->addU16(market.tradeAs); + fin->addU16(market.showAs); + fin->addString(market.name); + fin->addU16(market.restrictVocation); + fin->addU16(market.requiredLevel); + break; + } + case ThingAttrUsable: + case ThingAttrElevation: + case ThingAttrGround: + case ThingAttrWritable: + case ThingAttrWritableOnce: + case ThingAttrMinimapColor: + case ThingAttrCloth: + case ThingAttrLensHelp: + fin->addU16(m_attribs.get(attr)); + break; + default: + break; + }; + } + fin->addU8(ThingLastAttr); + + fin->addU8(m_size.width()); + fin->addU8(m_size.height()); + + if(m_size.width() > 1 || m_size.height() > 1) + fin->addU8(m_realSize); + + fin->addU8(m_layers); + fin->addU8(m_numPatternX); + fin->addU8(m_numPatternY); + fin->addU8(m_numPatternZ); + fin->addU8(m_animationPhases); + + for(uint i = 0; i < m_spritesIndex.size(); i++) { + if(g_game.getFeature(Otc::GameSpritesU32)) + fin->addU32(m_spritesIndex[i]); + else + fin->addU16(m_spritesIndex[i]); + } +} + void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileStreamPtr& fin) { m_null = false; @@ -129,7 +210,13 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS uint8 width = fin->getU8(); uint8 height = fin->getU8(); m_size = Size(width, height); - m_exactSize = (width > 1 || height > 1) ? std::min((int)fin->getU8(), std::max(width * 32, height * 32)) : 32; + if(width > 1 || height > 1) { + m_realSize = fin->getU8(); + m_exactSize = std::min(m_realSize, std::max(width * 32, height * 32)); + } + else + m_exactSize = 32; + m_layers = fin->getU8(); m_numPatternX = fin->getU8(); m_numPatternY = fin->getU8(); diff --git a/src/client/thingtype.h b/src/client/thingtype.h index 44b794d2..f099be73 100644 --- a/src/client/thingtype.h +++ b/src/client/thingtype.h @@ -117,6 +117,8 @@ public: void unserialize(uint16 clientId, ThingCategory category, const FileStreamPtr& fin); void unserializeOtml(const OTMLNodePtr& node); + void serialize(const FileStreamPtr& fin); + void draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, LightView *lightView = nullptr); uint16 getId() { return m_id; } @@ -199,6 +201,7 @@ private: Size m_size; Point m_displacement; int m_exactSize; + int m_realSize; int m_numPatternX, m_numPatternY, m_numPatternZ; int m_animationPhases; int m_layers; diff --git a/src/client/thingtypemanager.cpp b/src/client/thingtypemanager.cpp index f84a2014..15ab59f0 100644 --- a/src/client/thingtypemanager.cpp +++ b/src/client/thingtypemanager.cpp @@ -62,6 +62,40 @@ void ThingTypeManager::terminate() m_nullItemType = nullptr; } +void ThingTypeManager::saveDat(std::string fileName) +{ + if(!m_datLoaded) + stdext::throw_exception("failed to save, dat is not loaded"); + + try { + FileStreamPtr fin = g_resources.createFile(fileName); + if(!fin) + stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName)); + + fin->cache(); + + fin->addU32(m_datSignature); + + for(int category = 0; category < ThingLastCategory; ++category) + fin->addU16(m_thingTypes[category].size() - 1); + + for(int category = 0; category < ThingLastCategory; ++category) { + uint16 firstId = 1; + if(category == ThingCategoryItem) + firstId = 100; + + for(uint16 id = firstId; id < m_thingTypes[category].size(); ++id) + m_thingTypes[category][id]->serialize(fin); + } + + + fin->flush(); + fin->close(); + } catch(std::exception& e) { + g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what())); + } +} + bool ThingTypeManager::loadDat(std::string file) { m_datLoaded = false; diff --git a/src/client/thingtypemanager.h b/src/client/thingtypemanager.h index 055d5c48..51e63013 100644 --- a/src/client/thingtypemanager.h +++ b/src/client/thingtypemanager.h @@ -41,6 +41,8 @@ public: void loadXml(const std::string& file); void parseItemType(uint16 id, TiXmlElement *elem); + void saveDat(std::string fileName); + void addItemType(const ItemTypePtr& itemType); const ItemTypePtr& findItemTypeByClientId(uint16 id); const ItemTypePtr& findItemTypeByName(std::string name);