mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-03 23:56:43 +00:00 
			
		
		
		
	Merge branch 'esm4' into 'master'
ESM4 Support See merge request OpenMW/openmw!1610
This commit is contained in:
		
						commit
						3af037d2ae
					
				
					 176 changed files with 20783 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -76,7 +76,7 @@ add_component_dir (to_utf8
 | 
			
		|||
    to_utf8
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
add_component_dir(esm attr defs esmcommon records util luascripts)
 | 
			
		||||
add_component_dir(esm attr common defs esmcommon reader records util luascripts)
 | 
			
		||||
 | 
			
		||||
add_component_dir (esm3
 | 
			
		||||
    esmreader esmwriter loadacti loadalch loadappa loadarmo loadbody loadbook loadbsgn loadcell
 | 
			
		||||
| 
						 | 
				
			
			@ -94,6 +94,16 @@ add_component_dir (esm3terrain
 | 
			
		|||
    storage
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
add_component_dir (esm4
 | 
			
		||||
    loadachr loadacre loadacti loadalch loadaloc loadammo loadanio loadappa loadarma loadarmo loadaspc loadbook
 | 
			
		||||
    loadbptd loadcell loadclas loadclfm loadclot common loadcont loadcrea loaddial loaddobj loaddoor loadeyes
 | 
			
		||||
    loadflor loadflst formid loadfurn loadglob loadgras loadhair loadhdpt loadidle loadidlm loadimod loadinfo
 | 
			
		||||
    loadingr loadkeym loadland loadlgtm loadligh loadltex loadlvlc loadlvli loadlvln loadmato loadmisc loadmset
 | 
			
		||||
    loadmstt loadmusc loadnavi loadnavm loadnote loadnpc loadotft loadpack loadpgrd loadpgre loadpwat loadqust
 | 
			
		||||
    loadrace loadrefr loadregn loadroad loadsbsp loadscol loadscpt loadscrl loadsgst loadslgm loadsndr
 | 
			
		||||
    loadsoun loadstat loadtact loadterm loadtes4 loadtree loadtxst loadweap loadwrld reader
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_component_dir (misc
 | 
			
		||||
    constants utf8stream stringops resourcehelpers rng messageformatparser weakcache thread
 | 
			
		||||
    compression osguservalues errorMarker color
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								components/esm/common.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								components/esm/common.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#include "sstream"
 | 
			
		||||
 | 
			
		||||
namespace ESM
 | 
			
		||||
{
 | 
			
		||||
    std::string printName(const std::uint32_t typeId)
 | 
			
		||||
    {
 | 
			
		||||
        unsigned char typeName[4];
 | 
			
		||||
        typeName[0] =  typeId        & 0xff;
 | 
			
		||||
        typeName[1] = (typeId >>  8) & 0xff;
 | 
			
		||||
        typeName[2] = (typeId >> 16) & 0xff;
 | 
			
		||||
        typeName[3] = (typeId >> 24) & 0xff;
 | 
			
		||||
 | 
			
		||||
        return std::string((char*)typeName, 4);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								components/esm/common.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								components/esm/common.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
#ifndef COMPONENT_ESM_COMMON_H
 | 
			
		||||
#define COMPONENT_ESM_COMMON_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace ESM
 | 
			
		||||
{
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
    union ESMVersion
 | 
			
		||||
    {
 | 
			
		||||
        float         f;
 | 
			
		||||
        std::uint32_t ui;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    union TypeId
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t value;
 | 
			
		||||
        char name[4]; // record type in ascii
 | 
			
		||||
    };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
    enum ESMVersions
 | 
			
		||||
    {
 | 
			
		||||
        VER_120 = 0x3f99999a, // TES3
 | 
			
		||||
        VER_130 = 0x3fa66666, // TES3
 | 
			
		||||
        VER_080 = 0x3f4ccccd, // TES4
 | 
			
		||||
        VER_100 = 0x3f800000, // TES4
 | 
			
		||||
        VER_132 = 0x3fa8f5c3, // FONV Courier's Stash, DeadMoney
 | 
			
		||||
        VER_133 = 0x3faa3d71, // FONV HonestHearts
 | 
			
		||||
        VER_134 = 0x3fab851f, // FONV, GunRunnersArsenal, LonesomeRoad, OldWorldBlues
 | 
			
		||||
        VER_094 = 0x3f70a3d7, // TES5/FO3
 | 
			
		||||
        VER_170 = 0x3fd9999a  // TES5
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Defines another files (esm or esp) that this file depends upon.
 | 
			
		||||
    struct MasterData
 | 
			
		||||
    {
 | 
			
		||||
        std::string   name;
 | 
			
		||||
        std::uint64_t size;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum VarType
 | 
			
		||||
    {
 | 
			
		||||
        VT_Unknown = 0,
 | 
			
		||||
        VT_None,
 | 
			
		||||
        VT_Short, // stored as a float, kinda
 | 
			
		||||
        VT_Int,
 | 
			
		||||
        VT_Long, // stored as a float
 | 
			
		||||
        VT_Float,
 | 
			
		||||
        VT_String
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::string printName(const std::uint32_t typeId);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // COMPONENT_ESM_COMMON_H
 | 
			
		||||
							
								
								
									
										86
									
								
								components/esm/reader.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								components/esm/reader.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
#include "reader.hpp"
 | 
			
		||||
 | 
			
		||||
//#ifdef NDEBUG
 | 
			
		||||
//#undef NDEBUG
 | 
			
		||||
//#endif
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include <components/files/constrainedfilestream.hpp>
 | 
			
		||||
 | 
			
		||||
#include "components/esm3/esmreader.hpp"
 | 
			
		||||
#include "components/esm4/reader.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM
 | 
			
		||||
{
 | 
			
		||||
    Reader* Reader::getReader(const std::string &filename)
 | 
			
		||||
    {
 | 
			
		||||
        Files::IStreamPtr esmStream(Files::openConstrainedFileStream (filename.c_str ()));
 | 
			
		||||
 | 
			
		||||
        std::uint32_t modVer = 0; // get the first 4 bytes of the record header only
 | 
			
		||||
        esmStream->read((char*)&modVer, sizeof(modVer));
 | 
			
		||||
        if (esmStream->gcount() == sizeof(modVer))
 | 
			
		||||
        {
 | 
			
		||||
            esmStream->seekg(0);
 | 
			
		||||
 | 
			
		||||
            if (modVer == ESM4::REC_TES4)
 | 
			
		||||
            {
 | 
			
		||||
                return new ESM4::Reader(esmStream, filename);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                //return new ESM3::ESMReader(esmStream, filename);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw std::runtime_error("Unknown file format");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool Reader::getStringImpl(std::string& str, std::size_t size,
 | 
			
		||||
            Files::IStreamPtr filestream, ToUTF8::StatelessUtf8Encoder* encoder, bool hasNull)
 | 
			
		||||
    {
 | 
			
		||||
        std::size_t newSize = size;
 | 
			
		||||
 | 
			
		||||
        if (encoder)
 | 
			
		||||
        {
 | 
			
		||||
            std::string input(size, '\0');
 | 
			
		||||
            filestream->read(input.data(), size);
 | 
			
		||||
            if (filestream->gcount() == static_cast<std::streamsize>(size))
 | 
			
		||||
            {
 | 
			
		||||
                encoder->getUtf8(input, ToUTF8::BufferAllocationPolicy::FitToRequiredSize, str);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (hasNull)
 | 
			
		||||
                newSize -= 1; // don't read the null terminator yet
 | 
			
		||||
 | 
			
		||||
            str.resize(newSize); // assumed C++11
 | 
			
		||||
            filestream->read(&str[0], newSize);
 | 
			
		||||
            if ((std::size_t)filestream->gcount() == newSize)
 | 
			
		||||
            {
 | 
			
		||||
                if (hasNull)
 | 
			
		||||
                {
 | 
			
		||||
                    char ch;
 | 
			
		||||
                    filestream->read(&ch, 1); // read the null terminator
 | 
			
		||||
                    assert (ch == '\0'
 | 
			
		||||
                            && "ESM4::Reader::getString string is not terminated with a null");
 | 
			
		||||
                }
 | 
			
		||||
#if 0
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // NOTE: normal ESMs don't but omwsave has locals or spells with null terminator
 | 
			
		||||
                    assert (str[newSize - 1] != '\0'
 | 
			
		||||
                            && "ESM4::Reader::getString string is unexpectedly terminated with a null");
 | 
			
		||||
                }
 | 
			
		||||
#endif
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        str.clear();
 | 
			
		||||
        return false; // FIXME: throw instead?
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								components/esm/reader.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								components/esm/reader.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
#ifndef COMPONENT_ESM_READER_H
 | 
			
		||||
#define COMPONENT_ESM_READER_H
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <components/files/constrainedfilestream.hpp>
 | 
			
		||||
#include <components/to_utf8/to_utf8.hpp>
 | 
			
		||||
 | 
			
		||||
#include "common.hpp" // MasterData
 | 
			
		||||
 | 
			
		||||
namespace ToUTF8
 | 
			
		||||
{
 | 
			
		||||
    class Utf8Encoder;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace ESM
 | 
			
		||||
{
 | 
			
		||||
    class Reader
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<Reader*>* mGlobalReaderList;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        virtual ~Reader() {}
 | 
			
		||||
 | 
			
		||||
        static Reader* getReader(const std::string& filename);
 | 
			
		||||
 | 
			
		||||
        void setGlobalReaderList(std::vector<Reader*> *list) {mGlobalReaderList = list;}
 | 
			
		||||
        std::vector<Reader*> *getGlobalReaderList() {return mGlobalReaderList;}
 | 
			
		||||
 | 
			
		||||
        virtual inline bool isEsm4() const = 0;
 | 
			
		||||
 | 
			
		||||
        virtual inline bool hasMoreRecs() const = 0;
 | 
			
		||||
 | 
			
		||||
        virtual inline void setEncoder(ToUTF8::StatelessUtf8Encoder* encoder) = 0;
 | 
			
		||||
 | 
			
		||||
        // used to check for dependencies e.g. CS::Editor::run()
 | 
			
		||||
        virtual inline const std::vector<ESM::MasterData>& getGameFiles() const = 0;
 | 
			
		||||
 | 
			
		||||
        // used by ContentSelector::ContentModel::addFiles()
 | 
			
		||||
        virtual inline const std::string getAuthor() const = 0;
 | 
			
		||||
        virtual inline const std::string getDesc() const = 0;
 | 
			
		||||
        virtual inline int getFormat() const = 0;
 | 
			
		||||
 | 
			
		||||
        virtual inline std::string getFileName() const = 0;
 | 
			
		||||
 | 
			
		||||
        // used by CSMWorld::Data::startLoading() and getTotalRecords() for loading progress bar
 | 
			
		||||
        virtual inline int getRecordCount() const = 0;
 | 
			
		||||
 | 
			
		||||
        virtual void setModIndex(std::uint32_t index) = 0;
 | 
			
		||||
 | 
			
		||||
        // used by CSMWorld::Data::getTotalRecords()
 | 
			
		||||
        virtual void close() = 0;
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
        bool getStringImpl(std::string& str, std::size_t size,
 | 
			
		||||
                Files::IStreamPtr filestream, ToUTF8::StatelessUtf8Encoder* encoder, bool hasNull = false);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // COMPONENT_ESM_READER_H
 | 
			
		||||
							
								
								
									
										70
									
								
								components/esm4/acti.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								components/esm4/acti.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_ACTI_H
 | 
			
		||||
#define ESM4_ACTI_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Activator
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
        FormId mLoopingSound;    // SOUN
 | 
			
		||||
        FormId mActivationSound; // SOUN
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        FormId mRadioTemplate; // SOUN
 | 
			
		||||
        FormId mRadioStation;  // TACT
 | 
			
		||||
 | 
			
		||||
        std::string mActivationPrompt;
 | 
			
		||||
 | 
			
		||||
        Activator();
 | 
			
		||||
        virtual ~Activator();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_ACTI_H
 | 
			
		||||
							
								
								
									
										163
									
								
								components/esm4/actor.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								components/esm4/actor.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,163 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_ACTOR_H
 | 
			
		||||
#define ESM4_ACTOR_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
    struct AIData        // NPC_, CREA
 | 
			
		||||
    {
 | 
			
		||||
        std::uint8_t  aggression;
 | 
			
		||||
        std::uint8_t  confidence;
 | 
			
		||||
        std::uint8_t  energyLevel;
 | 
			
		||||
        std::uint8_t  responsibility;
 | 
			
		||||
        std::uint32_t aiFlags;
 | 
			
		||||
        std::uint8_t  trainSkill;
 | 
			
		||||
        std::uint8_t  trainLevel;
 | 
			
		||||
        std::uint16_t unknown;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct AttributeValues
 | 
			
		||||
    {
 | 
			
		||||
        std::uint8_t  strength;
 | 
			
		||||
        std::uint8_t  intelligence;
 | 
			
		||||
        std::uint8_t  willpower;
 | 
			
		||||
        std::uint8_t  agility;
 | 
			
		||||
        std::uint8_t  speed;
 | 
			
		||||
        std::uint8_t  endurance;
 | 
			
		||||
        std::uint8_t  personality;
 | 
			
		||||
        std::uint8_t  luck;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct ACBS_TES4
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t flags;
 | 
			
		||||
        std::uint16_t baseSpell;
 | 
			
		||||
        std::uint16_t fatigue;
 | 
			
		||||
        std::uint16_t barterGold;
 | 
			
		||||
        std::int16_t  levelOrOffset;
 | 
			
		||||
        std::uint16_t calcMin;
 | 
			
		||||
        std::uint16_t calcMax;
 | 
			
		||||
        std::uint32_t padding1;
 | 
			
		||||
        std::uint32_t padding2;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct ACBS_FO3
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t flags;
 | 
			
		||||
        std::uint16_t fatigue;
 | 
			
		||||
        std::uint16_t barterGold;
 | 
			
		||||
        std::int16_t  levelOrMult;
 | 
			
		||||
        std::uint16_t calcMinlevel;
 | 
			
		||||
        std::uint16_t calcMaxlevel;
 | 
			
		||||
        std::uint16_t speedMultiplier;
 | 
			
		||||
        float         karma;
 | 
			
		||||
        std::int16_t  dispositionBase;
 | 
			
		||||
        std::uint16_t templateFlags;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct ACBS_TES5
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t flags;
 | 
			
		||||
        std::uint16_t magickaOffset;
 | 
			
		||||
        std::uint16_t staminaOffset;
 | 
			
		||||
        std::uint16_t levelOrMult;     // TODO: check if int16_t
 | 
			
		||||
        std::uint16_t calcMinlevel;
 | 
			
		||||
        std::uint16_t calcMaxlevel;
 | 
			
		||||
        std::uint16_t speedMultiplier;
 | 
			
		||||
        std::uint16_t dispositionBase; // TODO: check if int16_t
 | 
			
		||||
        std::uint16_t templateFlags;
 | 
			
		||||
        std::uint16_t healthOffset;
 | 
			
		||||
        std::uint16_t bleedoutOverride;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    union ActorBaseConfig
 | 
			
		||||
    {
 | 
			
		||||
        ACBS_TES4 tes4;
 | 
			
		||||
        ACBS_FO3  fo3;
 | 
			
		||||
        ACBS_TES5 tes5;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct ActorFaction
 | 
			
		||||
    {
 | 
			
		||||
        FormId       faction;
 | 
			
		||||
        std::int8_t  rank;
 | 
			
		||||
        std::uint8_t unknown1;
 | 
			
		||||
        std::uint8_t unknown2;
 | 
			
		||||
        std::uint8_t unknown3;
 | 
			
		||||
    };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
    struct BodyTemplate // TES5
 | 
			
		||||
    {
 | 
			
		||||
        // 0x00000001 - Head
 | 
			
		||||
        // 0x00000002 - Hair
 | 
			
		||||
        // 0x00000004 - Body
 | 
			
		||||
        // 0x00000008 - Hands
 | 
			
		||||
        // 0x00000010 - Forearms
 | 
			
		||||
        // 0x00000020 - Amulet
 | 
			
		||||
        // 0x00000040 - Ring
 | 
			
		||||
        // 0x00000080 - Feet
 | 
			
		||||
        // 0x00000100 - Calves
 | 
			
		||||
        // 0x00000200 - Shield
 | 
			
		||||
        // 0x00000400 - Tail
 | 
			
		||||
        // 0x00000800 - Long Hair
 | 
			
		||||
        // 0x00001000 - Circlet
 | 
			
		||||
        // 0x00002000 - Ears
 | 
			
		||||
        // 0x00004000 - Body AddOn 3
 | 
			
		||||
        // 0x00008000 - Body AddOn 4
 | 
			
		||||
        // 0x00010000 - Body AddOn 5
 | 
			
		||||
        // 0x00020000 - Body AddOn 6
 | 
			
		||||
        // 0x00040000 - Body AddOn 7
 | 
			
		||||
        // 0x00080000 - Body AddOn 8
 | 
			
		||||
        // 0x00100000 - Decapitate Head
 | 
			
		||||
        // 0x00200000 - Decapitate
 | 
			
		||||
        // 0x00400000 - Body AddOn 9
 | 
			
		||||
        // 0x00800000 - Body AddOn 10
 | 
			
		||||
        // 0x01000000 - Body AddOn 11
 | 
			
		||||
        // 0x02000000 - Body AddOn 12
 | 
			
		||||
        // 0x04000000 - Body AddOn 13
 | 
			
		||||
        // 0x08000000 - Body AddOn 14
 | 
			
		||||
        // 0x10000000 - Body AddOn 15
 | 
			
		||||
        // 0x20000000 - Body AddOn 16
 | 
			
		||||
        // 0x40000000 - Body AddOn 17
 | 
			
		||||
        // 0x80000000 - FX01
 | 
			
		||||
        std::uint32_t bodyPart;
 | 
			
		||||
        std::uint8_t flags;
 | 
			
		||||
        std::uint8_t unknown1; // probably padding
 | 
			
		||||
        std::uint8_t unknown2; // probably padding
 | 
			
		||||
        std::uint8_t unknown3; // probably padding
 | 
			
		||||
        std::uint32_t type; // 0 = light, 1 = heavy, 2 = none (cloth?)
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_ACTOR_H
 | 
			
		||||
							
								
								
									
										100
									
								
								components/esm4/common.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								components/esm4/common.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,100 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2015-2016, 2018, 2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "common.hpp"
 | 
			
		||||
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    const char *sGroupType[] =
 | 
			
		||||
    {
 | 
			
		||||
        "Record Type", "World Child", "Interior Cell", "Interior Sub Cell", "Exterior Cell",
 | 
			
		||||
        "Exterior Sub Cell", "Cell Child", "Topic Child", "Cell Persistent Child",
 | 
			
		||||
        "Cell Temporary Child", "Cell Visible Dist Child", "Unknown"
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::string printLabel(const GroupLabel& label, const std::uint32_t type)
 | 
			
		||||
    {
 | 
			
		||||
        std::ostringstream ss;
 | 
			
		||||
        ss << std::string(sGroupType[std::min(type, (uint32_t)11)]); // avoid out of range
 | 
			
		||||
 | 
			
		||||
        switch (type)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::Grp_RecordType:
 | 
			
		||||
            {
 | 
			
		||||
                ss << ": " << std::string((char*)label.recordType, 4);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::Grp_ExteriorCell:
 | 
			
		||||
            case ESM4::Grp_ExteriorSubCell:
 | 
			
		||||
            {
 | 
			
		||||
                //short x, y;
 | 
			
		||||
                //y = label & 0xff;
 | 
			
		||||
                //x = (label >> 16) & 0xff;
 | 
			
		||||
                ss << ": grid (x, y) " << std::dec << label.grid[1] << ", " << label.grid[0];
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::Grp_InteriorCell:
 | 
			
		||||
            case ESM4::Grp_InteriorSubCell:
 | 
			
		||||
            {
 | 
			
		||||
                ss << ": block 0x" << std::hex << label.value;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::Grp_WorldChild:
 | 
			
		||||
            case ESM4::Grp_CellChild:
 | 
			
		||||
            case ESM4::Grp_TopicChild:
 | 
			
		||||
            case ESM4::Grp_CellPersistentChild:
 | 
			
		||||
            case ESM4::Grp_CellTemporaryChild:
 | 
			
		||||
            case ESM4::Grp_CellVisibleDistChild:
 | 
			
		||||
            {
 | 
			
		||||
                ss << ": FormId 0x" << formIdToString(label.value);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ss.str();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void gridToString(std::int16_t x, std::int16_t y, std::string& str)
 | 
			
		||||
    {
 | 
			
		||||
        char buf[6+6+2+1]; // longest signed 16 bit number is 6 characters (-32768)
 | 
			
		||||
        int res = snprintf(buf, 6+6+2+1, "#%d %d", x, y);
 | 
			
		||||
        if (res > 0 && res < 6+6+2+1)
 | 
			
		||||
            str.assign(buf);
 | 
			
		||||
        else
 | 
			
		||||
            throw std::runtime_error("possible buffer overflow while converting grid");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										939
									
								
								components/esm4/common.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										939
									
								
								components/esm4/common.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,939 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2015-2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
  MKTAG macro was adapated from ScummVM.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_COMMON_H
 | 
			
		||||
#define ESM4_COMMON_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
// From ScummVM's endianness.h but for little endian
 | 
			
		||||
#ifndef MKTAG
 | 
			
		||||
#define MKTAG(a0,a1,a2,a3) ((std::uint32_t)((a0) | ((a1) << 8) | ((a2) << 16) | ((a3) << 24)))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    // Based on http://www.uesp.net/wiki/Tes5Mod:Mod_File_Format
 | 
			
		||||
    enum RecordTypes
 | 
			
		||||
    {
 | 
			
		||||
        REC_AACT = MKTAG('A','A','C','T'), // Action
 | 
			
		||||
        REC_ACHR = MKTAG('A','C','H','R'), // Actor Reference
 | 
			
		||||
        REC_ACTI = MKTAG('A','C','T','I'), // Activator
 | 
			
		||||
        REC_ADDN = MKTAG('A','D','D','N'), // Addon Node
 | 
			
		||||
        REC_ALCH = MKTAG('A','L','C','H'), // Potion
 | 
			
		||||
        REC_AMMO = MKTAG('A','M','M','O'), // Ammo
 | 
			
		||||
        REC_ANIO = MKTAG('A','N','I','O'), // Animated Object
 | 
			
		||||
        REC_APPA = MKTAG('A','P','P','A'), // Apparatus (probably unused)
 | 
			
		||||
        REC_ARMA = MKTAG('A','R','M','A'), // Armature (Model)
 | 
			
		||||
        REC_ARMO = MKTAG('A','R','M','O'), // Armor
 | 
			
		||||
        REC_ARTO = MKTAG('A','R','T','O'), // Art Object
 | 
			
		||||
        REC_ASPC = MKTAG('A','S','P','C'), // Acoustic Space
 | 
			
		||||
        REC_ASTP = MKTAG('A','S','T','P'), // Association Type
 | 
			
		||||
        REC_AVIF = MKTAG('A','V','I','F'), // Actor Values/Perk Tree Graphics
 | 
			
		||||
        REC_BOOK = MKTAG('B','O','O','K'), // Book
 | 
			
		||||
        REC_BPTD = MKTAG('B','P','T','D'), // Body Part Data
 | 
			
		||||
        REC_CAMS = MKTAG('C','A','M','S'), // Camera Shot
 | 
			
		||||
        REC_CELL = MKTAG('C','E','L','L'), // Cell
 | 
			
		||||
        REC_CLAS = MKTAG('C','L','A','S'), // Class
 | 
			
		||||
        REC_CLFM = MKTAG('C','L','F','M'), // Color
 | 
			
		||||
        REC_CLMT = MKTAG('C','L','M','T'), // Climate
 | 
			
		||||
        REC_CLOT = MKTAG('C','L','O','T'), // Clothing
 | 
			
		||||
        REC_COBJ = MKTAG('C','O','B','J'), // Constructible Object (recipes)
 | 
			
		||||
        REC_COLL = MKTAG('C','O','L','L'), // Collision Layer
 | 
			
		||||
        REC_CONT = MKTAG('C','O','N','T'), // Container
 | 
			
		||||
        REC_CPTH = MKTAG('C','P','T','H'), // Camera Path
 | 
			
		||||
        REC_CREA = MKTAG('C','R','E','A'), // Creature
 | 
			
		||||
        REC_CSTY = MKTAG('C','S','T','Y'), // Combat Style
 | 
			
		||||
        REC_DEBR = MKTAG('D','E','B','R'), // Debris
 | 
			
		||||
        REC_DIAL = MKTAG('D','I','A','L'), // Dialog Topic
 | 
			
		||||
        REC_DLBR = MKTAG('D','L','B','R'), // Dialog Branch
 | 
			
		||||
        REC_DLVW = MKTAG('D','L','V','W'), // Dialog View
 | 
			
		||||
        REC_DOBJ = MKTAG('D','O','B','J'), // Default Object Manager
 | 
			
		||||
        REC_DOOR = MKTAG('D','O','O','R'), // Door
 | 
			
		||||
        REC_DUAL = MKTAG('D','U','A','L'), // Dual Cast Data (possibly unused)
 | 
			
		||||
      //REC_ECZN = MKTAG('E','C','Z','N'), // Encounter Zone
 | 
			
		||||
        REC_EFSH = MKTAG('E','F','S','H'), // Effect Shader
 | 
			
		||||
        REC_ENCH = MKTAG('E','N','C','H'), // Enchantment
 | 
			
		||||
        REC_EQUP = MKTAG('E','Q','U','P'), // Equip Slot (flag-type values)
 | 
			
		||||
        REC_EXPL = MKTAG('E','X','P','L'), // Explosion
 | 
			
		||||
        REC_EYES = MKTAG('E','Y','E','S'), // Eyes
 | 
			
		||||
        REC_FACT = MKTAG('F','A','C','T'), // Faction
 | 
			
		||||
        REC_FLOR = MKTAG('F','L','O','R'), // Flora
 | 
			
		||||
        REC_FLST = MKTAG('F','L','S','T'), // Form List (non-levelled list)
 | 
			
		||||
        REC_FSTP = MKTAG('F','S','T','P'), // Footstep
 | 
			
		||||
        REC_FSTS = MKTAG('F','S','T','S'), // Footstep Set
 | 
			
		||||
        REC_FURN = MKTAG('F','U','R','N'), // Furniture
 | 
			
		||||
        REC_GLOB = MKTAG('G','L','O','B'), // Global Variable
 | 
			
		||||
        REC_GMST = MKTAG('G','M','S','T'), // Game Setting
 | 
			
		||||
        REC_GRAS = MKTAG('G','R','A','S'), // Grass
 | 
			
		||||
        REC_GRUP = MKTAG('G','R','U','P'), // Form Group
 | 
			
		||||
        REC_HAIR = MKTAG('H','A','I','R'), // Hair
 | 
			
		||||
      //REC_HAZD = MKTAG('H','A','Z','D'), // Hazard
 | 
			
		||||
        REC_HDPT = MKTAG('H','D','P','T'), // Head Part
 | 
			
		||||
        REC_IDLE = MKTAG('I','D','L','E'), // Idle Animation
 | 
			
		||||
        REC_IDLM = MKTAG('I','D','L','M'), // Idle Marker
 | 
			
		||||
        REC_IMAD = MKTAG('I','M','A','D'), // Image Space Modifier
 | 
			
		||||
        REC_IMGS = MKTAG('I','M','G','S'), // Image Space
 | 
			
		||||
        REC_INFO = MKTAG('I','N','F','O'), // Dialog Topic Info
 | 
			
		||||
        REC_INGR = MKTAG('I','N','G','R'), // Ingredient
 | 
			
		||||
        REC_IPCT = MKTAG('I','P','C','T'), // Impact Data
 | 
			
		||||
        REC_IPDS = MKTAG('I','P','D','S'), // Impact Data Set
 | 
			
		||||
        REC_KEYM = MKTAG('K','E','Y','M'), // Key
 | 
			
		||||
        REC_KYWD = MKTAG('K','Y','W','D'), // Keyword
 | 
			
		||||
        REC_LAND = MKTAG('L','A','N','D'), // Land
 | 
			
		||||
        REC_LCRT = MKTAG('L','C','R','T'), // Location Reference Type
 | 
			
		||||
        REC_LCTN = MKTAG('L','C','T','N'), // Location
 | 
			
		||||
        REC_LGTM = MKTAG('L','G','T','M'), // Lighting Template
 | 
			
		||||
        REC_LIGH = MKTAG('L','I','G','H'), // Light
 | 
			
		||||
        REC_LSCR = MKTAG('L','S','C','R'), // Load Screen
 | 
			
		||||
        REC_LTEX = MKTAG('L','T','E','X'), // Land Texture
 | 
			
		||||
        REC_LVLC = MKTAG('L','V','L','C'), // Leveled Creature
 | 
			
		||||
        REC_LVLI = MKTAG('L','V','L','I'), // Leveled Item
 | 
			
		||||
        REC_LVLN = MKTAG('L','V','L','N'), // Leveled Actor
 | 
			
		||||
        REC_LVSP = MKTAG('L','V','S','P'), // Leveled Spell
 | 
			
		||||
        REC_MATO = MKTAG('M','A','T','O'), // Material Object
 | 
			
		||||
        REC_MATT = MKTAG('M','A','T','T'), // Material Type
 | 
			
		||||
        REC_MESG = MKTAG('M','E','S','G'), // Message
 | 
			
		||||
        REC_MGEF = MKTAG('M','G','E','F'), // Magic Effect
 | 
			
		||||
        REC_MISC = MKTAG('M','I','S','C'), // Misc. Object
 | 
			
		||||
        REC_MOVT = MKTAG('M','O','V','T'), // Movement Type
 | 
			
		||||
        REC_MSTT = MKTAG('M','S','T','T'), // Movable Static
 | 
			
		||||
        REC_MUSC = MKTAG('M','U','S','C'), // Music Type
 | 
			
		||||
        REC_MUST = MKTAG('M','U','S','T'), // Music Track
 | 
			
		||||
        REC_NAVI = MKTAG('N','A','V','I'), // Navigation (master data)
 | 
			
		||||
        REC_NAVM = MKTAG('N','A','V','M'), // Nav Mesh
 | 
			
		||||
        REC_NOTE = MKTAG('N','O','T','E'), // Note
 | 
			
		||||
        REC_NPC_ = MKTAG('N','P','C','_'), // Actor (NPC, Creature)
 | 
			
		||||
        REC_OTFT = MKTAG('O','T','F','T'), // Outfit
 | 
			
		||||
        REC_PACK = MKTAG('P','A','C','K'), // AI Package
 | 
			
		||||
        REC_PERK = MKTAG('P','E','R','K'), // Perk
 | 
			
		||||
        REC_PGRE = MKTAG('P','G','R','E'), // Placed grenade
 | 
			
		||||
        REC_PHZD = MKTAG('P','H','Z','D'), // Placed hazard
 | 
			
		||||
        REC_PROJ = MKTAG('P','R','O','J'), // Projectile
 | 
			
		||||
        REC_QUST = MKTAG('Q','U','S','T'), // Quest
 | 
			
		||||
        REC_RACE = MKTAG('R','A','C','E'), // Race / Creature type
 | 
			
		||||
        REC_REFR = MKTAG('R','E','F','R'), // Object Reference
 | 
			
		||||
        REC_REGN = MKTAG('R','E','G','N'), // Region (Audio/Weather)
 | 
			
		||||
        REC_RELA = MKTAG('R','E','L','A'), // Relationship
 | 
			
		||||
        REC_REVB = MKTAG('R','E','V','B'), // Reverb Parameters
 | 
			
		||||
        REC_RFCT = MKTAG('R','F','C','T'), // Visual Effect
 | 
			
		||||
        REC_SBSP = MKTAG('S','B','S','P'), // Subspace (TES4 only?)
 | 
			
		||||
        REC_SCEN = MKTAG('S','C','E','N'), // Scene
 | 
			
		||||
        REC_SCPT = MKTAG('S','C','P','T'), // Script
 | 
			
		||||
        REC_SCRL = MKTAG('S','C','R','L'), // Scroll
 | 
			
		||||
        REC_SGST = MKTAG('S','G','S','T'), // Sigil Stone
 | 
			
		||||
        REC_SHOU = MKTAG('S','H','O','U'), // Shout
 | 
			
		||||
        REC_SLGM = MKTAG('S','L','G','M'), // Soul Gem
 | 
			
		||||
        REC_SMBN = MKTAG('S','M','B','N'), // Story Manager Branch Node
 | 
			
		||||
        REC_SMEN = MKTAG('S','M','E','N'), // Story Manager Event Node
 | 
			
		||||
        REC_SMQN = MKTAG('S','M','Q','N'), // Story Manager Quest Node
 | 
			
		||||
        REC_SNCT = MKTAG('S','N','C','T'), // Sound Category
 | 
			
		||||
        REC_SNDR = MKTAG('S','N','D','R'), // Sound Reference
 | 
			
		||||
        REC_SOPM = MKTAG('S','O','P','M'), // Sound Output Model
 | 
			
		||||
        REC_SOUN = MKTAG('S','O','U','N'), // Sound
 | 
			
		||||
        REC_SPEL = MKTAG('S','P','E','L'), // Spell
 | 
			
		||||
        REC_SPGD = MKTAG('S','P','G','D'), // Shader Particle Geometry
 | 
			
		||||
        REC_STAT = MKTAG('S','T','A','T'), // Static
 | 
			
		||||
        REC_TACT = MKTAG('T','A','C','T'), // Talking Activator
 | 
			
		||||
        REC_TERM = MKTAG('T','E','R','M'), // Terminal
 | 
			
		||||
        REC_TES4 = MKTAG('T','E','S','4'), // Plugin info
 | 
			
		||||
        REC_TREE = MKTAG('T','R','E','E'), // Tree
 | 
			
		||||
        REC_TXST = MKTAG('T','X','S','T'), // Texture Set
 | 
			
		||||
        REC_VTYP = MKTAG('V','T','Y','P'), // Voice Type
 | 
			
		||||
        REC_WATR = MKTAG('W','A','T','R'), // Water Type
 | 
			
		||||
        REC_WEAP = MKTAG('W','E','A','P'), // Weapon
 | 
			
		||||
        REC_WOOP = MKTAG('W','O','O','P'), // Word Of Power
 | 
			
		||||
        REC_WRLD = MKTAG('W','R','L','D'), // World Space
 | 
			
		||||
        REC_WTHR = MKTAG('W','T','H','R'), // Weather
 | 
			
		||||
        REC_ACRE = MKTAG('A','C','R','E'), // Placed Creature (TES4 only?)
 | 
			
		||||
        REC_PGRD = MKTAG('P','G','R','D'), // Pathgrid (TES4 only?)
 | 
			
		||||
        REC_ROAD = MKTAG('R','O','A','D'), // Road (TES4 only?)
 | 
			
		||||
        REC_IMOD = MKTAG('I','M','O','D'), // Item Mod
 | 
			
		||||
        REC_PWAT = MKTAG('P','W','A','T'), // Placeable Water
 | 
			
		||||
        REC_SCOL = MKTAG('S','C','O','L'), // Static Collection
 | 
			
		||||
        REC_CCRD = MKTAG('C','C','R','D'), // Caravan Card
 | 
			
		||||
        REC_CMNY = MKTAG('C','M','N','Y'), // Caravan Money
 | 
			
		||||
        REC_ALOC = MKTAG('A','L','O','C'), // Audio Location Controller
 | 
			
		||||
        REC_MSET = MKTAG('M','S','E','T')  // Media Set
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum SubRecordTypes
 | 
			
		||||
    {
 | 
			
		||||
        SUB_HEDR = MKTAG('H','E','D','R'),
 | 
			
		||||
        SUB_CNAM = MKTAG('C','N','A','M'),
 | 
			
		||||
        SUB_SNAM = MKTAG('S','N','A','M'), // TES4 only?
 | 
			
		||||
        SUB_MAST = MKTAG('M','A','S','T'),
 | 
			
		||||
        SUB_DATA = MKTAG('D','A','T','A'),
 | 
			
		||||
        SUB_ONAM = MKTAG('O','N','A','M'),
 | 
			
		||||
        SUB_INTV = MKTAG('I','N','T','V'),
 | 
			
		||||
        SUB_INCC = MKTAG('I','N','C','C'),
 | 
			
		||||
        SUB_OFST = MKTAG('O','F','S','T'), // TES4 only?
 | 
			
		||||
        SUB_DELE = MKTAG('D','E','L','E'), // TES4 only?
 | 
			
		||||
 | 
			
		||||
        SUB_DNAM = MKTAG('D','N','A','M'),
 | 
			
		||||
        SUB_EDID = MKTAG('E','D','I','D'),
 | 
			
		||||
        SUB_FULL = MKTAG('F','U','L','L'),
 | 
			
		||||
        SUB_LTMP = MKTAG('L','T','M','P'),
 | 
			
		||||
        SUB_MHDT = MKTAG('M','H','D','T'),
 | 
			
		||||
        SUB_MNAM = MKTAG('M','N','A','M'),
 | 
			
		||||
        SUB_MODL = MKTAG('M','O','D','L'),
 | 
			
		||||
        SUB_NAM0 = MKTAG('N','A','M','0'),
 | 
			
		||||
        SUB_NAM2 = MKTAG('N','A','M','2'),
 | 
			
		||||
        SUB_NAM3 = MKTAG('N','A','M','3'),
 | 
			
		||||
        SUB_NAM4 = MKTAG('N','A','M','4'),
 | 
			
		||||
        SUB_NAM9 = MKTAG('N','A','M','9'),
 | 
			
		||||
        SUB_NAMA = MKTAG('N','A','M','A'),
 | 
			
		||||
        SUB_PNAM = MKTAG('P','N','A','M'),
 | 
			
		||||
        SUB_RNAM = MKTAG('R','N','A','M'),
 | 
			
		||||
        SUB_TNAM = MKTAG('T','N','A','M'),
 | 
			
		||||
        SUB_UNAM = MKTAG('U','N','A','M'),
 | 
			
		||||
        SUB_WCTR = MKTAG('W','C','T','R'),
 | 
			
		||||
        SUB_WNAM = MKTAG('W','N','A','M'),
 | 
			
		||||
        SUB_XEZN = MKTAG('X','E','Z','N'),
 | 
			
		||||
        SUB_XLCN = MKTAG('X','L','C','N'),
 | 
			
		||||
        SUB_XXXX = MKTAG('X','X','X','X'),
 | 
			
		||||
        SUB_ZNAM = MKTAG('Z','N','A','M'),
 | 
			
		||||
        SUB_MODT = MKTAG('M','O','D','T'),
 | 
			
		||||
        SUB_ICON = MKTAG('I','C','O','N'), // TES4 only?
 | 
			
		||||
 | 
			
		||||
        SUB_NVER = MKTAG('N','V','E','R'),
 | 
			
		||||
        SUB_NVMI = MKTAG('N','V','M','I'),
 | 
			
		||||
        SUB_NVPP = MKTAG('N','V','P','P'),
 | 
			
		||||
        SUB_NVSI = MKTAG('N','V','S','I'),
 | 
			
		||||
 | 
			
		||||
        SUB_NVNM = MKTAG('N','V','N','M'),
 | 
			
		||||
        SUB_NNAM = MKTAG('N','N','A','M'),
 | 
			
		||||
 | 
			
		||||
        SUB_XCLC = MKTAG('X','C','L','C'),
 | 
			
		||||
        SUB_XCLL = MKTAG('X','C','L','L'),
 | 
			
		||||
        SUB_TVDT = MKTAG('T','V','D','T'),
 | 
			
		||||
        SUB_XCGD = MKTAG('X','C','G','D'),
 | 
			
		||||
        SUB_LNAM = MKTAG('L','N','A','M'),
 | 
			
		||||
        SUB_XCLW = MKTAG('X','C','L','W'),
 | 
			
		||||
        SUB_XNAM = MKTAG('X','N','A','M'),
 | 
			
		||||
        SUB_XCLR = MKTAG('X','C','L','R'),
 | 
			
		||||
        SUB_XWCS = MKTAG('X','W','C','S'),
 | 
			
		||||
        SUB_XWCN = MKTAG('X','W','C','N'),
 | 
			
		||||
        SUB_XWCU = MKTAG('X','W','C','U'),
 | 
			
		||||
        SUB_XCWT = MKTAG('X','C','W','T'),
 | 
			
		||||
        SUB_XOWN = MKTAG('X','O','W','N'),
 | 
			
		||||
        SUB_XILL = MKTAG('X','I','L','L'),
 | 
			
		||||
        SUB_XWEM = MKTAG('X','W','E','M'),
 | 
			
		||||
        SUB_XCCM = MKTAG('X','C','C','M'),
 | 
			
		||||
        SUB_XCAS = MKTAG('X','C','A','S'),
 | 
			
		||||
        SUB_XCMO = MKTAG('X','C','M','O'),
 | 
			
		||||
        SUB_XCIM = MKTAG('X','C','I','M'),
 | 
			
		||||
        SUB_XCMT = MKTAG('X','C','M','T'), // TES4 only?
 | 
			
		||||
        SUB_XRNK = MKTAG('X','R','N','K'), // TES4 only?
 | 
			
		||||
        SUB_XGLB = MKTAG('X','G','L','B'), // TES4 only?
 | 
			
		||||
 | 
			
		||||
        SUB_VNML = MKTAG('V','N','M','L'),
 | 
			
		||||
        SUB_VHGT = MKTAG('V','H','G','T'),
 | 
			
		||||
        SUB_VCLR = MKTAG('V','C','L','R'),
 | 
			
		||||
        SUA_BTXT = MKTAG('B','T','X','T'),
 | 
			
		||||
        SUB_ATXT = MKTAG('A','T','X','T'),
 | 
			
		||||
        SUB_VTXT = MKTAG('V','T','X','T'),
 | 
			
		||||
        SUB_VTEX = MKTAG('V','T','E','X'),
 | 
			
		||||
 | 
			
		||||
        SUB_HNAM = MKTAG('H','N','A','M'),
 | 
			
		||||
        SUB_GNAM = MKTAG('G','N','A','M'),
 | 
			
		||||
 | 
			
		||||
        SUB_RCLR = MKTAG('R','C','L','R'),
 | 
			
		||||
        SUB_RPLI = MKTAG('R','P','L','I'),
 | 
			
		||||
        SUB_RPLD = MKTAG('R','P','L','D'),
 | 
			
		||||
        SUB_RDAT = MKTAG('R','D','A','T'),
 | 
			
		||||
        SUB_RDMD = MKTAG('R','D','M','D'), // TES4 only?
 | 
			
		||||
        SUB_RDSD = MKTAG('R','D','S','D'), // TES4 only?
 | 
			
		||||
        SUB_RDGS = MKTAG('R','D','G','S'), // TES4 only?
 | 
			
		||||
        SUB_RDMO = MKTAG('R','D','M','O'),
 | 
			
		||||
        SUB_RDSA = MKTAG('R','D','S','A'),
 | 
			
		||||
        SUB_RDWT = MKTAG('R','D','W','T'),
 | 
			
		||||
        SUB_RDOT = MKTAG('R','D','O','T'),
 | 
			
		||||
        SUB_RDMP = MKTAG('R','D','M','P'),
 | 
			
		||||
 | 
			
		||||
        SUB_MODB = MKTAG('M','O','D','B'),
 | 
			
		||||
        SUB_OBND = MKTAG('O','B','N','D'),
 | 
			
		||||
        SUB_MODS = MKTAG('M','O','D','S'),
 | 
			
		||||
 | 
			
		||||
        SUB_NAME = MKTAG('N','A','M','E'),
 | 
			
		||||
        SUB_XMRK = MKTAG('X','M','R','K'),
 | 
			
		||||
        SUB_FNAM = MKTAG('F','N','A','M'),
 | 
			
		||||
        SUB_XSCL = MKTAG('X','S','C','L'),
 | 
			
		||||
        SUB_XTEL = MKTAG('X','T','E','L'),
 | 
			
		||||
        SUB_XTRG = MKTAG('X','T','R','G'),
 | 
			
		||||
        SUB_XSED = MKTAG('X','S','E','D'),
 | 
			
		||||
        SUB_XLOD = MKTAG('X','L','O','D'),
 | 
			
		||||
        SUB_XPCI = MKTAG('X','P','C','I'),
 | 
			
		||||
        SUB_XLOC = MKTAG('X','L','O','C'),
 | 
			
		||||
        SUB_XESP = MKTAG('X','E','S','P'),
 | 
			
		||||
        SUB_XLCM = MKTAG('X','L','C','M'),
 | 
			
		||||
        SUB_XRTM = MKTAG('X','R','T','M'),
 | 
			
		||||
        SUB_XACT = MKTAG('X','A','C','T'),
 | 
			
		||||
        SUB_XCNT = MKTAG('X','C','N','T'),
 | 
			
		||||
        SUB_VMAD = MKTAG('V','M','A','D'),
 | 
			
		||||
        SUB_XPRM = MKTAG('X','P','R','M'),
 | 
			
		||||
        SUB_XMBO = MKTAG('X','M','B','O'),
 | 
			
		||||
        SUB_XPOD = MKTAG('X','P','O','D'),
 | 
			
		||||
        SUB_XRMR = MKTAG('X','R','M','R'),
 | 
			
		||||
        SUB_INAM = MKTAG('I','N','A','M'),
 | 
			
		||||
        SUB_SCHR = MKTAG('S','C','H','R'),
 | 
			
		||||
        SUB_XLRM = MKTAG('X','L','R','M'),
 | 
			
		||||
        SUB_XRGD = MKTAG('X','R','G','D'),
 | 
			
		||||
        SUB_XRDS = MKTAG('X','R','D','S'),
 | 
			
		||||
        SUB_XEMI = MKTAG('X','E','M','I'),
 | 
			
		||||
        SUB_XLIG = MKTAG('X','L','I','G'),
 | 
			
		||||
        SUB_XALP = MKTAG('X','A','L','P'),
 | 
			
		||||
        SUB_XNDP = MKTAG('X','N','D','P'),
 | 
			
		||||
        SUB_XAPD = MKTAG('X','A','P','D'),
 | 
			
		||||
        SUB_XAPR = MKTAG('X','A','P','R'),
 | 
			
		||||
        SUB_XLIB = MKTAG('X','L','I','B'),
 | 
			
		||||
        SUB_XLKR = MKTAG('X','L','K','R'),
 | 
			
		||||
        SUB_XLRT = MKTAG('X','L','R','T'),
 | 
			
		||||
        SUB_XCVL = MKTAG('X','C','V','L'),
 | 
			
		||||
        SUB_XCVR = MKTAG('X','C','V','R'),
 | 
			
		||||
        SUB_XCZA = MKTAG('X','C','Z','A'),
 | 
			
		||||
        SUB_XCZC = MKTAG('X','C','Z','C'),
 | 
			
		||||
        SUB_XFVC = MKTAG('X','F','V','C'),
 | 
			
		||||
        SUB_XHTW = MKTAG('X','H','T','W'),
 | 
			
		||||
        SUB_XIS2 = MKTAG('X','I','S','2'),
 | 
			
		||||
        SUB_XMBR = MKTAG('X','M','B','R'),
 | 
			
		||||
        SUB_XCCP = MKTAG('X','C','C','P'),
 | 
			
		||||
        SUB_XPWR = MKTAG('X','P','W','R'),
 | 
			
		||||
        SUB_XTRI = MKTAG('X','T','R','I'),
 | 
			
		||||
        SUB_XATR = MKTAG('X','A','T','R'),
 | 
			
		||||
        SUB_XPRD = MKTAG('X','P','R','D'),
 | 
			
		||||
        SUB_XPPA = MKTAG('X','P','P','A'),
 | 
			
		||||
        SUB_PDTO = MKTAG('P','D','T','O'),
 | 
			
		||||
        SUB_XLRL = MKTAG('X','L','R','L'),
 | 
			
		||||
 | 
			
		||||
        SUB_QNAM = MKTAG('Q','N','A','M'),
 | 
			
		||||
        SUB_COCT = MKTAG('C','O','C','T'),
 | 
			
		||||
        SUB_COED = MKTAG('C','O','E','D'),
 | 
			
		||||
        SUB_CNTO = MKTAG('C','N','T','O'),
 | 
			
		||||
        SUB_SCRI = MKTAG('S','C','R','I'),
 | 
			
		||||
 | 
			
		||||
        SUB_BNAM = MKTAG('B','N','A','M'),
 | 
			
		||||
 | 
			
		||||
        SUB_BMDT = MKTAG('B','M','D','T'),
 | 
			
		||||
        SUB_MOD2 = MKTAG('M','O','D','2'),
 | 
			
		||||
        SUB_MOD3 = MKTAG('M','O','D','3'),
 | 
			
		||||
        SUB_MOD4 = MKTAG('M','O','D','4'),
 | 
			
		||||
        SUB_MO2B = MKTAG('M','O','2','B'),
 | 
			
		||||
        SUB_MO3B = MKTAG('M','O','3','B'),
 | 
			
		||||
        SUB_MO4B = MKTAG('M','O','4','B'),
 | 
			
		||||
        SUB_MO2T = MKTAG('M','O','2','T'),
 | 
			
		||||
        SUB_MO3T = MKTAG('M','O','3','T'),
 | 
			
		||||
        SUB_MO4T = MKTAG('M','O','4','T'),
 | 
			
		||||
        SUB_ANAM = MKTAG('A','N','A','M'),
 | 
			
		||||
        SUB_ENAM = MKTAG('E','N','A','M'),
 | 
			
		||||
        SUB_ICO2 = MKTAG('I','C','O','2'),
 | 
			
		||||
 | 
			
		||||
        SUB_ACBS = MKTAG('A','C','B','S'),
 | 
			
		||||
        SUB_SPLO = MKTAG('S','P','L','O'),
 | 
			
		||||
        SUB_AIDT = MKTAG('A','I','D','T'),
 | 
			
		||||
        SUB_PKID = MKTAG('P','K','I','D'),
 | 
			
		||||
        SUB_HCLR = MKTAG('H','C','L','R'),
 | 
			
		||||
        SUB_FGGS = MKTAG('F','G','G','S'),
 | 
			
		||||
        SUB_FGGA = MKTAG('F','G','G','A'),
 | 
			
		||||
        SUB_FGTS = MKTAG('F','G','T','S'),
 | 
			
		||||
        SUB_KFFZ = MKTAG('K','F','F','Z'),
 | 
			
		||||
 | 
			
		||||
        SUB_PFIG = MKTAG('P','F','I','G'),
 | 
			
		||||
        SUB_PFPC = MKTAG('P','F','P','C'),
 | 
			
		||||
 | 
			
		||||
        SUB_XHRS = MKTAG('X','H','R','S'),
 | 
			
		||||
        SUB_XMRC = MKTAG('X','M','R','C'),
 | 
			
		||||
 | 
			
		||||
        SUB_SNDD = MKTAG('S','N','D','D'),
 | 
			
		||||
        SUB_SNDX = MKTAG('S','N','D','X'),
 | 
			
		||||
 | 
			
		||||
        SUB_DESC = MKTAG('D','E','S','C'),
 | 
			
		||||
 | 
			
		||||
        SUB_ENIT = MKTAG('E','N','I','T'),
 | 
			
		||||
        SUB_EFID = MKTAG('E','F','I','D'),
 | 
			
		||||
        SUB_EFIT = MKTAG('E','F','I','T'),
 | 
			
		||||
        SUB_SCIT = MKTAG('S','C','I','T'),
 | 
			
		||||
 | 
			
		||||
        SUB_SOUL = MKTAG('S','O','U','L'),
 | 
			
		||||
        SUB_SLCP = MKTAG('S','L','C','P'),
 | 
			
		||||
 | 
			
		||||
        SUB_CSCR = MKTAG('C','S','C','R'),
 | 
			
		||||
        SUB_CSDI = MKTAG('C','S','D','I'),
 | 
			
		||||
        SUB_CSDC = MKTAG('C','S','D','C'),
 | 
			
		||||
        SUB_NIFZ = MKTAG('N','I','F','Z'),
 | 
			
		||||
        SUB_CSDT = MKTAG('C','S','D','T'),
 | 
			
		||||
        SUB_NAM1 = MKTAG('N','A','M','1'),
 | 
			
		||||
        SUB_NIFT = MKTAG('N','I','F','T'),
 | 
			
		||||
 | 
			
		||||
        SUB_LVLD = MKTAG('L','V','L','D'),
 | 
			
		||||
        SUB_LVLF = MKTAG('L','V','L','F'),
 | 
			
		||||
        SUB_LVLO = MKTAG('L','V','L','O'),
 | 
			
		||||
 | 
			
		||||
        SUB_BODT = MKTAG('B','O','D','T'),
 | 
			
		||||
        SUB_YNAM = MKTAG('Y','N','A','M'),
 | 
			
		||||
        SUB_DEST = MKTAG('D','E','S','T'),
 | 
			
		||||
        SUB_DMDL = MKTAG('D','M','D','L'),
 | 
			
		||||
        SUB_DMDS = MKTAG('D','M','D','S'),
 | 
			
		||||
        SUB_DMDT = MKTAG('D','M','D','T'),
 | 
			
		||||
        SUB_DSTD = MKTAG('D','S','T','D'),
 | 
			
		||||
        SUB_DSTF = MKTAG('D','S','T','F'),
 | 
			
		||||
        SUB_KNAM = MKTAG('K','N','A','M'),
 | 
			
		||||
        SUB_KSIZ = MKTAG('K','S','I','Z'),
 | 
			
		||||
        SUB_KWDA = MKTAG('K','W','D','A'),
 | 
			
		||||
        SUB_VNAM = MKTAG('V','N','A','M'),
 | 
			
		||||
        SUB_SDSC = MKTAG('S','D','S','C'),
 | 
			
		||||
        SUB_MO2S = MKTAG('M','O','2','S'),
 | 
			
		||||
        SUB_MO4S = MKTAG('M','O','4','S'),
 | 
			
		||||
        SUB_BOD2 = MKTAG('B','O','D','2'),
 | 
			
		||||
        SUB_BAMT = MKTAG('B','A','M','T'),
 | 
			
		||||
        SUB_BIDS = MKTAG('B','I','D','S'),
 | 
			
		||||
        SUB_ETYP = MKTAG('E','T','Y','P'),
 | 
			
		||||
        SUB_BMCT = MKTAG('B','M','C','T'),
 | 
			
		||||
        SUB_MICO = MKTAG('M','I','C','O'),
 | 
			
		||||
        SUB_MIC2 = MKTAG('M','I','C','2'),
 | 
			
		||||
        SUB_EAMT = MKTAG('E','A','M','T'),
 | 
			
		||||
        SUB_EITM = MKTAG('E','I','T','M'),
 | 
			
		||||
 | 
			
		||||
        SUB_SCTX = MKTAG('S','C','T','X'),
 | 
			
		||||
        SUB_XLTW = MKTAG('X','L','T','W'),
 | 
			
		||||
        SUB_XMBP = MKTAG('X','M','B','P'),
 | 
			
		||||
        SUB_XOCP = MKTAG('X','O','C','P'),
 | 
			
		||||
        SUB_XRGB = MKTAG('X','R','G','B'),
 | 
			
		||||
        SUB_XSPC = MKTAG('X','S','P','C'),
 | 
			
		||||
        SUB_XTNM = MKTAG('X','T','N','M'),
 | 
			
		||||
        SUB_ATKR = MKTAG('A','T','K','R'),
 | 
			
		||||
        SUB_CRIF = MKTAG('C','R','I','F'),
 | 
			
		||||
        SUB_DOFT = MKTAG('D','O','F','T'),
 | 
			
		||||
        SUB_DPLT = MKTAG('D','P','L','T'),
 | 
			
		||||
        SUB_ECOR = MKTAG('E','C','O','R'),
 | 
			
		||||
        SUB_ATKD = MKTAG('A','T','K','D'),
 | 
			
		||||
        SUB_ATKE = MKTAG('A','T','K','E'),
 | 
			
		||||
        SUB_FTST = MKTAG('F','T','S','T'),
 | 
			
		||||
        SUB_HCLF = MKTAG('H','C','L','F'),
 | 
			
		||||
        SUB_NAM5 = MKTAG('N','A','M','5'),
 | 
			
		||||
        SUB_NAM6 = MKTAG('N','A','M','6'),
 | 
			
		||||
        SUB_NAM7 = MKTAG('N','A','M','7'),
 | 
			
		||||
        SUB_NAM8 = MKTAG('N','A','M','8'),
 | 
			
		||||
        SUB_PRKR = MKTAG('P','R','K','R'),
 | 
			
		||||
        SUB_PRKZ = MKTAG('P','R','K','Z'),
 | 
			
		||||
        SUB_SOFT = MKTAG('S','O','F','T'),
 | 
			
		||||
        SUB_SPCT = MKTAG('S','P','C','T'),
 | 
			
		||||
        SUB_TINC = MKTAG('T','I','N','C'),
 | 
			
		||||
        SUB_TIAS = MKTAG('T','I','A','S'),
 | 
			
		||||
        SUB_TINI = MKTAG('T','I','N','I'),
 | 
			
		||||
        SUB_TINV = MKTAG('T','I','N','V'),
 | 
			
		||||
        SUB_TPLT = MKTAG('T','P','L','T'),
 | 
			
		||||
        SUB_VTCK = MKTAG('V','T','C','K'),
 | 
			
		||||
        SUB_SHRT = MKTAG('S','H','R','T'),
 | 
			
		||||
        SUB_SPOR = MKTAG('S','P','O','R'),
 | 
			
		||||
        SUB_XHOR = MKTAG('X','H','O','R'),
 | 
			
		||||
        SUB_CTDA = MKTAG('C','T','D','A'),
 | 
			
		||||
        SUB_CRDT = MKTAG('C','R','D','T'),
 | 
			
		||||
        SUB_FNMK = MKTAG('F','N','M','K'),
 | 
			
		||||
        SUB_FNPR = MKTAG('F','N','P','R'),
 | 
			
		||||
        SUB_WBDT = MKTAG('W','B','D','T'),
 | 
			
		||||
        SUB_QUAL = MKTAG('Q','U','A','L'),
 | 
			
		||||
        SUB_INDX = MKTAG('I','N','D','X'),
 | 
			
		||||
        SUB_ATTR = MKTAG('A','T','T','R'),
 | 
			
		||||
        SUB_MTNM = MKTAG('M','T','N','M'),
 | 
			
		||||
        SUB_UNES = MKTAG('U','N','E','S'),
 | 
			
		||||
        SUB_TIND = MKTAG('T','I','N','D'),
 | 
			
		||||
        SUB_TINL = MKTAG('T','I','N','L'),
 | 
			
		||||
        SUB_TINP = MKTAG('T','I','N','P'),
 | 
			
		||||
        SUB_TINT = MKTAG('T','I','N','T'),
 | 
			
		||||
        SUB_TIRS = MKTAG('T','I','R','S'),
 | 
			
		||||
        SUB_PHWT = MKTAG('P','H','W','T'),
 | 
			
		||||
        SUB_AHCF = MKTAG('A','H','C','F'),
 | 
			
		||||
        SUB_AHCM = MKTAG('A','H','C','M'),
 | 
			
		||||
        SUB_HEAD = MKTAG('H','E','A','D'),
 | 
			
		||||
        SUB_MPAI = MKTAG('M','P','A','I'),
 | 
			
		||||
        SUB_MPAV = MKTAG('M','P','A','V'),
 | 
			
		||||
        SUB_DFTF = MKTAG('D','F','T','F'),
 | 
			
		||||
        SUB_DFTM = MKTAG('D','F','T','M'),
 | 
			
		||||
        SUB_FLMV = MKTAG('F','L','M','V'),
 | 
			
		||||
        SUB_FTSF = MKTAG('F','T','S','F'),
 | 
			
		||||
        SUB_FTSM = MKTAG('F','T','S','M'),
 | 
			
		||||
        SUB_MTYP = MKTAG('M','T','Y','P'),
 | 
			
		||||
        SUB_PHTN = MKTAG('P','H','T','N'),
 | 
			
		||||
        SUB_RNMV = MKTAG('R','N','M','V'),
 | 
			
		||||
        SUB_RPRF = MKTAG('R','P','R','F'),
 | 
			
		||||
        SUB_RPRM = MKTAG('R','P','R','M'),
 | 
			
		||||
        SUB_SNMV = MKTAG('S','N','M','V'),
 | 
			
		||||
        SUB_SPED = MKTAG('S','P','E','D'),
 | 
			
		||||
        SUB_SWMV = MKTAG('S','W','M','V'),
 | 
			
		||||
        SUB_WKMV = MKTAG('W','K','M','V'),
 | 
			
		||||
        SUB_LLCT = MKTAG('L','L','C','T'),
 | 
			
		||||
        SUB_IDLF = MKTAG('I','D','L','F'),
 | 
			
		||||
        SUB_IDLA = MKTAG('I','D','L','A'),
 | 
			
		||||
        SUB_IDLC = MKTAG('I','D','L','C'),
 | 
			
		||||
        SUB_IDLT = MKTAG('I','D','L','T'),
 | 
			
		||||
        SUB_DODT = MKTAG('D','O','D','T'),
 | 
			
		||||
        SUB_TX00 = MKTAG('T','X','0','0'),
 | 
			
		||||
        SUB_TX01 = MKTAG('T','X','0','1'),
 | 
			
		||||
        SUB_TX02 = MKTAG('T','X','0','2'),
 | 
			
		||||
        SUB_TX03 = MKTAG('T','X','0','3'),
 | 
			
		||||
        SUB_TX04 = MKTAG('T','X','0','4'),
 | 
			
		||||
        SUB_TX05 = MKTAG('T','X','0','5'),
 | 
			
		||||
        SUB_TX06 = MKTAG('T','X','0','6'),
 | 
			
		||||
        SUB_TX07 = MKTAG('T','X','0','7'),
 | 
			
		||||
        SUB_BPND = MKTAG('B','P','N','D'),
 | 
			
		||||
        SUB_BPTN = MKTAG('B','P','T','N'),
 | 
			
		||||
        SUB_BPNN = MKTAG('B','P','N','N'),
 | 
			
		||||
        SUB_BPNT = MKTAG('B','P','N','T'),
 | 
			
		||||
        SUB_BPNI = MKTAG('B','P','N','I'),
 | 
			
		||||
        SUB_RAGA = MKTAG('R','A','G','A'),
 | 
			
		||||
 | 
			
		||||
        SUB_QSTI = MKTAG('Q','S','T','I'),
 | 
			
		||||
        SUB_QSTR = MKTAG('Q','S','T','R'),
 | 
			
		||||
        SUB_QSDT = MKTAG('Q','S','D','T'),
 | 
			
		||||
        SUB_SCDA = MKTAG('S','C','D','A'),
 | 
			
		||||
        SUB_SCRO = MKTAG('S','C','R','O'),
 | 
			
		||||
        SUB_QSTA = MKTAG('Q','S','T','A'),
 | 
			
		||||
        SUB_CTDT = MKTAG('C','T','D','T'),
 | 
			
		||||
        SUB_SCHD = MKTAG('S','C','H','D'),
 | 
			
		||||
        SUB_TCLF = MKTAG('T','C','L','F'),
 | 
			
		||||
        SUB_TCLT = MKTAG('T','C','L','T'),
 | 
			
		||||
        SUB_TRDT = MKTAG('T','R','D','T'),
 | 
			
		||||
        SUB_TPIC = MKTAG('T','P','I','C'),
 | 
			
		||||
 | 
			
		||||
        SUB_PKDT = MKTAG('P','K','D','T'),
 | 
			
		||||
        SUB_PSDT = MKTAG('P','S','D','T'),
 | 
			
		||||
        SUB_PLDT = MKTAG('P','L','D','T'),
 | 
			
		||||
        SUB_PTDT = MKTAG('P','T','D','T'),
 | 
			
		||||
        SUB_PGRP = MKTAG('P','G','R','P'),
 | 
			
		||||
        SUB_PGRR = MKTAG('P','G','R','R'),
 | 
			
		||||
        SUB_PGRI = MKTAG('P','G','R','I'),
 | 
			
		||||
        SUB_PGRL = MKTAG('P','G','R','L'),
 | 
			
		||||
        SUB_PGAG = MKTAG('P','G','A','G'),
 | 
			
		||||
        SUB_FLTV = MKTAG('F','L','T','V'),
 | 
			
		||||
 | 
			
		||||
        SUB_XHLT = MKTAG('X','H','L','T'), // Unofficial Oblivion Patch
 | 
			
		||||
        SUB_XCHG = MKTAG('X','C','H','G'), // thievery.exp
 | 
			
		||||
 | 
			
		||||
        SUB_ITXT = MKTAG('I','T','X','T'),
 | 
			
		||||
        SUB_MO5T = MKTAG('M','O','5','T'),
 | 
			
		||||
        SUB_MOD5 = MKTAG('M','O','D','5'),
 | 
			
		||||
        SUB_MDOB = MKTAG('M','D','O','B'),
 | 
			
		||||
        SUB_SPIT = MKTAG('S','P','I','T'),
 | 
			
		||||
        SUB_PTDA = MKTAG('P','T','D','A'), // TES5
 | 
			
		||||
        SUB_PFOR = MKTAG('P','F','O','R'), // TES5
 | 
			
		||||
        SUB_PFO2 = MKTAG('P','F','O','2'), // TES5
 | 
			
		||||
        SUB_PRCB = MKTAG('P','R','C','B'), // TES5
 | 
			
		||||
        SUB_PKCU = MKTAG('P','K','C','U'), // TES5
 | 
			
		||||
        SUB_PKC2 = MKTAG('P','K','C','2'), // TES5
 | 
			
		||||
        SUB_CITC = MKTAG('C','I','T','C'), // TES5
 | 
			
		||||
        SUB_CIS1 = MKTAG('C','I','S','1'), // TES5
 | 
			
		||||
        SUB_CIS2 = MKTAG('C','I','S','2'), // TES5
 | 
			
		||||
        SUB_TIFC = MKTAG('T','I','F','C'), // TES5
 | 
			
		||||
        SUB_ALCA = MKTAG('A','L','C','A'), // TES5
 | 
			
		||||
        SUB_ALCL = MKTAG('A','L','C','L'), // TES5
 | 
			
		||||
        SUB_ALCO = MKTAG('A','L','C','O'), // TES5
 | 
			
		||||
        SUB_ALDN = MKTAG('A','L','D','N'), // TES5
 | 
			
		||||
        SUB_ALEA = MKTAG('A','L','E','A'), // TES5
 | 
			
		||||
        SUB_ALED = MKTAG('A','L','E','D'), // TES5
 | 
			
		||||
        SUB_ALEQ = MKTAG('A','L','E','Q'), // TES5
 | 
			
		||||
        SUB_ALFA = MKTAG('A','L','F','A'), // TES5
 | 
			
		||||
        SUB_ALFC = MKTAG('A','L','F','C'), // TES5
 | 
			
		||||
        SUB_ALFD = MKTAG('A','L','F','D'), // TES5
 | 
			
		||||
        SUB_ALFE = MKTAG('A','L','F','E'), // TES5
 | 
			
		||||
        SUB_ALFI = MKTAG('A','L','F','I'), // TES5
 | 
			
		||||
        SUB_ALFL = MKTAG('A','L','F','L'), // TES5
 | 
			
		||||
        SUB_ALFR = MKTAG('A','L','F','R'), // TES5
 | 
			
		||||
        SUB_ALID = MKTAG('A','L','I','D'), // TES5
 | 
			
		||||
        SUB_ALLS = MKTAG('A','L','L','S'), // TES5
 | 
			
		||||
        SUB_ALNA = MKTAG('A','L','N','A'), // TES5
 | 
			
		||||
        SUB_ALNT = MKTAG('A','L','N','T'), // TES5
 | 
			
		||||
        SUB_ALPC = MKTAG('A','L','P','C'), // TES5
 | 
			
		||||
        SUB_ALRT = MKTAG('A','L','R','T'), // TES5
 | 
			
		||||
        SUB_ALSP = MKTAG('A','L','S','P'), // TES5
 | 
			
		||||
        SUB_ALST = MKTAG('A','L','S','T'), // TES5
 | 
			
		||||
        SUB_ALUA = MKTAG('A','L','U','A'), // TES5
 | 
			
		||||
        SUB_FLTR = MKTAG('F','L','T','R'), // TES5
 | 
			
		||||
        SUB_QTGL = MKTAG('Q','T','G','L'), // TES5
 | 
			
		||||
        SUB_TWAT = MKTAG('T','W','A','T'), // TES5
 | 
			
		||||
        SUB_XIBS = MKTAG('X','I','B','S'), // FO3
 | 
			
		||||
        SUB_REPL = MKTAG('R','E','P','L'), // FO3
 | 
			
		||||
        SUB_BIPL = MKTAG('B','I','P','L'), // FO3
 | 
			
		||||
        SUB_MODD = MKTAG('M','O','D','D'), // FO3
 | 
			
		||||
        SUB_MOSD = MKTAG('M','O','S','D'), // FO3
 | 
			
		||||
        SUB_MO3S = MKTAG('M','O','3','S'), // FO3
 | 
			
		||||
        SUB_XCET = MKTAG('X','C','E','T'), // FO3
 | 
			
		||||
        SUB_LVLG = MKTAG('L','V','L','G'), // FO3
 | 
			
		||||
        SUB_NVCI = MKTAG('N','V','C','I'), // FO3
 | 
			
		||||
        SUB_NVVX = MKTAG('N','V','V','X'), // FO3
 | 
			
		||||
        SUB_NVTR = MKTAG('N','V','T','R'), // FO3
 | 
			
		||||
        SUB_NVCA = MKTAG('N','V','C','A'), // FO3
 | 
			
		||||
        SUB_NVDP = MKTAG('N','V','D','P'), // FO3
 | 
			
		||||
        SUB_NVGD = MKTAG('N','V','G','D'), // FO3
 | 
			
		||||
        SUB_NVEX = MKTAG('N','V','E','X'), // FO3
 | 
			
		||||
        SUB_XHLP = MKTAG('X','H','L','P'), // FO3
 | 
			
		||||
        SUB_XRDO = MKTAG('X','R','D','O'), // FO3
 | 
			
		||||
        SUB_XAMT = MKTAG('X','A','M','T'), // FO3
 | 
			
		||||
        SUB_XAMC = MKTAG('X','A','M','C'), // FO3
 | 
			
		||||
        SUB_XRAD = MKTAG('X','R','A','D'), // FO3
 | 
			
		||||
        SUB_XORD = MKTAG('X','O','R','D'), // FO3
 | 
			
		||||
        SUB_XCLP = MKTAG('X','C','L','P'), // FO3
 | 
			
		||||
        SUB_NEXT = MKTAG('N','E','X','T'), // FO3
 | 
			
		||||
        SUB_QOBJ = MKTAG('Q','O','B','J'), // FO3
 | 
			
		||||
        SUB_POBA = MKTAG('P','O','B','A'), // FO3
 | 
			
		||||
        SUB_POCA = MKTAG('P','O','C','A'), // FO3
 | 
			
		||||
        SUB_POEA = MKTAG('P','O','E','A'), // FO3
 | 
			
		||||
        SUB_PKDD = MKTAG('P','K','D','D'), // FO3
 | 
			
		||||
        SUB_PKD2 = MKTAG('P','K','D','2'), // FO3
 | 
			
		||||
        SUB_PKPT = MKTAG('P','K','P','T'), // FO3
 | 
			
		||||
        SUB_PKED = MKTAG('P','K','E','D'), // FO3
 | 
			
		||||
        SUB_PKE2 = MKTAG('P','K','E','2'), // FO3
 | 
			
		||||
        SUB_PKAM = MKTAG('P','K','A','M'), // FO3
 | 
			
		||||
        SUB_PUID = MKTAG('P','U','I','D'), // FO3
 | 
			
		||||
        SUB_PKW3 = MKTAG('P','K','W','3'), // FO3
 | 
			
		||||
        SUB_PTD2 = MKTAG('P','T','D','2'), // FO3
 | 
			
		||||
        SUB_PLD2 = MKTAG('P','L','D','2'), // FO3
 | 
			
		||||
        SUB_PKFD = MKTAG('P','K','F','D'), // FO3
 | 
			
		||||
        SUB_IDLB = MKTAG('I','D','L','B'), // FO3
 | 
			
		||||
        SUB_XDCR = MKTAG('X','D','C','R'), // FO3
 | 
			
		||||
        SUB_DALC = MKTAG('D','A','L','C'), // FO3
 | 
			
		||||
        SUB_IMPS = MKTAG('I','M','P','S'), // FO3 Anchorage
 | 
			
		||||
        SUB_IMPF = MKTAG('I','M','P','F'), // FO3 Anchorage
 | 
			
		||||
 | 
			
		||||
        SUB_XATO = MKTAG('X','A','T','O'), // FONV
 | 
			
		||||
        SUB_INFC = MKTAG('I','N','F','C'), // FONV
 | 
			
		||||
        SUB_INFX = MKTAG('I','N','F','X'), // FONV
 | 
			
		||||
        SUB_TDUM = MKTAG('T','D','U','M'), // FONV
 | 
			
		||||
        SUB_TCFU = MKTAG('T','C','F','U'), // FONV
 | 
			
		||||
        SUB_DAT2 = MKTAG('D','A','T','2'), // FONV
 | 
			
		||||
        SUB_RCIL = MKTAG('R','C','I','L'), // FONV
 | 
			
		||||
        SUB_MMRK = MKTAG('M','M','R','K'), // FONV
 | 
			
		||||
        SUB_SCRV = MKTAG('S','C','R','V'), // FONV
 | 
			
		||||
        SUB_SCVR = MKTAG('S','C','V','R'), // FONV
 | 
			
		||||
        SUB_SLSD = MKTAG('S','L','S','D'), // FONV
 | 
			
		||||
        SUB_XSRF = MKTAG('X','S','R','F'), // FONV
 | 
			
		||||
        SUB_XSRD = MKTAG('X','S','R','D'), // FONV
 | 
			
		||||
        SUB_WMI1 = MKTAG('W','M','I','1'), // FONV
 | 
			
		||||
        SUB_RDID = MKTAG('R','D','I','D'), // FONV
 | 
			
		||||
        SUB_RDSB = MKTAG('R','D','S','B'), // FONV
 | 
			
		||||
        SUB_RDSI = MKTAG('R','D','S','I'), // FONV
 | 
			
		||||
        SUB_BRUS = MKTAG('B','R','U','S'), // FONV
 | 
			
		||||
        SUB_VATS = MKTAG('V','A','T','S'), // FONV
 | 
			
		||||
        SUB_VANM = MKTAG('V','A','N','M'), // FONV
 | 
			
		||||
        SUB_MWD1 = MKTAG('M','W','D','1'), // FONV
 | 
			
		||||
        SUB_MWD2 = MKTAG('M','W','D','2'), // FONV
 | 
			
		||||
        SUB_MWD3 = MKTAG('M','W','D','3'), // FONV
 | 
			
		||||
        SUB_MWD4 = MKTAG('M','W','D','4'), // FONV
 | 
			
		||||
        SUB_MWD5 = MKTAG('M','W','D','5'), // FONV
 | 
			
		||||
        SUB_MWD6 = MKTAG('M','W','D','6'), // FONV
 | 
			
		||||
        SUB_MWD7 = MKTAG('M','W','D','7'), // FONV
 | 
			
		||||
        SUB_WMI2 = MKTAG('W','M','I','2'), // FONV
 | 
			
		||||
        SUB_WMI3 = MKTAG('W','M','I','3'), // FONV
 | 
			
		||||
        SUB_WMS1 = MKTAG('W','M','S','1'), // FONV
 | 
			
		||||
        SUB_WMS2 = MKTAG('W','M','S','2'), // FONV
 | 
			
		||||
        SUB_WNM1 = MKTAG('W','N','M','1'), // FONV
 | 
			
		||||
        SUB_WNM2 = MKTAG('W','N','M','2'), // FONV
 | 
			
		||||
        SUB_WNM3 = MKTAG('W','N','M','3'), // FONV
 | 
			
		||||
        SUB_WNM4 = MKTAG('W','N','M','4'), // FONV
 | 
			
		||||
        SUB_WNM5 = MKTAG('W','N','M','5'), // FONV
 | 
			
		||||
        SUB_WNM6 = MKTAG('W','N','M','6'), // FONV
 | 
			
		||||
        SUB_WNM7 = MKTAG('W','N','M','7'), // FONV
 | 
			
		||||
        SUB_JNAM = MKTAG('J','N','A','M'), // FONV
 | 
			
		||||
        SUB_EFSD = MKTAG('E','F','S','D'), // FONV DeadMoney
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum MagicEffectID
 | 
			
		||||
    {
 | 
			
		||||
        // Alteration
 | 
			
		||||
        EFI_BRDN = MKTAG('B','R','D','N'),
 | 
			
		||||
        EFI_FTHR = MKTAG('F','T','H','R'),
 | 
			
		||||
        EFI_FISH = MKTAG('F','I','S','H'),
 | 
			
		||||
        EFI_FRSH = MKTAG('F','R','S','H'),
 | 
			
		||||
        EFI_OPEN = MKTAG('O','P','N','N'),
 | 
			
		||||
        EFI_SHLD = MKTAG('S','H','L','D'),
 | 
			
		||||
        EFI_LISH = MKTAG('L','I','S','H'),
 | 
			
		||||
        EFI_WABR = MKTAG('W','A','B','R'),
 | 
			
		||||
        EFI_WAWA = MKTAG('W','A','W','A'),
 | 
			
		||||
 | 
			
		||||
        // Conjuration
 | 
			
		||||
        EFI_BABO = MKTAG('B','A','B','O'), // Bound Boots
 | 
			
		||||
        EFI_BACU = MKTAG('B','A','C','U'), // Bound Cuirass
 | 
			
		||||
        EFI_BAGA = MKTAG('B','A','G','A'), // Bound Gauntlets
 | 
			
		||||
        EFI_BAGR = MKTAG('B','A','G','R'), // Bound Greaves
 | 
			
		||||
        EFI_BAHE = MKTAG('B','A','H','E'), // Bound Helmet
 | 
			
		||||
        EFI_BASH = MKTAG('B','A','S','H'), // Bound Shield
 | 
			
		||||
        EFI_BWAX = MKTAG('B','W','A','X'), // Bound Axe
 | 
			
		||||
        EFI_BWBO = MKTAG('B','W','B','O'), // Bound Bow
 | 
			
		||||
        EFI_BWDA = MKTAG('B','W','D','A'), // Bound Dagger
 | 
			
		||||
        EFI_BWMA = MKTAG('B','W','M','A'), // Bound Mace
 | 
			
		||||
        EFI_BWSW = MKTAG('B','W','S','W'), // Bound Sword
 | 
			
		||||
        EFI_Z001 = MKTAG('Z','0','0','1'), // Summon Rufio's Ghost
 | 
			
		||||
        EFI_Z002 = MKTAG('Z','0','0','2'), // Summon Ancestor Guardian
 | 
			
		||||
        EFI_Z003 = MKTAG('Z','0','0','3'), // Summon Spiderling
 | 
			
		||||
        EFI_Z005 = MKTAG('Z','0','0','5'), // Summon Bear
 | 
			
		||||
        EFI_ZCLA = MKTAG('Z','C','L','A'), // Summon Clannfear
 | 
			
		||||
        EFI_ZDAE = MKTAG('Z','D','A','E'), // Summon Daedroth
 | 
			
		||||
        EFI_ZDRE = MKTAG('Z','D','R','E'), // Summon Dremora
 | 
			
		||||
        EFI_ZDRL = MKTAG('Z','D','R','L'), // Summon Dremora Lord
 | 
			
		||||
        EFI_ZFIA = MKTAG('Z','F','I','A'), // Summon Flame Atronach
 | 
			
		||||
        EFI_ZFRA = MKTAG('Z','F','R','A'), // Summon Frost Atronach
 | 
			
		||||
        EFI_ZGHO = MKTAG('Z','G','H','O'), // Summon Ghost
 | 
			
		||||
        EFI_ZHDZ = MKTAG('Z','H','D','Z'), // Summon Headless Zombie
 | 
			
		||||
        EFI_ZLIC = MKTAG('Z','L','I','C'), // Summon Lich
 | 
			
		||||
        EFI_ZSCA = MKTAG('Z','S','C','A'), // Summon Scamp
 | 
			
		||||
        EFI_ZSKE = MKTAG('Z','S','K','E'), // Summon Skeleton
 | 
			
		||||
        EFI_ZSKA = MKTAG('Z','S','K','A'), // Summon Skeleton Guardian
 | 
			
		||||
        EFI_ZSKH = MKTAG('Z','S','K','H'), // Summon Skeleton Hero
 | 
			
		||||
        EFI_ZSKC = MKTAG('Z','S','K','C'), // Summon Skeleton Champion
 | 
			
		||||
        EFI_ZSPD = MKTAG('Z','S','P','D'), // Summon Spider Daedra
 | 
			
		||||
        EFI_ZSTA = MKTAG('Z','S','T','A'), // Summon Storm Atronach
 | 
			
		||||
        EFI_ZWRA = MKTAG('Z','W','R','A'), // Summon Faded Wraith
 | 
			
		||||
        EFI_ZWRL = MKTAG('Z','W','R','L'), // Summon Gloom Wraith
 | 
			
		||||
        EFI_ZXIV = MKTAG('Z','X','I','V'), // Summon Xivilai
 | 
			
		||||
        EFI_ZZOM = MKTAG('Z','Z','O','M'), // Summon Zombie
 | 
			
		||||
        EFI_TURN = MKTAG('T','U','R','N'), // Turn Undead
 | 
			
		||||
 | 
			
		||||
        // Destruction
 | 
			
		||||
        EFI_DGAT = MKTAG('D','G','A','T'), // Damage Attribute
 | 
			
		||||
        EFI_DGFA = MKTAG('D','G','F','A'), // Damage Fatigue
 | 
			
		||||
        EFI_DGHE = MKTAG('D','G','H','E'), // Damage Health
 | 
			
		||||
        EFI_DGSP = MKTAG('D','G','S','P'), // Damage Magicka
 | 
			
		||||
        EFI_DIAR = MKTAG('D','I','A','R'), // Disintegrate Armor
 | 
			
		||||
        EFI_DIWE = MKTAG('D','I','W','E'), // Disintegrate Weapon
 | 
			
		||||
        EFI_DRAT = MKTAG('D','R','A','T'), // Drain Attribute
 | 
			
		||||
        EFI_DRFA = MKTAG('D','R','F','A'), // Drain Fatigue
 | 
			
		||||
        EFI_DRHE = MKTAG('D','R','H','E'), // Drain Health
 | 
			
		||||
        EFI_DRSP = MKTAG('D','R','S','P'), // Drain Magicka
 | 
			
		||||
        EFI_DRSK = MKTAG('D','R','S','K'), // Drain Skill
 | 
			
		||||
        EFI_FIDG = MKTAG('F','I','D','G'), // Fire Damage
 | 
			
		||||
        EFI_FRDG = MKTAG('F','R','D','G'), // Frost Damage
 | 
			
		||||
        EFI_SHDG = MKTAG('S','H','D','G'), // Shock Damage
 | 
			
		||||
        EFI_WKDI = MKTAG('W','K','D','I'), // Weakness to Disease
 | 
			
		||||
        EFI_WKFI = MKTAG('W','K','F','I'), // Weakness to Fire
 | 
			
		||||
        EFI_WKFR = MKTAG('W','K','F','R'), // Weakness to Frost
 | 
			
		||||
        EFI_WKMA = MKTAG('W','K','M','A'), // Weakness to Magic
 | 
			
		||||
        EFI_WKNW = MKTAG('W','K','N','W'), // Weakness to Normal Weapons
 | 
			
		||||
        EFI_WKPO = MKTAG('W','K','P','O'), // Weakness to Poison
 | 
			
		||||
        EFI_WKSH = MKTAG('W','K','S','H'), // Weakness to Shock
 | 
			
		||||
 | 
			
		||||
        // Illusion
 | 
			
		||||
        EFI_CALM = MKTAG('C','A','L','M'), // Calm
 | 
			
		||||
        EFI_CHML = MKTAG('C','H','M','L'), // Chameleon
 | 
			
		||||
        EFI_CHRM = MKTAG('C','H','R','M'), // Charm
 | 
			
		||||
        EFI_COCR = MKTAG('C','O','C','R'), // Command Creature
 | 
			
		||||
        EFI_COHU = MKTAG('C','O','H','U'), // Command Humanoid
 | 
			
		||||
        EFI_DEMO = MKTAG('D','E','M','O'), // Demoralize
 | 
			
		||||
        EFI_FRNZ = MKTAG('F','R','N','Z'), // Frenzy
 | 
			
		||||
        EFI_INVI = MKTAG('I','N','V','I'), // Invisibility
 | 
			
		||||
        EFI_LGHT = MKTAG('L','G','H','T'), // Light
 | 
			
		||||
        EFI_NEYE = MKTAG('N','E','Y','E'), // Night-Eye
 | 
			
		||||
        EFI_PARA = MKTAG('P','A','R','A'), // Paralyze
 | 
			
		||||
        EFI_RALY = MKTAG('R','A','L','Y'), // Rally
 | 
			
		||||
        EFI_SLNC = MKTAG('S','L','N','C'), // Silence
 | 
			
		||||
 | 
			
		||||
        // Mysticism
 | 
			
		||||
        EFI_DTCT = MKTAG('D','T','C','T'), // Detect Life
 | 
			
		||||
        EFI_DSPL = MKTAG('D','S','P','L'), // Dispel
 | 
			
		||||
        EFI_REDG = MKTAG('R','E','D','G'), // Reflect Damage
 | 
			
		||||
        EFI_RFLC = MKTAG('R','F','L','C'), // Reflect Spell
 | 
			
		||||
        EFI_STRP = MKTAG('S','T','R','P'), // Soul Trap
 | 
			
		||||
        EFI_SABS = MKTAG('S','A','B','S'), // Spell Absorption
 | 
			
		||||
        EFI_TELE = MKTAG('T','E','L','E'), // Telekinesis
 | 
			
		||||
 | 
			
		||||
        // Restoration
 | 
			
		||||
        EFI_ABAT = MKTAG('A','B','A','T'), // Absorb Attribute
 | 
			
		||||
        EFI_ABFA = MKTAG('A','B','F','A'), // Absorb Fatigue
 | 
			
		||||
        EFI_ABHe = MKTAG('A','B','H','e'), // Absorb Health
 | 
			
		||||
        EFI_ABSP = MKTAG('A','B','S','P'), // Absorb Magicka
 | 
			
		||||
        EFI_ABSK = MKTAG('A','B','S','K'), // Absorb Skill
 | 
			
		||||
        EFI_1400 = MKTAG('1','4','0','0'), // Cure Disease
 | 
			
		||||
        EFI_CUPA = MKTAG('C','U','P','A'), // Cure Paralysis
 | 
			
		||||
        EFI_CUPO = MKTAG('C','U','P','O'), // Cure Poison
 | 
			
		||||
        EFI_FOAT = MKTAG('F','O','A','T'), // Fortify Attribute
 | 
			
		||||
        EFI_FOFA = MKTAG('F','O','F','A'), // Fortify Fatigue
 | 
			
		||||
        EFI_FOHE = MKTAG('F','O','H','E'), // Fortify Health
 | 
			
		||||
        EFI_FOSP = MKTAG('F','O','S','P'), // Fortify Magicka
 | 
			
		||||
        EFI_FOSK = MKTAG('F','O','S','K'), // Fortify Skill
 | 
			
		||||
        EFI_RSDI = MKTAG('R','S','D','I'), // Resist Disease
 | 
			
		||||
        EFI_RSFI = MKTAG('R','S','F','I'), // Resist Fire
 | 
			
		||||
        EFI_RSFR = MKTAG('R','S','F','R'), // Resist Frost
 | 
			
		||||
        EFI_RSMA = MKTAG('R','S','M','A'), // Resist Magic
 | 
			
		||||
        EFI_RSNW = MKTAG('R','S','N','W'), // Resist Normal Weapons
 | 
			
		||||
        EFI_RSPA = MKTAG('R','S','P','A'), // Resist Paralysis
 | 
			
		||||
        EFI_RSPO = MKTAG('R','S','P','O'), // Resist Poison
 | 
			
		||||
        EFI_RSSH = MKTAG('R','S','S','H'), // Resist Shock
 | 
			
		||||
        EFI_REAT = MKTAG('R','E','A','T'), // Restore Attribute
 | 
			
		||||
        EFI_REFA = MKTAG('R','E','F','A'), // Restore Fatigue
 | 
			
		||||
        EFI_REHE = MKTAG('R','E','H','E'), // Restore Health
 | 
			
		||||
        EFI_RESP = MKTAG('R','E','S','P'), // Restore Magicka
 | 
			
		||||
 | 
			
		||||
        // Effects
 | 
			
		||||
        EFI_LOCK = MKTAG('L','O','C','K'), // Lock Lock
 | 
			
		||||
        EFI_SEFF = MKTAG('S','E','F','F'), // Script Effect
 | 
			
		||||
        EFI_Z020 = MKTAG('Z','0','2','0'), // Summon 20 Extra
 | 
			
		||||
        EFI_MYHL = MKTAG('M','Y','H','L'), // Summon Mythic Dawn Helmet
 | 
			
		||||
        EFI_MYTH = MKTAG('M','Y','T','H'), // Summon Mythic Dawn Armor
 | 
			
		||||
        EFI_REAN = MKTAG('R','E','A','N'), // Reanimate
 | 
			
		||||
        EFI_DISE = MKTAG('D','I','S','E'), // Disease Info
 | 
			
		||||
        EFI_POSN = MKTAG('P','O','S','N'), // Poison Info
 | 
			
		||||
        EFI_DUMY = MKTAG('D','U','M','Y'), // Mehrunes Dagon Custom Effect
 | 
			
		||||
        EFI_STMA = MKTAG('S','T','M','A'), // Stunted Magicka
 | 
			
		||||
        EFI_SUDG = MKTAG('S','U','D','G'), // Sun Damage
 | 
			
		||||
        EFI_VAMP = MKTAG('V','A','M','P'), // Vampirism
 | 
			
		||||
        EFI_DARK = MKTAG('D','A','R','K'), // Darkness
 | 
			
		||||
        EFI_RSWD = MKTAG('R','S','W','D')  // Resist Water Damage
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Based on http://www.uesp.net/wiki/Tes5Mod:Mod_File_Format#Groups
 | 
			
		||||
    enum GroupType
 | 
			
		||||
    {
 | 
			
		||||
        Grp_RecordType           = 0,
 | 
			
		||||
        Grp_WorldChild           = 1,
 | 
			
		||||
        Grp_InteriorCell         = 2,
 | 
			
		||||
        Grp_InteriorSubCell      = 3,
 | 
			
		||||
        Grp_ExteriorCell         = 4,
 | 
			
		||||
        Grp_ExteriorSubCell      = 5,
 | 
			
		||||
        Grp_CellChild            = 6,
 | 
			
		||||
        Grp_TopicChild           = 7,
 | 
			
		||||
        Grp_CellPersistentChild  = 8,
 | 
			
		||||
        Grp_CellTemporaryChild   = 9,
 | 
			
		||||
        Grp_CellVisibleDistChild = 10
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Based on http://www.uesp.net/wiki/Tes5Mod:Mod_File_Format#Records
 | 
			
		||||
    enum RecordFlag
 | 
			
		||||
    {
 | 
			
		||||
        Rec_ESM        = 0x00000001, // (TES4 record only) Master (ESM) file.
 | 
			
		||||
        Rec_Deleted    = 0x00000020, // Deleted
 | 
			
		||||
        Rec_Constant   = 0x00000040, // Constant
 | 
			
		||||
        Rec_HiddenLMap = 0x00000040, // (REFR) Hidden From Local Map (Needs Confirmation: Related to shields)
 | 
			
		||||
        Rec_Localized  = 0x00000080, // (TES4 record only) Is localized. This will make Skyrim load the
 | 
			
		||||
                                     //   .STRINGS, .DLSTRINGS, and .ILSTRINGS files associated with the mod.
 | 
			
		||||
                                     //   If this flag is not set, lstrings are treated as zstrings.
 | 
			
		||||
        Rec_FireOff    = 0x00000080, // (PHZD) Turn off fire
 | 
			
		||||
        Rec_UpdateAnim = 0x00000100, // Must Update Anims
 | 
			
		||||
        Rec_NoAccess   = 0x00000100, // (REFR) Inaccessible
 | 
			
		||||
        Rec_Hidden     = 0x00000200, // (REFR) Hidden from local map
 | 
			
		||||
        Rec_StartDead  = 0x00000200, // (ACHR) Starts dead /(REFR) MotionBlurCastsShadows
 | 
			
		||||
        Rec_Persistent = 0x00000400, // Quest item / Persistent reference
 | 
			
		||||
        Rec_DispMenu   = 0x00000400, // (LSCR) Displays in Main Menu
 | 
			
		||||
        Rec_Disabled   = 0x00000800, // Initially disabled
 | 
			
		||||
        Rec_Ignored    = 0x00001000, // Ignored
 | 
			
		||||
        Rec_VisDistant = 0x00008000, // Visible when distant
 | 
			
		||||
        Rec_RandAnim   = 0x00010000, // (ACTI) Random Animation Start
 | 
			
		||||
        Rec_Danger     = 0x00020000, // (ACTI) Dangerous / Off limits (Interior cell)
 | 
			
		||||
                                     //   Dangerous Can't be set withough Ignore Object Interaction
 | 
			
		||||
        Rec_Compressed = 0x00040000, // Data is compressed
 | 
			
		||||
        Rec_CanNotWait = 0x00080000, // Can't wait
 | 
			
		||||
        Rec_IgnoreObj  = 0x00100000, // (ACTI) Ignore Object Interaction
 | 
			
		||||
                                     //   Ignore Object Interaction Sets Dangerous Automatically
 | 
			
		||||
        Rec_Marker     = 0x00800000, // Is Marker
 | 
			
		||||
        Rec_Obstacle   = 0x02000000, // (ACTI) Obstacle / (REFR) No AI Acquire
 | 
			
		||||
        Rec_NavMFilter = 0x04000000, // NavMesh Gen - Filter
 | 
			
		||||
        Rec_NavMBBox   = 0x08000000, // NavMesh Gen - Bounding Box
 | 
			
		||||
        Rec_ExitToTalk = 0x10000000, // (FURN) Must Exit to Talk
 | 
			
		||||
        Rec_Refected   = 0x10000000, // (REFR) Reflected By Auto Water
 | 
			
		||||
        Rec_ChildUse   = 0x20000000, // (FURN/IDLM) Child Can Use
 | 
			
		||||
        Rec_NoHavok    = 0x20000000, // (REFR) Don't Havok Settle
 | 
			
		||||
        Rec_NavMGround = 0x40000000, // NavMesh Gen - Ground
 | 
			
		||||
        Rec_NoRespawn  = 0x40000000, // (REFR) NoRespawn
 | 
			
		||||
        Rec_MultiBound = 0x80000000  // (REFR) MultiBound
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
    // NOTE: the label field of a group is not reliable (http://www.uesp.net/wiki/Tes4Mod:Mod_File_Format)
 | 
			
		||||
    union GroupLabel
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t value;     // formId, blockNo or raw int representation of type
 | 
			
		||||
        char recordType[4];      // record type in ascii
 | 
			
		||||
        std::int16_t grid[2];    // grid y, x (note the reverse order)
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct GroupTypeHeader
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t typeId;
 | 
			
		||||
        std::uint32_t groupSize; // includes the 24 bytes (20 for TES4) of header (i.e. this struct)
 | 
			
		||||
        GroupLabel    label;     // format based on type
 | 
			
		||||
        std::int32_t  type;
 | 
			
		||||
        std::uint16_t stamp;     // & 0xff for day, & 0xff00 for months since Dec 2002 (i.e. 1 = Jan 2003)
 | 
			
		||||
        std::uint16_t unknown;
 | 
			
		||||
        std::uint16_t version;   // not in TES4
 | 
			
		||||
        std::uint16_t unknown2;  // not in TES4
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct RecordTypeHeader
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t typeId;
 | 
			
		||||
        std::uint32_t dataSize;  // does *not* include 24 bytes (20 for TES4) of header
 | 
			
		||||
        std::uint32_t flags;
 | 
			
		||||
        FormId        id;
 | 
			
		||||
        std::uint32_t revision;
 | 
			
		||||
        std::uint16_t version;  // not in TES4
 | 
			
		||||
        std::uint16_t unknown;  // not in TES4
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    union RecordHeader
 | 
			
		||||
    {
 | 
			
		||||
        struct GroupTypeHeader  group;
 | 
			
		||||
        struct RecordTypeHeader record;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct SubRecordHeader
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t typeId;
 | 
			
		||||
        std::uint16_t dataSize;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Grid, CellGrid and Vertex are shared by NVMI(NAVI) and NVNM(NAVM)
 | 
			
		||||
 | 
			
		||||
    struct Grid
 | 
			
		||||
    {
 | 
			
		||||
        std::int16_t x;
 | 
			
		||||
        std::int16_t y;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    union CellGrid
 | 
			
		||||
    {
 | 
			
		||||
        FormId cellId;
 | 
			
		||||
        Grid   grid;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct Vertex
 | 
			
		||||
    {
 | 
			
		||||
        float x;
 | 
			
		||||
        float y;
 | 
			
		||||
        float z;
 | 
			
		||||
    };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
    // For pretty printing GroupHeader labels
 | 
			
		||||
    std::string printLabel(const GroupLabel& label, const std::uint32_t type);
 | 
			
		||||
 | 
			
		||||
    void gridToString(std::int16_t x, std::int16_t y, std::string& str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_COMMON_H
 | 
			
		||||
							
								
								
									
										46
									
								
								components/esm4/dialogue.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								components/esm4/dialogue.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_DIALOGUE_H
 | 
			
		||||
#define ESM4_DIALOGUE_H
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    enum DialType
 | 
			
		||||
    {
 | 
			
		||||
        DTYP_Topic         = 0,
 | 
			
		||||
        DTYP_Conversation  = 1,
 | 
			
		||||
        DTYP_Combat        = 2,
 | 
			
		||||
        DTYP_Persuation    = 3,
 | 
			
		||||
        DTYP_Detection     = 4,
 | 
			
		||||
        DTYP_Service       = 5,
 | 
			
		||||
        DTYP_Miscellaneous = 6,
 | 
			
		||||
        // below FO3/FONV
 | 
			
		||||
        DTYP_Radio         = 7
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_DIALOGUE_H
 | 
			
		||||
							
								
								
									
										56
									
								
								components/esm4/effect.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								components/esm4/effect.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_EFFECT_H
 | 
			
		||||
#define ESM4_EFFECT_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
    union EFI_Label
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t value;
 | 
			
		||||
        char effect[4];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct ScriptEffect
 | 
			
		||||
    {
 | 
			
		||||
        FormId       formId;       // Script effect (Magic effect must be SEFF)
 | 
			
		||||
        std::int32_t school;       // Magic school. See Magic schools for more information.
 | 
			
		||||
        EFI_Label    visualEffect; // Visual effect name or 0x00000000 if None
 | 
			
		||||
        std::uint8_t flags;        // 0x01 = Hostile
 | 
			
		||||
        std::uint8_t unknown1;
 | 
			
		||||
        std::uint8_t unknown2;
 | 
			
		||||
        std::uint8_t unknown3;
 | 
			
		||||
    };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_EFFECT_H
 | 
			
		||||
							
								
								
									
										78
									
								
								components/esm4/formid.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								components/esm4/formid.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cstdlib> // strtol
 | 
			
		||||
#include <climits> // LONG_MIN, LONG_MAX for gcc
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    void formIdToString(FormId formId, std::string& str)
 | 
			
		||||
    {
 | 
			
		||||
        char buf[8+1];
 | 
			
		||||
        int res = snprintf(buf, 8+1, "%08X", formId);
 | 
			
		||||
        if (res > 0 && res < 8+1)
 | 
			
		||||
            str.assign(buf);
 | 
			
		||||
        else
 | 
			
		||||
            throw std::runtime_error("Possible buffer overflow while converting formId");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string formIdToString(FormId formId)
 | 
			
		||||
    {
 | 
			
		||||
        std::string str;
 | 
			
		||||
        formIdToString(formId, str);
 | 
			
		||||
        return str;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool isFormId(const std::string& str, FormId *id)
 | 
			
		||||
    {
 | 
			
		||||
        if (str.size() != 8)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        char *tmp;
 | 
			
		||||
        errno = 0;
 | 
			
		||||
        unsigned long val = strtol(str.c_str(), &tmp, 16);
 | 
			
		||||
 | 
			
		||||
        if (tmp == str.c_str() || *tmp != '\0'
 | 
			
		||||
                || ((val == (unsigned long)LONG_MIN || val == (unsigned long)LONG_MAX) && errno == ERANGE))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        if (id != nullptr)
 | 
			
		||||
            *id = static_cast<FormId>(val);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    FormId stringToFormId(const std::string& str)
 | 
			
		||||
    {
 | 
			
		||||
        if (str.size() != 8)
 | 
			
		||||
            throw std::out_of_range("StringToFormId: incorrect string size");
 | 
			
		||||
 | 
			
		||||
        return static_cast<FormId>(std::stoul(str, nullptr, 16));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								components/esm4/formid.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								components/esm4/formid.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_FORMID_H
 | 
			
		||||
#define ESM4_FORMID_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    typedef std::uint32_t FormId;
 | 
			
		||||
 | 
			
		||||
    void formIdToString(FormId formId, std::string& str);
 | 
			
		||||
 | 
			
		||||
    std::string formIdToString(FormId formId);
 | 
			
		||||
 | 
			
		||||
    bool isFormId(const std::string& str, FormId *id = nullptr);
 | 
			
		||||
 | 
			
		||||
    FormId stringToFormId(const std::string& str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_FORMID_H
 | 
			
		||||
							
								
								
									
										55
									
								
								components/esm4/inventory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								components/esm4/inventory.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_INVENTORY_H
 | 
			
		||||
#define ESM4_INVENTORY_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
    // LVLC, LVLI
 | 
			
		||||
    struct LVLO
 | 
			
		||||
    {
 | 
			
		||||
        std::int16_t  level;
 | 
			
		||||
        std::uint16_t unknown;  // sometimes missing
 | 
			
		||||
        FormId        item;
 | 
			
		||||
        std::int16_t  count;
 | 
			
		||||
        std::uint16_t unknown2; // sometimes missing
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct InventoryItem // NPC_, CREA, CONT
 | 
			
		||||
    {
 | 
			
		||||
        FormId        item;
 | 
			
		||||
        std::uint32_t count;
 | 
			
		||||
    };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_INVENTORY_H
 | 
			
		||||
							
								
								
									
										79
									
								
								components/esm4/lighting.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								components/esm4/lighting.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_LIGHTING_H
 | 
			
		||||
#define ESM4_LIGHTING_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
    // guesses only for TES4
 | 
			
		||||
    struct Lighting
 | 
			
		||||
    {                              //               | Aichan Prison values
 | 
			
		||||
        std::uint32_t ambient;     //               | 16 17 19 00 (RGBA)
 | 
			
		||||
        std::uint32_t directional; //               | 00 00 00 00 (RGBA)
 | 
			
		||||
        std::uint32_t fogColor;    //               | 1D 1B 16 00 (RGBA)
 | 
			
		||||
        float         fogNear;     // Fog Near      | 00 00 00 00 = 0.f
 | 
			
		||||
        float         fogFar;      // Fog Far       | 00 80 3B 45 = 3000.f
 | 
			
		||||
        std::int32_t  rotationXY;  // rotation xy   | 00 00 00 00 = 0
 | 
			
		||||
        std::int32_t  rotationZ;   // rotation z    | 00 00 00 00 = 0
 | 
			
		||||
        float         fogDirFade;  // Fog dir fade  | 00 00 80 3F = 1.f
 | 
			
		||||
        float         fogClipDist; // Fog clip dist | 00 80 3B 45 = 3000.f
 | 
			
		||||
        float         fogPower;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct Lighting_TES5
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t ambient;
 | 
			
		||||
        std::uint32_t directional;
 | 
			
		||||
        std::uint32_t fogColor;
 | 
			
		||||
        float         fogNear;
 | 
			
		||||
        float         fogFar;
 | 
			
		||||
        std::int32_t  rotationXY;
 | 
			
		||||
        std::int32_t  rotationZ;
 | 
			
		||||
        float         fogDirFade;
 | 
			
		||||
        float         fogClipDist;
 | 
			
		||||
        float         fogPower;
 | 
			
		||||
        std::uint32_t unknown1;
 | 
			
		||||
        std::uint32_t unknown2;
 | 
			
		||||
        std::uint32_t unknown3;
 | 
			
		||||
        std::uint32_t unknown4;
 | 
			
		||||
        std::uint32_t unknown5;
 | 
			
		||||
        std::uint32_t unknown6;
 | 
			
		||||
        std::uint32_t unknown7;
 | 
			
		||||
        std::uint32_t unknown8;
 | 
			
		||||
        std::uint32_t fogColorFar;
 | 
			
		||||
        float         fogMax;
 | 
			
		||||
        float         LightFadeStart;
 | 
			
		||||
        float         LightFadeEnd;
 | 
			
		||||
        std::uint32_t padding;
 | 
			
		||||
    };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_LIGHTING_H
 | 
			
		||||
							
								
								
									
										124
									
								
								components/esm4/loadachr.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								components/esm4/loadachr.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,124 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadachr.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::ActorCharacter::ActorCharacter() : mFormId(0), mFlags(0), mBaseObj(0),
 | 
			
		||||
                                         mScale(1.f), mOwner(0), mGlobal(0), mInitiallyDisabled(false)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
 | 
			
		||||
    mEsp.parent = 0;
 | 
			
		||||
    mEsp.flags = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::ActorCharacter::~ActorCharacter()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::ActorCharacter::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
    mParent = reader.currCell(); // NOTE: only for persistent achr? (aren't they all persistent?)
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getZString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_NAME: reader.getFormId(mBaseObj);   break;
 | 
			
		||||
            case ESM4::SUB_DATA: reader.get(mPlacement); break;
 | 
			
		||||
            case ESM4::SUB_XSCL: reader.get(mScale);     break;
 | 
			
		||||
            case ESM4::SUB_XOWN: reader.get(mOwner);     break;
 | 
			
		||||
            case ESM4::SUB_XESP:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mEsp);
 | 
			
		||||
                reader.adjustFormId(mEsp.parent);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_XRGD: // ragdoll
 | 
			
		||||
            case ESM4::SUB_XRGB: // ragdoll biped
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "ACHR " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_XHRS: // horse formId
 | 
			
		||||
            case ESM4::SUB_XMRC: // merchant container formId
 | 
			
		||||
            // TES5
 | 
			
		||||
            case ESM4::SUB_XAPD: // activation parent
 | 
			
		||||
            case ESM4::SUB_XAPR: // active parent
 | 
			
		||||
            case ESM4::SUB_XEZN: // encounter zone
 | 
			
		||||
            case ESM4::SUB_XHOR:
 | 
			
		||||
            case ESM4::SUB_XLCM: // levelled creature
 | 
			
		||||
            case ESM4::SUB_XLCN: // location
 | 
			
		||||
            case ESM4::SUB_XLKR: // location route?
 | 
			
		||||
            case ESM4::SUB_XLRT: // location type
 | 
			
		||||
            //
 | 
			
		||||
            case ESM4::SUB_XPRD:
 | 
			
		||||
            case ESM4::SUB_XPPA:
 | 
			
		||||
            case ESM4::SUB_INAM:
 | 
			
		||||
            case ESM4::SUB_PDTO:
 | 
			
		||||
            //
 | 
			
		||||
            case ESM4::SUB_XIS2:
 | 
			
		||||
            case ESM4::SUB_XPCI: // formId
 | 
			
		||||
            case ESM4::SUB_XLOD:
 | 
			
		||||
            case ESM4::SUB_VMAD:
 | 
			
		||||
            case ESM4::SUB_XLRL: // Unofficial Skyrim Patch
 | 
			
		||||
            case ESM4::SUB_XRDS: // FO3
 | 
			
		||||
            case ESM4::SUB_XIBS: // FO3
 | 
			
		||||
            case ESM4::SUB_SCHR: // FO3
 | 
			
		||||
            case ESM4::SUB_TNAM: // FO3
 | 
			
		||||
            case ESM4::SUB_XATO: // FONV
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "ACHR " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::ACHR::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::ActorCharacter::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::ActorCharacter::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										70
									
								
								components/esm4/loadachr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								components/esm4/loadachr.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_ACHR_H
 | 
			
		||||
#define ESM4_ACHR_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
#include "reference.hpp" // FormId, Placement, EnableParent
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct ActorCharacter
 | 
			
		||||
    {
 | 
			
		||||
        FormId mParent;       // cell formId, from the loading sequence
 | 
			
		||||
                              // NOTE: for exterior cells it will be the dummy cell FormId
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        FormId      mBaseObj;
 | 
			
		||||
 | 
			
		||||
        Placement mPlacement;
 | 
			
		||||
        float    mScale;      // default 1.f
 | 
			
		||||
        FormId   mOwner;
 | 
			
		||||
        FormId   mGlobal;
 | 
			
		||||
 | 
			
		||||
        bool mInitiallyDisabled; // TODO may need to check mFlags & 0x800 (initially disabled)
 | 
			
		||||
 | 
			
		||||
        EnableParent mEsp;
 | 
			
		||||
 | 
			
		||||
        ActorCharacter();
 | 
			
		||||
        virtual ~ActorCharacter();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_ACHR_H
 | 
			
		||||
							
								
								
									
										106
									
								
								components/esm4/loadacre.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								components/esm4/loadacre.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,106 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadacre.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::ActorCreature::ActorCreature() : mFormId(0), mFlags(0), mBaseObj(0), mScale(1.f),
 | 
			
		||||
                                       mOwner(0), mGlobal(0), mFactionRank(0), mInitiallyDisabled(false)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
 | 
			
		||||
    mEsp.parent = 0;
 | 
			
		||||
    mEsp.flags = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::ActorCreature::~ActorCreature()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::ActorCreature::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_NAME: reader.getFormId(mBaseObj);   break;
 | 
			
		||||
            case ESM4::SUB_DATA: reader.get(mPlacement);       break;
 | 
			
		||||
            case ESM4::SUB_XSCL: reader.get(mScale);           break;
 | 
			
		||||
            case ESM4::SUB_XESP:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mEsp);
 | 
			
		||||
                reader.adjustFormId(mEsp.parent);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_XOWN: reader.getFormId(mOwner);     break;
 | 
			
		||||
            case ESM4::SUB_XGLB: reader.get(mGlobal);          break; // FIXME: formId?
 | 
			
		||||
            case ESM4::SUB_XRNK: reader.get(mFactionRank);     break;
 | 
			
		||||
            case ESM4::SUB_XRGD: // ragdoll
 | 
			
		||||
            case ESM4::SUB_XRGB: // ragdoll biped
 | 
			
		||||
            {
 | 
			
		||||
                // seems to occur only for dead bodies, e.g. DeadMuffy, DeadDogVicious
 | 
			
		||||
                //std::cout << "ACRE " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_XLKR: // FO3
 | 
			
		||||
            case ESM4::SUB_XLCM: // FO3
 | 
			
		||||
            case ESM4::SUB_XEZN: // FO3
 | 
			
		||||
            case ESM4::SUB_XMRC: // FO3
 | 
			
		||||
            case ESM4::SUB_XAPD: // FO3
 | 
			
		||||
            case ESM4::SUB_XAPR: // FO3
 | 
			
		||||
            case ESM4::SUB_XRDS: // FO3
 | 
			
		||||
            case ESM4::SUB_XPRD: // FO3
 | 
			
		||||
            case ESM4::SUB_XATO: // FONV
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "ACRE " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::ACRE::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::ActorCreature::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::ActorCreature::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										67
									
								
								components/esm4/loadacre.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								components/esm4/loadacre.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,67 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_ACRE_H
 | 
			
		||||
#define ESM4_ACRE_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
#include "reference.hpp" // FormId, Placement, EnableParent
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct ActorCreature
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        FormId      mBaseObj;
 | 
			
		||||
 | 
			
		||||
        Placement mPlacement;
 | 
			
		||||
        float    mScale;      // default 1.f
 | 
			
		||||
        FormId   mOwner;
 | 
			
		||||
        FormId   mGlobal;
 | 
			
		||||
        std::uint32_t mFactionRank;
 | 
			
		||||
 | 
			
		||||
        bool mInitiallyDisabled; // TODO may need to check mFlags & 0x800 (initially disabled)
 | 
			
		||||
 | 
			
		||||
        EnableParent mEsp;
 | 
			
		||||
 | 
			
		||||
        ActorCreature();
 | 
			
		||||
        virtual ~ActorCreature();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_ACRE_H
 | 
			
		||||
							
								
								
									
										103
									
								
								components/esm4/loadacti.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								components/esm4/loadacti.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,103 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "acti.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <iostream> // FIXME
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Activator::Activator() : mFormId(0), mFlags(0), mScriptId(0), mLoopingSound(0), mActivationSound(0),
 | 
			
		||||
    mBoundRadius(0.f), mRadioTemplate(0), mRadioStation(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
 | 
			
		||||
    mActivationPrompt.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Activator::~Activator()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Activator::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId); break;
 | 
			
		||||
            case ESM4::SUB_SNAM: reader.getFormId(mLoopingSound);  break;
 | 
			
		||||
            case ESM4::SUB_VNAM: reader.getFormId(mActivationSound);  break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_INAM: reader.getFormId(mRadioTemplate); break; // FONV
 | 
			
		||||
            case ESM4::SUB_RNAM: reader.getFormId(mRadioStation); break;
 | 
			
		||||
            case ESM4::SUB_XATO: reader.getZString(mActivationPrompt); break; // FONV
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_MODS:
 | 
			
		||||
            case ESM4::SUB_DEST:
 | 
			
		||||
            case ESM4::SUB_DMDL:
 | 
			
		||||
            case ESM4::SUB_DMDS:
 | 
			
		||||
            case ESM4::SUB_DMDT:
 | 
			
		||||
            case ESM4::SUB_DSTD:
 | 
			
		||||
            case ESM4::SUB_DSTF:
 | 
			
		||||
            case ESM4::SUB_FNAM:
 | 
			
		||||
            case ESM4::SUB_KNAM:
 | 
			
		||||
            case ESM4::SUB_KSIZ:
 | 
			
		||||
            case ESM4::SUB_KWDA:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_PNAM:
 | 
			
		||||
            case ESM4::SUB_VMAD:
 | 
			
		||||
            case ESM4::SUB_WNAM:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "ACTI " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::ACTI::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Activator::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Activator::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										121
									
								
								components/esm4/loadalch.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								components/esm4/loadalch.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,121 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadalch.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
//#include <iostream> // FIXME
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Potion::Potion() : mFormId(0), mFlags(0), mPickUpSound(0), mDropSound(0), mScriptId(0), mBoundRadius(0.f)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
    mIcon.clear();
 | 
			
		||||
    mMiniIcon.clear();
 | 
			
		||||
 | 
			
		||||
    mData.weight = 0.f;
 | 
			
		||||
 | 
			
		||||
    std::memset(&mEffect, 0, sizeof(ScriptEffect));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Potion::~Potion()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Potion::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIcon);  break;
 | 
			
		||||
            case ESM4::SUB_MICO: reader.getZString(mMiniIcon); break; // FO3
 | 
			
		||||
            case ESM4::SUB_DATA: reader.get(mData);         break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId); break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_SCIT:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mEffect);
 | 
			
		||||
                reader.adjustFormId(mEffect.formId);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_ENIT:
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize == 8) // TES4
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(&mItem, 8);
 | 
			
		||||
                    mItem.withdrawl = 0;
 | 
			
		||||
                    mItem.sound = 0;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                reader.get(mItem);
 | 
			
		||||
                reader.adjustFormId(mItem.withdrawl);
 | 
			
		||||
                reader.adjustFormId(mItem.sound);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_YNAM: reader.getFormId(mPickUpSound); break;
 | 
			
		||||
            case ESM4::SUB_ZNAM: reader.getFormId(mDropSound); break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_EFID:
 | 
			
		||||
            case ESM4::SUB_EFIT:
 | 
			
		||||
            case ESM4::SUB_CTDA:
 | 
			
		||||
            case ESM4::SUB_KSIZ:
 | 
			
		||||
            case ESM4::SUB_KWDA:
 | 
			
		||||
            case ESM4::SUB_MODS:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_ETYP: // FO3
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "ALCH " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::ALCH::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Potion::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Potion::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										88
									
								
								components/esm4/loadalch.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								components/esm4/loadalch.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,88 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_ALCH_H
 | 
			
		||||
#define ESM4_ALCH_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "effect.hpp" // FormId, ScriptEffect
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Potion
 | 
			
		||||
    {
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            float weight;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct EnchantedItem
 | 
			
		||||
        {
 | 
			
		||||
            std::int32_t value;
 | 
			
		||||
            std::uint32_t flags;
 | 
			
		||||
            FormId withdrawl;
 | 
			
		||||
            float  chanceAddition;
 | 
			
		||||
            FormId sound;
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
        std::string mIcon; // inventory
 | 
			
		||||
        std::string mMiniIcon; // inventory
 | 
			
		||||
 | 
			
		||||
        FormId mPickUpSound;
 | 
			
		||||
        FormId mDropSound;
 | 
			
		||||
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
        ScriptEffect mEffect;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
        EnchantedItem mItem;
 | 
			
		||||
 | 
			
		||||
        Potion();
 | 
			
		||||
        virtual ~Potion();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_ALCH_H
 | 
			
		||||
							
								
								
									
										172
									
								
								components/esm4/loadaloc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								components/esm4/loadaloc.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,172 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadaloc.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
//#include <iostream> // FIXME: for debugging only
 | 
			
		||||
//#include <iomanip>  // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
//#include <boost/scoped_array.hpp> // FIXME
 | 
			
		||||
 | 
			
		||||
//#include "formid.hpp" // FIXME:
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::MediaLocationController::MediaLocationController() : mFormId(0), mFlags(0),
 | 
			
		||||
    mConditionalFaction(0), mLocationDelay(0.f), mRetriggerDelay(0.f), mDayStart(0), mNightStart(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
 | 
			
		||||
    std::memset(&mMediaFlags, 0, sizeof(MLC_Flags));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::MediaLocationController::~MediaLocationController()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::MediaLocationController::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId);  break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getZString(mFullName);  break;
 | 
			
		||||
            case ESM4::SUB_GNAM:
 | 
			
		||||
            {
 | 
			
		||||
                FormId id;
 | 
			
		||||
                reader.getFormId(id);
 | 
			
		||||
                mBattleSets.push_back(id);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_LNAM:
 | 
			
		||||
            {
 | 
			
		||||
                FormId id;
 | 
			
		||||
                reader.getFormId(id);
 | 
			
		||||
                mLocationSets.push_back(id);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_YNAM:
 | 
			
		||||
            {
 | 
			
		||||
                FormId id;
 | 
			
		||||
                reader.getFormId(id);
 | 
			
		||||
                mEnemySets.push_back(id);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_HNAM:
 | 
			
		||||
            {
 | 
			
		||||
                FormId id;
 | 
			
		||||
                reader.getFormId(id);
 | 
			
		||||
                mNeutralSets.push_back(id);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_XNAM:
 | 
			
		||||
            {
 | 
			
		||||
                FormId id;
 | 
			
		||||
                reader.getFormId(id);
 | 
			
		||||
                mFriendSets.push_back(id);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_ZNAM:
 | 
			
		||||
            {
 | 
			
		||||
                FormId id;
 | 
			
		||||
                reader.getFormId(id);
 | 
			
		||||
                mAllySets.push_back(id);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_RNAM: reader.getFormId(mConditionalFaction); break;
 | 
			
		||||
            case ESM4::SUB_NAM1:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mMediaFlags);
 | 
			
		||||
                std::uint8_t flags = mMediaFlags.loopingOptions;
 | 
			
		||||
                mMediaFlags.loopingOptions = (flags & 0xF0) >> 4;
 | 
			
		||||
                mMediaFlags.factionNotFound = flags & 0x0F; // WARN: overwriting data
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_NAM4: reader.get(mLocationDelay); break;
 | 
			
		||||
            case ESM4::SUB_NAM7: reader.get(mRetriggerDelay); break;
 | 
			
		||||
            case ESM4::SUB_NAM5: reader.get(mDayStart); break;
 | 
			
		||||
            case ESM4::SUB_NAM6: reader.get(mNightStart); break;
 | 
			
		||||
            case ESM4::SUB_NAM2: // always 0? 4 bytes
 | 
			
		||||
            case ESM4::SUB_NAM3: // always 0? 4 bytes
 | 
			
		||||
            case ESM4::SUB_FNAM: // always 0? 4 bytes
 | 
			
		||||
            {
 | 
			
		||||
#if 0
 | 
			
		||||
                boost::scoped_array<unsigned char> mDataBuf(new unsigned char[subHdr.dataSize]);
 | 
			
		||||
                reader.get(&mDataBuf[0], subHdr.dataSize);
 | 
			
		||||
 | 
			
		||||
                std::ostringstream ss;
 | 
			
		||||
                ss << mEditorId << " " << ESM::printName(subHdr.typeId) << ":size " << subHdr.dataSize << "\n";
 | 
			
		||||
                for (std::size_t i = 0; i < subHdr.dataSize; ++i)
 | 
			
		||||
                {
 | 
			
		||||
                    //if (mDataBuf[i] > 64 && mDataBuf[i] < 91) // looks like printable ascii char
 | 
			
		||||
                        //ss << (char)(mDataBuf[i]) << " ";
 | 
			
		||||
                    //else
 | 
			
		||||
                        ss << std::setfill('0') << std::setw(2) << std::hex << (int)(mDataBuf[i]);
 | 
			
		||||
                    if ((i & 0x000f) == 0xf) // wrap around
 | 
			
		||||
                        ss << "\n";
 | 
			
		||||
                    else if (i < subHdr.dataSize-1)
 | 
			
		||||
                        ss << " ";
 | 
			
		||||
                }
 | 
			
		||||
                std::cout << ss.str() << std::endl;
 | 
			
		||||
#else
 | 
			
		||||
                //std::cout << "ALOC " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                          //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
#endif
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                //std::cout << "ALOC " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                          //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                //reader.skipSubRecordData();
 | 
			
		||||
                throw std::runtime_error("ESM4::ALOC::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::MediaLocationController::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::MediaLocationController::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										88
									
								
								components/esm4/loadaloc.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								components/esm4/loadaloc.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,88 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_ALOC_H
 | 
			
		||||
#define ESM4_ALOC_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
    struct MLC_Flags
 | 
			
		||||
    {
 | 
			
		||||
        // use day/night transition:  0 = loop, 1 = random, 2 = retrigger, 3 = none
 | 
			
		||||
        // use defaults (6:00/23:54): 4 = loop, 5 = random, 6 = retrigger, 7 = none
 | 
			
		||||
        std::uint8_t loopingOptions;
 | 
			
		||||
        // 0 = neutral, 1 = enemy, 2 = ally, 3 = friend, 4 = location, 5 = none
 | 
			
		||||
        std::uint8_t factionNotFound; // WARN: overwriting whatever is in this
 | 
			
		||||
        std::uint16_t unknown; // padding?
 | 
			
		||||
    };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
    struct MediaLocationController
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
 | 
			
		||||
        std::vector<FormId> mBattleSets;
 | 
			
		||||
        std::vector<FormId> mLocationSets;
 | 
			
		||||
        std::vector<FormId> mEnemySets;
 | 
			
		||||
        std::vector<FormId> mNeutralSets;
 | 
			
		||||
        std::vector<FormId> mFriendSets;
 | 
			
		||||
        std::vector<FormId> mAllySets;
 | 
			
		||||
 | 
			
		||||
        MLC_Flags mMediaFlags;
 | 
			
		||||
 | 
			
		||||
        FormId mConditionalFaction;
 | 
			
		||||
 | 
			
		||||
        float mLocationDelay;
 | 
			
		||||
        float mRetriggerDelay;
 | 
			
		||||
 | 
			
		||||
        std::uint32_t mDayStart;
 | 
			
		||||
        std::uint32_t mNightStart;
 | 
			
		||||
 | 
			
		||||
        MediaLocationController();
 | 
			
		||||
        virtual ~MediaLocationController();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_ALOC_H
 | 
			
		||||
							
								
								
									
										133
									
								
								components/esm4/loadammo.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								components/esm4/loadammo.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,133 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadammo.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Ammunition::Ammunition() : mFormId(0), mFlags(0), mPickUpSound(0), mDropSound(0), mBoundRadius(0.f)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
    mText.clear();
 | 
			
		||||
    mIcon.clear();
 | 
			
		||||
    mMiniIcon.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Ammunition::~Ammunition()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Ammunition::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
    std::uint32_t esmVer = reader.esmVersion();
 | 
			
		||||
    bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                //if (reader.esmVersion() == ESM::VER_094 || reader.esmVersion() == ESM::VER_170)
 | 
			
		||||
                if (subHdr.dataSize == 16) // FO3 has 13 bytes even though VER_094
 | 
			
		||||
                {
 | 
			
		||||
                    FormId projectile;
 | 
			
		||||
                    reader.get(projectile); // FIXME: add to mData
 | 
			
		||||
                    reader.get(mData.flags);
 | 
			
		||||
                    reader.get(mData.weight);
 | 
			
		||||
                    float damageInFloat;
 | 
			
		||||
                    reader.get(damageInFloat); // FIXME: add to mData
 | 
			
		||||
                }
 | 
			
		||||
                else if (isFONV || subHdr.dataSize == 13)
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData.speed);
 | 
			
		||||
                    std::uint8_t flags;
 | 
			
		||||
                    reader.get(flags);
 | 
			
		||||
                    mData.flags = flags;
 | 
			
		||||
                    static std::uint8_t dummy;
 | 
			
		||||
                    reader.get(dummy);
 | 
			
		||||
                    reader.get(dummy);
 | 
			
		||||
                    reader.get(dummy);
 | 
			
		||||
                    reader.get(mData.value);
 | 
			
		||||
                    reader.get(mData.clipRounds);
 | 
			
		||||
                }
 | 
			
		||||
                else // TES4
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData.speed);
 | 
			
		||||
                    reader.get(mData.flags);
 | 
			
		||||
                    reader.get(mData.value);
 | 
			
		||||
                    reader.get(mData.weight);
 | 
			
		||||
                    reader.get(mData.damage);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIcon);  break;
 | 
			
		||||
            case ESM4::SUB_MICO: reader.getZString(mMiniIcon); break; // FO3
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_ANAM: reader.get(mEnchantmentPoints); break;
 | 
			
		||||
            case ESM4::SUB_ENAM: reader.getFormId(mEnchantment); break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_DESC: reader.getLocalizedString(mText); break;
 | 
			
		||||
            case ESM4::SUB_YNAM: reader.getFormId(mPickUpSound); break;
 | 
			
		||||
            case ESM4::SUB_ZNAM: reader.getFormId(mDropSound); break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_KSIZ:
 | 
			
		||||
            case ESM4::SUB_KWDA:
 | 
			
		||||
            case ESM4::SUB_ONAM: // FO3
 | 
			
		||||
            case ESM4::SUB_DAT2: // FONV
 | 
			
		||||
            case ESM4::SUB_QNAM: // FONV
 | 
			
		||||
            case ESM4::SUB_RCIL: // FONV
 | 
			
		||||
            case ESM4::SUB_SCRI: // FONV
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "AMMO " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::AMMO::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Ammunition::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Ammunition::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										84
									
								
								components/esm4/loadammo.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								components/esm4/loadammo.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018-2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_AMMO_H
 | 
			
		||||
#define ESM4_AMMO_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Ammunition
 | 
			
		||||
    {
 | 
			
		||||
        struct Data // FIXME: TES5 projectile, damage (float)
 | 
			
		||||
        {
 | 
			
		||||
            float         speed;
 | 
			
		||||
            std::uint32_t flags;
 | 
			
		||||
            std::uint32_t value;   // gold
 | 
			
		||||
            float         weight;
 | 
			
		||||
            std::uint16_t damage;
 | 
			
		||||
            std::uint8_t  clipRounds; // only in FO3/FONV
 | 
			
		||||
 | 
			
		||||
            Data() : speed(0.f), flags(0), value(0), weight(0.f), damage(0), clipRounds(0) {}
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
        std::string mText;
 | 
			
		||||
        std::string mIcon; // inventory
 | 
			
		||||
        std::string mMiniIcon; // inventory
 | 
			
		||||
 | 
			
		||||
        FormId mPickUpSound;
 | 
			
		||||
        FormId mDropSound;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        std::uint16_t mEnchantmentPoints;
 | 
			
		||||
        FormId mEnchantment;
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Ammunition();
 | 
			
		||||
        virtual ~Ammunition();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_AMMO_H
 | 
			
		||||
							
								
								
									
										80
									
								
								components/esm4/loadanio.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								components/esm4/loadanio.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadanio.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::AnimObject::AnimObject() : mFormId(0), mFlags(0), mBoundRadius(0.f), mIdleAnim(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
    mUnloadEvent.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::AnimObject::~AnimObject()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::AnimObject::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel);    break;
 | 
			
		||||
            case ESM4::SUB_BNAM: reader.getZString(mUnloadEvent); break;
 | 
			
		||||
            case ESM4::SUB_DATA: reader.getFormId(mIdleAnim);  break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);     break;
 | 
			
		||||
            case ESM4::SUB_MODT: // TES5 only
 | 
			
		||||
            case ESM4::SUB_MODS: // TES5 only
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "ANIO " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::ANIO::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::AnimObject::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::AnimObject::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										63
									
								
								components/esm4/loadanio.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								components/esm4/loadanio.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_ANIO_H
 | 
			
		||||
#define ESM4_ANIO_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct AnimObject
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        FormId mIdleAnim;         // only in TES4
 | 
			
		||||
        std::string mUnloadEvent; // only in TES5
 | 
			
		||||
 | 
			
		||||
        AnimObject();
 | 
			
		||||
        virtual ~AnimObject();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_ANIO_H
 | 
			
		||||
							
								
								
									
										106
									
								
								components/esm4/loadappa.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								components/esm4/loadappa.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,106 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadappa.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Apparatus::Apparatus() : mFormId(0), mFlags(0), mBoundRadius(0.f), mScriptId(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
    mText.clear();
 | 
			
		||||
    mIcon.clear();
 | 
			
		||||
 | 
			
		||||
    mData.type = 0;
 | 
			
		||||
    mData.value = 0;
 | 
			
		||||
    mData.weight = 0.f;
 | 
			
		||||
    mData.quality = 0.f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Apparatus::~Apparatus()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Apparatus::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.esmVersion() == ESM::VER_094 || reader.esmVersion() == ESM::VER_170)
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData.value);
 | 
			
		||||
                    reader.get(mData.weight);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData.type);
 | 
			
		||||
                    reader.get(mData.value);
 | 
			
		||||
                    reader.get(mData.weight);
 | 
			
		||||
                    reader.get(mData.quality);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIcon);  break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId); break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_DESC: reader.getLocalizedString(mText); break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_QUAL:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "APPA " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::APPA::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Apparatus::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Apparatus::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										75
									
								
								components/esm4/loadappa.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								components/esm4/loadappa.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018-2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_APPA_H
 | 
			
		||||
#define ESM4_APPA_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Apparatus
 | 
			
		||||
    {
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint8_t  type;  // 0 = Mortar and Pestle, 1 = Alembic, 2 = Calcinator, 3 = Retort
 | 
			
		||||
            std::uint32_t value; // gold
 | 
			
		||||
            float         weight;
 | 
			
		||||
            float         quality;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
        std::string mText;
 | 
			
		||||
        std::string mIcon; // inventory
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Apparatus();
 | 
			
		||||
        virtual ~Apparatus();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_APPA_H
 | 
			
		||||
							
								
								
									
										151
									
								
								components/esm4/loadarma.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								components/esm4/loadarma.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,151 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2019, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadarma.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME: testing only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::ArmorAddon::ArmorAddon() : mFormId(0), mFlags(0), mTextureMale(0), mTextureFemale(0),
 | 
			
		||||
                                 mRacePrimary(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
 | 
			
		||||
    mModelMale.clear();
 | 
			
		||||
    mModelFemale.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::ArmorAddon::~ArmorAddon()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::ArmorAddon::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    std::uint32_t esmVer = reader.esmVersion();
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_MOD2: reader.getZString(mModelMale); break;
 | 
			
		||||
            case ESM4::SUB_MOD3: reader.getZString(mModelFemale); break;
 | 
			
		||||
            case ESM4::SUB_MOD4:
 | 
			
		||||
            case ESM4::SUB_MOD5:
 | 
			
		||||
            {
 | 
			
		||||
                std::string model;
 | 
			
		||||
                reader.getZString(model);
 | 
			
		||||
 | 
			
		||||
                //std::cout << mEditorId << " " << ESM::printName(subHdr.typeId) << " " << model << std::endl;
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_NAM0: reader.getFormId(mTextureMale); break;
 | 
			
		||||
            case ESM4::SUB_NAM1: reader.getFormId(mTextureFemale); break;
 | 
			
		||||
            case ESM4::SUB_RNAM: reader.getFormId(mRacePrimary); break;
 | 
			
		||||
            case ESM4::SUB_MODL:
 | 
			
		||||
            {
 | 
			
		||||
                if ((esmVer == ESM::VER_094 || esmVer == ESM::VER_170) && subHdr.dataSize == 4) // TES5
 | 
			
		||||
                {
 | 
			
		||||
                    FormId formId;
 | 
			
		||||
                    reader.getFormId(formId);
 | 
			
		||||
                    mRaces.push_back(formId);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    reader.skipSubRecordData(); // FIXME: this should be mModelMale for FO3/FONV
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_BODT: // body template
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mBodyTemplate.bodyPart);
 | 
			
		||||
                reader.get(mBodyTemplate.flags);
 | 
			
		||||
                reader.get(mBodyTemplate.unknown1); // probably padding
 | 
			
		||||
                reader.get(mBodyTemplate.unknown2); // probably padding
 | 
			
		||||
                reader.get(mBodyTemplate.unknown3); // probably padding
 | 
			
		||||
                reader.get(mBodyTemplate.type);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_BOD2: // TES5
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mBodyTemplate.bodyPart);
 | 
			
		||||
                mBodyTemplate.flags = 0;
 | 
			
		||||
                mBodyTemplate.unknown1 = 0; // probably padding
 | 
			
		||||
                mBodyTemplate.unknown2 = 0; // probably padding
 | 
			
		||||
                mBodyTemplate.unknown3 = 0; // probably padding
 | 
			
		||||
                reader.get(mBodyTemplate.type);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_DNAM:
 | 
			
		||||
            case ESM4::SUB_MO2T: // FIXME: should group with MOD2
 | 
			
		||||
            case ESM4::SUB_MO2S: // FIXME: should group with MOD2
 | 
			
		||||
            case ESM4::SUB_MO3T: // FIXME: should group with MOD3
 | 
			
		||||
            case ESM4::SUB_MO3S: // FIXME: should group with MOD3
 | 
			
		||||
            case ESM4::SUB_MOSD: // FO3 // FIXME: should group with MOD3
 | 
			
		||||
            case ESM4::SUB_MO4T: // FIXME: should group with MOD4
 | 
			
		||||
            case ESM4::SUB_MO4S: // FIXME: should group with MOD4
 | 
			
		||||
            case ESM4::SUB_MO5T:
 | 
			
		||||
            case ESM4::SUB_NAM2: // txst formid male
 | 
			
		||||
            case ESM4::SUB_NAM3: // txst formid female
 | 
			
		||||
            case ESM4::SUB_SNDD: // footset sound formid
 | 
			
		||||
            case ESM4::SUB_BMDT: // FO3
 | 
			
		||||
            case ESM4::SUB_DATA: // FO3
 | 
			
		||||
            case ESM4::SUB_ETYP: // FO3
 | 
			
		||||
            case ESM4::SUB_FULL: // FO3
 | 
			
		||||
            case ESM4::SUB_ICO2: // FO3 // female
 | 
			
		||||
            case ESM4::SUB_ICON: // FO3 // male
 | 
			
		||||
            case ESM4::SUB_MODT: // FO3 // FIXME: should group with MODL
 | 
			
		||||
            case ESM4::SUB_MODS: // FO3 // FIXME: should group with MODL
 | 
			
		||||
            case ESM4::SUB_MODD: // FO3 // FIXME: should group with MODL
 | 
			
		||||
            case ESM4::SUB_OBND: // FO3
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "ARMA " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::ARMA::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::ArmorAddon::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::ArmorAddon::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										70
									
								
								components/esm4/loadarma.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								components/esm4/loadarma.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2019, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_ARMA_H
 | 
			
		||||
#define ESM4_ARMA_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
#include "actor.hpp" // BodyTemplate
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct ArmorAddon
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
 | 
			
		||||
        std::string mModelMale;
 | 
			
		||||
        std::string mModelFemale;
 | 
			
		||||
 | 
			
		||||
        FormId mTextureMale;
 | 
			
		||||
        FormId mTextureFemale;
 | 
			
		||||
 | 
			
		||||
        FormId mRacePrimary;
 | 
			
		||||
        std::vector<FormId> mRaces; // TES5 only
 | 
			
		||||
 | 
			
		||||
        BodyTemplate mBodyTemplate; // TES5
 | 
			
		||||
 | 
			
		||||
        ArmorAddon();
 | 
			
		||||
        virtual ~ArmorAddon();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_ARMA_H
 | 
			
		||||
							
								
								
									
										218
									
								
								components/esm4/loadarmo.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								components/esm4/loadarmo.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,218 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadarmo.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME: testing only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Armor::Armor() : mFormId(0), mFlags(0), mIsTES4(false), mIsFO3(false), mIsFONV(false),
 | 
			
		||||
                       mPickUpSound(0), mDropSound(0), mBoundRadius(0.f),
 | 
			
		||||
                       mArmorFlags(0), mGeneralFlags(0), mScriptId(0), mEnchantmentPoints(0), mEnchantment(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModelMale.clear();
 | 
			
		||||
    mModelMaleWorld.clear();
 | 
			
		||||
    mModelFemale.clear();
 | 
			
		||||
    mModelFemaleWorld.clear();
 | 
			
		||||
    mText.clear();
 | 
			
		||||
    mIconMale.clear();
 | 
			
		||||
    mMiniIconMale.clear();
 | 
			
		||||
    mIconFemale.clear();
 | 
			
		||||
    mMiniIconFemale.clear();
 | 
			
		||||
 | 
			
		||||
    mData.armor = 0;
 | 
			
		||||
    mData.value = 0;
 | 
			
		||||
    mData.health = 0;
 | 
			
		||||
    mData.weight = 0.f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Armor::~Armor()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Armor::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
    std::uint32_t esmVer = reader.esmVersion();
 | 
			
		||||
    mIsFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                //if (reader.esmVersion() == ESM::VER_094 || reader.esmVersion() == ESM::VER_170)
 | 
			
		||||
                if (subHdr.dataSize == 8) // FO3 has 12 bytes even though VER_094
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData.value);
 | 
			
		||||
                    reader.get(mData.weight);
 | 
			
		||||
                    mIsFO3 = true;
 | 
			
		||||
                }
 | 
			
		||||
                else if (mIsFONV || subHdr.dataSize == 12)
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData.value);
 | 
			
		||||
                    reader.get(mData.health);
 | 
			
		||||
                    reader.get(mData.weight);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData); // TES4
 | 
			
		||||
                    mIsTES4 = true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_MODL: // seems only for Dawnguard/Dragonborn?
 | 
			
		||||
            {
 | 
			
		||||
                //if (esmVer == ESM::VER_094 || esmVer == ESM::VER_170 || isFONV)
 | 
			
		||||
                if (subHdr.dataSize == 4) // FO3 has zstring even though VER_094
 | 
			
		||||
                {
 | 
			
		||||
                    FormId formId;
 | 
			
		||||
                    reader.getFormId(formId);
 | 
			
		||||
 | 
			
		||||
                    mAddOns.push_back(formId);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (!reader.getZString(mModelMale))
 | 
			
		||||
                        throw std::runtime_error ("ARMO MODL data read error");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_MOD2: reader.getZString(mModelMaleWorld);break;
 | 
			
		||||
            case ESM4::SUB_MOD3: reader.getZString(mModelFemale); break;
 | 
			
		||||
            case ESM4::SUB_MOD4: reader.getZString(mModelFemaleWorld); break;
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIconMale);   break;
 | 
			
		||||
            case ESM4::SUB_MICO: reader.getZString(mMiniIconMale);   break;
 | 
			
		||||
            case ESM4::SUB_ICO2: reader.getZString(mIconFemale); break;
 | 
			
		||||
            case ESM4::SUB_MIC2: reader.getZString(mMiniIconFemale); break;
 | 
			
		||||
            case ESM4::SUB_BMDT:
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize == 8) // FO3
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mArmorFlags);
 | 
			
		||||
                    reader.get(mGeneralFlags);
 | 
			
		||||
                    mGeneralFlags &= 0x000000ff;
 | 
			
		||||
                    mGeneralFlags |= TYPE_FO3;
 | 
			
		||||
                }
 | 
			
		||||
                else                      // TES4
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mArmorFlags);
 | 
			
		||||
                    mGeneralFlags = (mArmorFlags & 0x00ff0000) >> 16;
 | 
			
		||||
                    mGeneralFlags |= TYPE_TES4;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_BODT:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mArmorFlags);
 | 
			
		||||
                uint32_t flags = 0;
 | 
			
		||||
                if (subHdr.dataSize == 12)
 | 
			
		||||
                    reader.get(flags);
 | 
			
		||||
                reader.get(mGeneralFlags);   // skill
 | 
			
		||||
                mGeneralFlags &= 0x0000000f; // 0 (light), 1 (heavy) or 2 (none)
 | 
			
		||||
                if (subHdr.dataSize == 12)
 | 
			
		||||
                    mGeneralFlags |= (flags & 0x0000000f) << 3;
 | 
			
		||||
                mGeneralFlags |= TYPE_TES5;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_BOD2:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mArmorFlags);
 | 
			
		||||
                reader.get(mGeneralFlags);
 | 
			
		||||
                mGeneralFlags &= 0x0000000f; // 0 (light), 1 (heavy) or 2 (none)
 | 
			
		||||
                mGeneralFlags |= TYPE_TES5;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId);      break;
 | 
			
		||||
            case ESM4::SUB_ANAM: reader.get(mEnchantmentPoints); break;
 | 
			
		||||
            case ESM4::SUB_ENAM: reader.getFormId(mEnchantment); break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);       break;
 | 
			
		||||
            case ESM4::SUB_DESC: reader.getLocalizedString(mText); break;
 | 
			
		||||
            case ESM4::SUB_YNAM: reader.getFormId(mPickUpSound); break;
 | 
			
		||||
            case ESM4::SUB_ZNAM: reader.getFormId(mDropSound); break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_MO2B:
 | 
			
		||||
            case ESM4::SUB_MO3B:
 | 
			
		||||
            case ESM4::SUB_MO4B:
 | 
			
		||||
            case ESM4::SUB_MO2T:
 | 
			
		||||
            case ESM4::SUB_MO2S:
 | 
			
		||||
            case ESM4::SUB_MO3T:
 | 
			
		||||
            case ESM4::SUB_MO4T:
 | 
			
		||||
            case ESM4::SUB_MO4S:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_RNAM: // race formid
 | 
			
		||||
            case ESM4::SUB_KSIZ:
 | 
			
		||||
            case ESM4::SUB_KWDA:
 | 
			
		||||
            case ESM4::SUB_TNAM:
 | 
			
		||||
            case ESM4::SUB_DNAM:
 | 
			
		||||
            case ESM4::SUB_BAMT:
 | 
			
		||||
            case ESM4::SUB_BIDS:
 | 
			
		||||
            case ESM4::SUB_ETYP:
 | 
			
		||||
            case ESM4::SUB_BMCT:
 | 
			
		||||
            case ESM4::SUB_EAMT:
 | 
			
		||||
            case ESM4::SUB_EITM:
 | 
			
		||||
            case ESM4::SUB_VMAD:
 | 
			
		||||
            case ESM4::SUB_REPL: // FO3
 | 
			
		||||
            case ESM4::SUB_BIPL: // FO3
 | 
			
		||||
            case ESM4::SUB_MODD: // FO3
 | 
			
		||||
            case ESM4::SUB_MOSD: // FO3
 | 
			
		||||
            case ESM4::SUB_MODS: // FO3
 | 
			
		||||
            case ESM4::SUB_MO3S: // FO3
 | 
			
		||||
            case ESM4::SUB_BNAM: // FONV
 | 
			
		||||
            case ESM4::SUB_SNAM: // FONV
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "ARMO " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::ARMO::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    //if ((mArmorFlags&0xffff) == 0x02) // only hair
 | 
			
		||||
        //std::cout << "only hair " << mEditorId << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Armor::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Armor::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										196
									
								
								components/esm4/loadarmo.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								components/esm4/loadarmo.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,196 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018-2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_ARMO_H
 | 
			
		||||
#define ESM4_ARMO_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Armor
 | 
			
		||||
    {
 | 
			
		||||
        // WARN: TES4 Armorflags still has the general flags high bits
 | 
			
		||||
        enum ArmorFlags
 | 
			
		||||
        {
 | 
			
		||||
            TES4_Head        = 0x00000001,
 | 
			
		||||
            TES4_Hair        = 0x00000002,
 | 
			
		||||
            TES4_UpperBody   = 0x00000004,
 | 
			
		||||
            TES4_LowerBody   = 0x00000008,
 | 
			
		||||
            TES4_Hands       = 0x00000010,
 | 
			
		||||
            TES4_Feet        = 0x00000020,
 | 
			
		||||
            TES4_RightRing   = 0x00000040,
 | 
			
		||||
            TES4_LeftRing    = 0x00000080,
 | 
			
		||||
            TES4_Amulet      = 0x00000100,
 | 
			
		||||
            TES4_Weapon      = 0x00000200,
 | 
			
		||||
            TES4_BackWeapon  = 0x00000400,
 | 
			
		||||
            TES4_SideWeapon  = 0x00000800,
 | 
			
		||||
            TES4_Quiver      = 0x00001000,
 | 
			
		||||
            TES4_Shield      = 0x00002000,
 | 
			
		||||
            TES4_Torch       = 0x00004000,
 | 
			
		||||
            TES4_Tail        = 0x00008000,
 | 
			
		||||
            //
 | 
			
		||||
            FO3_Head         = 0x00000001,
 | 
			
		||||
            FO3_Hair         = 0x00000002,
 | 
			
		||||
            FO3_UpperBody    = 0x00000004,
 | 
			
		||||
            FO3_LeftHand     = 0x00000008,
 | 
			
		||||
            FO3_RightHand    = 0x00000010,
 | 
			
		||||
            FO3_Weapon       = 0x00000020,
 | 
			
		||||
            FO3_PipBoy       = 0x00000040,
 | 
			
		||||
            FO3_Backpack     = 0x00000080,
 | 
			
		||||
            FO3_Necklace     = 0x00000100,
 | 
			
		||||
            FO3_Headband     = 0x00000200,
 | 
			
		||||
            FO3_Hat          = 0x00000400,
 | 
			
		||||
            FO3_EyeGlasses   = 0x00000800,
 | 
			
		||||
            FO3_NoseRing     = 0x00001000,
 | 
			
		||||
            FO3_Earrings     = 0x00002000,
 | 
			
		||||
            FO3_Mask         = 0x00004000,
 | 
			
		||||
            FO3_Choker       = 0x00008000,
 | 
			
		||||
            FO3_MouthObject  = 0x00010000,
 | 
			
		||||
            FO3_BodyAddOn1   = 0x00020000,
 | 
			
		||||
            FO3_BodyAddOn2   = 0x00040000,
 | 
			
		||||
            FO3_BodyAddOn3   = 0x00080000,
 | 
			
		||||
            //
 | 
			
		||||
            TES5_Head        = 0x00000001,
 | 
			
		||||
            TES5_Hair        = 0x00000002,
 | 
			
		||||
            TES5_Body        = 0x00000004,
 | 
			
		||||
            TES5_Hands       = 0x00000008,
 | 
			
		||||
            TES5_Forearms    = 0x00000010,
 | 
			
		||||
            TES5_Amulet      = 0x00000020,
 | 
			
		||||
            TES5_Ring        = 0x00000040,
 | 
			
		||||
            TES5_Feet        = 0x00000080,
 | 
			
		||||
            TES5_Calves      = 0x00000100,
 | 
			
		||||
            TES5_Shield      = 0x00000200,
 | 
			
		||||
            TES5_Tail        = 0x00000400,
 | 
			
		||||
            TES5_LongHair    = 0x00000800,
 | 
			
		||||
            TES5_Circlet     = 0x00001000,
 | 
			
		||||
            TES5_Ears        = 0x00002000,
 | 
			
		||||
            TES5_BodyAddOn3  = 0x00004000,
 | 
			
		||||
            TES5_BodyAddOn4  = 0x00008000,
 | 
			
		||||
            TES5_BodyAddOn5  = 0x00010000,
 | 
			
		||||
            TES5_BodyAddOn6  = 0x00020000,
 | 
			
		||||
            TES5_BodyAddOn7  = 0x00040000,
 | 
			
		||||
            TES5_BodyAddOn8  = 0x00080000,
 | 
			
		||||
            TES5_DecapHead   = 0x00100000,
 | 
			
		||||
            TES5_Decapitate  = 0x00200000,
 | 
			
		||||
            TES5_BodyAddOn9  = 0x00400000,
 | 
			
		||||
            TES5_BodyAddOn10 = 0x00800000,
 | 
			
		||||
            TES5_BodyAddOn11 = 0x01000000,
 | 
			
		||||
            TES5_BodyAddOn12 = 0x02000000,
 | 
			
		||||
            TES5_BodyAddOn13 = 0x04000000,
 | 
			
		||||
            TES5_BodyAddOn14 = 0x08000000,
 | 
			
		||||
            TES5_BodyAddOn15 = 0x10000000,
 | 
			
		||||
            TES5_BodyAddOn16 = 0x20000000,
 | 
			
		||||
            TES5_BodyAddOn17 = 0x40000000,
 | 
			
		||||
            TES5_FX01        = 0x80000000
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        enum GeneralFlags
 | 
			
		||||
        {
 | 
			
		||||
            TYPE_TES4        = 0x1000,
 | 
			
		||||
            TYPE_FO3         = 0x2000,
 | 
			
		||||
            TYPE_TES5        = 0x3000,
 | 
			
		||||
            TYPE_FONV        = 0x4000,
 | 
			
		||||
            //
 | 
			
		||||
            TES4_HideRings   = 0x0001,
 | 
			
		||||
            TES4_HideAmulet  = 0x0002,
 | 
			
		||||
            TES4_NonPlayable = 0x0040,
 | 
			
		||||
            TES4_HeavyArmor  = 0x0080,
 | 
			
		||||
            //
 | 
			
		||||
            FO3_PowerArmor   = 0x0020,
 | 
			
		||||
            FO3_NonPlayable  = 0x0040,
 | 
			
		||||
            FO3_HeavyArmor   = 0x0080,
 | 
			
		||||
            //
 | 
			
		||||
            TES5_LightArmor  = 0x0000,
 | 
			
		||||
            TES5_HeavyArmor  = 0x0001,
 | 
			
		||||
            TES5_None        = 0x0002,
 | 
			
		||||
            TES5_ModVoice    = 0x0004, // note bit shift
 | 
			
		||||
            TES5_NonPlayable = 0x0040  // note bit shift
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint16_t armor; // only in TES4?
 | 
			
		||||
            std::uint32_t value;
 | 
			
		||||
            std::uint32_t health; // not in TES5?
 | 
			
		||||
            float         weight;
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        bool mIsTES4; // TODO: check that these match the general flags
 | 
			
		||||
        bool mIsFO3;
 | 
			
		||||
        bool mIsFONV;
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModelMale;
 | 
			
		||||
        std::string mModelMaleWorld;
 | 
			
		||||
        std::string mModelFemale;
 | 
			
		||||
        std::string mModelFemaleWorld;
 | 
			
		||||
        std::string mText;
 | 
			
		||||
        std::string mIconMale;
 | 
			
		||||
        std::string mMiniIconMale;
 | 
			
		||||
        std::string mIconFemale;
 | 
			
		||||
        std::string mMiniIconFemale;
 | 
			
		||||
 | 
			
		||||
        FormId mPickUpSound;
 | 
			
		||||
        FormId mDropSound;
 | 
			
		||||
 | 
			
		||||
        std::string mModel; // FIXME: for OpenCS
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        std::uint32_t mArmorFlags;
 | 
			
		||||
        std::uint32_t mGeneralFlags;
 | 
			
		||||
        FormId        mScriptId;
 | 
			
		||||
        std::uint16_t mEnchantmentPoints;
 | 
			
		||||
        FormId        mEnchantment;
 | 
			
		||||
 | 
			
		||||
        std::vector<FormId> mAddOns; // TES5 ARMA
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Armor();
 | 
			
		||||
        virtual ~Armor();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_ARMO_H
 | 
			
		||||
							
								
								
									
										94
									
								
								components/esm4/loadaspc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								components/esm4/loadaspc.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,94 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadaspc.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::AcousticSpace::AcousticSpace() : mFormId(0), mFlags(0), mEnvironmentType(0), mSoundRegion(0),
 | 
			
		||||
    mIsInterior(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::AcousticSpace::~AcousticSpace()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::AcousticSpace::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId);  break;
 | 
			
		||||
            case ESM4::SUB_ANAM: reader.get(mEnvironmentType); break;
 | 
			
		||||
            case ESM4::SUB_SNAM:
 | 
			
		||||
            {
 | 
			
		||||
                FormId id;
 | 
			
		||||
                reader.getFormId(id);
 | 
			
		||||
                mAmbientLoopSounds.push_back(id);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_RDAT: reader.getFormId(mSoundRegion); break;
 | 
			
		||||
            case ESM4::SUB_INAM: reader.get(mIsInterior); break;
 | 
			
		||||
            case ESM4::SUB_WNAM: // usually 0 for FONV (maybe # of close Actors for Walla to trigger)
 | 
			
		||||
            {
 | 
			
		||||
                std::uint32_t dummy;
 | 
			
		||||
                reader.get(dummy);
 | 
			
		||||
                //std::cout << "WNAM " << mEditorId << " " << dummy << std::endl;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_BNAM: // TES5 reverb formid
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "ASPC " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                          //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::ASPC::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::AcousticSpace::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::AcousticSpace::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										66
									
								
								components/esm4/loadaspc.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								components/esm4/loadaspc.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,66 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_ASPC_H
 | 
			
		||||
#define ESM4_ASPC_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct AcousticSpace
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
 | 
			
		||||
        std::uint32_t mEnvironmentType;
 | 
			
		||||
 | 
			
		||||
        // 0 Dawn (5:00 start), 1 Afternoon (8:00), 2 Dusk (18:00), 3 Night (20:00)
 | 
			
		||||
        std::vector<FormId> mAmbientLoopSounds;
 | 
			
		||||
        FormId mSoundRegion;
 | 
			
		||||
 | 
			
		||||
        std::uint32_t mIsInterior; // if true only use mAmbientLoopSounds[0]
 | 
			
		||||
 | 
			
		||||
        AcousticSpace();
 | 
			
		||||
        virtual ~AcousticSpace();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_ASPC_H
 | 
			
		||||
							
								
								
									
										121
									
								
								components/esm4/loadbook.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								components/esm4/loadbook.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,121 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadbook.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Book::Book() : mFormId(0), mFlags(0), mBoundRadius(0.f), mScriptId(0),
 | 
			
		||||
                     mEnchantmentPoints(0), mEnchantment(0), mPickUpSound(0), mDropSound(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
    mText.clear();
 | 
			
		||||
    mIcon.clear();
 | 
			
		||||
 | 
			
		||||
    mData.flags = 0;
 | 
			
		||||
    mData.type = 0;
 | 
			
		||||
    mData.bookSkill = 0;
 | 
			
		||||
    mData.value = 0;
 | 
			
		||||
    mData.weight = 0.f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Book::~Book()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Book::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
    //std::uint32_t esmVer = reader.esmVersion(); // currently unused
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_DESC: reader.getLocalizedString(mText); break;
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mData.flags);
 | 
			
		||||
                //if (reader.esmVersion() == ESM::VER_094 || reader.esmVersion() == ESM::VER_170)
 | 
			
		||||
                if (subHdr.dataSize == 16) // FO3 has 10 bytes even though VER_094
 | 
			
		||||
                {
 | 
			
		||||
                    static std::uint8_t dummy;
 | 
			
		||||
                    reader.get(mData.type);
 | 
			
		||||
                    reader.get(dummy);
 | 
			
		||||
                    reader.get(dummy);
 | 
			
		||||
                    reader.get(mData.teaches);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData.bookSkill);
 | 
			
		||||
                }
 | 
			
		||||
                reader.get(mData.value);
 | 
			
		||||
                reader.get(mData.weight);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIcon);  break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId);      break;
 | 
			
		||||
            case ESM4::SUB_ANAM: reader.get(mEnchantmentPoints); break;
 | 
			
		||||
            case ESM4::SUB_ENAM: reader.getFormId(mEnchantment); break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_YNAM: reader.getFormId(mPickUpSound); break;
 | 
			
		||||
            case ESM4::SUB_ZNAM: reader.getFormId(mDropSound); break; // TODO: does this exist?
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_KSIZ:
 | 
			
		||||
            case ESM4::SUB_KWDA:
 | 
			
		||||
            case ESM4::SUB_CNAM:
 | 
			
		||||
            case ESM4::SUB_INAM:
 | 
			
		||||
            case ESM4::SUB_VMAD:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "BOOK " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::BOOK::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Book::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Book::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										114
									
								
								components/esm4/loadbook.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								components/esm4/loadbook.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,114 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_BOOK_H
 | 
			
		||||
#define ESM4_BOOK_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Book
 | 
			
		||||
    {
 | 
			
		||||
        enum Flags
 | 
			
		||||
        {
 | 
			
		||||
            Flag_Scroll = 0x0001,
 | 
			
		||||
            Flag_NoTake = 0x0002
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        enum BookSkill // for TES4 only
 | 
			
		||||
        {
 | 
			
		||||
            BookSkill_None        = -1,
 | 
			
		||||
            BookSkill_Armorer     =  0,
 | 
			
		||||
            BookSkill_Athletics   =  1,
 | 
			
		||||
            BookSkill_Blade       =  2,
 | 
			
		||||
            BookSkill_Block       =  3,
 | 
			
		||||
            BookSkill_Blunt       =  4,
 | 
			
		||||
            BookSkill_HandToHand  =  5,
 | 
			
		||||
            BookSkill_HeavyArmor  =  6,
 | 
			
		||||
            BookSkill_Alchemy     =  7,
 | 
			
		||||
            BookSkill_Alteration  =  8,
 | 
			
		||||
            BookSkill_Conjuration =  9,
 | 
			
		||||
            BookSkill_Destruction = 10,
 | 
			
		||||
            BookSkill_Illusion    = 11,
 | 
			
		||||
            BookSkill_Mysticism   = 12,
 | 
			
		||||
            BookSkill_Restoration = 13,
 | 
			
		||||
            BookSkill_Acrobatics  = 14,
 | 
			
		||||
            BookSkill_LightArmor  = 15,
 | 
			
		||||
            BookSkill_Marksman    = 16,
 | 
			
		||||
            BookSkill_Mercantile  = 17,
 | 
			
		||||
            BookSkill_Security    = 18,
 | 
			
		||||
            BookSkill_Sneak       = 19,
 | 
			
		||||
            BookSkill_Speechcraft = 20
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint8_t  flags;
 | 
			
		||||
            std::uint8_t  type;    // TES5 only
 | 
			
		||||
            std::uint32_t teaches; // TES5 only
 | 
			
		||||
            std::int8_t bookSkill; // not in TES5
 | 
			
		||||
            std::uint32_t value;
 | 
			
		||||
            float         weight;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        std::string mText;
 | 
			
		||||
        FormId      mScriptId;
 | 
			
		||||
        std::string mIcon;
 | 
			
		||||
        std::uint16_t mEnchantmentPoints;
 | 
			
		||||
        FormId      mEnchantment;
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        FormId mPickUpSound;
 | 
			
		||||
        FormId mDropSound;
 | 
			
		||||
 | 
			
		||||
        Book();
 | 
			
		||||
        virtual ~Book();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_BOOK_H
 | 
			
		||||
							
								
								
									
										113
									
								
								components/esm4/loadbptd.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								components/esm4/loadbptd.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,113 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2019-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadbptd.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <iostream> // FIXME: testing only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
void ESM4::BodyPartData::BodyPart::clear()
 | 
			
		||||
{
 | 
			
		||||
    mPartName.clear();
 | 
			
		||||
    mNodeName.clear();
 | 
			
		||||
    mVATSTarget.clear();
 | 
			
		||||
    mIKStartNode.clear();
 | 
			
		||||
    std::memset(&mData, 0, sizeof(BPND));
 | 
			
		||||
    mLimbReplacementModel.clear();
 | 
			
		||||
    mGoreEffectsTarget.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::BodyPartData::BodyPartData() : mFormId(0), mFlags(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::BodyPartData::~BodyPartData()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::BodyPartData::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    BodyPart bodyPart;
 | 
			
		||||
    bodyPart.clear();
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_BPTN: reader.getLocalizedString(bodyPart.mPartName); break;
 | 
			
		||||
            case ESM4::SUB_BPNN: reader.getZString(bodyPart.mNodeName); break;
 | 
			
		||||
            case ESM4::SUB_BPNT: reader.getZString(bodyPart.mVATSTarget); break;
 | 
			
		||||
            case ESM4::SUB_BPNI: reader.getZString(bodyPart.mIKStartNode); break;
 | 
			
		||||
            case ESM4::SUB_BPND: reader.get(bodyPart.mData); break;
 | 
			
		||||
            case ESM4::SUB_NAM1: reader.getZString(bodyPart.mLimbReplacementModel); break;
 | 
			
		||||
            case ESM4::SUB_NAM4: // FIXME: assumed occurs last
 | 
			
		||||
            {
 | 
			
		||||
                reader.getZString(bodyPart.mGoreEffectsTarget); // target bone
 | 
			
		||||
 | 
			
		||||
                mBodyParts.push_back(bodyPart); // FIXME: possible without copying?
 | 
			
		||||
 | 
			
		||||
                bodyPart.clear();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_NAM5:
 | 
			
		||||
            case ESM4::SUB_RAGA: // ragdoll
 | 
			
		||||
            case ESM4::SUB_MODS:
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "BPTD " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::BPTD::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //if (mEditorId == "DefaultBodyPartData")
 | 
			
		||||
        //std::cout << "BPTD: " << mEditorId << std::endl; // FIXME: testing only
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::BodyPartData::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::BodyPartData::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										128
									
								
								components/esm4/loadbptd.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								components/esm4/loadbptd.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,128 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2019, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_BPTD_H
 | 
			
		||||
#define ESM4_BPTD_H
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct BodyPartData
 | 
			
		||||
    {
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        struct BPND
 | 
			
		||||
        {
 | 
			
		||||
            float damageMult;
 | 
			
		||||
 | 
			
		||||
            // Severable
 | 
			
		||||
            // IK Data
 | 
			
		||||
            // IK Data - Biped Data
 | 
			
		||||
            // Explodable
 | 
			
		||||
            // IK Data - Is Head
 | 
			
		||||
            // IK Data - Headtracking
 | 
			
		||||
            // To Hit Chance - Absolute
 | 
			
		||||
            std::uint8_t flags;
 | 
			
		||||
 | 
			
		||||
            // Torso
 | 
			
		||||
            // Head
 | 
			
		||||
            // Eye
 | 
			
		||||
            // LookAt
 | 
			
		||||
            // Fly Grab
 | 
			
		||||
            // Saddle
 | 
			
		||||
            std::uint8_t partType;
 | 
			
		||||
 | 
			
		||||
            std::uint8_t healthPercent;
 | 
			
		||||
            std::int8_t  actorValue; //(Actor Values)
 | 
			
		||||
            std::uint8_t toHitChance;
 | 
			
		||||
 | 
			
		||||
            std::uint8_t explExplosionChance; // %
 | 
			
		||||
            std::uint16_t explDebrisCount;
 | 
			
		||||
            FormId explDebris;
 | 
			
		||||
            FormId explExplosion;
 | 
			
		||||
            float trackingMaxAngle;
 | 
			
		||||
            float explDebrisScale;
 | 
			
		||||
 | 
			
		||||
            std::int32_t sevDebrisCount;
 | 
			
		||||
            FormId sevDebris;
 | 
			
		||||
            FormId sevExplosion;
 | 
			
		||||
            float sevDebrisScale;
 | 
			
		||||
 | 
			
		||||
            //Struct - Gore Effects Positioning
 | 
			
		||||
            float transX;
 | 
			
		||||
            float transY;
 | 
			
		||||
            float transZ;
 | 
			
		||||
            float rotX;
 | 
			
		||||
            float rotY;
 | 
			
		||||
            float rotZ;
 | 
			
		||||
 | 
			
		||||
            FormId sevImpactDataSet;
 | 
			
		||||
            FormId explImpactDataSet;
 | 
			
		||||
            uint8_t sevDecalCount;
 | 
			
		||||
            uint8_t explDecalCount;
 | 
			
		||||
            uint16_t Unknown;
 | 
			
		||||
            float limbReplacementScale;
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        struct BodyPart
 | 
			
		||||
        {
 | 
			
		||||
            std::string mPartName;
 | 
			
		||||
            std::string mNodeName;
 | 
			
		||||
            std::string mVATSTarget;
 | 
			
		||||
            std::string mIKStartNode;
 | 
			
		||||
            BPND mData;
 | 
			
		||||
            std::string mLimbReplacementModel;
 | 
			
		||||
            std::string mGoreEffectsTarget;
 | 
			
		||||
 | 
			
		||||
            void clear();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        std::vector<BodyPart> mBodyParts;
 | 
			
		||||
 | 
			
		||||
        BodyPartData();
 | 
			
		||||
        virtual ~BodyPartData();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_BPTD_H
 | 
			
		||||
							
								
								
									
										269
									
								
								components/esm4/loadcell.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								components/esm4/loadcell.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,269 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2015-2016, 2018-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadcell.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef NDEBUG // FIXME: debuggigng only
 | 
			
		||||
#undef NDEBUG
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cfloat> // FLT_MAX for gcc
 | 
			
		||||
 | 
			
		||||
#include <iostream> // FIXME: debug only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Cell::Cell() : mParent(0), mFormId(0), mFlags(0), mCellFlags(0), mX(0), mY(0), mOwner(0),
 | 
			
		||||
                     mGlobal(0), mClimate(0), mWater(0), mWaterHeight(0.f),
 | 
			
		||||
                     mLightingTemplate(0), mLightingTemplateFlags(0), mMusic(0), mAcousticSpace(0),
 | 
			
		||||
                     mMusicType(0), mPreloaded(false)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
 | 
			
		||||
    mLighting.ambient = 0;
 | 
			
		||||
    mLighting.directional = 0;
 | 
			
		||||
    mLighting.fogColor = 0;
 | 
			
		||||
    mLighting.fogNear = 0.f;
 | 
			
		||||
    mLighting.fogFar = 0.f;
 | 
			
		||||
    mLighting.rotationXY = 0;
 | 
			
		||||
    mLighting.rotationZ = 0;
 | 
			
		||||
    mLighting.fogDirFade = 0.f;
 | 
			
		||||
    mLighting.fogClipDist = 0.f;
 | 
			
		||||
    mLighting.fogPower = FLT_MAX; // hack way to detect TES4
 | 
			
		||||
 | 
			
		||||
    mRegions.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Cell::~Cell()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Cell::init(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
    mParent = reader.currWorld();
 | 
			
		||||
 | 
			
		||||
    reader.clearCellGrid(); // clear until XCLC FIXME: somehow do this automatically?
 | 
			
		||||
 | 
			
		||||
    // Sometimes cell 0,0 does not have an XCLC sub record (e.g. ToddLand 000009BF)
 | 
			
		||||
    // To workaround this issue put a default value if group is "exterior sub cell" and its
 | 
			
		||||
    // grid from label is "0 0".  Note the reversed X/Y order (no matter since they're both 0
 | 
			
		||||
    // anyway).
 | 
			
		||||
    if (reader.grp().type == ESM4::Grp_ExteriorSubCell
 | 
			
		||||
            && reader.grp().label.grid[1] == 0 && reader.grp().label.grid[0] == 0)
 | 
			
		||||
    {
 | 
			
		||||
        ESM4::CellGrid currCellGrid;
 | 
			
		||||
        currCellGrid.grid.x = 0;
 | 
			
		||||
        currCellGrid.grid.y = 0;
 | 
			
		||||
        reader.setCurrCellGrid(currCellGrid);  // side effect: sets mCellGridValid  true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: Try loading only EDID and XCLC (along with mFormId, mFlags and mParent)
 | 
			
		||||
//
 | 
			
		||||
// But, for external cells we may be scanning the whole record since we don't know if there is
 | 
			
		||||
// going to be an EDID subrecord. And the vast majority of cells are these kinds.
 | 
			
		||||
//
 | 
			
		||||
// So perhaps some testing needs to be done to see if scanning and skipping takes
 | 
			
		||||
// longer/shorter/same as loading the subrecords.
 | 
			
		||||
bool ESM4::Cell::preload(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    if (!mPreloaded)
 | 
			
		||||
        load(reader);
 | 
			
		||||
 | 
			
		||||
    mPreloaded = true;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Cell::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    if (mPreloaded)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    // WARN: we need to call setCurrCell (and maybe setCurrCellGrid?) again before loading
 | 
			
		||||
    // cell child groups if we are loading them after restoring the context
 | 
			
		||||
    // (may be easier to update the context before saving?)
 | 
			
		||||
    init(reader);
 | 
			
		||||
    reader.setCurrCell(mFormId); // save for LAND (and other children) to access later
 | 
			
		||||
    std::uint32_t esmVer = reader.esmVersion();
 | 
			
		||||
    bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID:
 | 
			
		||||
            {
 | 
			
		||||
                if (!reader.getZString(mEditorId))
 | 
			
		||||
                    throw std::runtime_error ("CELL EDID data read error");
 | 
			
		||||
#if 0
 | 
			
		||||
                std::string padding = "";
 | 
			
		||||
                padding.insert(0, reader.stackSize()*2, ' ');
 | 
			
		||||
                std::cout << padding << "CELL Editor ID: " << mEditorId << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_XCLC:
 | 
			
		||||
            {
 | 
			
		||||
                //(X, Y) grid location of the cell followed by flags. Always in
 | 
			
		||||
                //exterior cells and never in interior cells.
 | 
			
		||||
                //
 | 
			
		||||
                //    int32 - X
 | 
			
		||||
                //    int32 - Y
 | 
			
		||||
                //    uint32 - flags (high bits look random)
 | 
			
		||||
                //
 | 
			
		||||
                //        0x1 - Force Hide Land Quad 1
 | 
			
		||||
                //        0x2 - Force Hide Land Quad 2
 | 
			
		||||
                //        0x4 - Force Hide Land Quad 3
 | 
			
		||||
                //        0x8 - Force Hide Land Quad 4
 | 
			
		||||
                uint32_t flags;
 | 
			
		||||
                reader.get(mX);
 | 
			
		||||
                reader.get(mY);
 | 
			
		||||
#if 0
 | 
			
		||||
                std::string padding = "";
 | 
			
		||||
                padding.insert(0, reader.stackSize()*2, ' ');
 | 
			
		||||
                std::cout << padding << "CELL group " << ESM4::printLabel(reader.grp().label, reader.grp().type) << std::endl;
 | 
			
		||||
                std::cout << padding << "CELL formId " << std::hex << reader.hdr().record.id << std::endl;
 | 
			
		||||
                std::cout << padding << "CELL X " << std::dec << mX << ", Y " << mY << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
                if (esmVer == ESM::VER_094 || esmVer == ESM::VER_170 || isFONV)
 | 
			
		||||
                    if (subHdr.dataSize == 12)
 | 
			
		||||
                        reader.get(flags); // not in Obvlivion, nor FO3/FONV
 | 
			
		||||
 | 
			
		||||
                // Remember cell grid for later (loading LAND, NAVM which should be CELL temporary children)
 | 
			
		||||
                // Note that grids only apply for external cells.  For interior cells use the cell's formid.
 | 
			
		||||
                ESM4::CellGrid currCell;
 | 
			
		||||
                currCell.grid.x = (int16_t)mX;
 | 
			
		||||
                currCell.grid.y = (int16_t)mY;
 | 
			
		||||
                reader.setCurrCellGrid(currCell);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                if (esmVer == ESM::VER_094 || esmVer == ESM::VER_170 || isFONV)
 | 
			
		||||
                    if (subHdr.dataSize == 2)
 | 
			
		||||
                        reader.get(mCellFlags);
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        assert(subHdr.dataSize == 1 && "CELL unexpected DATA flag size");
 | 
			
		||||
                        reader.get(&mCellFlags, sizeof(std::uint8_t));
 | 
			
		||||
                    }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get((std::uint8_t&)mCellFlags); // 8 bits in Obvlivion
 | 
			
		||||
                }
 | 
			
		||||
#if 0
 | 
			
		||||
                std::string padding = "";
 | 
			
		||||
                padding.insert(0, reader.stackSize()*2, ' ');
 | 
			
		||||
                std::cout << padding  << "flags: " << std::hex << mCellFlags << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_XCLR: // for exterior cells
 | 
			
		||||
            {
 | 
			
		||||
                mRegions.resize(subHdr.dataSize/sizeof(FormId));
 | 
			
		||||
                for (std::vector<FormId>::iterator it = mRegions.begin(); it != mRegions.end(); ++it)
 | 
			
		||||
                {
 | 
			
		||||
                    reader.getFormId(*it);
 | 
			
		||||
#if 0
 | 
			
		||||
                    std::string padding = "";
 | 
			
		||||
                    padding.insert(0, reader.stackSize()*2, ' ');
 | 
			
		||||
                    std::cout << padding  << "region: " << std::hex << *it << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_XOWN: reader.getFormId(mOwner);   break;
 | 
			
		||||
            case ESM4::SUB_XGLB: reader.getFormId(mGlobal);  break; // Oblivion only?
 | 
			
		||||
            case ESM4::SUB_XCCM: reader.getFormId(mClimate); break;
 | 
			
		||||
            case ESM4::SUB_XCWT: reader.getFormId(mWater);   break;
 | 
			
		||||
            case ESM4::SUB_XCLW: reader.get(mWaterHeight);   break;
 | 
			
		||||
            case ESM4::SUB_XCLL:
 | 
			
		||||
            {
 | 
			
		||||
                if (esmVer == ESM::VER_094 || esmVer == ESM::VER_170 || isFONV)
 | 
			
		||||
                {
 | 
			
		||||
                    if (subHdr.dataSize == 40) // FO3/FONV
 | 
			
		||||
                        reader.get(mLighting);
 | 
			
		||||
                    else if (subHdr.dataSize == 92) // TES5
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.get(mLighting);
 | 
			
		||||
                        reader.skipSubRecordData(52); // FIXME
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                        reader.skipSubRecordData();
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    reader.get(&mLighting, 36); // TES4
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_XCMT: reader.get(mMusicType); break; // Oblivion only?
 | 
			
		||||
            case ESM4::SUB_LTMP: reader.getFormId(mLightingTemplate); break;
 | 
			
		||||
            case ESM4::SUB_LNAM: reader.get(mLightingTemplateFlags); break; // seems to always follow LTMP
 | 
			
		||||
            case ESM4::SUB_XCMO: reader.getFormId(mMusic); break;
 | 
			
		||||
            case ESM4::SUB_XCAS: reader.getFormId(mAcousticSpace); break;
 | 
			
		||||
            case ESM4::SUB_TVDT:
 | 
			
		||||
            case ESM4::SUB_MHDT:
 | 
			
		||||
            case ESM4::SUB_XCGD:
 | 
			
		||||
            case ESM4::SUB_XNAM:
 | 
			
		||||
            case ESM4::SUB_XLCN:
 | 
			
		||||
            case ESM4::SUB_XWCS:
 | 
			
		||||
            case ESM4::SUB_XWCU:
 | 
			
		||||
            case ESM4::SUB_XWCN:
 | 
			
		||||
            case ESM4::SUB_XCIM:
 | 
			
		||||
            case ESM4::SUB_XEZN:
 | 
			
		||||
            case ESM4::SUB_XWEM:
 | 
			
		||||
            case ESM4::SUB_XILL:
 | 
			
		||||
            case ESM4::SUB_XRNK: // Oblivion only?
 | 
			
		||||
            case ESM4::SUB_XCET: // FO3
 | 
			
		||||
            case ESM4::SUB_IMPF: // FO3 Zeta
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "CELL " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::CELL::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Cell::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
void ESM4::Cell::blank()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										109
									
								
								components/esm4/loadcell.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								components/esm4/loadcell.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,109 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2015-2016, 2018-2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_CELL_H
 | 
			
		||||
#define ESM4_CELL_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
#include "lighting.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
    struct ReaderContext;
 | 
			
		||||
    struct CellGroup;
 | 
			
		||||
    typedef std::uint32_t FormId;
 | 
			
		||||
 | 
			
		||||
    enum CellFlags               // TES4                     TES5
 | 
			
		||||
    {                            // -----------------------  ------------------------------------
 | 
			
		||||
        CELL_Interior = 0x0001,  // Can't travel from here   Interior
 | 
			
		||||
        CELL_HasWater = 0x0002,  // Has water (Int)          Has Water (Int)
 | 
			
		||||
        CELL_NoTravel = 0x0004,  //                          not Can't Travel From Here(Int only)
 | 
			
		||||
        CELL_HideLand = 0x0008,  // Force hide land (Ext)    No LOD Water
 | 
			
		||||
                                 // Oblivion interior (Int)
 | 
			
		||||
        CELL_Public   = 0x0020,  // Public place             Public Area
 | 
			
		||||
        CELL_HandChgd = 0x0040,  // Hand changed             Hand Changed
 | 
			
		||||
        CELL_QuasiExt = 0x0080,  // Behave like exterior     Show Sky
 | 
			
		||||
        CELL_SkyLight = 0x0100   //                          Use Sky Lighting
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Unlike TES3, multiple cells can have the same exterior co-ordinates.
 | 
			
		||||
    // The cells need to be organised under world spaces.
 | 
			
		||||
    struct Cell
 | 
			
		||||
    {
 | 
			
		||||
        FormId mParent;       // world formId (for grouping cells), from the loading sequence
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::uint16_t mCellFlags; // TES5 can also be 8 bits
 | 
			
		||||
 | 
			
		||||
        std::int32_t mX;
 | 
			
		||||
        std::int32_t mY;
 | 
			
		||||
 | 
			
		||||
        FormId mOwner;
 | 
			
		||||
        FormId mGlobal;
 | 
			
		||||
        FormId mClimate;
 | 
			
		||||
        FormId mWater;
 | 
			
		||||
        float  mWaterHeight;
 | 
			
		||||
 | 
			
		||||
        std::vector<FormId> mRegions;
 | 
			
		||||
        Lighting mLighting;
 | 
			
		||||
 | 
			
		||||
        FormId mLightingTemplate;             // FO3/FONV
 | 
			
		||||
        std::uint32_t mLightingTemplateFlags; // FO3/FONV
 | 
			
		||||
 | 
			
		||||
        FormId mMusic;         // FO3/FONV
 | 
			
		||||
        FormId mAcousticSpace; // FO3/FONV
 | 
			
		||||
        // TES4: 0 = default, 1 = public, 2 = dungeon
 | 
			
		||||
        // FO3/FONV have more types (not sure how they are used, however)
 | 
			
		||||
        std::uint8_t mMusicType;
 | 
			
		||||
 | 
			
		||||
        CellGroup *mCellGroup;
 | 
			
		||||
 | 
			
		||||
        Cell();
 | 
			
		||||
        virtual ~Cell();
 | 
			
		||||
 | 
			
		||||
        void init(ESM4::Reader& reader); // common setup for both preload() and load()
 | 
			
		||||
 | 
			
		||||
        bool mPreloaded;
 | 
			
		||||
        bool preload(ESM4::Reader& reader);
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_CELL_H
 | 
			
		||||
							
								
								
									
										84
									
								
								components/esm4/loadclas.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								components/esm4/loadclas.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadclas.hpp"
 | 
			
		||||
 | 
			
		||||
//#ifdef NDEBUG // FIXME: debugging only
 | 
			
		||||
//#undef NDEBUG
 | 
			
		||||
//#endif
 | 
			
		||||
 | 
			
		||||
//#include <cassert>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Class::Class()
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mDesc.clear();
 | 
			
		||||
    mIcon.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Class::~Class()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Class::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    //mFormId = reader.adjustFormId(reader.hdr().record.id); // FIXME: use master adjusted?
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_DESC: reader.getLocalizedString(mDesc); break;
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIcon);     break;
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "CLAS " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::CLAS::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Class::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Class::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										66
									
								
								components/esm4/loadclas.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								components/esm4/loadclas.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,66 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_CLAS_H
 | 
			
		||||
#define ESM4_CLAS_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Class
 | 
			
		||||
    {
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint32_t attr;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mDesc;
 | 
			
		||||
        std::string mIcon;
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Class();
 | 
			
		||||
        ~Class();
 | 
			
		||||
 | 
			
		||||
        void load(ESM4::Reader& reader);
 | 
			
		||||
        //void save(ESM4::Writer& reader) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_CLAS_H
 | 
			
		||||
							
								
								
									
										93
									
								
								components/esm4/loadclfm.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								components/esm4/loadclfm.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,93 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadclfm.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <iostream> // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Colour::Colour() : mFormId(0), mFlags(0), mPlayable(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
 | 
			
		||||
    mColour.red = 0;
 | 
			
		||||
    mColour.green = 0;
 | 
			
		||||
    mColour.blue = 0;
 | 
			
		||||
    mColour.custom = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Colour::~Colour()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Colour::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId);  break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_CNAM:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mColour.red);
 | 
			
		||||
                reader.get(mColour.green);
 | 
			
		||||
                reader.get(mColour.blue);
 | 
			
		||||
                reader.get(mColour.custom);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_FNAM:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mPlayable);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                //std::cout << "CLFM " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                          //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                //reader.skipSubRecordData();
 | 
			
		||||
                throw std::runtime_error("ESM4::CLFM::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Colour::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Colour::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										70
									
								
								components/esm4/loadclfm.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								components/esm4/loadclfm.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_CLFM_H
 | 
			
		||||
#define ESM4_CLFM_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    // FIXME: duplicate with Npc
 | 
			
		||||
    struct ColourRGB
 | 
			
		||||
    {
 | 
			
		||||
        std::uint8_t red;
 | 
			
		||||
        std::uint8_t green;
 | 
			
		||||
        std::uint8_t blue;
 | 
			
		||||
        std::uint8_t custom; // alpha?
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct Colour
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
 | 
			
		||||
        ColourRGB mColour;
 | 
			
		||||
        std::uint32_t mPlayable;
 | 
			
		||||
 | 
			
		||||
        Colour();
 | 
			
		||||
        virtual ~Colour();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_CLFM_H
 | 
			
		||||
							
								
								
									
										106
									
								
								components/esm4/loadclot.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								components/esm4/loadclot.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,106 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadclot.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Clothing::Clothing() : mFormId(0), mFlags(0), mBoundRadius(0.f), mClothingFlags(0),
 | 
			
		||||
                             mScriptId(0), mEnchantmentPoints(0), mEnchantment(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModelMale.clear();
 | 
			
		||||
    mModelMaleWorld.clear();
 | 
			
		||||
    mModelFemale.clear();
 | 
			
		||||
    mModelFemaleWorld.clear();
 | 
			
		||||
    mIconMale.clear();
 | 
			
		||||
    mIconFemale.clear();
 | 
			
		||||
 | 
			
		||||
    mData.value = 0;
 | 
			
		||||
    mData.weight = 0.f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Clothing::~Clothing()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Clothing::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getZString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_DATA: reader.get(mData);            break;
 | 
			
		||||
            case ESM4::SUB_BMDT: reader.get(mClothingFlags);   break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId);      break;
 | 
			
		||||
            case ESM4::SUB_ENAM: reader.getFormId(mEnchantment); break;
 | 
			
		||||
            case ESM4::SUB_ANAM: reader.get(mEnchantmentPoints); break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);     break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModelMale); break;
 | 
			
		||||
            case ESM4::SUB_MOD2: reader.getZString(mModelMaleWorld); break;
 | 
			
		||||
            case ESM4::SUB_MOD3: reader.getZString(mModelFemale); break;
 | 
			
		||||
            case ESM4::SUB_MOD4: reader.getZString(mModelFemaleWorld); break;
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIconMale); break;
 | 
			
		||||
            case ESM4::SUB_ICO2: reader.getZString(mIconFemale); break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_MO2B:
 | 
			
		||||
            case ESM4::SUB_MO3B:
 | 
			
		||||
            case ESM4::SUB_MO4B:
 | 
			
		||||
            case ESM4::SUB_MO2T:
 | 
			
		||||
            case ESM4::SUB_MO3T:
 | 
			
		||||
            case ESM4::SUB_MO4T:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "CLOT " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::CLOT::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    //if ((mClothingFlags&0xffff) == 0x02) // only hair
 | 
			
		||||
        //std::cout << "only hair " << mEditorId << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Clothing::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Clothing::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										83
									
								
								components/esm4/loadclot.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								components/esm4/loadclot.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,83 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018-2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_CLOT_H
 | 
			
		||||
#define ESM4_CLOT_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Clothing
 | 
			
		||||
    {
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint32_t value;   // gold
 | 
			
		||||
            float         weight;
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModelMale;
 | 
			
		||||
        std::string mModelMaleWorld;
 | 
			
		||||
        std::string mModelFemale;
 | 
			
		||||
        std::string mModelFemaleWorld;
 | 
			
		||||
        std::string mIconMale;   // texture
 | 
			
		||||
        std::string mIconFemale; // texture
 | 
			
		||||
 | 
			
		||||
        std::string mModel; // FIXME: for OpenCS
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        std::uint32_t mClothingFlags; // see Armor::ArmorFlags for the values
 | 
			
		||||
        FormId        mScriptId;
 | 
			
		||||
        std::uint16_t mEnchantmentPoints;
 | 
			
		||||
        FormId        mEnchantment;
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Clothing();
 | 
			
		||||
        virtual ~Clothing();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_CLOT_H
 | 
			
		||||
							
								
								
									
										107
									
								
								components/esm4/loadcont.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								components/esm4/loadcont.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,107 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadcont.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Container::Container() : mFormId(0), mFlags(0), mBoundRadius(0.f), mDataFlags(0), mWeight(0.f),
 | 
			
		||||
                               mOpenSound(0), mCloseSound(0), mScriptId(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Container::~Container()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Container::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mDataFlags);
 | 
			
		||||
                reader.get(mWeight);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_CNTO:
 | 
			
		||||
            {
 | 
			
		||||
                static InventoryItem inv; // FIXME: use unique_ptr here?
 | 
			
		||||
                reader.get(inv);
 | 
			
		||||
                reader.adjustFormId(inv.item);
 | 
			
		||||
                mInventory.push_back(inv);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel);     break;
 | 
			
		||||
            case ESM4::SUB_SNAM: reader.getFormId(mOpenSound);  break;
 | 
			
		||||
            case ESM4::SUB_QNAM: reader.getFormId(mCloseSound); break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId);     break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);      break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_MODS: // TES5 only
 | 
			
		||||
            case ESM4::SUB_VMAD: // TES5 only
 | 
			
		||||
            case ESM4::SUB_OBND: // TES5 only
 | 
			
		||||
            case ESM4::SUB_COCT: // TES5 only
 | 
			
		||||
            case ESM4::SUB_COED: // TES5 only
 | 
			
		||||
            case ESM4::SUB_DEST: // FONV
 | 
			
		||||
            case ESM4::SUB_DSTD: // FONV
 | 
			
		||||
            case ESM4::SUB_DSTF: // FONV
 | 
			
		||||
            case ESM4::SUB_DMDL: // FONV
 | 
			
		||||
            case ESM4::SUB_DMDT: // FONV
 | 
			
		||||
            case ESM4::SUB_RNAM: // FONV
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "CONT " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::CONT::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Container::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Container::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										71
									
								
								components/esm4/loadcont.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								components/esm4/loadcont.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_CONT_H
 | 
			
		||||
#define ESM4_CONT_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
#include "inventory.hpp" // InventoryItem
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Container
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
        unsigned char mDataFlags;
 | 
			
		||||
        float mWeight;
 | 
			
		||||
 | 
			
		||||
        FormId mOpenSound;
 | 
			
		||||
        FormId mCloseSound;
 | 
			
		||||
        FormId mScriptId; // TES4 only
 | 
			
		||||
 | 
			
		||||
        std::vector<InventoryItem> mInventory;
 | 
			
		||||
 | 
			
		||||
        Container();
 | 
			
		||||
        virtual ~Container();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_CONT_H
 | 
			
		||||
							
								
								
									
										232
									
								
								components/esm4/loadcrea.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								components/esm4/loadcrea.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,232 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadcrea.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef NDEBUG // FIXME: debuggigng only
 | 
			
		||||
#undef NDEBUG
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <iostream> // FIXME
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Creature::Creature() : mFormId(0), mFlags(0), mDeathItem(0), mScriptId(0), mCombatStyle(0),
 | 
			
		||||
                             mSoundBase(0), mSound(0), mSoundChance(0), mBaseScale(0.f),
 | 
			
		||||
                             mTurningSpeed(0.f), mFootWeight(0.f), mBoundRadius(0.f)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
 | 
			
		||||
    mBloodSpray.clear();
 | 
			
		||||
    mBloodDecal.clear();
 | 
			
		||||
 | 
			
		||||
    mAIData.aggression = 0;
 | 
			
		||||
    mAIData.confidence = 0;
 | 
			
		||||
    mAIData.energyLevel = 0;
 | 
			
		||||
    mAIData.responsibility = 0;
 | 
			
		||||
    mAIData.aiFlags = 0;
 | 
			
		||||
    mAIData.trainSkill = 0;
 | 
			
		||||
    mAIData.trainLevel = 0;
 | 
			
		||||
 | 
			
		||||
    std::memset(&mData, 0, sizeof(Data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Creature::~Creature()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Creature::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getZString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel);    break;
 | 
			
		||||
            case ESM4::SUB_CNTO:
 | 
			
		||||
            {
 | 
			
		||||
                static InventoryItem inv; // FIXME: use unique_ptr here?
 | 
			
		||||
                reader.get(inv);
 | 
			
		||||
                reader.adjustFormId(inv.item);
 | 
			
		||||
                mInventory.push_back(inv);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_SPLO:
 | 
			
		||||
            {
 | 
			
		||||
                FormId id;
 | 
			
		||||
                reader.getFormId(id);
 | 
			
		||||
                mSpell.push_back(id);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_PKID:
 | 
			
		||||
            {
 | 
			
		||||
                FormId id;
 | 
			
		||||
                reader.getFormId(id);
 | 
			
		||||
                mAIPackages.push_back(id);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_SNAM:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mFaction);
 | 
			
		||||
                reader.adjustFormId(mFaction.faction);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_INAM: reader.getFormId(mDeathItem);   break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId);      break;
 | 
			
		||||
            case ESM4::SUB_AIDT:
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize == 20) // FO3
 | 
			
		||||
                    reader.skipSubRecordData();
 | 
			
		||||
                else
 | 
			
		||||
                    reader.get(mAIData); // 12 bytes
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_ACBS:
 | 
			
		||||
            {
 | 
			
		||||
                //if (esmVer == ESM::VER_094 || esmVer == ESM::VER_170 || mIsFONV)
 | 
			
		||||
                if (subHdr.dataSize == 24)
 | 
			
		||||
                    reader.get(mBaseConfig);
 | 
			
		||||
                else
 | 
			
		||||
                    reader.get(&mBaseConfig, 16); // TES4
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize == 17) // FO3
 | 
			
		||||
                    reader.skipSubRecordData();
 | 
			
		||||
                else
 | 
			
		||||
                    reader.get(mData);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_ZNAM: reader.getFormId(mCombatStyle); break;
 | 
			
		||||
            case ESM4::SUB_CSCR: reader.getFormId(mSoundBase);   break;
 | 
			
		||||
            case ESM4::SUB_CSDI: reader.getFormId(mSound);       break;
 | 
			
		||||
            case ESM4::SUB_CSDC: reader.get(mSoundChance);  break;
 | 
			
		||||
            case ESM4::SUB_BNAM: reader.get(mBaseScale);    break;
 | 
			
		||||
            case ESM4::SUB_TNAM: reader.get(mTurningSpeed); break;
 | 
			
		||||
            case ESM4::SUB_WNAM: reader.get(mFootWeight);   break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_NAM0: reader.getZString(mBloodSpray); break;
 | 
			
		||||
            case ESM4::SUB_NAM1: reader.getZString(mBloodDecal); break;
 | 
			
		||||
            case ESM4::SUB_NIFZ:
 | 
			
		||||
            {
 | 
			
		||||
                std::string str;
 | 
			
		||||
                if (!reader.getZString(str))
 | 
			
		||||
                    throw std::runtime_error ("CREA NIFZ data read error");
 | 
			
		||||
 | 
			
		||||
                std::stringstream ss(str);
 | 
			
		||||
                std::string file;
 | 
			
		||||
                while (std::getline(ss, file, '\0')) // split the strings
 | 
			
		||||
                    mNif.push_back(file);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_NIFT:
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize != 4) // FIXME: FO3
 | 
			
		||||
                {
 | 
			
		||||
                    reader.skipSubRecordData();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                assert(subHdr.dataSize == 4 && "CREA NIFT datasize error");
 | 
			
		||||
                std::uint32_t nift;
 | 
			
		||||
                reader.get(nift);
 | 
			
		||||
                if (nift)
 | 
			
		||||
                    std::cout << "CREA NIFT " << mFormId << ", non-zero " << nift << std::endl;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_KFFZ:
 | 
			
		||||
            {
 | 
			
		||||
                std::string str;
 | 
			
		||||
                if (!reader.getZString(str))
 | 
			
		||||
                    throw std::runtime_error ("CREA KFFZ data read error");
 | 
			
		||||
 | 
			
		||||
                std::stringstream ss(str);
 | 
			
		||||
                std::string file;
 | 
			
		||||
                while (std::getline(ss, file, '\0')) // split the strings
 | 
			
		||||
                    mKf.push_back(file);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_TPLT: reader.get(mBaseTemplate); break; // FO3
 | 
			
		||||
            case ESM4::SUB_PNAM: // FO3/FONV/TES5
 | 
			
		||||
            {
 | 
			
		||||
                FormId bodyPart;
 | 
			
		||||
                reader.get(bodyPart);
 | 
			
		||||
                mBodyParts.push_back(bodyPart);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_RNAM:
 | 
			
		||||
            case ESM4::SUB_CSDT:
 | 
			
		||||
            case ESM4::SUB_OBND: // FO3
 | 
			
		||||
            case ESM4::SUB_EAMT: // FO3
 | 
			
		||||
            case ESM4::SUB_VTCK: // FO3
 | 
			
		||||
            case ESM4::SUB_NAM4: // FO3
 | 
			
		||||
            case ESM4::SUB_NAM5: // FO3
 | 
			
		||||
            case ESM4::SUB_CNAM: // FO3
 | 
			
		||||
            case ESM4::SUB_LNAM: // FO3
 | 
			
		||||
            case ESM4::SUB_EITM: // FO3
 | 
			
		||||
            case ESM4::SUB_DEST: // FO3
 | 
			
		||||
            case ESM4::SUB_DSTD: // FO3
 | 
			
		||||
            case ESM4::SUB_DSTF: // FO3
 | 
			
		||||
            case ESM4::SUB_DMDL: // FO3
 | 
			
		||||
            case ESM4::SUB_DMDT: // FO3
 | 
			
		||||
            case ESM4::SUB_COED: // FO3
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "CREA " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::CREA::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Creature::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Creature::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										151
									
								
								components/esm4/loadcrea.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								components/esm4/loadcrea.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,151 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_CREA_H
 | 
			
		||||
#define ESM4_CREA_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "actor.hpp"
 | 
			
		||||
#include "inventory.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Creature
 | 
			
		||||
    {
 | 
			
		||||
        enum ACBS_TES4
 | 
			
		||||
        {
 | 
			
		||||
            TES4_Essential      = 0x000002,
 | 
			
		||||
            TES4_WeapAndShield  = 0x000004,
 | 
			
		||||
            TES4_Respawn        = 0x000008,
 | 
			
		||||
            TES4_PCLevelOffset  = 0x000080,
 | 
			
		||||
            TES4_NoLowLevelProc = 0x000200,
 | 
			
		||||
            TES4_NoHead         = 0x008000, // different meaning to npc_
 | 
			
		||||
            TES4_NoRightArm     = 0x010000,
 | 
			
		||||
            TES4_NoLeftArm      = 0x020000,
 | 
			
		||||
            TES4_NoCombatWater  = 0x040000,
 | 
			
		||||
            TES4_NoShadow       = 0x080000,
 | 
			
		||||
            TES4_NoCorpseCheck  = 0x100000  // opposite of npc_
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        enum ACBS_FO3
 | 
			
		||||
        {
 | 
			
		||||
            FO3_Biped          = 0x00000001,
 | 
			
		||||
            FO3_Essential      = 0x00000002,
 | 
			
		||||
            FO3_Weap_Shield    = 0x00000004,
 | 
			
		||||
            FO3_Respawn        = 0x00000008,
 | 
			
		||||
            FO3_CanSwim        = 0x00000010,
 | 
			
		||||
            FO3_CanFly         = 0x00000020,
 | 
			
		||||
            FO3_CanWalk        = 0x00000040,
 | 
			
		||||
            FO3_PCLevelMult    = 0x00000080,
 | 
			
		||||
            FO3_NoLowLevelProc = 0x00000200,
 | 
			
		||||
            FO3_NoBloodSpray   = 0x00000800,
 | 
			
		||||
            FO3_NoBloodDecal   = 0x00001000,
 | 
			
		||||
            FO3_NoHead         = 0x00008000,
 | 
			
		||||
            FO3_NoRightArm     = 0x00010000,
 | 
			
		||||
            FO3_NoLeftArm      = 0x00020000,
 | 
			
		||||
            FO3_NoWaterCombat  = 0x00040000,
 | 
			
		||||
            FO3_NoShadow       = 0x00080000,
 | 
			
		||||
            FO3_NoVATSMelee    = 0x00100000,
 | 
			
		||||
            FO3_AllowPCDialog  = 0x00200000,
 | 
			
		||||
            FO3_NoOpenDoors    = 0x00400000,
 | 
			
		||||
            FO3_Immobile       = 0x00800000,
 | 
			
		||||
            FO3_TiltFrontBack  = 0x01000000,
 | 
			
		||||
            FO3_TiltLeftRight  = 0x02000000,
 | 
			
		||||
            FO3_NoKnockdown    = 0x04000000,
 | 
			
		||||
            FO3_NotPushable    = 0x08000000,
 | 
			
		||||
            FO3_AllowPickpoket = 0x10000000,
 | 
			
		||||
            FO3_IsGhost        = 0x20000000,
 | 
			
		||||
            FO3_NoRotateHead   = 0x40000000,
 | 
			
		||||
            FO3_Invulnerable   = 0x80000000
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint8_t  unknown;
 | 
			
		||||
            std::uint8_t  combat;
 | 
			
		||||
            std::uint8_t  magic;
 | 
			
		||||
            std::uint8_t  stealth;
 | 
			
		||||
            std::uint16_t soul;
 | 
			
		||||
            std::uint16_t health;
 | 
			
		||||
            std::uint16_t unknown2;
 | 
			
		||||
            std::uint16_t damage;
 | 
			
		||||
            AttributeValues attribs;
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        FormId mDeathItem;
 | 
			
		||||
        std::vector<FormId> mSpell;
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
 | 
			
		||||
        AIData mAIData;
 | 
			
		||||
        std::vector<FormId> mAIPackages;
 | 
			
		||||
        ActorBaseConfig mBaseConfig;
 | 
			
		||||
        ActorFaction mFaction;
 | 
			
		||||
        Data   mData;
 | 
			
		||||
        FormId mCombatStyle;
 | 
			
		||||
        FormId mSoundBase;
 | 
			
		||||
        FormId mSound;
 | 
			
		||||
        std::uint8_t mSoundChance;
 | 
			
		||||
        float mBaseScale;
 | 
			
		||||
        float mTurningSpeed;
 | 
			
		||||
        float mFootWeight;
 | 
			
		||||
        std::string mBloodSpray;
 | 
			
		||||
        std::string mBloodDecal;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
        std::vector<std::string> mNif; // NIF filenames, get directory from mModel
 | 
			
		||||
        std::vector<std::string> mKf;
 | 
			
		||||
 | 
			
		||||
        std::vector<InventoryItem> mInventory;
 | 
			
		||||
 | 
			
		||||
        FormId mBaseTemplate;           // FO3/FONV
 | 
			
		||||
        std::vector<FormId> mBodyParts; // FO3/FONV
 | 
			
		||||
 | 
			
		||||
        Creature();
 | 
			
		||||
        virtual ~Creature();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_CREA_H
 | 
			
		||||
							
								
								
									
										125
									
								
								components/esm4/loaddial.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								components/esm4/loaddial.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,125 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loaddial.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <iostream> // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Dialogue::Dialogue() : mFormId(0), mFlags(0), mDoAllBeforeRepeat(false),
 | 
			
		||||
                             mDialType(0), mDialFlags(0), mPriority(0.f)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mTopicName.clear();
 | 
			
		||||
 | 
			
		||||
    mTextDumb.clear(); // FIXME: temp name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Dialogue::~Dialogue()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Dialogue::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId);  break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getZString(mTopicName); break;
 | 
			
		||||
            case ESM4::SUB_QSTI:
 | 
			
		||||
            {
 | 
			
		||||
                FormId questId;
 | 
			
		||||
                reader.getFormId(questId);
 | 
			
		||||
                mQuests.push_back(questId);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_QSTR: // Seems never used in TES4
 | 
			
		||||
            {
 | 
			
		||||
                FormId questRem;
 | 
			
		||||
                reader.getFormId(questRem);
 | 
			
		||||
                mQuestsRemoved.push_back(questRem);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize == 4) // TES5
 | 
			
		||||
                {
 | 
			
		||||
                    std::uint8_t dummy;
 | 
			
		||||
                    reader.get(dummy);
 | 
			
		||||
                    if (dummy != 0)
 | 
			
		||||
                        mDoAllBeforeRepeat = true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                reader.get(mDialType); // TES4/FO3/FONV/TES5
 | 
			
		||||
 | 
			
		||||
                if (subHdr.dataSize >= 2) // FO3/FONV/TES5
 | 
			
		||||
                    reader.get(mDialFlags);
 | 
			
		||||
 | 
			
		||||
                if (subHdr.dataSize >= 3) // TES5
 | 
			
		||||
                    reader.skipSubRecordData(1); // unknown
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_PNAM: reader.get(mPriority); break; // FO3/FONV
 | 
			
		||||
            case ESM4::SUB_TDUM: reader.getZString(mTextDumb); break; // FONV
 | 
			
		||||
            case ESM4::SUB_SCRI:
 | 
			
		||||
            case ESM4::SUB_INFC: // FONV info connection
 | 
			
		||||
            case ESM4::SUB_INFX: // FONV info index
 | 
			
		||||
            case ESM4::SUB_QNAM: // TES5
 | 
			
		||||
            case ESM4::SUB_BNAM: // TES5
 | 
			
		||||
            case ESM4::SUB_SNAM: // TES5
 | 
			
		||||
            case ESM4::SUB_TIFC: // TES5
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "DIAL " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                        //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::DIAL::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Dialogue::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Dialogue::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										70
									
								
								components/esm4/loaddial.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								components/esm4/loaddial.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_DIAL_H
 | 
			
		||||
#define ESM4_DIAL_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
#include "dialogue.hpp" // DialType
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Dialogue
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::vector<FormId> mQuests;
 | 
			
		||||
        std::vector<FormId> mQuestsRemoved; // FONV only?
 | 
			
		||||
        std::string mTopicName;
 | 
			
		||||
 | 
			
		||||
        std::string mTextDumb; // FIXME: temp name
 | 
			
		||||
 | 
			
		||||
        bool mDoAllBeforeRepeat; // TES5 only
 | 
			
		||||
        std::uint8_t mDialType;  // DialType
 | 
			
		||||
        std::uint8_t mDialFlags; // FO3/FONV: 0x1 rumours, 0x2 top-level
 | 
			
		||||
 | 
			
		||||
        float mPriority;
 | 
			
		||||
 | 
			
		||||
        Dialogue();
 | 
			
		||||
        virtual ~Dialogue();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_DIAL_H
 | 
			
		||||
							
								
								
									
										128
									
								
								components/esm4/loaddobj.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								components/esm4/loaddobj.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,128 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
  Also see https://tes5edit.github.io/fopdoc/ for FO3/FONV specific details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loaddobj.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
//#include <iostream> // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
//#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::DefaultObj::DefaultObj() : mFormId(0), mFlags(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
 | 
			
		||||
    std::memset(&mData, 0, sizeof(Defaults));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::DefaultObj::~DefaultObj()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::DefaultObj::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break; // "DefaultObjectManager"
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                reader.getFormId(mData.stimpack);
 | 
			
		||||
                reader.getFormId(mData.superStimpack);
 | 
			
		||||
                reader.getFormId(mData.radX);
 | 
			
		||||
                reader.getFormId(mData.radAway);
 | 
			
		||||
                reader.getFormId(mData.morphine);
 | 
			
		||||
                reader.getFormId(mData.perkParalysis);
 | 
			
		||||
                reader.getFormId(mData.playerFaction);
 | 
			
		||||
                reader.getFormId(mData.mysteriousStrangerNPC);
 | 
			
		||||
                reader.getFormId(mData.mysteriousStrangerFaction);
 | 
			
		||||
                reader.getFormId(mData.defaultMusic);
 | 
			
		||||
                reader.getFormId(mData.battleMusic);
 | 
			
		||||
                reader.getFormId(mData.deathMusic);
 | 
			
		||||
                reader.getFormId(mData.successMusic);
 | 
			
		||||
                reader.getFormId(mData.levelUpMusic);
 | 
			
		||||
                reader.getFormId(mData.playerVoiceMale);
 | 
			
		||||
                reader.getFormId(mData.playerVoiceMaleChild);
 | 
			
		||||
                reader.getFormId(mData.playerVoiceFemale);
 | 
			
		||||
                reader.getFormId(mData.playerVoiceFemaleChild);
 | 
			
		||||
                reader.getFormId(mData.eatPackageDefaultFood);
 | 
			
		||||
                reader.getFormId(mData.everyActorAbility);
 | 
			
		||||
                reader.getFormId(mData.drugWearsOffImageSpace);
 | 
			
		||||
                // below FONV only
 | 
			
		||||
                if (subHdr.dataSize == 136) // FONV 136/4 = 34 formid
 | 
			
		||||
                {
 | 
			
		||||
                    reader.getFormId(mData.doctorsBag);
 | 
			
		||||
                    reader.getFormId(mData.missFortuneNPC);
 | 
			
		||||
                    reader.getFormId(mData.missFortuneFaction);
 | 
			
		||||
                    reader.getFormId(mData.meltdownExplosion);
 | 
			
		||||
                    reader.getFormId(mData.unarmedForwardPA);
 | 
			
		||||
                    reader.getFormId(mData.unarmedBackwardPA);
 | 
			
		||||
                    reader.getFormId(mData.unarmedLeftPA);
 | 
			
		||||
                    reader.getFormId(mData.unarmedRightPA);
 | 
			
		||||
                    reader.getFormId(mData.unarmedCrouchPA);
 | 
			
		||||
                    reader.getFormId(mData.unarmedCounterPA);
 | 
			
		||||
                    reader.getFormId(mData.spotterEffect);
 | 
			
		||||
                    reader.getFormId(mData.itemDetectedEfect);
 | 
			
		||||
                    reader.getFormId(mData.cateyeMobileEffectNYI);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_DNAM:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "DOBJ " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                          //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                //std::cout << "DOBJ " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                          //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                //reader.skipSubRecordData();
 | 
			
		||||
                throw std::runtime_error("ESM4::DOBJ::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::DefaultObj::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::DefaultObj::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										100
									
								
								components/esm4/loaddobj.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								components/esm4/loaddobj.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,100 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
  Also see https://tes5edit.github.io/fopdoc/ for FO3/FONV specific details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_DOBJ_H
 | 
			
		||||
#define ESM4_DOBJ_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Defaults
 | 
			
		||||
    {
 | 
			
		||||
        FormId stimpack;
 | 
			
		||||
        FormId superStimpack;
 | 
			
		||||
        FormId radX;
 | 
			
		||||
        FormId radAway;
 | 
			
		||||
        FormId morphine;
 | 
			
		||||
        FormId perkParalysis;
 | 
			
		||||
        FormId playerFaction;
 | 
			
		||||
        FormId mysteriousStrangerNPC;
 | 
			
		||||
        FormId mysteriousStrangerFaction;
 | 
			
		||||
        FormId defaultMusic;
 | 
			
		||||
        FormId battleMusic;
 | 
			
		||||
        FormId deathMusic;
 | 
			
		||||
        FormId successMusic;
 | 
			
		||||
        FormId levelUpMusic;
 | 
			
		||||
        FormId playerVoiceMale;
 | 
			
		||||
        FormId playerVoiceMaleChild;
 | 
			
		||||
        FormId playerVoiceFemale;
 | 
			
		||||
        FormId playerVoiceFemaleChild;
 | 
			
		||||
        FormId eatPackageDefaultFood;
 | 
			
		||||
        FormId everyActorAbility;
 | 
			
		||||
        FormId drugWearsOffImageSpace;
 | 
			
		||||
        // below FONV only
 | 
			
		||||
        FormId doctorsBag;
 | 
			
		||||
        FormId missFortuneNPC;
 | 
			
		||||
        FormId missFortuneFaction;
 | 
			
		||||
        FormId meltdownExplosion;
 | 
			
		||||
        FormId unarmedForwardPA;
 | 
			
		||||
        FormId unarmedBackwardPA;
 | 
			
		||||
        FormId unarmedLeftPA;
 | 
			
		||||
        FormId unarmedRightPA;
 | 
			
		||||
        FormId unarmedCrouchPA;
 | 
			
		||||
        FormId unarmedCounterPA;
 | 
			
		||||
        FormId spotterEffect;
 | 
			
		||||
        FormId itemDetectedEfect;
 | 
			
		||||
        FormId cateyeMobileEffectNYI;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct DefaultObj
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
 | 
			
		||||
        Defaults mData;
 | 
			
		||||
 | 
			
		||||
        DefaultObj();
 | 
			
		||||
        virtual ~DefaultObj();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_DOBJ_H
 | 
			
		||||
							
								
								
									
										93
									
								
								components/esm4/loaddoor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								components/esm4/loaddoor.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,93 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loaddoor.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Door::Door() : mFormId(0), mFlags(0), mBoundRadius(0.f), mDoorFlags(0), mScriptId(0),
 | 
			
		||||
                     mOpenSound(0), mCloseSound(0), mLoopSound(0), mRandomTeleport(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Door::~Door()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Door::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel);     break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId);     break;
 | 
			
		||||
            case ESM4::SUB_SNAM: reader.getFormId(mOpenSound);  break;
 | 
			
		||||
            case ESM4::SUB_ANAM: reader.getFormId(mCloseSound); break;
 | 
			
		||||
            case ESM4::SUB_BNAM: reader.getFormId(mLoopSound);  break;
 | 
			
		||||
            case ESM4::SUB_FNAM: reader.get(mDoorFlags);        break;
 | 
			
		||||
            case ESM4::SUB_TNAM: reader.getFormId(mRandomTeleport); break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);      break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_MODS:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_VMAD:
 | 
			
		||||
            case ESM4::SUB_DEST: // FO3
 | 
			
		||||
            case ESM4::SUB_DSTD: // FO3
 | 
			
		||||
            case ESM4::SUB_DSTF: // FO3
 | 
			
		||||
            case ESM4::SUB_DMDL: // FO3
 | 
			
		||||
            case ESM4::SUB_DMDT: // FO3
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "DOOR " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::DOOR::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Door::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Door::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										76
									
								
								components/esm4/loaddoor.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								components/esm4/loaddoor.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_DOOR_H
 | 
			
		||||
#define ESM4_DOOR_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Door
 | 
			
		||||
    {
 | 
			
		||||
        enum Flags
 | 
			
		||||
        {
 | 
			
		||||
            Flag_OblivionGate  = 0x01,
 | 
			
		||||
            Flag_AutomaticDoor = 0x02,
 | 
			
		||||
            Flag_Hidden        = 0x04,
 | 
			
		||||
            Flag_MinimalUse    = 0x08
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        std::uint8_t mDoorFlags;
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
        FormId mOpenSound;  // SNDR for TES5, SOUN for others
 | 
			
		||||
        FormId mCloseSound; // SNDR for TES5, SOUN for others
 | 
			
		||||
        FormId mLoopSound;
 | 
			
		||||
        FormId mRandomTeleport;
 | 
			
		||||
 | 
			
		||||
        Door();
 | 
			
		||||
        virtual ~Door();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_DOOR_H
 | 
			
		||||
							
								
								
									
										74
									
								
								components/esm4/loadeyes.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								components/esm4/loadeyes.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,74 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadeyes.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Eyes::Eyes() : mFormId(0), mFlags(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mIcon.clear();
 | 
			
		||||
 | 
			
		||||
    mData.flags = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Eyes::~Eyes()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Eyes::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIcon); break;
 | 
			
		||||
            case ESM4::SUB_DATA: reader.get(mData); break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::EYES::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Eyes::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Eyes::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										68
									
								
								components/esm4/loadeyes.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								components/esm4/loadeyes.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,68 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_EYES_H
 | 
			
		||||
#define ESM4_EYES_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Eyes
 | 
			
		||||
    {
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint8_t flags; // 0x01 = playable?
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mIcon;    // texture
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Eyes();
 | 
			
		||||
        virtual ~Eyes();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_EYES_H
 | 
			
		||||
							
								
								
									
										89
									
								
								components/esm4/loadflor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								components/esm4/loadflor.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,89 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadflor.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Flora::Flora() : mFormId(0), mFlags(0), mBoundRadius(0.f), mScriptId(0), mIngredient(0),
 | 
			
		||||
                       mSound(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Flora::~Flora()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Flora::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId);     break;
 | 
			
		||||
            case ESM4::SUB_PFIG: reader.getFormId(mIngredient); break;
 | 
			
		||||
            case ESM4::SUB_PFPC: reader.get(mPercentHarvest);   break;
 | 
			
		||||
            case ESM4::SUB_SNAM: reader.getFormId(mSound);      break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_MODS:
 | 
			
		||||
            case ESM4::SUB_FNAM:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_PNAM:
 | 
			
		||||
            case ESM4::SUB_RNAM:
 | 
			
		||||
            case ESM4::SUB_VMAD:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "FLOR " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::FLOR::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Flora::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Flora::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										78
									
								
								components/esm4/loadflor.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								components/esm4/loadflor.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_FLOR_H
 | 
			
		||||
#define ESM4_FLOR_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Flora
 | 
			
		||||
    {
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        struct Production
 | 
			
		||||
        {
 | 
			
		||||
            std::uint8_t spring;
 | 
			
		||||
            std::uint8_t summer;
 | 
			
		||||
            std::uint8_t autumn;
 | 
			
		||||
            std::uint8_t winter;
 | 
			
		||||
 | 
			
		||||
            Production() : spring(0), summer(0), autumn(0), winter(0) {}
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
        FormId mIngredient;
 | 
			
		||||
        FormId mSound;
 | 
			
		||||
        Production mPercentHarvest;
 | 
			
		||||
 | 
			
		||||
        Flora();
 | 
			
		||||
        virtual ~Flora();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_FLOR_H
 | 
			
		||||
							
								
								
									
										81
									
								
								components/esm4/loadflst.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								components/esm4/loadflst.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,81 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadflst.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::FormIdList::FormIdList() : mFormId(0), mFlags(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::FormIdList::~FormIdList()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::FormIdList::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId);  break;
 | 
			
		||||
            case ESM4::SUB_LNAM:
 | 
			
		||||
            {
 | 
			
		||||
                FormId formId;
 | 
			
		||||
                reader.getFormId(formId);
 | 
			
		||||
 | 
			
		||||
                mObjects.push_back(formId);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                //std::cout << "FLST " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                          //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                //reader.skipSubRecordData();
 | 
			
		||||
                throw std::runtime_error("ESM4::FLST::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    //std::cout << "flst " << mEditorId << " " << mObjects.size() << std::endl; // FIXME
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::FormIdList::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::FormIdList::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										60
									
								
								components/esm4/loadflst.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								components/esm4/loadflst.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_FLST_H
 | 
			
		||||
#define ESM4_FLST_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct FormIdList
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
 | 
			
		||||
        std::vector<FormId> mObjects;
 | 
			
		||||
 | 
			
		||||
        FormIdList();
 | 
			
		||||
        virtual ~FormIdList();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_FLST_H
 | 
			
		||||
							
								
								
									
										98
									
								
								components/esm4/loadfurn.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								components/esm4/loadfurn.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,98 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadfurn.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Furniture::Furniture() : mFormId(0), mFlags(0), mBoundRadius(0.f), mScriptId(0),
 | 
			
		||||
                               mActiveMarkerFlags(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Furniture::~Furniture()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Furniture::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId); break;
 | 
			
		||||
            case ESM4::SUB_MNAM: reader.get(mActiveMarkerFlags); break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_DEST:
 | 
			
		||||
            case ESM4::SUB_DSTD:
 | 
			
		||||
            case ESM4::SUB_DSTF:
 | 
			
		||||
            case ESM4::SUB_ENAM:
 | 
			
		||||
            case ESM4::SUB_FNAM:
 | 
			
		||||
            case ESM4::SUB_FNMK:
 | 
			
		||||
            case ESM4::SUB_FNPR:
 | 
			
		||||
            case ESM4::SUB_KNAM:
 | 
			
		||||
            case ESM4::SUB_KSIZ:
 | 
			
		||||
            case ESM4::SUB_KWDA:
 | 
			
		||||
            case ESM4::SUB_MODS:
 | 
			
		||||
            case ESM4::SUB_NAM0:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_PNAM:
 | 
			
		||||
            case ESM4::SUB_VMAD:
 | 
			
		||||
            case ESM4::SUB_WBDT:
 | 
			
		||||
            case ESM4::SUB_XMRK:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "FURN " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::FURN::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Furniture::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Furniture::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										64
									
								
								components/esm4/loadfurn.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								components/esm4/loadfurn.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_FURN_H
 | 
			
		||||
#define ESM4_FURN_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Furniture
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
        std::uint32_t mActiveMarkerFlags;
 | 
			
		||||
 | 
			
		||||
        Furniture();
 | 
			
		||||
        virtual ~Furniture();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_FURN_H
 | 
			
		||||
							
								
								
									
										82
									
								
								components/esm4/loadglob.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								components/esm4/loadglob.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadglob.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <iostream> // FIXME
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::GlobalVariable::GlobalVariable() : mFormId(0), mFlags(0), mType(0), mValue(0.f)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::GlobalVariable::~GlobalVariable()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::GlobalVariable::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FNAM: reader.get(mType);  break;
 | 
			
		||||
            case ESM4::SUB_FLTV: reader.get(mValue);  break;
 | 
			
		||||
            case ESM4::SUB_FULL:
 | 
			
		||||
            case ESM4::SUB_MODL:
 | 
			
		||||
            case ESM4::SUB_MODB:
 | 
			
		||||
            case ESM4::SUB_ICON:
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            case ESM4::SUB_OBND: // TES5
 | 
			
		||||
            case ESM4::SUB_VMAD: // TES5
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "GLOB " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::GLOB::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::GlobalVariable::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::GlobalVariable::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										60
									
								
								components/esm4/loadglob.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								components/esm4/loadglob.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_GLOB_H
 | 
			
		||||
#define ESM4_GLOB_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct GlobalVariable
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
 | 
			
		||||
        std::uint8_t mType;
 | 
			
		||||
        float mValue;
 | 
			
		||||
 | 
			
		||||
        GlobalVariable();
 | 
			
		||||
        virtual ~GlobalVariable();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_GLOB_H
 | 
			
		||||
							
								
								
									
										78
									
								
								components/esm4/loadgras.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								components/esm4/loadgras.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadgras.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Grass::Grass() : mFormId(0), mFlags(0), mBoundRadius(0.f)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Grass::~Grass()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Grass::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_DATA: reader.get(mData);         break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "GRAS " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::GRAS::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Grass::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Grass::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										98
									
								
								components/esm4/loadgras.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								components/esm4/loadgras.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,98 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_GRAS_H
 | 
			
		||||
#define ESM4_GRAS_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Grass
 | 
			
		||||
    {
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        // unused fields are probably packing
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint8_t  density;
 | 
			
		||||
            std::uint8_t  minSlope;
 | 
			
		||||
            std::uint8_t  maxSlope;
 | 
			
		||||
            std::uint8_t  unused;
 | 
			
		||||
            std::uint16_t distanceFromWater;
 | 
			
		||||
            std::uint16_t unused2;
 | 
			
		||||
            /*
 | 
			
		||||
            1 Above - At Least
 | 
			
		||||
            2 Above - At Most
 | 
			
		||||
            3 Below - At Least
 | 
			
		||||
            4 Below - At Most
 | 
			
		||||
            5 Either - At Least
 | 
			
		||||
            6 Either - At Most
 | 
			
		||||
            7 Either - At Most Above
 | 
			
		||||
            8 Either - At Most Below
 | 
			
		||||
            */
 | 
			
		||||
            std::uint32_t waterDistApplication;
 | 
			
		||||
            float positionRange;
 | 
			
		||||
            float heightRange;
 | 
			
		||||
            float colorRange;
 | 
			
		||||
            float wavePeriod;
 | 
			
		||||
            /*
 | 
			
		||||
            0x01 Vertex Lighting
 | 
			
		||||
            0x02 Uniform Scaling
 | 
			
		||||
            0x04 Fit to Slope
 | 
			
		||||
            */
 | 
			
		||||
            std::uint8_t  flags;
 | 
			
		||||
            std::uint8_t  unused3;
 | 
			
		||||
            std::uint16_t unused4;
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Grass();
 | 
			
		||||
        virtual ~Grass();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_GRAS_H
 | 
			
		||||
							
								
								
									
										158
									
								
								components/esm4/loadgrup.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								components/esm4/loadgrup.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,158 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_GRUP_H
 | 
			
		||||
#define ESM4_GRUP_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "common.hpp" // GroupLabel
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    // http://www.uesp.net/wiki/Tes4Mod:Mod_File_Format#Hierarchical_Top_Groups
 | 
			
		||||
    //
 | 
			
		||||
    //  Type | Info                                 |
 | 
			
		||||
    // ------+--------------------------------------+-------------------
 | 
			
		||||
    //   2   | Interior Cell Block                  |
 | 
			
		||||
    //   3   |   Interior Cell Sub-Block            |
 | 
			
		||||
    //     R |     CELL                             |
 | 
			
		||||
    //   6   |     Cell Childen                     |
 | 
			
		||||
    //   8   |       Persistent children            |
 | 
			
		||||
    //     R |         REFR, ACHR, ACRE             |
 | 
			
		||||
    //  10   |       Visible distant children       |
 | 
			
		||||
    //     R |         REFR, ACHR, ACRE             |
 | 
			
		||||
    //   9   |       Temp Children                  |
 | 
			
		||||
    //     R |         PGRD                         |
 | 
			
		||||
    //     R |         REFR, ACHR, ACRE             |
 | 
			
		||||
    //       |                                      |
 | 
			
		||||
    //   0   | Top (Type)                           |
 | 
			
		||||
    //     R |   WRLD                               |
 | 
			
		||||
    //   1   |   World Children                     |
 | 
			
		||||
    //     R |     ROAD                             |
 | 
			
		||||
    //     R |     CELL                             |
 | 
			
		||||
    //   6   |     Cell Childen                     |
 | 
			
		||||
    //   8   |       Persistent children            |
 | 
			
		||||
    //     R |         REFR, ACHR, ACRE             |
 | 
			
		||||
    //  10   |       Visible distant children       |
 | 
			
		||||
    //     R |         REFR, ACHR, ACRE             |
 | 
			
		||||
    //   9   |       Temp Children                  |
 | 
			
		||||
    //     R |         PGRD                         |
 | 
			
		||||
    //     R |         REFR, ACHR, ACRE             |
 | 
			
		||||
    //   4   |       Exterior World Block           |
 | 
			
		||||
    //   5   |         Exterior World Sub-block     |
 | 
			
		||||
    //     R |           CELL                       |
 | 
			
		||||
    //   6   |           Cell Childen               |
 | 
			
		||||
    //   8   |             Persistent children      |
 | 
			
		||||
    //     R |               REFR, ACHR, ACRE       |
 | 
			
		||||
    //  10   |             Visible distant children |
 | 
			
		||||
    //     R |               REFR, ACHR, ACRE       |
 | 
			
		||||
    //   9   |             Temp Children            |
 | 
			
		||||
    //     R |               LAND                   |
 | 
			
		||||
    //     R |               PGRD                   |
 | 
			
		||||
    //     R |               REFR, ACHR, ACRE       |
 | 
			
		||||
    //
 | 
			
		||||
    struct WorldGroup
 | 
			
		||||
    {
 | 
			
		||||
        FormId mWorld; // WRLD record for this group
 | 
			
		||||
 | 
			
		||||
        // occurs only after World Child (type 1)
 | 
			
		||||
        // since GRUP label may not be reliable, need to keep the formid of the current WRLD in
 | 
			
		||||
        // the reader's context
 | 
			
		||||
        FormId mRoad;
 | 
			
		||||
 | 
			
		||||
        std::vector<FormId> mCells; // FIXME should this be CellGroup* instead?
 | 
			
		||||
 | 
			
		||||
        WorldGroup() : mWorld(0), mRoad(0) {}
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // http://www.uesp.net/wiki/Tes4Mod:Mod_File_Format/CELL
 | 
			
		||||
    //
 | 
			
		||||
    // The block and subblock groups for an interior cell are determined by the last two decimal
 | 
			
		||||
    // digits of the lower 3 bytes of the cell form ID (the modindex is not included in the
 | 
			
		||||
    // calculation). For example, for form ID 0x000CF2=3314, the block is 4 and the subblock is 1.
 | 
			
		||||
    //
 | 
			
		||||
    // The block and subblock groups for an exterior cell are determined by the X-Y coordinates of
 | 
			
		||||
    // the cell. Each block contains 16 subblocks (4x4) and each subblock contains 64 cells (8x8).
 | 
			
		||||
    // So each block contains 1024 cells (32x32).
 | 
			
		||||
    //
 | 
			
		||||
    // NOTE: There may be many CELL records in one subblock
 | 
			
		||||
    struct CellGroup
 | 
			
		||||
    {
 | 
			
		||||
        FormId mCell;      // CELL record for this cell group
 | 
			
		||||
        int mCellModIndex; // from which file to get the CELL record (e.g. may have been updated)
 | 
			
		||||
 | 
			
		||||
        // For retrieving parent group size (for lazy loading or skipping) and sub-block number / grid
 | 
			
		||||
        // NOTE: There can be more than one file that adds/modifies records to this cell group
 | 
			
		||||
        //
 | 
			
		||||
        // Use Case 1: To quickly get only the visble when distant records:
 | 
			
		||||
        //
 | 
			
		||||
        //   - Find the FormId of the CELL (maybe WRLD/X/Y grid lookup or from XTEL of a REFR)
 | 
			
		||||
        //   - search a map of CELL FormId to CellGroup
 | 
			
		||||
        //   - load CELL and its child groups (or load the visible distant only, or whatever)
 | 
			
		||||
        //
 | 
			
		||||
        // Use Case 2: Scan the files but don't load CELL or cell group
 | 
			
		||||
        //
 | 
			
		||||
        //   - Load referenceables and other records up front, updating them as required
 | 
			
		||||
        //   - Don't load CELL, LAND, PGRD or ROAD (keep FormId's and file index, and file
 | 
			
		||||
        //     context then skip the rest of the group)
 | 
			
		||||
        //
 | 
			
		||||
        std::vector<GroupTypeHeader> mHeaders; // FIXME: is this needed?
 | 
			
		||||
 | 
			
		||||
        // FIXME: should these be pairs?  i.e. <FormId, modindex> so that we know from which file
 | 
			
		||||
        //        the formid came (it may have been updated by a mod)
 | 
			
		||||
        //        but does it matter?  the record itself keeps track of whether it is base,
 | 
			
		||||
        //        added or modified anyway
 | 
			
		||||
        // FIXME: should these be maps? e.g. std::map<FormId, std::uint8_t>
 | 
			
		||||
        //        or vector for storage with a corresponding map of index?
 | 
			
		||||
 | 
			
		||||
        // cache (modindex adjusted) formId's of children
 | 
			
		||||
        // FIXME: also need file index + file context of all those that has type 8 GRUP
 | 
			
		||||
        GroupTypeHeader mHdrPersist;
 | 
			
		||||
        std::vector<FormId> mPersistent;  // REFR, ACHR, ACRE
 | 
			
		||||
        std::vector<FormId> mdelPersistent;
 | 
			
		||||
 | 
			
		||||
        // FIXME: also need file index + file context of all those that has type 10 GRUP
 | 
			
		||||
        GroupTypeHeader mHdrVisDist;
 | 
			
		||||
        std::vector<FormId> mVisibleDist; // REFR, ACHR, ACRE
 | 
			
		||||
        std::vector<FormId> mdelVisibleDist;
 | 
			
		||||
 | 
			
		||||
        // FIXME: also need file index + file context of all those that has type 9 GRUP
 | 
			
		||||
        GroupTypeHeader mHdrTemp;
 | 
			
		||||
        FormId mLand; // if present, assume only one LAND per exterior CELL
 | 
			
		||||
        FormId mPgrd; // if present, seems to be the first record after LAND in Temp Cell Child GRUP
 | 
			
		||||
        std::vector<FormId> mTemporary;   // REFR, ACHR, ACRE
 | 
			
		||||
        std::vector<FormId> mdelTemporary;
 | 
			
		||||
 | 
			
		||||
        // need to keep modindex and context for lazy loading (of all the files that contribute
 | 
			
		||||
        // to this group)
 | 
			
		||||
 | 
			
		||||
        CellGroup() : mCell(0), mLand(0), mPgrd(0) {}
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_GRUP_H
 | 
			
		||||
							
								
								
									
										84
									
								
								components/esm4/loadhair.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								components/esm4/loadhair.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadhair.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Hair::Hair() : mFormId(0), mFlags(0), mBoundRadius(0.f)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
    mIcon.clear();
 | 
			
		||||
 | 
			
		||||
    mData.flags = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Hair::~Hair()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Hair::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getZString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIcon);  break;
 | 
			
		||||
            case ESM4::SUB_DATA: reader.get(mData);         break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "HAIR " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::HAIR::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Hair::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Hair::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										71
									
								
								components/esm4/loadhair.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								components/esm4/loadhair.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_HAIR
 | 
			
		||||
#define ESM4_HAIR
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Hair
 | 
			
		||||
    {
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint8_t flags; // 0x01 = not playable, 0x02 = not male, 0x04 = not female, ?? = fixed
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;   // mesh
 | 
			
		||||
        std::string mIcon;    // texture
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Hair();
 | 
			
		||||
        virtual ~Hair();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_HAIR
 | 
			
		||||
							
								
								
									
										104
									
								
								components/esm4/loadhdpt.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								components/esm4/loadhdpt.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2019-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadhdpt.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME: testing only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::HeadPart::HeadPart() : mFormId(0), mFlags(0), mData(0), mAdditionalPart(0), mBaseTexture(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
 | 
			
		||||
    mTriFile.resize(3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::HeadPart::~HeadPart()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::HeadPart::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    std::uint32_t type;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_DATA: reader.get(mData); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_HNAM: reader.getFormId(mAdditionalPart); break;
 | 
			
		||||
            case ESM4::SUB_NAM0: // TES5
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(type);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_NAM1: // TES5
 | 
			
		||||
            {
 | 
			
		||||
                std::string file;
 | 
			
		||||
                reader.getZString(file);
 | 
			
		||||
 | 
			
		||||
                // FIXME: check type >= 0 && type < 3
 | 
			
		||||
                mTriFile[type] = std::move(file);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_TNAM: reader.getFormId(mBaseTexture); break;
 | 
			
		||||
            case ESM4::SUB_PNAM:
 | 
			
		||||
            case ESM4::SUB_MODS:
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_RNAM:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "HDPT " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::HDPT::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::HeadPart::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::HeadPart::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										66
									
								
								components/esm4/loadhdpt.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								components/esm4/loadhdpt.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,66 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2019, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_HDPT_H
 | 
			
		||||
#define ESM4_HDPT_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct HeadPart
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        std::uint8_t mData;
 | 
			
		||||
 | 
			
		||||
        FormId mAdditionalPart;
 | 
			
		||||
 | 
			
		||||
        std::vector<std::string> mTriFile;
 | 
			
		||||
        FormId mBaseTexture;
 | 
			
		||||
 | 
			
		||||
        HeadPart();
 | 
			
		||||
        virtual ~HeadPart();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_HDPT_H
 | 
			
		||||
							
								
								
									
										84
									
								
								components/esm4/loadidle.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								components/esm4/loadidle.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadidle.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::IdleAnimation::IdleAnimation() : mFormId(0), mFlags(0), mParent(0), mPrevious(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mCollision.clear();
 | 
			
		||||
    mEvent.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::IdleAnimation::~IdleAnimation()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::IdleAnimation::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId);  break;
 | 
			
		||||
            case ESM4::SUB_DNAM: reader.getZString(mCollision); break;
 | 
			
		||||
            case ESM4::SUB_ENAM: reader.getZString(mEvent);     break;
 | 
			
		||||
            case ESM4::SUB_ANAM:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mParent);
 | 
			
		||||
                reader.get(mPrevious);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_CTDA: // formId
 | 
			
		||||
            case ESM4::SUB_DATA: // formId
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "IDLE " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::IDLE::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::IdleAnimation::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::IdleAnimation::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										62
									
								
								components/esm4/loadidle.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								components/esm4/loadidle.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_IDLE_H
 | 
			
		||||
#define ESM4_IDLE_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct IdleAnimation
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mCollision;
 | 
			
		||||
        std::string mEvent;
 | 
			
		||||
 | 
			
		||||
        FormId      mParent;  // IDLE or AACT
 | 
			
		||||
        FormId      mPrevious;
 | 
			
		||||
 | 
			
		||||
        IdleAnimation();
 | 
			
		||||
        virtual ~IdleAnimation();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_IDLE_H
 | 
			
		||||
							
								
								
									
										103
									
								
								components/esm4/loadidlm.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								components/esm4/loadidlm.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,103 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2019, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadidlm.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME: testing only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::IdleMarker::IdleMarker() : mFormId(0), mFlags(0), mIdleFlags(0), mIdleCount(0), mIdleTimer(0.f), mIdleAnim(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::IdleMarker::~IdleMarker()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::IdleMarker::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    std::uint32_t esmVer = reader.esmVersion();
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_IDLF: reader.get(mIdleFlags);       break;
 | 
			
		||||
            case ESM4::SUB_IDLC:
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize != 1) // FO3 can have 4?
 | 
			
		||||
                {
 | 
			
		||||
                    reader.skipSubRecordData();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                reader.get(mIdleCount);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_IDLT: reader.get(mIdleTimer);       break;
 | 
			
		||||
            case ESM4::SUB_IDLA:
 | 
			
		||||
            {
 | 
			
		||||
                bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134;
 | 
			
		||||
                if (esmVer == ESM::VER_094 || isFONV) // FO3? 4 or 8 bytes
 | 
			
		||||
                {
 | 
			
		||||
                    reader.skipSubRecordData();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                mIdleAnim.resize(mIdleCount);
 | 
			
		||||
                for (unsigned int i = 0; i < static_cast<unsigned int>(mIdleCount); ++i)
 | 
			
		||||
                    reader.get(mIdleAnim.at(i));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_OBND: // object bounds
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "IDLM " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::IDLM::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::IdleMarker::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::IdleMarker::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										63
									
								
								components/esm4/loadidlm.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								components/esm4/loadidlm.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2019, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_IDLM_H
 | 
			
		||||
#define ESM4_IDLM_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct IdleMarker
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
 | 
			
		||||
        std::uint8_t mIdleFlags;
 | 
			
		||||
        std::uint8_t mIdleCount;
 | 
			
		||||
        float mIdleTimer;
 | 
			
		||||
        std::vector<FormId> mIdleAnim;
 | 
			
		||||
 | 
			
		||||
        IdleMarker();
 | 
			
		||||
        virtual ~IdleMarker();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_IDLM_H
 | 
			
		||||
							
								
								
									
										89
									
								
								components/esm4/loadimod.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								components/esm4/loadimod.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,89 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
  Also see https://tes5edit.github.io/fopdoc/ for FO3/FONV specific details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadimod.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <iostream> // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::ItemMod::ItemMod() : mFormId(0), mFlags(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::ItemMod::~ItemMod()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::ItemMod::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId);  break;
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_FULL:
 | 
			
		||||
            case ESM4::SUB_MODL:
 | 
			
		||||
            case ESM4::SUB_ICON:
 | 
			
		||||
            case ESM4::SUB_MICO:
 | 
			
		||||
            case ESM4::SUB_SCRI:
 | 
			
		||||
            case ESM4::SUB_DESC:
 | 
			
		||||
            case ESM4::SUB_YNAM:
 | 
			
		||||
            case ESM4::SUB_ZNAM:
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "IMOD " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                          //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                std::cout << "IMOD " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                          << subHdr.dataSize << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                //throw std::runtime_error("ESM4::IMOD::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::ItemMod::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::ItemMod::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										59
									
								
								components/esm4/loadimod.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								components/esm4/loadimod.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
  Also see https://tes5edit.github.io/fopdoc/ for FO3/FONV specific details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_IMOD_H
 | 
			
		||||
#define ESM4_IMOD_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct ItemMod
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
 | 
			
		||||
        ItemMod();
 | 
			
		||||
        virtual ~ItemMod();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_IMOD_H
 | 
			
		||||
							
								
								
									
										222
									
								
								components/esm4/loadinfo.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								components/esm4/loadinfo.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,222 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadinfo.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <iostream> // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::DialogInfo::DialogInfo() : mFormId(0), mFlags(0), mQuest(0), mSound(0),
 | 
			
		||||
    mDialType(0), mNextSpeaker(0), mInfoFlags(0), mParam3(0)
 | 
			
		||||
{
 | 
			
		||||
    std::memset(&mResponseData, 0, sizeof(TargetResponseData));
 | 
			
		||||
    mResponse.clear();
 | 
			
		||||
    mNotes.clear();
 | 
			
		||||
    mEdits.clear();
 | 
			
		||||
 | 
			
		||||
    std::memset(&mTargetCondition, 0, sizeof(TargetCondition));
 | 
			
		||||
 | 
			
		||||
    std::memset(&mScript.scriptHeader, 0, sizeof(ScriptHeader));
 | 
			
		||||
    mScript.scriptSource.clear();
 | 
			
		||||
    mScript.globReference = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::DialogInfo::~DialogInfo()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::DialogInfo::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    mEditorId = formIdToString(mFormId); // FIXME: quick workaround to use existing code
 | 
			
		||||
 | 
			
		||||
    static ScriptLocalVariableData localVar;
 | 
			
		||||
    bool ignore = false;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_QSTI: reader.getFormId(mQuest); break; // FormId quest id
 | 
			
		||||
            case ESM4::SUB_SNDD: reader.getFormId(mSound); break; // FO3 (not used in FONV?)
 | 
			
		||||
            case ESM4::SUB_TRDT:
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize == 16) // TES4
 | 
			
		||||
                    reader.get(&mResponseData, 16);
 | 
			
		||||
                else if (subHdr.dataSize == 20) // FO3
 | 
			
		||||
                    reader.get(&mResponseData, 20);
 | 
			
		||||
                else // FO3/FONV
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mResponseData);
 | 
			
		||||
                    if (mResponseData.sound)
 | 
			
		||||
                        reader.adjustFormId(mResponseData.sound);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_NAM1: reader.getZString(mResponse); break; // response text
 | 
			
		||||
            case ESM4::SUB_NAM2: reader.getZString(mNotes); break; // actor notes
 | 
			
		||||
            case ESM4::SUB_NAM3: reader.getZString(mEdits); break; // not in TES4
 | 
			
		||||
            case ESM4::SUB_CTDA: // FIXME: how to detect if 1st/2nd param is a formid?
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize == 24) // TES4
 | 
			
		||||
                    reader.get(&mTargetCondition, 24);
 | 
			
		||||
                else if (subHdr.dataSize == 20) // FO3
 | 
			
		||||
                    reader.get(&mTargetCondition, 20);
 | 
			
		||||
                else if (subHdr.dataSize == 28)
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mTargetCondition); // FO3/FONV
 | 
			
		||||
                    if (mTargetCondition.reference)
 | 
			
		||||
                        reader.adjustFormId(mTargetCondition.reference);
 | 
			
		||||
                }
 | 
			
		||||
                else // TES5
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(&mTargetCondition, 20);
 | 
			
		||||
                    if (subHdr.dataSize == 36)
 | 
			
		||||
                        reader.getFormId(mParam3);
 | 
			
		||||
                    reader.get(mTargetCondition.runOn);
 | 
			
		||||
                    reader.get(mTargetCondition.reference);
 | 
			
		||||
                    if (mTargetCondition.reference)
 | 
			
		||||
                        reader.adjustFormId(mTargetCondition.reference);
 | 
			
		||||
                    reader.skipSubRecordData(4); // unknown
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_SCHR:
 | 
			
		||||
            {
 | 
			
		||||
                if (!ignore)
 | 
			
		||||
                    reader.get(mScript.scriptHeader);
 | 
			
		||||
                else
 | 
			
		||||
                    reader.skipSubRecordData(); // TODO: does the second one ever used?
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_SCDA: reader.skipSubRecordData(); break; // compiled script data
 | 
			
		||||
            case ESM4::SUB_SCTX: reader.getString(mScript.scriptSource); break;
 | 
			
		||||
            case ESM4::SUB_SCRO: reader.getFormId(mScript.globReference); break;
 | 
			
		||||
            case ESM4::SUB_SLSD:
 | 
			
		||||
            {
 | 
			
		||||
                localVar.clear();
 | 
			
		||||
                reader.get(localVar.index);
 | 
			
		||||
                reader.get(localVar.unknown1);
 | 
			
		||||
                reader.get(localVar.unknown2);
 | 
			
		||||
                reader.get(localVar.unknown3);
 | 
			
		||||
                reader.get(localVar.type);
 | 
			
		||||
                reader.get(localVar.unknown4);
 | 
			
		||||
                // WARN: assumes SCVR will follow immediately
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_SCVR: // assumed always pair with SLSD
 | 
			
		||||
            {
 | 
			
		||||
                reader.getZString(localVar.variableName);
 | 
			
		||||
 | 
			
		||||
                mScript.localVarData.push_back(localVar);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_SCRV:
 | 
			
		||||
            {
 | 
			
		||||
                std::uint32_t index;
 | 
			
		||||
                reader.get(index);
 | 
			
		||||
 | 
			
		||||
                mScript.localRefVarIndex.push_back(index);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_NEXT: // FO3/FONV marker for next script header
 | 
			
		||||
            {
 | 
			
		||||
                ignore = true;
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_DATA: // always 3 for TES4 ?
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize == 4) // FO3/FONV
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mDialType);
 | 
			
		||||
                    reader.get(mNextSpeaker);
 | 
			
		||||
                    reader.get(mInfoFlags);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    reader.skipSubRecordData(); // FIXME
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_NAME: // FormId add topic (not always present)
 | 
			
		||||
            case ESM4::SUB_CTDT: // older version of CTDA? 20 bytes
 | 
			
		||||
            case ESM4::SUB_SCHD: // 28 bytes
 | 
			
		||||
            case ESM4::SUB_TCLT: // FormId choice
 | 
			
		||||
            case ESM4::SUB_TCLF: // FormId
 | 
			
		||||
            case ESM4::SUB_PNAM: // TES4 DLC
 | 
			
		||||
            case ESM4::SUB_TPIC: // TES4 DLC
 | 
			
		||||
            case ESM4::SUB_ANAM: // FO3 speaker formid
 | 
			
		||||
            case ESM4::SUB_DNAM: // FO3 speech challenge
 | 
			
		||||
            case ESM4::SUB_KNAM: // FO3 formid
 | 
			
		||||
            case ESM4::SUB_LNAM: // FONV
 | 
			
		||||
            case ESM4::SUB_TCFU: // FONV
 | 
			
		||||
            case ESM4::SUB_TIFC: // TES5
 | 
			
		||||
            case ESM4::SUB_TWAT: // TES5
 | 
			
		||||
            case ESM4::SUB_CIS2: // TES5
 | 
			
		||||
            case ESM4::SUB_CNAM: // TES5
 | 
			
		||||
            case ESM4::SUB_ENAM: // TES5
 | 
			
		||||
            case ESM4::SUB_EDID: // TES5
 | 
			
		||||
            case ESM4::SUB_VMAD: // TES5
 | 
			
		||||
            case ESM4::SUB_BNAM: // TES5
 | 
			
		||||
            case ESM4::SUB_SNAM: // TES5
 | 
			
		||||
            case ESM4::SUB_ONAM: // TES5
 | 
			
		||||
            case ESM4::SUB_QNAM: // TES5 for mScript
 | 
			
		||||
            case ESM4::SUB_RNAM: // TES5
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "INFO " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                        //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                std::cout << "INFO " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                        << subHdr.dataSize << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                //throw std::runtime_error("ESM4::INFO::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::DialogInfo::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::DialogInfo::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										90
									
								
								components/esm4/loadinfo.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								components/esm4/loadinfo.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,90 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_INFO_H
 | 
			
		||||
#define ESM4_INFO_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
#include "script.hpp" // TargetCondition
 | 
			
		||||
#include "dialogue.hpp" // DialType
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    enum InfoFlag
 | 
			
		||||
    {
 | 
			
		||||
        INFO_Goodbye         = 0x0001,
 | 
			
		||||
        INFO_Random          = 0x0002,
 | 
			
		||||
        INFO_SayOnce         = 0x0004,
 | 
			
		||||
        INFO_RunImmediately  = 0x0008,
 | 
			
		||||
        INFO_InfoRefusal     = 0x0010,
 | 
			
		||||
        INFO_RandomEnd       = 0x0020,
 | 
			
		||||
        INFO_RunForRumors    = 0x0040,
 | 
			
		||||
        INFO_SpeechChallenge = 0x0080,
 | 
			
		||||
        INFO_SayOnceADay     = 0x0100,
 | 
			
		||||
        INFO_AlwaysDarken    = 0x0200
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct DialogInfo
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId; // FIXME: no such record for INFO, but keep here to avoid extra work for now
 | 
			
		||||
 | 
			
		||||
        FormId mQuest;
 | 
			
		||||
        FormId mSound; // unused?
 | 
			
		||||
 | 
			
		||||
        TargetResponseData mResponseData;
 | 
			
		||||
        std::string mResponse;
 | 
			
		||||
        std::string mNotes;
 | 
			
		||||
        std::string mEdits;
 | 
			
		||||
 | 
			
		||||
        std::uint8_t  mDialType;  // DialType
 | 
			
		||||
        std::uint8_t  mNextSpeaker;
 | 
			
		||||
        std::uint16_t mInfoFlags; // see above enum
 | 
			
		||||
 | 
			
		||||
        TargetCondition mTargetCondition;
 | 
			
		||||
        FormId mParam3; // TES5 only
 | 
			
		||||
 | 
			
		||||
        ScriptDefinition mScript; // FIXME: ignoring the second one after the NEXT sub-record
 | 
			
		||||
 | 
			
		||||
        DialogInfo();
 | 
			
		||||
        virtual ~DialogInfo();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_INFO_H
 | 
			
		||||
							
								
								
									
										133
									
								
								components/esm4/loadingr.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								components/esm4/loadingr.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,133 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadingr.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Ingredient::Ingredient() : mFormId(0), mFlags(0), mBoundRadius(0.f), mScriptId(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
    mIcon.clear();
 | 
			
		||||
 | 
			
		||||
    mData.value = 0;
 | 
			
		||||
    mData.weight = 0.f;
 | 
			
		||||
    mEnchantment.value = 0;
 | 
			
		||||
    mEnchantment.flags = 0;
 | 
			
		||||
 | 
			
		||||
    std::memset(&mEffect, 0, sizeof(ScriptEffect));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Ingredient::~Ingredient()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Ingredient::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL:
 | 
			
		||||
            {
 | 
			
		||||
                if (mFullName.empty())
 | 
			
		||||
                {
 | 
			
		||||
                    reader.getLocalizedString(mFullName); break;
 | 
			
		||||
                }
 | 
			
		||||
                else // in TES4 subsequent FULL records are script effect names
 | 
			
		||||
                {
 | 
			
		||||
                    // FIXME: should be part of a struct?
 | 
			
		||||
                    std::string scriptEffectName;
 | 
			
		||||
                    if (!reader.getZString(scriptEffectName))
 | 
			
		||||
                        throw std::runtime_error ("INGR FULL data read error");
 | 
			
		||||
 | 
			
		||||
                    mScriptEffect.push_back(scriptEffectName);
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                //if (reader.esmVersion() == ESM::VER_094 || reader.esmVersion() == ESM::VER_170)
 | 
			
		||||
                if (subHdr.dataSize == 8) // FO3 is size 4 even though VER_094
 | 
			
		||||
                    reader.get(mData);
 | 
			
		||||
                else
 | 
			
		||||
                    reader.get(mData.weight);
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIcon);  break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId); break;
 | 
			
		||||
            case ESM4::SUB_ENIT: reader.get(mEnchantment);  break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_SCIT:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mEffect);
 | 
			
		||||
                reader.adjustFormId(mEffect.formId);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_MODS: // Dragonborn only?
 | 
			
		||||
            case ESM4::SUB_EFID:
 | 
			
		||||
            case ESM4::SUB_EFIT:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_KSIZ:
 | 
			
		||||
            case ESM4::SUB_KWDA:
 | 
			
		||||
            case ESM4::SUB_VMAD:
 | 
			
		||||
            case ESM4::SUB_YNAM:
 | 
			
		||||
            case ESM4::SUB_ZNAM:
 | 
			
		||||
            case ESM4::SUB_ETYP: // FO3
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "INGR " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::INGR::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Ingredient::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Ingredient::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										83
									
								
								components/esm4/loadingr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								components/esm4/loadingr.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,83 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_INGR_H
 | 
			
		||||
#define ESM4_INGR_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "effect.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Ingredient
 | 
			
		||||
    {
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint32_t value;
 | 
			
		||||
            float         weight;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct ENIT
 | 
			
		||||
        {
 | 
			
		||||
            std::uint32_t value;
 | 
			
		||||
            std::uint32_t flags;
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
        std::string mIcon; // inventory
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        std::vector<std::string> mScriptEffect; // FIXME: prob. should be in a struct
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
        ScriptEffect mEffect;
 | 
			
		||||
        ENIT   mEnchantment;
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Ingredient();
 | 
			
		||||
        virtual ~Ingredient();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_INGR_H
 | 
			
		||||
							
								
								
									
										93
									
								
								components/esm4/loadkeym.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								components/esm4/loadkeym.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,93 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadkeym.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Key::Key() : mFormId(0), mFlags(0), mPickUpSound(0), mDropSound(0), mBoundRadius(0.f), mScriptId(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
    mIcon.clear();
 | 
			
		||||
    mMiniIcon.clear();
 | 
			
		||||
 | 
			
		||||
    mData.value = 0;
 | 
			
		||||
    mData.weight = 0.f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Key::~Key()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Key::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIcon);  break;
 | 
			
		||||
            case ESM4::SUB_MICO: reader.getZString(mMiniIcon); break; // FO3
 | 
			
		||||
            case ESM4::SUB_DATA: reader.get(mData);         break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId); break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_YNAM: reader.getFormId(mPickUpSound); break;
 | 
			
		||||
            case ESM4::SUB_ZNAM: reader.getFormId(mDropSound); break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_KSIZ:
 | 
			
		||||
            case ESM4::SUB_KWDA:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_VMAD:
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "KEYM " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::KEYM::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Key::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Key::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										77
									
								
								components/esm4/loadkeym.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								components/esm4/loadkeym.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,77 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_KEYM_H
 | 
			
		||||
#define ESM4_KEYM_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Key
 | 
			
		||||
    {
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint32_t value; // gold
 | 
			
		||||
            float         weight;
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
        std::string mIcon; // inventory
 | 
			
		||||
        std::string mMiniIcon; // inventory
 | 
			
		||||
 | 
			
		||||
        FormId mPickUpSound;
 | 
			
		||||
        FormId mDropSound;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Key();
 | 
			
		||||
        virtual ~Key();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_KEYM_H
 | 
			
		||||
							
								
								
									
										255
									
								
								components/esm4/loadland.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								components/esm4/loadland.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,255 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2015-2016, 2018, 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadland.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef NDEBUG // FIXME: debuggigng only
 | 
			
		||||
#undef NDEBUG
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include <iostream> // FIXME: debug only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Land::Land() : mFormId(0), mFlags(0), mLandFlags(0), mDataTypes(0)
 | 
			
		||||
{
 | 
			
		||||
    for (int i = 0; i < 4; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        mTextures[i].base.formId = 0;
 | 
			
		||||
        mTextures[i].base.quadrant = 0;
 | 
			
		||||
        mTextures[i].base.unknown1 = 0;
 | 
			
		||||
        mTextures[i].base.unknown2 = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Land::~Land()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//             overlap north
 | 
			
		||||
//
 | 
			
		||||
//         32
 | 
			
		||||
//         31
 | 
			
		||||
//         30
 | 
			
		||||
// overlap  .
 | 
			
		||||
//  west    .
 | 
			
		||||
//          .
 | 
			
		||||
//          2
 | 
			
		||||
//          1
 | 
			
		||||
//          0
 | 
			
		||||
//           0 1 2 ... 30 31 32
 | 
			
		||||
//
 | 
			
		||||
//             overlap south
 | 
			
		||||
//
 | 
			
		||||
void ESM4::Land::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    TxtLayer layer;
 | 
			
		||||
    std::int8_t currentAddQuad = -1; // for VTXT following ATXT
 | 
			
		||||
 | 
			
		||||
    //std::map<FormId, int> uniqueTextures; // FIXME: for temp testing only
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mLandFlags);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_VNML: // vertex normals, 33x33x(1+1+1) = 3267
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mVertNorm);
 | 
			
		||||
                mDataTypes |= LAND_VNML;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_VHGT: // vertex height gradient, 4+33x33+3 = 4+1089+3 = 1096
 | 
			
		||||
            {
 | 
			
		||||
#if 0
 | 
			
		||||
                reader.get(mHeightMap.heightOffset);
 | 
			
		||||
                reader.get(mHeightMap.gradientData);
 | 
			
		||||
                reader.get(mHeightMap.unknown1);
 | 
			
		||||
                reader.get(mHeightMap.unknown2);
 | 
			
		||||
#endif
 | 
			
		||||
                reader.get(mHeightMap);
 | 
			
		||||
                mDataTypes |= LAND_VHGT;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_VCLR: // vertex colours, 24bit RGB, 33x33x(1+1+1) = 3267
 | 
			
		||||
            {
 | 
			
		||||
                reader.get(mVertColr);
 | 
			
		||||
                mDataTypes |= LAND_VCLR;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUA_BTXT:
 | 
			
		||||
            {
 | 
			
		||||
                BTXT base;
 | 
			
		||||
                if (reader.getExact(base))
 | 
			
		||||
                {
 | 
			
		||||
                    assert(base.quadrant < 4 && base.quadrant >= 0 && "base texture quadrant index error");
 | 
			
		||||
 | 
			
		||||
                    reader.adjustFormId(base.formId);
 | 
			
		||||
                    mTextures[base.quadrant].base = std::move(base);
 | 
			
		||||
#if 0
 | 
			
		||||
                    std::cout << "Base Texture formid: 0x"
 | 
			
		||||
                        << std::hex << mTextures[base.quadrant].base.formId
 | 
			
		||||
                        << ", quad " << std::dec << (int)base.quadrant << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_ATXT:
 | 
			
		||||
            {
 | 
			
		||||
                if (currentAddQuad != -1)
 | 
			
		||||
                {
 | 
			
		||||
                    // FIXME: sometimes there are no VTXT following an ATXT?  Just add a dummy one for now
 | 
			
		||||
                    std::cout << "ESM4::Land VTXT empty layer " << (int)layer.texture.layerIndex << std::endl;
 | 
			
		||||
                    mTextures[currentAddQuad].layers.push_back(layer);
 | 
			
		||||
                }
 | 
			
		||||
                reader.get(layer.texture);
 | 
			
		||||
                reader.adjustFormId(layer.texture.formId);
 | 
			
		||||
                assert(layer.texture.quadrant < 4 && layer.texture.quadrant >= 0
 | 
			
		||||
                       && "additional texture quadrant index error");
 | 
			
		||||
#if 0
 | 
			
		||||
                FormId txt = layer.texture.formId;
 | 
			
		||||
                std::map<FormId, int>::iterator lb = uniqueTextures.lower_bound(txt);
 | 
			
		||||
                if (lb != uniqueTextures.end() && !(uniqueTextures.key_comp()(txt, lb->first)))
 | 
			
		||||
                {
 | 
			
		||||
                    lb->second += 1;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    uniqueTextures.insert(lb, std::make_pair(txt, 1));
 | 
			
		||||
#endif
 | 
			
		||||
#if 0
 | 
			
		||||
                std::cout << "Additional Texture formId: 0x"
 | 
			
		||||
                    << std::hex << layer.texture.formId
 | 
			
		||||
                    << ", quad " << std::dec << (int)layer.texture.quadrant << std::endl;
 | 
			
		||||
                std::cout << "Additional Texture layer: "
 | 
			
		||||
                    << std::dec << (int)layer.texture.layerIndex << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
                currentAddQuad = layer.texture.quadrant;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_VTXT:
 | 
			
		||||
            {
 | 
			
		||||
                assert(currentAddQuad != -1 && "VTXT without ATXT found");
 | 
			
		||||
 | 
			
		||||
                int count = (int)reader.subRecordHeader().dataSize / sizeof(ESM4::Land::VTXT);
 | 
			
		||||
                assert((reader.subRecordHeader().dataSize % sizeof(ESM4::Land::VTXT)) == 0
 | 
			
		||||
                        && "ESM4::LAND VTXT data size error");
 | 
			
		||||
 | 
			
		||||
                if (count)
 | 
			
		||||
                {
 | 
			
		||||
                    layer.data.resize(count);
 | 
			
		||||
                    std::vector<ESM4::Land::VTXT>::iterator it = layer.data.begin();
 | 
			
		||||
                    for (;it != layer.data.end(); ++it)
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.get(*it);
 | 
			
		||||
                        // FIXME: debug only
 | 
			
		||||
                        //std::cout << "pos: " << std::dec << (int)(*it).position << std::endl;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                mTextures[currentAddQuad].layers.push_back(layer);
 | 
			
		||||
 | 
			
		||||
                // Assumed that the layers are added in the correct sequence
 | 
			
		||||
                // FIXME: Knights.esp doesn't seem to observe this - investigate more
 | 
			
		||||
                //assert(layer.texture.layerIndex == mTextures[currentAddQuad].layers.size()-1
 | 
			
		||||
                        //&& "additional texture layer index error");
 | 
			
		||||
 | 
			
		||||
                currentAddQuad = -1;
 | 
			
		||||
                layer.data.clear();
 | 
			
		||||
                // FIXME: debug only
 | 
			
		||||
                //std::cout << "VTXT: count " << std::dec << count << std::endl;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_VTEX: // only in Oblivion?
 | 
			
		||||
            {
 | 
			
		||||
                int count = (int)reader.subRecordHeader().dataSize / sizeof(FormId);
 | 
			
		||||
                assert((reader.subRecordHeader().dataSize % sizeof(FormId)) == 0
 | 
			
		||||
                        && "ESM4::LAND VTEX data size error");
 | 
			
		||||
 | 
			
		||||
                if (count)
 | 
			
		||||
                {
 | 
			
		||||
                    mIds.resize(count);
 | 
			
		||||
                    for (std::vector<FormId>::iterator it = mIds.begin(); it != mIds.end(); ++it)
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.getFormId(*it);
 | 
			
		||||
                        // FIXME: debug only
 | 
			
		||||
                        //std::cout << "VTEX: " << std::hex << *it << std::endl;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::LAND::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (currentAddQuad != -1)
 | 
			
		||||
    {
 | 
			
		||||
        // FIXME: not sure if it happens here as well
 | 
			
		||||
        std::cout << "ESM4::Land VTXT empty layer " << (int)layer.texture.layerIndex << " quad " << (int)layer.texture.quadrant << std::endl;
 | 
			
		||||
        mTextures[currentAddQuad].layers.push_back(layer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool missing = false;
 | 
			
		||||
    for (int i = 0; i < 4; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        if (mTextures[i].base.formId == 0)
 | 
			
		||||
        {
 | 
			
		||||
            //std::cout << "ESM4::LAND " << ESM4::formIdToString(mFormId) << " missing base, quad " << i << std::endl;
 | 
			
		||||
            //std::cout << "layers " << mTextures[i].layers.size() << std::endl;
 | 
			
		||||
            // NOTE: can't set the default here since FO3/FONV may have different defaults
 | 
			
		||||
            //mTextures[i].base.formId = 0x000008C0; // TerrainHDDirt01.dds
 | 
			
		||||
            missing = true;
 | 
			
		||||
        }
 | 
			
		||||
        //else
 | 
			
		||||
        //{
 | 
			
		||||
        //    std::cout << "ESM4::LAND " << ESM4::formIdToString(mFormId) << " base, quad " << i << std::endl;
 | 
			
		||||
        //    std::cout << "layers " << mTextures[i].layers.size() << std::endl;
 | 
			
		||||
        //}
 | 
			
		||||
    }
 | 
			
		||||
    // at least one of the quadrants do not have a base texture, return without setting the flag
 | 
			
		||||
    if (!missing)
 | 
			
		||||
        mDataTypes |= LAND_VTEX;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Land::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Land::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										136
									
								
								components/esm4/loadland.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								components/esm4/loadland.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,136 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2015-2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_LAND_H
 | 
			
		||||
#define ESM4_LAND_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
 | 
			
		||||
    struct Land
 | 
			
		||||
    {
 | 
			
		||||
        enum
 | 
			
		||||
        {
 | 
			
		||||
            LAND_VNML = 1,
 | 
			
		||||
            LAND_VHGT = 2,
 | 
			
		||||
            LAND_WNAM = 4, // only in TES3?
 | 
			
		||||
            LAND_VCLR = 8,
 | 
			
		||||
            LAND_VTEX = 16
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // number of vertices per side
 | 
			
		||||
        static const int VERTS_PER_SIDE = 33;
 | 
			
		||||
 | 
			
		||||
        // cell terrain size in world coords
 | 
			
		||||
        static const int REAL_SIZE = 4096;
 | 
			
		||||
 | 
			
		||||
        // total number of vertices
 | 
			
		||||
        static const int LAND_NUM_VERTS = VERTS_PER_SIDE * VERTS_PER_SIDE;
 | 
			
		||||
 | 
			
		||||
        static const int HEIGHT_SCALE = 8;
 | 
			
		||||
 | 
			
		||||
        // number of textures per side of a land quadrant
 | 
			
		||||
        // (for TES4 - based on vanilla observations)
 | 
			
		||||
        static const int QUAD_TEXTURE_PER_SIDE = 6;
 | 
			
		||||
 | 
			
		||||
#pragma pack(push,1)
 | 
			
		||||
        struct VHGT
 | 
			
		||||
        {
 | 
			
		||||
            float         heightOffset;
 | 
			
		||||
            std::int8_t   gradientData[VERTS_PER_SIDE * VERTS_PER_SIDE];
 | 
			
		||||
            std::uint16_t unknown1;
 | 
			
		||||
            unsigned char unknown2;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct BTXT
 | 
			
		||||
        {
 | 
			
		||||
            FormId        formId;
 | 
			
		||||
            std::uint8_t  quadrant; // 0 = bottom left, 1 = bottom right, 2 = top left, 3 = top right
 | 
			
		||||
            std::uint8_t  unknown1;
 | 
			
		||||
            std::uint16_t unknown2;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct ATXT
 | 
			
		||||
        {
 | 
			
		||||
            FormId        formId;
 | 
			
		||||
            std::uint8_t  quadrant; // 0 = bottom left, 1 = bottom right, 2 = top left, 3 = top right
 | 
			
		||||
            std::uint8_t  unknown;
 | 
			
		||||
            std::uint16_t layerIndex; // texture layer, 0..7
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct VTXT
 | 
			
		||||
        {
 | 
			
		||||
            std::uint16_t position; // 0..288 (17x17 grid)
 | 
			
		||||
            std::uint8_t  unknown1;
 | 
			
		||||
            std::uint8_t  unknown2;
 | 
			
		||||
            float         opacity;
 | 
			
		||||
        };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
        struct TxtLayer
 | 
			
		||||
        {
 | 
			
		||||
            ATXT          texture;
 | 
			
		||||
            std::vector<VTXT> data; // alpha data
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        struct Texture
 | 
			
		||||
        {
 | 
			
		||||
            BTXT          base;
 | 
			
		||||
            std::vector<TxtLayer> layers;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::uint32_t mLandFlags; // from DATA subrecord
 | 
			
		||||
 | 
			
		||||
        // FIXME: lazy loading not yet implemented
 | 
			
		||||
        int mDataTypes; // which data types are loaded
 | 
			
		||||
 | 
			
		||||
        signed char   mVertNorm[VERTS_PER_SIDE * VERTS_PER_SIDE * 3]; // from VNML subrecord
 | 
			
		||||
        signed char   mVertColr[VERTS_PER_SIDE * VERTS_PER_SIDE * 3]; // from VCLR subrecord
 | 
			
		||||
        VHGT          mHeightMap;
 | 
			
		||||
        Texture       mTextures[4]; // 0 = bottom left, 1 = bottom right, 2 = top left, 3 = top right
 | 
			
		||||
        std::vector<FormId> mIds;   // land texture (LTEX) formids
 | 
			
		||||
 | 
			
		||||
        Land();
 | 
			
		||||
        virtual ~Land();
 | 
			
		||||
 | 
			
		||||
        virtual void load(Reader& reader);
 | 
			
		||||
        //virtual void save(Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_LAND_H
 | 
			
		||||
							
								
								
									
										105
									
								
								components/esm4/loadlgtm.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								components/esm4/loadlgtm.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,105 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
  Also see https://tes5edit.github.io/fopdoc/ for FO3/FONV specific details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadlgtm.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <cfloat> // FLT_MAX for gcc
 | 
			
		||||
//#include <iostream> // FIXME: for debugging only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::LightingTemplate::LightingTemplate() : mFormId(0), mFlags(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
 | 
			
		||||
    mLighting.ambient = 0;
 | 
			
		||||
    mLighting.directional = 0;
 | 
			
		||||
    mLighting.fogColor = 0;
 | 
			
		||||
    mLighting.fogNear = 0.f;
 | 
			
		||||
    mLighting.fogFar = 0.f;
 | 
			
		||||
    mLighting.rotationXY = 0;
 | 
			
		||||
    mLighting.rotationZ = 0;
 | 
			
		||||
    mLighting.fogDirFade = 0.f;
 | 
			
		||||
    mLighting.fogClipDist = 0.f;
 | 
			
		||||
    mLighting.fogPower = FLT_MAX; // hack way to detect TES4
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::LightingTemplate::~LightingTemplate()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::LightingTemplate::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId);  break;
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                if (subHdr.dataSize == 36) // TES4
 | 
			
		||||
                    reader.get(&mLighting, 36);
 | 
			
		||||
                if (subHdr.dataSize == 40) // FO3/FONV
 | 
			
		||||
                    reader.get(mLighting);
 | 
			
		||||
                else if (subHdr.dataSize == 92) // TES5
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mLighting);
 | 
			
		||||
                    reader.skipSubRecordData(52); // FIXME
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    reader.skipSubRecordData(); // throw?
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_DALC: // TES5
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "LGTM " << ESM::printName(subHdr.typeId) << " skipping..."
 | 
			
		||||
                          //<< subHdr.dataSize << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::LGTM::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::LightingTemplate::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::LightingTemplate::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										63
									
								
								components/esm4/loadlgtm.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								components/esm4/loadlgtm.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,63 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
  Also see https://tes5edit.github.io/fopdoc/ for FO3/FONV specific details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_LGTM_H
 | 
			
		||||
#define ESM4_LGTM_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
#include "lighting.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
    typedef std::uint32_t FormId;
 | 
			
		||||
 | 
			
		||||
    struct LightingTemplate
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
 | 
			
		||||
        Lighting mLighting;
 | 
			
		||||
 | 
			
		||||
        LightingTemplate();
 | 
			
		||||
        virtual ~LightingTemplate();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_LGTM_H
 | 
			
		||||
							
								
								
									
										120
									
								
								components/esm4/loadligh.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								components/esm4/loadligh.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,120 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadligh.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::Light::Light() : mFormId(0), mFlags(0), mBoundRadius(0.f), mScriptId(0), mSound(0),
 | 
			
		||||
                       mFade(0.f)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mFullName.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
    mIcon.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::Light::~Light()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::Light::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
    std::uint32_t esmVer = reader.esmVersion();
 | 
			
		||||
    bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_FULL: reader.getLocalizedString(mFullName); break;
 | 
			
		||||
            case ESM4::SUB_DATA:
 | 
			
		||||
            {
 | 
			
		||||
                // FIXME: TES4 might be uint32 as well, need to check
 | 
			
		||||
                if (isFONV || (esmVer == ESM::VER_094 && subHdr.dataSize == 32)/*FO3*/)
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData.time);     // uint32
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    reader.get(mData.duration); // float
 | 
			
		||||
 | 
			
		||||
                reader.get(mData.radius);
 | 
			
		||||
                reader.get(mData.colour);
 | 
			
		||||
                reader.get(mData.flags);
 | 
			
		||||
                //if (reader.esmVersion() == ESM::VER_094 || reader.esmVersion() == ESM::VER_170)
 | 
			
		||||
                if (subHdr.dataSize == 48)
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData.falloff);
 | 
			
		||||
                    reader.get(mData.FOV);
 | 
			
		||||
                    reader.get(mData.nearClip);
 | 
			
		||||
                    reader.get(mData.frequency);
 | 
			
		||||
                    reader.get(mData.intensityAmplitude);
 | 
			
		||||
                    reader.get(mData.movementAmplitude);
 | 
			
		||||
                }
 | 
			
		||||
                else if (subHdr.dataSize == 32) // TES4
 | 
			
		||||
                {
 | 
			
		||||
                    reader.get(mData.falloff);
 | 
			
		||||
                    reader.get(mData.FOV);
 | 
			
		||||
                }
 | 
			
		||||
                reader.get(mData.value);
 | 
			
		||||
                reader.get(mData.weight);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel); break;
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mIcon);  break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId); break;
 | 
			
		||||
            case ESM4::SUB_SNAM: reader.getFormId(mSound);  break;
 | 
			
		||||
            case ESM4::SUB_MODB: reader.get(mBoundRadius);  break;
 | 
			
		||||
            case ESM4::SUB_FNAM: reader.get(mFade);         break;
 | 
			
		||||
            case ESM4::SUB_MODT:
 | 
			
		||||
            case ESM4::SUB_OBND:
 | 
			
		||||
            case ESM4::SUB_VMAD: // Dragonborn only?
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "LIGH " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::LIGH::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Light::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::Light::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										101
									
								
								components/esm4/loadligh.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								components/esm4/loadligh.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,101 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018-2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_LIGH_H
 | 
			
		||||
#define ESM4_LIGH_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct Light
 | 
			
		||||
    {
 | 
			
		||||
        struct Data
 | 
			
		||||
        {
 | 
			
		||||
            std::uint32_t time;               // FO/FONV only
 | 
			
		||||
            float         duration;
 | 
			
		||||
            std::uint32_t radius;
 | 
			
		||||
            std::uint32_t colour; // RGBA
 | 
			
		||||
            // flags:
 | 
			
		||||
            // 0x00000001 = Dynamic
 | 
			
		||||
            // 0x00000002 = Can be Carried
 | 
			
		||||
            // 0x00000004 = Negative
 | 
			
		||||
            // 0x00000008 = Flicker
 | 
			
		||||
            // 0x00000020 = Off By Default
 | 
			
		||||
            // 0x00000040 = Flicker Slow
 | 
			
		||||
            // 0x00000080 = Pulse
 | 
			
		||||
            // 0x00000100 = Pulse Slow
 | 
			
		||||
            // 0x00000200 = Spot Light
 | 
			
		||||
            // 0x00000400 = Spot Shadow
 | 
			
		||||
            std::int32_t  flags;
 | 
			
		||||
            float         falloff;
 | 
			
		||||
            float         FOV;
 | 
			
		||||
            float         nearClip;           // TES5 only
 | 
			
		||||
            float         frequency;          // TES5 only
 | 
			
		||||
            float         intensityAmplitude; // TES5 only
 | 
			
		||||
            float         movementAmplitude;  // TES5 only
 | 
			
		||||
            std::uint32_t value;   // gold
 | 
			
		||||
            float         weight;
 | 
			
		||||
            Data() : duration(-1), radius(0), colour(0), flags(0), falloff(1.f), FOV(90),
 | 
			
		||||
                     nearClip(0.f), frequency(0.f), intensityAmplitude(0.f), movementAmplitude(0.f),
 | 
			
		||||
                     value(0), weight(0.f) // FIXME: FOV in degrees or radians?
 | 
			
		||||
            {}
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
        std::string mFullName;
 | 
			
		||||
        std::string mModel;
 | 
			
		||||
        std::string mIcon;
 | 
			
		||||
 | 
			
		||||
        float mBoundRadius;
 | 
			
		||||
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
        FormId mSound;
 | 
			
		||||
 | 
			
		||||
        float mFade;
 | 
			
		||||
 | 
			
		||||
        Data mData;
 | 
			
		||||
 | 
			
		||||
        Light();
 | 
			
		||||
        virtual ~Light();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_LIGH_H
 | 
			
		||||
							
								
								
									
										107
									
								
								components/esm4/loadltex.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								components/esm4/loadltex.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,107 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2015-2016, 2018 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadltex.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef NDEBUG // FIXME: debuggigng only
 | 
			
		||||
#undef NDEBUG
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME: debugging only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::LandTexture::LandTexture() : mFormId(0), mFlags(0), mHavokFriction(0), mHavokRestitution(0),
 | 
			
		||||
                                   mTextureSpecular(0), mGrass(0), mHavokMaterial(0), mTexture(0),
 | 
			
		||||
                                   mMaterial(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mTextureFile.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::LandTexture::~LandTexture()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::LandTexture::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
    std::uint32_t esmVer = reader.esmVersion();
 | 
			
		||||
    bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_HNAM:
 | 
			
		||||
            {
 | 
			
		||||
                if (isFONV)
 | 
			
		||||
                {
 | 
			
		||||
                    reader.skipSubRecordData(); // FIXME: skip FONV for now
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if ((reader.esmVersion() == ESM::VER_094 || reader.esmVersion() == ESM::VER_170)
 | 
			
		||||
                    && subHdr.dataSize == 2) // FO3 is VER_094 but dataSize 3
 | 
			
		||||
                {
 | 
			
		||||
                    //assert(subHdr.dataSize == 2 && "LTEX unexpected HNAM size");
 | 
			
		||||
                    reader.get(mHavokFriction);
 | 
			
		||||
                    reader.get(mHavokRestitution);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    assert(subHdr.dataSize == 3 && "LTEX unexpected HNAM size");
 | 
			
		||||
                    reader.get(mHavokMaterial);
 | 
			
		||||
                    reader.get(mHavokFriction);
 | 
			
		||||
                    reader.get(mHavokRestitution);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_ICON: reader.getZString(mTextureFile); break; // Oblivion only?
 | 
			
		||||
            case ESM4::SUB_SNAM: reader.get(mTextureSpecular); break;
 | 
			
		||||
            case ESM4::SUB_GNAM: reader.getFormId(mGrass);     break;
 | 
			
		||||
            case ESM4::SUB_TNAM: reader.getFormId(mTexture);   break; // TES5 only
 | 
			
		||||
            case ESM4::SUB_MNAM: reader.getFormId(mMaterial);  break; // TES5 only
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::LTEX::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::LandTexture::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::LandTexture::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										75
									
								
								components/esm4/loadltex.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								components/esm4/loadltex.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2015-2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_LTEX_H
 | 
			
		||||
#define ESM4_LTEX_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct LandTexture
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
 | 
			
		||||
        std::uint8_t mHavokFriction;
 | 
			
		||||
        std::uint8_t mHavokRestitution;
 | 
			
		||||
 | 
			
		||||
        std::uint8_t mTextureSpecular; // default 30
 | 
			
		||||
        FormId mGrass;
 | 
			
		||||
 | 
			
		||||
        // ------ TES4 only -----
 | 
			
		||||
 | 
			
		||||
        std::string mTextureFile;
 | 
			
		||||
        std::uint8_t mHavokMaterial;
 | 
			
		||||
 | 
			
		||||
        // ------ TES5 only -----
 | 
			
		||||
 | 
			
		||||
        FormId mTexture;
 | 
			
		||||
        FormId mMaterial;
 | 
			
		||||
 | 
			
		||||
        // ----------------------
 | 
			
		||||
 | 
			
		||||
        LandTexture();
 | 
			
		||||
        virtual ~LandTexture();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_LTEX_H
 | 
			
		||||
							
								
								
									
										130
									
								
								components/esm4/loadlvlc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								components/esm4/loadlvlc.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,130 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadlvlc.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::LevelledCreature::LevelledCreature() : mFormId(0), mFlags(0), mScriptId(0), mTemplate(0),
 | 
			
		||||
                                           mChanceNone(0), mLvlCreaFlags(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::LevelledCreature::~LevelledCreature()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::LevelledCreature::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_SCRI: reader.getFormId(mScriptId);    break;
 | 
			
		||||
            case ESM4::SUB_TNAM: reader.getFormId(mTemplate);  break;
 | 
			
		||||
            case ESM4::SUB_LVLD: reader.get(mChanceNone);      break;
 | 
			
		||||
            case ESM4::SUB_LVLF: reader.get(mLvlCreaFlags);    break;
 | 
			
		||||
            case ESM4::SUB_LVLO:
 | 
			
		||||
            {
 | 
			
		||||
                static LVLO lvlo;
 | 
			
		||||
                if (subHdr.dataSize != 12)
 | 
			
		||||
                {
 | 
			
		||||
                    if (subHdr.dataSize == 8)
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.get(lvlo.level);
 | 
			
		||||
                        reader.get(lvlo.item);
 | 
			
		||||
                        reader.get(lvlo.count);
 | 
			
		||||
                        //std::cout << "LVLC " << mEditorId << " LVLO lev " << lvlo.level << ", item " << lvlo.item
 | 
			
		||||
                                  //<< ", count " << lvlo.count << std::endl;
 | 
			
		||||
                        // FIXME: seems to happen only once, don't add to mLvlObject
 | 
			
		||||
                        // LVLC TesKvatchCreature LVLO lev 1, item 1393819648, count 2
 | 
			
		||||
                        // 0x0001, 0x5314 0000, 0x0002
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                        throw std::runtime_error("ESM4::LVLC::load - " + mEditorId + " LVLO size error");
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    reader.get(lvlo);
 | 
			
		||||
 | 
			
		||||
                reader.adjustFormId(lvlo.item);
 | 
			
		||||
                mLvlObject.push_back(lvlo);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_OBND: // FO3
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "LVLC " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::LVLC::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ESM4::LevelledCreature::calcAllLvlLessThanPlayer() const
 | 
			
		||||
{
 | 
			
		||||
    if (mHasLvlCreaFlags)
 | 
			
		||||
        return (mLvlCreaFlags & 0x01) != 0;
 | 
			
		||||
    else
 | 
			
		||||
        return (mChanceNone & 0x80) != 0; // FIXME: 0x80 is just a guess
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ESM4::LevelledCreature::calcEachItemInCount() const
 | 
			
		||||
{
 | 
			
		||||
    if (mHasLvlCreaFlags)
 | 
			
		||||
        return (mLvlCreaFlags & 0x02) != 0;
 | 
			
		||||
    else
 | 
			
		||||
        return true; // FIXME: just a guess
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::int8_t ESM4::LevelledCreature::chanceNone() const
 | 
			
		||||
{
 | 
			
		||||
    if (mHasLvlCreaFlags)
 | 
			
		||||
        return mChanceNone;
 | 
			
		||||
    else
 | 
			
		||||
        return (mChanceNone & 0x7f); // FIXME: 0x80 is just a guess
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::LevelledCreature::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::LevelledCreature::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										71
									
								
								components/esm4/loadlvlc.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								components/esm4/loadlvlc.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_LVLC_H
 | 
			
		||||
#define ESM4_LVLC_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
#include "inventory.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct LevelledCreature
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
 | 
			
		||||
        FormId mScriptId;
 | 
			
		||||
        FormId mTemplate;
 | 
			
		||||
        std::int8_t mChanceNone;
 | 
			
		||||
 | 
			
		||||
        bool mHasLvlCreaFlags;
 | 
			
		||||
        std::uint8_t mLvlCreaFlags;
 | 
			
		||||
 | 
			
		||||
        std::vector<LVLO> mLvlObject;
 | 
			
		||||
 | 
			
		||||
        bool calcAllLvlLessThanPlayer() const;
 | 
			
		||||
        bool calcEachItemInCount() const;
 | 
			
		||||
        std::int8_t chanceNone() const;
 | 
			
		||||
 | 
			
		||||
        LevelledCreature();
 | 
			
		||||
        virtual ~LevelledCreature();
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_LVLC_H
 | 
			
		||||
							
								
								
									
										142
									
								
								components/esm4/loadlvli.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								components/esm4/loadlvli.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,142 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018-2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadlvli.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <iostream> // FIXME: for debugging
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::LevelledItem::LevelledItem() : mFormId(0), mFlags(0), mChanceNone(0), mHasLvlItemFlags(false),
 | 
			
		||||
    mLvlItemFlags(0), mData(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::LevelledItem::~LevelledItem()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::LevelledItem::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_LVLD: reader.get(mChanceNone); break;
 | 
			
		||||
            case ESM4::SUB_LVLF: reader.get(mLvlItemFlags); mHasLvlItemFlags = true; break;
 | 
			
		||||
            case ESM4::SUB_DATA: reader.get(mData); break;
 | 
			
		||||
            case ESM4::SUB_LVLO:
 | 
			
		||||
            {
 | 
			
		||||
                static LVLO lvlo;
 | 
			
		||||
                if (subHdr.dataSize != 12)
 | 
			
		||||
                {
 | 
			
		||||
                    if (subHdr.dataSize == 8)
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.get(lvlo.level);
 | 
			
		||||
                        reader.get(lvlo.item);
 | 
			
		||||
                        reader.get(lvlo.count);
 | 
			
		||||
//                        std::cout << "LVLI " << mEditorId << " LVLO lev " << lvlo.level << ", item " << lvlo.item
 | 
			
		||||
//                                  << ", count " << lvlo.count << std::endl;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                        throw std::runtime_error("ESM4::LVLI::load - " + mEditorId + " LVLO size error");
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    reader.get(lvlo);
 | 
			
		||||
 | 
			
		||||
                reader.adjustFormId(lvlo.item);
 | 
			
		||||
                mLvlObject.push_back(lvlo);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_LLCT:
 | 
			
		||||
            case ESM4::SUB_OBND: // FO3/FONV
 | 
			
		||||
            case ESM4::SUB_COED: // FO3/FONV
 | 
			
		||||
            case ESM4::SUB_LVLG: // FO3/FONV
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                //std::cout << "LVLI " << ESM::printName(subHdr.typeId) << " skipping..." << subHdr.dataSize << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::LVLI::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // FIXME: testing
 | 
			
		||||
    //if (mHasLvlItemFlags && mChanceNone >= 90)
 | 
			
		||||
        //std::cout << "LVLI " << mEditorId << " chance none " << int(mChanceNone) << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ESM4::LevelledItem::calcAllLvlLessThanPlayer() const
 | 
			
		||||
{
 | 
			
		||||
    if (mHasLvlItemFlags)
 | 
			
		||||
        return (mLvlItemFlags & 0x01) != 0;
 | 
			
		||||
    else
 | 
			
		||||
        return (mChanceNone & 0x80) != 0; // FIXME: 0x80 is just a guess
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ESM4::LevelledItem::calcEachItemInCount() const
 | 
			
		||||
{
 | 
			
		||||
    if (mHasLvlItemFlags)
 | 
			
		||||
        return (mLvlItemFlags & 0x02) != 0;
 | 
			
		||||
    else
 | 
			
		||||
        return mData != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::int8_t ESM4::LevelledItem::chanceNone() const
 | 
			
		||||
{
 | 
			
		||||
    if (mHasLvlItemFlags)
 | 
			
		||||
        return mChanceNone;
 | 
			
		||||
    else
 | 
			
		||||
        return (mChanceNone & 0x7f); // FIXME: 0x80 is just a guess
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ESM4::LevelledItem::useAll() const
 | 
			
		||||
{
 | 
			
		||||
    if (mHasLvlItemFlags)
 | 
			
		||||
        return (mLvlItemFlags & 0x04) != 0;
 | 
			
		||||
    else
 | 
			
		||||
        return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::LevelledItem::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::LevelledItem::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										72
									
								
								components/esm4/loadlvli.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								components/esm4/loadlvli.hpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2016, 2018, 2020 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#ifndef ESM4_LVLI_H
 | 
			
		||||
#define ESM4_LVLI_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "formid.hpp"
 | 
			
		||||
#include "inventory.hpp" // LVLO
 | 
			
		||||
 | 
			
		||||
namespace ESM4
 | 
			
		||||
{
 | 
			
		||||
    class Reader;
 | 
			
		||||
    class Writer;
 | 
			
		||||
 | 
			
		||||
    struct LevelledItem
 | 
			
		||||
    {
 | 
			
		||||
        FormId mFormId;       // from the header
 | 
			
		||||
        std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
 | 
			
		||||
 | 
			
		||||
        std::string mEditorId;
 | 
			
		||||
 | 
			
		||||
        std::int8_t mChanceNone;
 | 
			
		||||
 | 
			
		||||
        bool mHasLvlItemFlags;
 | 
			
		||||
        std::uint8_t mLvlItemFlags;
 | 
			
		||||
 | 
			
		||||
        std::uint8_t mData;
 | 
			
		||||
 | 
			
		||||
        std::vector<LVLO> mLvlObject;
 | 
			
		||||
 | 
			
		||||
        LevelledItem();
 | 
			
		||||
        virtual ~LevelledItem();
 | 
			
		||||
 | 
			
		||||
        bool calcAllLvlLessThanPlayer() const;
 | 
			
		||||
        bool calcEachItemInCount() const;
 | 
			
		||||
        bool useAll() const;
 | 
			
		||||
        std::int8_t chanceNone() const;
 | 
			
		||||
 | 
			
		||||
        virtual void load(ESM4::Reader& reader);
 | 
			
		||||
        //virtual void save(ESM4::Writer& writer) const;
 | 
			
		||||
 | 
			
		||||
        //void blank();
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // ESM4_LVLI_H
 | 
			
		||||
							
								
								
									
										114
									
								
								components/esm4/loadlvln.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								components/esm4/loadlvln.cpp
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,114 @@
 | 
			
		|||
/*
 | 
			
		||||
  Copyright (C) 2019-2021 cc9cii
 | 
			
		||||
 | 
			
		||||
  This software is provided 'as-is', without any express or implied
 | 
			
		||||
  warranty.  In no event will the authors be held liable for any damages
 | 
			
		||||
  arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
  Permission is granted to anyone to use this software for any purpose,
 | 
			
		||||
  including commercial applications, and to alter it and redistribute it
 | 
			
		||||
  freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
  1. The origin of this software must not be misrepresented; you must not
 | 
			
		||||
     claim that you wrote the original software. If you use this software
 | 
			
		||||
     in a product, an acknowledgment in the product documentation would be
 | 
			
		||||
     appreciated but is not required.
 | 
			
		||||
  2. Altered source versions must be plainly marked as such, and must not be
 | 
			
		||||
     misrepresented as being the original software.
 | 
			
		||||
  3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
 | 
			
		||||
  cc9cii cc9c@iinet.net.au
 | 
			
		||||
 | 
			
		||||
  Much of the information on the data structures are based on the information
 | 
			
		||||
  from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
 | 
			
		||||
  trial & error.  See http://en.uesp.net/wiki for details.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
#include "loadlvln.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
//#include <iostream> // FIXME: testing only
 | 
			
		||||
 | 
			
		||||
#include "reader.hpp"
 | 
			
		||||
//#include "writer.hpp"
 | 
			
		||||
 | 
			
		||||
ESM4::LevelledNpc::LevelledNpc() : mFormId(0), mFlags(0), mChanceNone(0), mLvlActorFlags(0), mListCount(0)
 | 
			
		||||
{
 | 
			
		||||
    mEditorId.clear();
 | 
			
		||||
    mModel.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ESM4::LevelledNpc::~LevelledNpc()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ESM4::LevelledNpc::load(ESM4::Reader& reader)
 | 
			
		||||
{
 | 
			
		||||
    mFormId = reader.hdr().record.id;
 | 
			
		||||
    reader.adjustFormId(mFormId);
 | 
			
		||||
    mFlags  = reader.hdr().record.flags;
 | 
			
		||||
    //std::uint32_t esmVer = reader.esmVersion(); // currently unused
 | 
			
		||||
 | 
			
		||||
    while (reader.getSubRecordHeader())
 | 
			
		||||
    {
 | 
			
		||||
        const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
 | 
			
		||||
        switch (subHdr.typeId)
 | 
			
		||||
        {
 | 
			
		||||
            case ESM4::SUB_EDID: reader.getZString(mEditorId); break;
 | 
			
		||||
            case ESM4::SUB_MODL: reader.getZString(mModel);    break;
 | 
			
		||||
            case ESM4::SUB_LLCT: reader.get(mListCount);       break;
 | 
			
		||||
            case ESM4::SUB_LVLD: reader.get(mChanceNone);      break;
 | 
			
		||||
            case ESM4::SUB_LVLF: reader.get(mLvlActorFlags);   break;
 | 
			
		||||
            case ESM4::SUB_LVLO:
 | 
			
		||||
            {
 | 
			
		||||
                static LVLO lvlo;
 | 
			
		||||
                if (subHdr.dataSize != 12)
 | 
			
		||||
                {
 | 
			
		||||
                    if (subHdr.dataSize == 8)
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.get(lvlo.level);
 | 
			
		||||
                        reader.get(lvlo.item);
 | 
			
		||||
                        reader.get(lvlo.count);
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                        throw std::runtime_error("ESM4::LVLN::load - " + mEditorId + " LVLO size error");
 | 
			
		||||
                }
 | 
			
		||||
//              else if (esmVer == ESM::VER_094 || esmVer == ESM::VER_170 || isFONV)
 | 
			
		||||
//              {
 | 
			
		||||
//                  std::uint32_t level;
 | 
			
		||||
//                  reader.get(level);
 | 
			
		||||
//                  lvlo.level = static_cast<std::uint16_t>(level);
 | 
			
		||||
//                  reader.get(lvlo.item);
 | 
			
		||||
//                  std::uint32_t count;
 | 
			
		||||
//                  reader.get(count);
 | 
			
		||||
//                  lvlo.count = static_cast<std::uint16_t>(count);
 | 
			
		||||
//              }
 | 
			
		||||
                else
 | 
			
		||||
                    reader.get(lvlo);
 | 
			
		||||
 | 
			
		||||
                reader.adjustFormId(lvlo.item);
 | 
			
		||||
                mLvlObject.push_back(lvlo);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case ESM4::SUB_COED: // owner
 | 
			
		||||
            case ESM4::SUB_OBND: // object bounds
 | 
			
		||||
            case ESM4::SUB_MODT: // model texture data
 | 
			
		||||
            {
 | 
			
		||||
                //std::cout << "LVLN " << ESM::printName(subHdr.typeId) << " skipping..." << std::endl;
 | 
			
		||||
                reader.skipSubRecordData();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
                throw std::runtime_error("ESM4::LVLN::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//void ESM4::LevelledNpc::save(ESM4::Writer& writer) const
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//void ESM4::LevelledNpc::blank()
 | 
			
		||||
//{
 | 
			
		||||
//}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue