forked from mirror/openmw-tes3mp
Merge branch 'master' of https://github.com/OpenMW/openmw into osg
Conflicts: apps/openmw/mwmechanics/aicombat.cpp apps/openmw/mwmechanics/aitravel.cpp
This commit is contained in:
commit
cad18969e3
56 changed files with 322 additions and 298 deletions
|
@ -830,12 +830,12 @@ std::string npcFlags(int flags)
|
||||||
std::string properties = "";
|
std::string properties = "";
|
||||||
if (flags == 0) properties += "[None] ";
|
if (flags == 0) properties += "[None] ";
|
||||||
// Mythicmods and the ESM component differ. Mythicmods says
|
// Mythicmods and the ESM component differ. Mythicmods says
|
||||||
// 0x8=None and 0x10=AutoCalc, while our code defines 0x8 as
|
// 0x8=None and 0x10=AutoCalc, while our code previously defined
|
||||||
// AutoCalc. The former seems to be correct. All Bethesda
|
// 0x8 as AutoCalc. The former seems to be correct. All Bethesda
|
||||||
// records have bit 0x8 set. A suspiciously large portion of
|
// records have bit 0x8 set. Previously, suspiciously large portion
|
||||||
// females have autocalc turned off.
|
// of females had autocalc turned off.
|
||||||
if (flags & ESM::NPC::Autocalc) properties += "Unknown ";
|
if (flags & 0x00000008) properties += "Unknown ";
|
||||||
if (flags & 0x00000010) properties += "Autocalc ";
|
if (flags & ESM::NPC::Autocalc) properties += "Autocalc ";
|
||||||
if (flags & ESM::NPC::Female) properties += "Female ";
|
if (flags & ESM::NPC::Female) properties += "Female ";
|
||||||
if (flags & ESM::NPC::Respawn) properties += "Respawn ";
|
if (flags & ESM::NPC::Respawn) properties += "Respawn ";
|
||||||
if (flags & ESM::NPC::Essential) properties += "Essential ";
|
if (flags & ESM::NPC::Essential) properties += "Essential ";
|
||||||
|
@ -847,8 +847,8 @@ std::string npcFlags(int flags)
|
||||||
// however the only unknown bit occurs on ALL records, and
|
// however the only unknown bit occurs on ALL records, and
|
||||||
// relatively few NPCs have this bit set.
|
// relatively few NPCs have this bit set.
|
||||||
int unused = (0xFFFFFFFF ^
|
int unused = (0xFFFFFFFF ^
|
||||||
(ESM::NPC::Autocalc|
|
(0x00000008|
|
||||||
0x00000010|
|
ESM::NPC::Autocalc|
|
||||||
ESM::NPC::Female|
|
ESM::NPC::Female|
|
||||||
ESM::NPC::Respawn|
|
ESM::NPC::Respawn|
|
||||||
ESM::NPC::Essential|
|
ESM::NPC::Essential|
|
||||||
|
|
|
@ -490,7 +490,7 @@ bool Launcher::MainDialog::writeSettings()
|
||||||
// Game settings
|
// Game settings
|
||||||
QFile file(userPath + QString("openmw.cfg"));
|
QFile file(userPath + QString("openmw.cfg"));
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) {
|
||||||
// File cannot be opened or created
|
// File cannot be opened or created
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setWindowTitle(tr("Error writing OpenMW configuration file"));
|
msgBox.setWindowTitle(tr("Error writing OpenMW configuration file"));
|
||||||
|
@ -503,8 +503,10 @@ bool Launcher::MainDialog::writeSettings()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTextStream stream(&file);
|
||||||
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||||
|
|
||||||
mGameSettings.writeFileWithComments(file);
|
mGameSettings.writeFile(stream);
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
// Graphics settings
|
// Graphics settings
|
||||||
|
@ -523,7 +525,6 @@ bool Launcher::MainDialog::writeSettings()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream stream(&file);
|
|
||||||
stream.setDevice(&file);
|
stream.setDevice(&file);
|
||||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||||
|
|
||||||
|
|
|
@ -648,7 +648,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
|
||||||
|
|
||||||
if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated
|
if (npc.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) //12 = autocalculated
|
||||||
{
|
{
|
||||||
if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0008 = autocalculated flag
|
if ((npc.mFlags & ESM::NPC::Autocalc) == 0) //0x0010 = autocalculated flag
|
||||||
{
|
{
|
||||||
messages.push_back (std::make_pair (id, npc.mId + " mNpdtType or flags mismatch!")); //should not happend?
|
messages.push_back (std::make_pair (id, npc.mId + " mNpdtType or flags mismatch!")); //should not happend?
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -37,10 +37,18 @@ void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData
|
||||||
Record<ESM::Potion>& record = static_cast<Record<ESM::Potion>&> (
|
Record<ESM::Potion>& record = static_cast<Record<ESM::Potion>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion)));
|
||||||
|
|
||||||
|
ESM::Potion potion = record.get();
|
||||||
|
|
||||||
if (column==mAutoCalc)
|
if (column==mAutoCalc)
|
||||||
record.get().mData.mAutoCalc = value.toInt();
|
potion.mData.mAutoCalc = value.toInt();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
InventoryRefIdAdapter<ESM::Potion>::setData (column, data, index, value);
|
InventoryRefIdAdapter<ESM::Potion>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(potion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,12 +79,19 @@ void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdD
|
||||||
Record<ESM::Apparatus>& record = static_cast<Record<ESM::Apparatus>&> (
|
Record<ESM::Apparatus>& record = static_cast<Record<ESM::Apparatus>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus)));
|
||||||
|
|
||||||
|
ESM::Apparatus apparatus = record.get();
|
||||||
|
|
||||||
if (column==mType)
|
if (column==mType)
|
||||||
record.get().mData.mType = value.toInt();
|
apparatus.mData.mType = value.toInt();
|
||||||
else if (column==mQuality)
|
else if (column==mQuality)
|
||||||
record.get().mData.mQuality = value.toFloat();
|
apparatus.mData.mQuality = value.toFloat();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
InventoryRefIdAdapter<ESM::Apparatus>::setData (column, data, index, value);
|
InventoryRefIdAdapter<ESM::Apparatus>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
record.setModified(apparatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,14 +129,22 @@ void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
|
||||||
Record<ESM::Armor>& record = static_cast<Record<ESM::Armor>&> (
|
Record<ESM::Armor>& record = static_cast<Record<ESM::Armor>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor)));
|
||||||
|
|
||||||
|
ESM::Armor armor = record.get();
|
||||||
|
|
||||||
if (column==mType)
|
if (column==mType)
|
||||||
record.get().mData.mType = value.toInt();
|
armor.mData.mType = value.toInt();
|
||||||
else if (column==mHealth)
|
else if (column==mHealth)
|
||||||
record.get().mData.mHealth = value.toInt();
|
armor.mData.mHealth = value.toInt();
|
||||||
else if (column==mArmor)
|
else if (column==mArmor)
|
||||||
record.get().mData.mArmor = value.toInt();
|
armor.mData.mArmor = value.toInt();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
EnchantableRefIdAdapter<ESM::Armor>::setData (column, data, index, value);
|
EnchantableRefIdAdapter<ESM::Armor>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(armor);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns,
|
CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns,
|
||||||
|
@ -151,12 +174,20 @@ void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
|
||||||
Record<ESM::Book>& record = static_cast<Record<ESM::Book>&> (
|
Record<ESM::Book>& record = static_cast<Record<ESM::Book>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book)));
|
||||||
|
|
||||||
|
ESM::Book book = record.get();
|
||||||
|
|
||||||
if (column==mScroll)
|
if (column==mScroll)
|
||||||
record.get().mData.mIsScroll = value.toInt();
|
book.mData.mIsScroll = value.toInt();
|
||||||
else if (column==mSkill)
|
else if (column==mSkill)
|
||||||
record.get().mData.mSkillID = value.toInt();
|
book.mData.mSkillID = value.toInt();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
EnchantableRefIdAdapter<ESM::Book>::setData (column, data, index, value);
|
EnchantableRefIdAdapter<ESM::Book>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(book);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns,
|
CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns,
|
||||||
|
@ -186,10 +217,18 @@ void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
|
||||||
Record<ESM::Clothing>& record = static_cast<Record<ESM::Clothing>&> (
|
Record<ESM::Clothing>& record = static_cast<Record<ESM::Clothing>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing)));
|
||||||
|
|
||||||
|
ESM::Clothing clothing = record.get();
|
||||||
|
|
||||||
if (column==mType)
|
if (column==mType)
|
||||||
record.get().mData.mType = value.toInt();
|
clothing.mData.mType = value.toInt();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
EnchantableRefIdAdapter<ESM::Clothing>::setData (column, data, index, value);
|
EnchantableRefIdAdapter<ESM::Clothing>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(clothing);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns,
|
CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns,
|
||||||
|
@ -226,24 +265,32 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD
|
||||||
Record<ESM::Container>& record = static_cast<Record<ESM::Container>&> (
|
Record<ESM::Container>& record = static_cast<Record<ESM::Container>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container)));
|
||||||
|
|
||||||
|
ESM::Container container = record.get();
|
||||||
|
|
||||||
if (column==mWeight)
|
if (column==mWeight)
|
||||||
record.get().mWeight = value.toFloat();
|
container.mWeight = value.toFloat();
|
||||||
else if (column==mOrganic)
|
else if (column==mOrganic)
|
||||||
{
|
{
|
||||||
if (value.toInt())
|
if (value.toInt())
|
||||||
record.get().mFlags |= ESM::Container::Organic;
|
container.mFlags |= ESM::Container::Organic;
|
||||||
else
|
else
|
||||||
record.get().mFlags &= ~ESM::Container::Organic;
|
container.mFlags &= ~ESM::Container::Organic;
|
||||||
}
|
}
|
||||||
else if (column==mRespawn)
|
else if (column==mRespawn)
|
||||||
{
|
{
|
||||||
if (value.toInt())
|
if (value.toInt())
|
||||||
record.get().mFlags |= ESM::Container::Respawn;
|
container.mFlags |= ESM::Container::Respawn;
|
||||||
else
|
else
|
||||||
record.get().mFlags &= ~ESM::Container::Respawn;
|
container.mFlags &= ~ESM::Container::Respawn;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
NameRefIdAdapter<ESM::Container>::setData (column, data, index, value);
|
NameRefIdAdapter<ESM::Container>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns)
|
CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns)
|
||||||
|
@ -303,20 +350,22 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
|
||||||
Record<ESM::Creature>& record = static_cast<Record<ESM::Creature>&> (
|
Record<ESM::Creature>& record = static_cast<Record<ESM::Creature>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
||||||
|
|
||||||
|
ESM::Creature creature = record.get();
|
||||||
|
|
||||||
if (column==mColumns.mType)
|
if (column==mColumns.mType)
|
||||||
record.get().mData.mType = value.toInt();
|
creature.mData.mType = value.toInt();
|
||||||
else if (column==mColumns.mSoul)
|
else if (column==mColumns.mSoul)
|
||||||
record.get().mData.mSoul = value.toInt();
|
creature.mData.mSoul = value.toInt();
|
||||||
else if (column==mColumns.mScale)
|
else if (column==mColumns.mScale)
|
||||||
record.get().mScale = value.toFloat();
|
creature.mScale = value.toFloat();
|
||||||
else if (column==mColumns.mOriginal)
|
else if (column==mColumns.mOriginal)
|
||||||
record.get().mOriginal = value.toString().toUtf8().constData();
|
creature.mOriginal = value.toString().toUtf8().constData();
|
||||||
else if (column==mColumns.mCombat)
|
else if (column==mColumns.mCombat)
|
||||||
record.get().mData.mCombat = value.toInt();
|
creature.mData.mCombat = value.toInt();
|
||||||
else if (column==mColumns.mMagic)
|
else if (column==mColumns.mMagic)
|
||||||
record.get().mData.mMagic = value.toInt();
|
creature.mData.mMagic = value.toInt();
|
||||||
else if (column==mColumns.mStealth)
|
else if (column==mColumns.mStealth)
|
||||||
record.get().mData.mStealth = value.toInt();
|
creature.mData.mStealth = value.toInt();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||||
|
@ -325,13 +374,19 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
|
||||||
if (iter!=mColumns.mFlags.end())
|
if (iter!=mColumns.mFlags.end())
|
||||||
{
|
{
|
||||||
if (value.toInt()!=0)
|
if (value.toInt()!=0)
|
||||||
record.get().mFlags |= iter->second;
|
creature.mFlags |= iter->second;
|
||||||
else
|
else
|
||||||
record.get().mFlags &= ~iter->second;
|
creature.mFlags &= ~iter->second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
ActorRefIdAdapter<ESM::Creature>::setData (column, data, index, value);
|
ActorRefIdAdapter<ESM::Creature>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record.setModified(creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns,
|
CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns,
|
||||||
|
@ -361,12 +416,20 @@ void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
|
||||||
Record<ESM::Door>& record = static_cast<Record<ESM::Door>&> (
|
Record<ESM::Door>& record = static_cast<Record<ESM::Door>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door)));
|
||||||
|
|
||||||
|
ESM::Door door = record.get();
|
||||||
|
|
||||||
if (column==mOpenSound)
|
if (column==mOpenSound)
|
||||||
record.get().mOpenSound = value.toString().toUtf8().constData();
|
door.mOpenSound = value.toString().toUtf8().constData();
|
||||||
else if (column==mCloseSound)
|
else if (column==mCloseSound)
|
||||||
record.get().mCloseSound = value.toString().toUtf8().constData();
|
door.mCloseSound = value.toString().toUtf8().constData();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
NameRefIdAdapter<ESM::Door>::setData (column, data, index, value);
|
NameRefIdAdapter<ESM::Door>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(door);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::LightColumns::LightColumns (const InventoryColumns& columns)
|
CSMWorld::LightColumns::LightColumns (const InventoryColumns& columns)
|
||||||
|
@ -409,14 +472,16 @@ void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
|
||||||
Record<ESM::Light>& record = static_cast<Record<ESM::Light>&> (
|
Record<ESM::Light>& record = static_cast<Record<ESM::Light>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light)));
|
||||||
|
|
||||||
|
ESM::Light light = record.get();
|
||||||
|
|
||||||
if (column==mColumns.mTime)
|
if (column==mColumns.mTime)
|
||||||
record.get().mData.mTime = value.toInt();
|
light.mData.mTime = value.toInt();
|
||||||
else if (column==mColumns.mRadius)
|
else if (column==mColumns.mRadius)
|
||||||
record.get().mData.mRadius = value.toInt();
|
light.mData.mRadius = value.toInt();
|
||||||
else if (column==mColumns.mColor)
|
else if (column==mColumns.mColor)
|
||||||
record.get().mData.mColor = value.toInt();
|
light.mData.mColor = value.toInt();
|
||||||
else if (column==mColumns.mSound)
|
else if (column==mColumns.mSound)
|
||||||
record.get().mSound = value.toString().toUtf8().constData();
|
light.mSound = value.toString().toUtf8().constData();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||||
|
@ -425,13 +490,19 @@ void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
|
||||||
if (iter!=mColumns.mFlags.end())
|
if (iter!=mColumns.mFlags.end())
|
||||||
{
|
{
|
||||||
if (value.toInt()!=0)
|
if (value.toInt()!=0)
|
||||||
record.get().mData.mFlags |= iter->second;
|
light.mData.mFlags |= iter->second;
|
||||||
else
|
else
|
||||||
record.get().mData.mFlags &= ~iter->second;
|
light.mData.mFlags &= ~iter->second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
InventoryRefIdAdapter<ESM::Light>::setData (column, data, index, value);
|
InventoryRefIdAdapter<ESM::Light>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record.setModified (light);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key)
|
CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key)
|
||||||
|
@ -456,10 +527,18 @@ void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
|
||||||
Record<ESM::Miscellaneous>& record = static_cast<Record<ESM::Miscellaneous>&> (
|
Record<ESM::Miscellaneous>& record = static_cast<Record<ESM::Miscellaneous>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous)));
|
||||||
|
|
||||||
|
ESM::Miscellaneous misc = record.get();
|
||||||
|
|
||||||
if (column==mKey)
|
if (column==mKey)
|
||||||
record.get().mData.mIsKey = value.toInt();
|
misc.mData.mIsKey = value.toInt();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
InventoryRefIdAdapter<ESM::Miscellaneous>::setData (column, data, index, value);
|
InventoryRefIdAdapter<ESM::Miscellaneous>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(misc);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns)
|
CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns)
|
||||||
|
@ -525,16 +604,18 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d
|
||||||
Record<ESM::NPC>& record = static_cast<Record<ESM::NPC>&> (
|
Record<ESM::NPC>& record = static_cast<Record<ESM::NPC>&> (
|
||||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
|
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
|
||||||
|
|
||||||
|
ESM::NPC npc = record.get();
|
||||||
|
|
||||||
if (column==mColumns.mRace)
|
if (column==mColumns.mRace)
|
||||||
record.get().mRace = value.toString().toUtf8().constData();
|
npc.mRace = value.toString().toUtf8().constData();
|
||||||
else if (column==mColumns.mClass)
|
else if (column==mColumns.mClass)
|
||||||
record.get().mClass = value.toString().toUtf8().constData();
|
npc.mClass = value.toString().toUtf8().constData();
|
||||||
else if (column==mColumns.mFaction)
|
else if (column==mColumns.mFaction)
|
||||||
record.get().mFaction = value.toString().toUtf8().constData();
|
npc.mFaction = value.toString().toUtf8().constData();
|
||||||
else if (column==mColumns.mHair)
|
else if (column==mColumns.mHair)
|
||||||
record.get().mHair = value.toString().toUtf8().constData();
|
npc.mHair = value.toString().toUtf8().constData();
|
||||||
else if (column==mColumns.mHead)
|
else if (column==mColumns.mHead)
|
||||||
record.get().mHead = value.toString().toUtf8().constData();
|
npc.mHead = value.toString().toUtf8().constData();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||||
|
@ -543,13 +624,23 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d
|
||||||
if (iter!=mColumns.mFlags.end())
|
if (iter!=mColumns.mFlags.end())
|
||||||
{
|
{
|
||||||
if (value.toInt()!=0)
|
if (value.toInt()!=0)
|
||||||
record.get().mFlags |= iter->second;
|
npc.mFlags |= iter->second;
|
||||||
else
|
else
|
||||||
record.get().mFlags &= ~iter->second;
|
npc.mFlags &= ~iter->second;
|
||||||
|
|
||||||
|
if (iter->second == ESM::NPC::Autocalc)
|
||||||
|
npc.mNpdtType = (value.toInt() != 0) ? ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS
|
||||||
|
: ESM::NPC::NPC_DEFAULT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
ActorRefIdAdapter<ESM::NPC>::setData (column, data, index, value);
|
ActorRefIdAdapter<ESM::NPC>::setData (column, data, index, value);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record.setModified (npc);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter ()
|
CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter ()
|
||||||
|
|
|
@ -673,44 +673,32 @@ namespace MWMechanics
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AiCombat::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
|
||||||
|
{
|
||||||
|
if (!mPathFinder.getPath().empty())
|
||||||
|
{
|
||||||
|
osg::Vec3f currPathTarget(PathFinder::MakeOsgVec3(mPathFinder.getPath().back()));
|
||||||
|
osg::Vec3f newPathTarget = PathFinder::MakeOsgVec3(dest);
|
||||||
|
float dist = (newPathTarget - currPathTarget).length();
|
||||||
|
float targetPosThreshold = (cell->isExterior()) ? 300.0f : 100.0f;
|
||||||
|
return dist > targetPosThreshold;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// necessarily construct a new path
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
|
void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
|
||||||
{
|
{
|
||||||
osg::Vec3f newPathTarget = target.getRefData().getPosition().asVec3();
|
ESM::Pathgrid::Point newPathTarget = PathFinder::MakePathgridPoint(target.getRefData().getPosition());
|
||||||
|
|
||||||
float dist;
|
|
||||||
|
|
||||||
if(!mPathFinder.getPath().empty())
|
|
||||||
{
|
|
||||||
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
|
|
||||||
osg::Vec3f currPathTarget(PathFinder::MakeOsgVec3(lastPt));
|
|
||||||
dist = (newPathTarget - currPathTarget).length();
|
|
||||||
}
|
|
||||||
else dist = 1e+38F; // necessarily construct a new path
|
|
||||||
|
|
||||||
float targetPosThreshold = (actor.getCell()->getCell()->isExterior())? 300.0f : 100.0f;
|
|
||||||
|
|
||||||
//construct new path only if target has moved away more than on [targetPosThreshold]
|
//construct new path only if target has moved away more than on [targetPosThreshold]
|
||||||
if(dist > targetPosThreshold)
|
if (doesPathNeedRecalc(newPathTarget, actor.getCell()->getCell()))
|
||||||
{
|
{
|
||||||
ESM::Position pos = actor.getRefData().getPosition();
|
ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(actor.getRefData().getPosition()));
|
||||||
|
mPathFinder.buildSyncedPath(start, newPathTarget, actor.getCell(), false);
|
||||||
ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(pos));
|
|
||||||
|
|
||||||
ESM::Pathgrid::Point dest(PathFinder::MakePathgridPoint(newPathTarget));
|
|
||||||
|
|
||||||
if(!mPathFinder.isPathConstructed())
|
|
||||||
mPathFinder.buildPath(start, dest, actor.getCell(), false);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PathFinder newPathFinder;
|
|
||||||
newPathFinder.buildPath(start, dest, actor.getCell(), false);
|
|
||||||
|
|
||||||
if(!mPathFinder.getPath().empty())
|
|
||||||
{
|
|
||||||
newPathFinder.syncStart(mPathFinder.getPath());
|
|
||||||
mPathFinder = newPathFinder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,9 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual void writeState(ESM::AiSequence::AiSequence &sequence) const;
|
virtual void writeState(ESM::AiSequence::AiSequence &sequence) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int mTargetActorId;
|
int mTargetActorId;
|
||||||
|
|
|
@ -28,9 +28,9 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
|
||||||
ESM::Position pos = actor.getRefData().getPosition(); //position of the actor
|
ESM::Position pos = actor.getRefData().getPosition(); //position of the actor
|
||||||
|
|
||||||
/// Stops the actor when it gets too close to a unloaded cell
|
/// Stops the actor when it gets too close to a unloaded cell
|
||||||
|
const ESM::Cell *cell = actor.getCell()->getCell();
|
||||||
{
|
{
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
const ESM::Cell *cell = actor.getCell()->getCell();
|
|
||||||
Movement &movement = actor.getClass().getMovementSettings(actor);
|
Movement &movement = actor.getClass().getMovementSettings(actor);
|
||||||
|
|
||||||
//Ensure pursuer doesn't leave loaded cells
|
//Ensure pursuer doesn't leave loaded cells
|
||||||
|
@ -65,8 +65,8 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
|
||||||
//***********************
|
//***********************
|
||||||
if(mTimer > 0.25)
|
if(mTimer > 0.25)
|
||||||
{
|
{
|
||||||
if(distance(mPrevDest, dest) > 10) { //Only rebuild path if it's moved
|
if (doesPathNeedRecalc(dest, cell)) { //Only rebuild path if it's moved
|
||||||
mPathFinder.buildPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved
|
mPathFinder.buildSyncedPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved
|
||||||
mPrevDest = dest;
|
mPrevDest = dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,3 +121,8 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MWMechanics::AiPackage::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
|
||||||
|
{
|
||||||
|
return distance(mPrevDest, dest) > 10;
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "pathfinding.hpp"
|
#include "pathfinding.hpp"
|
||||||
#include <components/esm/defs.hpp>
|
#include <components/esm/defs.hpp>
|
||||||
|
|
||||||
|
#include "../mwworld/cellstore.hpp"
|
||||||
|
|
||||||
#include "obstacle.hpp"
|
#include "obstacle.hpp"
|
||||||
#include "aistate.hpp"
|
#include "aistate.hpp"
|
||||||
|
|
||||||
|
@ -71,6 +73,8 @@ namespace MWMechanics
|
||||||
/** \return If the actor has arrived at his destination **/
|
/** \return If the actor has arrived at his destination **/
|
||||||
bool pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Point dest, float duration);
|
bool pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Point dest, float duration);
|
||||||
|
|
||||||
|
virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell);
|
||||||
|
|
||||||
// TODO: all this does not belong here, move into temporary storage
|
// TODO: all this does not belong here, move into temporary storage
|
||||||
PathFinder mPathFinder;
|
PathFinder mPathFinder;
|
||||||
ObstacleCheck mObstacleCheck;
|
ObstacleCheck mObstacleCheck;
|
||||||
|
|
|
@ -49,64 +49,31 @@ namespace MWMechanics
|
||||||
|
|
||||||
bool AiTravel::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
bool AiTravel::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
|
||||||
ESM::Position pos = actor.getRefData().getPosition();
|
ESM::Position pos = actor.getRefData().getPosition();
|
||||||
Movement &movement = actor.getClass().getMovementSettings(actor);
|
|
||||||
const ESM::Cell *cell = actor.getCell()->getCell();
|
|
||||||
|
|
||||||
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false);
|
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false);
|
||||||
|
|
||||||
actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing);
|
actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing);
|
||||||
|
|
||||||
MWWorld::Ptr player = world->getPlayerPtr();
|
|
||||||
if(cell->mData.mX != player.getCell()->getCell()->mData.mX)
|
|
||||||
{
|
|
||||||
int sideX = PathFinder::sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX);
|
|
||||||
//check if actor is near the border of an inactive cell. If so, stop walking.
|
|
||||||
if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) >
|
|
||||||
sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
|
|
||||||
{
|
|
||||||
movement.mPosition[1] = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(cell->mData.mY != player.getCell()->getCell()->mData.mY)
|
|
||||||
{
|
|
||||||
int sideY = PathFinder::sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY);
|
|
||||||
//check if actor is near the border of an inactive cell. If so, stop walking.
|
|
||||||
if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) >
|
|
||||||
sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
|
|
||||||
{
|
|
||||||
movement.mPosition[1] = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isWithinMaxRange(osg::Vec3f(mX, mY, mZ), pos.asVec3()))
|
if (!isWithinMaxRange(osg::Vec3f(mX, mY, mZ), pos.asVec3()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (pathTo(actor, ESM::Pathgrid::Point(static_cast<int>(mX), static_cast<int>(mY), static_cast<int>(mZ)), duration))
|
||||||
|
{
|
||||||
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AiTravel::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
|
||||||
|
{
|
||||||
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
|
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
|
||||||
if(!mPathFinder.isPathConstructed() || cellChange)
|
if (!mPathFinder.isPathConstructed() || cellChange)
|
||||||
{
|
{
|
||||||
mCellX = cell->mData.mX;
|
mCellX = cell->mData.mX;
|
||||||
mCellY = cell->mData.mY;
|
mCellY = cell->mData.mY;
|
||||||
|
|
||||||
ESM::Pathgrid::Point dest(static_cast<int>(mX), static_cast<int>(mY), static_cast<int>(mZ));
|
|
||||||
|
|
||||||
ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(pos));
|
|
||||||
|
|
||||||
mPathFinder.buildPath(start, dest, actor.getCell(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1]))
|
|
||||||
{
|
|
||||||
movement.mPosition[1] = 0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
zTurn(actor, osg::DegreesToRadians(mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1])));
|
|
||||||
movement.mPosition[1] = 1;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,9 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual int getTypeId() const;
|
virtual int getTypeId() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float mX;
|
float mX;
|
||||||
float mY;
|
float mY;
|
||||||
|
|
|
@ -298,23 +298,35 @@ namespace MWMechanics
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// used by AiCombat, see header for the rationale
|
// see header for the rationale
|
||||||
bool PathFinder::syncStart(const std::list<ESM::Pathgrid::Point> &path)
|
void PathFinder::buildSyncedPath(const ESM::Pathgrid::Point &startPoint,
|
||||||
|
const ESM::Pathgrid::Point &endPoint,
|
||||||
|
const MWWorld::CellStore* cell,
|
||||||
|
bool allowShortcuts)
|
||||||
{
|
{
|
||||||
if (mPath.size() < 2)
|
if (mPath.size() < 2)
|
||||||
return false; //nothing to pop
|
|
||||||
|
|
||||||
std::list<ESM::Pathgrid::Point>::const_iterator oldStart = path.begin();
|
|
||||||
std::list<ESM::Pathgrid::Point>::iterator iter = ++mPath.begin();
|
|
||||||
|
|
||||||
if( (*iter).mX == oldStart->mX
|
|
||||||
&& (*iter).mY == oldStart->mY
|
|
||||||
&& (*iter).mZ == oldStart->mZ)
|
|
||||||
{
|
{
|
||||||
mPath.pop_front();
|
// if path has one point, then it's the destination.
|
||||||
return true;
|
// don't need to worry about bad path for this case
|
||||||
|
buildPath(startPoint, endPoint, cell, allowShortcuts);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const ESM::Pathgrid::Point oldStart(*getPath().begin());
|
||||||
|
buildPath(startPoint, endPoint, cell, allowShortcuts);
|
||||||
|
if (mPath.size() >= 2)
|
||||||
|
{
|
||||||
|
// if 2nd waypoint of new path == 1st waypoint of old,
|
||||||
|
// delete 1st waypoint of new path.
|
||||||
|
std::list<ESM::Pathgrid::Point>::iterator iter = ++mPath.begin();
|
||||||
|
if (iter->mX == oldStart.mX
|
||||||
|
&& iter->mY == oldStart.mY
|
||||||
|
&& iter->mZ == oldStart.mZ)
|
||||||
|
{
|
||||||
|
mPath.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,13 +61,13 @@ namespace MWMechanics
|
||||||
|
|
||||||
/** Synchronize new path with old one to avoid visiting 1 waypoint 2 times
|
/** Synchronize new path with old one to avoid visiting 1 waypoint 2 times
|
||||||
@note
|
@note
|
||||||
If the first point is chosen as the nearest one
|
BuildPath() takes closest PathGrid point to NPC as first point of path.
|
||||||
the situation can occur when the 1st point of the new path is undesirable
|
This is undesireable if NPC has just passed a Pathgrid point, as this
|
||||||
(i.e. the 2nd point of new path == the 1st point of old path).
|
makes the 2nd point of the new path == the 1st point of old path.
|
||||||
@param path - old path
|
Which results in NPC "running in a circle" back to the just passed waypoint.
|
||||||
@return true if such point was found and deleted
|
|
||||||
*/
|
*/
|
||||||
bool syncStart(const std::list<ESM::Pathgrid::Point> &path);
|
void buildSyncedPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint,
|
||||||
|
const MWWorld::CellStore* cell, bool allowShortcuts = true);
|
||||||
|
|
||||||
void addPointToPath(ESM::Pathgrid::Point &point)
|
void addPointToPath(ESM::Pathgrid::Point &point)
|
||||||
{
|
{
|
||||||
|
|
|
@ -188,7 +188,7 @@ namespace MWWorld
|
||||||
const T *ptr = search(id);
|
const T *ptr = search(id);
|
||||||
if (ptr == 0) {
|
if (ptr == 0) {
|
||||||
std::ostringstream msg;
|
std::ostringstream msg;
|
||||||
msg << "Object '" << id << "' not found (const)";
|
msg << T::getRecordType() << " '" << id << "' not found";
|
||||||
throw std::runtime_error(msg.str());
|
throw std::runtime_error(msg.str());
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
|
@ -202,7 +202,7 @@ namespace MWWorld
|
||||||
if(ptr == 0)
|
if(ptr == 0)
|
||||||
{
|
{
|
||||||
std::ostringstream msg;
|
std::ostringstream msg;
|
||||||
msg << "Object starting with '"<<id<<"' not found (const)";
|
msg << T::getRecordType() << " starting with '"<<id<<"' not found";
|
||||||
throw std::runtime_error(msg.str());
|
throw std::runtime_error(msg.str());
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
|
@ -989,7 +989,7 @@ namespace MWWorld
|
||||||
const T *ptr = search(index);
|
const T *ptr = search(index);
|
||||||
if (ptr == 0) {
|
if (ptr == 0) {
|
||||||
std::ostringstream msg;
|
std::ostringstream msg;
|
||||||
msg << "Object with index " << index << " not found";
|
msg << T::getRecordType() << " with index " << index << " not found";
|
||||||
throw std::runtime_error(msg.str());
|
throw std::runtime_error(msg.str());
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "gamesettings.hpp"
|
#include "gamesettings.hpp"
|
||||||
#include "launchersettings.hpp"
|
#include "launchersettings.hpp"
|
||||||
|
|
||||||
#include <QTextCodec>
|
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -174,138 +173,6 @@ bool Config::GameSettings::writeFile(QTextStream &stream)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Policy:
|
|
||||||
//
|
|
||||||
// - Always ignore a line beginning with '#' or empty lines
|
|
||||||
//
|
|
||||||
// - If a line in file exists with matching key and first part of value (before ',',
|
|
||||||
// '\n', etc) also matches, then replace the line with that of mUserSettings.
|
|
||||||
// - else remove line (TODO: maybe replace the line with '#' in front instead?)
|
|
||||||
//
|
|
||||||
// - If there is no corresponding line in file, add at the end
|
|
||||||
//
|
|
||||||
bool Config::GameSettings::writeFileWithComments(QFile &file)
|
|
||||||
{
|
|
||||||
QTextStream stream(&file);
|
|
||||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
||||||
|
|
||||||
// slurp
|
|
||||||
std::vector<QString> fileCopy;
|
|
||||||
QString line = stream.readLine();
|
|
||||||
while (!line.isNull())
|
|
||||||
{
|
|
||||||
fileCopy.push_back(line);
|
|
||||||
line = stream.readLine();
|
|
||||||
}
|
|
||||||
stream.seek(0);
|
|
||||||
|
|
||||||
// empty file, no comments to keep
|
|
||||||
if (fileCopy.empty())
|
|
||||||
return writeFile(stream);
|
|
||||||
|
|
||||||
// Temp copy of settings to save, but with the keys appended with the first part of the value
|
|
||||||
//
|
|
||||||
// ATTENTION!
|
|
||||||
//
|
|
||||||
// A hack to avoid looping through each line, makes use of the fact that fallbacks values
|
|
||||||
// are comma separated.
|
|
||||||
QMap<QString, QString> userSettingsCopy;
|
|
||||||
QRegExp settingRegex("^([^=]+)\\s*=\\s*([^,]+)(.*)$");
|
|
||||||
QString settingLine;
|
|
||||||
QMap<QString, QString>::const_iterator settingsIter = mUserSettings.begin();
|
|
||||||
for (; settingsIter != mUserSettings.end(); ++settingsIter)
|
|
||||||
{
|
|
||||||
settingLine = settingsIter.key()+"="+settingsIter.value();
|
|
||||||
if (settingRegex.indexIn(settingLine) != -1)
|
|
||||||
{
|
|
||||||
userSettingsCopy[settingRegex.cap(1)+"="+settingRegex.cap(2)] =
|
|
||||||
(settingRegex.captureCount() < 3) ? "" : settingRegex.cap(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString keyVal;
|
|
||||||
for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
|
|
||||||
{
|
|
||||||
// skip empty or comment lines
|
|
||||||
if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#")))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// look for a key in the line
|
|
||||||
if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2)
|
|
||||||
{
|
|
||||||
// no key or first part of value found in line, replace with a null string which
|
|
||||||
// will be remved later
|
|
||||||
*iter = QString();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// look for a matching key in user settings
|
|
||||||
keyVal = settingRegex.cap(1)+"="+settingRegex.cap(2);
|
|
||||||
QMap<QString, QString>::iterator it = userSettingsCopy.find(keyVal);
|
|
||||||
if (it == userSettingsCopy.end())
|
|
||||||
{
|
|
||||||
// no such key+valStart, replace with a null string which will be remved later
|
|
||||||
*iter = QString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*iter = QString(it.key()+it.value());
|
|
||||||
userSettingsCopy.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// write the new config file
|
|
||||||
QString key;
|
|
||||||
QString value;
|
|
||||||
for (std::vector<QString>::iterator iter = fileCopy.begin(); iter != fileCopy.end(); ++iter)
|
|
||||||
{
|
|
||||||
if ((*iter).isNull())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Below is based on readFile() code, if that changes corresponding change may be
|
|
||||||
// required (for example duplicates may be inserted if the rules don't match)
|
|
||||||
if ((*iter).isEmpty() || (*iter).contains(QRegExp("^\\s*#")))
|
|
||||||
{
|
|
||||||
stream << *iter << "\n";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settingRegex.indexIn(*iter) == -1 || settingRegex.captureCount() < 2)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Quote paths with spaces
|
|
||||||
key = settingRegex.cap(1);
|
|
||||||
value = settingRegex.cap(2)+settingRegex.cap(3);
|
|
||||||
if (key == QLatin1String("data")
|
|
||||||
|| key == QLatin1String("data-local")
|
|
||||||
|| key == QLatin1String("resources"))
|
|
||||||
{
|
|
||||||
if (value.contains(QChar(' ')))
|
|
||||||
{
|
|
||||||
value.remove(QChar('\"')); // Remove quotes
|
|
||||||
|
|
||||||
stream << key << "=\"" << value << "\"\n";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stream << key << "=" << value << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// new entries
|
|
||||||
if (!userSettingsCopy.empty())
|
|
||||||
{
|
|
||||||
QMap<QString, QString>::const_iterator it = userSettingsCopy.begin();
|
|
||||||
for (; it != userSettingsCopy.end(); ++it)
|
|
||||||
{
|
|
||||||
stream << it.key() << it.value() << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.resize(file.pos());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Config::GameSettings::hasMaster()
|
bool Config::GameSettings::hasMaster()
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QFile>
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
|
@ -67,7 +66,6 @@ namespace Config
|
||||||
bool readUserFile(QTextStream &stream);
|
bool readUserFile(QTextStream &stream);
|
||||||
|
|
||||||
bool writeFile(QTextStream &stream);
|
bool writeFile(QTextStream &stream);
|
||||||
bool writeFileWithComments(QFile &file);
|
|
||||||
|
|
||||||
void setContentList(const QStringList& fileNames);
|
void setContentList(const QStringList& fileNames);
|
||||||
QStringList getContentList() const;
|
QStringList getContentList() const;
|
||||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
||||||
struct Activator
|
struct Activator
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Activator"; }
|
||||||
|
|
||||||
std::string mId, mName, mScript, mModel;
|
std::string mId, mName, mScript, mModel;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,9 @@ struct Potion
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Potion"; }
|
||||||
|
|
||||||
struct ALDTstruct
|
struct ALDTstruct
|
||||||
{
|
{
|
||||||
float mWeight;
|
float mWeight;
|
||||||
|
|
|
@ -16,6 +16,8 @@ class ESMWriter;
|
||||||
struct Apparatus
|
struct Apparatus
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Apparatus"; }
|
||||||
|
|
||||||
enum AppaType
|
enum AppaType
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,6 +66,8 @@ struct PartReferenceList
|
||||||
struct Armor
|
struct Armor
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Armor"; }
|
||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
||||||
struct BodyPart
|
struct BodyPart
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "BodyPart"; }
|
||||||
|
|
||||||
enum MeshPart
|
enum MeshPart
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,8 @@ class ESMWriter;
|
||||||
struct Book
|
struct Book
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Book"; }
|
||||||
|
|
||||||
struct BKDTstruct
|
struct BKDTstruct
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,6 +14,8 @@ class ESMWriter;
|
||||||
struct BirthSign
|
struct BirthSign
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "BirthSign"; }
|
||||||
|
|
||||||
std::string mId, mName, mDescription, mTexture;
|
std::string mId, mName, mDescription, mTexture;
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ typedef std::list<CellRef> CellRefTracker;
|
||||||
struct Cell
|
struct Cell
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Cell"; }
|
||||||
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
||||||
struct Class
|
struct Class
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Class"; }
|
||||||
|
|
||||||
enum AutoCalc
|
enum AutoCalc
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
||||||
struct Clothing
|
struct Clothing
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Clothing"; }
|
||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,6 +36,8 @@ struct InventoryList
|
||||||
struct Container
|
struct Container
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Container"; }
|
||||||
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,8 @@ class ESMWriter;
|
||||||
struct Creature
|
struct Creature
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Creature"; }
|
||||||
|
|
||||||
// Default is 0x48?
|
// Default is 0x48?
|
||||||
enum Flags
|
enum Flags
|
||||||
|
|
|
@ -21,6 +21,8 @@ class ESMWriter;
|
||||||
struct Dialogue
|
struct Dialogue
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Dialogue"; }
|
||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
||||||
struct Door
|
struct Door
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Door"; }
|
||||||
|
|
||||||
std::string mId, mName, mModel, mScript, mOpenSound, mCloseSound;
|
std::string mId, mName, mModel, mScript, mOpenSound, mCloseSound;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
||||||
struct Enchantment
|
struct Enchantment
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Enchantment"; }
|
||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,6 +30,8 @@ struct RankData
|
||||||
struct Faction
|
struct Faction
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Faction"; }
|
||||||
|
|
||||||
std::string mId, mName;
|
std::string mId, mName;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
||||||
struct Global
|
struct Global
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Global"; }
|
||||||
|
|
||||||
std::string mId;
|
std::string mId;
|
||||||
Variant mValue;
|
Variant mValue;
|
||||||
|
|
|
@ -19,6 +19,8 @@ class ESMWriter;
|
||||||
struct GameSetting
|
struct GameSetting
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "GameSetting"; }
|
||||||
|
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@ class ESMWriter;
|
||||||
struct DialInfo
|
struct DialInfo
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "DialInfo"; }
|
||||||
|
|
||||||
enum Gender
|
enum Gender
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,8 @@ class ESMWriter;
|
||||||
struct Ingredient
|
struct Ingredient
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Ingredient"; }
|
||||||
|
|
||||||
struct IRDTstruct
|
struct IRDTstruct
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
||||||
struct Land
|
struct Land
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Land"; }
|
||||||
|
|
||||||
Land();
|
Land();
|
||||||
~Land();
|
~Land();
|
||||||
|
|
|
@ -46,6 +46,8 @@ struct LevelledListBase
|
||||||
struct CreatureLevList: LevelledListBase
|
struct CreatureLevList: LevelledListBase
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "CreatureLevList"; }
|
||||||
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
|
@ -64,6 +66,8 @@ struct CreatureLevList: LevelledListBase
|
||||||
struct ItemLevList: LevelledListBase
|
struct ItemLevList: LevelledListBase
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "ItemLevList"; }
|
||||||
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,8 @@ class ESMWriter;
|
||||||
struct Light
|
struct Light
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Light"; }
|
||||||
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
||||||
struct Lockpick
|
struct Lockpick
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Lockpick"; }
|
||||||
|
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,8 @@ class ESMWriter;
|
||||||
struct LandTexture
|
struct LandTexture
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "LandTexture"; }
|
||||||
|
|
||||||
std::string mId, mTexture;
|
std::string mId, mTexture;
|
||||||
int mIndex;
|
int mIndex;
|
||||||
|
|
|
@ -13,6 +13,8 @@ class ESMWriter;
|
||||||
struct MagicEffect
|
struct MagicEffect
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "MagicEffect"; }
|
||||||
|
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@ class ESMWriter;
|
||||||
struct Miscellaneous
|
struct Miscellaneous
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Miscellaneous"; }
|
||||||
|
|
||||||
struct MCDTstruct
|
struct MCDTstruct
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,8 @@ class ESMWriter;
|
||||||
struct NPC
|
struct NPC
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "NPC"; }
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
enum Services
|
enum Services
|
||||||
|
@ -52,12 +54,12 @@ struct NPC
|
||||||
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
Female = 0x0001,
|
Female = 0x0001,
|
||||||
Essential = 0x0002,
|
Essential = 0x0002,
|
||||||
Respawn = 0x0004,
|
Respawn = 0x0004,
|
||||||
Autocalc = 0x0008,
|
Autocalc = 0x0010,
|
||||||
Skeleton = 0x0400, // Skeleton blood effect (white)
|
Skeleton = 0x0400, // Skeleton blood effect (white)
|
||||||
Metal = 0x0800 // Metal blood effect (golden?)
|
Metal = 0x0800 // Metal blood effect (golden?)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum NpcType
|
enum NpcType
|
||||||
|
|
|
@ -16,6 +16,8 @@ class ESMWriter;
|
||||||
struct Pathgrid
|
struct Pathgrid
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Pathgrid"; }
|
||||||
|
|
||||||
struct DATAstruct
|
struct DATAstruct
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
||||||
struct Probe
|
struct Probe
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Probe"; }
|
||||||
|
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
||||||
struct Race
|
struct Race
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Race"; }
|
||||||
|
|
||||||
struct SkillBonus
|
struct SkillBonus
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,8 @@ class ESMWriter;
|
||||||
struct Region
|
struct Region
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Region"; }
|
||||||
|
|
||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
||||||
struct Repair
|
struct Repair
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Repair"; }
|
||||||
|
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,8 @@ class Script
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Script"; }
|
||||||
|
|
||||||
struct SCHDstruct
|
struct SCHDstruct
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,8 @@ class ESMWriter;
|
||||||
struct Skill
|
struct Skill
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Skill"; }
|
||||||
|
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ class ESMWriter;
|
||||||
struct SoundGenerator
|
struct SoundGenerator
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "SoundGenerator"; }
|
||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,8 @@ struct SOUNstruct
|
||||||
struct Sound
|
struct Sound
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Sound"; }
|
||||||
|
|
||||||
SOUNstruct mData;
|
SOUNstruct mData;
|
||||||
std::string mId, mSound;
|
std::string mId, mSound;
|
||||||
|
|
|
@ -14,6 +14,8 @@ class ESMWriter;
|
||||||
struct Spell
|
struct Spell
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Spell"; }
|
||||||
|
|
||||||
enum SpellType
|
enum SpellType
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,8 @@ class ESMWriter;
|
||||||
struct StartScript
|
struct StartScript
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "StartScript"; }
|
||||||
|
|
||||||
std::string mData;
|
std::string mData;
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
|
@ -23,6 +23,8 @@ class ESMWriter;
|
||||||
struct Static
|
struct Static
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Static"; }
|
||||||
|
|
||||||
std::string mId, mModel;
|
std::string mId, mModel;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ class ESMWriter;
|
||||||
struct Weapon
|
struct Weapon
|
||||||
{
|
{
|
||||||
static unsigned int sRecordId;
|
static unsigned int sRecordId;
|
||||||
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
|
static std::string getRecordType() { return "Weapon"; }
|
||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue