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 = "";
|
||||
if (flags == 0) properties += "[None] ";
|
||||
// Mythicmods and the ESM component differ. Mythicmods says
|
||||
// 0x8=None and 0x10=AutoCalc, while our code defines 0x8 as
|
||||
// AutoCalc. The former seems to be correct. All Bethesda
|
||||
// records have bit 0x8 set. A suspiciously large portion of
|
||||
// females have autocalc turned off.
|
||||
if (flags & ESM::NPC::Autocalc) properties += "Unknown ";
|
||||
if (flags & 0x00000010) properties += "Autocalc ";
|
||||
// 0x8=None and 0x10=AutoCalc, while our code previously defined
|
||||
// 0x8 as AutoCalc. The former seems to be correct. All Bethesda
|
||||
// records have bit 0x8 set. Previously, suspiciously large portion
|
||||
// of females had autocalc turned off.
|
||||
if (flags & 0x00000008) properties += "Unknown ";
|
||||
if (flags & ESM::NPC::Autocalc) properties += "Autocalc ";
|
||||
if (flags & ESM::NPC::Female) properties += "Female ";
|
||||
if (flags & ESM::NPC::Respawn) properties += "Respawn ";
|
||||
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
|
||||
// relatively few NPCs have this bit set.
|
||||
int unused = (0xFFFFFFFF ^
|
||||
(ESM::NPC::Autocalc|
|
||||
0x00000010|
|
||||
(0x00000008|
|
||||
ESM::NPC::Autocalc|
|
||||
ESM::NPC::Female|
|
||||
ESM::NPC::Respawn|
|
||||
ESM::NPC::Essential|
|
||||
|
|
|
@ -490,7 +490,7 @@ bool Launcher::MainDialog::writeSettings()
|
|||
// Game settings
|
||||
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
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("Error writing OpenMW configuration file"));
|
||||
|
@ -503,8 +503,10 @@ bool Launcher::MainDialog::writeSettings()
|
|||
return false;
|
||||
}
|
||||
|
||||
QTextStream stream(&file);
|
||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
mGameSettings.writeFileWithComments(file);
|
||||
mGameSettings.writeFile(stream);
|
||||
file.close();
|
||||
|
||||
// Graphics settings
|
||||
|
@ -523,7 +525,6 @@ bool Launcher::MainDialog::writeSettings()
|
|||
return false;
|
||||
}
|
||||
|
||||
QTextStream stream(&file);
|
||||
stream.setDevice(&file);
|
||||
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.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?
|
||||
return;
|
||||
|
|
|
@ -37,10 +37,18 @@ void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData
|
|||
Record<ESM::Potion>& record = static_cast<Record<ESM::Potion>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion)));
|
||||
|
||||
ESM::Potion potion = record.get();
|
||||
|
||||
if (column==mAutoCalc)
|
||||
record.get().mData.mAutoCalc = value.toInt();
|
||||
potion.mData.mAutoCalc = value.toInt();
|
||||
else
|
||||
{
|
||||
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>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus)));
|
||||
|
||||
ESM::Apparatus apparatus = record.get();
|
||||
|
||||
if (column==mType)
|
||||
record.get().mData.mType = value.toInt();
|
||||
apparatus.mData.mType = value.toInt();
|
||||
else if (column==mQuality)
|
||||
record.get().mData.mQuality = value.toFloat();
|
||||
apparatus.mData.mQuality = value.toFloat();
|
||||
else
|
||||
{
|
||||
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>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor)));
|
||||
|
||||
ESM::Armor armor = record.get();
|
||||
|
||||
if (column==mType)
|
||||
record.get().mData.mType = value.toInt();
|
||||
armor.mData.mType = value.toInt();
|
||||
else if (column==mHealth)
|
||||
record.get().mData.mHealth = value.toInt();
|
||||
armor.mData.mHealth = value.toInt();
|
||||
else if (column==mArmor)
|
||||
record.get().mData.mArmor = value.toInt();
|
||||
armor.mData.mArmor = value.toInt();
|
||||
else
|
||||
{
|
||||
EnchantableRefIdAdapter<ESM::Armor>::setData (column, data, index, value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(armor);
|
||||
}
|
||||
|
||||
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>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book)));
|
||||
|
||||
ESM::Book book = record.get();
|
||||
|
||||
if (column==mScroll)
|
||||
record.get().mData.mIsScroll = value.toInt();
|
||||
book.mData.mIsScroll = value.toInt();
|
||||
else if (column==mSkill)
|
||||
record.get().mData.mSkillID = value.toInt();
|
||||
book.mData.mSkillID = value.toInt();
|
||||
else
|
||||
{
|
||||
EnchantableRefIdAdapter<ESM::Book>::setData (column, data, index, value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(book);
|
||||
}
|
||||
|
||||
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>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing)));
|
||||
|
||||
ESM::Clothing clothing = record.get();
|
||||
|
||||
if (column==mType)
|
||||
record.get().mData.mType = value.toInt();
|
||||
clothing.mData.mType = value.toInt();
|
||||
else
|
||||
{
|
||||
EnchantableRefIdAdapter<ESM::Clothing>::setData (column, data, index, value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(clothing);
|
||||
}
|
||||
|
||||
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>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container)));
|
||||
|
||||
ESM::Container container = record.get();
|
||||
|
||||
if (column==mWeight)
|
||||
record.get().mWeight = value.toFloat();
|
||||
container.mWeight = value.toFloat();
|
||||
else if (column==mOrganic)
|
||||
{
|
||||
if (value.toInt())
|
||||
record.get().mFlags |= ESM::Container::Organic;
|
||||
container.mFlags |= ESM::Container::Organic;
|
||||
else
|
||||
record.get().mFlags &= ~ESM::Container::Organic;
|
||||
container.mFlags &= ~ESM::Container::Organic;
|
||||
}
|
||||
else if (column==mRespawn)
|
||||
{
|
||||
if (value.toInt())
|
||||
record.get().mFlags |= ESM::Container::Respawn;
|
||||
container.mFlags |= ESM::Container::Respawn;
|
||||
else
|
||||
record.get().mFlags &= ~ESM::Container::Respawn;
|
||||
container.mFlags &= ~ESM::Container::Respawn;
|
||||
}
|
||||
else
|
||||
{
|
||||
NameRefIdAdapter<ESM::Container>::setData (column, data, index, value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(container);
|
||||
}
|
||||
|
||||
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>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature)));
|
||||
|
||||
ESM::Creature creature = record.get();
|
||||
|
||||
if (column==mColumns.mType)
|
||||
record.get().mData.mType = value.toInt();
|
||||
creature.mData.mType = value.toInt();
|
||||
else if (column==mColumns.mSoul)
|
||||
record.get().mData.mSoul = value.toInt();
|
||||
creature.mData.mSoul = value.toInt();
|
||||
else if (column==mColumns.mScale)
|
||||
record.get().mScale = value.toFloat();
|
||||
creature.mScale = value.toFloat();
|
||||
else if (column==mColumns.mOriginal)
|
||||
record.get().mOriginal = value.toString().toUtf8().constData();
|
||||
creature.mOriginal = value.toString().toUtf8().constData();
|
||||
else if (column==mColumns.mCombat)
|
||||
record.get().mData.mCombat = value.toInt();
|
||||
creature.mData.mCombat = value.toInt();
|
||||
else if (column==mColumns.mMagic)
|
||||
record.get().mData.mMagic = value.toInt();
|
||||
creature.mData.mMagic = value.toInt();
|
||||
else if (column==mColumns.mStealth)
|
||||
record.get().mData.mStealth = value.toInt();
|
||||
creature.mData.mStealth = value.toInt();
|
||||
else
|
||||
{
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
|
@ -325,15 +374,21 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
|
|||
if (iter!=mColumns.mFlags.end())
|
||||
{
|
||||
if (value.toInt()!=0)
|
||||
record.get().mFlags |= iter->second;
|
||||
creature.mFlags |= iter->second;
|
||||
else
|
||||
record.get().mFlags &= ~iter->second;
|
||||
creature.mFlags &= ~iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
ActorRefIdAdapter<ESM::Creature>::setData (column, data, index, value);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
record.setModified(creature);
|
||||
}
|
||||
|
||||
CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns,
|
||||
const RefIdColumn *openSound, const RefIdColumn *closeSound)
|
||||
: NameRefIdAdapter<ESM::Door> (UniversalId::Type_Door, columns), mOpenSound (openSound),
|
||||
|
@ -361,12 +416,20 @@ void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
|
|||
Record<ESM::Door>& record = static_cast<Record<ESM::Door>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door)));
|
||||
|
||||
ESM::Door door = record.get();
|
||||
|
||||
if (column==mOpenSound)
|
||||
record.get().mOpenSound = value.toString().toUtf8().constData();
|
||||
door.mOpenSound = value.toString().toUtf8().constData();
|
||||
else if (column==mCloseSound)
|
||||
record.get().mCloseSound = value.toString().toUtf8().constData();
|
||||
door.mCloseSound = value.toString().toUtf8().constData();
|
||||
else
|
||||
{
|
||||
NameRefIdAdapter<ESM::Door>::setData (column, data, index, value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(door);
|
||||
}
|
||||
|
||||
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>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light)));
|
||||
|
||||
ESM::Light light = record.get();
|
||||
|
||||
if (column==mColumns.mTime)
|
||||
record.get().mData.mTime = value.toInt();
|
||||
light.mData.mTime = value.toInt();
|
||||
else if (column==mColumns.mRadius)
|
||||
record.get().mData.mRadius = value.toInt();
|
||||
light.mData.mRadius = value.toInt();
|
||||
else if (column==mColumns.mColor)
|
||||
record.get().mData.mColor = value.toInt();
|
||||
light.mData.mColor = value.toInt();
|
||||
else if (column==mColumns.mSound)
|
||||
record.get().mSound = value.toString().toUtf8().constData();
|
||||
light.mSound = value.toString().toUtf8().constData();
|
||||
else
|
||||
{
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
|
@ -425,15 +490,21 @@ void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
|
|||
if (iter!=mColumns.mFlags.end())
|
||||
{
|
||||
if (value.toInt()!=0)
|
||||
record.get().mData.mFlags |= iter->second;
|
||||
light.mData.mFlags |= iter->second;
|
||||
else
|
||||
record.get().mData.mFlags &= ~iter->second;
|
||||
light.mData.mFlags &= ~iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
InventoryRefIdAdapter<ESM::Light>::setData (column, data, index, value);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
record.setModified (light);
|
||||
}
|
||||
|
||||
CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key)
|
||||
: InventoryRefIdAdapter<ESM::Miscellaneous> (UniversalId::Type_Miscellaneous, columns), mKey (key)
|
||||
{}
|
||||
|
@ -456,10 +527,18 @@ void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData&
|
|||
Record<ESM::Miscellaneous>& record = static_cast<Record<ESM::Miscellaneous>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous)));
|
||||
|
||||
ESM::Miscellaneous misc = record.get();
|
||||
|
||||
if (column==mKey)
|
||||
record.get().mData.mIsKey = value.toInt();
|
||||
misc.mData.mIsKey = value.toInt();
|
||||
else
|
||||
{
|
||||
InventoryRefIdAdapter<ESM::Miscellaneous>::setData (column, data, index, value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
record.setModified(misc);
|
||||
}
|
||||
|
||||
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>&> (
|
||||
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
|
||||
|
||||
ESM::NPC npc = record.get();
|
||||
|
||||
if (column==mColumns.mRace)
|
||||
record.get().mRace = value.toString().toUtf8().constData();
|
||||
npc.mRace = value.toString().toUtf8().constData();
|
||||
else if (column==mColumns.mClass)
|
||||
record.get().mClass = value.toString().toUtf8().constData();
|
||||
npc.mClass = value.toString().toUtf8().constData();
|
||||
else if (column==mColumns.mFaction)
|
||||
record.get().mFaction = value.toString().toUtf8().constData();
|
||||
npc.mFaction = value.toString().toUtf8().constData();
|
||||
else if (column==mColumns.mHair)
|
||||
record.get().mHair = value.toString().toUtf8().constData();
|
||||
npc.mHair = value.toString().toUtf8().constData();
|
||||
else if (column==mColumns.mHead)
|
||||
record.get().mHead = value.toString().toUtf8().constData();
|
||||
npc.mHead = value.toString().toUtf8().constData();
|
||||
else
|
||||
{
|
||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||
|
@ -543,15 +624,25 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d
|
|||
if (iter!=mColumns.mFlags.end())
|
||||
{
|
||||
if (value.toInt()!=0)
|
||||
record.get().mFlags |= iter->second;
|
||||
npc.mFlags |= iter->second;
|
||||
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
|
||||
{
|
||||
ActorRefIdAdapter<ESM::NPC>::setData (column, data, index, value);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
record.setModified (npc);
|
||||
}
|
||||
|
||||
CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter ()
|
||||
{}
|
||||
|
||||
|
|
|
@ -673,44 +673,32 @@ namespace MWMechanics
|
|||
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();
|
||||
|
||||
float dist;
|
||||
|
||||
if (!mPathFinder.getPath().empty())
|
||||
{
|
||||
ESM::Pathgrid::Point lastPt = mPathFinder.getPath().back();
|
||||
osg::Vec3f currPathTarget(PathFinder::MakeOsgVec3(lastPt));
|
||||
dist = (newPathTarget - currPathTarget).length();
|
||||
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 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]
|
||||
if(dist > targetPosThreshold)
|
||||
{
|
||||
ESM::Position pos = actor.getRefData().getPosition();
|
||||
|
||||
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);
|
||||
// necessarily construct a new path
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!mPathFinder.getPath().empty())
|
||||
void AiCombat::buildNewPath(const MWWorld::Ptr& actor, const MWWorld::Ptr& target)
|
||||
{
|
||||
newPathFinder.syncStart(mPathFinder.getPath());
|
||||
mPathFinder = newPathFinder;
|
||||
}
|
||||
}
|
||||
ESM::Pathgrid::Point newPathTarget = PathFinder::MakePathgridPoint(target.getRefData().getPosition());
|
||||
|
||||
//construct new path only if target has moved away more than on [targetPosThreshold]
|
||||
if (doesPathNeedRecalc(newPathTarget, actor.getCell()->getCell()))
|
||||
{
|
||||
ESM::Pathgrid::Point start(PathFinder::MakePathgridPoint(actor.getRefData().getPosition()));
|
||||
mPathFinder.buildSyncedPath(start, newPathTarget, actor.getCell(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,9 @@ namespace MWMechanics
|
|||
|
||||
virtual void writeState(ESM::AiSequence::AiSequence &sequence) const;
|
||||
|
||||
protected:
|
||||
virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell);
|
||||
|
||||
private:
|
||||
|
||||
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
|
||||
|
||||
/// 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();
|
||||
const ESM::Cell *cell = actor.getCell()->getCell();
|
||||
Movement &movement = actor.getClass().getMovementSettings(actor);
|
||||
|
||||
//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(distance(mPrevDest, dest) > 10) { //Only rebuild path if it's moved
|
||||
mPathFinder.buildPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved
|
||||
if (doesPathNeedRecalc(dest, cell)) { //Only rebuild path if it's moved
|
||||
mPathFinder.buildSyncedPath(start, dest, actor.getCell(), true); //Rebuild path, in case the target has moved
|
||||
mPrevDest = dest;
|
||||
}
|
||||
|
||||
|
@ -121,3 +121,8 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
|
|||
|
||||
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 <components/esm/defs.hpp>
|
||||
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
|
||||
#include "obstacle.hpp"
|
||||
#include "aistate.hpp"
|
||||
|
||||
|
@ -71,6 +73,8 @@ namespace MWMechanics
|
|||
/** \return If the actor has arrived at his destination **/
|
||||
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
|
||||
PathFinder mPathFinder;
|
||||
ObstacleCheck mObstacleCheck;
|
||||
|
|
|
@ -49,64 +49,31 @@ namespace MWMechanics
|
|||
|
||||
bool AiTravel::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||
{
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
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).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()))
|
||||
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;
|
||||
if (!mPathFinder.isPathConstructed() || cellChange)
|
||||
{
|
||||
mCellX = cell->mData.mX;
|
||||
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;
|
||||
}
|
||||
|
||||
zTurn(actor, osg::DegreesToRadians(mPathFinder.getZAngleToNext(pos.pos[0], pos.pos[1])));
|
||||
movement.mPosition[1] = 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ namespace MWMechanics
|
|||
|
||||
virtual int getTypeId() const;
|
||||
|
||||
protected:
|
||||
virtual bool doesPathNeedRecalc(ESM::Pathgrid::Point dest, const ESM::Cell *cell);
|
||||
|
||||
private:
|
||||
float mX;
|
||||
float mY;
|
||||
|
|
|
@ -298,23 +298,35 @@ namespace MWMechanics
|
|||
return false;
|
||||
}
|
||||
|
||||
// used by AiCombat, see header for the rationale
|
||||
bool PathFinder::syncStart(const std::list<ESM::Pathgrid::Point> &path)
|
||||
// see header for the rationale
|
||||
void PathFinder::buildSyncedPath(const ESM::Pathgrid::Point &startPoint,
|
||||
const ESM::Pathgrid::Point &endPoint,
|
||||
const MWWorld::CellStore* cell,
|
||||
bool allowShortcuts)
|
||||
{
|
||||
if (mPath.size() < 2)
|
||||
return false; //nothing to pop
|
||||
|
||||
std::list<ESM::Pathgrid::Point>::const_iterator oldStart = path.begin();
|
||||
{
|
||||
// if path has one point, then it's the destination.
|
||||
// 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)
|
||||
if (iter->mX == oldStart.mX
|
||||
&& iter->mY == oldStart.mY
|
||||
&& iter->mZ == oldStart.mZ)
|
||||
{
|
||||
mPath.pop_front();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -61,13 +61,13 @@ namespace MWMechanics
|
|||
|
||||
/** Synchronize new path with old one to avoid visiting 1 waypoint 2 times
|
||||
@note
|
||||
If the first point is chosen as the nearest one
|
||||
the situation can occur when the 1st point of the new path is undesirable
|
||||
(i.e. the 2nd point of new path == the 1st point of old path).
|
||||
@param path - old path
|
||||
@return true if such point was found and deleted
|
||||
BuildPath() takes closest PathGrid point to NPC as first point of path.
|
||||
This is undesireable if NPC has just passed a Pathgrid point, as this
|
||||
makes the 2nd point of the new path == the 1st point of old path.
|
||||
Which results in NPC "running in a circle" back to the just passed waypoint.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -188,7 +188,7 @@ namespace MWWorld
|
|||
const T *ptr = search(id);
|
||||
if (ptr == 0) {
|
||||
std::ostringstream msg;
|
||||
msg << "Object '" << id << "' not found (const)";
|
||||
msg << T::getRecordType() << " '" << id << "' not found";
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
return ptr;
|
||||
|
@ -202,7 +202,7 @@ namespace MWWorld
|
|||
if(ptr == 0)
|
||||
{
|
||||
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());
|
||||
}
|
||||
return ptr;
|
||||
|
@ -989,7 +989,7 @@ namespace MWWorld
|
|||
const T *ptr = search(index);
|
||||
if (ptr == 0) {
|
||||
std::ostringstream msg;
|
||||
msg << "Object with index " << index << " not found";
|
||||
msg << T::getRecordType() << " with index " << index << " not found";
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
return ptr;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "gamesettings.hpp"
|
||||
#include "launchersettings.hpp"
|
||||
|
||||
#include <QTextCodec>
|
||||
#include <QTextStream>
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
|
@ -174,138 +173,6 @@ bool Config::GameSettings::writeFile(QTextStream &stream)
|
|||
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 result = false;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <QTextStream>
|
||||
#include <QStringList>
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <QMap>
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
@ -67,7 +66,6 @@ namespace Config
|
|||
bool readUserFile(QTextStream &stream);
|
||||
|
||||
bool writeFile(QTextStream &stream);
|
||||
bool writeFileWithComments(QFile &file);
|
||||
|
||||
void setContentList(const QStringList& fileNames);
|
||||
QStringList getContentList() const;
|
||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
|||
struct Activator
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@ struct Potion
|
|||
{
|
||||
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
|
||||
{
|
||||
float mWeight;
|
||||
|
|
|
@ -16,6 +16,8 @@ class ESMWriter;
|
|||
struct Apparatus
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -66,6 +66,8 @@ struct PartReferenceList
|
|||
struct Armor
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
|||
struct BodyPart
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -15,6 +15,8 @@ class ESMWriter;
|
|||
struct Book
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -14,6 +14,8 @@ class ESMWriter;
|
|||
struct BirthSign
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ typedef std::list<CellRef> CellRefTracker;
|
|||
struct Cell
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
|||
struct Class
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
|||
struct Clothing
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -36,6 +36,8 @@ struct InventoryList
|
|||
struct Container
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -22,6 +22,8 @@ class ESMWriter;
|
|||
struct Creature
|
||||
{
|
||||
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?
|
||||
enum Flags
|
||||
|
|
|
@ -21,6 +21,8 @@ class ESMWriter;
|
|||
struct Dialogue
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
|||
struct Door
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
|||
struct Enchantment
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -30,6 +30,8 @@ struct RankData
|
|||
struct Faction
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
|||
struct Global
|
||||
{
|
||||
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;
|
||||
Variant mValue;
|
||||
|
|
|
@ -19,6 +19,8 @@ class ESMWriter;
|
|||
struct GameSetting
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ class ESMWriter;
|
|||
struct DialInfo
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -16,6 +16,8 @@ class ESMWriter;
|
|||
struct Ingredient
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
|||
struct Land
|
||||
{
|
||||
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();
|
||||
|
|
|
@ -46,6 +46,8 @@ struct LevelledListBase
|
|||
struct CreatureLevList: LevelledListBase
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -64,6 +66,8 @@ struct CreatureLevList: LevelledListBase
|
|||
struct ItemLevList: LevelledListBase
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -17,6 +17,8 @@ class ESMWriter;
|
|||
struct Light
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
|||
struct Lockpick
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -28,6 +28,8 @@ class ESMWriter;
|
|||
struct LandTexture
|
||||
{
|
||||
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;
|
||||
int mIndex;
|
||||
|
|
|
@ -13,6 +13,8 @@ class ESMWriter;
|
|||
struct MagicEffect
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ class ESMWriter;
|
|||
struct Miscellaneous
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -23,6 +23,8 @@ class ESMWriter;
|
|||
struct NPC
|
||||
{
|
||||
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
|
||||
enum Services
|
||||
|
@ -55,7 +57,7 @@ struct NPC
|
|||
Female = 0x0001,
|
||||
Essential = 0x0002,
|
||||
Respawn = 0x0004,
|
||||
Autocalc = 0x0008,
|
||||
Autocalc = 0x0010,
|
||||
Skeleton = 0x0400, // Skeleton blood effect (white)
|
||||
Metal = 0x0800 // Metal blood effect (golden?)
|
||||
};
|
||||
|
|
|
@ -16,6 +16,8 @@ class ESMWriter;
|
|||
struct Pathgrid
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
|||
struct Probe
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -18,6 +18,8 @@ class ESMWriter;
|
|||
struct Race
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -19,6 +19,8 @@ class ESMWriter;
|
|||
struct Region
|
||||
{
|
||||
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(1)
|
||||
|
|
|
@ -12,6 +12,8 @@ class ESMWriter;
|
|||
struct Repair
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -20,6 +20,8 @@ class Script
|
|||
{
|
||||
public:
|
||||
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
|
||||
{
|
||||
|
|
|
@ -20,6 +20,8 @@ class ESMWriter;
|
|||
struct Skill
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ class ESMWriter;
|
|||
struct SoundGenerator
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -17,6 +17,8 @@ struct SOUNstruct
|
|||
struct Sound
|
||||
{
|
||||
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;
|
||||
std::string mId, mSound;
|
||||
|
|
|
@ -14,6 +14,8 @@ class ESMWriter;
|
|||
struct Spell
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -20,6 +20,8 @@ class ESMWriter;
|
|||
struct StartScript
|
||||
{
|
||||
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 mId;
|
||||
|
|
|
@ -23,6 +23,8 @@ class ESMWriter;
|
|||
struct Static
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ class ESMWriter;
|
|||
struct Weapon
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue