Ejemplo n.º 1
0
    void Script::load(ESMReader &esm)
    {
        SCHD data;
        esm.getHNT(data, "SCHD", 52);
        mData = data.mData;
        mId = data.mName.toString();

        mVarNames.clear();

        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            uint32_t name = esm.retSubName().val;
            switch (name)
            {
                case ESM::FourCC<'S','C','V','R'>::value:
                    // list of local variables
                    loadSCVR(esm);
                    break;
                case ESM::FourCC<'S','C','D','T'>::value:
                    // compiled script
                    mScriptData.resize(mData.mScriptDataSize);
                    esm.getHExact(&mScriptData[0], mScriptData.size());
                    break;
                case ESM::FourCC<'S','C','T','X'>::value:
                    mScriptText = esm.getHString();
                    break;
                default:
                    esm.fail("Unknown subrecord");
            }
        }
    }
Ejemplo n.º 2
0
 void Weapon::load(ESMReader &esm)
 {
     bool hasData = false;
     while (esm.hasMoreSubs())
     {
         esm.getSubName();
         uint32_t name = esm.retSubName().val;
         switch (name)
         {
             case ESM::FourCC<'M','O','D','L'>::value:
                 mModel = esm.getHString();
                 break;
             case ESM::FourCC<'F','N','A','M'>::value:
                 mName = esm.getHString();
                 break;
             case ESM::FourCC<'W','P','D','T'>::value:
                 esm.getHT(mData, 32);
                 hasData = true;
                 break;
             case ESM::FourCC<'S','C','R','I'>::value:
                 mScript = esm.getHString();
                 break;
             case ESM::FourCC<'I','T','E','X'>::value:
                 mIcon = esm.getHString();
                 break;
             case ESM::FourCC<'E','N','A','M'>::value:
                 mEnchant = esm.getHString();
                 break;
             default:
                 esm.fail("Unknown subrecord");
         }
     }
     if (!hasData)
         esm.fail("Missing WPDT subrecord");
 }
Ejemplo n.º 3
0
 void Door::load(ESMReader &esm)
 {
     while (esm.hasMoreSubs())
     {
         esm.getSubName();
         uint32_t name = esm.retSubName().val;
         switch (name)
         {
             case ESM::FourCC<'M','O','D','L'>::value:
                 mModel = esm.getHString();
                 break;
             case ESM::FourCC<'F','N','A','M'>::value:
                 mName = esm.getHString();
                 break;
             case ESM::FourCC<'S','C','R','I'>::value:
                 mScript = esm.getHString();
                 break;
             case ESM::FourCC<'S','N','A','M'>::value:
                 mOpenSound = esm.getHString();
                 break;
             case ESM::FourCC<'A','N','A','M'>::value:
                 mCloseSound = esm.getHString();
                 break;
             default:
                 esm.fail("Unknown subrecord");
         }
     }
 }
Ejemplo n.º 4
0
void BodyPart::load(ESMReader &esm)
{
    bool hasData = false;
    while (esm.hasMoreSubs())
    {
        esm.getSubName();
        uint32_t name = esm.retSubName().val;
        switch (name)
        {
            case ESM::FourCC<'M','O','D','L'>::value:
                mModel = esm.getHString();
                break;
            case ESM::FourCC<'F','N','A','M'>::value:
                mRace = esm.getHString();
                break;
            case ESM::FourCC<'B','Y','D','T'>::value:
                esm.getHT(mData, 4);
                hasData = true;
                break;
            default:
                esm.fail("Unknown subrecord");
        }
    }

    if (!hasData)
        esm.fail("Missing BYDT subrecord");
}
Ejemplo n.º 5
0
    void StartScript::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        bool hasData = false;
        bool hasName = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().val)
            {
                case ESM::SREC_NAME:
                    mId = esm.getHString();
                    hasName = true;
                    break;
                case ESM::FourCC<'D','A','T','A'>::value:
                    mData = esm.getHString();
                    hasData = true;
                    break;
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.fail("Unknown subrecord");
                    break;
            }
        }

        if (!hasName)
            esm.fail("Missing NAME");
        if (!hasData && !isDeleted)
            esm.fail("Missing DATA");
    }
Ejemplo n.º 6
0
void GameSetting::load(ESMReader &esm)
{
    assert(mId != "");

    // We are apparently allowed to be empty
    if (!esm.hasMoreSubs())
    {
        mType = VT_None;
        return;
    }

    // Load some data
    esm.getSubName();
    NAME n = esm.retSubName();
    if (n == "STRV")
    {
        mStr = esm.getHString();
        mType = VT_String;
    }
    else if (n == "INTV")
    {
        esm.getHT(mI);
        mType = VT_Int;
    }
    else if (n == "FLTV")
    {
        esm.getHT(mF);
        mType = VT_Float;
    }
    else
        esm.fail("Unwanted subrecord type");
}
Ejemplo n.º 7
0
bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted)
{
    // TODO: Try and document reference numbering, I don't think this has been done anywhere else.
    if (!esm.hasMoreSubs())
        return false;

    // NOTE: We should not need this check. It is a safety check until we have checked
    // more plugins, and how they treat these moved references.
    if (esm.isNextSub("MVRF")) {
        esm.skipRecord(); // skip MVRF
        esm.skipRecord(); // skip CNDT
        // That should be it, I haven't seen any other fields yet.
    }

    ref.load (esm);

    // Identify references belonging to a parent file and adapt the ID accordingly.
    adjustRefNum (ref.mRefNum, esm);

    if (esm.isNextSub("DELE"))
    {
        esm.skipHSub();
        deleted = true;
    }
    else
        deleted = false;

    return true;
}
Ejemplo n.º 8
0
void ESM::DebugProfile::load (ESMReader& esm, bool &isDeleted)
{
    isDeleted = false;

    while (esm.hasMoreSubs())
    {
        esm.getSubName();
        switch (esm.retSubName().intval)
        {
            case ESM::SREC_NAME:
                mId = esm.getHString();
                break;
            case ESM::FourCC<'D','E','S','C'>::value:
                mDescription = esm.getHString();
                break;
            case ESM::FourCC<'S','C','R','P'>::value:
                mScriptText = esm.getHString();
                break;
            case ESM::FourCC<'F','L','A','G'>::value:
                esm.getHT(mFlags);
                break;
            case ESM::SREC_DELE:
                esm.skipHSub();
                isDeleted = true;
                break;
            default:
                esm.fail("Unknown subrecord");
                break;
        }
    }
}
Ejemplo n.º 9
0
    void Skill::load(ESMReader &esm)
    {
        bool hasIndex = false;
        bool hasData = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            uint32_t name = esm.retSubName().val;
            switch (name)
            {
                case ESM::FourCC<'I','N','D','X'>::value:
                    esm.getHT(mIndex);
                    hasIndex = true;
                    break;
                case ESM::FourCC<'S','K','D','T'>::value:
                    esm.getHT(mData, 24);
                    hasData = true;
                    break;
                case ESM::FourCC<'D','E','S','C'>::value:
                    mDescription = esm.getHString();
                    break;
                default:
                    esm.fail("Unknown subrecord");
            }
        }
        if (!hasIndex)
            esm.fail("Missing INDX");
        if (!hasData)
            esm.fail("Missing SKDT");

        // create an ID from the index and the name (only used in the editor and likely to change in the
        // future)
        mId = indexToId (mIndex);
    }
Ejemplo n.º 10
0
    void Faction::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        mReactions.clear();
        for (int i=0;i<10;++i)
            mRanks[i].clear();

        int rankCounter = 0;
        bool hasName = false;
        bool hasData = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().val)
            {
                case ESM::SREC_NAME:
                    mId = esm.getHString();
                    hasName = true;
                    break;
                case ESM::FourCC<'F','N','A','M'>::value:
                    mName = esm.getHString();
                    break;
                case ESM::FourCC<'R','N','A','M'>::value:
                    if (rankCounter >= 10)
                        esm.fail("Rank out of range");
                    mRanks[rankCounter++] = esm.getHString();
                    break;
                case ESM::FourCC<'F','A','D','T'>::value:
                    esm.getHT(mData, 240);
                    if (mData.mIsHidden > 1)
                        esm.fail("Unknown flag!");
                    hasData = true;
                    break;
                case ESM::FourCC<'A','N','A','M'>::value:
                {
                    std::string faction = esm.getHString();
                    int reaction;
                    esm.getHNT(reaction, "INTV");
                    mReactions[faction] = reaction;
                    break;
                }
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.fail("Unknown subrecord");
                    break;
            }
        }

        if (!hasName)
            esm.fail("Missing NAME subrecord");
        if (!hasData && !isDeleted)
            esm.fail("Missing FADT subrecord");
    }
Ejemplo n.º 11
0
    void Book::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        bool hasName = false;
        bool hasData = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().intval)
            {
                case ESM::SREC_NAME:
                    mId = esm.getHString();
                    hasName = true;
                    break;
                case ESM::FourCC<'M','O','D','L'>::value:
                    mModel = esm.getHString();
                    break;
                case ESM::FourCC<'F','N','A','M'>::value:
                    mName = esm.getHString();
                    break;
                case ESM::FourCC<'B','K','D','T'>::value:
                    esm.getHT(mData, 20);
                    hasData = true;
                    break;
                case ESM::FourCC<'S','C','R','I'>::value:
                    mScript = esm.getHString();
                    break;
                case ESM::FourCC<'I','T','E','X'>::value:
                    mIcon = esm.getHString();
                    break;
                case ESM::FourCC<'E','N','A','M'>::value:
                    mEnchant = esm.getHString();
                    break;
                case ESM::FourCC<'T','E','X','T'>::value:
                    mText = esm.getHString();
                    break;
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.fail("Unknown subrecord");
                    break;
            }
        }

        if (!hasName)
            esm.fail("Missing NAME subrecord");
        if (!hasData && !isDeleted)
            esm.fail("Missing BKDT subrecord");
    }
