forked from teamnwah/openmw-tes3coop
Merge branch 'master' of git://github.com/zinnschlag/openmw into companion
This commit is contained in:
commit
1a2daa3bc1
41 changed files with 490 additions and 160 deletions
|
@ -627,10 +627,10 @@ 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_Playable) properties += "Playable ";
|
if (flags & ESM::BodyPart::BPF_NotPlayable) properties += "NotPlayable ";
|
||||||
int unused = (0xFFFFFFFF ^
|
int unused = (0xFFFFFFFF ^
|
||||||
(ESM::BodyPart::BPF_Female|
|
(ESM::BodyPart::BPF_Female|
|
||||||
ESM::BodyPart::BPF_Playable));
|
ESM::BodyPart::BPF_NotPlayable));
|
||||||
if (flags & unused) properties += "Invalid ";
|
if (flags & unused) properties += "Invalid ";
|
||||||
properties += str(boost::format("(0x%08X)") % flags);
|
properties += str(boost::format("(0x%08X)") % flags);
|
||||||
return properties;
|
return properties;
|
||||||
|
|
|
@ -207,7 +207,7 @@ void CSMDoc::Document::createBase()
|
||||||
{
|
{
|
||||||
ESM::Skill record;
|
ESM::Skill record;
|
||||||
record.mIndex = i;
|
record.mIndex = i;
|
||||||
record.mId = ESM::Skill::getIndexToId (record.mIndex);
|
record.mId = ESM::Skill::indexToId (record.mIndex);
|
||||||
record.blank();
|
record.blank();
|
||||||
|
|
||||||
getData().getSkills().add (record);
|
getData().getSkills().add (record);
|
||||||
|
|
|
@ -33,7 +33,8 @@ namespace CSMWorld
|
||||||
Display_GmstVarType,
|
Display_GmstVarType,
|
||||||
Display_GlobalVarType,
|
Display_GlobalVarType,
|
||||||
Display_Specialisation,
|
Display_Specialisation,
|
||||||
Display_Attribute
|
Display_Attribute,
|
||||||
|
Display_Boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string mTitle;
|
std::string mTitle;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef CSM_WOLRD_COLUMNS_H
|
#ifndef CSM_WOLRD_COLUMNS_H
|
||||||
#define CSM_WOLRD_COLUMNS_H
|
#define CSM_WOLRD_COLUMNS_H
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#include "columnbase.hpp"
|
#include "columnbase.hpp"
|
||||||
|
@ -285,6 +287,128 @@ namespace CSMWorld
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename ESXRecordT>
|
||||||
|
struct NameColumn : public Column<ESXRecordT>
|
||||||
|
{
|
||||||
|
NameColumn() : Column<ESXRecordT> ("Name", ColumnBase::Display_String) {}
|
||||||
|
|
||||||
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
|
{
|
||||||
|
return QString::fromUtf8 (record.get().mName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
ESXRecordT record2 = record.get();
|
||||||
|
|
||||||
|
record2.mName = data.toString().toUtf8().constData();
|
||||||
|
|
||||||
|
record.setModified (record2);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ESXRecordT>
|
||||||
|
struct AttributesColumn : public Column<ESXRecordT>
|
||||||
|
{
|
||||||
|
int mIndex;
|
||||||
|
|
||||||
|
AttributesColumn (int index)
|
||||||
|
: Column<ESXRecordT> ("Attribute #" + boost::lexical_cast<std::string> (index),
|
||||||
|
ColumnBase::Display_Attribute), mIndex (index) {}
|
||||||
|
|
||||||
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
|
{
|
||||||
|
return record.get().mData.mAttribute[mIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
ESXRecordT record2 = record.get();
|
||||||
|
|
||||||
|
record2.mData.mAttribute[mIndex] = data.toInt();
|
||||||
|
|
||||||
|
record.setModified (record2);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ESXRecordT>
|
||||||
|
struct SkillsColumn : public Column<ESXRecordT>
|
||||||
|
{
|
||||||
|
int mIndex;
|
||||||
|
bool mMajor;
|
||||||
|
|
||||||
|
SkillsColumn (int index, bool major)
|
||||||
|
: Column<ESXRecordT> ((major ? "Major Skill #" : "Minor Skill #")+
|
||||||
|
boost::lexical_cast<std::string> (index), ColumnBase::Display_String),
|
||||||
|
mIndex (index), mMajor (major)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
|
{
|
||||||
|
int skill = record.get().mData.mSkills[mIndex][mMajor ? 1 : 0];
|
||||||
|
|
||||||
|
return QString::fromUtf8 (ESM::Skill::indexToId (skill).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
std::istringstream stream (data.toString().toUtf8().constData());
|
||||||
|
|
||||||
|
int index = -1;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
stream >> c >> index;
|
||||||
|
|
||||||
|
if (index!=-1)
|
||||||
|
{
|
||||||
|
ESXRecordT record2 = record.get();
|
||||||
|
|
||||||
|
record2.mData.mSkills[mIndex][mMajor ? 1 : 0] = index;
|
||||||
|
|
||||||
|
record.setModified (record2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ESXRecordT>
|
||||||
|
struct PlayableColumn : public Column<ESXRecordT>
|
||||||
|
{
|
||||||
|
PlayableColumn() : Column<ESXRecordT> ("Playable", ColumnBase::Display_Boolean) {}
|
||||||
|
|
||||||
|
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||||
|
{
|
||||||
|
return record.get().mData.mIsPlayable!=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
ESXRecordT record2 = record.get();
|
||||||
|
|
||||||
|
record2.mData.mIsPlayable = data.toInt();
|
||||||
|
|
||||||
|
record.setModified (record2);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -44,9 +44,23 @@ CSMWorld::Data::Data()
|
||||||
mSkills.addColumn (new UseValueColumn<ESM::Skill> (i));
|
mSkills.addColumn (new UseValueColumn<ESM::Skill> (i));
|
||||||
mSkills.addColumn (new DescriptionColumn<ESM::Skill>);
|
mSkills.addColumn (new DescriptionColumn<ESM::Skill>);
|
||||||
|
|
||||||
|
mClasses.addColumn (new StringIdColumn<ESM::Class>);
|
||||||
|
mClasses.addColumn (new RecordStateColumn<ESM::Class>);
|
||||||
|
mClasses.addColumn (new NameColumn<ESM::Class>);
|
||||||
|
mClasses.addColumn (new AttributesColumn<ESM::Class> (0));
|
||||||
|
mClasses.addColumn (new AttributesColumn<ESM::Class> (1));
|
||||||
|
mClasses.addColumn (new SpecialisationColumn<ESM::Class>);
|
||||||
|
for (int i=0; i<5; ++i)
|
||||||
|
mClasses.addColumn (new SkillsColumn<ESM::Class> (i, true));
|
||||||
|
for (int i=0; i<5; ++i)
|
||||||
|
mClasses.addColumn (new SkillsColumn<ESM::Class> (i, false));
|
||||||
|
mClasses.addColumn (new PlayableColumn<ESM::Class>);
|
||||||
|
mClasses.addColumn (new DescriptionColumn<ESM::Class>);
|
||||||
|
|
||||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
||||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
||||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
|
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
|
||||||
|
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMWorld::Data::~Data()
|
CSMWorld::Data::~Data()
|
||||||
|
@ -122,6 +136,7 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base)
|
||||||
case ESM::REC_GLOB: mGlobals.load (reader, base); break;
|
case ESM::REC_GLOB: mGlobals.load (reader, base); break;
|
||||||
case ESM::REC_GMST: mGmsts.load (reader, base); break;
|
case ESM::REC_GMST: mGmsts.load (reader, base); break;
|
||||||
case ESM::REC_SKIL: mSkills.load (reader, base); break;
|
case ESM::REC_SKIL: mSkills.load (reader, base); break;
|
||||||
|
case ESM::REC_CLAS: mClasses.load (reader, base); break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <components/esm/loadglob.hpp>
|
#include <components/esm/loadglob.hpp>
|
||||||
#include <components/esm/loadgmst.hpp>
|
#include <components/esm/loadgmst.hpp>
|
||||||
#include <components/esm/loadskil.hpp>
|
#include <components/esm/loadskil.hpp>
|
||||||
|
#include <components/esm/loadclas.hpp>
|
||||||
|
|
||||||
#include "idcollection.hpp"
|
#include "idcollection.hpp"
|
||||||
#include "universalid.hpp"
|
#include "universalid.hpp"
|
||||||
|
@ -22,6 +23,7 @@ namespace CSMWorld
|
||||||
IdCollection<ESM::Global> mGlobals;
|
IdCollection<ESM::Global> mGlobals;
|
||||||
IdCollection<ESM::GameSetting> mGmsts;
|
IdCollection<ESM::GameSetting> mGmsts;
|
||||||
IdCollection<ESM::Skill> mSkills;
|
IdCollection<ESM::Skill> mSkills;
|
||||||
|
IdCollection<ESM::Class> mClasses;
|
||||||
std::vector<QAbstractItemModel *> mModels;
|
std::vector<QAbstractItemModel *> mModels;
|
||||||
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings" },
|
||||||
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills" },
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills" },
|
||||||
|
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Classes, "Classes" },
|
||||||
|
|
||||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||||
};
|
};
|
||||||
|
@ -29,6 +30,7 @@ namespace
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" },
|
||||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill" },
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill" },
|
||||||
|
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class" },
|
||||||
|
|
||||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,7 +39,9 @@ namespace CSMWorld
|
||||||
Type_Gmsts,
|
Type_Gmsts,
|
||||||
Type_Gmst,
|
Type_Gmst,
|
||||||
Type_Skills,
|
Type_Skills,
|
||||||
Type_Skill
|
Type_Skill,
|
||||||
|
Type_Classes,
|
||||||
|
Type_Class
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -90,6 +90,10 @@ void CSVDoc::View::setupWorldMenu()
|
||||||
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView()));
|
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView()));
|
||||||
world->addAction (skills);
|
world->addAction (skills);
|
||||||
|
|
||||||
|
QAction *classes = new QAction (tr ("Classes"), this);
|
||||||
|
connect (classes, SIGNAL (triggered()), this, SLOT (addClassesSubView()));
|
||||||
|
world->addAction (classes);
|
||||||
|
|
||||||
mVerify = new QAction (tr ("&Verify"), this);
|
mVerify = new QAction (tr ("&Verify"), this);
|
||||||
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
||||||
world->addAction (mVerify);
|
world->addAction (mVerify);
|
||||||
|
@ -253,6 +257,11 @@ void CSVDoc::View::addSkillsSubView()
|
||||||
addSubView (CSMWorld::UniversalId::Type_Skills);
|
addSubView (CSMWorld::UniversalId::Type_Skills);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVDoc::View::addClassesSubView()
|
||||||
|
{
|
||||||
|
addSubView (CSMWorld::UniversalId::Type_Classes);
|
||||||
|
}
|
||||||
|
|
||||||
void CSVDoc::View::abortOperation (int type)
|
void CSVDoc::View::abortOperation (int type)
|
||||||
{
|
{
|
||||||
mDocument->abortOperation (type);
|
mDocument->abortOperation (type);
|
||||||
|
|
|
@ -117,6 +117,8 @@ namespace CSVDoc
|
||||||
void addGmstsSubView();
|
void addGmstsSubView();
|
||||||
|
|
||||||
void addSkillsSubView();
|
void addSkillsSubView();
|
||||||
|
|
||||||
|
void addClassesSubView();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||||
manager.add (CSMWorld::UniversalId::Type_Skills,
|
manager.add (CSMWorld::UniversalId::Type_Skills,
|
||||||
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false));
|
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false));
|
||||||
|
|
||||||
manager.add (CSMWorld::UniversalId::Type_Global,
|
manager.add (CSMWorld::UniversalId::Type_Classes,
|
||||||
new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
|
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true));
|
||||||
|
|
||||||
|
// manager.add (CSMWorld::UniversalId::Type_Global,
|
||||||
|
// new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
|
||||||
}
|
}
|
|
@ -44,6 +44,11 @@ namespace MWRender
|
||||||
class Animation;
|
class Animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
class Movement;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
class Fallback;
|
class Fallback;
|
||||||
|
@ -54,7 +59,7 @@ namespace MWWorld
|
||||||
class ESMStore;
|
class ESMStore;
|
||||||
class RefData;
|
class RefData;
|
||||||
|
|
||||||
typedef std::vector<std::pair<MWWorld::Ptr,Ogre::Vector3> > PtrMovementList;
|
typedef std::vector<std::pair<MWWorld::Ptr,MWMechanics::Movement> > PtrMovementList;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWBase
|
namespace MWBase
|
||||||
|
|
|
@ -24,6 +24,18 @@
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool isGold (const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
return Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_001")
|
||||||
|
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_005")
|
||||||
|
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_010")
|
||||||
|
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_025")
|
||||||
|
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_100");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
|
@ -110,25 +122,15 @@ namespace MWClass
|
||||||
|
|
||||||
std::string Miscellaneous::getUpSoundId (const MWWorld::Ptr& ptr) const
|
std::string Miscellaneous::getUpSoundId (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
if (isGold(ptr))
|
||||||
ptr.get<ESM::Miscellaneous>();
|
|
||||||
|
|
||||||
if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGold")->getString())
|
|
||||||
{
|
|
||||||
return std::string("Item Gold Up");
|
return std::string("Item Gold Up");
|
||||||
}
|
|
||||||
return std::string("Item Misc Up");
|
return std::string("Item Misc Up");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Miscellaneous::getDownSoundId (const MWWorld::Ptr& ptr) const
|
std::string Miscellaneous::getDownSoundId (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
if (isGold(ptr))
|
||||||
ptr.get<ESM::Miscellaneous>();
|
|
||||||
|
|
||||||
if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGold")->getString())
|
|
||||||
{
|
|
||||||
return std::string("Item Gold Down");
|
return std::string("Item Gold Down");
|
||||||
}
|
|
||||||
return std::string("Item Misc Down");
|
return std::string("Item Misc Down");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,19 +161,15 @@ namespace MWClass
|
||||||
|
|
||||||
int count = ptr.getRefData().getCount();
|
int count = ptr.getRefData().getCount();
|
||||||
|
|
||||||
bool isGold = Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_001")
|
bool gold = isGold(ptr);
|
||||||
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_005")
|
|
||||||
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_010")
|
|
||||||
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_025")
|
|
||||||
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_100");
|
|
||||||
|
|
||||||
if (isGold && ptr.getCellRef().mGoldValue != 1)
|
if (gold && ptr.getCellRef().mGoldValue != 1)
|
||||||
count = ptr.getCellRef().mGoldValue;
|
count = ptr.getCellRef().mGoldValue;
|
||||||
else if (isGold)
|
else if (gold)
|
||||||
count *= ref->mBase->mData.mValue;
|
count *= ref->mBase->mData.mValue;
|
||||||
|
|
||||||
std::string countString;
|
std::string countString;
|
||||||
if (!isGold)
|
if (!gold)
|
||||||
countString = MWGui::ToolTips::getCountString(count);
|
countString = MWGui::ToolTips::getCountString(count);
|
||||||
else // gold displays its count also if it's 1.
|
else // gold displays its count also if it's 1.
|
||||||
countString = " (" + boost::lexical_cast<std::string>(count) + ")";
|
countString = " (" + boost::lexical_cast<std::string>(count) + ")";
|
||||||
|
@ -187,7 +185,7 @@ namespace MWClass
|
||||||
|
|
||||||
std::string text;
|
std::string text;
|
||||||
|
|
||||||
if (!isGold)
|
if (!gold)
|
||||||
{
|
{
|
||||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
||||||
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
|
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
|
||||||
|
@ -211,7 +209,7 @@ namespace MWClass
|
||||||
const MWWorld::ESMStore &store =
|
const MWWorld::ESMStore &store =
|
||||||
MWBase::Environment::get().getWorld()->getStore();
|
MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
if (MWWorld::Class::get(ptr).getName(ptr) == store.get<ESM::GameSetting>().find("sGold")->getString()) {
|
if (isGold(ptr)) {
|
||||||
int goldAmount = ptr.getRefData().getCount();
|
int goldAmount = ptr.getRefData().getCount();
|
||||||
|
|
||||||
std::string base = "Gold_001";
|
std::string base = "Gold_001";
|
||||||
|
|
|
@ -368,7 +368,7 @@ namespace MWClass
|
||||||
moveSpeed = runSpeed;
|
moveSpeed = runSpeed;
|
||||||
else
|
else
|
||||||
moveSpeed = walkSpeed;
|
moveSpeed = walkSpeed;
|
||||||
if(getMovementSettings(ptr).mLeftRight != 0 && getMovementSettings(ptr).mForwardBackward == 0)
|
if(getMovementSettings(ptr).mPosition[0] != 0 && getMovementSettings(ptr).mPosition[1] == 0)
|
||||||
moveSpeed *= 0.75f;
|
moveSpeed *= 0.75f;
|
||||||
|
|
||||||
return moveSpeed;
|
return moveSpeed;
|
||||||
|
@ -414,12 +414,22 @@ namespace MWClass
|
||||||
|
|
||||||
Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
|
Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
Ogre::Vector3 vector;
|
MWMechanics::Movement &movement = getMovementSettings(ptr);
|
||||||
vector.x = getMovementSettings(ptr).mLeftRight;
|
Ogre::Vector3 vec(movement.mPosition);
|
||||||
vector.y = getMovementSettings(ptr).mForwardBackward;
|
movement.mPosition[0] = 0.0f;
|
||||||
vector.z = getMovementSettings(ptr).mUpDown;
|
movement.mPosition[1] = 0.0f;
|
||||||
|
movement.mPosition[2] = 0.0f;
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
return vector;
|
Ogre::Vector3 Npc::getRotationVector (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
MWMechanics::Movement &movement = getMovementSettings(ptr);
|
||||||
|
Ogre::Vector3 vec(movement.mRotation);
|
||||||
|
movement.mRotation[0] = 0.0f;
|
||||||
|
movement.mRotation[1] = 0.0f;
|
||||||
|
movement.mRotation[2] = 0.0f;
|
||||||
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Npc::isEssential (const MWWorld::Ptr& ptr) const
|
bool Npc::isEssential (const MWWorld::Ptr& ptr) const
|
||||||
|
|
|
@ -96,6 +96,9 @@ namespace MWClass
|
||||||
///< Return desired movement vector (determined based on movement settings,
|
///< Return desired movement vector (determined based on movement settings,
|
||||||
/// stance and stats).
|
/// stance and stats).
|
||||||
|
|
||||||
|
virtual Ogre::Vector3 getRotationVector (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return desired rotations, as euler angles.
|
||||||
|
|
||||||
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
|
virtual float getCapacity (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return total weight that fits into the object. Throws an exception, if the object can't
|
///< Return total weight that fits into the object. Throws an exception, if the object can't
|
||||||
/// hold other objects.
|
/// hold other objects.
|
||||||
|
|
|
@ -140,13 +140,8 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
|
||||||
|
|
||||||
if (isInventory())
|
if (isInventory())
|
||||||
{
|
{
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
|
||||||
|
|
||||||
// the player is trying to sell an item, check if the merchant accepts it
|
// the player is trying to sell an item, check if the merchant accepts it
|
||||||
// also, don't allow selling gold (let's be better than Morrowind at this, can we?)
|
if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object))
|
||||||
if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object) ||
|
|
||||||
MWWorld::Class::get(object).getName(object) == gmst.find("sGold")->getString())
|
|
||||||
{
|
{
|
||||||
// user notification "i don't buy this item"
|
// user notification "i don't buy this item"
|
||||||
MWBase::Environment::get().getWindowManager()->
|
MWBase::Environment::get().getWindowManager()->
|
||||||
|
|
|
@ -19,6 +19,49 @@
|
||||||
using namespace MWGui;
|
using namespace MWGui;
|
||||||
using namespace Widgets;
|
using namespace Widgets;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
int wrap(int index, int max)
|
||||||
|
{
|
||||||
|
if (index < 0)
|
||||||
|
return max - 1;
|
||||||
|
else if (index >= max)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int countParts(const std::string &part, const std::string &race, bool male)
|
||||||
|
{
|
||||||
|
/// \todo loop through the whole store for appropriate bodyparts instead of looking for fixed IDs
|
||||||
|
const MWWorld::Store<ESM::BodyPart> &store =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
||||||
|
|
||||||
|
std::string prefix =
|
||||||
|
"b_n_" + race + ((male) ? "_m_" : "_f_") + part;
|
||||||
|
|
||||||
|
std::string suffix;
|
||||||
|
suffix.reserve(prefix.size() + 3);
|
||||||
|
|
||||||
|
int count = -1;
|
||||||
|
do {
|
||||||
|
++count;
|
||||||
|
suffix = "_" + (boost::format("%02d") % (count + 1)).str();
|
||||||
|
}
|
||||||
|
while (store.search(prefix + suffix) != 0);
|
||||||
|
|
||||||
|
if (count == 0 && part == "hair") {
|
||||||
|
count = -1;
|
||||||
|
do {
|
||||||
|
++count;
|
||||||
|
suffix = (boost::format("%02d") % (count + 1)).str();
|
||||||
|
}
|
||||||
|
while (store.search(prefix + suffix) != 0);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
|
RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
|
||||||
: WindowModal("openmw_chargen_race.layout", parWindowManager)
|
: WindowModal("openmw_chargen_race.layout", parWindowManager)
|
||||||
, mGenderIndex(0)
|
, mGenderIndex(0)
|
||||||
|
@ -144,45 +187,6 @@ void RaceDialog::setRaceId(const std::string &raceId)
|
||||||
updateSpellPowers();
|
updateSpellPowers();
|
||||||
}
|
}
|
||||||
|
|
||||||
int wrap(int index, int max)
|
|
||||||
{
|
|
||||||
if (index < 0)
|
|
||||||
return max - 1;
|
|
||||||
else if (index >= max)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
int countParts(const std::string &part, const std::string &race, bool male)
|
|
||||||
{
|
|
||||||
const MWWorld::Store<ESM::BodyPart> &store =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
|
||||||
|
|
||||||
std::string prefix =
|
|
||||||
"b_n_" + race + ((male) ? "_m_" : "_f_") + part;
|
|
||||||
|
|
||||||
std::string suffix;
|
|
||||||
suffix.reserve(prefix.size() + 3);
|
|
||||||
|
|
||||||
int count = -1;
|
|
||||||
do {
|
|
||||||
++count;
|
|
||||||
suffix = "_" + (boost::format("%02d") % (count + 1)).str();
|
|
||||||
}
|
|
||||||
while (store.search(prefix + suffix) != 0);
|
|
||||||
|
|
||||||
if (count == 0 && part == "hair") {
|
|
||||||
count = -1;
|
|
||||||
do {
|
|
||||||
++count;
|
|
||||||
suffix = (boost::format("%02d") % (count + 1)).str();
|
|
||||||
}
|
|
||||||
while (store.search(prefix + suffix) != 0);
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::close()
|
void RaceDialog::close()
|
||||||
{
|
{
|
||||||
delete mPreview;
|
delete mPreview;
|
||||||
|
@ -229,28 +233,67 @@ void RaceDialog::onSelectNextGender(MyGUI::Widget*)
|
||||||
|
|
||||||
void RaceDialog::onSelectPreviousFace(MyGUI::Widget*)
|
void RaceDialog::onSelectPreviousFace(MyGUI::Widget*)
|
||||||
{
|
{
|
||||||
mFaceIndex = wrap(mFaceIndex - 1, mFaceCount);
|
do
|
||||||
|
mFaceIndex = wrap(mFaceIndex - 1, mFaceCount);
|
||||||
|
while (!isFacePlayable());
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaceDialog::onSelectNextFace(MyGUI::Widget*)
|
void RaceDialog::onSelectNextFace(MyGUI::Widget*)
|
||||||
{
|
{
|
||||||
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
|
do
|
||||||
|
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
|
||||||
|
while (!isFacePlayable());
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaceDialog::onSelectPreviousHair(MyGUI::Widget*)
|
void RaceDialog::onSelectPreviousHair(MyGUI::Widget*)
|
||||||
{
|
{
|
||||||
mHairIndex = wrap(mHairIndex - 1, mHairCount);
|
do
|
||||||
|
mHairIndex = wrap(mHairIndex - 1, mHairCount);
|
||||||
|
while (!isHairPlayable());
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaceDialog::onSelectNextHair(MyGUI::Widget*)
|
void RaceDialog::onSelectNextHair(MyGUI::Widget*)
|
||||||
{
|
{
|
||||||
mHairIndex = wrap(mHairIndex + 1, mHairCount);
|
do
|
||||||
|
mHairIndex = wrap(mHairIndex + 1, mHairCount);
|
||||||
|
while (!isHairPlayable());
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RaceDialog::isFacePlayable()
|
||||||
|
{
|
||||||
|
std::string prefix =
|
||||||
|
"b_n_" + mCurrentRaceId + ((mGenderIndex == 0) ? "_m_" : "_f_");
|
||||||
|
|
||||||
|
std::string headIndex = (boost::format("%02d") % (mFaceIndex + 1)).str();
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::BodyPart> &parts =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
||||||
|
|
||||||
|
if (parts.search(prefix + "head_" + headIndex) == 0)
|
||||||
|
return !(parts.find(prefix + "head" + headIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
||||||
|
else
|
||||||
|
return !(parts.find(prefix + "head_" + headIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RaceDialog::isHairPlayable()
|
||||||
|
{
|
||||||
|
std::string prefix =
|
||||||
|
"b_n_" + mCurrentRaceId + ((mGenderIndex == 0) ? "_m_" : "_f_");
|
||||||
|
|
||||||
|
std::string hairIndex = (boost::format("%02d") % (mHairIndex + 1)).str();
|
||||||
|
|
||||||
|
const MWWorld::Store<ESM::BodyPart> &parts =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
|
||||||
|
if (parts.search(prefix + "hair_" + hairIndex) == 0)
|
||||||
|
return !(parts.find(prefix + "hair" + hairIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
||||||
|
else
|
||||||
|
return !(parts.find(prefix + "hair_" + hairIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
|
||||||
|
}
|
||||||
|
|
||||||
void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
|
void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
|
||||||
{
|
{
|
||||||
if (_index == MyGUI::ITEM_NONE)
|
if (_index == MyGUI::ITEM_NONE)
|
||||||
|
@ -273,11 +316,16 @@ void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
|
||||||
|
|
||||||
void RaceDialog::recountParts()
|
void RaceDialog::recountParts()
|
||||||
{
|
{
|
||||||
|
mFaceCount = countParts("head", mCurrentRaceId, mGenderIndex == 0);
|
||||||
|
mHairCount = countParts("hair", mCurrentRaceId, mGenderIndex == 0);
|
||||||
|
|
||||||
mFaceIndex = 0;
|
mFaceIndex = 0;
|
||||||
mHairIndex = 0;
|
mHairIndex = 0;
|
||||||
|
|
||||||
mFaceCount = countParts("head", mCurrentRaceId, mGenderIndex == 0);
|
while (!isHairPlayable())
|
||||||
mHairCount = countParts("hair", mCurrentRaceId, mGenderIndex == 0);
|
mHairIndex = wrap(mHairIndex + 1, mHairCount);
|
||||||
|
while (!isFacePlayable())
|
||||||
|
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update widget content
|
// update widget content
|
||||||
|
|
|
@ -81,6 +81,9 @@ namespace MWGui
|
||||||
void updatePreview();
|
void updatePreview();
|
||||||
void recountParts();
|
void recountParts();
|
||||||
|
|
||||||
|
bool isHairPlayable();
|
||||||
|
bool isFacePlayable();
|
||||||
|
|
||||||
MyGUI::ImageBox* mPreviewImage;
|
MyGUI::ImageBox* mPreviewImage;
|
||||||
MyGUI::ListBox* mRaceList;
|
MyGUI::ListBox* mRaceList;
|
||||||
MyGUI::ScrollBar* mHeadRotate;
|
MyGUI::ScrollBar* mHeadRotate;
|
||||||
|
|
|
@ -129,13 +129,10 @@ namespace MWGui
|
||||||
MWWorld::Ptr gold;
|
MWWorld::Ptr gold;
|
||||||
MWWorld::ContainerStore& playerStore = mWindowManager.getInventoryWindow()->getContainerStore();
|
MWWorld::ContainerStore& playerStore = mWindowManager.getInventoryWindow()->getContainerStore();
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
|
||||||
|
|
||||||
for (MWWorld::ContainerStoreIterator it = playerStore.begin();
|
for (MWWorld::ContainerStoreIterator it = playerStore.begin();
|
||||||
it != playerStore.end(); ++it)
|
it != playerStore.end(); ++it)
|
||||||
{
|
{
|
||||||
if (MWWorld::Class::get(*it).getName(*it) == gmst.find("sGold")->getString())
|
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001"))
|
||||||
{
|
{
|
||||||
goldFound = true;
|
goldFound = true;
|
||||||
gold = *it;
|
gold = *it;
|
||||||
|
@ -342,6 +339,9 @@ namespace MWGui
|
||||||
|
|
||||||
bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item)
|
bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item)
|
||||||
{
|
{
|
||||||
|
if (Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_001"))
|
||||||
|
return false;
|
||||||
|
|
||||||
int services = 0;
|
int services = 0;
|
||||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||||
{
|
{
|
||||||
|
|
|
@ -287,8 +287,6 @@ namespace MWInput
|
||||||
triedToMove = true;
|
triedToMove = true;
|
||||||
mPlayer.setLeftRight (1);
|
mPlayer.setLeftRight (1);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mPlayer.setLeftRight (0);
|
|
||||||
|
|
||||||
if (actionIsActive(A_MoveForward))
|
if (actionIsActive(A_MoveForward))
|
||||||
{
|
{
|
||||||
|
@ -302,8 +300,6 @@ namespace MWInput
|
||||||
mPlayer.setAutoMove (false);
|
mPlayer.setAutoMove (false);
|
||||||
mPlayer.setForwardBackward (-1);
|
mPlayer.setForwardBackward (-1);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mPlayer.setForwardBackward (0);
|
|
||||||
|
|
||||||
mPlayer.setSneak(actionIsActive(A_Sneak));
|
mPlayer.setSneak(actionIsActive(A_Sneak));
|
||||||
|
|
||||||
|
@ -312,8 +308,6 @@ namespace MWInput
|
||||||
mPlayer.setUpDown (1);
|
mPlayer.setUpDown (1);
|
||||||
triedToMove = true;
|
triedToMove = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mPlayer.setUpDown (0);
|
|
||||||
|
|
||||||
if (mAlwaysRunActive)
|
if (mAlwaysRunActive)
|
||||||
mPlayer.setRunState(!actionIsActive(A_Run));
|
mPlayer.setRunState(!actionIsActive(A_Run));
|
||||||
|
@ -542,11 +536,11 @@ namespace MWInput
|
||||||
{
|
{
|
||||||
resetIdleTime();
|
resetIdleTime();
|
||||||
|
|
||||||
float x = arg.state.X.rel * mCameraSensitivity * 0.2;
|
float x = arg.state.X.rel * mCameraSensitivity * 0.2f;
|
||||||
float y = arg.state.Y.rel * mCameraSensitivity * 0.2 * (mInvertY ? -1 : 1) * mUIYMultiplier;
|
float y = arg.state.Y.rel * mCameraSensitivity * 0.2f * (mInvertY ? -1 : 1) * mUIYMultiplier;
|
||||||
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
mPlayer.setYaw(x);
|
||||||
world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, x, true);
|
mPlayer.setPitch(-y);
|
||||||
|
|
||||||
if (arg.state.Z.rel)
|
if (arg.state.Z.rel)
|
||||||
MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.state.Z.rel);
|
MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.state.Z.rel);
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <OgreVector3.h>
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
|
#include "movement.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
|
@ -56,7 +58,10 @@ void Activators::update(float duration, bool paused)
|
||||||
if(!paused)
|
if(!paused)
|
||||||
{
|
{
|
||||||
for(PtrControllerMap::iterator iter(mActivators.begin());iter != mActivators.end();++iter)
|
for(PtrControllerMap::iterator iter(mActivators.begin());iter != mActivators.end();++iter)
|
||||||
iter->second.update(duration);
|
{
|
||||||
|
Movement movement;
|
||||||
|
iter->second.update(duration, movement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "creaturestats.hpp"
|
#include "creaturestats.hpp"
|
||||||
|
#include "movement.hpp"
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
@ -266,7 +267,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
|
for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 movement = iter->second.update(duration);
|
Movement movement;
|
||||||
|
iter->second.update(duration, movement);
|
||||||
mMovement.push_back(std::make_pair(iter->first, movement));
|
mMovement.push_back(std::make_pair(iter->first, movement));
|
||||||
}
|
}
|
||||||
MWBase::Environment::get().getWorld()->doPhysics(mMovement, duration);
|
MWBase::Environment::get().getWorld()->doPhysics(mMovement, duration);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "character.hpp"
|
#include "character.hpp"
|
||||||
|
#include "movement.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include <OgreStringConverter.h>
|
#include <OgreStringConverter.h>
|
||||||
|
|
||||||
|
#include "movement.hpp"
|
||||||
|
|
||||||
#include "../mwrender/animation.hpp"
|
#include "../mwrender/animation.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -73,6 +75,9 @@ static const struct {
|
||||||
{ CharState_SneakLeft, "sneakleft" },
|
{ CharState_SneakLeft, "sneakleft" },
|
||||||
{ CharState_SneakRight, "sneakright" },
|
{ CharState_SneakRight, "sneakright" },
|
||||||
|
|
||||||
|
{ CharState_TurnLeft, "turnleft" },
|
||||||
|
{ CharState_TurnRight, "turnright" },
|
||||||
|
|
||||||
{ CharState_Jump, "jump" },
|
{ CharState_Jump, "jump" },
|
||||||
|
|
||||||
{ CharState_Death1, "death1" },
|
{ CharState_Death1, "death1" },
|
||||||
|
@ -168,21 +173,20 @@ void CharacterController::markerEvent(float time, const std::string &evt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ogre::Vector3 CharacterController::update(float duration)
|
void CharacterController::update(float duration, Movement &movement)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 movement(0.0f);
|
|
||||||
|
|
||||||
float speed = 0.0f;
|
float speed = 0.0f;
|
||||||
if(!(getState() >= CharState_Death1))
|
if(!(getState() >= CharState_Death1))
|
||||||
{
|
{
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
|
const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
|
||||||
const Ogre::Vector3 &vec = cls.getMovementVector(mPtr);
|
|
||||||
|
|
||||||
bool onground = world->isOnGround(mPtr);
|
bool onground = world->isOnGround(mPtr);
|
||||||
bool inwater = world->isSwimming(mPtr);
|
bool inwater = world->isSwimming(mPtr);
|
||||||
bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
|
bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
|
||||||
bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak);
|
bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak);
|
||||||
|
const Ogre::Vector3 &vec = cls.getMovementVector(mPtr);
|
||||||
|
const Ogre::Vector3 &rot = cls.getRotationVector(mPtr);
|
||||||
speed = cls.getSpeed(mPtr);
|
speed = cls.getSpeed(mPtr);
|
||||||
|
|
||||||
/* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except
|
/* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except
|
||||||
|
@ -192,14 +196,14 @@ Ogre::Vector3 CharacterController::update(float duration)
|
||||||
float x = cls.getJump(mPtr);
|
float x = cls.getJump(mPtr);
|
||||||
|
|
||||||
if(vec.x == 0 && vec.y == 0)
|
if(vec.x == 0 && vec.y == 0)
|
||||||
movement.z += x*duration;
|
movement.mPosition[2] += x*duration;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* FIXME: this would be more correct if we were going into a jumping state,
|
/* FIXME: this would be more correct if we were going into a jumping state,
|
||||||
* rather than normal walking/idle states. */
|
* rather than normal walking/idle states. */
|
||||||
//Ogre::Vector3 lat = Ogre::Vector3(vec.x, vec.y, 0.0f).normalisedCopy();
|
//Ogre::Vector3 lat = Ogre::Vector3(vec.x, vec.y, 0.0f).normalisedCopy();
|
||||||
//movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration;
|
//movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration;
|
||||||
movement.z += x * 0.707f * duration;
|
movement.mPosition[2] += x * 0.707f * duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
//decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult;
|
//decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult;
|
||||||
|
@ -216,7 +220,7 @@ Ogre::Vector3 CharacterController::update(float duration)
|
||||||
: (sneak ? CharState_SneakLeft : (isrunning ? CharState_RunLeft : CharState_WalkLeft)), true);
|
: (sneak ? CharState_SneakLeft : (isrunning ? CharState_RunLeft : CharState_WalkLeft)), true);
|
||||||
|
|
||||||
// Apply any forward/backward movement manually
|
// Apply any forward/backward movement manually
|
||||||
movement.y += vec.y * (speed*duration);
|
movement.mPosition[1] += vec.y * (speed*duration);
|
||||||
}
|
}
|
||||||
else if(vec.y != 0.0f && speed > 0.0f)
|
else if(vec.y != 0.0f && speed > 0.0f)
|
||||||
{
|
{
|
||||||
|
@ -228,20 +232,32 @@ Ogre::Vector3 CharacterController::update(float duration)
|
||||||
setState(inwater ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack)
|
setState(inwater ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack)
|
||||||
: (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack)), true);
|
: (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack)), true);
|
||||||
// Apply any sideways movement manually
|
// Apply any sideways movement manually
|
||||||
movement.x += vec.x * (speed*duration);
|
movement.mPosition[0] += vec.x * (speed*duration);
|
||||||
|
}
|
||||||
|
else if(rot.z != 0.0f && !inwater && !sneak)
|
||||||
|
{
|
||||||
|
if(rot.z > 0.0f)
|
||||||
|
setState(CharState_TurnRight, true);
|
||||||
|
else if(rot.z < 0.0f)
|
||||||
|
setState(CharState_TurnLeft, true);
|
||||||
}
|
}
|
||||||
else if(mAnimQueue.size() == 0)
|
else if(mAnimQueue.size() == 0)
|
||||||
setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true);
|
setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true);
|
||||||
|
|
||||||
|
movement.mRotation[0] += rot.x * duration;
|
||||||
|
movement.mRotation[1] += rot.y * duration;
|
||||||
|
movement.mRotation[2] += rot.z * duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mAnimation && !mSkipAnim)
|
if(mAnimation && !mSkipAnim)
|
||||||
{
|
{
|
||||||
mAnimation->setSpeed(speed);
|
mAnimation->setSpeed(speed);
|
||||||
movement += mAnimation->runAnimation(duration);
|
Ogre::Vector3 moved = mAnimation->runAnimation(duration);
|
||||||
|
movement.mPosition[0] += moved.x;
|
||||||
|
movement.mPosition[1] += moved.y;
|
||||||
|
movement.mPosition[2] += moved.z;
|
||||||
}
|
}
|
||||||
mSkipAnim = false;
|
mSkipAnim = false;
|
||||||
|
|
||||||
return movement;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace MWRender
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class Movement;
|
||||||
|
|
||||||
enum CharacterState {
|
enum CharacterState {
|
||||||
CharState_SpecialIdle,
|
CharState_SpecialIdle,
|
||||||
CharState_Idle,
|
CharState_Idle,
|
||||||
|
@ -52,6 +54,9 @@ enum CharacterState {
|
||||||
CharState_SneakLeft,
|
CharState_SneakLeft,
|
||||||
CharState_SneakRight,
|
CharState_SneakRight,
|
||||||
|
|
||||||
|
CharState_TurnLeft,
|
||||||
|
CharState_TurnRight,
|
||||||
|
|
||||||
CharState_Jump,
|
CharState_Jump,
|
||||||
|
|
||||||
/* Death states must be last! */
|
/* Death states must be last! */
|
||||||
|
@ -87,7 +92,7 @@ public:
|
||||||
|
|
||||||
void updatePtr(const MWWorld::Ptr &ptr);
|
void updatePtr(const MWWorld::Ptr &ptr);
|
||||||
|
|
||||||
Ogre::Vector3 update(float duration);
|
void update(float duration, Movement &movement);
|
||||||
|
|
||||||
void playGroup(const std::string &groupname, int mode, int count);
|
void playGroup(const std::string &groupname, int mode, int count);
|
||||||
void skipAnim();
|
void skipAnim();
|
||||||
|
|
|
@ -6,11 +6,14 @@ namespace MWMechanics
|
||||||
/// Desired movement for an actor
|
/// Desired movement for an actor
|
||||||
struct Movement
|
struct Movement
|
||||||
{
|
{
|
||||||
signed char mLeftRight; // 1: wants to move left, -1: wants to move right
|
float mPosition[3];
|
||||||
signed char mForwardBackward; // 1:wants to move forward, -1: wants to move backward
|
float mRotation[3];
|
||||||
signed char mUpDown;
|
|
||||||
|
|
||||||
Movement() : mLeftRight (0), mForwardBackward (0), mUpDown(0) {}
|
Movement()
|
||||||
|
{
|
||||||
|
mPosition[0] = mPosition[1] = mPosition[2] = 0.0f;
|
||||||
|
mRotation[0] = mRotation[1] = mRotation[2] = 0.0f;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,7 +262,7 @@ void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3
|
||||||
ptr.getRefData().getBaseNode()->setScale(scale);
|
ptr.getRefData().getBaseNode()->setScale(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderingManager::rotateObject( const MWWorld::Ptr &ptr, Ogre::Vector3 &rot, bool adjust)
|
bool RenderingManager::rotateObject(const MWWorld::Ptr &ptr, Ogre::Vector3 &rot, bool adjust)
|
||||||
{
|
{
|
||||||
bool isActive = ptr.getRefData().getBaseNode() != 0;
|
bool isActive = ptr.getRefData().getBaseNode() != 0;
|
||||||
bool isPlayer = isActive && ptr.getRefData().getHandle() == "player";
|
bool isPlayer = isActive && ptr.getRefData().getHandle() == "player";
|
||||||
|
@ -272,27 +272,19 @@ bool RenderingManager::rotateObject( const MWWorld::Ptr &ptr, Ogre::Vector3 &rot
|
||||||
force = mPlayer->rotate(rot, adjust);
|
force = mPlayer->rotate(rot, adjust);
|
||||||
|
|
||||||
MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z);
|
MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z);
|
||||||
|
|
||||||
if (!isPlayer && isActive)
|
if (!isPlayer && isActive)
|
||||||
{
|
{
|
||||||
Ogre::Quaternion xr(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X);
|
if(adjust)
|
||||||
Ogre::Quaternion yr(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y);
|
{
|
||||||
Ogre::Quaternion zr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
|
const float *objRot = ptr.getRefData().getPosition().rot;
|
||||||
|
rot.x += objRot[0];
|
||||||
Ogre::Quaternion xref(Ogre::Radian(-ptr.getRefData().getPosition().rot[0]), Ogre::Vector3::UNIT_X);
|
rot.y += objRot[1];
|
||||||
Ogre::Quaternion yref(Ogre::Radian(-ptr.getRefData().getPosition().rot[1]), Ogre::Vector3::UNIT_Y);
|
rot.z += objRot[2];
|
||||||
Ogre::Quaternion zref(Ogre::Radian(-ptr.getRefData().getPosition().rot[2]), Ogre::Vector3::UNIT_Z);
|
}
|
||||||
|
|
||||||
Ogre::Quaternion newo = adjust ? (xr * yr * zr) * (xref*yref*zref) : xr * yr * zr;
|
|
||||||
|
|
||||||
Ogre::Matrix3 mat;
|
|
||||||
newo.ToRotationMatrix(mat);
|
|
||||||
Ogre::Radian ax,ay,az;
|
|
||||||
mat.ToEulerAnglesXYZ(ax,ay,az);
|
|
||||||
rot.x = -ax.valueRadians();
|
|
||||||
rot.y = -ay.valueRadians();
|
|
||||||
rot.z = -az.valueRadians();
|
|
||||||
|
|
||||||
|
Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) *
|
||||||
|
Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) *
|
||||||
|
Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
|
||||||
ptr.getRefData().getBaseNode()->setOrientation(newo);
|
ptr.getRefData().getBaseNode()->setOrientation(newo);
|
||||||
}
|
}
|
||||||
else if(isPlayer)
|
else if(isPlayer)
|
||||||
|
|
|
@ -316,5 +316,7 @@ op 0x20001f9: Drop, explicit reference
|
||||||
op 0x20001fa: DropSoulGem
|
op 0x20001fa: DropSoulGem
|
||||||
op 0x20001fb: DropSoulGem, explicit reference
|
op 0x20001fb: DropSoulGem, explicit reference
|
||||||
op 0x20001fc: OnDeath
|
op 0x20001fc: OnDeath
|
||||||
|
op 0x20001fd: IsWerewolf
|
||||||
|
op 0x20001fe: IsWerewolf, explicit reference
|
||||||
|
|
||||||
opcodes 0x20001fd-0x3ffffff unused
|
opcodes 0x20001ff-0x3ffffff unused
|
||||||
|
|
|
@ -1046,6 +1046,18 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class R>
|
||||||
|
class OpIsWerewolf : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
runtime.push(MWWorld::Class::get(ptr).getNpcStats(ptr).isWerewolf());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const int numberOfAttributes = 8;
|
const int numberOfAttributes = 8;
|
||||||
|
|
||||||
const int opcodeGetAttribute = 0x2000027;
|
const int opcodeGetAttribute = 0x2000027;
|
||||||
|
@ -1137,6 +1149,9 @@ namespace MWScript
|
||||||
|
|
||||||
const int opcodeOnDeath = 0x20001fc;
|
const int opcodeOnDeath = 0x20001fc;
|
||||||
|
|
||||||
|
const int opcodeIsWerewolf = 0x20001fd;
|
||||||
|
const int opcodeIsWerewolfExplicit = 0x20001fe;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
static const char *attributes[numberOfAttributes] =
|
static const char *attributes[numberOfAttributes] =
|
||||||
|
@ -1252,6 +1267,8 @@ namespace MWScript
|
||||||
extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit);
|
extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit);
|
||||||
|
|
||||||
extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath);
|
extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath);
|
||||||
|
|
||||||
|
extensions.registerFunction ("iswerewolf", 'l', "", opcodeIsWerewolf, opcodeIsWerewolfExplicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -1368,6 +1385,9 @@ namespace MWScript
|
||||||
interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>);
|
interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>);
|
||||||
|
|
||||||
interpreter.installSegment5 (opcodeOnDeath, new OpOnDeath);
|
interpreter.installSegment5 (opcodeOnDeath, new OpOnDeath);
|
||||||
|
|
||||||
|
interpreter.installSegment5 (opcodeIsWerewolf, new OpIsWerewolf<ImplicitRef>);
|
||||||
|
interpreter.installSegment5 (opcodeIsWerewolfExplicit, new OpIsWerewolf<ExplicitRef>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,11 @@ namespace MWWorld
|
||||||
return Ogre::Vector3 (0, 0, 0);
|
return Ogre::Vector3 (0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 Class::getRotationVector (const Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return Ogre::Vector3 (0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<std::vector<int>, bool> Class::getEquipmentSlots (const Ptr& ptr) const
|
std::pair<std::vector<int>, bool> Class::getEquipmentSlots (const Ptr& ptr) const
|
||||||
{
|
{
|
||||||
return std::make_pair (std::vector<int>(), false);
|
return std::make_pair (std::vector<int>(), false);
|
||||||
|
|
|
@ -150,6 +150,9 @@ namespace MWWorld
|
||||||
///< Return desired movement vector (determined based on movement settings,
|
///< Return desired movement vector (determined based on movement settings,
|
||||||
/// stance and stats).
|
/// stance and stats).
|
||||||
|
|
||||||
|
virtual Ogre::Vector3 getRotationVector (const Ptr& ptr) const;
|
||||||
|
///< Return desired rotations, as euler angles.
|
||||||
|
|
||||||
virtual std::pair<std::vector<int>, bool> getEquipmentSlots (const Ptr& ptr) const;
|
virtual std::pair<std::vector<int>, bool> getEquipmentSlots (const Ptr& ptr) const;
|
||||||
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
|
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
|
||||||
/// stay stacked when equipped?
|
/// stay stacked when equipped?
|
||||||
|
|
|
@ -42,14 +42,14 @@ namespace MWWorld
|
||||||
if (mAutoMove)
|
if (mAutoMove)
|
||||||
value = 1;
|
value = 1;
|
||||||
|
|
||||||
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
|
MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[1] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::setLeftRight (int value)
|
void Player::setLeftRight (int value)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = getPlayer();
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
|
||||||
MWWorld::Class::get (ptr).getMovementSettings (ptr).mLeftRight = value;
|
MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[0] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::setForwardBackward (int value)
|
void Player::setForwardBackward (int value)
|
||||||
|
@ -61,14 +61,14 @@ namespace MWWorld
|
||||||
if (mAutoMove)
|
if (mAutoMove)
|
||||||
value = 1;
|
value = 1;
|
||||||
|
|
||||||
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
|
MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[1] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::setUpDown(int value)
|
void Player::setUpDown(int value)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = getPlayer();
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
|
||||||
MWWorld::Class::get (ptr).getMovementSettings (ptr).mUpDown = value;
|
MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[2] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::setRunState(bool run)
|
void Player::setRunState(bool run)
|
||||||
|
@ -84,6 +84,22 @@ namespace MWWorld
|
||||||
MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Sneak, sneak);
|
MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Sneak, sneak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::setYaw(float yaw)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[2] = yaw;
|
||||||
|
}
|
||||||
|
void Player::setPitch(float pitch)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[0] = pitch;
|
||||||
|
}
|
||||||
|
void Player::setRoll(float roll)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[1] = roll;
|
||||||
|
}
|
||||||
|
|
||||||
MWMechanics::DrawState_ Player::getDrawState()
|
MWMechanics::DrawState_ Player::getDrawState()
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = getPlayer();
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
|
|
@ -67,6 +67,10 @@ namespace MWWorld
|
||||||
|
|
||||||
void setRunState(bool run);
|
void setRunState(bool run);
|
||||||
void setSneak(bool sneak);
|
void setSneak(bool sneak);
|
||||||
|
|
||||||
|
void setYaw(float yaw);
|
||||||
|
void setPitch(float pitch);
|
||||||
|
void setRoll(float roll);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "../mwbase/scriptmanager.hpp"
|
#include "../mwbase/scriptmanager.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
#include "../mwmechanics/movement.hpp"
|
||||||
|
|
||||||
#include "../mwrender/sky.hpp"
|
#include "../mwrender/sky.hpp"
|
||||||
#include "../mwrender/player.hpp"
|
#include "../mwrender/player.hpp"
|
||||||
|
@ -805,18 +806,15 @@ namespace MWWorld
|
||||||
mPhysics->scaleObject(ptr);
|
mPhysics->scaleObject(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
|
void World::rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 rot;
|
|
||||||
rot.x = Ogre::Degree(x).valueRadians();
|
|
||||||
rot.y = Ogre::Degree(y).valueRadians();
|
|
||||||
rot.z = Ogre::Degree(z).valueRadians();
|
|
||||||
|
|
||||||
if (mRendering->rotateObject(ptr, rot, adjust))
|
if (mRendering->rotateObject(ptr, rot, adjust))
|
||||||
{
|
{
|
||||||
// rotate physically iff renderer confirm so
|
// rotate physically iff renderer confirm so
|
||||||
float *objRot = ptr.getRefData().getPosition().rot;
|
float *objRot = ptr.getRefData().getPosition().rot;
|
||||||
objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z;
|
objRot[0] = rot.x;
|
||||||
|
objRot[1] = rot.y;
|
||||||
|
objRot[2] = rot.z;
|
||||||
|
|
||||||
if (ptr.getRefData().getBaseNode() != 0) {
|
if (ptr.getRefData().getBaseNode() != 0) {
|
||||||
mPhysics->rotateObject(ptr);
|
mPhysics->rotateObject(ptr);
|
||||||
|
@ -824,6 +822,14 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
|
||||||
|
{
|
||||||
|
rotateObjectImp(ptr, Ogre::Vector3(Ogre::Degree(x).valueRadians(),
|
||||||
|
Ogre::Degree(y).valueRadians(),
|
||||||
|
Ogre::Degree(z).valueRadians()),
|
||||||
|
adjust);
|
||||||
|
}
|
||||||
|
|
||||||
void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos)
|
void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos)
|
||||||
{
|
{
|
||||||
copyObjectToCell(ptr,Cell,pos);
|
copyObjectToCell(ptr,Cell,pos);
|
||||||
|
@ -873,13 +879,18 @@ namespace MWWorld
|
||||||
player = iter;
|
player = iter;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Ogre::Vector3 vec = mPhysics->move(iter->first, iter->second, duration,
|
|
||||||
|
rotateObjectImp(iter->first, Ogre::Vector3(iter->second.mRotation), true);
|
||||||
|
|
||||||
|
Ogre::Vector3 vec = mPhysics->move(iter->first, Ogre::Vector3(iter->second.mPosition), duration,
|
||||||
!isSwimming(iter->first) && !isFlying(iter->first));
|
!isSwimming(iter->first) && !isFlying(iter->first));
|
||||||
moveObjectImp(iter->first, vec.x, vec.y, vec.z);
|
moveObjectImp(iter->first, vec.x, vec.y, vec.z);
|
||||||
}
|
}
|
||||||
if(player != actors.end())
|
if(player != actors.end())
|
||||||
{
|
{
|
||||||
Ogre::Vector3 vec = mPhysics->move(player->first, player->second, duration,
|
rotateObjectImp(player->first, Ogre::Vector3(player->second.mRotation), true);
|
||||||
|
|
||||||
|
Ogre::Vector3 vec = mPhysics->move(player->first, Ogre::Vector3(player->second.mPosition), duration,
|
||||||
!isSwimming(player->first) && !isFlying(player->first));
|
!isSwimming(player->first) && !isFlying(player->first));
|
||||||
moveObjectImp(player->first, vec.x, vec.y, vec.z);
|
moveObjectImp(player->first, vec.x, vec.y, vec.z);
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,8 @@ namespace MWWorld
|
||||||
|
|
||||||
int getDaysPerMonth (int month) const;
|
int getDaysPerMonth (int month) const;
|
||||||
|
|
||||||
|
void rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust);
|
||||||
|
|
||||||
bool moveObjectImp (const Ptr& ptr, float x, float y, float z);
|
bool moveObjectImp (const Ptr& ptr, float x, float y, float z);
|
||||||
///< @return true if the active cell (cell player is in) changed
|
///< @return true if the active cell (cell player is in) changed
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,12 @@ namespace Compiler
|
||||||
mLoc.mLiteral.clear();
|
mLoc.mLiteral.clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (c==':')
|
||||||
|
{
|
||||||
|
// treat : as a whitespace :(
|
||||||
|
mLoc.mLiteral.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (std::isdigit (c))
|
else if (std::isdigit (c))
|
||||||
{
|
{
|
||||||
bool cont = false;
|
bool cont = false;
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct BodyPart
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
BPF_Female = 1,
|
BPF_Female = 1,
|
||||||
BPF_Playable = 2
|
BPF_NotPlayable = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MeshType
|
enum MeshType
|
||||||
|
|
|
@ -35,4 +35,18 @@ void Class::save(ESMWriter &esm)
|
||||||
esm.writeHNOString("DESC", mDescription);
|
esm.writeHNOString("DESC", mDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Class::blank()
|
||||||
|
{
|
||||||
|
mName.clear();
|
||||||
|
mDescription.clear();
|
||||||
|
|
||||||
|
mData.mAttribute[0] = mData.mAttribute[1] = 0;
|
||||||
|
mData.mSpecialization = 0;
|
||||||
|
mData.mIsPlayable = 0;
|
||||||
|
mData.mCalc = 0;
|
||||||
|
|
||||||
|
for (int i=0; i<5; ++i)
|
||||||
|
for (int i2=0; i2<2; ++i2)
|
||||||
|
mData.mSkills[i][i2] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,10 @@ struct Class
|
||||||
|
|
||||||
void load(ESMReader &esm);
|
void load(ESMReader &esm);
|
||||||
void save(ESMWriter &esm);
|
void save(ESMWriter &esm);
|
||||||
|
|
||||||
|
void blank();
|
||||||
|
///< Set record to default state (does not touch the ID/index).
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
#include "esmreader.hpp"
|
#include "esmreader.hpp"
|
||||||
#include "esmwriter.hpp"
|
#include "esmwriter.hpp"
|
||||||
|
|
||||||
|
@ -103,8 +105,9 @@ void Skill::load(ESMReader &esm)
|
||||||
|
|
||||||
// create an ID from the index and the name (only used in the editor and likely to change in the
|
// create an ID from the index and the name (only used in the editor and likely to change in the
|
||||||
// future)
|
// future)
|
||||||
mId = getIndexToId (mIndex);
|
mId = indexToId (mIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skill::save(ESMWriter &esm)
|
void Skill::save(ESMWriter &esm)
|
||||||
{
|
{
|
||||||
esm.writeHNT("INDX", mIndex);
|
esm.writeHNT("INDX", mIndex);
|
||||||
|
@ -120,7 +123,7 @@ void Skill::save(ESMWriter &esm)
|
||||||
mDescription.clear();
|
mDescription.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Skill::getIndexToId (int index)
|
std::string Skill::indexToId (int index)
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct Skill
|
||||||
void blank();
|
void blank();
|
||||||
///< Set record to default state (does not touch the ID/index).
|
///< Set record to default state (does not touch the ID/index).
|
||||||
|
|
||||||
static std::string getIndexToId (int index);
|
static std::string indexToId (int index);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue