mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-20 21:41:35 +00:00
Merge branch 'master' into 'touch_my_crank'
# Conflicts: # CHANGELOG.md
This commit is contained in:
commit
3c0a0ba9e1
92 changed files with 341 additions and 128 deletions
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
Bug #3737: Scripts from The Underground 2 .esp do not play (all patched versions)
|
Bug #3737: Scripts from The Underground 2 .esp do not play (all patched versions)
|
||||||
Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes
|
Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes
|
||||||
|
Bug #3905: Great House Dagoth issues
|
||||||
|
Bug #5120: Scripted object spawning updates physics system
|
||||||
Bug #5379: Wandering NPCs falling through cantons
|
Bug #5379: Wandering NPCs falling through cantons
|
||||||
Bug #5453: Magic effect VFX are offset for creatures
|
Bug #5453: Magic effect VFX are offset for creatures
|
||||||
Bug #5483: AutoCalc flag is not used to calculate spells cost
|
Bug #5483: AutoCalc flag is not used to calculate spells cost
|
||||||
|
@ -16,6 +18,7 @@
|
||||||
Bug #6131: Item selection in the avatar window not working correctly for large window sizes
|
Bug #6131: Item selection in the avatar window not working correctly for large window sizes
|
||||||
Bug #6133: Cannot reliably sneak or steal in the sight of the NPCs siding with player
|
Bug #6133: Cannot reliably sneak or steal in the sight of the NPCs siding with player
|
||||||
Feature #5489: MCP: Telekinesis fix for activators
|
Feature #5489: MCP: Telekinesis fix for activators
|
||||||
|
Feature #6017: Separate persistent and temporary cell references when saving
|
||||||
|
|
||||||
0.47.0
|
0.47.0
|
||||||
------
|
------
|
||||||
|
|
|
@ -253,10 +253,71 @@ int CSMDoc::WriteCellCollectionStage::setup()
|
||||||
return mDocument.getData().getCells().getSize();
|
return mDocument.getData().getCells().getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSMDoc::WriteCellCollectionStage::writeReferences (const std::deque<int>& references, bool interior, unsigned int& newRefNum)
|
||||||
|
{
|
||||||
|
ESM::ESMWriter& writer = mState.getWriter();
|
||||||
|
|
||||||
|
for (std::deque<int>::const_iterator iter (references.begin());
|
||||||
|
iter!=references.end(); ++iter)
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<CSMWorld::CellRef>& ref =
|
||||||
|
mDocument.getData().getReferences().getRecord (*iter);
|
||||||
|
|
||||||
|
if (ref.isModified() || ref.mState == CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
CSMWorld::CellRef refRecord = ref.get();
|
||||||
|
|
||||||
|
// Check for uninitialized content file
|
||||||
|
if (!refRecord.mRefNum.hasContentFile())
|
||||||
|
refRecord.mRefNum.mContentFile = 0;
|
||||||
|
|
||||||
|
// recalculate the ref's cell location
|
||||||
|
std::ostringstream stream;
|
||||||
|
if (!interior)
|
||||||
|
{
|
||||||
|
std::pair<int, int> index = refRecord.getCellIndex();
|
||||||
|
stream << "#" << index.first << " " << index.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refRecord.mNew || refRecord.mRefNum.mIndex == 0 ||
|
||||||
|
(!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly &&
|
||||||
|
refRecord.mCell!=stream.str()))
|
||||||
|
{
|
||||||
|
refRecord.mRefNum.mIndex = newRefNum++;
|
||||||
|
}
|
||||||
|
else if ((refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell)
|
||||||
|
!= stream.str() && !interior)
|
||||||
|
{
|
||||||
|
// An empty mOriginalCell is meant to indicate that it is the same as
|
||||||
|
// the current cell. It is possible that a moved ref is moved again.
|
||||||
|
|
||||||
|
ESM::MovedCellRef moved;
|
||||||
|
moved.mRefNum = refRecord.mRefNum;
|
||||||
|
|
||||||
|
// Need to fill mTarget with the ref's new position.
|
||||||
|
std::istringstream istream (stream.str().c_str());
|
||||||
|
|
||||||
|
char ignore;
|
||||||
|
istream >> ignore >> moved.mTarget[0] >> moved.mTarget[1];
|
||||||
|
|
||||||
|
refRecord.mRefNum.save (writer, false, "MVRF");
|
||||||
|
writer.writeHNT ("CNDT", moved.mTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
refRecord.save (writer, false, false, ref.mState == CSMWorld::RecordBase::State_Deleted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
||||||
{
|
{
|
||||||
ESM::ESMWriter& writer = mState.getWriter();
|
ESM::ESMWriter& writer = mState.getWriter();
|
||||||
const CSMWorld::Record<CSMWorld::Cell>& cell = mDocument.getData().getCells().getRecord (stage);
|
const CSMWorld::Record<CSMWorld::Cell>& cell = mDocument.getData().getCells().getRecord (stage);
|
||||||
|
const CSMWorld::RefIdCollection& referenceables = mDocument.getData().getReferenceables();
|
||||||
|
const CSMWorld::RefIdData& refIdData = referenceables.getDataSet();
|
||||||
|
|
||||||
|
std::deque<int> tempRefs;
|
||||||
|
std::deque<int> persistentRefs;
|
||||||
|
|
||||||
std::map<std::string, std::deque<int> >::const_iterator references =
|
std::map<std::string, std::deque<int> >::const_iterator references =
|
||||||
mState.getSubRecords().find (Misc::StringUtils::lowerCase (cell.get().mId));
|
mState.getSubRecords().find (Misc::StringUtils::lowerCase (cell.get().mId));
|
||||||
|
@ -281,6 +342,18 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
||||||
|
|
||||||
CSMWorld::CellRef refRecord = ref.get();
|
CSMWorld::CellRef refRecord = ref.get();
|
||||||
|
|
||||||
|
CSMWorld::RefIdData::LocalIndex localIndex = refIdData.searchId(refRecord.mRefID);
|
||||||
|
unsigned int recordFlags = refIdData.getRecordFlags(refRecord.mRefID);
|
||||||
|
bool isPersistent = ((recordFlags & ESM::FLAG_Persistent) != 0)
|
||||||
|
|| refRecord.mTeleport
|
||||||
|
|| localIndex.second == CSMWorld::UniversalId::Type_Creature
|
||||||
|
|| localIndex.second == CSMWorld::UniversalId::Type_Npc;
|
||||||
|
|
||||||
|
if (isPersistent)
|
||||||
|
persistentRefs.push_back(*iter);
|
||||||
|
else
|
||||||
|
tempRefs.push_back(*iter);
|
||||||
|
|
||||||
if (refRecord.mNew ||
|
if (refRecord.mNew ||
|
||||||
(!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly &&
|
(!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly &&
|
||||||
/// \todo consider worldspace
|
/// \todo consider worldspace
|
||||||
|
@ -289,7 +362,6 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
||||||
|
|
||||||
if (refRecord.mRefNum.mIndex >= newRefNum)
|
if (refRecord.mRefNum.mIndex >= newRefNum)
|
||||||
newRefNum = refRecord.mRefNum.mIndex + 1;
|
newRefNum = refRecord.mRefNum.mIndex + 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,56 +384,9 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
||||||
// write references
|
// write references
|
||||||
if (references!=mState.getSubRecords().end())
|
if (references!=mState.getSubRecords().end())
|
||||||
{
|
{
|
||||||
for (std::deque<int>::const_iterator iter (references->second.begin());
|
writeReferences(persistentRefs, interior, newRefNum);
|
||||||
iter!=references->second.end(); ++iter)
|
cellRecord.saveTempMarker(writer, int(references->second.size()) - persistentRefs.size());
|
||||||
{
|
writeReferences(tempRefs, interior, newRefNum);
|
||||||
const CSMWorld::Record<CSMWorld::CellRef>& ref =
|
|
||||||
mDocument.getData().getReferences().getRecord (*iter);
|
|
||||||
|
|
||||||
if (ref.isModified() || ref.mState == CSMWorld::RecordBase::State_Deleted)
|
|
||||||
{
|
|
||||||
CSMWorld::CellRef refRecord = ref.get();
|
|
||||||
|
|
||||||
// Check for uninitialized content file
|
|
||||||
if (!refRecord.mRefNum.hasContentFile())
|
|
||||||
refRecord.mRefNum.mContentFile = 0;
|
|
||||||
|
|
||||||
// recalculate the ref's cell location
|
|
||||||
std::ostringstream stream;
|
|
||||||
if (!interior)
|
|
||||||
{
|
|
||||||
std::pair<int, int> index = refRecord.getCellIndex();
|
|
||||||
stream << "#" << index.first << " " << index.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refRecord.mNew || refRecord.mRefNum.mIndex == 0 ||
|
|
||||||
(!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly &&
|
|
||||||
refRecord.mCell!=stream.str()))
|
|
||||||
{
|
|
||||||
refRecord.mRefNum.mIndex = newRefNum++;
|
|
||||||
}
|
|
||||||
else if ((refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell)
|
|
||||||
!= stream.str() && !interior)
|
|
||||||
{
|
|
||||||
// An empty mOriginalCell is meant to indicate that it is the same as
|
|
||||||
// the current cell. It is possible that a moved ref is moved again.
|
|
||||||
|
|
||||||
ESM::MovedCellRef moved;
|
|
||||||
moved.mRefNum = refRecord.mRefNum;
|
|
||||||
|
|
||||||
// Need to fill mTarget with the ref's new position.
|
|
||||||
std::istringstream istream (stream.str().c_str());
|
|
||||||
|
|
||||||
char ignore;
|
|
||||||
istream >> ignore >> moved.mTarget[0] >> moved.mTarget[1];
|
|
||||||
|
|
||||||
refRecord.mRefNum.save (writer, false, "MVRF");
|
|
||||||
writer.writeHNT ("CNDT", moved.mTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
refRecord.save (writer, false, false, ref.mState == CSMWorld::RecordBase::State_Deleted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.endRecord (cellRecord.sRecordId);
|
writer.endRecord (cellRecord.sRecordId);
|
||||||
|
|
|
@ -171,6 +171,8 @@ namespace CSMDoc
|
||||||
Document& mDocument;
|
Document& mDocument;
|
||||||
SavingState& mState;
|
SavingState& mState;
|
||||||
|
|
||||||
|
void writeReferences (const std::deque<int>& references, bool interior, unsigned int& newRefNum);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
WriteCellCollectionStage (Document& document, SavingState& state);
|
WriteCellCollectionStage (Document& document, SavingState& state);
|
||||||
|
|
|
@ -294,7 +294,6 @@ namespace CSMWorld
|
||||||
{ ColumnId_NpcReputation, "Reputation" },
|
{ ColumnId_NpcReputation, "Reputation" },
|
||||||
{ ColumnId_NpcRank, "NPC Rank" },
|
{ ColumnId_NpcRank, "NPC Rank" },
|
||||||
{ ColumnId_Gold, "Gold" },
|
{ ColumnId_Gold, "Gold" },
|
||||||
{ ColumnId_NpcPersistence, "Persistent" },
|
|
||||||
|
|
||||||
{ ColumnId_RaceAttributes, "Race Attributes" },
|
{ ColumnId_RaceAttributes, "Race Attributes" },
|
||||||
{ ColumnId_Male, "Male" },
|
{ ColumnId_Male, "Male" },
|
||||||
|
@ -371,6 +370,8 @@ namespace CSMWorld
|
||||||
{ ColumnId_Skill6, "Skill 6" },
|
{ ColumnId_Skill6, "Skill 6" },
|
||||||
{ ColumnId_Skill7, "Skill 7" },
|
{ ColumnId_Skill7, "Skill 7" },
|
||||||
|
|
||||||
|
{ ColumnId_Persistent, "Persistent" },
|
||||||
|
|
||||||
{ -1, 0 } // end marker
|
{ -1, 0 } // end marker
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,7 +280,7 @@ namespace CSMWorld
|
||||||
ColumnId_NpcReputation = 258,
|
ColumnId_NpcReputation = 258,
|
||||||
ColumnId_NpcRank = 259,
|
ColumnId_NpcRank = 259,
|
||||||
ColumnId_Gold = 260,
|
ColumnId_Gold = 260,
|
||||||
ColumnId_NpcPersistence = 261,
|
// unused
|
||||||
|
|
||||||
ColumnId_RaceAttributes = 262,
|
ColumnId_RaceAttributes = 262,
|
||||||
ColumnId_Male = 263,
|
ColumnId_Male = 263,
|
||||||
|
@ -343,6 +343,8 @@ namespace CSMWorld
|
||||||
ColumnId_FactionAttrib1 = 311,
|
ColumnId_FactionAttrib1 = 311,
|
||||||
ColumnId_FactionAttrib2 = 312,
|
ColumnId_FactionAttrib2 = 312,
|
||||||
|
|
||||||
|
ColumnId_Persistent = 313,
|
||||||
|
|
||||||
// Allocated to a separate value range, so we don't get a collision should we ever need
|
// Allocated to a separate value range, so we don't get a collision should we ever need
|
||||||
// to extend the number of use values.
|
// to extend the number of use values.
|
||||||
ColumnId_UseValue1 = 0x10000,
|
ColumnId_UseValue1 = 0x10000,
|
||||||
|
|
|
@ -1108,7 +1108,6 @@ QVariant CSMWorld::NpcMiscRefIdAdapter::getNestedData (const RefIdColumn *column
|
||||||
case 5: return static_cast<int>(record.get().mNpdt.mReputation);
|
case 5: return static_cast<int>(record.get().mNpdt.mReputation);
|
||||||
case 6: return static_cast<int>(record.get().mNpdt.mRank);
|
case 6: return static_cast<int>(record.get().mNpdt.mRank);
|
||||||
case 7: return record.get().mNpdt.mGold;
|
case 7: return record.get().mNpdt.mGold;
|
||||||
case 8: return record.get().mPersistent == true;
|
|
||||||
default: return QVariant(); // throw an exception here?
|
default: return QVariant(); // throw an exception here?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1122,7 +1121,6 @@ QVariant CSMWorld::NpcMiscRefIdAdapter::getNestedData (const RefIdColumn *column
|
||||||
case 5: return static_cast<int>(record.get().mNpdt.mReputation);
|
case 5: return static_cast<int>(record.get().mNpdt.mReputation);
|
||||||
case 6: return static_cast<int>(record.get().mNpdt.mRank);
|
case 6: return static_cast<int>(record.get().mNpdt.mRank);
|
||||||
case 7: return record.get().mNpdt.mGold;
|
case 7: return record.get().mNpdt.mGold;
|
||||||
case 8: return record.get().mPersistent == true;
|
|
||||||
default: return QVariant(); // throw an exception here?
|
default: return QVariant(); // throw an exception here?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1147,7 +1145,6 @@ void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column,
|
||||||
case 5: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
|
case 5: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
|
||||||
case 6: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
|
case 6: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
|
||||||
case 7: npc.mNpdt.mGold = value.toInt(); break;
|
case 7: npc.mNpdt.mGold = value.toInt(); break;
|
||||||
case 8: npc.mPersistent = value.toBool(); break;
|
|
||||||
default: return; // throw an exception here?
|
default: return; // throw an exception here?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1161,7 +1158,6 @@ void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column,
|
||||||
case 5: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
|
case 5: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
|
||||||
case 6: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
|
case 6: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
|
||||||
case 7: npc.mNpdt.mGold = value.toInt(); break;
|
case 7: npc.mNpdt.mGold = value.toInt(); break;
|
||||||
case 8: npc.mPersistent = value.toBool(); break;
|
|
||||||
default: return; // throw an exception here?
|
default: return; // throw an exception here?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1170,7 +1166,7 @@ void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column,
|
||||||
|
|
||||||
int CSMWorld::NpcMiscRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
|
int CSMWorld::NpcMiscRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
|
||||||
{
|
{
|
||||||
return 9; // Level, Health, Mana, Fatigue, Disposition, Reputation, Rank, Gold, Persist
|
return 8; // Level, Health, Mana, Fatigue, Disposition, Reputation, Rank, Gold
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSMWorld::NpcMiscRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
|
int CSMWorld::NpcMiscRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
|
||||||
|
|
|
@ -114,8 +114,9 @@ namespace CSMWorld
|
||||||
struct ModelColumns : public BaseColumns
|
struct ModelColumns : public BaseColumns
|
||||||
{
|
{
|
||||||
const RefIdColumn *mModel;
|
const RefIdColumn *mModel;
|
||||||
|
const RefIdColumn *mPersistence;
|
||||||
|
|
||||||
ModelColumns (const BaseColumns& base) : BaseColumns (base), mModel(nullptr) {}
|
ModelColumns (const BaseColumns& base) : BaseColumns (base), mModel(nullptr), mPersistence(nullptr) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Adapter for IDs with models (all but levelled lists)
|
/// \brief Adapter for IDs with models (all but levelled lists)
|
||||||
|
@ -151,6 +152,9 @@ namespace CSMWorld
|
||||||
if (column==mModel.mModel)
|
if (column==mModel.mModel)
|
||||||
return QString::fromUtf8 (record.get().mModel.c_str());
|
return QString::fromUtf8 (record.get().mModel.c_str());
|
||||||
|
|
||||||
|
if (column==mModel.mPersistence)
|
||||||
|
return (record.get().mRecordFlags & ESM::FLAG_Persistent) != 0;
|
||||||
|
|
||||||
return BaseRefIdAdapter<RecordT>::getData (column, data, index);
|
return BaseRefIdAdapter<RecordT>::getData (column, data, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,6 +168,13 @@ namespace CSMWorld
|
||||||
RecordT record2 = record.get();
|
RecordT record2 = record.get();
|
||||||
if (column==mModel.mModel)
|
if (column==mModel.mModel)
|
||||||
record2.mModel = value.toString().toUtf8().constData();
|
record2.mModel = value.toString().toUtf8().constData();
|
||||||
|
else if (column==mModel.mPersistence)
|
||||||
|
{
|
||||||
|
if (value.toInt() != 0)
|
||||||
|
record2.mRecordFlags |= ESM::FLAG_Persistent;
|
||||||
|
else
|
||||||
|
record2.mRecordFlags &= ~ESM::FLAG_Persistent;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BaseRefIdAdapter<RecordT>::setData (column, data, index, value);
|
BaseRefIdAdapter<RecordT>::setData (column, data, index, value);
|
||||||
|
|
|
@ -54,6 +54,8 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
||||||
|
|
||||||
mColumns.emplace_back(Columns::ColumnId_Model, ColumnBase::Display_Mesh);
|
mColumns.emplace_back(Columns::ColumnId_Model, ColumnBase::Display_Mesh);
|
||||||
modelColumns.mModel = &mColumns.back();
|
modelColumns.mModel = &mColumns.back();
|
||||||
|
mColumns.emplace_back(Columns::ColumnId_Persistent, ColumnBase::Display_Boolean);
|
||||||
|
modelColumns.mPersistence = &mColumns.back();
|
||||||
|
|
||||||
NameColumns nameColumns (modelColumns);
|
NameColumns nameColumns (modelColumns);
|
||||||
|
|
||||||
|
@ -549,8 +551,6 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
||||||
new RefIdColumn (Columns::ColumnId_NpcRank, CSMWorld::ColumnBase::Display_UnsignedInteger8));
|
new RefIdColumn (Columns::ColumnId_NpcRank, CSMWorld::ColumnBase::Display_UnsignedInteger8));
|
||||||
mColumns.back().addColumn(
|
mColumns.back().addColumn(
|
||||||
new RefIdColumn (Columns::ColumnId_Gold, CSMWorld::ColumnBase::Display_Integer));
|
new RefIdColumn (Columns::ColumnId_Gold, CSMWorld::ColumnBase::Display_Integer));
|
||||||
mColumns.back().addColumn(
|
|
||||||
new RefIdColumn (Columns::ColumnId_NpcPersistence, CSMWorld::ColumnBase::Display_Boolean));
|
|
||||||
|
|
||||||
WeaponColumns weaponColumns (enchantableColumns);
|
WeaponColumns weaponColumns (enchantableColumns);
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,39 @@ CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId (
|
||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int CSMWorld::RefIdData::getRecordFlags (const std::string& id) const
|
||||||
|
{
|
||||||
|
LocalIndex localIndex = searchId (id);
|
||||||
|
|
||||||
|
switch (localIndex.second)
|
||||||
|
{
|
||||||
|
case UniversalId::Type_Activator: return mActivators.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Potion: return mPotions.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Apparatus: return mApparati.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Armor: return mArmors.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Book: return mBooks.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Clothing: return mClothing.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Container: return mContainers.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Creature: return mCreatures.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Door: return mDoors.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Ingredient: return mIngredients.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_CreatureLevelledList: return mCreatureLevelledLists.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_ItemLevelledList: return mItemLevelledLists.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Light: return mLights.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Lockpick: return mLockpicks.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Miscellaneous: return mMiscellaneous.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Npc: return mNpcs.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Probe: return mProbes.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Repair: return mRepairs.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Static: return mStatics.getRecordFlags(localIndex.first);
|
||||||
|
case UniversalId::Type_Weapon: return mWeapons.getRecordFlags(localIndex.first);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void CSMWorld::RefIdData::erase (int index, int count)
|
void CSMWorld::RefIdData::erase (int index, int count)
|
||||||
{
|
{
|
||||||
LocalIndex localIndex = globalToLocalIndex (index);
|
LocalIndex localIndex = globalToLocalIndex (index);
|
||||||
|
|
|
@ -47,6 +47,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
virtual RecordBase& getRecord (int index)= 0;
|
virtual RecordBase& getRecord (int index)= 0;
|
||||||
|
|
||||||
|
virtual unsigned int getRecordFlags (int index) const = 0;
|
||||||
|
|
||||||
virtual void appendRecord (const std::string& id, bool base) = 0;
|
virtual void appendRecord (const std::string& id, bool base) = 0;
|
||||||
|
|
||||||
virtual void insertRecord (RecordBase& record) = 0;
|
virtual void insertRecord (RecordBase& record) = 0;
|
||||||
|
@ -72,6 +74,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
RecordBase& getRecord (int index) override;
|
RecordBase& getRecord (int index) override;
|
||||||
|
|
||||||
|
unsigned int getRecordFlags (int index) const override;
|
||||||
|
|
||||||
void appendRecord (const std::string& id, bool base) override;
|
void appendRecord (const std::string& id, bool base) override;
|
||||||
|
|
||||||
void insertRecord (RecordBase& record) override;
|
void insertRecord (RecordBase& record) override;
|
||||||
|
@ -111,6 +115,12 @@ namespace CSMWorld
|
||||||
return mContainer.at (index);
|
return mContainer.at (index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename RecordT>
|
||||||
|
unsigned int RefIdDataContainer<RecordT>::getRecordFlags (int index) const
|
||||||
|
{
|
||||||
|
return mContainer.at (index).get().mRecordFlags;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename RecordT>
|
template<typename RecordT>
|
||||||
void RefIdDataContainer<RecordT>::appendRecord (const std::string& id, bool base)
|
void RefIdDataContainer<RecordT>::appendRecord (const std::string& id, bool base)
|
||||||
{
|
{
|
||||||
|
@ -209,7 +219,7 @@ namespace CSMWorld
|
||||||
if (record.isModified() || record.mState == RecordBase::State_Deleted)
|
if (record.isModified() || record.mState == RecordBase::State_Deleted)
|
||||||
{
|
{
|
||||||
RecordT esmRecord = record.get();
|
RecordT esmRecord = record.get();
|
||||||
writer.startRecord(esmRecord.sRecordId);
|
writer.startRecord(esmRecord.sRecordId, esmRecord.mRecordFlags);
|
||||||
esmRecord.save(writer, record.mState == RecordBase::State_Deleted);
|
esmRecord.save(writer, record.mState == RecordBase::State_Deleted);
|
||||||
writer.endRecord(esmRecord.sRecordId);
|
writer.endRecord(esmRecord.sRecordId);
|
||||||
}
|
}
|
||||||
|
@ -273,6 +283,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
RecordBase& getRecord (const LocalIndex& index);
|
RecordBase& getRecord (const LocalIndex& index);
|
||||||
|
|
||||||
|
unsigned int getRecordFlags(const std::string& id) const;
|
||||||
|
|
||||||
void appendRecord (UniversalId::Type type, const std::string& id, bool base);
|
void appendRecord (UniversalId::Type type, const std::string& id, bool base);
|
||||||
|
|
||||||
int getAppendIndex (UniversalId::Type type) const;
|
int getAppendIndex (UniversalId::Type type) const;
|
||||||
|
|
|
@ -39,6 +39,11 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
||||||
|
{
|
||||||
|
insertObjectPhysics(ptr, model, rotation, physics, skipAnimated);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activator::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
||||||
{
|
{
|
||||||
if(!model.empty())
|
if(!model.empty())
|
||||||
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated);
|
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated);
|
||||||
|
|
|
@ -19,6 +19,8 @@ namespace MWClass
|
||||||
|
|
||||||
void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
||||||
|
|
||||||
|
void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const override;
|
||||||
|
|
||||||
std::string getName (const MWWorld::ConstPtr& ptr) const override;
|
std::string getName (const MWWorld::ConstPtr& ptr) const override;
|
||||||
///< \return name or ID; can return an empty string.
|
///< \return name or ID; can return an empty string.
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,11 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
||||||
|
{
|
||||||
|
insertObjectPhysics(ptr, model, rotation, physics, skipAnimated);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Container::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
||||||
{
|
{
|
||||||
if(!model.empty())
|
if(!model.empty())
|
||||||
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated);
|
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated);
|
||||||
|
|
|
@ -43,6 +43,7 @@ namespace MWClass
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
||||||
|
void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
||||||
|
|
||||||
std::string getName (const MWWorld::ConstPtr& ptr) const override;
|
std::string getName (const MWWorld::ConstPtr& ptr) const override;
|
||||||
///< \return name or ID; can return an empty string.
|
///< \return name or ID; can return an empty string.
|
||||||
|
|
|
@ -588,7 +588,7 @@ namespace MWClass
|
||||||
bool Creature::isPersistent(const MWWorld::ConstPtr &actor) const
|
bool Creature::isPersistent(const MWWorld::ConstPtr &actor) const
|
||||||
{
|
{
|
||||||
const MWWorld::LiveCellRef<ESM::Creature>* ref = actor.get<ESM::Creature>();
|
const MWWorld::LiveCellRef<ESM::Creature>* ref = actor.get<ESM::Creature>();
|
||||||
return ref->mBase->mPersistent;
|
return (ref->mBase->mRecordFlags & ESM::FLAG_Persistent) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Creature::getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const
|
std::string Creature::getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const
|
||||||
|
|
|
@ -57,8 +57,7 @@ namespace MWClass
|
||||||
|
|
||||||
void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
||||||
{
|
{
|
||||||
if(!model.empty())
|
insertObjectPhysics(ptr, model, rotation, physics, skipAnimated);
|
||||||
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_Door, skipAnimated);
|
|
||||||
|
|
||||||
// Resume the door's opening/closing animation if it wasn't finished
|
// Resume the door's opening/closing animation if it wasn't finished
|
||||||
if (ptr.getRefData().getCustomData())
|
if (ptr.getRefData().getCustomData())
|
||||||
|
@ -71,6 +70,12 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Door::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
||||||
|
{
|
||||||
|
if(!model.empty())
|
||||||
|
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_Door, skipAnimated);
|
||||||
|
}
|
||||||
|
|
||||||
bool Door::isDoor() const
|
bool Door::isDoor() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace MWClass
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
||||||
|
void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
||||||
|
|
||||||
bool isDoor() const override;
|
bool isDoor() const override;
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,7 @@ namespace MWClass
|
||||||
ptr.get<ESM::Light>();
|
ptr.get<ESM::Light>();
|
||||||
assert (ref->mBase != nullptr);
|
assert (ref->mBase != nullptr);
|
||||||
|
|
||||||
// TODO: add option somewhere to enable collision for placeable objects
|
insertObjectPhysics(ptr, model, rotation, physics, skipAnimated);
|
||||||
if (!model.empty() && (ref->mBase->mData.mFlags & ESM::Light::Carry) == 0)
|
|
||||||
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated);
|
|
||||||
|
|
||||||
if (!ref->mBase->mSound.empty() && !(ref->mBase->mData.mFlags & ESM::Light::OffDefault))
|
if (!ref->mBase->mSound.empty() && !(ref->mBase->mData.mFlags & ESM::Light::OffDefault))
|
||||||
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0,
|
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0,
|
||||||
|
@ -49,6 +47,13 @@ namespace MWClass
|
||||||
MWSound::PlayMode::Loop);
|
MWSound::PlayMode::Loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Light::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
||||||
|
{
|
||||||
|
// TODO: add option somewhere to enable collision for placeable objects
|
||||||
|
if (!model.empty() && (ptr.get<ESM::Light>()->mBase->mData.mFlags & ESM::Light::Carry) == 0)
|
||||||
|
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated);
|
||||||
|
}
|
||||||
|
|
||||||
bool Light::useAnim() const
|
bool Light::useAnim() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace MWClass
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
||||||
|
void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
||||||
|
|
||||||
bool useAnim() const override;
|
bool useAnim() const override;
|
||||||
|
|
||||||
|
|
|
@ -403,7 +403,7 @@ namespace MWClass
|
||||||
bool Npc::isPersistent(const MWWorld::ConstPtr &actor) const
|
bool Npc::isPersistent(const MWWorld::ConstPtr &actor) const
|
||||||
{
|
{
|
||||||
const MWWorld::LiveCellRef<ESM::NPC>* ref = actor.get<ESM::NPC>();
|
const MWWorld::LiveCellRef<ESM::NPC>* ref = actor.get<ESM::NPC>();
|
||||||
return ref->mBase->mPersistent;
|
return (ref->mBase->mRecordFlags & ESM::FLAG_Persistent) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Npc::getModel(const MWWorld::ConstPtr &ptr) const
|
std::string Npc::getModel(const MWWorld::ConstPtr &ptr) const
|
||||||
|
|
|
@ -24,6 +24,11 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
void Static::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
void Static::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
||||||
|
{
|
||||||
|
insertObjectPhysics(ptr, model, rotation, physics, skipAnimated);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Static::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
||||||
{
|
{
|
||||||
if(!model.empty())
|
if(!model.empty())
|
||||||
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated);
|
physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated);
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace MWClass
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
||||||
|
void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override;
|
||||||
|
|
||||||
std::string getName (const MWWorld::ConstPtr& ptr) const override;
|
std::string getName (const MWWorld::ConstPtr& ptr) const override;
|
||||||
///< \return name or ID; can return an empty string.
|
///< \return name or ID; can return an empty string.
|
||||||
|
|
|
@ -463,6 +463,8 @@ namespace MWPhysics
|
||||||
|
|
||||||
void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType, bool skipAnimated)
|
void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType, bool skipAnimated)
|
||||||
{
|
{
|
||||||
|
if (ptr.mRef->mData.mPhysicsPostponed)
|
||||||
|
return;
|
||||||
osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance = mShapeManager->getInstance(mesh);
|
osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance = mShapeManager->getInstance(mesh);
|
||||||
if (!shapeInstance || !shapeInstance->getCollisionShape())
|
if (!shapeInstance || !shapeInstance->getCollisionShape())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -168,6 +168,8 @@ namespace MWScript
|
||||||
void execute (Interpreter::Runtime& runtime) override
|
void execute (Interpreter::Runtime& runtime) override
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
if(!ptr.isEmpty() && !ptr.mRef->mData.isEnabled())
|
||||||
|
ptr.mRef->mData.mPhysicsPostponed = false;
|
||||||
MWBase::Environment::get().getWorld()->enable (ptr);
|
MWBase::Environment::get().getWorld()->enable (ptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,10 +42,19 @@ namespace MWScript
|
||||||
|
|
||||||
void execute (Interpreter::Runtime& runtime) override
|
void execute (Interpreter::Runtime& runtime) override
|
||||||
{
|
{
|
||||||
MWWorld::Ptr from = R()(runtime);
|
MWWorld::Ptr from = R()(runtime, !R::implicit);
|
||||||
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
|
if (from.isEmpty())
|
||||||
|
{
|
||||||
|
std::string error = "Missing implicit ref";
|
||||||
|
runtime.getContext().report(error);
|
||||||
|
Log(Debug::Error) << error;
|
||||||
|
runtime.push(0.f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (from.getContainerStore()) // is the object contained?
|
if (from.getContainerStore()) // is the object contained?
|
||||||
{
|
{
|
||||||
MWWorld::Ptr container = MWBase::Environment::get().getWorld()->findContainer(from);
|
MWWorld::Ptr container = MWBase::Environment::get().getWorld()->findContainer(from);
|
||||||
|
@ -501,6 +510,7 @@ namespace MWScript
|
||||||
pos.rot[0] = pos.rot[1] = 0;
|
pos.rot[0] = pos.rot[1] = 0;
|
||||||
pos.rot[2] = osg::DegreesToRadians(zRotDegrees);
|
pos.rot[2] = osg::DegreesToRadians(zRotDegrees);
|
||||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID);
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID);
|
||||||
|
ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor();
|
||||||
ref.getPtr().getCellRef().setPosition(pos);
|
ref.getPtr().getCellRef().setPosition(pos);
|
||||||
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(),store,pos);
|
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(),store,pos);
|
||||||
placed.getClass().adjustPosition(placed, true);
|
placed.getClass().adjustPosition(placed, true);
|
||||||
|
@ -548,6 +558,7 @@ namespace MWScript
|
||||||
pos.rot[0] = pos.rot[1] = 0;
|
pos.rot[0] = pos.rot[1] = 0;
|
||||||
pos.rot[2] = osg::DegreesToRadians(zRotDegrees);
|
pos.rot[2] = osg::DegreesToRadians(zRotDegrees);
|
||||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID);
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID);
|
||||||
|
ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor();
|
||||||
ref.getPtr().getCellRef().setPosition(pos);
|
ref.getPtr().getCellRef().setPosition(pos);
|
||||||
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(),store,pos);
|
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(),store,pos);
|
||||||
placed.getClass().adjustPosition(placed, true);
|
placed.getClass().adjustPosition(placed, true);
|
||||||
|
@ -588,6 +599,7 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
// create item
|
// create item
|
||||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID, 1);
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID, 1);
|
||||||
|
ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor();
|
||||||
|
|
||||||
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), actor, actor.getCell(), direction, distance);
|
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), actor, actor.getCell(), direction, distance);
|
||||||
MWBase::Environment::get().getWorld()->scaleObject(ptr, actor.getCellRef().getScale());
|
MWBase::Environment::get().getWorld()->scaleObject(ptr, actor.getCellRef().getScale());
|
||||||
|
|
|
@ -610,9 +610,17 @@ namespace MWWorld
|
||||||
ref.mRefNum.mContentFile = ESM::RefNum::RefNum_NoContentFile;
|
ref.mRefNum.mContentFile = ESM::RefNum::RefNum_NoContentFile;
|
||||||
|
|
||||||
// Get each reference in turn
|
// Get each reference in turn
|
||||||
|
ESM::MovedCellRef cMRef;
|
||||||
|
cMRef.mRefNum.mIndex = 0;
|
||||||
bool deleted = false;
|
bool deleted = false;
|
||||||
while(mCell->getNextRef(esm[index], ref, deleted))
|
while(mCell->getNextRef(esm[index], ref, deleted, /*ignoreMoves*/true, &cMRef))
|
||||||
{
|
{
|
||||||
|
if (cMRef.mRefNum.mIndex)
|
||||||
|
{
|
||||||
|
cMRef.mRefNum.mIndex = 0;
|
||||||
|
continue; // ignore refs that are moved
|
||||||
|
}
|
||||||
|
|
||||||
// Don't load reference if it was moved to a different cell.
|
// Don't load reference if it was moved to a different cell.
|
||||||
ESM::MovedCellRefTracker::const_iterator iter =
|
ESM::MovedCellRefTracker::const_iterator iter =
|
||||||
std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefNum);
|
std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefNum);
|
||||||
|
|
|
@ -35,6 +35,9 @@ namespace MWWorld
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Class::insertObjectPhysics(const Ptr& ptr, const std::string& mesh, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const
|
||||||
|
{}
|
||||||
|
|
||||||
bool Class::apply (const MWWorld::Ptr& ptr, const std::string& id, const MWWorld::Ptr& actor) const
|
bool Class::apply (const MWWorld::Ptr& ptr, const std::string& id, const MWWorld::Ptr& actor) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -80,6 +80,7 @@ namespace MWWorld
|
||||||
virtual void insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
virtual void insertObject(const Ptr& ptr, const std::string& mesh, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const;
|
virtual void insertObject(const Ptr& ptr, const std::string& mesh, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const;
|
||||||
///< Add reference into a cell for rendering (default implementation: don't render anything).
|
///< Add reference into a cell for rendering (default implementation: don't render anything).
|
||||||
|
virtual void insertObjectPhysics(const Ptr& ptr, const std::string& mesh, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const;
|
||||||
|
|
||||||
virtual std::string getName (const ConstPtr& ptr) const = 0;
|
virtual std::string getName (const ConstPtr& ptr) const = 0;
|
||||||
///< \return name or ID; can return an empty string.
|
///< \return name or ID; can return an empty string.
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace MWWorld
|
||||||
mChanged = refData.mChanged;
|
mChanged = refData.mChanged;
|
||||||
mDeletedByContentFile = refData.mDeletedByContentFile;
|
mDeletedByContentFile = refData.mDeletedByContentFile;
|
||||||
mFlags = refData.mFlags;
|
mFlags = refData.mFlags;
|
||||||
|
mPhysicsPostponed = refData.mPhysicsPostponed;
|
||||||
|
|
||||||
mAnimationState = refData.mAnimationState;
|
mAnimationState = refData.mAnimationState;
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
RefData::RefData()
|
RefData::RefData()
|
||||||
: mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true), mCount (1), mCustomData (nullptr), mChanged(false), mFlags(0)
|
: mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true), mCount (1), mCustomData (nullptr), mChanged(false), mFlags(0), mPhysicsPostponed(false)
|
||||||
{
|
{
|
||||||
for (int i=0; i<3; ++i)
|
for (int i=0; i<3; ++i)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +58,7 @@ namespace MWWorld
|
||||||
: mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true),
|
: mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true),
|
||||||
mCount (1), mPosition (cellRef.mPos),
|
mCount (1), mPosition (cellRef.mPos),
|
||||||
mCustomData (nullptr),
|
mCustomData (nullptr),
|
||||||
mChanged(false), mFlags(0) // Loading from ESM/ESP files -> assume unchanged
|
mChanged(false), mFlags(0), mPhysicsPostponed(false) // Loading from ESM/ESP files -> assume unchanged
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ namespace MWWorld
|
||||||
mPosition (objectState.mPosition),
|
mPosition (objectState.mPosition),
|
||||||
mAnimationState(objectState.mAnimationState),
|
mAnimationState(objectState.mAnimationState),
|
||||||
mCustomData (nullptr),
|
mCustomData (nullptr),
|
||||||
mChanged(true), mFlags(objectState.mFlags) // Loading from a savegame -> assume changed
|
mChanged(true), mFlags(objectState.mFlags), mPhysicsPostponed(false) // Loading from a savegame -> assume changed
|
||||||
{
|
{
|
||||||
// "Note that the ActivationFlag_UseEnabled is saved to the reference,
|
// "Note that the ActivationFlag_UseEnabled is saved to the reference,
|
||||||
// which will result in permanently suppressed activation if the reference script is removed.
|
// which will result in permanently suppressed activation if the reference script is removed.
|
||||||
|
|
|
@ -58,6 +58,8 @@ namespace MWWorld
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
bool mPhysicsPostponed;
|
||||||
|
|
||||||
RefData();
|
RefData();
|
||||||
|
|
||||||
/// @param cellRef Used to copy constant data such as position into this class where it can
|
/// @param cellRef Used to copy constant data such as position into this class where it can
|
||||||
|
|
|
@ -343,7 +343,10 @@ namespace MWWorld
|
||||||
|
|
||||||
cell->forEach(visitor);
|
cell->forEach(visitor);
|
||||||
for (const auto& ptr : visitor.mObjects)
|
for (const auto& ptr : visitor.mObjects)
|
||||||
|
{
|
||||||
mPhysics->remove(ptr);
|
mPhysics->remove(ptr);
|
||||||
|
ptr.mRef->mData.mPhysicsPostponed = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (cell->getCell()->isExterior())
|
if (cell->getCell()->isExterior())
|
||||||
{
|
{
|
||||||
|
@ -626,6 +629,24 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
return cellsPositionsToLoad;
|
return cellsPositionsToLoad;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for(const auto& cell : mActiveCells)
|
||||||
|
{
|
||||||
|
cell->forEach([&](const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
if(ptr.mRef->mData.mPhysicsPostponed)
|
||||||
|
{
|
||||||
|
ptr.mRef->mData.mPhysicsPostponed = false;
|
||||||
|
if(ptr.mRef->mData.isEnabled() && ptr.mRef->mData.getCount() > 0) {
|
||||||
|
std::string model = getModel(ptr, MWBase::Environment::get().getResourceSystem()->getVFS());
|
||||||
|
const auto rotation = makeNodeRotation(ptr, RotationOrder::direct);
|
||||||
|
ptr.getClass().insertObjectPhysics(ptr, model, rotation, *mPhysics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
auto cellsPositionsToLoad = cellsToLoad(mActiveCells,mHalfGridSize);
|
auto cellsPositionsToLoad = cellsToLoad(mActiveCells,mHalfGridSize);
|
||||||
auto cellsPositionsToLoadInactive = cellsToLoad(mInactiveCells,mHalfGridSize+1);
|
auto cellsPositionsToLoadInactive = cellsToLoad(mInactiveCells,mHalfGridSize+1);
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,10 @@ void ESM::CellRef::loadData(ESMReader &esm, bool &isDeleted)
|
||||||
esm.getHT(mPos, 24);
|
esm.getHT(mPos, 24);
|
||||||
break;
|
break;
|
||||||
case ESM::FourCC<'N','A','M','0'>::value:
|
case ESM::FourCC<'N','A','M','0'>::value:
|
||||||
|
{
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ESM::SREC_DELE:
|
case ESM::SREC_DELE:
|
||||||
esm.skipHSub();
|
esm.skipHSub();
|
||||||
isDeleted = true;
|
isDeleted = true;
|
||||||
|
@ -145,7 +147,7 @@ void ESM::CellRef::save (ESMWriter &esm, bool wideRefNum, bool inInventory, bool
|
||||||
esm.writeHNCString("NAME", mRefID);
|
esm.writeHNCString("NAME", mRefID);
|
||||||
|
|
||||||
if (isDeleted) {
|
if (isDeleted) {
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ void ESM::DebugProfile::save (ESMWriter& esm, bool isDeleted) const
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,11 @@ enum Version
|
||||||
VER_13 = 0x3fa66666
|
VER_13 = 0x3fa66666
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum RecordFlag
|
||||||
|
{
|
||||||
|
FLAG_Persistent = 0x00000400,
|
||||||
|
FLAG_Blocked = 0x00002000
|
||||||
|
};
|
||||||
|
|
||||||
// CRTP for FIXED_STRING class, a structure used for holding fixed-length strings
|
// CRTP for FIXED_STRING class, a structure used for holding fixed-length strings
|
||||||
template< template<size_t> class DERIVED, size_t SIZE>
|
template< template<size_t> class DERIVED, size_t SIZE>
|
||||||
|
|
|
@ -42,7 +42,7 @@ void ESM::Filter::save (ESMWriter& esm, bool isDeleted) const
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Activator::load(ESMReader &esm, bool &isDeleted)
|
void Activator::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
while (esm.hasMoreSubs())
|
while (esm.hasMoreSubs())
|
||||||
|
@ -50,7 +51,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ struct Activator
|
||||||
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
static std::string getRecordType() { return "Activator"; }
|
static std::string getRecordType() { return "Activator"; }
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mScript, mModel;
|
std::string mId, mName, mScript, mModel;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Potion::load(ESMReader &esm, bool &isDeleted)
|
void Potion::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
mEffects.mList.clear();
|
mEffects.mList.clear();
|
||||||
|
|
||||||
|
@ -65,7 +66,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct Potion
|
||||||
};
|
};
|
||||||
ALDTstruct mData;
|
ALDTstruct mData;
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mIcon, mScript;
|
std::string mId, mName, mModel, mIcon, mScript;
|
||||||
EffectList mEffects;
|
EffectList mEffects;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Apparatus::load(ESMReader &esm, bool &isDeleted)
|
void Apparatus::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
|
@ -61,7 +62,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ struct Apparatus
|
||||||
};
|
};
|
||||||
|
|
||||||
AADTstruct mData;
|
AADTstruct mData;
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mModel, mIcon, mScript, mName;
|
std::string mId, mModel, mIcon, mScript, mName;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace ESM
|
||||||
void Armor::load(ESMReader &esm, bool &isDeleted)
|
void Armor::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
mParts.mParts.clear();
|
mParts.mParts.clear();
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ struct Armor
|
||||||
AODTstruct mData;
|
AODTstruct mData;
|
||||||
PartReferenceList mParts;
|
PartReferenceList mParts;
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mIcon, mScript, mEnchant;
|
std::string mId, mName, mModel, mIcon, mScript, mEnchant;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Book::load(ESMReader &esm, bool &isDeleted)
|
void Book::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
|
@ -66,7 +67,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct Book
|
||||||
|
|
||||||
BKDTstruct mData;
|
BKDTstruct mData;
|
||||||
std::string mName, mModel, mIcon, mScript, mEnchant, mText;
|
std::string mName, mModel, mIcon, mScript, mEnchant, mText;
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
esm.writeHNOCString("FNAM", mName);
|
esm.writeHNOCString("FNAM", mName);
|
||||||
|
|
|
@ -146,7 +146,7 @@ namespace ESM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (saveContext)
|
if (saveContext)
|
||||||
{
|
{
|
||||||
mContextList.push_back(esm.getContext());
|
mContextList.push_back(esm.getContext());
|
||||||
esm.skipRecord();
|
esm.skipRecord();
|
||||||
|
@ -167,7 +167,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,9 +197,12 @@ namespace ESM
|
||||||
if (mMapColor != 0)
|
if (mMapColor != 0)
|
||||||
esm.writeHNT("NAM5", mMapColor);
|
esm.writeHNT("NAM5", mMapColor);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mRefNumCounter != 0)
|
void Cell::saveTempMarker(ESMWriter &esm, int tempCount) const
|
||||||
esm.writeHNT("NAM0", mRefNumCounter);
|
{
|
||||||
|
if (tempCount != 0)
|
||||||
|
esm.writeHNT("NAM0", tempCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cell::restore(ESMReader &esm, int iCtx) const
|
void Cell::restore(ESMReader &esm, int iCtx) const
|
||||||
|
@ -251,6 +254,8 @@ namespace ESM
|
||||||
{
|
{
|
||||||
ref.load (esm, isDeleted);
|
ref.load (esm, isDeleted);
|
||||||
|
|
||||||
|
// TODO: should count the number of temp refs and validate the number
|
||||||
|
|
||||||
// Identify references belonging to a parent file and adapt the ID accordingly.
|
// Identify references belonging to a parent file and adapt the ID accordingly.
|
||||||
adjustRefNum (ref.mRefNum, esm);
|
adjustRefNum (ref.mRefNum, esm);
|
||||||
return true;
|
return true;
|
||||||
|
@ -275,7 +280,7 @@ namespace ESM
|
||||||
mWater = 0;
|
mWater = 0;
|
||||||
mWaterInt = false;
|
mWaterInt = false;
|
||||||
mMapColor = 0;
|
mMapColor = 0;
|
||||||
mRefNumCounter = 0;
|
mRefNumCounter = -1;
|
||||||
|
|
||||||
mData.mFlags = 0;
|
mData.mFlags = 0;
|
||||||
mData.mX = 0;
|
mData.mX = 0;
|
||||||
|
|
|
@ -94,7 +94,7 @@ struct Cell
|
||||||
mWater(0),
|
mWater(0),
|
||||||
mWaterInt(false),
|
mWaterInt(false),
|
||||||
mMapColor(0),
|
mMapColor(0),
|
||||||
mRefNumCounter(0)
|
mRefNumCounter(-1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Interior cells are indexed by this (it's the 'id'), for exterior
|
// Interior cells are indexed by this (it's the 'id'), for exterior
|
||||||
|
@ -133,6 +133,7 @@ struct Cell
|
||||||
void loadCell(ESMReader &esm, bool saveContext = true); // Load everything, except NAME, DATAstruct and references
|
void loadCell(ESMReader &esm, bool saveContext = true); // Load everything, except NAME, DATAstruct and references
|
||||||
|
|
||||||
void save(ESMWriter &esm, bool isDeleted = false) const;
|
void save(ESMWriter &esm, bool isDeleted = false) const;
|
||||||
|
void saveTempMarker(ESMWriter &esm, int tempCount) const;
|
||||||
|
|
||||||
bool isExterior() const
|
bool isExterior() const
|
||||||
{
|
{
|
||||||
|
@ -183,7 +184,7 @@ struct Cell
|
||||||
/// \param ignoreMoves ignore MVRF record and read reference like a regular CellRef.
|
/// \param ignoreMoves ignore MVRF record and read reference like a regular CellRef.
|
||||||
static bool getNextRef(ESMReader &esm,
|
static bool getNextRef(ESMReader &esm,
|
||||||
CellRef &ref,
|
CellRef &ref,
|
||||||
bool &isDeleted,
|
bool &isDeleted,
|
||||||
bool ignoreMoves = false,
|
bool ignoreMoves = false,
|
||||||
MovedCellRef *mref = nullptr);
|
MovedCellRef *mref = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Clothing::load(ESMReader &esm, bool &isDeleted)
|
void Clothing::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
mParts.mParts.clear();
|
mParts.mParts.clear();
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct Clothing
|
||||||
|
|
||||||
PartReferenceList mParts;
|
PartReferenceList mParts;
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mIcon, mEnchant, mScript;
|
std::string mId, mName, mModel, mIcon, mEnchant, mScript;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace ESM
|
||||||
void Container::load(ESMReader &esm, bool &isDeleted)
|
void Container::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
mInventory.mList.clear();
|
mInventory.mList.clear();
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct Container
|
||||||
Unknown = 8
|
Unknown = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mScript;
|
std::string mId, mName, mModel, mScript;
|
||||||
|
|
||||||
float mWeight; // Not sure, might be max total weight allowed?
|
float mWeight; // Not sure, might be max total weight allowed?
|
||||||
|
|
|
@ -13,8 +13,7 @@ namespace ESM {
|
||||||
void Creature::load(ESMReader &esm, bool &isDeleted)
|
void Creature::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
mPersistent = (esm.getRecordFlags() & 0x0400) != 0;
|
|
||||||
|
|
||||||
mAiPackage.mList.clear();
|
mAiPackage.mList.clear();
|
||||||
mInventory.mList.clear();
|
mInventory.mList.clear();
|
||||||
|
@ -115,7 +114,7 @@ namespace ESM {
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,10 +76,9 @@ struct Creature
|
||||||
int mBloodType;
|
int mBloodType;
|
||||||
unsigned char mFlags;
|
unsigned char mFlags;
|
||||||
|
|
||||||
bool mPersistent;
|
|
||||||
|
|
||||||
float mScale;
|
float mScale;
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mModel, mName, mScript;
|
std::string mId, mModel, mName, mScript;
|
||||||
std::string mOriginal; // Base creature that this is a modification of
|
std::string mOriginal; // Base creature that this is a modification of
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace ESM
|
||||||
esm.writeHNCString("NAME", mId);
|
esm.writeHNCString("NAME", mId);
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Door::load(ESMReader &esm, bool &isDeleted)
|
void Door::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
while (esm.hasMoreSubs())
|
while (esm.hasMoreSubs())
|
||||||
|
@ -57,7 +58,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ struct Door
|
||||||
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
static std::string getRecordType() { return "Door"; }
|
static std::string getRecordType() { return "Door"; }
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mScript, mOpenSound, mCloseSound;
|
std::string mId, mName, mModel, mScript, mOpenSound, mCloseSound;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Ingredient::load(ESMReader &esm, bool &isDeleted)
|
void Ingredient::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
|
@ -84,7 +85,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct Ingredient
|
||||||
};
|
};
|
||||||
|
|
||||||
IRDTstruct mData;
|
IRDTstruct mData;
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mIcon, mScript;
|
std::string mId, mName, mModel, mIcon, mScript;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -123,7 +123,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace ESM
|
||||||
void LevelledListBase::load(ESMReader &esm, bool &isDeleted)
|
void LevelledListBase::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
bool hasList = false;
|
bool hasList = false;
|
||||||
|
@ -80,7 +81,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ struct LevelledListBase
|
||||||
{
|
{
|
||||||
int mFlags;
|
int mFlags;
|
||||||
unsigned char mChanceNone; // Chance that none are selected (0-100)
|
unsigned char mChanceNone; // Chance that none are selected (0-100)
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
||||||
// Record name used to read references. Must be set before load() is
|
// Record name used to read references. Must be set before load() is
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Light::load(ESMReader &esm, bool &isDeleted)
|
void Light::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
|
@ -63,7 +64,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ struct Light
|
||||||
|
|
||||||
LHDTstruct mData;
|
LHDTstruct mData;
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mSound, mScript, mModel, mIcon, mName, mId;
|
std::string mSound, mScript, mModel, mIcon, mName, mId;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Lockpick::load(ESMReader &esm, bool &isDeleted)
|
void Lockpick::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
|
@ -61,7 +62,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct Lockpick
|
||||||
}; // Size = 16
|
}; // Size = 16
|
||||||
|
|
||||||
Data mData;
|
Data mData;
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mIcon, mScript;
|
std::string mId, mName, mModel, mIcon, mScript;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Miscellaneous::load(ESMReader &esm, bool &isDeleted)
|
void Miscellaneous::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
|
@ -61,7 +62,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct Miscellaneous
|
||||||
};
|
};
|
||||||
MCDTstruct mData;
|
MCDTstruct mData;
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mIcon, mScript;
|
std::string mId, mName, mModel, mIcon, mScript;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -11,8 +11,7 @@ namespace ESM
|
||||||
void NPC::load(ESMReader &esm, bool &isDeleted)
|
void NPC::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
mPersistent = (esm.getRecordFlags() & 0x0400) != 0;
|
|
||||||
|
|
||||||
mSpells.mList.clear();
|
mSpells.mList.clear();
|
||||||
mInventory.mList.clear();
|
mInventory.mList.clear();
|
||||||
|
@ -135,7 +134,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,8 +116,6 @@ struct NPC
|
||||||
int mBloodType;
|
int mBloodType;
|
||||||
unsigned char mFlags;
|
unsigned char mFlags;
|
||||||
|
|
||||||
bool mPersistent;
|
|
||||||
|
|
||||||
InventoryList mInventory;
|
InventoryList mInventory;
|
||||||
SpellList mSpells;
|
SpellList mSpells;
|
||||||
|
|
||||||
|
@ -129,6 +127,7 @@ struct NPC
|
||||||
|
|
||||||
AIPackageList mAiPackage;
|
AIPackageList mAiPackage;
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mRace, mClass, mFaction, mScript;
|
std::string mId, mName, mModel, mRace, mClass, mFaction, mScript;
|
||||||
|
|
||||||
// body parts
|
// body parts
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Probe::load(ESMReader &esm, bool &isDeleted)
|
void Probe::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
|
@ -61,7 +62,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct Probe
|
||||||
}; // Size = 16
|
}; // Size = 16
|
||||||
|
|
||||||
Data mData;
|
Data mData;
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mIcon, mScript;
|
std::string mId, mName, mModel, mIcon, mScript;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Repair::load(ESMReader &esm, bool &isDeleted)
|
void Repair::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
|
@ -61,7 +62,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct Repair
|
||||||
}; // Size = 16
|
}; // Size = 16
|
||||||
|
|
||||||
Data mData;
|
Data mData;
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mIcon, mScript;
|
std::string mId, mName, mModel, mIcon, mScript;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -155,7 +155,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace ESM
|
||||||
esm.writeHNCString("NAME", mId);
|
esm.writeHNCString("NAME", mId);
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,9 @@ namespace ESM
|
||||||
void Static::load(ESMReader &esm, bool &isDeleted)
|
void Static::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
//bool isBlocked = (mRecordFlags & ESM::FLAG_Blocked) != 0;
|
||||||
|
//bool isPersistent = (mRecordFlags & ESM::FLAG_Persistent) != 0;
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
while (esm.hasMoreSubs())
|
while (esm.hasMoreSubs())
|
||||||
|
@ -43,7 +46,7 @@ namespace ESM
|
||||||
esm.writeHNCString("NAME", mId);
|
esm.writeHNCString("NAME", mId);
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct Static
|
||||||
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
static std::string getRecordType() { return "Static"; }
|
static std::string getRecordType() { return "Static"; }
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mModel;
|
std::string mId, mModel;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace ESM
|
||||||
void Weapon::load(ESMReader &esm, bool &isDeleted)
|
void Weapon::load(ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
isDeleted = false;
|
isDeleted = false;
|
||||||
|
mRecordFlags = esm.getRecordFlags();
|
||||||
|
|
||||||
bool hasName = false;
|
bool hasName = false;
|
||||||
bool hasData = false;
|
bool hasData = false;
|
||||||
|
@ -62,7 +63,7 @@ namespace ESM
|
||||||
|
|
||||||
if (isDeleted)
|
if (isDeleted)
|
||||||
{
|
{
|
||||||
esm.writeHNCString("DELE", "");
|
esm.writeHNString("DELE", "", 3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ struct Weapon
|
||||||
|
|
||||||
WPDTstruct mData;
|
WPDTstruct mData;
|
||||||
|
|
||||||
|
unsigned int mRecordFlags;
|
||||||
std::string mId, mName, mModel, mIcon, mEnchant, mScript;
|
std::string mId, mName, mModel, mIcon, mEnchant, mScript;
|
||||||
|
|
||||||
void load(ESMReader &esm, bool &isDeleted);
|
void load(ESMReader &esm, bool &isDeleted);
|
||||||
|
|
Loading…
Reference in a new issue