Ejemplo n.º 12
0
    void Cell::loadNameAndData(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        blank();

        bool hasData = false;
        bool isLoaded = false;
        while (!isLoaded && esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().intval)
            {
                case ESM::SREC_NAME:
                    mName = esm.getHString();
                    break;
                case ESM::FourCC<'D','A','T','A'>::value:
                    esm.getHT(mData, 12);
                    hasData = true;
                    break;
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.cacheSubName();
                    isLoaded = true;
                    break;
            }
        }

        if (!hasData)
            esm.fail("Missing DATA subrecord");

        mCellId.mPaged = !(mData.mFlags & Interior);

        if (mCellId.mPaged)
        {
            mCellId.mWorldspace = ESM::CellId::sDefaultWorldspace;
            mCellId.mIndex.mX = mData.mX;
            mCellId.mIndex.mY = mData.mY;
        }
        else
        {
            mCellId.mWorldspace = Misc::StringUtils::lowerCase (mName);
            mCellId.mIndex.mX = 0;
            mCellId.mIndex.mY = 0;
        }
    }
Ejemplo n.º 13
0
void printRaw(ESMReader &esm)
{
  while(esm.hasMoreRecs())
    {
      NAME n = esm.getRecName();
      cout << "Record: " << n.toString() << endl;
      esm.getRecHeader();
      while(esm.hasMoreSubs())
        {
          uint64_t offs = esm.getOffset();
          esm.getSubName();
          esm.skipHSub();
          n = esm.retSubName();
          cout << "    " << n.toString() << " - " << esm.getSubSize()
               << " bytes @ 0x" << hex << offs << "\n";
        }
    }
}
Ejemplo n.º 14
0
    void Race::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        mPowers.mList.clear();

        bool hasName = false;
        bool hasData = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().val)
            {
                case ESM::SREC_NAME:
                    mId = esm.getHString();
                    hasName = true;
                    break;
                case ESM::FourCC<'F','N','A','M'>::value:
                    mName = esm.getHString();
                    break;
                case ESM::FourCC<'R','A','D','T'>::value:
                    esm.getHT(mData, 140);
                    hasData = true;
                    break;
                case ESM::FourCC<'D','E','S','C'>::value:
                    mDescription = esm.getHString();
                    break;
                case ESM::FourCC<'N','P','C','S'>::value:
                    mPowers.add(esm);
                    break;
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.fail("Unknown subrecord");
            }
        }

        if (!hasName)
            esm.fail("Missing NAME subrecord");
        if (!hasData && !isDeleted)
            esm.fail("Missing RADT subrecord");
    }
Ejemplo n.º 15
0
    void Spell::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        mEffects.mList.clear();

        bool hasName = false;
        bool hasData = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().val)
            {
                case ESM::SREC_NAME:
                    mId = esm.getHString();
                    hasName = true;
                    break;
                case ESM::FourCC<'F','N','A','M'>::value:
                    mName = esm.getHString();
                    break;
                case ESM::FourCC<'S','P','D','T'>::value:
                    esm.getHT(mData, 12);
                    hasData = true;
                    break;
                case ESM::FourCC<'E','N','A','M'>::value:
                    ENAMstruct s;
                    esm.getHT(s, 24);
                    mEffects.mList.push_back(s);
                    break;
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.fail("Unknown subrecord");
                    break;
            }
        }

        if (!hasName)
            esm.fail("Missing NAME subrecord");
        if (!hasData && !isDeleted)
            esm.fail("Missing SPDT subrecord");
    }
Ejemplo n.º 16
0
 void Container::load(ESMReader &esm)
 {
     mInventory.mList.clear();
     bool hasWeight = false;
     bool hasFlags = false;
     while (esm.hasMoreSubs())
     {
         esm.getSubName();
         uint32_t name = esm.retSubName().val;
         switch (name)
         {
             case ESM::FourCC<'M','O','D','L'>::value:
                 mModel = esm.getHString();
                 break;
             case ESM::FourCC<'F','N','A','M'>::value:
                 mName = esm.getHString();
                 break;
             case ESM::FourCC<'C','N','D','T'>::value:
                 esm.getHT(mWeight, 4);
                 hasWeight = true;
                 break;
             case ESM::FourCC<'F','L','A','G'>::value:
                 esm.getHT(mFlags, 4);
                 if (mFlags & 0xf4)
                     esm.fail("Unknown flags");
                 if (!(mFlags & 0x8))
                     esm.fail("Flag 8 not set");
                 hasFlags = true;
                 break;
             case ESM::FourCC<'S','C','R','I'>::value:
                 mScript = esm.getHString();
                 break;
             case ESM::FourCC<'N','P','C','O'>::value:
                 mInventory.add(esm);
                 break;
             default:
                 esm.fail("Unknown subrecord");
         }
     }
     if (!hasWeight)
         esm.fail("Missing CNDT subrecord");
     if (!hasFlags)
         esm.fail("Missing FLAG subrecord");
 }
Ejemplo n.º 17
0
void Faction::load(ESMReader &esm)
{
    mReactions.clear();
    for (int i=0;i<10;++i)
        mRanks[i].clear();

    int rankCounter=0;
    bool hasData = false;
    while (esm.hasMoreSubs())
    {
        esm.getSubName();
        uint32_t name = esm.retSubName().val;
        switch (name)
        {
            case ESM::FourCC<'F','N','A','M'>::value:
                mName = esm.getHString();
                break;
            case ESM::FourCC<'R','N','A','M'>::value:
                if (rankCounter >= 10)
                    esm.fail("Rank out of range");
                mRanks[rankCounter++] = esm.getHString();
                break;
            case ESM::FourCC<'F','A','D','T'>::value:
                esm.getHT(mData, 240);
                if (mData.mIsHidden > 1)
                    esm.fail("Unknown flag!");
                hasData = true;
                break;
            case ESM::FourCC<'A','N','A','M'>::value:
            {
                std::string faction = esm.getHString();
                int reaction;
                esm.getHNT(reaction, "INTV");
                mReactions[faction] = reaction;
                break;
            }
            default:
                esm.fail("Unknown subrecord");
        }
    }
    if (!hasData)
        esm.fail("Missing FADT subrecord");
}
Ejemplo n.º 18
0
    void Cell::loadCell(ESMReader &esm, bool saveContext)
    {
        bool isLoaded = false;
        while (!isLoaded && esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().intval)
            {
                case ESM::FourCC<'I','N','T','V'>::value:
                    int waterl;
                    esm.getHT(waterl);
                    mWater = static_cast<float>(waterl);
                    mWaterInt = true;
                    break;
                case ESM::FourCC<'W','H','G','T'>::value:
                    esm.getHT(mWater);
                    mWaterInt = false;
                    break;
                case ESM::FourCC<'A','M','B','I'>::value:
                    esm.getHT(mAmbi);
                    break;
                case ESM::FourCC<'R','G','N','N'>::value:
                    mRegion = esm.getHString();
                    break;
                case ESM::FourCC<'N','A','M','5'>::value:
                    esm.getHT(mMapColor);
                    break;
                case ESM::FourCC<'N','A','M','0'>::value:
                    esm.getHT(mRefNumCounter);
                    break;
                default:
                    esm.cacheSubName();
                    isLoaded = true;
                    break;
            }
        }

        if (saveContext) 
        {
            mContextList.push_back(esm.getContext());
            esm.skipRecord();
        }
    }
Ejemplo n.º 19
0
    void Class::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        bool hasName = false;
        bool hasData = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().intval)
            {
                case ESM::SREC_NAME:
                    mId = esm.getHString();
                    hasName = true;
                    break;
                case ESM::FourCC<'F','N','A','M'>::value:
                    mName = esm.getHString();
                    break;
                case ESM::FourCC<'C','L','D','T'>::value:
                    esm.getHT(mData, 60);
                    if (mData.mIsPlayable > 1)
                        esm.fail("Unknown bool value");
                    hasData = true;
                    break;
                case ESM::FourCC<'D','E','S','C'>::value:
                    mDescription = esm.getHString();
                    break;
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.fail("Unknown subrecord");
                    break;
            }
        }

        if (!hasName)
            esm.fail("Missing NAME subrecord");
        if (!hasData && !isDeleted)
            esm.fail("Missing CLDT subrecord");
    }
Ejemplo n.º 20
0
    void Door::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        bool hasName = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().val)
            {
                case ESM::SREC_NAME:
                    mId = esm.getHString();
                    hasName = true;
                    break;
                case ESM::FourCC<'M','O','D','L'>::value:
                    mModel = esm.getHString();
                    break;
                case ESM::FourCC<'F','N','A','M'>::value:
                    mName = esm.getHString();
                    break;
                case ESM::FourCC<'S','C','R','I'>::value:
                    mScript = esm.getHString();
                    break;
                case ESM::FourCC<'S','N','A','M'>::value:
                    mOpenSound = esm.getHString();
                    break;
                case ESM::FourCC<'A','N','A','M'>::value:
                    mCloseSound = esm.getHString();
                    break;
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.fail("Unknown subrecord");
                    break;
            }
        }

        if (!hasName)
            esm.fail("Missing NAME subrecord");
    }
