mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 03:56:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			177 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "importcellref.hpp"
 | 
						|
 | 
						|
#include <components/esm3/esmreader.hpp>
 | 
						|
 | 
						|
namespace ESSImport
 | 
						|
{
 | 
						|
 | 
						|
    void CellRef::load(ESM::ESMReader& esm)
 | 
						|
    {
 | 
						|
        blank();
 | 
						|
 | 
						|
        esm.getHNT(mRefNum.mIndex, "FRMR");
 | 
						|
 | 
						|
        // this is required since openmw supports more than 255 content files
 | 
						|
        int pluginIndex = (mRefNum.mIndex & 0xff000000) >> 24;
 | 
						|
        mRefNum.mContentFile = pluginIndex - 1;
 | 
						|
        mRefNum.mIndex &= 0x00ffffff;
 | 
						|
 | 
						|
        mIndexedRefId = esm.getHNString("NAME");
 | 
						|
 | 
						|
        if (esm.isNextSub("ACTN"))
 | 
						|
        {
 | 
						|
            /*
 | 
						|
            Activation flags:
 | 
						|
            ActivationFlag_UseEnabled  = 1
 | 
						|
            ActivationFlag_OnActivate  = 2
 | 
						|
            ActivationFlag_OnDeath  = 10h
 | 
						|
            ActivationFlag_OnKnockout  = 20h
 | 
						|
            ActivationFlag_OnMurder  = 40h
 | 
						|
            ActivationFlag_DoorOpening  = 100h
 | 
						|
            ActivationFlag_DoorClosing  = 200h
 | 
						|
            ActivationFlag_DoorJammedOpening  = 400h
 | 
						|
            ActivationFlag_DoorJammedClosing  = 800h
 | 
						|
            */
 | 
						|
            esm.skipHSub();
 | 
						|
        }
 | 
						|
 | 
						|
        if (esm.isNextSub("STPR"))
 | 
						|
            esm.skipHSub();
 | 
						|
 | 
						|
        if (esm.isNextSub("MNAM"))
 | 
						|
            esm.skipHSub();
 | 
						|
 | 
						|
        bool isDeleted = false;
 | 
						|
        ESM::CellRef::loadData(esm, isDeleted);
 | 
						|
 | 
						|
        mActorData.mHasACDT = false;
 | 
						|
        if (esm.isNextSub("ACDT"))
 | 
						|
        {
 | 
						|
            mActorData.mHasACDT = true;
 | 
						|
            esm.getHT(mActorData.mACDT);
 | 
						|
        }
 | 
						|
 | 
						|
        mActorData.mHasACSC = false;
 | 
						|
        if (esm.isNextSub("ACSC"))
 | 
						|
        {
 | 
						|
            mActorData.mHasACSC = true;
 | 
						|
            esm.getHT(mActorData.mACSC);
 | 
						|
        }
 | 
						|
 | 
						|
        if (esm.isNextSub("ACSL"))
 | 
						|
            esm.skipHSubSize(112);
 | 
						|
 | 
						|
        if (esm.isNextSub("CSTN"))
 | 
						|
            esm.skipHSub(); // "PlayerSaveGame", link to some object?
 | 
						|
 | 
						|
        if (esm.isNextSub("LSTN"))
 | 
						|
            esm.skipHSub(); // "PlayerSaveGame", link to some object?
 | 
						|
 | 
						|
        // unsure at which point between LSTN and TGTN
 | 
						|
        if (esm.isNextSub("CSHN"))
 | 
						|
            esm.skipHSub(); // "PlayerSaveGame", link to some object?
 | 
						|
 | 
						|
        // unsure if before or after CSTN/LSTN
 | 
						|
        if (esm.isNextSub("LSHN"))
 | 
						|
            esm.skipHSub(); // "PlayerSaveGame", link to some object?
 | 
						|
 | 
						|
        while (esm.isNextSub("TGTN"))
 | 
						|
            esm.skipHSub(); // "PlayerSaveGame", link to some object?
 | 
						|
 | 
						|
        while (esm.isNextSub("FGTN"))
 | 
						|
            esm.getHString(); // fight target?
 | 
						|
 | 
						|
        // unsure at which point between TGTN and CRED
 | 
						|
        if (esm.isNextSub("AADT"))
 | 
						|
        {
 | 
						|
            // occurred when a creature was in the middle of its attack, 44 bytes
 | 
						|
            esm.skipHSub();
 | 
						|
        }
 | 
						|
 | 
						|
        // unsure at which point between FGTN and CHRD
 | 
						|
        if (esm.isNextSub("PWPC"))
 | 
						|
            esm.skipHSub();
 | 
						|
        if (esm.isNextSub("PWPS"))
 | 
						|
            esm.skipHSub();
 | 
						|
 | 
						|
        if (esm.isNextSub("WNAM"))
 | 
						|
        {
 | 
						|
            std::string id = esm.getHString();
 | 
						|
 | 
						|
            if (esm.isNextSub("XNAM"))
 | 
						|
                mActorData.mSelectedEnchantItem = esm.getHString();
 | 
						|
            else
 | 
						|
                mActorData.mSelectedSpell = id;
 | 
						|
 | 
						|
            if (esm.isNextSub("YNAM"))
 | 
						|
                esm.skipHSub(); // 4 byte, 0
 | 
						|
        }
 | 
						|
 | 
						|
        while (esm.isNextSub("APUD"))
 | 
						|
        {
 | 
						|
            // used power
 | 
						|
            esm.getSubHeader();
 | 
						|
            std::string id = esm.getString(32);
 | 
						|
            (void)id;
 | 
						|
            // timestamp can't be used: this is the total hours passed, calculated by
 | 
						|
            // timestamp = 24 * (365 * year + cumulativeDays[month] + day)
 | 
						|
            // unfortunately cumulativeDays[month] is not clearly defined,
 | 
						|
            // in the (non-MCP) vanilla version the first month was missing, but MCP added it.
 | 
						|
            double timestamp;
 | 
						|
            esm.getT(timestamp);
 | 
						|
        }
 | 
						|
 | 
						|
        // FIXME: not all actors have this, add flag
 | 
						|
        if (esm.isNextSub("CHRD")) // npc only
 | 
						|
            esm.getHExact(mActorData.mSkills, 27 * 2 * sizeof(int));
 | 
						|
 | 
						|
        if (esm.isNextSub("CRED")) // creature only
 | 
						|
            esm.getHExact(mActorData.mCombatStats, 3 * 2 * sizeof(int));
 | 
						|
 | 
						|
        mActorData.mSCRI.load(esm);
 | 
						|
 | 
						|
        if (esm.isNextSub("ND3D"))
 | 
						|
            esm.skipHSub();
 | 
						|
 | 
						|
        mActorData.mHasANIS = false;
 | 
						|
        if (esm.isNextSub("ANIS"))
 | 
						|
        {
 | 
						|
            mActorData.mHasANIS = true;
 | 
						|
            esm.getHT(mActorData.mANIS);
 | 
						|
        }
 | 
						|
 | 
						|
        if (esm.isNextSub("LVCR"))
 | 
						|
        {
 | 
						|
            // occurs on levelled creature spawner references
 | 
						|
            // probably some identifier for the creature that has been spawned?
 | 
						|
            unsigned char lvcr;
 | 
						|
            esm.getHT(lvcr);
 | 
						|
            // std::cout << "LVCR: " << (int)lvcr << std::endl;
 | 
						|
        }
 | 
						|
 | 
						|
        mEnabled = true;
 | 
						|
        esm.getHNOT(mEnabled, "ZNAM");
 | 
						|
 | 
						|
        // DATA should occur for all references, except levelled creature spawners
 | 
						|
        // I've seen DATA *twice* on a creature record, and with the exact same content too! weird
 | 
						|
        // alarmvoi0000.ess
 | 
						|
        esm.getHNOTSized<24>(mPos, "DATA");
 | 
						|
        esm.getHNOTSized<24>(mPos, "DATA");
 | 
						|
 | 
						|
        mDeleted = 0;
 | 
						|
        if (esm.isNextSub("DELE"))
 | 
						|
        {
 | 
						|
            unsigned int deleted;
 | 
						|
            esm.getHT(deleted);
 | 
						|
            mDeleted = ((deleted >> 24) & 0x2) != 0; // the other 3 bytes seem to be uninitialized garbage
 | 
						|
        }
 | 
						|
 | 
						|
        if (esm.isNextSub("MVRF"))
 | 
						|
        {
 | 
						|
            esm.skipHSub();
 | 
						|
            esm.getSubName();
 | 
						|
            esm.skipHSub();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
}
 |