mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-13 12:40:04 +00:00
Merge branch 'master' into graphics
This commit is contained in:
commit
7ad1e962e0
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,3 +17,4 @@ data
|
||||
CMakeLists.txt.user
|
||||
*.swp
|
||||
*.swo
|
||||
*.kate-swp
|
||||
|
@ -227,7 +227,10 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info)
|
||||
std::cout << " Refnum: " << ref.mRefnum << std::endl;
|
||||
std::cout << " ID: '" << ref.mRefID << "'\n";
|
||||
std::cout << " Owner: '" << ref.mOwner << "'\n";
|
||||
std::cout << " INTV: " << ref.mIntv << " NAM9: " << ref.mIntv << std::endl;
|
||||
std::cout << " Enchantment charge: '" << ref.mEnchantmentCharge << "'\n";
|
||||
std::cout << " Uses/health: '" << ref.mCharge << "'\n";
|
||||
std::cout << " Gold value: '" << ref.mGoldValue << "'\n";
|
||||
std::cout << " Blocked: '" << static_cast<int>(ref.mReferenceBlocked) << "'" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ RecordBase::create(ESM::NAME type)
|
||||
}
|
||||
case ESM::REC_LOCK:
|
||||
{
|
||||
record = new EsmTool::Record<ESM::Tool>;
|
||||
record = new EsmTool::Record<ESM::Lockpick>;
|
||||
break;
|
||||
}
|
||||
case ESM::REC_LTEX:
|
||||
@ -864,14 +864,13 @@ void Record<ESM::Light>::print()
|
||||
}
|
||||
|
||||
template<>
|
||||
void Record<ESM::Tool>::print()
|
||||
void Record<ESM::Lockpick>::print()
|
||||
{
|
||||
std::cout << " Name: " << mData.mName << std::endl;
|
||||
std::cout << " Model: " << mData.mModel << std::endl;
|
||||
std::cout << " Icon: " << mData.mIcon << std::endl;
|
||||
if (mData.mScript != "")
|
||||
std::cout << " Script: " << mData.mScript << std::endl;
|
||||
std::cout << " Type: " << mData.mType << std::endl;
|
||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||
@ -886,8 +885,6 @@ void Record<ESM::Probe>::print()
|
||||
std::cout << " Icon: " << mData.mIcon << std::endl;
|
||||
if (mData.mScript != "")
|
||||
std::cout << " Script: " << mData.mScript << std::endl;
|
||||
// BUG? No Type Label?
|
||||
std::cout << " Type: " << mData.mType << std::endl;
|
||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||
@ -902,7 +899,6 @@ void Record<ESM::Repair>::print()
|
||||
std::cout << " Icon: " << mData.mIcon << std::endl;
|
||||
if (mData.mScript != "")
|
||||
std::cout << " Script: " << mData.mScript << std::endl;
|
||||
std::cout << " Type: " << mData.mType << std::endl;
|
||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||
std::cout << " Quality: " << mData.mData.mQuality << std::endl;
|
||||
|
@ -104,7 +104,7 @@ namespace EsmTool
|
||||
template<> void Record<ESM::CreatureLevList>::print();
|
||||
template<> void Record<ESM::ItemLevList>::print();
|
||||
template<> void Record<ESM::Light>::print();
|
||||
template<> void Record<ESM::Tool>::print();
|
||||
template<> void Record<ESM::Lockpick>::print();
|
||||
template<> void Record<ESM::Probe>::print();
|
||||
template<> void Record<ESM::Repair>::print();
|
||||
template<> void Record<ESM::LandTexture>::print();
|
||||
|
@ -22,3 +22,8 @@ if (BUILD_WITH_CODE_COVERAGE)
|
||||
add_definitions (--coverage)
|
||||
target_link_libraries(mwiniimport gcov)
|
||||
endif()
|
||||
|
||||
if(DPKG_PROGRAM)
|
||||
INSTALL(TARGETS mwiniimport RUNTIME DESTINATION games COMPONENT mwiniimport)
|
||||
endif()
|
||||
|
||||
|
@ -35,7 +35,7 @@ opencs_units (model/tools
|
||||
)
|
||||
|
||||
opencs_units_noqt (model/tools
|
||||
stage verifier mandatoryid
|
||||
stage verifier mandatoryid skillcheck
|
||||
)
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "document.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <QDebug>
|
||||
|
||||
void CSMDoc::Document::load (const std::vector<boost::filesystem::path>::const_iterator& begin,
|
||||
const std::vector<boost::filesystem::path>::const_iterator& end, bool lastAsModified)
|
||||
{
|
||||
@ -150,6 +150,10 @@ void CSMDoc::Document::addOptionalGlobals()
|
||||
ESM::Global global;
|
||||
global.mId = sGlobals[i];
|
||||
global.mValue.setType (ESM::VT_Long);
|
||||
|
||||
if (i==0)
|
||||
global.mValue.setInteger (1); // dayspassed starts counting at 1
|
||||
|
||||
addOptionalGlobal (global);
|
||||
}
|
||||
}
|
||||
@ -189,15 +193,25 @@ void CSMDoc::Document::createBase()
|
||||
|
||||
record.mId = sGlobals[i];
|
||||
|
||||
record.mValue.setType (i==2 ? ESM::VT_Float : ESM::VT_Int);
|
||||
record.mValue.setType (i==2 ? ESM::VT_Float : ESM::VT_Long);
|
||||
|
||||
if (i==0)
|
||||
if (i==0 || i==1)
|
||||
record.mValue.setInteger (1);
|
||||
|
||||
getData().getGlobals().add (record);
|
||||
}
|
||||
|
||||
/// \todo add GMSTs
|
||||
|
||||
for (int i=0; i<27; ++i)
|
||||
{
|
||||
ESM::Skill record;
|
||||
record.mIndex = i;
|
||||
record.mId = ESM::Skill::getIndexToId (record.mIndex);
|
||||
record.blank();
|
||||
|
||||
getData().getSkills().add (record);
|
||||
}
|
||||
}
|
||||
|
||||
CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files, bool new_)
|
||||
@ -214,7 +228,7 @@ CSMDoc::Document::Document (const std::vector<boost::filesystem::path>& files, b
|
||||
|
||||
if (new_ && files.size()==1)
|
||||
createBase();
|
||||
else if (files.size()>1)
|
||||
else
|
||||
{
|
||||
std::vector<boost::filesystem::path>::const_iterator end = files.end();
|
||||
|
||||
|
37
apps/opencs/model/tools/skillcheck.cpp
Normal file
37
apps/opencs/model/tools/skillcheck.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
#include "skillcheck.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
||||
#include "../world/universalid.hpp"
|
||||
|
||||
CSMTools::SkillCheckStage::SkillCheckStage (const CSMWorld::IdCollection<ESM::Skill>& skills)
|
||||
: mSkills (skills)
|
||||
{}
|
||||
|
||||
int CSMTools::SkillCheckStage::setup()
|
||||
{
|
||||
return mSkills.getSize();
|
||||
}
|
||||
|
||||
void CSMTools::SkillCheckStage::perform (int stage, std::vector<std::string>& messages)
|
||||
{
|
||||
const ESM::Skill& skill = mSkills.getRecord (stage).get();
|
||||
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Skill, skill.mId);
|
||||
|
||||
for (int i=0; i<4; ++i)
|
||||
if (skill.mData.mUseValue[i]<0)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << id.toString() << "|Use value #" << i << " of " << skill.mId << " is negative";
|
||||
|
||||
messages.push_back (stream.str());
|
||||
}
|
||||
|
||||
if (skill.mDescription.empty())
|
||||
messages.push_back (id.toString() + "|" + skill.mId + " has an empty description");
|
||||
}
|
29
apps/opencs/model/tools/skillcheck.hpp
Normal file
29
apps/opencs/model/tools/skillcheck.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef CSM_TOOLS_SKILLCHECK_H
|
||||
#define CSM_TOOLS_SKILLCHECK_H
|
||||
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
||||
#include "../world/idcollection.hpp"
|
||||
|
||||
#include "stage.hpp"
|
||||
|
||||
namespace CSMTools
|
||||
{
|
||||
/// \brief VerifyStage: make sure that skill records are internally consistent
|
||||
class SkillCheckStage : public Stage
|
||||
{
|
||||
const CSMWorld::IdCollection<ESM::Skill>& mSkills;
|
||||
|
||||
public:
|
||||
|
||||
SkillCheckStage (const CSMWorld::IdCollection<ESM::Skill>& skills);
|
||||
|
||||
virtual int setup();
|
||||
///< \return number of steps
|
||||
|
||||
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||
///< Messages resulting from this tage will be appended to \a messages.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "reportmodel.hpp"
|
||||
#include "mandatoryid.hpp"
|
||||
#include "skillcheck.hpp"
|
||||
|
||||
CSMTools::Operation *CSMTools::Tools::get (int type)
|
||||
{
|
||||
@ -51,6 +52,8 @@ CSMTools::Verifier *CSMTools::Tools::getVerifier()
|
||||
|
||||
mVerifier->appendStage (new MandatoryIdStage (mData.getGlobals(),
|
||||
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
|
||||
|
||||
mVerifier->appendStage (new SkillCheckStage (mData.getSkills()));
|
||||
}
|
||||
|
||||
return mVerifier;
|
||||
|
@ -31,7 +31,9 @@ namespace CSMWorld
|
||||
Display_Float,
|
||||
Display_Var,
|
||||
Display_GmstVarType,
|
||||
Display_GlobalVarType
|
||||
Display_GlobalVarType,
|
||||
Display_Specialisation,
|
||||
Display_Attribute
|
||||
};
|
||||
|
||||
std::string mTitle;
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef CSM_WOLRD_COLUMNS_H
|
||||
#define CSM_WOLRD_COLUMNS_H
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "columnbase.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
@ -35,7 +37,7 @@ namespace CSMWorld
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mId.c_str();
|
||||
return QString::fromUtf8 (record.get().mId.c_str());
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
@ -127,17 +129,17 @@ namespace CSMWorld
|
||||
{
|
||||
case ESM::VT_String:
|
||||
|
||||
return record.get().mValue.getString().c_str(); break;
|
||||
return QString::fromUtf8 (record.get().mValue.getString().c_str());
|
||||
|
||||
case ESM::VT_Int:
|
||||
case ESM::VT_Short:
|
||||
case ESM::VT_Long:
|
||||
|
||||
return record.get().mValue.getInteger(); break;
|
||||
return record.get().mValue.getInteger();
|
||||
|
||||
case ESM::VT_Float:
|
||||
|
||||
return record.get().mValue.getFloat(); break;
|
||||
return record.get().mValue.getFloat();
|
||||
|
||||
default: return QVariant();
|
||||
}
|
||||
@ -177,6 +179,112 @@ namespace CSMWorld
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct DescriptionColumn : public Column<ESXRecordT>
|
||||
{
|
||||
DescriptionColumn() : Column<ESXRecordT> ("Description", ColumnBase::Display_String) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return QString::fromUtf8 (record.get().mDescription.c_str());
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mDescription = data.toString().toUtf8().constData();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct SpecialisationColumn : public Column<ESXRecordT>
|
||||
{
|
||||
SpecialisationColumn() : Column<ESXRecordT> ("Specialisation", ColumnBase::Display_Specialisation) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mSpecialization;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mSpecialization = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct UseValueColumn : public Column<ESXRecordT>
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
UseValueColumn (int index)
|
||||
: Column<ESXRecordT> ("Use value #" + boost::lexical_cast<std::string> (index),
|
||||
ColumnBase::Display_Float), mIndex (index)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mUseValue[mIndex];
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mUseValue[mIndex] = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
struct AttributeColumn : public Column<ESXRecordT>
|
||||
{
|
||||
AttributeColumn() : Column<ESXRecordT> ("Attribute", ColumnBase::Display_Attribute) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mData.mAttribute;
|
||||
}
|
||||
|
||||
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
|
||||
{
|
||||
ESXRecordT record2 = record.get();
|
||||
|
||||
record2.mData.mAttribute = data.toInt();
|
||||
|
||||
record.setModified (record2);
|
||||
}
|
||||
|
||||
virtual bool isEditable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
|
||||
#include "commands.hpp"
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include "idtableproxymodel.hpp"
|
||||
#include "idtable.hpp"
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
#include <components/esm/defs.hpp>
|
||||
@ -12,7 +12,7 @@
|
||||
#include "idtable.hpp"
|
||||
#include "columns.hpp"
|
||||
|
||||
void CSMWorld::Data::addModel (QAbstractTableModel *model, UniversalId::Type type1,
|
||||
void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||
UniversalId::Type type2)
|
||||
{
|
||||
mModels.push_back (model);
|
||||
@ -36,13 +36,22 @@ CSMWorld::Data::Data()
|
||||
mGmsts.addColumn (new VarTypeColumn<ESM::GameSetting> (ColumnBase::Display_GmstVarType));
|
||||
mGmsts.addColumn (new VarValueColumn<ESM::GameSetting>);
|
||||
|
||||
mSkills.addColumn (new StringIdColumn<ESM::Skill>);
|
||||
mSkills.addColumn (new RecordStateColumn<ESM::Skill>);
|
||||
mSkills.addColumn (new AttributeColumn<ESM::Skill>);
|
||||
mSkills.addColumn (new SpecialisationColumn<ESM::Skill>);
|
||||
for (int i=0; i<4; ++i)
|
||||
mSkills.addColumn (new UseValueColumn<ESM::Skill> (i));
|
||||
mSkills.addColumn (new DescriptionColumn<ESM::Skill>);
|
||||
|
||||
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
|
||||
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
|
||||
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
|
||||
}
|
||||
|
||||
CSMWorld::Data::~Data()
|
||||
{
|
||||
for (std::vector<QAbstractTableModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
|
||||
for (std::vector<QAbstractItemModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
@ -66,9 +75,19 @@ CSMWorld::IdCollection<ESM::GameSetting>& CSMWorld::Data::getGmsts()
|
||||
return mGmsts;
|
||||
}
|
||||
|
||||
QAbstractTableModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
||||
const CSMWorld::IdCollection<ESM::Skill>& CSMWorld::Data::getSkills() const
|
||||
{
|
||||
std::map<UniversalId::Type, QAbstractTableModel *>::iterator iter = mModelIndex.find (id.getType());
|
||||
return mSkills;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Skill>& CSMWorld::Data::getSkills()
|
||||
{
|
||||
return mSkills;
|
||||
}
|
||||
|
||||
QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
||||
{
|
||||
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());
|
||||
|
||||
if (iter==mModelIndex.end())
|
||||
throw std::logic_error ("No table model available for " + id.toString());
|
||||
@ -102,7 +121,7 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base)
|
||||
{
|
||||
case ESM::REC_GLOB: mGlobals.load (reader, base); break;
|
||||
case ESM::REC_GMST: mGmsts.load (reader, base); break;
|
||||
|
||||
case ESM::REC_SKIL: mSkills.load (reader, base); break;
|
||||
|
||||
default:
|
||||
|
||||
|
@ -8,11 +8,12 @@
|
||||
|
||||
#include <components/esm/loadglob.hpp>
|
||||
#include <components/esm/loadgmst.hpp>
|
||||
#include <components/esm/loadskil.hpp>
|
||||
|
||||
#include "idcollection.hpp"
|
||||
#include "universalid.hpp"
|
||||
|
||||
class QAbstractTableModel;
|
||||
class QAbstractItemModel;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
@ -20,14 +21,15 @@ namespace CSMWorld
|
||||
{
|
||||
IdCollection<ESM::Global> mGlobals;
|
||||
IdCollection<ESM::GameSetting> mGmsts;
|
||||
std::vector<QAbstractTableModel *> mModels;
|
||||
std::map<UniversalId::Type, QAbstractTableModel *> mModelIndex;
|
||||
IdCollection<ESM::Skill> mSkills;
|
||||
std::vector<QAbstractItemModel *> mModels;
|
||||
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;
|
||||
|
||||
// not implemented
|
||||
Data (const Data&);
|
||||
Data& operator= (const Data&);
|
||||
|
||||
void addModel (QAbstractTableModel *model, UniversalId::Type type1,
|
||||
void addModel (QAbstractItemModel *model, UniversalId::Type type1,
|
||||
UniversalId::Type type2 = UniversalId::Type_None);
|
||||
|
||||
public:
|
||||
@ -44,7 +46,11 @@ namespace CSMWorld
|
||||
|
||||
IdCollection<ESM::GameSetting>& getGmsts();
|
||||
|
||||
QAbstractTableModel *getTableModel (const UniversalId& id);
|
||||
const IdCollection<ESM::Skill>& getSkills() const;
|
||||
|
||||
IdCollection<ESM::Skill>& getSkills();
|
||||
|
||||
QAbstractItemModel *getTableModel (const UniversalId& id);
|
||||
///< If no table model is available for \a id, an exception is thrown.
|
||||
///
|
||||
/// \note The returned table may either be the model for the ID itself or the model that
|
||||
|
@ -74,6 +74,8 @@ namespace CSMWorld
|
||||
|
||||
virtual const RecordBase& getRecord (const std::string& id) const = 0;
|
||||
|
||||
virtual const RecordBase& getRecord (int index) const = 0;
|
||||
|
||||
virtual void load (ESM::ESMReader& reader, bool base) = 0;
|
||||
};
|
||||
|
||||
@ -139,7 +141,9 @@ namespace CSMWorld
|
||||
///
|
||||
/// \attention Throw san exception, if the type of \a record does not match.
|
||||
|
||||
virtual const RecordBase& getRecord (const std::string& id) const;
|
||||
virtual const Record<ESXRecordT>& getRecord (const std::string& id) const;
|
||||
|
||||
virtual const Record<ESXRecordT>& getRecord (int index) const;
|
||||
|
||||
virtual void load (ESM::ESMReader& reader, bool base);
|
||||
|
||||
@ -373,11 +377,18 @@ namespace CSMWorld
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
const RecordBase& IdCollection<ESXRecordT>::getRecord (const std::string& id) const
|
||||
const Record<ESXRecordT>& IdCollection<ESXRecordT>::getRecord (const std::string& id) const
|
||||
{
|
||||
int index = getIndex (id);
|
||||
return mRecords.at (index);
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
const Record<ESXRecordT>& IdCollection<ESXRecordT>::getRecord (int index) const
|
||||
{
|
||||
return mRecords.at (index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -96,6 +96,25 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren
|
||||
return true;
|
||||
}
|
||||
|
||||
QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
if (row<0 || row>=mIdCollection->getSize())
|
||||
return QModelIndex();
|
||||
|
||||
if (column<0 || column>=mIdCollection->getColumns())
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex (row, column);
|
||||
}
|
||||
|
||||
QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void CSMWorld::IdTable::addRecord (const std::string& id)
|
||||
{
|
||||
int index = mIdCollection->getSize();
|
||||
|
@ -1,14 +1,14 @@
|
||||
#ifndef CSM_WOLRD_IDTABLE_H
|
||||
#define CSM_WOLRD_IDTABLE_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdCollectionBase;
|
||||
class RecordBase;
|
||||
|
||||
class IdTable : public QAbstractTableModel
|
||||
class IdTable : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -39,6 +39,11 @@ namespace CSMWorld
|
||||
|
||||
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
|
||||
|
||||
virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex())
|
||||
const;
|
||||
|
||||
virtual QModelIndex parent (const QModelIndex& index) const;
|
||||
|
||||
void addRecord (const std::string& id);
|
||||
|
||||
QModelIndex getModelIndex (const std::string& id, int column) const;
|
||||
|
@ -62,7 +62,7 @@ namespace CSMWorld
|
||||
if (mState==State_Erased)
|
||||
throw std::logic_error ("attempt to access a deleted record");
|
||||
|
||||
return mState==State_BaseOnly ? mBase : mModified;
|
||||
return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified;
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
@ -81,9 +81,7 @@ namespace CSMWorld
|
||||
throw std::logic_error ("attempt to modify a deleted record");
|
||||
|
||||
mModified = modified;
|
||||
|
||||
if (mState!=State_ModifiedOnly)
|
||||
mState = mBase==mModified ? State_BaseOnly : State_Modified;
|
||||
mState = State_Modified;
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
|
@ -19,6 +19,7 @@ namespace
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty" },
|
||||
{ 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_Skills, "Skills" },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
@ -27,6 +28,7 @@ namespace
|
||||
{
|
||||
{ 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_Skill, "Skill" },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
|
||||
};
|
||||
@ -43,7 +45,7 @@ CSMWorld::UniversalId::UniversalId (const std::string& universalId)
|
||||
{
|
||||
std::string::size_type index = universalId.find (':');
|
||||
|
||||
if (index==std::string::npos)
|
||||
if (index!=std::string::npos)
|
||||
{
|
||||
std::string type = universalId.substr (0, index);
|
||||
|
||||
|
@ -37,8 +37,9 @@ namespace CSMWorld
|
||||
Type_Global,
|
||||
Type_VerificationResults,
|
||||
Type_Gmsts,
|
||||
Type_Gmst
|
||||
|
||||
Type_Gmst,
|
||||
Type_Skills,
|
||||
Type_Skill
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -86,6 +86,10 @@ void CSVDoc::View::setupWorldMenu()
|
||||
connect (gmsts, SIGNAL (triggered()), this, SLOT (addGmstsSubView()));
|
||||
world->addAction (gmsts);
|
||||
|
||||
QAction *skills = new QAction (tr ("Skills"), this);
|
||||
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView()));
|
||||
world->addAction (skills);
|
||||
|
||||
mVerify = new QAction (tr ("&Verify"), this);
|
||||
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
|
||||
world->addAction (mVerify);
|
||||
@ -244,6 +248,11 @@ void CSVDoc::View::addGmstsSubView()
|
||||
addSubView (CSMWorld::UniversalId::Type_Gmsts);
|
||||
}
|
||||
|
||||
void CSVDoc::View::addSkillsSubView()
|
||||
{
|
||||
addSubView (CSMWorld::UniversalId::Type_Skills);
|
||||
}
|
||||
|
||||
void CSVDoc::View::abortOperation (int type)
|
||||
{
|
||||
mDocument->abortOperation (type);
|
||||
|
@ -116,6 +116,7 @@ namespace CSVDoc
|
||||
|
||||
void addGmstsSubView();
|
||||
|
||||
void addSkillsSubView();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,17 @@ void CSVDoc::ViewManager::updateIndices()
|
||||
CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
||||
: mDocumentManager (documentManager), mExitOnSaveStateChange(false), mUserWarned(false)
|
||||
{
|
||||
static const char *sSpecialisations[] =
|
||||
{
|
||||
"Combat", "Magic", "Stealth", 0
|
||||
};
|
||||
|
||||
static const char *sAttributes[] =
|
||||
{
|
||||
"Strength", "Intelligence", "Willpower", "Agility", "Speed", "Endurance", "Personality",
|
||||
"Luck", 0
|
||||
};
|
||||
|
||||
mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection;
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType,
|
||||
@ -45,6 +56,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_GlobalVarType,
|
||||
new CSVWorld::VarTypeDelegateFactory (ESM::VT_Short, ESM::VT_Long, ESM::VT_Float));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_Specialisation,
|
||||
new CSVWorld::EnumDelegateFactory (sSpecialisations));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_Attribute,
|
||||
new CSVWorld::EnumDelegateFactory (sAttributes));
|
||||
}
|
||||
|
||||
CSVDoc::ViewManager::~ViewManager()
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QAbstractTableModel>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QSpinBox>
|
||||
#include <QLineEdit>
|
||||
@ -24,7 +24,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
|
||||
|
||||
widget->setLayout (layout);
|
||||
|
||||
QAbstractTableModel *model = document.getData().getTableModel (id);
|
||||
QAbstractItemModel *model = document.getData().getTableModel (id);
|
||||
|
||||
int columns = model->columnCount();
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
#include "enumdelegate.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QComboBox>
|
||||
@ -89,6 +90,16 @@ void CSVWorld::EnumDelegate::paint (QPainter *painter, const QStyleOptionViewIte
|
||||
}
|
||||
|
||||
|
||||
CSVWorld::EnumDelegateFactory::EnumDelegateFactory() {}
|
||||
|
||||
CSVWorld::EnumDelegateFactory::EnumDelegateFactory (const char **names)
|
||||
{
|
||||
assert (names);
|
||||
|
||||
for (int i=0; names[i]; ++i)
|
||||
add (i, names[i]);
|
||||
}
|
||||
|
||||
CSVWorld::CommandDelegate *CSVWorld::EnumDelegateFactory::makeDelegate (QUndoStack& undoStack,
|
||||
QObject *parent) const
|
||||
{
|
||||
|
@ -45,6 +45,11 @@ namespace CSVWorld
|
||||
|
||||
public:
|
||||
|
||||
EnumDelegateFactory();
|
||||
|
||||
EnumDelegateFactory (const char **names);
|
||||
///< \param names Array of char pointer with a 0-pointer as end mark
|
||||
|
||||
virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const;
|
||||
///< The ownership of the returned CommandDelegate is transferred to the caller.
|
||||
|
||||
|
@ -14,6 +14,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||
manager.add (CSMWorld::UniversalId::Type_Gmsts,
|
||||
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Skills,
|
||||
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Global,
|
||||
new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
|
||||
}
|
@ -31,6 +31,7 @@ add_openmw_dir (mwgui
|
||||
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
|
||||
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
|
||||
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
|
||||
merchantrepair repair
|
||||
)
|
||||
|
||||
add_openmw_dir (mwdialogue
|
||||
@ -53,7 +54,7 @@ add_openmw_dir (mwworld
|
||||
containerstore actiontalk actiontake manualref player cellfunctors failedaction
|
||||
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
||||
actionequip timestamp actionalchemy cellstore actionapply actioneat
|
||||
esmstore store recordcmp fallback
|
||||
esmstore store recordcmp fallback actionrepair
|
||||
)
|
||||
|
||||
add_openmw_dir (mwclass
|
||||
@ -64,7 +65,7 @@ add_openmw_dir (mwclass
|
||||
add_openmw_dir (mwmechanics
|
||||
mechanicsmanagerimp stat character creaturestats magiceffects movement actors activators
|
||||
drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow
|
||||
aiescort aiactivate
|
||||
aiescort aiactivate repair enchanting
|
||||
)
|
||||
|
||||
add_openmw_dir (mwbase
|
||||
|
@ -238,6 +238,8 @@ namespace MWBase
|
||||
virtual void startSpellMaking(MWWorld::Ptr actor) = 0;
|
||||
virtual void startEnchanting(MWWorld::Ptr actor) = 0;
|
||||
virtual void startTraining(MWWorld::Ptr actor) = 0;
|
||||
virtual void startRepair(MWWorld::Ptr actor) = 0;
|
||||
virtual void startRepairItem(MWWorld::Ptr item) = 0;
|
||||
|
||||
virtual void changePointer (const std::string& name) = 0;
|
||||
|
||||
|
@ -244,27 +244,44 @@ namespace MWBase
|
||||
///< Toggle a render mode.
|
||||
///< \return Resulting mode
|
||||
|
||||
virtual const ESM::Potion *createRecord (const ESM::Potion& record)
|
||||
= 0;
|
||||
///< Create a new recrod (of type potion) in the ESM store.
|
||||
virtual const ESM::Potion *createRecord (const ESM::Potion& record) = 0;
|
||||
///< Create a new record (of type potion) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Spell *createRecord (const ESM::Spell& record)
|
||||
= 0;
|
||||
///< Create a new recrod (of type spell) in the ESM store.
|
||||
virtual const ESM::Spell *createRecord (const ESM::Spell& record) = 0;
|
||||
///< Create a new record (of type spell) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Class *createRecord (const ESM::Class& record)
|
||||
= 0;
|
||||
///< Create a new recrod (of type class) in the ESM store.
|
||||
virtual const ESM::Class *createRecord (const ESM::Class& record) = 0;
|
||||
///< Create a new record (of type class) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Cell *createRecord (const ESM::Cell& record) = 0;
|
||||
///< Create a new recrod (of type cell) in the ESM store.
|
||||
///< Create a new record (of type cell) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0;
|
||||
///< Create a new recrod (of type npc) in the ESM store.
|
||||
///< Create a new record (of type npc) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Armor *createRecord (const ESM::Armor& record) = 0;
|
||||
///< Create a new record (of type armor) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Weapon *createRecord (const ESM::Weapon& record) = 0;
|
||||
///< Create a new record (of type weapon) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Clothing *createRecord (const ESM::Clothing& record) = 0;
|
||||
///< Create a new record (of type clothing) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Enchantment *createRecord (const ESM::Enchantment& record) = 0;
|
||||
///< Create a new record (of type enchantment) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Book *createRecord (const ESM::Book& record) = 0;
|
||||
///< Create a new record (of type book) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual void update (float duration, bool paused) = 0;
|
||||
|
@ -247,8 +247,9 @@ namespace MWClass
|
||||
|
||||
text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor);
|
||||
|
||||
/// \todo store the current armor health somewhere
|
||||
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
|
||||
int remainingHealth = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mHealth;
|
||||
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/"
|
||||
+ MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
|
||||
|
||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight) + " (" + typeText + ")";
|
||||
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
||||
@ -273,6 +274,20 @@ namespace MWClass
|
||||
return ref->mBase->mEnchant;
|
||||
}
|
||||
|
||||
std::string Armor::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Armor> *ref =
|
||||
ptr.get<ESM::Armor>();
|
||||
|
||||
ESM::Armor newItem = *ref->mBase;
|
||||
newItem.mId="";
|
||||
newItem.mName=newName;
|
||||
newItem.mData.mEnchant=enchCharge;
|
||||
newItem.mEnchant=enchId;
|
||||
const ESM::Armor *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
|
||||
return record->mId;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));
|
||||
@ -290,4 +305,12 @@ namespace MWClass
|
||||
|
||||
return MWWorld::Ptr(&cell.mArmors.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
short Armor::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Armor> *ref =
|
||||
ptr.get<ESM::Armor>();
|
||||
|
||||
return ref->mBase->mData.mEnchant;
|
||||
}
|
||||
}
|
||||
|
@ -65,11 +65,15 @@ namespace MWClass
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual std::string applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -147,6 +147,21 @@ namespace MWClass
|
||||
return ref->mBase->mEnchant;
|
||||
}
|
||||
|
||||
std::string Book::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Book> *ref =
|
||||
ptr.get<ESM::Book>();
|
||||
|
||||
ESM::Book newItem = *ref->mBase;
|
||||
newItem.mId="";
|
||||
newItem.mName=newName;
|
||||
newItem.mData.mIsScroll = 1;
|
||||
newItem.mData.mEnchant=enchCharge;
|
||||
newItem.mEnchant=enchId;
|
||||
const ESM::Book *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
|
||||
return record->mId;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr));
|
||||
@ -160,4 +175,12 @@ namespace MWClass
|
||||
|
||||
return MWWorld::Ptr(&cell.mBooks.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
short Book::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Book> *ref =
|
||||
ptr.get<ESM::Book>();
|
||||
|
||||
return ref->mBase->mData.mEnchant;
|
||||
}
|
||||
}
|
||||
|
@ -51,10 +51,14 @@ namespace MWClass
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual std::string applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -221,6 +221,20 @@ namespace MWClass
|
||||
return ref->mBase->mEnchant;
|
||||
}
|
||||
|
||||
std::string Clothing::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Clothing> *ref =
|
||||
ptr.get<ESM::Clothing>();
|
||||
|
||||
ESM::Clothing newItem = *ref->mBase;
|
||||
newItem.mId="";
|
||||
newItem.mName=newName;
|
||||
newItem.mData.mEnchant=enchCharge;
|
||||
newItem.mEnchant=enchId;
|
||||
const ESM::Clothing *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
|
||||
return record->mId;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));
|
||||
@ -238,4 +252,12 @@ namespace MWClass
|
||||
|
||||
return MWWorld::Ptr(&cell.mClothes.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
short Clothing::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Clothing> *ref =
|
||||
ptr.get<ESM::Clothing>();
|
||||
|
||||
return ref->mBase->mData.mEnchant;
|
||||
}
|
||||
}
|
||||
|
@ -59,11 +59,15 @@ namespace MWClass
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual std::string applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#include "lockpick.hpp"
|
||||
|
||||
#include <components/esm/loadlocks.hpp>
|
||||
#include <components/esm/loadlock.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
@ -41,8 +41,8 @@ namespace MWClass
|
||||
|
||||
std::string Lockpick::getModel(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Tool> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
||||
ptr.get<ESM::Lockpick>();
|
||||
assert(ref->mBase != NULL);
|
||||
|
||||
const std::string &model = ref->mBase->mModel;
|
||||
@ -54,8 +54,8 @@ namespace MWClass
|
||||
|
||||
std::string Lockpick::getName (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Tool> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
||||
ptr.get<ESM::Lockpick>();
|
||||
|
||||
return ref->mBase->mName;
|
||||
}
|
||||
@ -75,8 +75,8 @@ namespace MWClass
|
||||
|
||||
std::string Lockpick::getScript (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Tool> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
||||
ptr.get<ESM::Lockpick>();
|
||||
|
||||
return ref->mBase->mScript;
|
||||
}
|
||||
@ -92,8 +92,8 @@ namespace MWClass
|
||||
|
||||
int Lockpick::getValue (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Tool> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
||||
ptr.get<ESM::Lockpick>();
|
||||
|
||||
return ref->mBase->mData.mValue;
|
||||
}
|
||||
@ -102,7 +102,7 @@ namespace MWClass
|
||||
{
|
||||
boost::shared_ptr<Class> instance (new Lockpick);
|
||||
|
||||
registerClass (typeid (ESM::Tool).name(), instance);
|
||||
registerClass (typeid (ESM::Lockpick).name(), instance);
|
||||
}
|
||||
|
||||
std::string Lockpick::getUpSoundId (const MWWorld::Ptr& ptr) const
|
||||
@ -117,24 +117,24 @@ namespace MWClass
|
||||
|
||||
std::string Lockpick::getInventoryIcon (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Tool> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
||||
ptr.get<ESM::Lockpick>();
|
||||
|
||||
return ref->mBase->mIcon;
|
||||
}
|
||||
|
||||
bool Lockpick::hasToolTip (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Tool> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
||||
ptr.get<ESM::Lockpick>();
|
||||
|
||||
return (ref->mBase->mName != "");
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Tool> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
||||
ptr.get<ESM::Lockpick>();
|
||||
|
||||
MWGui::ToolTipInfo info;
|
||||
info.caption = ref->mBase->mName + MWGui::ToolTips::getCountString(ptr.getRefData().getCount());
|
||||
@ -142,9 +142,9 @@ namespace MWClass
|
||||
|
||||
std::string text;
|
||||
|
||||
/// \todo store remaining uses somewhere
|
||||
int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses;
|
||||
|
||||
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
|
||||
text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
|
||||
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
|
||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
||||
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
||||
@ -171,8 +171,8 @@ namespace MWClass
|
||||
MWWorld::Ptr
|
||||
Lockpick::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Tool> *ref =
|
||||
ptr.get<ESM::Tool>();
|
||||
MWWorld::LiveCellRef<ESM::Lockpick> *ref =
|
||||
ptr.get<ESM::Lockpick>();
|
||||
|
||||
return MWWorld::Ptr(&cell.mLockpicks.insert(*ref), &cell);
|
||||
}
|
||||
|
@ -89,7 +89,15 @@ namespace MWClass
|
||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
return ref->mBase->mData.mValue;
|
||||
int value = (ptr.getCellRef().mGoldValue == 1) ? ref->mBase->mData.mValue : ptr.getCellRef().mGoldValue;
|
||||
|
||||
if (ptr.getCellRef().mSoul != "")
|
||||
{
|
||||
const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(ref->mRef.mSoul);
|
||||
value *= creature->mData.mSoul;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void Miscellaneous::registerSelf()
|
||||
@ -151,8 +159,10 @@ namespace MWClass
|
||||
int count = ptr.getRefData().getCount();
|
||||
|
||||
bool isGold = (ref->mBase->mName == store.get<ESM::GameSetting>().find("sGold")->getString());
|
||||
if (isGold && count == 1)
|
||||
count = ref->mBase->mData.mValue;
|
||||
if (isGold && ptr.getCellRef().mGoldValue != 1)
|
||||
count = ptr.getCellRef().mGoldValue;
|
||||
else if (isGold)
|
||||
count *= ref->mBase->mData.mValue;
|
||||
|
||||
std::string countString;
|
||||
if (!isGold)
|
||||
@ -174,7 +184,7 @@ namespace MWClass
|
||||
if (!isGold)
|
||||
{
|
||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
||||
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
||||
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
|
||||
}
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||
@ -214,7 +224,8 @@ namespace MWClass
|
||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||
newRef.getPtr().get<ESM::Miscellaneous>();
|
||||
newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell);
|
||||
newPtr.getRefData ().setCount(goldAmount);
|
||||
newPtr.getRefData ().setCount(1);
|
||||
newPtr.getCellRef().mGoldValue = goldAmount;
|
||||
} else {
|
||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#include "probe.hpp"
|
||||
|
||||
#include <components/esm/loadlocks.hpp>
|
||||
#include <components/esm/loadprob.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
@ -141,9 +141,9 @@ namespace MWClass
|
||||
|
||||
std::string text;
|
||||
|
||||
/// \todo store remaining uses somewhere
|
||||
int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses;
|
||||
|
||||
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
|
||||
text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
|
||||
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
|
||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
||||
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#include "repair.hpp"
|
||||
|
||||
#include <components/esm/loadlocks.hpp>
|
||||
#include <components/esm/loadrepa.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
@ -12,6 +12,7 @@
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
#include "../mwworld/actionrepair.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
@ -120,6 +121,19 @@ namespace MWClass
|
||||
return (ref->mBase->mName != "");
|
||||
}
|
||||
|
||||
bool Repair::hasItemHealth (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int Repair::getItemMaxHealth (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Repair> *ref =
|
||||
ptr.get<ESM::Repair>();
|
||||
|
||||
return ref->mBase->mData.mUses;
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Repair> *ref =
|
||||
@ -131,9 +145,9 @@ namespace MWClass
|
||||
|
||||
std::string text;
|
||||
|
||||
/// \todo store remaining uses somewhere
|
||||
int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses;
|
||||
|
||||
text += "\n#{sUses}: " + MWGui::ToolTips::toString(ref->mBase->mData.mUses);
|
||||
text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
|
||||
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
|
||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
||||
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
||||
@ -156,4 +170,9 @@ namespace MWClass
|
||||
|
||||
return MWWorld::Ptr(&cell.mRepairs.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Repair::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRepair(ptr));
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,18 @@ namespace MWClass
|
||||
///< Return name of inventory icon.
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu (default implementation: return a
|
||||
/// null action).
|
||||
|
||||
virtual bool hasItemHealth (const MWWorld::Ptr& ptr) const;
|
||||
///< \return Item health data available? (default implementation: false)
|
||||
|
||||
virtual int getItemMaxHealth (const MWWorld::Ptr& ptr) const;
|
||||
///< Return item max health or throw an exception, if class does not have item health
|
||||
/// (default implementation: throw an exceoption)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,10 @@ namespace MWClass
|
||||
|
||||
bool Weapon::hasItemHealth (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
return true;
|
||||
MWWorld::LiveCellRef<ESM::Weapon> *ref =
|
||||
ptr.get<ESM::Weapon>();
|
||||
|
||||
return (ref->mBase->mData.mType < 11); // thrown weapons and arrows/bolts don't have health, only quantity
|
||||
}
|
||||
|
||||
int Weapon::getItemMaxHealth (const MWWorld::Ptr& ptr) const
|
||||
@ -334,9 +337,12 @@ namespace MWClass
|
||||
}
|
||||
}
|
||||
|
||||
/// \todo store the current weapon health somewhere
|
||||
if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity
|
||||
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
|
||||
{
|
||||
int remainingHealth = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mHealth;
|
||||
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/"
|
||||
+ MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
|
||||
}
|
||||
|
||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
||||
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
||||
@ -361,6 +367,20 @@ namespace MWClass
|
||||
return ref->mBase->mEnchant;
|
||||
}
|
||||
|
||||
std::string Weapon::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Weapon> *ref =
|
||||
ptr.get<ESM::Weapon>();
|
||||
|
||||
ESM::Weapon newItem = *ref->mBase;
|
||||
newItem.mId="";
|
||||
newItem.mName=newName;
|
||||
newItem.mData.mEnchant=enchCharge;
|
||||
newItem.mEnchant=enchId;
|
||||
const ESM::Weapon *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
|
||||
return record->mId;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));
|
||||
@ -378,4 +398,12 @@ namespace MWClass
|
||||
|
||||
return MWWorld::Ptr(&cell.mWeapons.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
short Weapon::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Weapon> *ref =
|
||||
ptr.get<ESM::Weapon>();
|
||||
|
||||
return ref->mBase->mData.mEnchant;
|
||||
}
|
||||
}
|
||||
|
@ -65,11 +65,15 @@ namespace MWClass
|
||||
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
|
||||
virtual std::string applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
|
||||
|
||||
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||
const;
|
||||
///< Generate action for using via inventory menu
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -367,6 +367,9 @@ namespace MWDialogue
|
||||
if (services & ESM::NPC::Enchanting)
|
||||
windowServices |= MWGui::DialogueWindow::Service_Enchant;
|
||||
|
||||
if (services & ESM::NPC::Repair)
|
||||
windowServices |= MWGui::DialogueWindow::Service_Repair;
|
||||
|
||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
||||
|
||||
win->setServices (windowServices);
|
||||
|
@ -136,8 +136,12 @@ bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info, bool invert
|
||||
|
||||
bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const
|
||||
{
|
||||
if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name())
|
||||
return select.isInverted();
|
||||
if (select.isNpcOnly() && (mActor.getTypeName() != typeid (ESM::NPC).name()))
|
||||
// If the actor is a creature, we do not test the conditions applicable
|
||||
// only to NPCs. Such conditions can never be satisfied, apart
|
||||
// inverted ones (NotClass, NotRace, NotFaction return true
|
||||
// because creatures are not of any race, class or faction).
|
||||
return select.getType() == SelectWrapper::Type_Inverted;
|
||||
|
||||
switch (select.getType())
|
||||
{
|
||||
@ -145,6 +149,9 @@ bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const
|
||||
case SelectWrapper::Type_Integer: return select.selectCompare (getSelectStructInteger (select));
|
||||
case SelectWrapper::Type_Numeric: return testSelectStructNumeric (select);
|
||||
case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select));
|
||||
|
||||
// We must not do the comparison for inverted functions (eg. Function_NotClass)
|
||||
case SelectWrapper::Type_Inverted: return getSelectStructBoolean (select);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -433,6 +440,30 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co
|
||||
|
||||
return Misc::StringUtils::lowerCase (mActor.getCell()->mCell->mName)!=select.getName();
|
||||
|
||||
case SelectWrapper::Function_NotLocal:
|
||||
{
|
||||
std::string scriptName = MWWorld::Class::get (mActor).getScript (mActor);
|
||||
|
||||
if (scriptName.empty())
|
||||
// This actor has no attached script, so there is no local variable
|
||||
return true;
|
||||
|
||||
const ESM::Script *script =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (scriptName);
|
||||
|
||||
std::string name = select.getName();
|
||||
|
||||
int i = 0;
|
||||
for (; i < static_cast<int> (script->mVarNames.size()); ++i)
|
||||
if (Misc::StringUtils::lowerCase(script->mVarNames[i]) == name)
|
||||
break;
|
||||
|
||||
if (i >= static_cast<int> (script->mVarNames.size()))
|
||||
return true; // script does not have a variable of this name
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
case SelectWrapper::Function_SameGender:
|
||||
|
||||
return (player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female)==
|
||||
|
@ -117,7 +117,7 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con
|
||||
case '9': return Function_NotClass;
|
||||
case 'A': return Function_NotRace;
|
||||
case 'B': return Function_NotCell;
|
||||
case 'C': return Function_Local;
|
||||
case 'C': return Function_NotLocal;
|
||||
}
|
||||
|
||||
return Function_None;
|
||||
@ -219,7 +219,6 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
|
||||
static const Function booleanFunctions[] =
|
||||
{
|
||||
Function_False,
|
||||
Function_NotId, Function_NotFaction, Function_NotClass, Function_NotRace, Function_NotCell,
|
||||
Function_SameGender, Function_SameRace, Function_SameFaction,
|
||||
Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus,
|
||||
Function_PcExpelled,
|
||||
@ -231,6 +230,13 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
|
||||
Function_None // end marker
|
||||
};
|
||||
|
||||
static const Function invertedBooleanFunctions[] =
|
||||
{
|
||||
Function_NotId, Function_NotFaction, Function_NotClass,
|
||||
Function_NotRace, Function_NotCell, Function_NotLocal,
|
||||
Function_None // end marker
|
||||
};
|
||||
|
||||
Function function = getFunction();
|
||||
|
||||
for (int i=0; integerFunctions[i]!=Function_None; ++i)
|
||||
@ -245,21 +251,18 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
|
||||
if (booleanFunctions[i]==function)
|
||||
return Type_Boolean;
|
||||
|
||||
for (int i=0; invertedBooleanFunctions[i]!=Function_None; ++i)
|
||||
if (invertedBooleanFunctions[i]==function)
|
||||
return Type_Inverted;
|
||||
|
||||
return Type_None;
|
||||
}
|
||||
|
||||
bool MWDialogue::SelectWrapper::isInverted() const
|
||||
{
|
||||
char type = mSelect.mSelectRule[1];
|
||||
|
||||
return type=='7' || type=='8' || type=='9' || type=='A' || type=='B' || type=='C';
|
||||
}
|
||||
|
||||
bool MWDialogue::SelectWrapper::isNpcOnly() const
|
||||
{
|
||||
static const Function functions[] =
|
||||
{
|
||||
Function_NotFaction, SelectWrapper::Function_NotClass, SelectWrapper::Function_NotRace,
|
||||
Function_NotFaction, Function_NotClass, Function_NotRace,
|
||||
Function_SameGender, Function_SameRace, Function_SameFaction,
|
||||
Function_PcSkill,
|
||||
Function_PcExpelled,
|
||||
@ -283,17 +286,17 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const
|
||||
|
||||
bool MWDialogue::SelectWrapper::selectCompare (int value) const
|
||||
{
|
||||
return selectCompareImp (mSelect, value)!=isInverted(); // logic XOR
|
||||
return selectCompareImp (mSelect, value);
|
||||
}
|
||||
|
||||
bool MWDialogue::SelectWrapper::selectCompare (float value) const
|
||||
{
|
||||
return selectCompareImp (mSelect, value)!=isInverted(); // logic XOR
|
||||
return selectCompareImp (mSelect, value);
|
||||
}
|
||||
|
||||
bool MWDialogue::SelectWrapper::selectCompare (bool value) const
|
||||
{
|
||||
return selectCompareImp (mSelect, static_cast<int> (value))!=isInverted(); // logic XOR
|
||||
return selectCompareImp (mSelect, static_cast<int> (value));
|
||||
}
|
||||
|
||||
std::string MWDialogue::SelectWrapper::getName() const
|
||||
|
@ -22,6 +22,7 @@ namespace MWDialogue
|
||||
Function_NotClass,
|
||||
Function_NotRace,
|
||||
Function_NotCell,
|
||||
Function_NotLocal,
|
||||
Function_Local,
|
||||
Function_Global,
|
||||
Function_SameGender, Function_SameRace, Function_SameFaction,
|
||||
@ -50,7 +51,8 @@ namespace MWDialogue
|
||||
Type_None,
|
||||
Type_Integer,
|
||||
Type_Numeric,
|
||||
Type_Boolean
|
||||
Type_Boolean,
|
||||
Type_Inverted
|
||||
};
|
||||
|
||||
private:
|
||||
@ -67,8 +69,6 @@ namespace MWDialogue
|
||||
|
||||
Type getType() const;
|
||||
|
||||
bool isInverted() const;
|
||||
|
||||
bool isNpcOnly() const;
|
||||
///< \attention Do not call any of the select functions for this select struct!
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace
|
||||
mapping.push_back( typeid(ESM::Book).name() );
|
||||
mapping.push_back( typeid(ESM::Light).name() );
|
||||
mapping.push_back( typeid(ESM::Miscellaneous).name() );
|
||||
mapping.push_back( typeid(ESM::Tool).name() );
|
||||
mapping.push_back( typeid(ESM::Lockpick).name() );
|
||||
mapping.push_back( typeid(ESM::Repair).name() );
|
||||
mapping.push_back( typeid(ESM::Probe).name() );
|
||||
|
||||
@ -68,6 +68,16 @@ namespace
|
||||
return compareType(left.getTypeName(), right.getTypeName());
|
||||
}
|
||||
}
|
||||
|
||||
bool isChargedSoulstone (MWWorld::Ptr ptr)
|
||||
{
|
||||
if (ptr.getTypeName() != typeid(ESM::Miscellaneous).name())
|
||||
return false;
|
||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
return (ref->mRef.mSoul != "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -345,7 +355,7 @@ void ContainerBase::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
mItemView->setViewOffset(MyGUI::IntPoint(mItemView->getViewOffset().left + _rel*0.3, 0));
|
||||
}
|
||||
|
||||
void ContainerBase::setFilter(ContainerBase::Filter filter)
|
||||
void ContainerBase::setFilter(int filter)
|
||||
{
|
||||
mFilter = filter;
|
||||
drawItems();
|
||||
@ -369,29 +379,34 @@ void ContainerBase::drawItems()
|
||||
int maxHeight = mItemView->getSize().height - 58;
|
||||
|
||||
bool onlyMagic = false;
|
||||
bool noMagic = false;
|
||||
int categories = 0;
|
||||
if (mFilter == Filter_All)
|
||||
categories = MWWorld::ContainerStore::Type_All;
|
||||
else if (mFilter == Filter_Weapon)
|
||||
categories = MWWorld::ContainerStore::Type_Weapon;
|
||||
else if (mFilter == Filter_Apparel)
|
||||
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor;
|
||||
else if (mFilter == Filter_Magic)
|
||||
if (mFilter & Filter_All)
|
||||
categories |= MWWorld::ContainerStore::Type_All;
|
||||
if (mFilter & Filter_Weapon)
|
||||
categories |= MWWorld::ContainerStore::Type_Weapon;
|
||||
if (mFilter & Filter_Apparel)
|
||||
categories |= MWWorld::ContainerStore::Type_Clothing | MWWorld::ContainerStore::Type_Armor;
|
||||
if (mFilter & Filter_Magic)
|
||||
{
|
||||
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor
|
||||
+ MWWorld::ContainerStore::Type_Weapon + MWWorld::ContainerStore::Type_Book
|
||||
+ MWWorld::ContainerStore::Type_Potion;
|
||||
categories |= MWWorld::ContainerStore::Type_Clothing | MWWorld::ContainerStore::Type_Armor
|
||||
| MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Book
|
||||
| MWWorld::ContainerStore::Type_Potion;
|
||||
onlyMagic = true;
|
||||
}
|
||||
else if (mFilter == Filter_Misc)
|
||||
if (mFilter & Filter_Misc)
|
||||
{
|
||||
categories = MWWorld::ContainerStore::Type_Miscellaneous + MWWorld::ContainerStore::Type_Book
|
||||
+ MWWorld::ContainerStore::Type_Ingredient + MWWorld::ContainerStore::Type_Repair
|
||||
+ MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light
|
||||
+ MWWorld::ContainerStore::Type_Apparatus + MWWorld::ContainerStore::Type_Probe;
|
||||
categories |= MWWorld::ContainerStore::Type_Miscellaneous | MWWorld::ContainerStore::Type_Book
|
||||
| MWWorld::ContainerStore::Type_Ingredient | MWWorld::ContainerStore::Type_Repair
|
||||
| MWWorld::ContainerStore::Type_Lockpick | MWWorld::ContainerStore::Type_Light
|
||||
| MWWorld::ContainerStore::Type_Apparatus | MWWorld::ContainerStore::Type_Probe;
|
||||
}
|
||||
else if (mFilter == Filter_Ingredients)
|
||||
categories = MWWorld::ContainerStore::Type_Ingredient;
|
||||
if (mFilter & Filter_Ingredients)
|
||||
categories |= MWWorld::ContainerStore::Type_Ingredient;
|
||||
if (mFilter & Filter_ChargedSoulstones)
|
||||
categories |= MWWorld::ContainerStore::Type_Miscellaneous;
|
||||
if (mFilter & Filter_NoMagic)
|
||||
noMagic = true;
|
||||
|
||||
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
|
||||
|
||||
@ -466,12 +481,29 @@ void ContainerBase::drawItems()
|
||||
{
|
||||
const MWWorld::Ptr* iter = &((*it).first);
|
||||
|
||||
|
||||
if (onlyMagic
|
||||
&& it->second != ItemState_Barter
|
||||
&& MWWorld::Class::get(*iter).getEnchantment(*iter) == ""
|
||||
&& iter->getTypeName() != typeid(ESM::Potion).name())
|
||||
continue;
|
||||
|
||||
if (noMagic
|
||||
&& it->second != ItemState_Barter
|
||||
&& (MWWorld::Class::get(*iter).getEnchantment(*iter) != ""
|
||||
|| iter->getTypeName() == typeid(ESM::Potion).name()))
|
||||
continue;
|
||||
|
||||
if ( (mFilter & Filter_ChargedSoulstones)
|
||||
&& !isChargedSoulstone(*iter))
|
||||
continue;
|
||||
|
||||
int displayCount = iter->getRefData().getCount();
|
||||
if (mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop && *iter == *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>())
|
||||
{
|
||||
displayCount -= mDragAndDrop->mDraggedCount;
|
||||
}
|
||||
if(displayCount > 0 && !(onlyMagic && it->second != ItemState_Barter && MWWorld::Class::get(*iter).getEnchantment(*iter) == "" && iter->getTypeName() != typeid(ESM::Potion).name()))
|
||||
if(displayCount > 0)
|
||||
{
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(*iter).getInventoryIcon(*iter);
|
||||
|
@ -48,16 +48,17 @@ namespace MWGui
|
||||
ContainerBase(DragAndDrop* dragAndDrop);
|
||||
virtual ~ContainerBase();
|
||||
|
||||
enum Filter
|
||||
{
|
||||
Filter_All = 0x01,
|
||||
Filter_Weapon = 0x02,
|
||||
Filter_Apparel = 0x03,
|
||||
Filter_Magic = 0x04,
|
||||
Filter_Misc = 0x05,
|
||||
// basic types (inclusive)
|
||||
static const int Filter_All = (1<<0);
|
||||
static const int Filter_Weapon = (1<<1);
|
||||
static const int Filter_Apparel = (1<<2);
|
||||
static const int Filter_Ingredients = (1<<3);
|
||||
static const int Filter_Misc = (1<<4);
|
||||
|
||||
Filter_Ingredients = 0x06
|
||||
};
|
||||
// special filtering (exclusive)
|
||||
static const int Filter_Magic = (1<<5);
|
||||
static const int Filter_NoMagic = (1<<6);
|
||||
static const int Filter_ChargedSoulstones = (1<<7);
|
||||
|
||||
enum ItemState
|
||||
{
|
||||
@ -78,7 +79,7 @@ namespace MWGui
|
||||
MWWorld::ContainerStore& getBoughtItems() { return mBoughtItems; }
|
||||
|
||||
void openContainer(MWWorld::Ptr container);
|
||||
void setFilter(Filter filter); ///< set category filter
|
||||
void setFilter(int filter); ///< set category filter
|
||||
void drawItems();
|
||||
|
||||
protected:
|
||||
@ -92,7 +93,7 @@ namespace MWGui
|
||||
|
||||
DragAndDrop* mDragAndDrop;
|
||||
|
||||
Filter mFilter;
|
||||
int mFilter;
|
||||
|
||||
// bought items are put in a separate ContainerStore so that they don't stack with other (not bought) items.
|
||||
MWWorld::ContainerStore mBoughtItems;
|
||||
|
@ -230,14 +230,14 @@ void DialogueWindow::onSelectTopic(const std::string& topic, int id)
|
||||
{
|
||||
if (!mEnabled) return;
|
||||
|
||||
int separatorPos = mTopicsList->getItemCount();
|
||||
int separatorPos = 0;
|
||||
for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
|
||||
{
|
||||
if (mTopicsList->getItemNameAt(i) == "")
|
||||
separatorPos = i;
|
||||
}
|
||||
|
||||
if (id > separatorPos)
|
||||
if (id >= separatorPos)
|
||||
MWBase::Environment::get().getDialogueManager()->keywordSelected(lower_string(topic));
|
||||
else
|
||||
{
|
||||
@ -280,6 +280,11 @@ void DialogueWindow::onSelectTopic(const std::string& topic, int id)
|
||||
mWindowManager.pushGuiMode(GM_Training);
|
||||
mWindowManager.startTraining (mPtr);
|
||||
}
|
||||
else if (topic == gmst.find("sRepair")->getString())
|
||||
{
|
||||
mWindowManager.pushGuiMode(GM_MerchantRepair);
|
||||
mWindowManager.startRepair (mPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -321,12 +326,15 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
|
||||
if (mServices & Service_CreateSpells)
|
||||
mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString());
|
||||
|
||||
// if (mServices & Service_Enchant)
|
||||
// mTopicsList->addItem(gmst.find("sEnchanting")->getString());
|
||||
if (mServices & Service_Enchant)
|
||||
mTopicsList->addItem(gmst.find("sEnchanting")->getString());
|
||||
|
||||
if (mServices & Service_Training)
|
||||
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
|
||||
|
||||
if (mServices & Service_Repair)
|
||||
mTopicsList->addItem(gmst.find("sRepair")->getString());
|
||||
|
||||
if (anyService || mPtr.getTypeName() == typeid(ESM::NPC).name())
|
||||
mTopicsList->addSeparator();
|
||||
|
||||
@ -381,10 +389,17 @@ std::string DialogueWindow::parseText(const std::string& text)
|
||||
|
||||
std::vector<std::string> topics;
|
||||
|
||||
bool hasSeparator = false;
|
||||
for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
|
||||
{
|
||||
if (mTopicsList->getItemNameAt(i) == "")
|
||||
hasSeparator = true;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0;i<mTopicsList->getItemCount();i++)
|
||||
{
|
||||
std::string keyWord = mTopicsList->getItemNameAt(i);
|
||||
if (separatorReached)
|
||||
if (separatorReached || !hasSeparator)
|
||||
topics.push_back(keyWord);
|
||||
else if (keyWord == "")
|
||||
separatorReached = true;
|
||||
|
@ -81,7 +81,8 @@ namespace MWGui
|
||||
Service_CreateSpells = 0x04,
|
||||
Service_Enchant = 0x08,
|
||||
Service_Training = 0x10,
|
||||
Service_Travel = 0x20
|
||||
Service_Travel = 0x20,
|
||||
Service_Repair = 0x40
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -1,5 +1,15 @@
|
||||
#include "enchantingdialog.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
|
||||
#include "itemselection.hpp"
|
||||
#include "container.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
@ -8,19 +18,71 @@ namespace MWGui
|
||||
EnchantingDialog::EnchantingDialog(MWBase::WindowManager &parWindowManager)
|
||||
: WindowBase("openmw_enchanting_dialog.layout", parWindowManager)
|
||||
, EffectEditorBase(parWindowManager)
|
||||
, mItemSelectionDialog(NULL)
|
||||
, mEnchanting(MWBase::Environment::get().getWorld()->getPlayer().getPlayer())
|
||||
{
|
||||
getWidget(mName, "NameEdit");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
getWidget(mAvailableEffectsList, "AvailableEffects");
|
||||
getWidget(mUsedEffectsView, "UsedEffects");
|
||||
getWidget(mItemBox, "ItemBox");
|
||||
getWidget(mSoulBox, "SoulBox");
|
||||
getWidget(mEnchantmentPoints, "Enchantment");
|
||||
getWidget(mCastCost, "CastCost");
|
||||
getWidget(mCharge, "Charge");
|
||||
getWidget(mTypeButton, "TypeButton");
|
||||
getWidget(mBuyButton, "BuyButton");
|
||||
getWidget(mPrice, "PriceLabel");
|
||||
|
||||
setWidgets(mAvailableEffectsList, mUsedEffectsView);
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onCancelButtonClicked);
|
||||
mItemBox->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onSelectItem);
|
||||
mSoulBox->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onSelectSoul);
|
||||
mBuyButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onBuyButtonClicked);
|
||||
mTypeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onTypeButtonClicked);
|
||||
}
|
||||
|
||||
EnchantingDialog::~EnchantingDialog()
|
||||
{
|
||||
delete mItemSelectionDialog;
|
||||
}
|
||||
|
||||
void EnchantingDialog::open()
|
||||
{
|
||||
center();
|
||||
onRemoveItem(NULL);
|
||||
onRemoveSoul(NULL);
|
||||
}
|
||||
|
||||
void EnchantingDialog::updateLabels()
|
||||
{
|
||||
mEnchantmentPoints->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantCost())
|
||||
+ " / " + boost::lexical_cast<std::string>(mEnchanting.getMaxEnchantValue()));
|
||||
|
||||
mCharge->setCaption(boost::lexical_cast<std::string>(mEnchanting.getGemCharge()));
|
||||
|
||||
mCastCost->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantCost()));
|
||||
|
||||
switch(mEnchanting.getEnchantType())
|
||||
{
|
||||
case 0:
|
||||
mTypeButton->setCaption(mWindowManager.getGameSettingString("sItemCastOnce","Cast Once"));
|
||||
mAddEffectDialog.constantEffect=false;
|
||||
break;
|
||||
case 1:
|
||||
mTypeButton->setCaption(mWindowManager.getGameSettingString("sItemCastWhenStrikes", "When Strikes"));
|
||||
mAddEffectDialog.constantEffect=false;
|
||||
break;
|
||||
case 2:
|
||||
mTypeButton->setCaption(mWindowManager.getGameSettingString("sItemCastWhenUsed", "When Used"));
|
||||
mAddEffectDialog.constantEffect=false;
|
||||
break;
|
||||
case 3:
|
||||
mTypeButton->setCaption(mWindowManager.getGameSettingString("sItemCastConstant", "Cast Constant"));
|
||||
mAddEffectDialog.constantEffect=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnchantingDialog::startEnchanting (MWWorld::Ptr actor)
|
||||
@ -40,4 +102,159 @@ namespace MWGui
|
||||
{
|
||||
mWindowManager.removeGuiMode (GM_Enchanting);
|
||||
}
|
||||
|
||||
void EnchantingDialog::onSelectItem(MyGUI::Widget *sender)
|
||||
{
|
||||
delete mItemSelectionDialog;
|
||||
mItemSelectionDialog = new ItemSelectionDialog("#{sEnchantItems}",
|
||||
ContainerBase::Filter_Apparel|ContainerBase::Filter_Weapon|ContainerBase::Filter_NoMagic, mWindowManager);
|
||||
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected);
|
||||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel);
|
||||
mItemSelectionDialog->setVisible(true);
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mItemSelectionDialog->drawItems ();
|
||||
}
|
||||
|
||||
void EnchantingDialog::onItemSelected(MWWorld::Ptr item)
|
||||
{
|
||||
mItemSelectionDialog->setVisible(false);
|
||||
|
||||
while (mItemBox->getChildCount ())
|
||||
MyGUI::Gui::getInstance ().destroyWidget (mItemBox->getChildAt(0));
|
||||
|
||||
MyGUI::ImageBox* image = mItemBox->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 32, 32), MyGUI::Align::Default);
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(item).getInventoryIcon(item);
|
||||
int pos = path.rfind(".");
|
||||
path.erase(pos);
|
||||
path.append(".dds");
|
||||
image->setImageTexture (path);
|
||||
image->setUserString ("ToolTipType", "ItemPtr");
|
||||
image->setUserData(item);
|
||||
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem);
|
||||
|
||||
mEnchanting.setOldItem(item);
|
||||
mEnchanting.nextEnchantType();
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void EnchantingDialog::onRemoveItem(MyGUI::Widget *sender)
|
||||
{
|
||||
while (mItemBox->getChildCount ())
|
||||
MyGUI::Gui::getInstance ().destroyWidget (mItemBox->getChildAt(0));
|
||||
mEnchanting.setOldItem(MWWorld::Ptr());
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void EnchantingDialog::onItemCancel()
|
||||
{
|
||||
mItemSelectionDialog->setVisible(false);
|
||||
}
|
||||
|
||||
void EnchantingDialog::onSoulSelected(MWWorld::Ptr item)
|
||||
{
|
||||
mItemSelectionDialog->setVisible(false);
|
||||
mEnchanting.setSoulGem(item);
|
||||
|
||||
if(mEnchanting.getGemCharge()==0)
|
||||
{
|
||||
mWindowManager.messageBox ("#{sNotifyMessage32}", std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
while (mSoulBox->getChildCount ())
|
||||
MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0));
|
||||
|
||||
MyGUI::ImageBox* image = mSoulBox->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 32, 32), MyGUI::Align::Default);
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(item).getInventoryIcon(item);
|
||||
int pos = path.rfind(".");
|
||||
path.erase(pos);
|
||||
path.append(".dds");
|
||||
image->setImageTexture (path);
|
||||
image->setUserString ("ToolTipType", "ItemPtr");
|
||||
image->setUserData(item);
|
||||
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveSoul);
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void EnchantingDialog::onRemoveSoul(MyGUI::Widget *sender)
|
||||
{
|
||||
while (mSoulBox->getChildCount ())
|
||||
MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0));
|
||||
mEnchanting.setSoulGem(MWWorld::Ptr());
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void EnchantingDialog::onSoulCancel()
|
||||
{
|
||||
mItemSelectionDialog->setVisible(false);
|
||||
}
|
||||
|
||||
void EnchantingDialog::onSelectSoul(MyGUI::Widget *sender)
|
||||
{
|
||||
delete mItemSelectionDialog;
|
||||
mItemSelectionDialog = new ItemSelectionDialog("#{sSoulGemsWithSouls}",
|
||||
ContainerBase::Filter_Misc|ContainerBase::Filter_ChargedSoulstones, mWindowManager);
|
||||
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected);
|
||||
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel);
|
||||
mItemSelectionDialog->setVisible(true);
|
||||
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||
mItemSelectionDialog->drawItems ();
|
||||
|
||||
//mWindowManager.messageBox("#{sInventorySelectNoSoul}");
|
||||
}
|
||||
|
||||
void EnchantingDialog::notifyEffectsChanged ()
|
||||
{
|
||||
mEffectList.mList = mEffects;
|
||||
mEnchanting.setEffect(mEffectList);
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void EnchantingDialog::onTypeButtonClicked(MyGUI::Widget* sender)
|
||||
{
|
||||
mEnchanting.nextEnchantType();
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
void EnchantingDialog::onBuyButtonClicked(MyGUI::Widget* sender)
|
||||
{
|
||||
if (mEffects.size() <= 0)
|
||||
{
|
||||
mWindowManager.messageBox ("#{sNotifyMessage30}", std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
if (mName->getCaption ().empty())
|
||||
{
|
||||
mWindowManager.messageBox ("#{sNotifyMessage10}", std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
if (boost::lexical_cast<int>(mPrice->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold())
|
||||
{
|
||||
mWindowManager.messageBox ("#{sNotifyMessage18}", std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEnchanting.soulEmpty())
|
||||
{
|
||||
mWindowManager.messageBox ("#{sNotifyMessage52}", std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEnchanting.itemEmpty())
|
||||
{
|
||||
mWindowManager.messageBox ("#{sNotifyMessage11}", std::vector<std::string>());
|
||||
return;
|
||||
}
|
||||
|
||||
mEnchanting.setNewItemName(mName->getCaption());
|
||||
mEnchanting.setEffect(mEffectList);
|
||||
|
||||
mEnchanting.create();
|
||||
mWindowManager.messageBox ("#{sEnchantmentMenu12}", std::vector<std::string>());
|
||||
mWindowManager.removeGuiMode (GM_Enchanting);
|
||||
}
|
||||
}
|
||||
|
@ -7,23 +7,57 @@
|
||||
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwmechanics/enchanting.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class ItemSelectionDialog;
|
||||
|
||||
class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase
|
||||
{
|
||||
public:
|
||||
EnchantingDialog(MWBase::WindowManager& parWindowManager);
|
||||
virtual ~EnchantingDialog();
|
||||
|
||||
virtual void open();
|
||||
void startEnchanting(MWWorld::Ptr actor);
|
||||
|
||||
protected:
|
||||
virtual void onReferenceUnavailable();
|
||||
virtual void notifyEffectsChanged ();
|
||||
|
||||
void onCancelButtonClicked(MyGUI::Widget* sender);
|
||||
void onSelectItem (MyGUI::Widget* sender);
|
||||
void onSelectSoul (MyGUI::Widget* sender);
|
||||
void onRemoveItem (MyGUI::Widget* sender);
|
||||
void onRemoveSoul (MyGUI::Widget* sender);
|
||||
|
||||
void onItemSelected(MWWorld::Ptr item);
|
||||
void onItemCancel();
|
||||
void onSoulSelected(MWWorld::Ptr item);
|
||||
void onSoulCancel();
|
||||
void onBuyButtonClicked(MyGUI::Widget* sender);
|
||||
void updateLabels();
|
||||
void onTypeButtonClicked(MyGUI::Widget* sender);
|
||||
|
||||
ItemSelectionDialog* mItemSelectionDialog;
|
||||
|
||||
MyGUI::Button* mCancelButton;
|
||||
MyGUI::ImageBox* mItemBox;
|
||||
MyGUI::ImageBox* mSoulBox;
|
||||
|
||||
MyGUI::Button* mTypeButton;
|
||||
MyGUI::Button* mBuyButton;
|
||||
|
||||
MyGUI::TextBox* mName;
|
||||
MyGUI::TextBox* mEnchantmentPoints;
|
||||
MyGUI::TextBox* mCastCost;
|
||||
MyGUI::TextBox* mCharge;
|
||||
MyGUI::TextBox* mPrice;
|
||||
|
||||
MWMechanics::Enchanting mEnchanting;
|
||||
ESM::EffectList mEffectList;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ namespace MWGui
|
||||
&& (type != typeid(ESM::Ingredient).name())
|
||||
&& (type != typeid(ESM::Light).name())
|
||||
&& (type != typeid(ESM::Miscellaneous).name())
|
||||
&& (type != typeid(ESM::Tool).name())
|
||||
&& (type != typeid(ESM::Lockpick).name())
|
||||
&& (type != typeid(ESM::Probe).name())
|
||||
&& (type != typeid(ESM::Repair).name())
|
||||
&& (type != typeid(ESM::Weapon).name())
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
ItemSelectionDialog::ItemSelectionDialog(const std::string &label, ContainerBase::Filter filter, MWBase::WindowManager& parWindowManager)
|
||||
ItemSelectionDialog::ItemSelectionDialog(const std::string &label, int filter, MWBase::WindowManager& parWindowManager)
|
||||
: ContainerBase(NULL)
|
||||
, WindowModal("openmw_itemselection_dialog.layout", parWindowManager)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@ namespace MWGui
|
||||
class ItemSelectionDialog : public ContainerBase, public WindowModal
|
||||
{
|
||||
public:
|
||||
ItemSelectionDialog(const std::string& label, ContainerBase::Filter filter, MWBase::WindowManager& parWindowManager);
|
||||
ItemSelectionDialog(const std::string& label, int filter, MWBase::WindowManager& parWindowManager);
|
||||
|
||||
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
|
||||
typedef MyGUI::delegates::CMultiDelegate1<MWWorld::Ptr> EventHandle_Item;
|
||||
|
132
apps/openmw/mwgui/merchantrepair.cpp
Normal file
132
apps/openmw/mwgui/merchantrepair.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
#include "merchantrepair.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "list.hpp"
|
||||
#include "inventorywindow.hpp"
|
||||
#include "tradewindow.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
MerchantRepair::MerchantRepair(MWBase::WindowManager &parWindowManager)
|
||||
: WindowBase("openmw_merchantrepair.layout", parWindowManager)
|
||||
{
|
||||
getWidget(mList, "RepairView");
|
||||
getWidget(mOkButton, "OkButton");
|
||||
getWidget(mGoldLabel, "PlayerGold");
|
||||
|
||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onOkButtonClick);
|
||||
}
|
||||
|
||||
void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
|
||||
{
|
||||
mActor = actor;
|
||||
|
||||
while (mList->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(mList->getChildAt(0));
|
||||
|
||||
int currentY = 0;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||
for (MWWorld::ContainerStoreIterator iter (store.begin());
|
||||
iter!=store.end(); ++iter)
|
||||
{
|
||||
if (MWWorld::Class::get(*iter).hasItemHealth(*iter))
|
||||
{
|
||||
int maxDurability = MWWorld::Class::get(*iter).getItemMaxHealth(*iter);
|
||||
int durability = (iter->getCellRef().mCharge == -1) ? maxDurability : iter->getCellRef().mCharge;
|
||||
if (maxDurability == durability)
|
||||
continue;
|
||||
|
||||
int basePrice = MWWorld::Class::get(*iter).getValue(*iter);
|
||||
float fRepairMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||
.find("fRepairMult")->getFloat();
|
||||
|
||||
float p = std::max(1, basePrice);
|
||||
float r = std::max(1, static_cast<int>(maxDurability / p));
|
||||
|
||||
int x = ((maxDurability - durability) / r);
|
||||
x = (fRepairMult * x);
|
||||
|
||||
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mActor, x, true);
|
||||
|
||||
|
||||
std::string name = MWWorld::Class::get(*iter).getName(*iter)
|
||||
+ " - " + boost::lexical_cast<std::string>(price)
|
||||
+ MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||
.find("sgp")->getString();;
|
||||
|
||||
|
||||
MyGUI::Button* button =
|
||||
mList->createWidget<MyGUI::Button>(
|
||||
(price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton",
|
||||
0,
|
||||
currentY,
|
||||
0,
|
||||
18,
|
||||
MyGUI::Align::Default
|
||||
);
|
||||
|
||||
currentY += 18;
|
||||
|
||||
button->setEnabled(price<=mWindowManager.getInventoryWindow()->getPlayerGold());
|
||||
button->setUserString("Price", boost::lexical_cast<std::string>(price));
|
||||
button->setUserData(*iter);
|
||||
button->setCaptionWithReplacing(name);
|
||||
button->setSize(button->getTextSize().width,18);
|
||||
button->eventMouseWheel += MyGUI::newDelegate(this, &MerchantRepair::onMouseWheel);
|
||||
button->setUserString("ToolTipType", "ItemPtr");
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onRepairButtonClick);
|
||||
}
|
||||
}
|
||||
mList->setCanvasSize (MyGUI::IntSize(mList->getWidth(), std::max(mList->getHeight(), currentY)));
|
||||
|
||||
mGoldLabel->setCaptionWithReplacing("#{sGold}: "
|
||||
+ boost::lexical_cast<std::string>(mWindowManager.getInventoryWindow()->getPlayerGold()));
|
||||
}
|
||||
|
||||
void MerchantRepair::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
if (mList->getViewOffset().top + _rel*0.3 > 0)
|
||||
mList->setViewOffset(MyGUI::IntPoint(0, 0));
|
||||
else
|
||||
mList->setViewOffset(MyGUI::IntPoint(0, mList->getViewOffset().top + _rel*0.3));
|
||||
}
|
||||
|
||||
void MerchantRepair::open()
|
||||
{
|
||||
center();
|
||||
}
|
||||
|
||||
void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
|
||||
{
|
||||
// repair
|
||||
MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>();
|
||||
item.getCellRef().mCharge = MWWorld::Class::get(item).getItemMaxHealth(item);
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1);
|
||||
|
||||
int price = boost::lexical_cast<int>(sender->getUserString("Price"));
|
||||
mWindowManager.getTradeWindow()->addOrRemoveGold(-price);
|
||||
|
||||
startRepair(mActor);
|
||||
}
|
||||
|
||||
void MerchantRepair::onOkButtonClick(MyGUI::Widget *sender)
|
||||
{
|
||||
mWindowManager.removeGuiMode(GM_MerchantRepair);
|
||||
}
|
||||
|
||||
}
|
37
apps/openmw/mwgui/merchantrepair.hpp
Normal file
37
apps/openmw/mwgui/merchantrepair.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef OPENMW_MWGUI_MERCHANTREPAIR_H
|
||||
#define OPENMW_MWGUI_MERCHANTREPAIR_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class MerchantRepair : public WindowBase
|
||||
{
|
||||
public:
|
||||
MerchantRepair(MWBase::WindowManager &parWindowManager);
|
||||
|
||||
virtual void open();
|
||||
|
||||
void startRepair(const MWWorld::Ptr& actor);
|
||||
|
||||
private:
|
||||
MyGUI::ScrollView* mList;
|
||||
MyGUI::Button* mOkButton;
|
||||
MyGUI::TextBox* mGoldLabel;
|
||||
|
||||
MWWorld::Ptr mActor;
|
||||
|
||||
protected:
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
void onRepairButtonClick(MyGUI::Widget* sender);
|
||||
void onOkButtonClick(MyGUI::Widget* sender);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -16,6 +16,7 @@ namespace MWGui
|
||||
GM_Scroll, // Read scroll
|
||||
GM_Book, // Read book
|
||||
GM_Alchemy, // Make potions
|
||||
GM_Repair,
|
||||
|
||||
GM_Dialogue, // NPC interaction
|
||||
GM_Barter,
|
||||
@ -26,6 +27,7 @@ namespace MWGui
|
||||
GM_SpellCreation,
|
||||
GM_Enchanting,
|
||||
GM_Training,
|
||||
GM_MerchantRepair,
|
||||
|
||||
GM_Levelup,
|
||||
|
||||
|
157
apps/openmw/mwgui/repair.cpp
Normal file
157
apps/openmw/mwgui/repair.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
#include "repair.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "widgets.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
Repair::Repair(MWBase::WindowManager &parWindowManager)
|
||||
: WindowBase("openmw_repair.layout", parWindowManager)
|
||||
{
|
||||
getWidget(mRepairBox, "RepairBox");
|
||||
getWidget(mRepairView, "RepairView");
|
||||
getWidget(mToolBox, "ToolBox");
|
||||
getWidget(mToolIcon, "ToolIcon");
|
||||
getWidget(mUsesLabel, "UsesLabel");
|
||||
getWidget(mQualityLabel, "QualityLabel");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onCancel);
|
||||
}
|
||||
|
||||
void Repair::open()
|
||||
{
|
||||
center();
|
||||
}
|
||||
|
||||
void Repair::startRepairItem(const MWWorld::Ptr &item)
|
||||
{
|
||||
mRepair.setTool(item);
|
||||
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(item).getInventoryIcon(item);
|
||||
int pos = path.rfind(".");
|
||||
path.erase(pos);
|
||||
path.append(".dds");
|
||||
mToolIcon->setImageTexture (path);
|
||||
mToolIcon->setUserString("ToolTipType", "ItemPtr");
|
||||
mToolIcon->setUserData(item);
|
||||
|
||||
updateRepairView();
|
||||
}
|
||||
|
||||
void Repair::updateRepairView()
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Repair> *ref =
|
||||
mRepair.getTool().get<ESM::Repair>();
|
||||
|
||||
int uses = (mRepair.getTool().getCellRef().mCharge != -1) ? mRepair.getTool().getCellRef().mCharge : ref->mBase->mData.mUses;
|
||||
|
||||
float quality = ref->mBase->mData.mQuality;
|
||||
|
||||
std::stringstream qualityStr;
|
||||
qualityStr << std::setprecision(3) << quality;
|
||||
|
||||
mUsesLabel->setCaptionWithReplacing("#{sUses} " + boost::lexical_cast<std::string>(uses));
|
||||
mQualityLabel->setCaptionWithReplacing("#{sQuality} " + qualityStr.str());
|
||||
|
||||
bool toolBoxVisible = (mRepair.getTool().getRefData().getCount() != 0);
|
||||
mToolBox->setVisible(toolBoxVisible);
|
||||
|
||||
bool toolBoxWasVisible = (mRepairBox->getPosition().top != mToolBox->getPosition().top);
|
||||
|
||||
if (toolBoxVisible && !toolBoxWasVisible)
|
||||
{
|
||||
// shrink
|
||||
mRepairBox->setPosition(mRepairBox->getPosition() + MyGUI::IntPoint(0,mToolBox->getSize().height));
|
||||
mRepairBox->setSize(mRepairBox->getSize() - MyGUI::IntSize(0,mToolBox->getSize().height));
|
||||
}
|
||||
else if (!toolBoxVisible && toolBoxWasVisible)
|
||||
{
|
||||
// expand
|
||||
mRepairBox->setPosition(MyGUI::IntPoint (mRepairBox->getPosition().left, mToolBox->getPosition().top));
|
||||
mRepairBox->setSize(mRepairBox->getSize() + MyGUI::IntSize(0,mToolBox->getSize().height));
|
||||
}
|
||||
|
||||
while (mRepairView->getChildCount())
|
||||
MyGUI::Gui::getInstance().destroyWidget(mRepairView->getChildAt(0));
|
||||
|
||||
int currentY = 0;
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||
int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor;
|
||||
for (MWWorld::ContainerStoreIterator iter (store.begin(categories));
|
||||
iter!=store.end(); ++iter)
|
||||
{
|
||||
if (MWWorld::Class::get(*iter).hasItemHealth(*iter))
|
||||
{
|
||||
int maxDurability = MWWorld::Class::get(*iter).getItemMaxHealth(*iter);
|
||||
int durability = (iter->getCellRef().mCharge == -1) ? maxDurability : iter->getCellRef().mCharge;
|
||||
if (maxDurability == durability)
|
||||
continue;
|
||||
|
||||
MyGUI::TextBox* text = mRepairView->createWidget<MyGUI::TextBox> (
|
||||
"SandText", MyGUI::IntCoord(8, currentY, mRepairView->getWidth()-8, 18), MyGUI::Align::Default);
|
||||
text->setCaption(MWWorld::Class::get(*iter).getName(*iter));
|
||||
text->setNeedMouseFocus(false);
|
||||
currentY += 19;
|
||||
|
||||
MyGUI::ImageBox* icon = mRepairView->createWidget<MyGUI::ImageBox> (
|
||||
"ImageBox", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default);
|
||||
std::string path = std::string("icons\\");
|
||||
path += MWWorld::Class::get(*iter).getInventoryIcon(*iter);
|
||||
int pos = path.rfind(".");
|
||||
path.erase(pos);
|
||||
path.append(".dds");
|
||||
icon->setImageTexture (path);
|
||||
icon->setUserString("ToolTipType", "ItemPtr");
|
||||
icon->setUserData(*iter);
|
||||
icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onRepairItem);
|
||||
icon->eventMouseWheel += MyGUI::newDelegate(this, &Repair::onMouseWheel);
|
||||
|
||||
Widgets::MWDynamicStatPtr chargeWidget = mRepairView->createWidget<Widgets::MWDynamicStat>
|
||||
("MW_ChargeBar", MyGUI::IntCoord(72, currentY+2, 199, 20), MyGUI::Align::Default);
|
||||
chargeWidget->setValue(durability, maxDurability);
|
||||
chargeWidget->setNeedMouseFocus(false);
|
||||
|
||||
currentY += 32 + 4;
|
||||
}
|
||||
}
|
||||
mRepairView->setCanvasSize (MyGUI::IntSize(mRepairView->getWidth(), std::max(mRepairView->getHeight(), currentY)));
|
||||
}
|
||||
|
||||
void Repair::onCancel(MyGUI::Widget *sender)
|
||||
{
|
||||
mWindowManager.removeGuiMode(GM_Repair);
|
||||
}
|
||||
|
||||
void Repair::onRepairItem(MyGUI::Widget *sender)
|
||||
{
|
||||
if (!mRepair.getTool().getRefData().getCount())
|
||||
return;
|
||||
|
||||
mRepair.repair(*sender->getUserData<MWWorld::Ptr>());
|
||||
|
||||
updateRepairView();
|
||||
}
|
||||
|
||||
void Repair::onMouseWheel(MyGUI::Widget* _sender, int _rel)
|
||||
{
|
||||
if (mRepairView->getViewOffset().top + _rel*0.3 > 0)
|
||||
mRepairView->setViewOffset(MyGUI::IntPoint(0, 0));
|
||||
else
|
||||
mRepairView->setViewOffset(MyGUI::IntPoint(0, mRepairView->getViewOffset().top + _rel*0.3));
|
||||
}
|
||||
|
||||
}
|
46
apps/openmw/mwgui/repair.hpp
Normal file
46
apps/openmw/mwgui/repair.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef OPENMW_MWGUI_REPAIR_H
|
||||
#define OPENMW_MWGUI_REPAIR_H
|
||||
|
||||
#include "window_base.hpp"
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwmechanics/repair.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
class Repair : public WindowBase
|
||||
{
|
||||
public:
|
||||
Repair(MWBase::WindowManager &parWindowManager);
|
||||
|
||||
virtual void open();
|
||||
|
||||
void startRepairItem (const MWWorld::Ptr& item);
|
||||
|
||||
protected:
|
||||
MyGUI::Widget* mRepairBox;
|
||||
MyGUI::ScrollView* mRepairView;
|
||||
|
||||
MyGUI::Widget* mToolBox;
|
||||
|
||||
MyGUI::ImageBox* mToolIcon;
|
||||
|
||||
MyGUI::TextBox* mUsesLabel;
|
||||
MyGUI::TextBox* mQualityLabel;
|
||||
|
||||
MyGUI::Button* mCancelButton;
|
||||
|
||||
MWMechanics::Repair mRepair;
|
||||
|
||||
void updateRepairView();
|
||||
|
||||
void onRepairItem (MyGUI::Widget* sender);
|
||||
void onCancel (MyGUI::Widget* sender);
|
||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -32,20 +32,9 @@ namespace MWGui
|
||||
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
getWidget(mPlayerGold, "PlayerGold");
|
||||
getWidget(mSelect, "Select");
|
||||
getWidget(mSpells, "Spells");
|
||||
getWidget(mSpellsView, "SpellsView");
|
||||
|
||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onCancelButtonClicked);
|
||||
|
||||
mSpells->setCoord(450/2-mSpells->getTextSize().width/2,
|
||||
mSpells->getTop(),
|
||||
mSpells->getTextSize().width,
|
||||
mSpells->getHeight());
|
||||
mSelect->setCoord(8,
|
||||
mSelect->getTop(),
|
||||
mSelect->getTextSize().width,
|
||||
mSelect->getHeight());
|
||||
}
|
||||
|
||||
void SpellBuyingWindow::addSpell(const std::string& spellId)
|
||||
|
@ -28,8 +28,6 @@ namespace MWGui
|
||||
protected:
|
||||
MyGUI::Button* mCancelButton;
|
||||
MyGUI::TextBox* mPlayerGold;
|
||||
MyGUI::TextBox* mSpells;
|
||||
MyGUI::TextBox* mSelect;
|
||||
|
||||
MyGUI::ScrollView* mSpellsView;
|
||||
|
||||
|
@ -72,6 +72,7 @@ namespace MWGui
|
||||
mMagnitudeMaxSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMaxChanged);
|
||||
mDurationSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onDurationChanged);
|
||||
mAreaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onAreaChanged);
|
||||
constantEffect=false;
|
||||
}
|
||||
|
||||
void EditEffectDialog::open()
|
||||
@ -164,7 +165,7 @@ namespace MWGui
|
||||
mMagnitudeBox->setVisible (true);
|
||||
curY += mMagnitudeBox->getSize().height;
|
||||
}
|
||||
if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoDuration))
|
||||
if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)&&constantEffect==false)
|
||||
{
|
||||
mDurationBox->setPosition(mDurationBox->getPosition().left, curY);
|
||||
mDurationBox->setVisible (true);
|
||||
|
@ -24,7 +24,7 @@ namespace MWGui
|
||||
|
||||
void newEffect (const ESM::MagicEffect* effect);
|
||||
void editEffect (ESM::ENAMstruct effect);
|
||||
|
||||
bool constantEffect;
|
||||
typedef MyGUI::delegates::CMultiDelegate1<ESM::ENAMstruct> EventHandle_Effect;
|
||||
|
||||
EventHandle_Effect eventEffectAdded;
|
||||
@ -69,7 +69,6 @@ namespace MWGui
|
||||
void onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos);
|
||||
void onDurationChanged (MyGUI::ScrollBar* sender, size_t pos);
|
||||
void onAreaChanged (MyGUI::ScrollBar* sender, size_t pos);
|
||||
|
||||
void setMagicEffect(const ESM::MagicEffect* effect);
|
||||
|
||||
void updateBoxes();
|
||||
|
@ -139,12 +139,13 @@ namespace MWGui
|
||||
}
|
||||
}
|
||||
|
||||
parent->setVisible(effects.size() != 0);
|
||||
|
||||
int w=2;
|
||||
|
||||
if (adjustSize)
|
||||
{
|
||||
int s = effects.size() * 16+4;
|
||||
if (!effects.size())
|
||||
s = 0;
|
||||
int diff = parent->getWidth() - s;
|
||||
parent->setSize(s, parent->getHeight());
|
||||
parent->setPosition(parent->getLeft()+diff, parent->getTop());
|
||||
|
@ -368,7 +368,7 @@ namespace MWGui
|
||||
return services & ESM::NPC::Books;
|
||||
else if (item.getTypeName() == typeid(ESM::Ingredient).name())
|
||||
return services & ESM::NPC::Ingredients;
|
||||
else if (item.getTypeName() == typeid(ESM::Tool).name())
|
||||
else if (item.getTypeName() == typeid(ESM::Lockpick).name())
|
||||
return services & ESM::NPC::Picks;
|
||||
else if (item.getTypeName() == typeid(ESM::Probe).name())
|
||||
return services & ESM::NPC::Probes;
|
||||
|
@ -132,7 +132,7 @@ namespace MWGui
|
||||
case 11:
|
||||
month = "#{sMonthEveningstar}";
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
int hour = MWBase::Environment::get().getWorld ()->getTimeStamp ().getHour ();
|
||||
@ -142,7 +142,7 @@ namespace MWGui
|
||||
|
||||
std::string dateTimeText =
|
||||
boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getDay ()) + " "
|
||||
+ month + " (#{sDay} " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getTimeStamp ().getDay ()+1)
|
||||
+ month + " (#{sDay} " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getTimeStamp ().getDay())
|
||||
+ ") " + boost::lexical_cast<std::string>(hour) + " " + (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}");
|
||||
|
||||
mDateTimeText->setCaptionWithReplacing (dateTimeText);
|
||||
@ -156,13 +156,13 @@ namespace MWGui
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWMechanics::CreatureStats stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
|
||||
float hourlyHealthDelta = stats.getAttribute(ESM::Attribute::Endurance).getModified() * 0.1;
|
||||
|
||||
|
||||
bool stunted = (stats.getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::StuntedMagicka)).mMagnitude > 0);
|
||||
float fRestMagicMult = store.get<ESM::GameSetting>().find("fRestMagicMult")->getFloat();
|
||||
float hourlyMagickaDelta = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified();
|
||||
|
||||
|
||||
// this massive duplication is why it has to be put into helper functions instead
|
||||
float fFatigueReturnBase = store.get<ESM::GameSetting>().find("fFatigueReturnBase")->getFloat();
|
||||
float fFatigueReturnMult = store.get<ESM::GameSetting>().find("fFatigueReturnMult")->getFloat();
|
||||
@ -174,7 +174,7 @@ namespace MWGui
|
||||
normalizedEncumbrance = 1;
|
||||
float hourlyFatigueDelta = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
|
||||
hourlyFatigueDelta *= 3600 * fEndFatigueMult * stats.getAttribute(ESM::Attribute::Endurance).getModified();
|
||||
|
||||
|
||||
float healthHours = hourlyHealthDelta >= 0.0
|
||||
? (stats.getHealth().getBase() - stats.getHealth().getCurrent()) / hourlyHealthDelta
|
||||
: 1.0f;
|
||||
@ -185,9 +185,9 @@ namespace MWGui
|
||||
float fatigueHours = hourlyFatigueDelta >= 0.0
|
||||
? (stats.getFatigue().getBase() - stats.getFatigue().getCurrent()) / hourlyFatigueDelta
|
||||
: 1.0f;
|
||||
|
||||
|
||||
int autoHours = int(std::ceil( std::max(std::max(healthHours, magickaHours), std::max(fatigueHours, 1.0f)) )); // this should use a variadic max if possible
|
||||
|
||||
|
||||
startWaiting(autoHours);
|
||||
}
|
||||
|
||||
@ -201,11 +201,11 @@ namespace MWGui
|
||||
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.2);
|
||||
setVisible(false);
|
||||
mProgressBar.setVisible (true);
|
||||
|
||||
|
||||
mWaiting = true;
|
||||
mCurHour = 0;
|
||||
mHours = hoursToWait;
|
||||
|
||||
|
||||
mRemainingTime = 0.05;
|
||||
mProgressBar.setProgress (0, mHours);
|
||||
}
|
||||
|
@ -55,6 +55,8 @@
|
||||
#include "exposedwindow.hpp"
|
||||
#include "cursor.hpp"
|
||||
#include "spellicons.hpp"
|
||||
#include "merchantrepair.hpp"
|
||||
#include "repair.hpp"
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
@ -90,6 +92,8 @@ WindowManager::WindowManager(
|
||||
, mSpellCreationDialog(NULL)
|
||||
, mEnchantingDialog(NULL)
|
||||
, mTrainingWindow(NULL)
|
||||
, mMerchantRepair(NULL)
|
||||
, mRepair(NULL)
|
||||
, mPlayerName()
|
||||
, mPlayerRaceId()
|
||||
, mPlayerAttributes()
|
||||
@ -180,6 +184,8 @@ WindowManager::WindowManager(
|
||||
mSpellCreationDialog = new SpellCreationDialog(*this);
|
||||
mEnchantingDialog = new EnchantingDialog(*this);
|
||||
mTrainingWindow = new TrainingWindow(*this);
|
||||
mMerchantRepair = new MerchantRepair(*this);
|
||||
mRepair = new Repair(*this);
|
||||
|
||||
mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this);
|
||||
mLoadingScreen->onResChange (w,h);
|
||||
@ -245,6 +251,8 @@ WindowManager::~WindowManager()
|
||||
delete mTrainingWindow;
|
||||
delete mCountDialog;
|
||||
delete mQuickKeysMenu;
|
||||
delete mMerchantRepair;
|
||||
delete mRepair;
|
||||
delete mCursor;
|
||||
|
||||
cleanupGarbage();
|
||||
@ -303,6 +311,8 @@ void WindowManager::updateVisible()
|
||||
mSpellCreationDialog->setVisible(false);
|
||||
mEnchantingDialog->setVisible(false);
|
||||
mTrainingWindow->setVisible(false);
|
||||
mMerchantRepair->setVisible(false);
|
||||
mRepair->setVisible(false);
|
||||
|
||||
mHud->setVisible(mHudEnabled);
|
||||
|
||||
@ -428,6 +438,12 @@ void WindowManager::updateVisible()
|
||||
case GM_Training:
|
||||
mTrainingWindow->setVisible(true);
|
||||
break;
|
||||
case GM_MerchantRepair:
|
||||
mMerchantRepair->setVisible(true);
|
||||
break;
|
||||
case GM_Repair:
|
||||
mRepair->setVisible(true);
|
||||
break;
|
||||
case GM_InterMessageBox:
|
||||
break;
|
||||
case GM_Journal:
|
||||
@ -1132,6 +1148,16 @@ void WindowManager::startTraining(MWWorld::Ptr actor)
|
||||
mTrainingWindow->startTraining(actor);
|
||||
}
|
||||
|
||||
void WindowManager::startRepair(MWWorld::Ptr actor)
|
||||
{
|
||||
mMerchantRepair->startRepair(actor);
|
||||
}
|
||||
|
||||
void WindowManager::startRepairItem(MWWorld::Ptr item)
|
||||
{
|
||||
mRepair->startRepairItem(item);
|
||||
}
|
||||
|
||||
const Translation::Storage& WindowManager::getTranslationDataStorage() const
|
||||
{
|
||||
return mTranslationDataStorage;
|
||||
|
@ -74,6 +74,8 @@ namespace MWGui
|
||||
class TrainingWindow;
|
||||
class Cursor;
|
||||
class SpellIcons;
|
||||
class MerchantRepair;
|
||||
class Repair;
|
||||
|
||||
class WindowManager : public MWBase::WindowManager
|
||||
{
|
||||
@ -229,6 +231,8 @@ namespace MWGui
|
||||
virtual void startSpellMaking(MWWorld::Ptr actor);
|
||||
virtual void startEnchanting(MWWorld::Ptr actor);
|
||||
virtual void startTraining(MWWorld::Ptr actor);
|
||||
virtual void startRepair(MWWorld::Ptr actor);
|
||||
virtual void startRepairItem(MWWorld::Ptr item);
|
||||
|
||||
virtual void changePointer (const std::string& name);
|
||||
|
||||
@ -266,6 +270,9 @@ namespace MWGui
|
||||
SpellCreationDialog* mSpellCreationDialog;
|
||||
EnchantingDialog* mEnchantingDialog;
|
||||
TrainingWindow* mTrainingWindow;
|
||||
MerchantRepair* mMerchantRepair;
|
||||
Repair* mRepair;
|
||||
|
||||
Translation::Storage& mTranslationDataStorage;
|
||||
Cursor* mCursor;
|
||||
|
||||
|
167
apps/openmw/mwmechanics/enchanting.cpp
Normal file
167
apps/openmw/mwmechanics/enchanting.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
#include "enchanting.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
namespace MWMechanics
|
||||
{
|
||||
Enchanting::Enchanting(MWWorld::Ptr enchanter):
|
||||
mEnchanter(enchanter),
|
||||
mEnchantType(0)
|
||||
{}
|
||||
|
||||
void Enchanting::setOldItem(MWWorld::Ptr oldItem)
|
||||
{
|
||||
mOldItemPtr=oldItem;
|
||||
if(!itemEmpty())
|
||||
{
|
||||
mObjectType = mOldItemPtr.getTypeName();
|
||||
mOldItemId = mOldItemPtr.getCellRef().mRefID;
|
||||
}
|
||||
else
|
||||
{
|
||||
mObjectType="";
|
||||
mOldItemId="";
|
||||
}
|
||||
}
|
||||
|
||||
void Enchanting::setNewItemName(std::string s)
|
||||
{
|
||||
mNewItemName=s;
|
||||
}
|
||||
|
||||
void Enchanting::setEffect(ESM::EffectList effectList)
|
||||
{
|
||||
mEffectList=effectList;
|
||||
}
|
||||
|
||||
int Enchanting::getEnchantType()
|
||||
{
|
||||
return mEnchantType;
|
||||
}
|
||||
|
||||
void Enchanting::setSoulGem(MWWorld::Ptr soulGem)
|
||||
{
|
||||
mSoulGemPtr=soulGem;
|
||||
}
|
||||
|
||||
void Enchanting::create()
|
||||
{
|
||||
mOldItemPtr.getRefData().setCount(mOldItemPtr.getRefData().getCount()-1);
|
||||
mSoulGemPtr.getRefData().setCount(mSoulGemPtr.getRefData().getCount()-1);
|
||||
|
||||
mEnchantment.mData.mCharge = getGemCharge();
|
||||
if(mEnchantType==3)
|
||||
{
|
||||
mEnchantment.mData.mCharge=0;
|
||||
}
|
||||
mEnchantment.mData.mType = mEnchantType;
|
||||
mEnchantment.mData.mCost = getEnchantCost();
|
||||
mEnchantment.mEffects = mEffectList;
|
||||
const ESM::Enchantment *enchantment = MWBase::Environment::get().getWorld()->createRecord (mEnchantment);
|
||||
|
||||
std::string newobjId = MWWorld::Class::get(mOldItemPtr).applyEnchantment(mOldItemPtr, enchantment->mId, getGemCharge(), mNewItemName);
|
||||
|
||||
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), newobjId);
|
||||
MWWorld::Ptr newobjPtr = ref.getPtr();
|
||||
MWWorld::Ptr result = mOldItemPtr;
|
||||
result.mPtr = newobjPtr.mPtr;
|
||||
MWWorld::Class::get (mEnchanter).getContainerStore (mEnchanter).add (result);
|
||||
}
|
||||
|
||||
void Enchanting::nextEnchantType()
|
||||
{
|
||||
mEnchantType++;
|
||||
if (itemEmpty())
|
||||
{
|
||||
mEnchantType = 0;
|
||||
return;
|
||||
}
|
||||
if ((mObjectType == typeid(ESM::Armor).name())||(mObjectType == typeid(ESM::Clothing).name()))
|
||||
{
|
||||
switch(mEnchantType)
|
||||
{
|
||||
case 1:
|
||||
mEnchantType = 2;
|
||||
case 3:
|
||||
if(getGemCharge()<400)
|
||||
mEnchantType=2;
|
||||
case 4:
|
||||
mEnchantType = 2;
|
||||
}
|
||||
}
|
||||
else if(mObjectType == typeid(ESM::Weapon).name())
|
||||
{
|
||||
switch(mEnchantType)
|
||||
{
|
||||
case 3:
|
||||
mEnchantType = 1;
|
||||
}
|
||||
}
|
||||
else if(mObjectType == typeid(ESM::Book).name())
|
||||
{
|
||||
mEnchantType=0;
|
||||
}
|
||||
}
|
||||
|
||||
int Enchanting::getEnchantCost()
|
||||
{
|
||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||
float cost = 0;
|
||||
std::vector<ESM::ENAMstruct> mEffects = mEffectList.mList;
|
||||
int i=mEffects.size();
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
|
||||
{
|
||||
const ESM::MagicEffect* effect = store.get<ESM::MagicEffect>().find(it->mEffectID);
|
||||
|
||||
float cost1 = ((it->mMagnMin + it->mMagnMax)*it->mDuration*effect->mData.mBaseCost*0.025);
|
||||
|
||||
float cost2 = (std::max(1, it->mArea)*0.125*effect->mData.mBaseCost);
|
||||
|
||||
if(mEnchantType==3)
|
||||
{
|
||||
cost1 *= 100;
|
||||
cost2 *= 2;
|
||||
}
|
||||
if(effect->mData.mFlags & ESM::MagicEffect::CastTarget)
|
||||
cost1 *= 1.5;
|
||||
|
||||
float fullcost = cost1+cost2;
|
||||
fullcost*= i;
|
||||
i--;
|
||||
|
||||
cost+=fullcost;
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
int Enchanting::getGemCharge()
|
||||
{
|
||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||
if(soulEmpty())
|
||||
return 0;
|
||||
if(mSoulGemPtr.getCellRef().mSoul=="")
|
||||
return 0;
|
||||
const ESM::Creature* soul = store.get<ESM::Creature>().find(mSoulGemPtr.getCellRef().mSoul);
|
||||
return soul->mData.mSoul;
|
||||
}
|
||||
|
||||
int Enchanting::getMaxEnchantValue()
|
||||
{
|
||||
if (itemEmpty())
|
||||
return 0;
|
||||
return MWWorld::Class::get(mOldItemPtr).getEnchantmentPoints(mOldItemPtr);
|
||||
}
|
||||
bool Enchanting::soulEmpty()
|
||||
{
|
||||
if (mSoulGemPtr.isEmpty())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Enchanting::itemEmpty()
|
||||
{
|
||||
if(mOldItemPtr.isEmpty())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
41
apps/openmw/mwmechanics/enchanting.hpp
Normal file
41
apps/openmw/mwmechanics/enchanting.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef GAME_MWMECHANICS_ENCHANTING_H
|
||||
#define GAME_MWMECHANICS_ENCHANTING_H
|
||||
#include <string>
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include <components/esm/effectlist.hpp>
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
namespace MWMechanics
|
||||
{
|
||||
class Enchanting
|
||||
{
|
||||
|
||||
MWWorld::Ptr mOldItemPtr;
|
||||
MWWorld::Ptr mSoulGemPtr;
|
||||
MWWorld::Ptr mEnchanter;
|
||||
const MWWorld::Ptr *mNewItemPtr;
|
||||
int mEnchantType;
|
||||
|
||||
ESM::EffectList mEffectList;
|
||||
ESM::Enchantment mEnchantment;
|
||||
|
||||
std::string mNewItemName;
|
||||
std::string mObjectType;
|
||||
std::string mOldItemId;
|
||||
public:
|
||||
Enchanting(MWWorld::Ptr enchanter);
|
||||
void setOldItem(MWWorld::Ptr oldItem);
|
||||
void setNewItemName(std::string s);
|
||||
void setEffect(ESM::EffectList effectList);
|
||||
void setSoulGem(MWWorld::Ptr soulGem);
|
||||
void create();
|
||||
void nextEnchantType();
|
||||
int getEnchantType();
|
||||
int getEnchantCost();
|
||||
int getMaxEnchantValue();
|
||||
int getGemCharge();
|
||||
bool soulEmpty();
|
||||
bool itemEmpty();
|
||||
};
|
||||
}
|
||||
#endif
|
110
apps/openmw/mwmechanics/repair.cpp
Normal file
110
apps/openmw/mwmechanics/repair.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "repair.hpp"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
|
||||
void Repair::repair(const MWWorld::Ptr &itemToRepair)
|
||||
{
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::LiveCellRef<ESM::Repair> *ref =
|
||||
mTool.get<ESM::Repair>();
|
||||
|
||||
// reduce number of uses left
|
||||
int uses = (mTool.getCellRef().mCharge != -1) ? mTool.getCellRef().mCharge : ref->mBase->mData.mUses;
|
||||
mTool.getCellRef().mCharge = uses-1;
|
||||
|
||||
// unstack tool if required
|
||||
if (mTool.getRefData().getCount() > 1 && uses == ref->mBase->mData.mUses)
|
||||
{
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||
MWWorld::ContainerStoreIterator it = store.add(mTool);
|
||||
it->getRefData().setCount(mTool.getRefData().getCount()-1);
|
||||
it->getCellRef().mCharge = -1;
|
||||
|
||||
mTool.getRefData().setCount(1);
|
||||
}
|
||||
|
||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player);
|
||||
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats(player);
|
||||
|
||||
float fatigueTerm = stats.getFatigueTerm();
|
||||
int pcStrength = stats.getAttribute(ESM::Attribute::Strength).getModified();
|
||||
int pcLuck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
int armorerSkill = npcStats.getSkill(ESM::Skill::Armorer).getModified();
|
||||
|
||||
float fRepairAmountMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||
.find("fRepairAmountMult")->getFloat();
|
||||
|
||||
float toolQuality = ref->mBase->mData.mQuality;
|
||||
|
||||
float x = (0.1 * pcStrength + 0.1 * pcLuck + armorerSkill) * fatigueTerm;
|
||||
|
||||
int roll = static_cast<float> (std::rand()) / RAND_MAX * 100;
|
||||
if (roll <= x)
|
||||
{
|
||||
int y = fRepairAmountMult * toolQuality * roll;
|
||||
y = std::max(1, y);
|
||||
|
||||
// repair by 'y' points
|
||||
itemToRepair.getCellRef().mCharge += y;
|
||||
itemToRepair.getCellRef().mCharge = std::min(itemToRepair.getCellRef().mCharge,
|
||||
MWWorld::Class::get(itemToRepair).getItemMaxHealth(itemToRepair));
|
||||
|
||||
// set the OnPCRepair variable on the item's script
|
||||
std::string script = MWWorld::Class::get(itemToRepair).getScript(itemToRepair);
|
||||
if(script != "")
|
||||
itemToRepair.getRefData().getLocals().setVarByInt(script, "onpcrepair", 1);
|
||||
|
||||
// increase skill
|
||||
MWWorld::Class::get(player).skillUsageSucceeded(player, ESM::Skill::Armorer, 0);
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1);
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairSuccess}");
|
||||
}
|
||||
else
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound("Repair Fail",1,1);
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairFailed}");
|
||||
}
|
||||
|
||||
// tool used up?
|
||||
if (mTool.getCellRef().mCharge == 0)
|
||||
{
|
||||
mTool.getRefData().setCount(0);
|
||||
|
||||
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||
.find("sNotifyMessage51")->getString();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->messageBox((boost::format(message) % MWWorld::Class::get(mTool).getName(mTool)).str());
|
||||
|
||||
// try to find a new tool of the same ID
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||
for (MWWorld::ContainerStoreIterator iter (store.begin());
|
||||
iter!=store.end(); ++iter)
|
||||
{
|
||||
if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, mTool.getCellRef().mRefID))
|
||||
{
|
||||
mTool = *iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
23
apps/openmw/mwmechanics/repair.hpp
Normal file
23
apps/openmw/mwmechanics/repair.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef OPENMW_MWMECHANICS_REPAIR_H
|
||||
#define OPENMW_MWMECHANICS_REPAIR_H
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
|
||||
class Repair
|
||||
{
|
||||
public:
|
||||
void setTool (const MWWorld::Ptr& tool) { mTool = tool; }
|
||||
MWWorld::Ptr getTool() { return mTool; }
|
||||
|
||||
void repair (const MWWorld::Ptr& itemToRepair);
|
||||
|
||||
private:
|
||||
MWWorld::Ptr mTool;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,5 +1,7 @@
|
||||
#include "objects.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreEntity.h>
|
||||
@ -271,16 +273,7 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, Ogre::Entity* skelBase, Ogre
|
||||
info.time = Ogre::Math::RangeRandom(-500, +500);
|
||||
info.phase = Ogre::Math::RangeRandom(-500, +500);
|
||||
|
||||
// changed to linear to look like morrowind
|
||||
bool quadratic = false;
|
||||
/*
|
||||
if (!lightOutQuadInLin)
|
||||
quadratic = lightQuadratic;
|
||||
else
|
||||
{
|
||||
quadratic = !info.interior;
|
||||
}
|
||||
*/
|
||||
bool quadratic = lightOutQuadInLin() ? !info.interior : lightQuadratic();
|
||||
|
||||
if (!quadratic)
|
||||
{
|
||||
@ -291,7 +284,7 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, Ogre::Entity* skelBase, Ogre
|
||||
else
|
||||
{
|
||||
float r = radius * lightQuadraticRadiusMult();
|
||||
float attenuation = lightQuadraticValue() / pow(r, 2);
|
||||
float attenuation = lightQuadraticValue() / std::pow(r, 2);
|
||||
light->setAttenuation(r*10, 0, 0, attenuation);
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ namespace MWScript
|
||||
store.get<ESM::CreatureLevList>().search (name) ||
|
||||
store.get<ESM::ItemLevList>().search (name) ||
|
||||
store.get<ESM::Light>().search (name) ||
|
||||
store.get<ESM::Tool>().search (name) ||
|
||||
store.get<ESM::Lockpick>().search (name) ||
|
||||
store.get<ESM::Miscellaneous>().search (name) ||
|
||||
store.get<ESM::NPC>().search (name) ||
|
||||
store.get<ESM::Probe>().search (name) ||
|
||||
|
18
apps/openmw/mwworld/actionrepair.cpp
Normal file
18
apps/openmw/mwworld/actionrepair.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "actionrepair.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
ActionRepair::ActionRepair(const Ptr &item)
|
||||
: Action(false, item)
|
||||
{
|
||||
}
|
||||
|
||||
void ActionRepair::executeImp (const Ptr& actor)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Repair);
|
||||
MWBase::Environment::get().getWindowManager()->startRepairItem(getTarget());
|
||||
}
|
||||
}
|
17
apps/openmw/mwworld/actionrepair.hpp
Normal file
17
apps/openmw/mwworld/actionrepair.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef GAME_MWWORLD_ACTIONREPAIR_H
|
||||
#define GAME_MWWORLD_ACTIONREPAIR_H
|
||||
|
||||
#include "action.hpp"
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class ActionRepair : public Action
|
||||
{
|
||||
virtual void executeImp (const Ptr& actor);
|
||||
|
||||
public:
|
||||
ActionRepair(const MWWorld::Ptr& item);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -206,7 +206,7 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, Ptr::CellStore& ce
|
||||
if (MWWorld::LiveCellRef<ESM::Light> *ref = cell.mLights.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Tool> *ref = cell.mLockpicks.find (name))
|
||||
if (MWWorld::LiveCellRef<ESM::Lockpick> *ref = cell.mLockpicks.find (name))
|
||||
ptr = Ptr (ref, &cell);
|
||||
|
||||
if (MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = cell.mMiscItems.find (name))
|
||||
|
@ -112,7 +112,7 @@ namespace MWWorld
|
||||
CellRefList<ESM::CreatureLevList> mCreatureLists;
|
||||
CellRefList<ESM::ItemLevList> mItemLists;
|
||||
CellRefList<ESM::Light> mLights;
|
||||
CellRefList<ESM::Tool> mLockpicks;
|
||||
CellRefList<ESM::Lockpick> mLockpicks;
|
||||
CellRefList<ESM::Miscellaneous> mMiscItems;
|
||||
CellRefList<ESM::NPC> mNpcs;
|
||||
CellRefList<ESM::Probe> mProbes;
|
||||
|
@ -127,6 +127,11 @@ namespace MWWorld
|
||||
return 0;
|
||||
}
|
||||
|
||||
short Class::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
throw std::runtime_error ("class does not support enchanting");
|
||||
}
|
||||
|
||||
MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const
|
||||
{
|
||||
throw std::runtime_error ("movement settings not supported by class");
|
||||
@ -169,7 +174,7 @@ namespace MWWorld
|
||||
|
||||
bool Class::hasDetected (const MWWorld::Ptr& ptr, const MWWorld::Ptr& ptr2) const
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
float Class::getArmorRating (const MWWorld::Ptr& ptr) const
|
||||
@ -241,6 +246,11 @@ namespace MWWorld
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string Class::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
|
||||
{
|
||||
throw std::runtime_error ("class can't be enchanted");
|
||||
}
|
||||
|
||||
MWWorld::Ptr
|
||||
Class::copyToCellImpl(const Ptr &ptr, CellStore &cell) const
|
||||
{
|
||||
|
@ -225,12 +225,17 @@ namespace MWWorld
|
||||
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
|
||||
/// (default implementation: return empty string)
|
||||
|
||||
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
|
||||
///< @return the number of enchantment points available for possible enchanting
|
||||
|
||||
virtual void adjustScale(const MWWorld::Ptr& ptr,float& scale) const;
|
||||
|
||||
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
||||
virtual std::string applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
|
||||
|
||||
virtual Ptr
|
||||
copyToCell(const Ptr &ptr, CellStore &cell) const;
|
||||
|
||||
|
@ -38,12 +38,6 @@ namespace
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
bool compare_string_ci(std::string str1, std::string str2)
|
||||
{
|
||||
Misc::StringUtils::toLower(str1);
|
||||
return str1 == str2;
|
||||
}
|
||||
}
|
||||
|
||||
MWWorld::ContainerStore::ContainerStore() : mStateId (0), mCachedWeight (0), mWeightUpToDate (false) {}
|
||||
@ -62,13 +56,17 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end()
|
||||
|
||||
bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
|
||||
{
|
||||
/// \todo add current weapon/armor health, remaining lockpick/repair uses, current enchantment charge here as soon as they are implemented
|
||||
/// \todo add current enchantment charge here when it is implemented
|
||||
if ( ptr1.mCellRef->mRefID == ptr2.mCellRef->mRefID
|
||||
&& MWWorld::Class::get(ptr1).getScript(ptr1) == "" // item with a script never stacks
|
||||
&& MWWorld::Class::get(ptr1).getEnchantment(ptr1) == "" // item with enchantment never stacks (we could revisit this later, but for now it makes selecting items in the spell window much easier)
|
||||
&& ptr1.mCellRef->mOwner == ptr2.mCellRef->mOwner
|
||||
&& ptr1.mCellRef->mSoul == ptr2.mCellRef->mSoul
|
||||
&& ptr1.mCellRef->mCharge == ptr2.mCellRef->mCharge)
|
||||
// item that is already partly used up never stacks
|
||||
&& (!MWWorld::Class::get(ptr1).hasItemHealth(ptr1) || ptr1.mCellRef->mCharge == -1
|
||||
|| MWWorld::Class::get(ptr1).getItemMaxHealth(ptr1) == ptr1.mCellRef->mCharge)
|
||||
&& (!MWWorld::Class::get(ptr2).hasItemHealth(ptr2) || ptr2.mCellRef->mCharge == -1
|
||||
|| MWWorld::Class::get(ptr2).getItemMaxHealth(ptr2) == ptr2.mCellRef->mCharge))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -118,19 +116,20 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr)
|
||||
MWWorld::LiveCellRef<ESM::Miscellaneous> *gold =
|
||||
ptr.get<ESM::Miscellaneous>();
|
||||
|
||||
if (compare_string_ci(gold->mRef.mRefID, "gold_001")
|
||||
|| compare_string_ci(gold->mRef.mRefID, "gold_005")
|
||||
|| compare_string_ci(gold->mRef.mRefID, "gold_010")
|
||||
|| compare_string_ci(gold->mRef.mRefID, "gold_025")
|
||||
|| compare_string_ci(gold->mRef.mRefID, "gold_100"))
|
||||
if (Misc::StringUtils::ciEqual(gold->mRef.mRefID, "gold_001")
|
||||
|| Misc::StringUtils::ciEqual(gold->mRef.mRefID, "gold_005")
|
||||
|| Misc::StringUtils::ciEqual(gold->mRef.mRefID, "gold_010")
|
||||
|| Misc::StringUtils::ciEqual(gold->mRef.mRefID, "gold_025")
|
||||
|| Misc::StringUtils::ciEqual(gold->mRef.mRefID, "gold_100"))
|
||||
{
|
||||
MWWorld::ManualRef ref(esmStore, "Gold_001");
|
||||
|
||||
int count = (ptr.getRefData().getCount() == 1) ? gold->mBase->mData.mValue : ptr.getRefData().getCount();
|
||||
int count = MWWorld::Class::get(ptr).getValue(ptr) * ptr.getRefData().getCount();
|
||||
|
||||
ref.getPtr().getRefData().setCount(count);
|
||||
for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
|
||||
{
|
||||
if (compare_string_ci((*iter).get<ESM::Miscellaneous>()->mRef.mRefID, "gold_001"))
|
||||
if (Misc::StringUtils::ciEqual((*iter).get<ESM::Miscellaneous>()->mRef.mRefID, "gold_001"))
|
||||
{
|
||||
(*iter).getRefData().setCount( (*iter).getRefData().getCount() + count);
|
||||
flagAsModified();
|
||||
@ -171,7 +170,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImpl (const Ptr& ptr
|
||||
case Type_Clothing: clothes.mList.push_back (*ptr.get<ESM::Clothing>()); it = ContainerStoreIterator(this, --clothes.mList.end()); break;
|
||||
case Type_Ingredient: ingreds.mList.push_back (*ptr.get<ESM::Ingredient>()); it = ContainerStoreIterator(this, --ingreds.mList.end()); break;
|
||||
case Type_Light: lights.mList.push_back (*ptr.get<ESM::Light>()); it = ContainerStoreIterator(this, --lights.mList.end()); break;
|
||||
case Type_Lockpick: lockpicks.mList.push_back (*ptr.get<ESM::Tool>()); it = ContainerStoreIterator(this, --lockpicks.mList.end()); break;
|
||||
case Type_Lockpick: lockpicks.mList.push_back (*ptr.get<ESM::Lockpick>()); it = ContainerStoreIterator(this, --lockpicks.mList.end()); break;
|
||||
case Type_Miscellaneous: miscItems.mList.push_back (*ptr.get<ESM::Miscellaneous>()); it = ContainerStoreIterator(this, --miscItems.mList.end()); break;
|
||||
case Type_Probe: probes.mList.push_back (*ptr.get<ESM::Probe>()); it = ContainerStoreIterator(this, --probes.mList.end()); break;
|
||||
case Type_Repair: repairs.mList.push_back (*ptr.get<ESM::Repair>()); it = ContainerStoreIterator(this, --repairs.mList.end()); break;
|
||||
@ -272,7 +271,7 @@ int MWWorld::ContainerStore::getType (const Ptr& ptr)
|
||||
if (ptr.getTypeName()==typeid (ESM::Light).name())
|
||||
return Type_Light;
|
||||
|
||||
if (ptr.getTypeName()==typeid (ESM::Tool).name())
|
||||
if (ptr.getTypeName()==typeid (ESM::Lockpick).name())
|
||||
return Type_Lockpick;
|
||||
|
||||
if (ptr.getTypeName()==typeid (ESM::Miscellaneous).name())
|
||||
@ -321,7 +320,7 @@ MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *contain
|
||||
: mType(MWWorld::ContainerStore::Type_Ingredient), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mIngredient(iterator){}
|
||||
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Light>::List::iterator iterator)
|
||||
: mType(MWWorld::ContainerStore::Type_Light), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mLight(iterator){}
|
||||
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Tool>::List::iterator iterator)
|
||||
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Lockpick>::List::iterator iterator)
|
||||
: mType(MWWorld::ContainerStore::Type_Lockpick), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mLockpick(iterator){}
|
||||
MWWorld::ContainerStoreIterator::ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Miscellaneous>::List::iterator iterator)
|
||||
: mType(MWWorld::ContainerStore::Type_Miscellaneous), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mMiscellaneous(iterator){}
|
||||
|
@ -44,7 +44,7 @@ namespace MWWorld
|
||||
MWWorld::CellRefList<ESM::Clothing> clothes;
|
||||
MWWorld::CellRefList<ESM::Ingredient> ingreds;
|
||||
MWWorld::CellRefList<ESM::Light> lights;
|
||||
MWWorld::CellRefList<ESM::Tool> lockpicks;
|
||||
MWWorld::CellRefList<ESM::Lockpick> lockpicks;
|
||||
MWWorld::CellRefList<ESM::Miscellaneous> miscItems;
|
||||
MWWorld::CellRefList<ESM::Probe> probes;
|
||||
MWWorld::CellRefList<ESM::Repair> repairs;
|
||||
@ -127,7 +127,7 @@ namespace MWWorld
|
||||
MWWorld::CellRefList<ESM::Clothing>::List::iterator mClothing;
|
||||
MWWorld::CellRefList<ESM::Ingredient>::List::iterator mIngredient;
|
||||
MWWorld::CellRefList<ESM::Light>::List::iterator mLight;
|
||||
MWWorld::CellRefList<ESM::Tool>::List::iterator mLockpick;
|
||||
MWWorld::CellRefList<ESM::Lockpick>::List::iterator mLockpick;
|
||||
MWWorld::CellRefList<ESM::Miscellaneous>::List::iterator mMiscellaneous;
|
||||
MWWorld::CellRefList<ESM::Probe>::List::iterator mProbe;
|
||||
MWWorld::CellRefList<ESM::Repair>::List::iterator mRepair;
|
||||
@ -149,7 +149,7 @@ namespace MWWorld
|
||||
ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Clothing>::List::iterator);
|
||||
ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Ingredient>::List::iterator);
|
||||
ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Light>::List::iterator);
|
||||
ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Tool>::List::iterator);
|
||||
ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Lockpick>::List::iterator);
|
||||
ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Miscellaneous>::List::iterator);
|
||||
ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Probe>::List::iterator);
|
||||
ContainerStoreIterator (ContainerStore *container, MWWorld::CellRefList<ESM::Repair>::List::iterator);
|
||||
|
@ -32,7 +32,7 @@ namespace MWWorld
|
||||
Store<ESM::CreatureLevList> mCreatureLists;
|
||||
Store<ESM::ItemLevList> mItemLists;
|
||||
Store<ESM::Light> mLights;
|
||||
Store<ESM::Tool> mLockpicks;
|
||||
Store<ESM::Lockpick> mLockpicks;
|
||||
Store<ESM::Miscellaneous> mMiscItems;
|
||||
Store<ESM::NPC> mNpcs;
|
||||
Store<ESM::LoadNPCC> mNpcChange;
|
||||
@ -312,7 +312,7 @@ namespace MWWorld
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const Store<ESM::Tool> &ESMStore::get<ESM::Tool>() const {
|
||||
inline const Store<ESM::Lockpick> &ESMStore::get<ESM::Lockpick>() const {
|
||||
return mLockpicks;
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ namespace MWWorld
|
||||
{
|
||||
// vanilla Morrowind does not define dayspassed.
|
||||
Data value;
|
||||
value.mLong = 0;
|
||||
value.mLong = 1; // but the addons start counting at 1 :(
|
||||
|
||||
mVariables.insert (std::make_pair ("dayspassed", std::make_pair ('l', value)));
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ namespace MWWorld
|
||||
!create (store.get<ESM::CreatureLevList>(), name) &&
|
||||
!create (store.get<ESM::ItemLevList>(), name) &&
|
||||
!create (store.get<ESM::Light>(), name) &&
|
||||
!create (store.get<ESM::Tool>(), name) &&
|
||||
!create (store.get<ESM::Lockpick>(), name) &&
|
||||
!create (store.get<ESM::Miscellaneous>(), name) &&
|
||||
!create (store.get<ESM::NPC>(), name) &&
|
||||
!create (store.get<ESM::Probe>(), name) &&
|
||||
@ -68,12 +68,12 @@ namespace MWWorld
|
||||
cellRef.mRefnum = -1;
|
||||
cellRef.mScale = 1;
|
||||
cellRef.mFactIndex = 0;
|
||||
cellRef.mCharge = 0;
|
||||
cellRef.mIntv = 0;
|
||||
cellRef.mNam9 = 0;
|
||||
cellRef.mCharge = -1;
|
||||
cellRef.mGoldValue = 1;
|
||||
cellRef.mEnchantmentCharge = -1;
|
||||
cellRef.mTeleport = false;
|
||||
cellRef.mLockLevel = 0;
|
||||
cellRef.mUnam = 0;
|
||||
cellRef.mReferenceBlocked = 0;
|
||||
}
|
||||
|
||||
const Ptr& getPtr() const
|
||||
|
@ -41,7 +41,7 @@ namespace
|
||||
|
||||
++current;
|
||||
|
||||
if (it->mData.getCount() || it->mData.isEnabled())
|
||||
if (it->mData.getCount() && it->mData.isEnabled())
|
||||
{
|
||||
MWWorld::Ptr ptr (&*it, &cell);
|
||||
|
||||
|
@ -101,7 +101,7 @@ namespace MWWorld
|
||||
return Ptr (ref, &cell);
|
||||
if (MWWorld::LiveCellRef<ESM::Light> *ref = searchViaHandle (handle, cell.mLights))
|
||||
return Ptr (ref, &cell);
|
||||
if (MWWorld::LiveCellRef<ESM::Tool> *ref = searchViaHandle (handle, cell.mLockpicks))
|
||||
if (MWWorld::LiveCellRef<ESM::Lockpick> *ref = searchViaHandle (handle, cell.mLockpicks))
|
||||
return Ptr (ref, &cell);
|
||||
if (MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = searchViaHandle (handle, cell.mMiscItems))
|
||||
return Ptr (ref, &cell);
|
||||
@ -949,6 +949,31 @@ namespace MWWorld
|
||||
return ret;
|
||||
}
|
||||
|
||||
const ESM::Armor *World::createRecord (const ESM::Armor& record)
|
||||
{
|
||||
return mStore.insert(record);
|
||||
}
|
||||
|
||||
const ESM::Weapon *World::createRecord (const ESM::Weapon& record)
|
||||
{
|
||||
return mStore.insert(record);
|
||||
}
|
||||
|
||||
const ESM::Clothing *World::createRecord (const ESM::Clothing& record)
|
||||
{
|
||||
return mStore.insert(record);
|
||||
}
|
||||
|
||||
const ESM::Enchantment *World::createRecord (const ESM::Enchantment& record)
|
||||
{
|
||||
return mStore.insert(record);
|
||||
}
|
||||
|
||||
const ESM::Book *World::createRecord (const ESM::Book& record)
|
||||
{
|
||||
return mStore.insert(record);
|
||||
}
|
||||
|
||||
void World::update (float duration, bool paused)
|
||||
{
|
||||
mWeatherManager->update (duration);
|
||||
|
@ -272,25 +272,44 @@ namespace MWWorld
|
||||
///< \return Resulting mode
|
||||
|
||||
virtual const ESM::Potion *createRecord (const ESM::Potion& record);
|
||||
///< Create a new recrod (of type potion) in the ESM store.
|
||||
///< Create a new record (of type potion) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Spell *createRecord (const ESM::Spell& record);
|
||||
///< Create a new recrod (of type spell) in the ESM store.
|
||||
///< Create a new record (of type spell) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Class *createRecord (const ESM::Class& record);
|
||||
///< Create a new recrod (of type class) in the ESM store.
|
||||
///< Create a new record (of type class) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Cell *createRecord (const ESM::Cell& record);
|
||||
///< Create a new recrod (of type cell) in the ESM store.
|
||||
///< Create a new record (of type cell) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::NPC *createRecord(const ESM::NPC &record);
|
||||
///< Create a new recrod (of type npc) in the ESM store.
|
||||
///< Create a new record (of type npc) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Armor *createRecord (const ESM::Armor& record);
|
||||
///< Create a new record (of type armor) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Weapon *createRecord (const ESM::Weapon& record);
|
||||
///< Create a new record (of type weapon) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Clothing *createRecord (const ESM::Clothing& record);
|
||||
///< Create a new record (of type clothing) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Enchantment *createRecord (const ESM::Enchantment& record);
|
||||
///< Create a new record (of type enchantment) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual const ESM::Book *createRecord (const ESM::Book& record);
|
||||
///< Create a new record (of type book) in the ESM store.
|
||||
/// \return pointer to created record
|
||||
|
||||
virtual void update (float duration, bool paused);
|
||||
|
||||
|
@ -37,7 +37,7 @@ add_component_dir (file_finder
|
||||
add_component_dir (esm
|
||||
attr defs esmcommon esmreader esmwriter loadacti loadalch loadappa loadarmo loadbody loadbook loadbsgn loadcell
|
||||
loadclas loadclot loadcont loadcrea loadcrec loaddial loaddoor loadench loadfact loadglob loadgmst
|
||||
loadinfo loadingr loadland loadlevlist loadligh loadlocks loadltex loadmgef loadmisc loadnpcc
|
||||
loadinfo loadingr loadland loadlevlist loadligh loadlock loadprob loadrepa loadltex loadmgef loadmisc loadnpcc
|
||||
loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat
|
||||
loadweap records aipackage effectlist spelllist variant variantimp loadtes3
|
||||
)
|
||||
|
@ -14,7 +14,7 @@
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
/// Some overloaded copare operators.
|
||||
/// Some overloaded compare operators.
|
||||
bool operator==(const MovedCellRef& ref, int pRefnum)
|
||||
{
|
||||
return (ref.mRefnum == pRefnum);
|
||||
@ -43,15 +43,14 @@ void CellRef::save(ESMWriter &esm)
|
||||
esm.writeHNT("INDX", mFactIndex);
|
||||
}
|
||||
|
||||
if (mCharge != -1.0) {
|
||||
esm.writeHNT("XCHG", mCharge);
|
||||
}
|
||||
if (mEnchantmentCharge != -1)
|
||||
esm.writeHNT("XCHG", mEnchantmentCharge);
|
||||
|
||||
if (mIntv != -1) {
|
||||
esm.writeHNT("INTV", mIntv);
|
||||
}
|
||||
if (mNam9 != 0) {
|
||||
esm.writeHNT("NAM9", mNam9);
|
||||
if (mCharge != -1)
|
||||
esm.writeHNT("INTV", mCharge);
|
||||
|
||||
if (mGoldValue != 1) {
|
||||
esm.writeHNT("NAM9", mGoldValue);
|
||||
}
|
||||
|
||||
if (mTeleport)
|
||||
@ -66,8 +65,8 @@ void CellRef::save(ESMWriter &esm)
|
||||
esm.writeHNOCString("KNAM", mKey);
|
||||
esm.writeHNOCString("TNAM", mTrap);
|
||||
|
||||
if (mUnam != -1) {
|
||||
esm.writeHNT("UNAM", mUnam);
|
||||
if (mReferenceBlocked != -1) {
|
||||
esm.writeHNT("UNAM", mReferenceBlocked);
|
||||
}
|
||||
if (mFltv != 0) {
|
||||
esm.writeHNT("FLTV", mFltv);
|
||||
@ -285,13 +284,15 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
|
||||
ref.mFactIndex = -2;
|
||||
esm.getHNOT(ref.mFactIndex, "INDX");
|
||||
|
||||
ref.mCharge = -1.0;
|
||||
esm.getHNOT(ref.mCharge, "XCHG");
|
||||
ref.mGoldValue = 1;
|
||||
ref.mCharge = -1;
|
||||
ref.mEnchantmentCharge = -1;
|
||||
|
||||
ref.mIntv = -1;
|
||||
ref.mNam9 = 0;
|
||||
esm.getHNOT(ref.mIntv, "INTV");
|
||||
esm.getHNOT(ref.mNam9, "NAM9");
|
||||
esm.getHNOT(ref.mEnchantmentCharge, "XCHG");
|
||||
|
||||
esm.getHNOT(ref.mCharge, "INTV");
|
||||
|
||||
esm.getHNOT(ref.mGoldValue, "NAM9");
|
||||
|
||||
// Present for doors that teleport you to another cell.
|
||||
if (esm.isNextSub("DODT"))
|
||||
@ -309,9 +310,9 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
|
||||
ref.mKey = esm.getHNOString("KNAM");
|
||||
ref.mTrap = esm.getHNOString("TNAM");
|
||||
|
||||
ref.mUnam = -1;
|
||||
ref.mReferenceBlocked = -1;
|
||||
ref.mFltv = 0;
|
||||
esm.getHNOT(ref.mUnam, "UNAM");
|
||||
esm.getHNOT(ref.mReferenceBlocked, "UNAM");
|
||||
esm.getHNOT(ref.mFltv, "FLTV");
|
||||
|
||||
esm.getHNOT(ref.mPos, "DATA", 24);
|
||||
|
@ -52,15 +52,15 @@ public:
|
||||
// is -1, which I assume means "any rank".
|
||||
int mFactIndex;
|
||||
|
||||
// Depends on context - possibly weapon health, number of uses left
|
||||
// or weapon magic charge?
|
||||
float mCharge;
|
||||
// For weapon or armor, this is the remaining item health.
|
||||
// For tools (lockpicks, probes, repair hammer) it is the remaining uses.
|
||||
int mCharge;
|
||||
|
||||
// I have no idea, these are present some times, often along with
|
||||
// owner (ANAM) and sometimes otherwise. They are often (but not
|
||||
// always) 1. INTV is big for lights (possibly a float?), might have
|
||||
// something to do with remaining light "charge".
|
||||
int mIntv, mNam9;
|
||||
// Remaining enchantment charge
|
||||
float mEnchantmentCharge;
|
||||
|
||||
// This is 5 for Gold_005 references, 100 for Gold_100 and so on.
|
||||
int mGoldValue;
|
||||
|
||||
// For doors - true if this door teleports to somewhere else, false
|
||||
// if it should open through animation.
|
||||
@ -76,8 +76,10 @@ public:
|
||||
int mLockLevel;
|
||||
std::string mKey, mTrap; // Key and trap ID names, if any
|
||||
|
||||
// No idea - occurs ONCE in Morrowind.esm, for an activator
|
||||
signed char mUnam;
|
||||
// This corresponds to the "Reference Blocked" checkbox in the construction set,
|
||||
// which prevents editing that reference.
|
||||
// -1 is not blocked, otherwise it is blocked.
|
||||
signed char mReferenceBlocked;
|
||||
|
||||
// Track deleted references. 0 - not deleted, 1 - deleted, but respawns, 2 - deleted and does not respawn.
|
||||
int mDeleted;
|
||||
|
31
components/esm/loadlock.cpp
Normal file
31
components/esm/loadlock.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "loadlock.hpp"
|
||||
|
||||
#include "esmreader.hpp"
|
||||
#include "esmwriter.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
void Lockpick::load(ESMReader &esm)
|
||||
{
|
||||
mModel = esm.getHNString("MODL");
|
||||
mName = esm.getHNString("FNAM");
|
||||
|
||||
esm.getHNT(mData, "LKDT", 16);
|
||||
|
||||
mScript = esm.getHNOString("SCRI");
|
||||
mIcon = esm.getHNOString("ITEX");
|
||||
}
|
||||
|
||||
void Lockpick::save(ESMWriter &esm)
|
||||
{
|
||||
esm.writeHNCString("MODL", mModel);
|
||||
esm.writeHNCString("FNAM", mName);
|
||||
|
||||
esm.writeHNT("LKDT", mData, 16);
|
||||
esm.writeHNOString("SCRI", mScript);
|
||||
esm.writeHNOCString("ITEX", mIcon);
|
||||
}
|
||||
|
||||
|
||||
}
|
31
components/esm/loadlock.hpp
Normal file
31
components/esm/loadlock.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef OPENMW_ESM_LOCK_H
|
||||
#define OPENMW_ESM_LOCK_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
class ESMReader;
|
||||
class ESMWriter;
|
||||
|
||||
struct Lockpick
|
||||
{
|
||||
struct Data
|
||||
{
|
||||
float mWeight;
|
||||
int mValue;
|
||||
|
||||
float mQuality;
|
||||
int mUses;
|
||||
}; // Size = 16
|
||||
|
||||
Data mData;
|
||||
std::string mId, mName, mModel, mIcon, mScript;
|
||||
|
||||
void load(ESMReader &esm);
|
||||
void save(ESMWriter &esm);
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
@ -1,65 +0,0 @@
|
||||
#include "loadlocks.hpp"
|
||||
|
||||
#include "esmreader.hpp"
|
||||
#include "esmwriter.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
void Tool::load(ESMReader &esm)
|
||||
{
|
||||
mModel = esm.getHNString("MODL");
|
||||
mName = esm.getHNString("FNAM");
|
||||
|
||||
esm.getSubName();
|
||||
NAME n = esm.retSubName();
|
||||
// The data name varies, RIDT for repair items, LKDT for lock
|
||||
// picks, PBDT for probes
|
||||
|
||||
esm.getHT(mData, 16);
|
||||
|
||||
if (n == "RIDT")
|
||||
{
|
||||
mType = Type_Repair;
|
||||
// Swap t.data.quality and t.data.uses for repair items (sigh)
|
||||
float tmp = *((float*) &mData.mUses);
|
||||
mData.mUses = *((int*) &mData.mQuality);
|
||||
mData.mQuality = tmp;
|
||||
}
|
||||
else if (n == "LKDT")
|
||||
mType = Type_Pick;
|
||||
else if (n == "PBDT")
|
||||
mType = Type_Probe;
|
||||
|
||||
mScript = esm.getHNOString("SCRI");
|
||||
mIcon = esm.getHNOString("ITEX");
|
||||
}
|
||||
|
||||
void Tool::save(ESMWriter &esm)
|
||||
{
|
||||
esm.writeHNCString("MODL", mModel);
|
||||
esm.writeHNCString("FNAM", mName);
|
||||
|
||||
std::string typeName;
|
||||
switch(mType)
|
||||
{
|
||||
case Type_Repair: typeName = "RIDT"; break;
|
||||
case Type_Pick: typeName = "LKDT"; break;
|
||||
case Type_Probe: typeName = "PBDT"; break;
|
||||
}
|
||||
|
||||
Data write = mData;
|
||||
if (mType == Type_Repair)
|
||||
{
|
||||
float tmp = *((float*) &write.mUses);
|
||||
write.mUses = *((int*) &write.mQuality);
|
||||
write.mQuality = tmp;
|
||||
}
|
||||
|
||||
esm.writeHNT(typeName, write, 16);
|
||||
esm.writeHNOString("SCRI", mScript);
|
||||
esm.writeHNOCString("ITEX", mIcon);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
#ifndef OPENMW_ESM_LOCKS_H
|
||||
#define OPENMW_ESM_LOCKS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
class ESMReader;
|
||||
class ESMWriter;
|
||||
|
||||
/*
|
||||
* This file covers lockpicks (LOCK), probes (PROB) and armor repair
|
||||
* items (REPA). These have nearly identical data structures.
|
||||
*/
|
||||
|
||||
struct Tool
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Type_Pick,
|
||||
Type_Probe,
|
||||
Type_Repair
|
||||
};
|
||||
|
||||
struct Data
|
||||
{
|
||||
float mWeight;
|
||||
int mValue;
|
||||
|
||||
float mQuality; // And when I say nearly identical structure, I
|
||||
int mUses; // mean perfectly identical except that these two
|
||||
// variables are swaped for repair items. Don't ask
|
||||
// me why.
|
||||
}; // Size = 16
|
||||
|
||||
Data mData;
|
||||
Type mType;
|
||||
std::string mId, mName, mModel, mIcon, mScript;
|
||||
|
||||
void load(ESMReader &esm);
|
||||
void save(ESMWriter &esm);
|
||||
};
|
||||
|
||||
struct Probe: Tool
|
||||
{
|
||||
Probe() { mType = Type_Probe; }
|
||||
};
|
||||
|
||||
struct Repair: Tool
|
||||
{
|
||||
Repair() { mType = Type_Repair; }
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
30
components/esm/loadprob.cpp
Normal file
30
components/esm/loadprob.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "loadprob.hpp"
|
||||
|
||||
#include "esmreader.hpp"
|
||||
#include "esmwriter.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
void Probe::load(ESMReader &esm)
|
||||
{
|
||||
mModel = esm.getHNString("MODL");
|
||||
mName = esm.getHNString("FNAM");
|
||||
|
||||
esm.getHNT(mData, "PBDT", 16);
|
||||
|
||||
mScript = esm.getHNOString("SCRI");
|
||||
mIcon = esm.getHNOString("ITEX");
|
||||
}
|
||||
|
||||
void Probe::save(ESMWriter &esm)
|
||||
{
|
||||
esm.writeHNCString("MODL", mModel);
|
||||
esm.writeHNCString("FNAM", mName);
|
||||
|
||||
esm.writeHNT("PBDT", mData, 16);
|
||||
esm.writeHNOString("SCRI", mScript);
|
||||
esm.writeHNOCString("ITEX", mIcon);
|
||||
}
|
||||
|
||||
}
|
31
components/esm/loadprob.hpp
Normal file
31
components/esm/loadprob.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef OPENMW_ESM_PROBE_H
|
||||
#define OPENMW_ESM_PROBE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
|
||||
class ESMReader;
|
||||
class ESMWriter;
|
||||
|
||||
struct Probe
|
||||
{
|
||||
struct Data
|
||||
{
|
||||
float mWeight;
|
||||
int mValue;
|
||||
|
||||
float mQuality;
|
||||
int mUses;
|
||||
}; // Size = 16
|
||||
|
||||
Data mData;
|
||||
std::string mId, mName, mModel, mIcon, mScript;
|
||||
|
||||
void load(ESMReader &esm);
|
||||
void save(ESMWriter &esm);
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user