Ejemplo n.º 1
0
bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref)
{
    esm.getHT(mref.mRefnum);
    esm.getHNOT(mref.mTarget, "CNDT");

    // Identify references belonging to a parent file and adapt the ID accordingly.
    int local = (mref.mRefnum & 0xff000000) >> 24;
    size_t global = esm.getIndex() + 1;
    mref.mRefnum &= 0x00ffffff; // delete old plugin ID
    const std::vector<Header::MasterData> &masters = esm.getGameFiles();
    global = masters[local-1].index + 1;
    mref.mRefnum |= global << 24; // insert global plugin ID

    return true;
}
Ejemplo n.º 2
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.º 3
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;
    }