Ejemplo n.º 21
0
void Region::load(ESMReader &esm)
{
    mName = esm.getHNString("FNAM");

    if (esm.getVer() == VER_12)
        esm.getHNExact(&mData, sizeof(mData) - 2, "WEAT");
    else if (esm.getVer() == VER_13)
        esm.getHNExact(&mData, sizeof(mData), "WEAT");
    else
        esm.fail("Don't know what to do in this version");

    mSleepList = esm.getHNOString("BNAM");

    esm.getHNT(mMapColor, "CNAM");

    while (esm.hasMoreSubs())
    {
        SoundRef sr;
        esm.getHNT(sr, "SNAM", 33);
        mSoundList.push_back(sr);
    }
}
Ejemplo n.º 22
0
  void load(ESMReader &esm)
  {
    name = esm.getHNString("FNAM");

    // Read rank names. These are optional.
    int i = 0;
    while(esm.isNextSub("RNAM") && i<10) ranks[i++] = esm.getHString();

    // Main data struct
    esm.getHNT(data, "FADT", 240);

    if(data.isHidden > 1) esm.fail("Unknown flag!");

    // Read faction response values
    while(esm.hasMoreSubs())
      {
        Reaction r;
        r.faction = esm.getHNString("ANAM");
        esm.getHNT(r.reaction, "INTV");
        reactions.push_back(r);
      }
  }
Ejemplo n.º 23
0
void Apparatus::load(ESMReader &esm)
{
    // we will not treat duplicated subrecords as errors here
    while (esm.hasMoreSubs())
    {
        esm.getSubName();
        NAME subName = esm.retSubName();

        if (subName == "MODL")
            mModel = esm.getHString();
        else if (subName == "FNAM")
            mName = esm.getHString();
        else if (subName == "AADT")
            esm.getHT(mData);
        else if (subName == "SCRI")
            mScript = esm.getHString();
        else if (subName == "ITEX")
            mIcon = esm.getHString();
        else
            esm.fail("wrong subrecord type " + subName.toString() + " for APPA record");
    }
}
Ejemplo n.º 24
0
bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMoves, MovedCellRef *mref)
{
    // TODO: Try and document reference numbering, I don't think this has been done anywhere else.
    if (!esm.hasMoreSubs())
        return false;

    // NOTE: We should not need this check. It is a safety check until we have checked
    // more plugins, and how they treat these moved references.
    if (esm.isNextSub("MVRF"))
    {
        if (ignoreMoves)
        {
            esm.getHT (mref->mRefNum.mIndex);
            esm.getHNOT (mref->mTarget, "CNDT");
            adjustRefNum (mref->mRefNum, esm);
        }
        else
        {
            // skip rest of cell record (moved references), they are handled elsewhere
            esm.skipRecord(); // skip MVRF, CNDT
            return false;
        }
    }

    ref.load (esm);

    // Identify references belonging to a parent file and adapt the ID accordingly.
    adjustRefNum (ref.mRefNum, esm);

    if (esm.isNextSub("DELE"))
    {
        esm.skipHSub();
        deleted = true;
    }
    else
        deleted = false;

    return true;
}
Ejemplo n.º 25
0
    void Enchantment::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;
        mEffects.mList.clear();

        bool hasName = false;
        bool hasData = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().intval)
            {
                case ESM::SREC_NAME:
                    mId = esm.getHString();
                    hasName = true;
                    break;
                case ESM::FourCC<'E','N','D','T'>::value:
                    esm.getHT(mData, 16);
                    hasData = true;
                    break;
                case ESM::FourCC<'E','N','A','M'>::value:
                    mEffects.add(esm);
                    break;
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.fail("Unknown subrecord");
                    break;
            }
        }

        if (!hasName)
            esm.fail("Missing NAME subrecord");
        if (!hasData && !isDeleted)
            esm.fail("Missing ENDT subrecord");
    }
