mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 18:56:43 +00:00 
			
		
		
		
	removing 255 content file limitation
This commit is contained in:
		
							parent
							
								
									09fadd446b
								
							
						
					
					
						commit
						c22e38f825
					
				
					 9 changed files with 74 additions and 68 deletions
				
			
		|  | @ -244,7 +244,7 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info) | |||
| 
 | ||||
|         if(quiet) continue; | ||||
| 
 | ||||
|         std::cout << "    Refnum: " << ref.mRefnum << std::endl; | ||||
|         std::cout << "    Refnum: " << ref.mRefNum.mIndex << std::endl; | ||||
|         std::cout << "    ID: '" << ref.mRefID << "'\n"; | ||||
|         std::cout << "    Owner: '" << ref.mOwner << "'\n"; | ||||
|         std::cout << "    Enchantment charge: '" << ref.mEnchantmentCharge << "'\n"; | ||||
|  |  | |||
|  | @ -38,7 +38,7 @@ namespace MWWorld | |||
|     void CellRefList<X>::load(ESM::CellRef &ref, const MWWorld::ESMStore &esmStore) | ||||
|     { | ||||
|         // Get existing reference, in case we need to overwrite it.
 | ||||
|         typename std::list<LiveRef>::iterator iter = std::find(mList.begin(), mList.end(), ref.mRefnum); | ||||
|         typename std::list<LiveRef>::iterator iter = std::find(mList.begin(), mList.end(), ref.mRefNum); | ||||
| 
 | ||||
|         // Skip this when reference was deleted.
 | ||||
|         // TODO: Support respawning references, in this case, we need to track it somehow.
 | ||||
|  | @ -148,13 +148,14 @@ namespace MWWorld | |||
|             mCell->restore (esm[index], i); | ||||
| 
 | ||||
|             ESM::CellRef ref; | ||||
|             ref.mRefNum.mContentFile = -1; | ||||
| 
 | ||||
|             // Get each reference in turn
 | ||||
|             while(mCell->getNextRef(esm[index], ref)) | ||||
|             { | ||||
|                 // Don't load reference if it was moved to a different cell.
 | ||||
|                 std::string lowerCase = Misc::StringUtils::lowerCase(ref.mRefID); | ||||
|                 ESM::MovedCellRefTracker::const_iterator iter = std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefnum); | ||||
|                 ESM::MovedCellRefTracker::const_iterator iter = std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefNum); | ||||
|                 if (iter != mCell->mMovedRefs.end()) { | ||||
|                     continue; | ||||
|                 } | ||||
|  |  | |||
|  | @ -31,6 +31,11 @@ namespace MWWorld | |||
|         virtual ~LiveCellRefBase() { } | ||||
|     }; | ||||
| 
 | ||||
|     inline bool operator== (const LiveCellRefBase& cellRef, const ESM::CellRef::RefNum refNum) | ||||
|     { | ||||
|         return cellRef.mRef.mRefNum==refNum; | ||||
|     } | ||||
| 
 | ||||
|     /// A reference to one object (of any type) in a cell.
 | ||||
|     ///
 | ||||
|     /// Constructing this with a CellRef instance in the constructor means that
 | ||||
|  | @ -51,8 +56,6 @@ namespace MWWorld | |||
|         // The object that this instance is based on.
 | ||||
|         const X* mBase; | ||||
|     }; | ||||
| 
 | ||||
| //    template<typename X> bool operator==(const LiveCellRef<X>& ref, int pRefnum);
 | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -25,6 +25,8 @@ namespace MWWorld | |||
