#include "datmanager.h" #include "spritemanager.h" #include DatManager g_dat; bool DatManager::load(const std::string& filename) { try { std::stringstream fin; g_resources.loadFile(filename, fin); m_signature = fw::getu32(fin); int numItems = fw::getu16(fin); int numCreatures = fw::getu16(fin); int numEffects = fw::getu16(fin); int numShots = fw::getu16(fin); m_itemsAttributes.resize(numItems); for(int id = 100; id < numItems; ++id) parseThingAttributes(fin, m_itemsAttributes[id - 100]); m_creaturesAttributes.resize(numItems); for(int id = 0; id < numCreatures; ++id) parseThingAttributes(fin, m_creaturesAttributes[id]); m_effectsAttributes.resize(numItems); for(int id = 0; id < numEffects; ++id) parseThingAttributes(fin, m_effectsAttributes[id]); m_shotsAttributes.resize(numItems); for(int id = 0; id < numShots; ++id) parseThingAttributes(fin, m_shotsAttributes[id]); return true; } catch(std::exception& e) { logError(e.what()); return false; } } void DatManager::unload() { m_itemsAttributes.clear(); m_creaturesAttributes.clear(); m_effectsAttributes.clear(); m_shotsAttributes.clear(); } void DatManager::parseThingAttributes(std::stringstream& fin, ThingAttributes& thingAttributes) { assert(fin.good()); while(true) { uint8 opt; fin.read((char*)&opt, 1); if(opt == 0xFF) break; parseThingAttributesOpt(fin, thingAttributes, opt); } thingAttributes.width = fw::getu8(fin); thingAttributes.height = fw::getu8(fin); if(thingAttributes.width > 1 || thingAttributes.height > 1) fw::getu8(fin); // ?? thingAttributes.blendframes = fw::getu8(fin); thingAttributes.xdiv = fw::getu8(fin); thingAttributes.ydiv = fw::getu8(fin); thingAttributes.zdiv = fw::getu8(fin); thingAttributes.animcount = fw::getu8(fin); int totalSprites = thingAttributes.width * thingAttributes.height * thingAttributes.blendframes * thingAttributes.xdiv * thingAttributes.ydiv * thingAttributes.zdiv * thingAttributes.animcount; thingAttributes.sprites.resize(totalSprites); for(uint16 i = 0; i < totalSprites; i++) thingAttributes.sprites[i] = fw::getu16(fin); } void DatManager::parseThingAttributesOpt(std::stringstream& fin, ThingAttributes& thingAttributes, uint8 opt) { uint8 read_byte; uint16 read_short; switch(opt) { case 0x00: // Ground tile fin.read((char*)&thingAttributes.speed, 2); thingAttributes.group = THING_GROUP_GROUND; break; case 0x01: // All OnTop thingAttributes.alwaysOnTop = true; thingAttributes.alwaysOnTopOrder = 1; break; case 0x02: // Can walk trough (open doors, arces, bug pen fence) thingAttributes.alwaysOnTop = true; thingAttributes.alwaysOnTopOrder = 2; break; case 0x03: // Can walk trough (arces) thingAttributes.alwaysOnTop = true; thingAttributes.alwaysOnTopOrder = 3; break; case 0x04: // Container thingAttributes.group = THING_GROUP_CONTAINER; break; case 0x05: // Stackable thingAttributes.stackable = true; break; case 0x06: // Unknown break; case 0x07: // Useable thingAttributes.useable = true; break; case 0x08: // Writtable thingAttributes.group = THING_GROUP_WRITEABLE; thingAttributes.readable = true; fin.read((char*)&thingAttributes.subParam07, 2); break; case 0x09: // Writtable once // Writtable objects that can't be edited by players thingAttributes.readable = true; fin.read((char*)&thingAttributes.subParam08, 2); break; case 0x0A: // Fluid containers fin.read((char*)&read_byte, 1); thingAttributes.group = THING_GROUP_FLUID; break; case 0x0B: // Splashes thingAttributes.group = THING_GROUP_SPLASH; break; case 0x0C: // Blocks solid objects (creatures, walls etc) thingAttributes.blockSolid = true; break; case 0x0D: // Not moveable thingAttributes.moveable = false; break; case 0x0E: // Blocks missiles (walls, magic wall etc) thingAttributes.blockProjectile = true; break; case 0x0F: // Blocks pathfind algorithms (monsters) thingAttributes.blockPathFind = true; break; case 0x10: // Blocks monster movement (flowers, parcels etc) thingAttributes.pickupable = true; break; case 0x11: // Hangable objects (wallpaper etc) thingAttributes.isHangable = true; break; case 0x12: // Horizontal wall thingAttributes.isHorizontal = true; break; case 0x13: // Vertical wall thingAttributes.isVertical = true; break; case 0x14: // Rotable thingAttributes.rotable = true; break; case 0x15: // Light info fin.read((char*)&thingAttributes.lightLevel, 2); fin.read((char*)&thingAttributes.lightColor, 2); break; case 0x16: break; case 0x17: // Changes floor break; case 0x18: // Thing must be drawed with offset thingAttributes.hasHeight = true; fin.read((char*)&thingAttributes.xOffset, 1); fin.read((char*)&thingAttributes.yOffset, 1); fin.read((char*)&read_short, 2); break; case 0x19: // pixels characters height //fin.read((char*)&thingAttributes.xOffset, 1); //fin.read((char*)&thingAttributes.yOffset, 1); fin.read((char*)&read_short, 2); //logDebug((int)thingAttributes.xOffset, " ", (int)thingAttributes.yOffset); break; case 0x1A: //thingAttributes.hasHeight = true; break; case 0x1B: break; case 0x1C: // Minimap color fin.read((char*)&thingAttributes.miniMapColor, 2); thingAttributes.hasMiniMapColor = true; break; case 0x1D: // Unknown fin.read((char*)&read_short, 2); if(read_short == 1112) thingAttributes.readable = true; break; case 0x1E: break; case 0x1F: thingAttributes.lookThrough = true; break; case 0x20: break; default: throw std::logic_error(fw::mkstr("ERROR: unknown .dat byte code: 0x", std::hex, (int)opt)); } }