Implemented a function to save .dat file

master
Sam 10 years ago
parent 53803b2218
commit f12ecd8404

@ -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);

@ -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<Light>(attr);
fin->addU16(light.intensity);
fin->addU16(light.color);
break;
}
case ThingAttrMarket: {
MarketData market = m_attribs.get<MarketData>(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<uint16>(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>((int)fin->getU8(), std::max<int>(width * 32, height * 32)) : 32;
if(width > 1 || height > 1) {
m_realSize = fin->getU8();
m_exactSize = std::min<int>(m_realSize, std::max<int>(width * 32, height * 32));
}
else
m_exactSize = 32;
m_layers = fin->getU8();
m_numPatternX = fin->getU8();
m_numPatternY = fin->getU8();

@ -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;

@ -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;

@ -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);

Loading…
Cancel
Save