Ejemplo n.º 26
0
bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
{
    // TODO: Try and document reference numbering, I don't think this has been done anywhere else.
    if (!esm.hasMoreSubs())
        return false;

    // NOTE: We should not need this check. It is a safety check until we have checked
    // more plugins, and how they treat these moved references.
    if (esm.isNextSub("MVRF")) {
        esm.skipRecord(); // skip MVRF
        esm.skipRecord(); // skip CNDT
        // That should be it, I haven't seen any other fields yet.
    }

    // NAM0 sometimes appears here, sometimes further on
    ref.mNam0 = 0;
    if (esm.isNextSub("NAM0"))
    {
        esm.getHT(ref.mNam0);
        //esm.getHNOT(NAM0, "NAM0");
    }

    esm.getHNT(ref.mRefnum, "FRMR");
    ref.mRefID = esm.getHNString("NAME");

    // Identify references belonging to a parent file and adapt the ID accordingly.
    int local = (ref.mRefnum & 0xff000000) >> 24;
    size_t global = esm.getIndex() + 1;
    if (local)
    {
        // If the most significant 8 bits are used, then this reference already exists.
        // In this case, do not spawn a new reference, but overwrite the old one.
        ref.mRefnum &= 0x00ffffff; // delete old plugin ID
        const std::vector<Header::MasterData> &masters = esm.getGameFiles();
        global = masters[local-1].index + 1;
        ref.mRefnum |= global << 24; // insert global plugin ID
    }
    else
    {
        // This is an addition by the present plugin. Set the corresponding plugin index.
        ref.mRefnum |= global << 24; // insert global plugin ID
    }

    // getHNOT will not change the existing value if the subrecord is
    // missing
    ref.mScale = 1.0;
    esm.getHNOT(ref.mScale, "XSCL");

    // TODO: support loading references from saves, there are tons of keys not recognized yet.
    // The following is just an incomplete list.
    if (esm.isNextSub("ACTN"))
        esm.skipHSub();
    if (esm.isNextSub("STPR"))
        esm.skipHSub();
    if (esm.isNextSub("ACDT"))
        esm.skipHSub();
    if (esm.isNextSub("ACSC"))
        esm.skipHSub();
    if (esm.isNextSub("ACSL"))
        esm.skipHSub();
    if (esm.isNextSub("CHRD"))
        esm.skipHSub();
    else if (esm.isNextSub("CRED")) // ???
        esm.skipHSub();

    ref.mOwner = esm.getHNOString("ANAM");
    ref.mGlob = esm.getHNOString("BNAM");
    ref.mSoul = esm.getHNOString("XSOL");

    ref.mFaction = esm.getHNOString("CNAM");
    ref.mFactIndex = -2;
    esm.getHNOT(ref.mFactIndex, "INDX");

    ref.mGoldValue = 1;
    ref.mCharge = -1;
    ref.mEnchantmentCharge = -1;

    esm.getHNOT(ref.mEnchantmentCharge, "XCHG");

    esm.getHNOT(ref.mCharge, "INTV");

    esm.getHNOT(ref.mGoldValue, "NAM9");

    // Present for doors that teleport you to another cell.
    if (esm.isNextSub("DODT"))
    {
        ref.mTeleport = true;
        esm.getHT(ref.mDoorDest);
        ref.mDestCell = esm.getHNOString("DNAM");
    } else {
        ref.mTeleport = false;
    }

    // Integer, despite the name suggesting otherwise
    ref.mLockLevel = -1;
    esm.getHNOT(ref.mLockLevel, "FLTV");
    ref.mKey = esm.getHNOString("KNAM");
    ref.mTrap = esm.getHNOString("TNAM");

    ref.mReferenceBlocked = -1;
    ref.mFltv = 0;
    esm.getHNOT(ref.mReferenceBlocked, "UNAM");
    esm.getHNOT(ref.mFltv, "FLTV");

    esm.getHNOT(ref.mPos, "DATA", 24);

    // Number of references in the cell? Maximum once in each cell,
    // but not always at the beginning, and not always right. In other
    // words, completely useless.
    // Update: Well, maybe not completely useless. This might actually be
    //  number_of_references + number_of_references_moved_here_Across_boundaries,
    //  and could be helpful for collecting these weird moved references.
    if (esm.isNextSub("NAM0"))
    {
        esm.getHT(ref.mNam0);
        //esm.getHNOT(NAM0, "NAM0");
    }

    if (esm.isNextSub("DELE")) {
        esm.skipHSub();
        ref.mDeleted = 2; // Deleted, will not respawn.
        // TODO: find out when references do respawn.
    } else
        ref.mDeleted = 0;

    return true;
}
Ejemplo n.º 27
0
    void LevelledListBase::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        bool hasName = false;
        bool hasList = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().val)
            {
                case ESM::SREC_NAME:
                    mId = esm.getHString();
                    hasName = true;
                    break;
                case ESM::FourCC<'D','A','T','A'>::value:
                    esm.getHT(mFlags);
                    break;
                case ESM::FourCC<'N','N','A','M'>::value:
                    esm.getHT(mChanceNone);
                    break;
                case ESM::FourCC<'I','N','D','X'>::value:
                {
                    int length = 0;
                    esm.getHT(length);
                    mList.resize(length);

                    // If this levelled list was already loaded by a previous content file,
                    // we overwrite the list. Merging lists should probably be left to external tools,
                    // with the limited amount of information there is in the records, all merging methods
                    // will be flawed in some way. For a proper fix the ESM format would have to be changed
                    // to actually track list changes instead of including the whole list for every file
                    // that does something with that list.
                    for (size_t i = 0; i < mList.size(); i++)
                    {
                        LevelItem &li = mList[i];
                        li.mId = esm.getHNString(mRecName);
                        esm.getHNT(li.mLevel, "INTV");
                    }

                    hasList = true;
                    break;
                }
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                {
                    if (!hasList)
                    {
                        // Original engine ignores rest of the record, even if there are items following
                        mList.clear();
                        esm.skipRecord();
                    }
                    else
                    {
                        esm.fail("Unknown subrecord");
                    }
                    break;
                }
            }
        }

        if (!hasName)
            esm.fail("Missing NAME subrecord");
    }
Ejemplo n.º 28
0
    void NPC::load(ESMReader &esm)
    {
        mPersistent = (esm.getRecordFlags() & 0x0400) != 0;

        mSpells.mList.clear();
        mInventory.mList.clear();
        mTransport.mList.clear();
        mAiPackage.mList.clear();

        bool hasNpdt = false;
        bool hasFlags = false;
        mHasAI = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            uint32_t name = esm.retSubName().val;
            switch (name)
            {
                case ESM::FourCC<'M','O','D','L'>::value:
                    mModel = esm.getHString();
                    break;
                case ESM::FourCC<'F','N','A','M'>::value:
                    mName = esm.getHString();
                    break;
                case ESM::FourCC<'R','N','A','M'>::value:
                    mRace = esm.getHString();
                    break;
                case ESM::FourCC<'C','N','A','M'>::value:
                    mClass = esm.getHString();
                    break;
                case ESM::FourCC<'A','N','A','M'>::value:
                    mFaction = esm.getHString();
                    break;
                case ESM::FourCC<'B','N','A','M'>::value:
                    mHead = esm.getHString();
                    break;
                case ESM::FourCC<'K','N','A','M'>::value:
                    mHair = esm.getHString();
                    break;
                case ESM::FourCC<'S','C','R','I'>::value:
                    mScript = esm.getHString();
                    break;
                case ESM::FourCC<'N','P','D','T'>::value:
                    hasNpdt = true;
                    esm.getSubHeader();
                    if (esm.getSubSize() == 52)
                    {
                        mNpdtType = NPC_DEFAULT;
                        esm.getExact(&mNpdt52, 52);
                    }
                    else if (esm.getSubSize() == 12)
                    {
                        mNpdtType = NPC_WITH_AUTOCALCULATED_STATS;
                        esm.getExact(&mNpdt12, 12);
                    }
                    else
                        esm.fail("NPC_NPDT must be 12 or 52 bytes long");
                    break;
                case ESM::FourCC<'F','L','A','G'>::value:
                    hasFlags = true;
                    esm.getHT(mFlags);
                    break;
                case ESM::FourCC<'N','P','C','S'>::value:
                    mSpells.add(esm);
                    break;
                case ESM::FourCC<'N','P','C','O'>::value:
                    mInventory.add(esm);
                    break;
                case ESM::FourCC<'A','I','D','T'>::value:
                    esm.getHExact(&mAiData, sizeof(mAiData));
                    mHasAI= true;
                    break;
                case ESM::FourCC<'D','O','D','T'>::value:
                case ESM::FourCC<'D','N','A','M'>::value:
                    mTransport.add(esm);
                    break;
                case AI_Wander:
                case AI_Activate:
                case AI_Escort:
                case AI_Follow:
                case AI_Travel:
                case AI_CNDT:
                    mAiPackage.add(esm);
                    break;
                default:
                    esm.fail("Unknown subrecord");
            }
        }
        if (!hasNpdt)
            esm.fail("Missing NPDT subrecord");
        if (!hasFlags)
            esm.fail("Missing FLAG subrecord");
    }
Ejemplo n.º 29
0
    void NPC::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        mPersistent = (esm.getRecordFlags() & 0x0400) != 0;

        mSpells.mList.clear();
        mInventory.mList.clear();
        mTransport.mList.clear();
        mAiPackage.mList.clear();
        mAiData.blank();
        mAiData.mHello = mAiData.mFight = mAiData.mFlee = 30;

        bool hasName = false;
        bool hasNpdt = false;
        bool hasFlags = false;
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().intval)
            {
                case ESM::SREC_NAME:
                    mId = esm.getHString();
                    hasName = true;
                    break;
                case ESM::FourCC<'M','O','D','L'>::value:
                    mModel = esm.getHString();
                    break;
                case ESM::FourCC<'F','N','A','M'>::value:
                    mName = esm.getHString();
                    break;
                case ESM::FourCC<'R','N','A','M'>::value:
                    mRace = esm.getHString();
                    break;
                case ESM::FourCC<'C','N','A','M'>::value:
                    mClass = esm.getHString();
                    break;
                case ESM::FourCC<'A','N','A','M'>::value:
                    mFaction = esm.getHString();
                    break;
                case ESM::FourCC<'B','N','A','M'>::value:
                    mHead = esm.getHString();
                    break;
                case ESM::FourCC<'K','N','A','M'>::value:
                    mHair = esm.getHString();
                    break;
                case ESM::FourCC<'S','C','R','I'>::value:
                    mScript = esm.getHString();
                    break;
                case ESM::FourCC<'N','P','D','T'>::value:
                    hasNpdt = true;
                    esm.getSubHeader();
                    if (esm.getSubSize() == 52)
                    {
                        mNpdtType = NPC_DEFAULT;
                        esm.getExact(&mNpdt, 52);
                    }
                    else if (esm.getSubSize() == 12)
                    {
                        //Reading into temporary NPDTstruct12 object
                        NPDTstruct12 npdt12;
                        mNpdtType = NPC_WITH_AUTOCALCULATED_STATS;
                        esm.getExact(&npdt12, 12);

                        //Clearing the mNdpt struct to initialize all values
                        blankNpdt();
                        //Swiching to an internal representation
                        mNpdt.mLevel = npdt12.mLevel;
                        mNpdt.mDisposition = npdt12.mDisposition;
                        mNpdt.mReputation = npdt12.mReputation;
                        mNpdt.mRank = npdt12.mRank;
                        mNpdt.mGold = npdt12.mGold;
                    }
                    else
                        esm.fail("NPC_NPDT must be 12 or 52 bytes long");
                    break;
                case ESM::FourCC<'F','L','A','G'>::value:
                    hasFlags = true;
                    esm.getHT(mFlags);
                    break;
                case ESM::FourCC<'N','P','C','S'>::value:
                    mSpells.add(esm);
                    break;
                case ESM::FourCC<'N','P','C','O'>::value:
                    mInventory.add(esm);
                    break;
                case ESM::FourCC<'A','I','D','T'>::value:
                    esm.getHExact(&mAiData, sizeof(mAiData));
                    break;
                case ESM::FourCC<'D','O','D','T'>::value:
                case ESM::FourCC<'D','N','A','M'>::value:
                    mTransport.add(esm);
                    break;
                case AI_Wander:
                case AI_Activate:
                case AI_Escort:
                case AI_Follow:
                case AI_Travel:
                case AI_CNDT:
                    mAiPackage.add(esm);
                    break;
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.fail("Unknown subrecord");
                    break;
            }
        }

        if (!hasName)
            esm.fail("Missing NAME subrecord");
        if (!hasNpdt && !isDeleted)
            esm.fail("Missing NPDT subrecord");
        if (!hasFlags && !isDeleted)
            esm.fail("Missing FLAG subrecord");
    }
Ejemplo n.º 30
0
    void Land::load(ESMReader &esm, bool &isDeleted)
    {
        isDeleted = false;

        mPlugin = esm.getIndex();

        bool hasLocation = false;
        bool isLoaded = false;
        while (!isLoaded && esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().val)
            {
                case ESM::FourCC<'I','N','T','V'>::value:
                    esm.getSubHeaderIs(8);
                    esm.getT<int>(mX);
                    esm.getT<int>(mY);
                    hasLocation = true;
                    break;
                case ESM::FourCC<'D','A','T','A'>::value:
                    esm.getHT(mFlags);
                    break;
                case ESM::SREC_DELE:
                    esm.skipHSub();
                    isDeleted = true;
                    break;
                default:
                    esm.cacheSubName();
                    isLoaded = true;
                    break;
            }
        }

        if (!hasLocation)
            esm.fail("Missing INTV subrecord");

        mContext = esm.getContext();

        // Skip the land data here. Load it when the cell is loaded.
        while (esm.hasMoreSubs())
        {
            esm.getSubName();
            switch (esm.retSubName().val)
            {
                case ESM::FourCC<'V','N','M','L'>::value:
                    esm.skipHSub();
                    mDataTypes |= DATA_VNML;
                    break;
                case ESM::FourCC<'V','H','G','T'>::value:
                    esm.skipHSub();
                    mDataTypes |= DATA_VHGT;
                    break;
                case ESM::FourCC<'W','N','A','M'>::value:
                    esm.skipHSub();
                    mDataTypes |= DATA_WNAM;
                    break;
                case ESM::FourCC<'V','C','L','R'>::value:
                    esm.skipHSub();
                    mDataTypes |= DATA_VCLR;
                    break;
                case ESM::FourCC<'V','T','E','X'>::value:
                    esm.skipHSub();
                    mDataTypes |= DATA_VTEX;
                    break;
                default:
                    esm.fail("Unknown subrecord");
                    break;
            }
        }

        mDataLoaded = 0;
        mLandData = NULL;
    }