Merge branch 'master' of https://github.com/OpenMW/openmw into osg

Conflicts:
	apps/openmw/mwmechanics/aicombat.cpp
	apps/openmw/mwmechanics/aitravel.cpp
c++11
scrawl 10 years ago
commit cad18969e3

@ -119,7 +119,7 @@ std::string clothingTypeLabel(int idx)
} }
std::string armorTypeLabel(int idx) std::string armorTypeLabel(int idx)
{ {
if (idx >= 0 && idx <= 10) if (idx >= 0 && idx <= 10)
{ {
static const char *armorTypeLabels[] = { static const char *armorTypeLabels[] = {
@ -645,7 +645,7 @@ std::string ruleFunction(int idx)
else else
return "Invalid"; return "Invalid";
} }
// The "unused flag bits" should probably be defined alongside the // The "unused flag bits" should probably be defined alongside the
// defined bits in the ESM component. The names of the flag bits are // defined bits in the ESM component. The names of the flag bits are
// very inconsistent. // very inconsistent.
@ -653,7 +653,7 @@ std::string ruleFunction(int idx)
std::string bodyPartFlags(int flags) std::string bodyPartFlags(int flags)
{ {
std::string properties = ""; std::string properties = "";
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::BodyPart::BPF_Female) properties += "Female "; if (flags & ESM::BodyPart::BPF_Female) properties += "Female ";
if (flags & ESM::BodyPart::BPF_NotPlayable) properties += "NotPlayable "; if (flags & ESM::BodyPart::BPF_NotPlayable) properties += "NotPlayable ";
int unused = (0xFFFFFFFF ^ int unused = (0xFFFFFFFF ^
@ -667,7 +667,7 @@ std::string bodyPartFlags(int flags)
std::string cellFlags(int flags) std::string cellFlags(int flags)
{ {
std::string properties = ""; std::string properties = "";
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::Cell::HasWater) properties += "HasWater "; if (flags & ESM::Cell::HasWater) properties += "HasWater ";
if (flags & ESM::Cell::Interior) properties += "Interior "; if (flags & ESM::Cell::Interior) properties += "Interior ";
if (flags & ESM::Cell::NoSleep) properties += "NoSleep "; if (flags & ESM::Cell::NoSleep) properties += "NoSleep ";
@ -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;
} }
void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target) bool AiCombat::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
{ {
osg::Vec3f newPathTarget = target.getRefData().getPosition().asVec3(); if (!mPathFinder.getPath().empty())
{
float dist; osg::Vec3f currPathTarget(PathFinder::MakeOsgVec3(mPathFinder.getPath().back()));
osg::Vec3f newPathTarget = PathFinder::MakeOsgVec3(dest);
if(!mPathFinder.getPath().empty()) float dist = (newPathTarget - currPathTarget).length();
float targetPosThreshold = (cell->isExterior()) ? 300.0f : 100.0f;
return dist > targetPosThreshold;
}
else
{ {
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back(); // necessarily construct a new path
osg::Vec3f currPathTarget(PathFinder::MakeOsgVec3(lastPt)); return true;
dist = (newPathTarget - currPathTarget).length();
} }
else dist = 1e+38F; // necessarily construct a new path }
float targetPosThreshold = (actor.getCell()->getCell()->isExterior())? 300.0f : 100.0f; void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
{
ESM::Pathgrid::Point newPathTarget = PathFinder::MakePathgridPoint(target.getRefData().getPosition());
//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;
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY; if (pathTo(actor, ESM::Pathgrid::Point(static_cast<int>(mX), static_cast<int>(mY), static_cast<int>(mZ)), duration))
if(!mPathFinder.isPathConstructed() || cellChange)
{ {
mCellX = cell->mData.mX; actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
mCellY = cell->mData.mY; return true;
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);
} }
return false;
}
if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1])) bool AiTravel::doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell)
{
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
if (!mPathFinder.isPathConstructed() || cellChange)
{ {
movement.mPosition[1] = 0; mCellX = cell->mData.mX;
mCellY = cell->mData.mY;
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…
Cancel
Save