|                 { | ||||
|                     LiveCellRef<T> ref; | ||||
|                     ref.mBase = instance; | ||||
|                     ref.mRef.mRefNum.mIndex = 0; | ||||
|                     ref.mRef.mRefNum.mContentFile = -1; | ||||
| 
 | ||||
|                     mRef = ref; | ||||
|                     mPtr = Ptr (&boost::any_cast<LiveCellRef<T>&> (mRef), 0); | ||||
|  | @ -65,7 +67,8 @@ namespace MWWorld | |||
|                 // initialise
 | ||||
|                 ESM::CellRef& cellRef = mPtr.getCellRef(); | ||||
|                 cellRef.mRefID = name; | ||||
|                 cellRef.mRefnum = -1; | ||||
|                 cellRef.mRefNum.mIndex = 0; | ||||
|                 cellRef.mRefNum.mContentFile = -1; | ||||
|                 cellRef.mScale = 1; | ||||
|                 cellRef.mFactIndex = 0; | ||||
|                 cellRef.mCharge = -1; | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ void Store<ESM::Cell>::load(ESM::ESMReader &esm, const std::string &id) | |||
|     //  and we merge all this data into one Cell object. However, we can't simply search for the cell id,
 | ||||
|     //  as many exterior cells do not have a name. Instead, we need to search by (x,y) coordinates - and they
 | ||||
|     //  are not available until both cells have been loaded! So first, proceed as usual.
 | ||||
|      | ||||
| 
 | ||||
|     // All cells have a name record, even nameless exterior cells.
 | ||||
|     std::string idLower = Misc::StringUtils::lowerCase(id); | ||||
|     ESM::Cell *cell = new ESM::Cell; | ||||
|  | @ -40,7 +40,7 @@ void Store<ESM::Cell>::load(ESM::ESMReader &esm, const std::string &id) | |||
|         // We should not need to test for duplicates, as this part of the code is pre-cell merge.
 | ||||
|         cell->mMovedRefs.push_back(cMRef); | ||||
|         // But there may be duplicates here!
 | ||||
|         ESM::CellRefTracker::iterator iter = std::find(cellAlt->mLeasedRefs.begin(), cellAlt->mLeasedRefs.end(), ref.mRefnum); | ||||
|         ESM::CellRefTracker::iterator iter = std::find(cellAlt->mLeasedRefs.begin(), cellAlt->mLeasedRefs.end(), ref.mRefNum); | ||||
|         if (iter == cellAlt->mLeasedRefs.end()) | ||||
|           cellAlt->mLeasedRefs.push_back(ref); | ||||
|         else | ||||
|  | @ -76,11 +76,11 @@ void Store<ESM::Cell>::load(ESM::ESMReader &esm, const std::string &id) | |||
|             // merge lists of leased references, use newer data in case of conflict
 | ||||
|             for (ESM::MovedCellRefTracker::const_iterator it = cell->mMovedRefs.begin(); it != cell->mMovedRefs.end(); ++it) { | ||||
|                 // remove reference from current leased ref tracker and add it to new cell
 | ||||
|                 ESM::MovedCellRefTracker::iterator itold = std::find(oldcell->mMovedRefs.begin(), oldcell->mMovedRefs.end(), it->mRefnum); | ||||
|                 ESM::MovedCellRefTracker::iterator itold = std::find(oldcell->mMovedRefs.begin(), oldcell->mMovedRefs.end(), it->mRefNum); | ||||
|                 if (itold != oldcell->mMovedRefs.end()) { | ||||
|                     ESM::MovedCellRef target0 = *itold; | ||||
|                     ESM::Cell *wipecell = const_cast<ESM::Cell*>(search(target0.mTarget[0], target0.mTarget[1])); | ||||
|                     ESM::CellRefTracker::iterator it_lease = std::find(wipecell->mLeasedRefs.begin(), wipecell->mLeasedRefs.end(), it->mRefnum); | ||||
|                     ESM::CellRefTracker::iterator it_lease = std::find(wipecell->mLeasedRefs.begin(), wipecell->mLeasedRefs.end(), it->mRefNum); | ||||
|                     wipecell->mLeasedRefs.erase(it_lease); | ||||
|                     *itold = *it; | ||||
|                 } | ||||
|  |  | |||
|  | @ -5,7 +5,8 @@ | |||
| 
 | ||||
| void ESM::CellRef::save(ESMWriter &esm) const | ||||
| { | ||||
|     esm.writeHNT("FRMR", mRefnum); | ||||
|     esm.writeHNT("FRMR", mRefNum.mIndex); | ||||
|     /// \todo read content file index (if present)
 | ||||
|     esm.writeHNCString("NAME", mRefID); | ||||
| 
 | ||||
|     if (mScale != 1.0) { | ||||
|  | @ -58,7 +59,8 @@ void ESM::CellRef::save(ESMWriter &esm) const | |||
| 
 | ||||
| void ESM::CellRef::blank() | ||||
| { | ||||
|     mRefnum = 0; | ||||
|     mRefNum.mIndex = 0; | ||||
|     mRefNum.mContentFile = -1; | ||||
|     mRefID.clear(); | ||||
|     mScale = 1; | ||||
|     mOwner.clear(); | ||||
|  | @ -84,4 +86,9 @@ void ESM::CellRef::blank() | |||
|         mPos.pos[i] = 0; | ||||
|         mPos.rot[i] = 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool ESM::operator== (const CellRef::RefNum& left, const CellRef::RefNum& right) | ||||
| { | ||||
|     return left.mIndex==right.mIndex && left.mContentFile==right.mContentFile; | ||||
| } | ||||
|  | @ -19,7 +19,13 @@ namespace ESM | |||
|     { | ||||
|         public: | ||||
| 
 | ||||
|             int mRefnum;           // Reference number
 | ||||
|             struct RefNum | ||||
|             { | ||||
|                 int mIndex; | ||||
|                 int mContentFile; // -1 no content file
 | ||||
|             }; | ||||
| 
 | ||||
|             RefNum mRefNum;        // Reference number
 | ||||
|             std::string mRefID;    // ID of object being referenced
 | ||||
| 
 | ||||
|             float mScale;          // Scale applied to mesh
 | ||||
|  | @ -87,6 +93,8 @@ namespace ESM | |||
| 
 | ||||
|             void blank(); | ||||
|     }; | ||||
| 
 | ||||
|     bool operator== (const CellRef::RefNum& left, const CellRef::RefNum& right); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | @ -9,20 +9,42 @@ | |||
| #include "esmwriter.hpp" | ||||
| #include "defs.hpp" | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
|     ///< Translate 8bit/24bit code (stored in refNum.mIndex) into a proper refNum
 | ||||
|     void adjustRefNum (ESM::CellRef::RefNum& refNum, ESM::ESMReader& reader) | ||||
|     { | ||||
|         int local = (refNum.mIndex & 0xff000000) >> 24; | ||||
| 
 | ||||
|         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.
 | ||||
|             refNum.mIndex &= 0x00ffffff; // delete old plugin ID
 | ||||
|             refNum.mContentFile = reader.getGameFiles()[local-1].index; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // This is an addition by the present plugin. Set the corresponding plugin index.
 | ||||
|             refNum.mContentFile = reader.getIndex(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| namespace ESM | ||||
| { | ||||
|     unsigned int Cell::sRecordId = REC_CELL; | ||||
| 
 | ||||
| /// Some overloaded compare operators.
 | ||||
| bool operator==(const MovedCellRef& ref, int pRefnum) | ||||
| { | ||||
|   return (ref.mRefnum == pRefnum); | ||||
| } | ||||
|     // Some overloaded compare operators.
 | ||||
|     bool operator== (const MovedCellRef& ref, const CellRef::RefNum& refNum) | ||||
|     { | ||||
|         return ref.mRefNum == refNum; | ||||
|     } | ||||
| 
 | ||||
| bool operator==(const CellRef& ref, int pRefnum) | ||||
| { | ||||
|   return (ref.mRefnum == pRefnum); | ||||
| } | ||||
|     bool operator== (const CellRef& ref, const CellRef::RefNum& refNum) | ||||
|     { | ||||
|         return ref.mRefNum == refNum; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| void Cell::load(ESMReader &esm, bool saveContext) | ||||
|  | @ -163,49 +185,17 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref) | |||
|         //esm.getHNOT(NAM0, "NAM0");
 | ||||
|     } | ||||
| 
 | ||||
|     esm.getHNT(ref.mRefnum, "FRMR"); | ||||
|     esm.getHNT (ref.mRefNum.mIndex, "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
 | ||||
|     } | ||||
|     adjustRefNum (ref.mRefNum, esm); | ||||
| 
 | ||||
|     // 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"); | ||||
|  | @ -271,16 +261,10 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref) | |||
| 
 | ||||
| bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref) | ||||
| { | ||||
|     esm.getHT(mref.mRefnum); | ||||
|     esm.getHT(mref.mRefNum.mIndex); | ||||
|     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
 | ||||
|     adjustRefNum (mref.mRefNum, esm); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ class ESMWriter; | |||
| class MovedCellRef | ||||
| { | ||||
| public: | ||||
|     int mRefnum; | ||||
|     CellRef::RefNum mRefNum; | ||||
| 
 | ||||
|     // Target cell (if exterior)
 | ||||
|     int mTarget[2]; | ||||
|  | @ -37,9 +37,9 @@ public: | |||
|     //  introduces a henchman (which no one uses), so we may need this as well.
 | ||||
| }; | ||||
| 
 | ||||
| /// Overloaded copare operator used to search inside a list of cell refs.
 | ||||
| bool operator==(const MovedCellRef& ref, int pRefnum); | ||||
| bool operator==(const CellRef& ref, int pRefnum); | ||||
| /// Overloaded compare operator used to search inside a list of cell refs.
 | ||||
| bool operator==(const MovedCellRef& ref, const CellRef::RefNum& refNum); | ||||
| bool operator==(const CellRef& ref, const CellRef::RefNum& refNum); | ||||
| 
 | ||||
| typedef std::list<MovedCellRef> MovedCellRefTracker; | ||||
| typedef std::list<CellRef> CellRefTracker; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue