Conflicts:
	apps/openmw/CMakeLists.txt
This commit is contained in:
gus 2013-04-01 14:10:19 +00:00
commit 1eb3d3e10e
123 changed files with 2115 additions and 551 deletions

View file

@ -227,7 +227,10 @@ void loadCell(ESM::Cell &cell, ESM::ESMReader &esm, Arguments& info)
std::cout << " Refnum: " << ref.mRefnum << std::endl; std::cout << " Refnum: " << ref.mRefnum << std::endl;
std::cout << " ID: '" << ref.mRefID << "'\n"; std::cout << " ID: '" << ref.mRefID << "'\n";
std::cout << " Owner: '" << ref.mOwner << "'\n"; std::cout << " Owner: '" << ref.mOwner << "'\n";
std::cout << " Uses/health: " << ref.mCharge << " NAM9: " << ref.mNam9 << 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;
} }
} }

View file

@ -627,10 +627,10 @@ std::string bodyPartFlags(int flags)
std::string properties = ""; std::string properties = "";
if (flags == 0) properties += "[None] "; if (flags == 0) properties += "[None] ";
if (flags & ESM::BodyPart::BPF_Female) properties += "Female "; if (flags & ESM::BodyPart::BPF_Female) properties += "Female ";
if (flags & ESM::BodyPart::BPF_Playable) properties += "Playable "; if (flags & ESM::BodyPart::BPF_NotPlayable) properties += "NotPlayable ";
int unused = (0xFFFFFFFF ^ int unused = (0xFFFFFFFF ^
(ESM::BodyPart::BPF_Female| (ESM::BodyPart::BPF_Female|
ESM::BodyPart::BPF_Playable)); ESM::BodyPart::BPF_NotPlayable));
if (flags & unused) properties += "Invalid "; if (flags & unused) properties += "Invalid ";
properties += str(boost::format("(0x%08X)") % flags); properties += str(boost::format("(0x%08X)") % flags);
return properties; return properties;

View file

@ -2,9 +2,9 @@
#define CS_EDITOR_H #define CS_EDITOR_H
#include <QObject> #include <QObject>
#ifndef Q_MOC_RUN
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
#endif
#include "model/doc/documentmanager.hpp" #include "model/doc/documentmanager.hpp"
#include "view/doc/viewmanager.hpp" #include "view/doc/viewmanager.hpp"

View file

@ -207,7 +207,7 @@ void CSMDoc::Document::createBase()
{ {
ESM::Skill record; ESM::Skill record;
record.mIndex = i; record.mIndex = i;
record.mId = ESM::Skill::getIndexToId (record.mIndex); record.mId = ESM::Skill::indexToId (record.mIndex);
record.blank(); record.blank();
getData().getSkills().add (record); getData().getSkills().add (record);

View file

@ -33,7 +33,8 @@ namespace CSMWorld
Display_GmstVarType, Display_GmstVarType,
Display_GlobalVarType, Display_GlobalVarType,
Display_Specialisation, Display_Specialisation,
Display_Attribute Display_Attribute,
Display_Boolean
}; };
std::string mTitle; std::string mTitle;

View file

@ -1,6 +1,8 @@
#ifndef CSM_WOLRD_COLUMNS_H #ifndef CSM_WOLRD_COLUMNS_H
#define CSM_WOLRD_COLUMNS_H #define CSM_WOLRD_COLUMNS_H
#include <sstream>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include "columnbase.hpp" #include "columnbase.hpp"
@ -285,6 +287,128 @@ namespace CSMWorld
} }
}; };
template<typename ESXRecordT>
struct NameColumn : public Column<ESXRecordT>
{
NameColumn() : Column<ESXRecordT> ("Name", ColumnBase::Display_String) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return QString::fromUtf8 (record.get().mName.c_str());
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mName = data.toString().toUtf8().constData();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct AttributesColumn : public Column<ESXRecordT>
{
int mIndex;
AttributesColumn (int index)
: Column<ESXRecordT> ("Attribute #" + boost::lexical_cast<std::string> (index),
ColumnBase::Display_Attribute), mIndex (index) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mData.mAttribute[mIndex];
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mAttribute[mIndex] = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct SkillsColumn : public Column<ESXRecordT>
{
int mIndex;
bool mMajor;
SkillsColumn (int index, bool major)
: Column<ESXRecordT> ((major ? "Major Skill #" : "Minor Skill #")+
boost::lexical_cast<std::string> (index), ColumnBase::Display_String),
mIndex (index), mMajor (major)
{}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
int skill = record.get().mData.mSkills[mIndex][mMajor ? 1 : 0];
return QString::fromUtf8 (ESM::Skill::indexToId (skill).c_str());
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
std::istringstream stream (data.toString().toUtf8().constData());
int index = -1;
char c;
stream >> c >> index;
if (index!=-1)
{
ESXRecordT record2 = record.get();
record2.mData.mSkills[mIndex][mMajor ? 1 : 0] = index;
record.setModified (record2);
}
}
virtual bool isEditable() const
{
return true;
}
};
template<typename ESXRecordT>
struct PlayableColumn : public Column<ESXRecordT>
{
PlayableColumn() : Column<ESXRecordT> ("Playable", ColumnBase::Display_Boolean) {}
virtual QVariant get (const Record<ESXRecordT>& record) const
{
return record.get().mData.mIsPlayable!=0;
}
virtual void set (Record<ESXRecordT>& record, const QVariant& data)
{
ESXRecordT record2 = record.get();
record2.mData.mIsPlayable = data.toInt();
record.setModified (record2);
}
virtual bool isEditable() const
{
return true;
}
};
} }
#endif #endif

View file

@ -44,9 +44,23 @@ CSMWorld::Data::Data()
mSkills.addColumn (new UseValueColumn<ESM::Skill> (i)); mSkills.addColumn (new UseValueColumn<ESM::Skill> (i));
mSkills.addColumn (new DescriptionColumn<ESM::Skill>); mSkills.addColumn (new DescriptionColumn<ESM::Skill>);
mClasses.addColumn (new StringIdColumn<ESM::Class>);
mClasses.addColumn (new RecordStateColumn<ESM::Class>);
mClasses.addColumn (new NameColumn<ESM::Class>);
mClasses.addColumn (new AttributesColumn<ESM::Class> (0));
mClasses.addColumn (new AttributesColumn<ESM::Class> (1));
mClasses.addColumn (new SpecialisationColumn<ESM::Class>);
for (int i=0; i<5; ++i)
mClasses.addColumn (new SkillsColumn<ESM::Class> (i, true));
for (int i=0; i<5; ++i)
mClasses.addColumn (new SkillsColumn<ESM::Class> (i, false));
mClasses.addColumn (new PlayableColumn<ESM::Class>);
mClasses.addColumn (new DescriptionColumn<ESM::Class>);
addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global);
addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst); addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill); addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
} }
CSMWorld::Data::~Data() CSMWorld::Data::~Data()
@ -122,6 +136,7 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base)
case ESM::REC_GLOB: mGlobals.load (reader, base); break; case ESM::REC_GLOB: mGlobals.load (reader, base); break;
case ESM::REC_GMST: mGmsts.load (reader, base); break; case ESM::REC_GMST: mGmsts.load (reader, base); break;
case ESM::REC_SKIL: mSkills.load (reader, base); break; case ESM::REC_SKIL: mSkills.load (reader, base); break;
case ESM::REC_CLAS: mClasses.load (reader, base); break;
default: default:

View file

@ -9,6 +9,7 @@
#include <components/esm/loadglob.hpp> #include <components/esm/loadglob.hpp>
#include <components/esm/loadgmst.hpp> #include <components/esm/loadgmst.hpp>
#include <components/esm/loadskil.hpp> #include <components/esm/loadskil.hpp>
#include <components/esm/loadclas.hpp>
#include "idcollection.hpp" #include "idcollection.hpp"
#include "universalid.hpp" #include "universalid.hpp"
@ -22,6 +23,7 @@ namespace CSMWorld
IdCollection<ESM::Global> mGlobals; IdCollection<ESM::Global> mGlobals;
IdCollection<ESM::GameSetting> mGmsts; IdCollection<ESM::GameSetting> mGmsts;
IdCollection<ESM::Skill> mSkills; IdCollection<ESM::Skill> mSkills;
IdCollection<ESM::Class> mClasses;
std::vector<QAbstractItemModel *> mModels; std::vector<QAbstractItemModel *> mModels;
std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex; std::map<UniversalId::Type, QAbstractItemModel *> mModelIndex;

View file

@ -20,6 +20,7 @@ namespace
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings" },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills" },
{ CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Classes, "Classes" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
}; };
@ -29,6 +30,7 @@ namespace
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
}; };

View file

@ -39,7 +39,9 @@ namespace CSMWorld
Type_Gmsts, Type_Gmsts,
Type_Gmst, Type_Gmst,
Type_Skills, Type_Skills,
Type_Skill Type_Skill,
Type_Classes,
Type_Class
}; };
private: private:

View file

@ -90,6 +90,10 @@ void CSVDoc::View::setupWorldMenu()
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView())); connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView()));
world->addAction (skills); world->addAction (skills);
QAction *classes = new QAction (tr ("Classes"), this);
connect (classes, SIGNAL (triggered()), this, SLOT (addClassesSubView()));
world->addAction (classes);
mVerify = new QAction (tr ("&Verify"), this); mVerify = new QAction (tr ("&Verify"), this);
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify())); connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
world->addAction (mVerify); world->addAction (mVerify);
@ -253,6 +257,11 @@ void CSVDoc::View::addSkillsSubView()
addSubView (CSMWorld::UniversalId::Type_Skills); addSubView (CSMWorld::UniversalId::Type_Skills);
} }
void CSVDoc::View::addClassesSubView()
{
addSubView (CSMWorld::UniversalId::Type_Classes);
}
void CSVDoc::View::abortOperation (int type) void CSVDoc::View::abortOperation (int type)
{ {
mDocument->abortOperation (type); mDocument->abortOperation (type);

View file

@ -117,6 +117,8 @@ namespace CSVDoc
void addGmstsSubView(); void addGmstsSubView();
void addSkillsSubView(); void addSkillsSubView();
void addClassesSubView();
}; };
} }

View file

@ -17,6 +17,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
manager.add (CSMWorld::UniversalId::Type_Skills, manager.add (CSMWorld::UniversalId::Type_Skills,
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false)); new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false));
manager.add (CSMWorld::UniversalId::Type_Global, manager.add (CSMWorld::UniversalId::Type_Classes,
new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true)); new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (true));
// manager.add (CSMWorld::UniversalId::Type_Global,
// new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
} }

View file

@ -31,7 +31,7 @@ add_openmw_dir (mwgui
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
merchantrepair repair merchantrepair repair soulgemdialog companionwindow
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue
@ -54,7 +54,7 @@ add_openmw_dir (mwworld
containerstore actiontalk actiontake manualref player cellfunctors failedaction containerstore actiontalk actiontake manualref player cellfunctors failedaction
cells localscripts customdata weather inventorystore ptr actionopen actionread cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp fallback actionrepair esmstore store recordcmp fallback actionrepair actionsoulgem
) )
add_openmw_dir (mwclass add_openmw_dir (mwclass
@ -63,9 +63,9 @@ add_openmw_dir (mwclass
) )
add_openmw_dir (mwmechanics add_openmw_dir (mwmechanics
mechanicsmanagerimp stat character creaturestats magiceffects movement actors activators mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects
drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow
aiescort aiactivate repair pathfinding aiescort aiactivate repair enchanting pathfinding
) )
add_openmw_dir (mwbase add_openmw_dir (mwbase

View file

@ -25,6 +25,8 @@ namespace MWBase
virtual ~DialogueManager() {} virtual ~DialogueManager() {}
virtual bool isInChoice() const = 0;
virtual void startDialogue (const MWWorld::Ptr& actor) = 0; virtual void startDialogue (const MWWorld::Ptr& actor) = 0;
virtual void addTopic (const std::string& topic) = 0; virtual void addTopic (const std::string& topic) = 0;

View file

@ -201,6 +201,7 @@ namespace MWBase
///< Hides dialog and schedules dialog to be deleted. ///< Hides dialog and schedules dialog to be deleted.
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>()) = 0; virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>()) = 0;
virtual void enterPressed () = 0; virtual void enterPressed () = 0;
virtual int readPressedButton() = 0; virtual int readPressedButton() = 0;
///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox)
@ -235,12 +236,16 @@ namespace MWBase
virtual bool getPlayerSleeping() = 0; virtual bool getPlayerSleeping() = 0;
virtual void wakeUpPlayer() = 0; virtual void wakeUpPlayer() = 0;
virtual void showCompanionWindow(MWWorld::Ptr actor) = 0;
virtual void startSpellMaking(MWWorld::Ptr actor) = 0; virtual void startSpellMaking(MWWorld::Ptr actor) = 0;
virtual void startEnchanting(MWWorld::Ptr actor) = 0; virtual void startEnchanting(MWWorld::Ptr actor) = 0;
virtual void startSelfEnchanting(MWWorld::Ptr soulgem) = 0;
virtual void startTraining(MWWorld::Ptr actor) = 0; virtual void startTraining(MWWorld::Ptr actor) = 0;
virtual void startRepair(MWWorld::Ptr actor) = 0; virtual void startRepair(MWWorld::Ptr actor) = 0;
virtual void startRepairItem(MWWorld::Ptr item) = 0; virtual void startRepairItem(MWWorld::Ptr item) = 0;
virtual void showSoulgemDialog (MWWorld::Ptr item) = 0;
virtual void changePointer (const std::string& name) = 0; virtual void changePointer (const std::string& name) = 0;
virtual const Translation::Storage& getTranslationDataStorage() const = 0; virtual const Translation::Storage& getTranslationDataStorage() const = 0;

View file

@ -44,6 +44,11 @@ namespace MWRender
class Animation; class Animation;
} }
namespace MWMechanics
{
class Movement;
}
namespace MWWorld namespace MWWorld
{ {
class Fallback; class Fallback;
@ -54,7 +59,7 @@ namespace MWWorld
class ESMStore; class ESMStore;
class RefData; class RefData;
typedef std::vector<std::pair<MWWorld::Ptr,Ogre::Vector3> > PtrMovementList; typedef std::vector<std::pair<MWWorld::Ptr,MWMechanics::Movement> > PtrMovementList;
} }
namespace MWBase namespace MWBase
@ -244,27 +249,44 @@ namespace MWBase
///< Toggle a render mode. ///< Toggle a render mode.
///< \return Resulting mode ///< \return Resulting mode
virtual const ESM::Potion *createRecord (const ESM::Potion& record) virtual const ESM::Potion *createRecord (const ESM::Potion& record) = 0;
= 0; ///< Create a new record (of type potion) in the ESM store.
///< Create a new recrod (of type potion) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::Spell *createRecord (const ESM::Spell& record) virtual const ESM::Spell *createRecord (const ESM::Spell& record) = 0;
= 0; ///< Create a new record (of type spell) in the ESM store.
///< Create a new recrod (of type spell) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::Class *createRecord (const ESM::Class& record) virtual const ESM::Class *createRecord (const ESM::Class& record) = 0;
= 0; ///< Create a new record (of type class) in the ESM store.
///< Create a new recrod (of type class) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::Cell *createRecord (const ESM::Cell& record) = 0; 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 /// \return pointer to created record
virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0; 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 /// \return pointer to created record
virtual void update (float duration, bool paused) = 0; virtual void update (float duration, bool paused) = 0;

View file

@ -274,6 +274,20 @@ namespace MWClass
return ref->mBase->mEnchant; 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> Armor::use (const MWWorld::Ptr& ptr) const
{ {
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));
@ -291,4 +305,12 @@ namespace MWClass
return MWWorld::Ptr(&cell.mArmors.insert(*ref), &cell); 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;
}
} }

View file

@ -65,11 +65,15 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @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) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const; virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
}; };
} }

View file

@ -147,6 +147,21 @@ namespace MWClass
return ref->mBase->mEnchant; 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 boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
{ {
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr));
@ -160,4 +175,12 @@ namespace MWClass
return MWWorld::Ptr(&cell.mBooks.insert(*ref), &cell); 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;
}
} }

View file

@ -51,10 +51,14 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @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; virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const; virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
}; };
} }

View file

@ -221,6 +221,20 @@ namespace MWClass
return ref->mBase->mEnchant; 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> Clothing::use (const MWWorld::Ptr& ptr) const
{ {
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));
@ -238,4 +252,12 @@ namespace MWClass
return MWWorld::Ptr(&cell.mClothes.insert(*ref), &cell); 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;
}
} }

View file

@ -59,11 +59,15 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @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) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const; virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
}; };
} }

View file

@ -115,7 +115,7 @@ namespace MWClass
if (needKey && hasKey) if (needKey && hasKey)
{ {
MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}", std::vector<std::string>()); MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}");
ptr.getCellRef().mLockLevel = 0; ptr.getCellRef().mLockLevel = 0;
// using a key disarms the trap // using a key disarms the trap
ptr.getCellRef().mTrap = ""; ptr.getCellRef().mTrap = "";

View file

@ -98,7 +98,7 @@ namespace MWClass
if (needKey && hasKey) if (needKey && hasKey)
{ {
MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}", std::vector<std::string>()); MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}");
ptr.getCellRef().mLockLevel = 0; ptr.getCellRef().mLockLevel = 0;
// using a key disarms the trap // using a key disarms the trap
ptr.getCellRef().mTrap = ""; ptr.getCellRef().mTrap = "";

View file

@ -15,6 +15,7 @@
#include "../mwworld/physicssystem.hpp" #include "../mwworld/physicssystem.hpp"
#include "../mwworld/manualref.hpp" #include "../mwworld/manualref.hpp"
#include "../mwworld/nullaction.hpp" #include "../mwworld/nullaction.hpp"
#include "../mwworld/actionsoulgem.hpp"
#include "../mwgui/tooltips.hpp" #include "../mwgui/tooltips.hpp"
@ -23,6 +24,18 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
namespace
{
bool isGold (const MWWorld::Ptr& ptr)
{
return Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_001")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_005")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_010")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_025")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_100");
}
}
namespace MWClass namespace MWClass
{ {
void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -89,7 +102,15 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); 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() void Miscellaneous::registerSelf()
@ -101,25 +122,15 @@ namespace MWClass
std::string Miscellaneous::getUpSoundId (const MWWorld::Ptr& ptr) const std::string Miscellaneous::getUpSoundId (const MWWorld::Ptr& ptr) const
{ {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = if (isGold(ptr))
ptr.get<ESM::Miscellaneous>();
if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGold")->getString())
{
return std::string("Item Gold Up"); return std::string("Item Gold Up");
}
return std::string("Item Misc Up"); return std::string("Item Misc Up");
} }
std::string Miscellaneous::getDownSoundId (const MWWorld::Ptr& ptr) const std::string Miscellaneous::getDownSoundId (const MWWorld::Ptr& ptr) const
{ {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = if (isGold(ptr))
ptr.get<ESM::Miscellaneous>();
if (ref->mBase->mName == MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGold")->getString())
{
return std::string("Item Gold Down"); return std::string("Item Gold Down");
}
return std::string("Item Misc Down"); return std::string("Item Misc Down");
} }
@ -150,12 +161,15 @@ namespace MWClass
int count = ptr.getRefData().getCount(); int count = ptr.getRefData().getCount();
bool isGold = (ref->mBase->mName == store.get<ESM::GameSetting>().find("sGold")->getString()); bool gold = isGold(ptr);
if (isGold && count == 1)
count = ref->mBase->mData.mValue; if (gold && ptr.getCellRef().mGoldValue != 1)
count = ptr.getCellRef().mGoldValue;
else if (gold)
count *= ref->mBase->mData.mValue;
std::string countString; std::string countString;
if (!isGold) if (!gold)
countString = MWGui::ToolTips::getCountString(count); countString = MWGui::ToolTips::getCountString(count);
else // gold displays its count also if it's 1. else // gold displays its count also if it's 1.
countString = " (" + boost::lexical_cast<std::string>(count) + ")"; countString = " (" + boost::lexical_cast<std::string>(count) + ")";
@ -171,10 +185,10 @@ namespace MWClass
std::string text; std::string text;
if (!isGold) if (!gold)
{ {
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
} }
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
@ -195,7 +209,7 @@ namespace MWClass
const MWWorld::ESMStore &store = const MWWorld::ESMStore &store =
MWBase::Environment::get().getWorld()->getStore(); MWBase::Environment::get().getWorld()->getStore();
if (MWWorld::Class::get(ptr).getName(ptr) == store.get<ESM::GameSetting>().find("sGold")->getString()) { if (isGold(ptr)) {
int goldAmount = ptr.getRefData().getCount(); int goldAmount = ptr.getRefData().getCount();
std::string base = "Gold_001"; std::string base = "Gold_001";
@ -214,7 +228,8 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
newRef.getPtr().get<ESM::Miscellaneous>(); newRef.getPtr().get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell); newPtr = MWWorld::Ptr(&cell.mMiscItems.insert(*ref), &cell);
newPtr.getRefData ().setCount(goldAmount); newPtr.getRefData ().setCount(1);
newPtr.getCellRef().mGoldValue = goldAmount;
} else { } else {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
@ -222,4 +237,13 @@ namespace MWClass
} }
return newPtr; return newPtr;
} }
boost::shared_ptr<MWWorld::Action> Miscellaneous::use (const MWWorld::Ptr& ptr) const
{
if (ptr.getCellRef().mSoul == "")
return boost::shared_ptr<MWWorld::Action>(new MWWorld::NullAction());
else
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionSoulgem(ptr));
}
} }

View file

@ -49,6 +49,10 @@ namespace MWClass
///< Return name of inventory icon. ///< Return name of inventory icon.
virtual std::string getModel(const MWWorld::Ptr &ptr) const; 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
}; };
} }

View file

@ -368,7 +368,7 @@ namespace MWClass
moveSpeed = runSpeed; moveSpeed = runSpeed;
else else
moveSpeed = walkSpeed; moveSpeed = walkSpeed;
if(getMovementSettings(ptr).mLeftRight != 0 && getMovementSettings(ptr).mForwardBackward == 0) if(getMovementSettings(ptr).mPosition[0] != 0 && getMovementSettings(ptr).mPosition[1] == 0)
moveSpeed *= 0.75f; moveSpeed *= 0.75f;
return moveSpeed; return moveSpeed;
@ -414,12 +414,22 @@ namespace MWClass
Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
{ {
Ogre::Vector3 vector; MWMechanics::Movement &movement = getMovementSettings(ptr);
vector.x = getMovementSettings(ptr).mLeftRight; Ogre::Vector3 vec(movement.mPosition);
vector.y = getMovementSettings(ptr).mForwardBackward; movement.mPosition[0] = 0.0f;
vector.z = getMovementSettings(ptr).mUpDown; movement.mPosition[1] = 0.0f;
movement.mPosition[2] = 0.0f;
return vec;
}
return vector; Ogre::Vector3 Npc::getRotationVector (const MWWorld::Ptr& ptr) const
{
MWMechanics::Movement &movement = getMovementSettings(ptr);
Ogre::Vector3 vec(movement.mRotation);
movement.mRotation[0] = 0.0f;
movement.mRotation[1] = 0.0f;
movement.mRotation[2] = 0.0f;
return vec;
} }
bool Npc::isEssential (const MWWorld::Ptr& ptr) const bool Npc::isEssential (const MWWorld::Ptr& ptr) const

View file

@ -96,6 +96,9 @@ namespace MWClass
///< Return desired movement vector (determined based on movement settings, ///< Return desired movement vector (determined based on movement settings,
/// stance and stats). /// stance and stats).
virtual Ogre::Vector3 getRotationVector (const MWWorld::Ptr& ptr) const;
///< Return desired rotations, as euler angles.
virtual float getCapacity (const MWWorld::Ptr& ptr) const; virtual float getCapacity (const MWWorld::Ptr& ptr) const;
///< Return total weight that fits into the object. Throws an exception, if the object can't ///< Return total weight that fits into the object. Throws an exception, if the object can't
/// hold other objects. /// hold other objects.

View file

@ -367,6 +367,20 @@ namespace MWClass
return ref->mBase->mEnchant; 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> Weapon::use (const MWWorld::Ptr& ptr) const
{ {
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));
@ -384,4 +398,12 @@ namespace MWClass
return MWWorld::Ptr(&cell.mWeapons.insert(*ref), &cell); 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;
}
} }

View file

@ -65,11 +65,15 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @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) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const; virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
}; };
} }

View file

@ -117,6 +117,8 @@ namespace MWDialogue
void DialogueManager::startDialogue (const MWWorld::Ptr& actor) void DialogueManager::startDialogue (const MWWorld::Ptr& actor)
{ {
mLastTopic = "";
mChoice = -1; mChoice = -1;
mIsInChoice = false; mIsInChoice = false;
@ -127,6 +129,9 @@ namespace MWDialogue
mActorKnownTopics.clear(); mActorKnownTopics.clear();
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->startDialogue(actor, MWWorld::Class::get (actor).getName (actor));
//setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI //setup the list of topics known by the actor. Topics who are also on the knownTopics list will be added to the GUI
updateTopics(); updateTopics();
@ -145,8 +150,6 @@ namespace MWDialogue
{ {
//initialise the GUI //initialise the GUI
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue); MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue);
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->startDialogue(actor, MWWorld::Class::get (actor).getName (actor));
creatureStats.talkedToPlayer(); creatureStats.talkedToPlayer();
@ -160,7 +163,7 @@ namespace MWDialogue
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
executeScript (info->mResultScript); executeScript (info->mResultScript);
mLastTopic = it->mId; mLastTopic = Misc::StringUtils::lowerCase(it->mId);
mLastDialogue = *info; mLastDialogue = *info;
break; break;
} }
@ -398,6 +401,11 @@ namespace MWDialogue
updateTopics(); updateTopics();
} }
bool DialogueManager::isInChoice() const
{
return mIsInChoice;
}
void DialogueManager::goodbyeSelected() void DialogueManager::goodbyeSelected()
{ {
// Do not close the dialogue window if the player has to answer a question // Do not close the dialogue window if the player has to answer a question
@ -424,15 +432,13 @@ namespace MWDialogue
if (mDialogueMap.find(mLastTopic) != mDialogueMap.end()) if (mDialogueMap.find(mLastTopic) != mDialogueMap.end())
{ {
if (mDialogueMap[mLastTopic].mType == ESM::Dialogue::Topic) Filter filter (mActor, mChoice, mTalkedTo);
{
Filter filter (mActor, mChoice, mTalkedTo);
if (mDialogueMap[mLastTopic].mType == ESM::Dialogue::Topic
|| mDialogueMap[mLastTopic].mType == ESM::Dialogue::Greeting)
{
if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic], true)) if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic], true))
{ {
mChoiceMap.clear();
mChoice = -1;
mIsInChoice = false;
std::string text = info->mResponse; std::string text = info->mResponse;
parseText (text); parseText (text);
@ -440,10 +446,12 @@ namespace MWDialogue
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addText (Interpreter::fixDefinesDialog(text, interpreterContext)); MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addText (Interpreter::fixDefinesDialog(text, interpreterContext));
MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId); MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId);
executeScript (info->mResultScript); executeScript (info->mResultScript);
mLastTopic = mLastTopic;
mLastDialogue = *info; mLastDialogue = *info;
} }
} }
mChoiceMap.clear();
mChoice = -1;
mIsInChoice = false;
} }
updateTopics(); updateTopics();

View file

@ -54,6 +54,8 @@ namespace MWDialogue
DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose, Translation::Storage& translationDataStorage); DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose, Translation::Storage& translationDataStorage);
virtual bool isInChoice() const;
virtual void startDialogue (const MWWorld::Ptr& actor); virtual void startDialogue (const MWWorld::Ptr& actor);
virtual void addTopic (const std::string& topic); virtual void addTopic (const std::string& topic);

View file

@ -198,7 +198,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
if (i<script->mData.mNumLongs) if (i<script->mData.mNumLongs)
return select.selectCompare (locals.mLongs[i]); return select.selectCompare (locals.mLongs[i]);
i -= script->mData.mNumShorts; i -= script->mData.mNumLongs;
return select.selectCompare (locals.mFloats.at (i)); return select.selectCompare (locals.mFloats.at (i));
} }

View file

@ -77,40 +77,40 @@ namespace MWGui
if (result == MWMechanics::Alchemy::Result_NoName) if (result == MWMechanics::Alchemy::Result_NoName)
{ {
mWindowManager.messageBox("#{sNotifyMessage37}", std::vector<std::string>()); mWindowManager.messageBox("#{sNotifyMessage37}");
return; return;
} }
// check if mortar & pestle is available (always needed) // check if mortar & pestle is available (always needed)
if (result == MWMechanics::Alchemy::Result_NoMortarAndPestle) if (result == MWMechanics::Alchemy::Result_NoMortarAndPestle)
{ {
mWindowManager.messageBox("#{sNotifyMessage45}", std::vector<std::string>()); mWindowManager.messageBox("#{sNotifyMessage45}");
return; return;
} }
// make sure 2 or more ingredients were selected // make sure 2 or more ingredients were selected
if (result == MWMechanics::Alchemy::Result_LessThanTwoIngredients) if (result == MWMechanics::Alchemy::Result_LessThanTwoIngredients)
{ {
mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector<std::string>()); mWindowManager.messageBox("#{sNotifyMessage6a}");
return; return;
} }
if (result == MWMechanics::Alchemy::Result_NoEffects) if (result == MWMechanics::Alchemy::Result_NoEffects)
{ {
mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>()); mWindowManager.messageBox("#{sNotifyMessage8}");
MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f); MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f);
return; return;
} }
if (result == MWMechanics::Alchemy::Result_Success) if (result == MWMechanics::Alchemy::Result_Success)
{ {
mWindowManager.messageBox("#{sPotionSuccess}", std::vector<std::string>()); mWindowManager.messageBox("#{sPotionSuccess}");
MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f); MWBase::Environment::get().getSoundManager()->playSound("potion success", 1.f, 1.f);
} }
else if (result == MWMechanics::Alchemy::Result_RandomFailure) else if (result == MWMechanics::Alchemy::Result_RandomFailure)
{ {
// potion failed // potion failed
mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>()); mWindowManager.messageBox("#{sNotifyMessage8}");
MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f); MWBase::Environment::get().getSoundManager()->playSound("potion fail", 1.f, 1.f);
} }

View file

@ -0,0 +1,107 @@
#include "companionwindow.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/dialoguemanager.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "messagebox.hpp"
namespace MWGui
{
CompanionWindow::CompanionWindow(MWBase::WindowManager &parWindowManager, DragAndDrop *dragAndDrop, MessageBoxManager* manager)
: ContainerBase(dragAndDrop)
, WindowBase("openmw_companion_window.layout", parWindowManager)
, mMessageBoxManager(manager)
{
MyGUI::ScrollView* itemView;
MyGUI::Widget* containerWidget;
getWidget(containerWidget, "Items");
getWidget(itemView, "ItemView");
setWidgets(containerWidget, itemView);
getWidget(mCloseButton, "CloseButton");
getWidget(mProfitLabel, "ProfitLabel");
getWidget(mEncumbranceBar, "EncumbranceBar");
mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CompanionWindow::onCloseButtonClicked);
setCoord(200,0,600,300);
}
void CompanionWindow::open(MWWorld::Ptr npc)
{
openContainer(npc);
setTitle(MWWorld::Class::get(npc).getName(npc));
drawItems();
updateEncumbranceBar();
}
void CompanionWindow::notifyItemDragged(MWWorld::Ptr item, int count)
{
if (mPtr.getTypeName() == typeid(ESM::NPC).name())
{
MWMechanics::NpcStats& stats = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
stats.modifyProfit(MWWorld::Class::get(item).getValue(item) * count);
}
updateEncumbranceBar();
}
void CompanionWindow::updateEncumbranceBar()
{
float capacity = MWWorld::Class::get(mPtr).getCapacity(mPtr);
float encumbrance = MWWorld::Class::get(mPtr).getEncumbrance(mPtr);
mEncumbranceBar->setValue(encumbrance, capacity);
if (mPtr.getTypeName() != typeid(ESM::NPC).name())
mProfitLabel->setCaption("");
else
{
MWMechanics::NpcStats& stats = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
mProfitLabel->setCaptionWithReplacing("#{sProfitValue} " + boost::lexical_cast<std::string>(stats.getProfit()));
}
}
void CompanionWindow::onWindowResize(MyGUI::Window* window)
{
drawItems();
}
void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender)
{
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && MWWorld::Class::get(mPtr).getNpcStats(mPtr).getProfit() < 0)
{
std::vector<std::string> buttons;
buttons.push_back("#{sCompanionWarningButtonOne}");
buttons.push_back("#{sCompanionWarningButtonTwo}");
mMessageBoxManager->createInteractiveMessageBox("#{sCompanionWarningMessage}", buttons);
mMessageBoxManager->eventButtonPressed += MyGUI::newDelegate(this, &CompanionWindow::onMessageBoxButtonClicked);
}
else
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion);
}
void CompanionWindow::onMessageBoxButtonClicked(int button)
{
if (button == 0)
{
mPtr.getRefData().getLocals().setVarByInt(MWWorld::Class::get(mPtr).getScript(mPtr),
"minimumProfit", MWWorld::Class::get(mPtr).getNpcStats(mPtr).getProfit());
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion);
MWBase::Environment::get().getDialogueManager()->startDialogue (mPtr);
}
}
void CompanionWindow::onReferenceUnavailable()
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion);
}
}

View file

@ -0,0 +1,39 @@
#ifndef OPENMW_MWGUI_COMPANIONWINDOW_H
#define OPENMW_MWGUI_COMPANIONWINDOW_H
#include "container.hpp"
#include "widgets.hpp"
namespace MWGui
{
class MessageBoxManager;
class CompanionWindow : public ContainerBase, public WindowBase
{
public:
CompanionWindow(MWBase::WindowManager& parWindowManager,DragAndDrop* dragAndDrop, MessageBoxManager* manager);
virtual ~CompanionWindow() {}
void open(MWWorld::Ptr npc);
virtual void notifyItemDragged(MWWorld::Ptr item, int count);
protected:
MyGUI::Button* mCloseButton;
MyGUI::TextBox* mProfitLabel;
Widgets::MWDynamicStat* mEncumbranceBar;
MessageBoxManager* mMessageBoxManager;
void onMessageBoxButtonClicked(int button);
void updateEncumbranceBar();
void onWindowResize(MyGUI::Window* window);
void onCloseButtonClicked(MyGUI::Widget* _sender);
virtual void onReferenceUnavailable();
};
}
#endif

View file

@ -68,6 +68,16 @@ namespace
return compareType(left.getTypeName(), right.getTypeName()); 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 != "");
}
} }
@ -130,17 +140,12 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
if (isInventory()) if (isInventory())
{ {
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
// the player is trying to sell an item, check if the merchant accepts it // the player is trying to sell an item, check if the merchant accepts it
// also, don't allow selling gold (let's be better than Morrowind at this, can we?) if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object))
if (!MWBase::Environment::get().getWindowManager()->getTradeWindow()->npcAcceptsItem(object) ||
MWWorld::Class::get(object).getName(object) == gmst.find("sGold")->getString())
{ {
// user notification "i don't buy this item" // user notification "i don't buy this item"
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
messageBox("#{sBarterDialog4}", std::vector<std::string>()); messageBox("#{sBarterDialog4}");
return; return;
} }
} }
@ -284,7 +289,7 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
{ {
// user notification // user notification
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
messageBox("#{sContentsMessage2}", std::vector<std::string>()); messageBox("#{sContentsMessage2}");
return; return;
} }
@ -308,7 +313,7 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
object.getRefData().setCount(origCount); object.getRefData().setCount(origCount);
// user notification // user notification
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
messageBox("#{sContentsMessage3}", std::vector<std::string>()); messageBox("#{sContentsMessage3}");
return; return;
} }
@ -330,6 +335,9 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
drawItems(); drawItems();
mDragAndDrop->mDraggedFrom->drawItems(); mDragAndDrop->mDraggedFrom->drawItems();
mDragAndDrop->mDraggedFrom->notifyItemDragged(object, -mDragAndDrop->mDraggedCount);
notifyItemDragged(object, mDragAndDrop->mDraggedCount);
MWBase::Environment::get().getWindowManager()->setDragDrop(false); MWBase::Environment::get().getWindowManager()->setDragDrop(false);
std::string sound = MWWorld::Class::get(object).getDownSoundId(object); std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
@ -345,7 +353,7 @@ void ContainerBase::onMouseWheel(MyGUI::Widget* _sender, int _rel)
mItemView->setViewOffset(MyGUI::IntPoint(mItemView->getViewOffset().left + _rel*0.3, 0)); mItemView->setViewOffset(MyGUI::IntPoint(mItemView->getViewOffset().left + _rel*0.3, 0));
} }
void ContainerBase::setFilter(ContainerBase::Filter filter) void ContainerBase::setFilter(int filter)
{ {
mFilter = filter; mFilter = filter;
drawItems(); drawItems();
@ -369,29 +377,34 @@ void ContainerBase::drawItems()
int maxHeight = mItemView->getSize().height - 58; int maxHeight = mItemView->getSize().height - 58;
bool onlyMagic = false; bool onlyMagic = false;
bool noMagic = false;
int categories = 0; int categories = 0;
if (mFilter == Filter_All) if (mFilter & Filter_All)
categories = MWWorld::ContainerStore::Type_All; categories |= MWWorld::ContainerStore::Type_All;
else if (mFilter == Filter_Weapon) if (mFilter & Filter_Weapon)
categories = MWWorld::ContainerStore::Type_Weapon; categories |= MWWorld::ContainerStore::Type_Weapon;
else if (mFilter == Filter_Apparel) if (mFilter & Filter_Apparel)
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor; categories |= MWWorld::ContainerStore::Type_Clothing | MWWorld::ContainerStore::Type_Armor;
else if (mFilter == Filter_Magic) if (mFilter & Filter_Magic)
{ {
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor categories |= MWWorld::ContainerStore::Type_Clothing | MWWorld::ContainerStore::Type_Armor
+ MWWorld::ContainerStore::Type_Weapon + MWWorld::ContainerStore::Type_Book | MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Book
+ MWWorld::ContainerStore::Type_Potion; | MWWorld::ContainerStore::Type_Potion;
onlyMagic = true; onlyMagic = true;
} }
else if (mFilter == Filter_Misc) if (mFilter & Filter_Misc)
{ {
categories = MWWorld::ContainerStore::Type_Miscellaneous + MWWorld::ContainerStore::Type_Book categories |= MWWorld::ContainerStore::Type_Miscellaneous | MWWorld::ContainerStore::Type_Book
+ MWWorld::ContainerStore::Type_Ingredient + MWWorld::ContainerStore::Type_Repair | MWWorld::ContainerStore::Type_Ingredient | MWWorld::ContainerStore::Type_Repair
+ MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light | MWWorld::ContainerStore::Type_Lockpick | MWWorld::ContainerStore::Type_Light
+ MWWorld::ContainerStore::Type_Apparatus + MWWorld::ContainerStore::Type_Probe; | MWWorld::ContainerStore::Type_Apparatus | MWWorld::ContainerStore::Type_Probe;
} }
else if (mFilter == Filter_Ingredients) if (mFilter & Filter_Ingredients)
categories = MWWorld::ContainerStore::Type_Ingredient; 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 /// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
@ -466,12 +479,29 @@ void ContainerBase::drawItems()
{ {
const MWWorld::Ptr* iter = &((*it).first); 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(); int displayCount = iter->getRefData().getCount();
if (mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop && *iter == *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>()) if (mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop && *iter == *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>())
{ {
displayCount -= mDragAndDrop->mDraggedCount; 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\\"); std::string path = std::string("icons\\");
path += MWWorld::Class::get(*iter).getInventoryIcon(*iter); path += MWWorld::Class::get(*iter).getInventoryIcon(*iter);

View file

@ -48,16 +48,17 @@ namespace MWGui
ContainerBase(DragAndDrop* dragAndDrop); ContainerBase(DragAndDrop* dragAndDrop);
virtual ~ContainerBase(); virtual ~ContainerBase();
enum Filter // basic types (inclusive)
{ static const int Filter_All = (1<<0);
Filter_All = 0x01, static const int Filter_Weapon = (1<<1);
Filter_Weapon = 0x02, static const int Filter_Apparel = (1<<2);
Filter_Apparel = 0x03, static const int Filter_Ingredients = (1<<3);
Filter_Magic = 0x04, static const int Filter_Misc = (1<<4);
Filter_Misc = 0x05,
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 enum ItemState
{ {
@ -78,9 +79,13 @@ namespace MWGui
MWWorld::ContainerStore& getBoughtItems() { return mBoughtItems; } MWWorld::ContainerStore& getBoughtItems() { return mBoughtItems; }
void openContainer(MWWorld::Ptr container); void openContainer(MWWorld::Ptr container);
void setFilter(Filter filter); ///< set category filter void setFilter(int filter); ///< set category filter
void drawItems(); void drawItems();
/// fired when an item was moved by drag&drop. \n
/// if it was removed from this container, count will be negative.
virtual void notifyItemDragged(MWWorld::Ptr item, int count) {}
protected: protected:
bool mDisplayEquippedItems; bool mDisplayEquippedItems;
bool mHighlightEquippedItems; bool mHighlightEquippedItems;
@ -92,7 +97,7 @@ namespace MWGui
DragAndDrop* mDragAndDrop; 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. // bought items are put in a separate ContainerStore so that they don't stack with other (not bought) items.
MWWorld::ContainerStore mBoughtItems; MWWorld::ContainerStore mBoughtItems;

View file

@ -228,7 +228,8 @@ void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
void DialogueWindow::onSelectTopic(const std::string& topic, int id) void DialogueWindow::onSelectTopic(const std::string& topic, int id)
{ {
if (!mEnabled) return; if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
return;
int separatorPos = 0; int separatorPos = 0;
for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i) for (unsigned int i=0; i<mTopicsList->getItemCount(); ++i)
@ -248,6 +249,11 @@ void DialogueWindow::onSelectTopic(const std::string& topic, int id)
{ {
mPersuasionDialog.setVisible(true); mPersuasionDialog.setVisible(true);
} }
else if (topic == gmst.find("sCompanionShare")->getString())
{
mWindowManager.pushGuiMode(GM_Companion);
mWindowManager.showCompanionWindow(mPtr);
}
else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused()) else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused())
{ {
if (topic == gmst.find("sBarter")->getString()) if (topic == gmst.find("sBarter")->getString())
@ -306,7 +312,10 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{ {
mTopicsList->clear(); mTopicsList->clear();
bool anyService = mServices > 0; bool isCompanion = !MWWorld::Class::get(mPtr).getScript(mPtr).empty()
&& mPtr.getRefData().getLocals().getIntVar(MWWorld::Class::get(mPtr).getScript(mPtr), "companion");
bool anyService = mServices > 0 || isCompanion || mPtr.getTypeName() == typeid(ESM::NPC).name();
const MWWorld::Store<ESM::GameSetting> &gmst = const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>(); MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
@ -326,8 +335,8 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
if (mServices & Service_CreateSpells) if (mServices & Service_CreateSpells)
mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString()); mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString());
// if (mServices & Service_Enchant) if (mServices & Service_Enchant)
// mTopicsList->addItem(gmst.find("sEnchanting")->getString()); mTopicsList->addItem(gmst.find("sEnchanting")->getString());
if (mServices & Service_Training) if (mServices & Service_Training)
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString()); mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
@ -335,9 +344,13 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
if (mServices & Service_Repair) if (mServices & Service_Repair)
mTopicsList->addItem(gmst.find("sRepair")->getString()); mTopicsList->addItem(gmst.find("sRepair")->getString());
if (anyService || mPtr.getTypeName() == typeid(ESM::NPC).name()) if (isCompanion)
mTopicsList->addItem(gmst.find("sCompanionShare")->getString());
if (anyService)
mTopicsList->addSeparator(); mTopicsList->addSeparator();
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it) for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
{ {
mTopicsList->addItem(*it); mTopicsList->addItem(*it);

View file

@ -1,5 +1,15 @@
#include "enchantingdialog.hpp" #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 namespace MWGui
{ {
@ -8,19 +18,71 @@ namespace MWGui
EnchantingDialog::EnchantingDialog(MWBase::WindowManager &parWindowManager) EnchantingDialog::EnchantingDialog(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_enchanting_dialog.layout", parWindowManager) : WindowBase("openmw_enchanting_dialog.layout", parWindowManager)
, EffectEditorBase(parWindowManager) , EffectEditorBase(parWindowManager)
, mItemSelectionDialog(NULL)
, mEnchanting(MWBase::Environment::get().getWorld()->getPlayer().getPlayer())
{ {
getWidget(mName, "NameEdit");
getWidget(mCancelButton, "CancelButton"); getWidget(mCancelButton, "CancelButton");
getWidget(mAvailableEffectsList, "AvailableEffects"); getWidget(mAvailableEffectsList, "AvailableEffects");
getWidget(mUsedEffectsView, "UsedEffects"); 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); setWidgets(mAvailableEffectsList, mUsedEffectsView);
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onCancelButtonClicked); 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() void EnchantingDialog::open()
{ {
center(); 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) void EnchantingDialog::startEnchanting (MWWorld::Ptr actor)
@ -30,6 +92,11 @@ namespace MWGui
startEditing (); startEditing ();
} }
void EnchantingDialog::startSelfEnchanting(MWWorld::Ptr soulgem)
{
/// \todo
}
void EnchantingDialog::onReferenceUnavailable () void EnchantingDialog::onReferenceUnavailable ()
{ {
mWindowManager.removeGuiMode (GM_Dialogue); mWindowManager.removeGuiMode (GM_Dialogue);
@ -40,4 +107,165 @@ namespace MWGui
{ {
mWindowManager.removeGuiMode (GM_Enchanting); 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}");
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}");
return;
}
if (mName->getCaption ().empty())
{
mWindowManager.messageBox ("#{sNotifyMessage10}");
return;
}
if (boost::lexical_cast<int>(mPrice->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold())
{
mWindowManager.messageBox ("#{sNotifyMessage18}");
return;
}
if (mEnchanting.soulEmpty())
{
mWindowManager.messageBox ("#{sNotifyMessage52}");
return;
}
if (mEnchanting.itemEmpty())
{
mWindowManager.messageBox ("#{sNotifyMessage11}");
return;
}
if (mEnchanting.getEnchantCost() > mEnchanting.getMaxEnchantValue())
{
mWindowManager.messageBox ("#{sNotifyMessage29}");
return;
}
mEnchanting.setNewItemName(mName->getCaption());
mEnchanting.setEffect(mEffectList);
mEnchanting.create();
mWindowManager.messageBox ("#{sEnchantmentMenu12}");
mWindowManager.removeGuiMode (GM_Enchanting);
}
} }

View file

@ -7,23 +7,58 @@
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwmechanics/enchanting.hpp"
namespace MWGui namespace MWGui
{ {
class ItemSelectionDialog;
class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase
{ {
public: public:
EnchantingDialog(MWBase::WindowManager& parWindowManager); EnchantingDialog(MWBase::WindowManager& parWindowManager);
virtual ~EnchantingDialog();
virtual void open(); virtual void open();
void startEnchanting(MWWorld::Ptr actor); void startEnchanting(MWWorld::Ptr actor);
void startSelfEnchanting(MWWorld::Ptr soulgem);
protected: protected:
virtual void onReferenceUnavailable(); virtual void onReferenceUnavailable();
virtual void notifyEffectsChanged ();
void onCancelButtonClicked(MyGUI::Widget* sender); 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::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;
}; };
} }

View file

@ -234,7 +234,8 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender)
mDragAndDrop->mDraggedWidget = 0; mDragAndDrop->mDraggedWidget = 0;
MWBase::Environment::get().getWindowManager()->setDragDrop(false); MWBase::Environment::get().getWindowManager()->setDragDrop(false);
MWBase::Environment::get().getWindowManager()->getInventoryWindow()->drawItems(); mDragAndDrop->mDraggedFrom->drawItems();
mDragAndDrop->mDraggedFrom->notifyItemDragged(object, -mDragAndDrop->mDraggedCount);
} }
else else
{ {

View file

@ -43,7 +43,6 @@ namespace MWGui
getWidget(mAvatar, "Avatar"); getWidget(mAvatar, "Avatar");
getWidget(mAvatarImage, "AvatarImage"); getWidget(mAvatarImage, "AvatarImage");
getWidget(mEncumbranceBar, "EncumbranceBar"); getWidget(mEncumbranceBar, "EncumbranceBar");
getWidget(mEncumbranceText, "EncumbranceBarT");
getWidget(mFilterAll, "AllButton"); getWidget(mFilterAll, "AllButton");
getWidget(mFilterWeapon, "WeaponButton"); getWidget(mFilterWeapon, "WeaponButton");
getWidget(mFilterApparel, "ApparelButton"); getWidget(mFilterApparel, "ApparelButton");
@ -240,9 +239,7 @@ namespace MWGui
float capacity = MWWorld::Class::get(player).getCapacity(player); float capacity = MWWorld::Class::get(player).getCapacity(player);
float encumbrance = MWWorld::Class::get(player).getEncumbrance(player); float encumbrance = MWWorld::Class::get(player).getEncumbrance(player);
mEncumbranceBar->setProgressRange(capacity); mEncumbranceBar->setValue(encumbrance, capacity);
mEncumbranceBar->setProgressPosition(encumbrance);
mEncumbranceText->setCaption( boost::lexical_cast<std::string>(int(encumbrance)) + "/" + boost::lexical_cast<std::string>(int(capacity)) );
} }
void InventoryWindow::onFrame() void InventoryWindow::onFrame()

View file

@ -5,6 +5,7 @@
#include "container.hpp" #include "container.hpp"
#include "window_pinnable_base.hpp" #include "window_pinnable_base.hpp"
#include "widgets.hpp"
namespace MWGui namespace MWGui
{ {
@ -36,8 +37,7 @@ namespace MWGui
MyGUI::Widget* mAvatar; MyGUI::Widget* mAvatar;
MyGUI::ImageBox* mAvatarImage; MyGUI::ImageBox* mAvatarImage;
MyGUI::TextBox* mArmorRating; MyGUI::TextBox* mArmorRating;
MyGUI::ProgressBar* mEncumbranceBar; Widgets::MWDynamicStat* mEncumbranceBar;
MyGUI::TextBox* mEncumbranceText;
MyGUI::Widget* mLeftPane; MyGUI::Widget* mLeftPane;
MyGUI::Widget* mRightPane; MyGUI::Widget* mRightPane;

View file

@ -3,7 +3,7 @@
namespace MWGui 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) : ContainerBase(NULL)
, WindowModal("openmw_itemselection_dialog.layout", parWindowManager) , WindowModal("openmw_itemselection_dialog.layout", parWindowManager)
{ {

View file

@ -8,7 +8,7 @@ namespace MWGui
class ItemSelectionDialog : public ContainerBase, public WindowModal class ItemSelectionDialog : public ContainerBase, public WindowModal
{ {
public: 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::CMultiDelegate0 EventHandle_Void;
typedef MyGUI::delegates::CMultiDelegate1<MWWorld::Ptr> EventHandle_Item; typedef MyGUI::delegates::CMultiDelegate1<MWWorld::Ptr> EventHandle_Item;

View file

@ -162,7 +162,7 @@ namespace MWGui
MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player);
if (mSpentAttributes.size() < 3) if (mSpentAttributes.size() < 3)
MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage36}", std::vector<std::string>()); MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage36}");
else else
{ {
// increase attributes // increase attributes

View file

@ -3,6 +3,7 @@
#include "messagebox.hpp" #include "messagebox.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwbase/inputmanager.hpp"
using namespace MWGui; using namespace MWGui;
@ -62,7 +63,8 @@ void MessageBoxManager::onFrame (float frameDuration)
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
delete mInterMessageBoxe; delete mInterMessageBoxe;
mInterMessageBoxe = NULL; mInterMessageBoxe = NULL;
mWindowManager->removeGuiMode(GM_InterMessageBox); MWBase::Environment::get().getInputManager()->changeInputMode(
MWBase::Environment::get().getWindowManager()->isGuiMode());
} }
} }
@ -90,11 +92,8 @@ void MessageBoxManager::createMessageBox (const std::string& message)
bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons) bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons)
{ {
/// \todo Don't write this kind of error message to cout. Either discard the old message box
/// silently or throw an exception.
if(mInterMessageBoxe != NULL) { if(mInterMessageBoxe != NULL) {
std::cout << "there is a MessageBox already" << std::endl; throw std::runtime_error("There is a message box already");
return false;
} }
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons); mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
@ -139,7 +138,8 @@ void MessageBoxManager::setMessageBoxSpeed (int speed)
void MessageBoxManager::enterPressed () void MessageBoxManager::enterPressed ()
{ {
mInterMessageBoxe->enterPressed(); if(mInterMessageBoxe != NULL)
mInterMessageBoxe->enterPressed();
} }
int MessageBoxManager::readPressedButton () int MessageBoxManager::readPressedButton ()
@ -213,10 +213,12 @@ int MessageBox::getHeight ()
InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons) InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons)
: Layout("openmw_interactive_messagebox.layout") : WindowModal("openmw_interactive_messagebox.layout", *MWBase::Environment::get().getWindowManager())
, mMessageBoxManager(parMessageBoxManager) , mMessageBoxManager(parMessageBoxManager)
, mButtonPressed(-1) , mButtonPressed(-1)
{ {
WindowModal::open();
int fixedWidth = 500; int fixedWidth = 500;
int textPadding = 10; // padding between text-widget and main-widget int textPadding = 10; // padding between text-widget and main-widget
int textButtonPadding = 20; // padding between the text-widget und the button-widget int textButtonPadding = 20; // padding between the text-widget und the button-widget
@ -232,7 +234,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
getWidget(mButtonsWidget, "buttons"); getWidget(mButtonsWidget, "buttons");
mMessageWidget->setOverflowToTheLeft(true); mMessageWidget->setOverflowToTheLeft(true);
mMessageWidget->addText(message); mMessageWidget->setCaptionWithReplacing(message);
MyGUI::IntSize textSize = mMessageWidget->getTextSize(); MyGUI::IntSize textSize = mMessageWidget->getTextSize();
@ -252,7 +254,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
std::string("MW_Button"), std::string("MW_Button"),
dummyCoord, dummyCoord,
MyGUI::Align::Default); MyGUI::Align::Default);
button->setCaption(*it); button->setCaptionWithReplacing(*it);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed); button->eventMouseButtonClick += MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed);
@ -399,6 +401,7 @@ void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed)
if(*button == pressed) if(*button == pressed)
{ {
mButtonPressed = index; mButtonPressed = index;
mMessageBoxManager.onButtonPressed(mButtonPressed);
return; return;
} }
index++; index++;

View file

@ -44,6 +44,13 @@ namespace MWGui
void enterPressed(); void enterPressed();
int readPressedButton (); int readPressedButton ();
typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_Int;
// Note: this delegate unassigns itself after it was fired, i.e. works once.
EventHandle_Int eventButtonPressed;
void onButtonPressed(int button) { eventButtonPressed(button); eventButtonPressed.clear(); }
MWBase::WindowManager *mWindowManager; MWBase::WindowManager *mWindowManager;
private: private:
@ -73,7 +80,7 @@ namespace MWGui
int mNextBoxPadding; int mNextBoxPadding;
}; };
class InteractiveMessageBox : public OEngine::GUI::Layout class InteractiveMessageBox : public WindowModal
{ {
public: public:
InteractiveMessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons); InteractiveMessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons);

View file

@ -5,9 +5,11 @@ namespace MWGui
{ {
enum GuiMode enum GuiMode
{ {
GM_None,
GM_Settings, // Settings window GM_Settings, // Settings window
GM_Inventory, // Inventory mode GM_Inventory, // Inventory mode
GM_Container, GM_Container,
GM_Companion,
GM_MainMenu, // Main menu mode GM_MainMenu, // Main menu mode
GM_Console, // Console mode GM_Console, // Console mode
@ -41,9 +43,6 @@ namespace MWGui
GM_ClassCreate, GM_ClassCreate,
GM_Review, GM_Review,
// interactive MessageBox
GM_InterMessageBox,
GM_Loading, GM_Loading,
GM_LoadingWallpaper, GM_LoadingWallpaper,

View file

@ -291,7 +291,7 @@ namespace MWGui
if (item.getRefData ().getCount() == 0) if (item.getRefData ().getCount() == 0)
{ {
MWBase::Environment::get().getWindowManager ()->messageBox ( MWBase::Environment::get().getWindowManager ()->messageBox (
"#{sQuickMenu5} " + MWWorld::Class::get(item).getName(item), std::vector<std::string>()); "#{sQuickMenu5} " + MWWorld::Class::get(item).getName(item));
return; return;
} }
@ -317,7 +317,7 @@ namespace MWGui
if (item.getRefData ().getCount() == 0) if (item.getRefData ().getCount() == 0)
{ {
MWBase::Environment::get().getWindowManager ()->messageBox ( MWBase::Environment::get().getWindowManager ()->messageBox (
"#{sQuickMenu5} " + MWWorld::Class::get(item).getName(item), std::vector<std::string>()); "#{sQuickMenu5} " + MWWorld::Class::get(item).getName(item));
return; return;
} }

View file

@ -19,6 +19,49 @@
using namespace MWGui; using namespace MWGui;
using namespace Widgets; using namespace Widgets;
namespace
{
int wrap(int index, int max)
{
if (index < 0)
return max - 1;
else if (index >= max)
return 0;
else
return index;
}
int countParts(const std::string &part, const std::string &race, bool male)
{
/// \todo loop through the whole store for appropriate bodyparts instead of looking for fixed IDs
const MWWorld::Store<ESM::BodyPart> &store =
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
std::string prefix =
"b_n_" + race + ((male) ? "_m_" : "_f_") + part;
std::string suffix;
suffix.reserve(prefix.size() + 3);
int count = -1;
do {
++count;
suffix = "_" + (boost::format("%02d") % (count + 1)).str();
}
while (store.search(prefix + suffix) != 0);
if (count == 0 && part == "hair") {
count = -1;
do {
++count;
suffix = (boost::format("%02d") % (count + 1)).str();
}
while (store.search(prefix + suffix) != 0);
}
return count;
}
}
RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager) RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
: WindowModal("openmw_chargen_race.layout", parWindowManager) : WindowModal("openmw_chargen_race.layout", parWindowManager)
, mGenderIndex(0) , mGenderIndex(0)
@ -144,45 +187,6 @@ void RaceDialog::setRaceId(const std::string &raceId)
updateSpellPowers(); updateSpellPowers();
} }
int wrap(int index, int max)
{
if (index < 0)
return max - 1;
else if (index >= max)
return 0;
else
return index;
}
int countParts(const std::string &part, const std::string &race, bool male)
{
const MWWorld::Store<ESM::BodyPart> &store =
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
std::string prefix =
"b_n_" + race + ((male) ? "_m_" : "_f_") + part;
std::string suffix;
suffix.reserve(prefix.size() + 3);
int count = -1;
do {
++count;
suffix = "_" + (boost::format("%02d") % (count + 1)).str();
}
while (store.search(prefix + suffix) != 0);
if (count == 0 && part == "hair") {
count = -1;
do {
++count;
suffix = (boost::format("%02d") % (count + 1)).str();
}
while (store.search(prefix + suffix) != 0);
}
return count;
}
void RaceDialog::close() void RaceDialog::close()
{ {
delete mPreview; delete mPreview;
@ -229,28 +233,67 @@ void RaceDialog::onSelectNextGender(MyGUI::Widget*)
void RaceDialog::onSelectPreviousFace(MyGUI::Widget*) void RaceDialog::onSelectPreviousFace(MyGUI::Widget*)
{ {
mFaceIndex = wrap(mFaceIndex - 1, mFaceCount); do
mFaceIndex = wrap(mFaceIndex - 1, mFaceCount);
while (!isFacePlayable());
updatePreview(); updatePreview();
} }
void RaceDialog::onSelectNextFace(MyGUI::Widget*) void RaceDialog::onSelectNextFace(MyGUI::Widget*)
{ {
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount); do
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
while (!isFacePlayable());
updatePreview(); updatePreview();
} }
void RaceDialog::onSelectPreviousHair(MyGUI::Widget*) void RaceDialog::onSelectPreviousHair(MyGUI::Widget*)
{ {
mHairIndex = wrap(mHairIndex - 1, mHairCount); do
mHairIndex = wrap(mHairIndex - 1, mHairCount);
while (!isHairPlayable());
updatePreview(); updatePreview();
} }
void RaceDialog::onSelectNextHair(MyGUI::Widget*) void RaceDialog::onSelectNextHair(MyGUI::Widget*)
{ {
mHairIndex = wrap(mHairIndex + 1, mHairCount); do
mHairIndex = wrap(mHairIndex + 1, mHairCount);
while (!isHairPlayable());
updatePreview(); updatePreview();
} }
bool RaceDialog::isFacePlayable()
{
std::string prefix =
"b_n_" + mCurrentRaceId + ((mGenderIndex == 0) ? "_m_" : "_f_");
std::string headIndex = (boost::format("%02d") % (mFaceIndex + 1)).str();
const MWWorld::Store<ESM::BodyPart> &parts =
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
if (parts.search(prefix + "head_" + headIndex) == 0)
return !(parts.find(prefix + "head" + headIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
else
return !(parts.find(prefix + "head_" + headIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
}
bool RaceDialog::isHairPlayable()
{
std::string prefix =
"b_n_" + mCurrentRaceId + ((mGenderIndex == 0) ? "_m_" : "_f_");
std::string hairIndex = (boost::format("%02d") % (mHairIndex + 1)).str();
const MWWorld::Store<ESM::BodyPart> &parts =
MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>();
if (parts.search(prefix + "hair_" + hairIndex) == 0)
return !(parts.find(prefix + "hair" + hairIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
else
return !(parts.find(prefix + "hair_" + hairIndex)->mData.mFlags & ESM::BodyPart::BPF_NotPlayable);
}
void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index) void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
{ {
if (_index == MyGUI::ITEM_NONE) if (_index == MyGUI::ITEM_NONE)
@ -273,11 +316,16 @@ void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index)
void RaceDialog::recountParts() void RaceDialog::recountParts()
{ {
mFaceCount = countParts("head", mCurrentRaceId, mGenderIndex == 0);
mHairCount = countParts("hair", mCurrentRaceId, mGenderIndex == 0);
mFaceIndex = 0; mFaceIndex = 0;
mHairIndex = 0; mHairIndex = 0;
mFaceCount = countParts("head", mCurrentRaceId, mGenderIndex == 0); while (!isHairPlayable())
mHairCount = countParts("hair", mCurrentRaceId, mGenderIndex == 0); mHairIndex = wrap(mHairIndex + 1, mHairCount);
while (!isFacePlayable())
mFaceIndex = wrap(mFaceIndex + 1, mFaceCount);
} }
// update widget content // update widget content

View file

@ -81,6 +81,9 @@ namespace MWGui
void updatePreview(); void updatePreview();
void recountParts(); void recountParts();
bool isHairPlayable();
bool isFacePlayable();
MyGUI::ImageBox* mPreviewImage; MyGUI::ImageBox* mPreviewImage;
MyGUI::ListBox* mRaceList; MyGUI::ListBox* mRaceList;
MyGUI::ScrollBar* mHeadRotate; MyGUI::ScrollBar* mHeadRotate;

View file

@ -26,7 +26,10 @@ namespace MWGui
// check if player has changed cell, or count of the reference has become 0 // check if player has changed cell, or count of the reference has become 0
if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL) if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL)
|| mPtr.getRefData().getCount() == 0) || mPtr.getRefData().getCount() == 0)
{
mPtr = MWWorld::Ptr();
onReferenceUnavailable(); onReferenceUnavailable();
}
mCurrentPlayerCell = playerCell; mCurrentPlayerCell = playerCell;
} }

View file

@ -362,7 +362,7 @@ namespace MWGui
{ {
std::string msg = "This resolution is not supported in Fullscreen mode. Please select a resolution from the list."; std::string msg = "This resolution is not supported in Fullscreen mode. Please select a resolution from the list.";
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
messageBox(msg, std::vector<std::string>()); messageBox(msg);
_sender->castType<MyGUI::Button>()->setCaption(off); _sender->castType<MyGUI::Button>()->setCaption(off);
} }
else else
@ -593,7 +593,7 @@ namespace MWGui
static_cast<MyGUI::Button*>(_sender)->setCaptionWithReplacing("#{sNone}"); static_cast<MyGUI::Button*>(_sender)->setCaptionWithReplacing("#{sNone}");
MWBase::Environment::get().getWindowManager ()->messageBox ("#{sControlsMenu3}", std::vector<std::string>()); MWBase::Environment::get().getWindowManager ()->messageBox ("#{sControlsMenu3}");
MWBase::Environment::get().getWindowManager ()->disallowMouse(); MWBase::Environment::get().getWindowManager ()->disallowMouse();
MWBase::Environment::get().getInputManager ()->enableDetectingBindingMode (actionId); MWBase::Environment::get().getInputManager ()->enableDetectingBindingMode (actionId);

View file

@ -0,0 +1,34 @@
#include "soulgemdialog.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
#include "messagebox.hpp"
namespace MWGui
{
void SoulgemDialog::show(const MWWorld::Ptr &soulgem)
{
mSoulgem = soulgem;
std::vector<std::string> buttons;
buttons.push_back("#{sRechargeEnchantment}");
buttons.push_back("#{sMake Enchantment}");
mManager->createInteractiveMessageBox("#{sDoYouWantTo}", buttons);
mManager->eventButtonPressed += MyGUI::newDelegate(this, &SoulgemDialog::onButtonPressed);
}
void SoulgemDialog::onButtonPressed(int button)
{
if (button == 0)
{
/// \todo show recharge enchanted item dialog here
}
else
{
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Enchanting);
MWBase::Environment::get().getWindowManager()->startSelfEnchanting(mSoulgem);
}
}
}

View file

@ -0,0 +1,28 @@
#ifndef OPENMW_MWGUI_SOULGEMDIALOG_H
#define OPENMW_MWGUI_SOULGEMDIALOG_H
#include "../mwworld/ptr.hpp"
namespace MWGui
{
class MessageBoxManager;
class SoulgemDialog
{
public:
SoulgemDialog (MessageBoxManager* manager)
: mManager(manager) {}
void show (const MWWorld::Ptr& soulgem);
void onButtonPressed(int button);
private:
MessageBoxManager* mManager;
MWWorld::Ptr mSoulgem;
};
}
#endif

View file

@ -72,6 +72,7 @@ namespace MWGui
mMagnitudeMaxSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMaxChanged); mMagnitudeMaxSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMaxChanged);
mDurationSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onDurationChanged); mDurationSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onDurationChanged);
mAreaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onAreaChanged); mAreaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onAreaChanged);
constantEffect=false;
} }
void EditEffectDialog::open() void EditEffectDialog::open()
@ -164,7 +165,7 @@ namespace MWGui
mMagnitudeBox->setVisible (true); mMagnitudeBox->setVisible (true);
curY += mMagnitudeBox->getSize().height; 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->setPosition(mDurationBox->getPosition().left, curY);
mDurationBox->setVisible (true); mDurationBox->setVisible (true);
@ -309,25 +310,25 @@ namespace MWGui
{ {
if (mEffects.size() <= 0) if (mEffects.size() <= 0)
{ {
mWindowManager.messageBox ("#{sNotifyMessage30}", std::vector<std::string>()); mWindowManager.messageBox ("#{sNotifyMessage30}");
return; return;
} }
if (mNameEdit->getCaption () == "") if (mNameEdit->getCaption () == "")
{ {
mWindowManager.messageBox ("#{sNotifyMessage10}", std::vector<std::string>()); mWindowManager.messageBox ("#{sNotifyMessage10}");
return; return;
} }
if (mMagickaCost->getCaption() == "0") if (mMagickaCost->getCaption() == "0")
{ {
mWindowManager.messageBox ("#{sEnchantmentMenu8}", std::vector<std::string>()); mWindowManager.messageBox ("#{sEnchantmentMenu8}");
return; return;
} }
if (boost::lexical_cast<int>(mPriceLabel->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold()) if (boost::lexical_cast<int>(mPriceLabel->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold())
{ {
mWindowManager.messageBox ("#{sNotifyMessage18}", std::vector<std::string>()); mWindowManager.messageBox ("#{sNotifyMessage18}");
return; return;
} }
@ -516,7 +517,7 @@ namespace MWGui
{ {
if (mEffects.size() >= 8) if (mEffects.size() >= 8)
{ {
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage28}", std::vector<std::string>()); MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage28}");
return; return;
} }
@ -527,7 +528,7 @@ namespace MWGui
{ {
if (it->mEffectID == effectId) if (it->mEffectID == effectId)
{ {
MWBase::Environment::get().getWindowManager()->messageBox ("#{sOnetypeEffectMessage}", std::vector<std::string>()); MWBase::Environment::get().getWindowManager()->messageBox ("#{sOnetypeEffectMessage}");
return; return;
} }
} }

View file

@ -24,7 +24,7 @@ namespace MWGui
void newEffect (const ESM::MagicEffect* effect); void newEffect (const ESM::MagicEffect* effect);
void editEffect (ESM::ENAMstruct effect); void editEffect (ESM::ENAMstruct effect);
bool constantEffect;
typedef MyGUI::delegates::CMultiDelegate1<ESM::ENAMstruct> EventHandle_Effect; typedef MyGUI::delegates::CMultiDelegate1<ESM::ENAMstruct> EventHandle_Effect;
EventHandle_Effect eventEffectAdded; EventHandle_Effect eventEffectAdded;
@ -69,7 +69,6 @@ namespace MWGui
void onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos); void onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos);
void onDurationChanged (MyGUI::ScrollBar* sender, size_t pos); void onDurationChanged (MyGUI::ScrollBar* sender, size_t pos);
void onAreaChanged (MyGUI::ScrollBar* sender, size_t pos); void onAreaChanged (MyGUI::ScrollBar* sender, size_t pos);
void setMagicEffect(const ESM::MagicEffect* effect); void setMagicEffect(const ESM::MagicEffect* effect);
void updateBoxes(); void updateBoxes();

View file

@ -139,12 +139,13 @@ namespace MWGui
} }
} }
parent->setVisible(effects.size() != 0);
int w=2; int w=2;
if (adjustSize) if (adjustSize)
{ {
int s = effects.size() * 16+4; int s = effects.size() * 16+4;
if (!effects.size())
s = 0;
int diff = parent->getWidth() - s; int diff = parent->getWidth() - s;
parent->setSize(s, parent->getHeight()); parent->setSize(s, parent->getHeight());
parent->setPosition(parent->getLeft()+diff, parent->getTop()); parent->setPosition(parent->getLeft()+diff, parent->getTop());

View file

@ -404,7 +404,7 @@ namespace MWGui
if (spell->mData.mFlags & ESM::Spell::F_Always if (spell->mData.mFlags & ESM::Spell::F_Always
|| spell->mData.mType == ESM::Spell::ST_Power) || spell->mData.mType == ESM::Spell::ST_Power)
{ {
mWindowManager.messageBox("#{sDeleteSpellError}", std::vector<std::string>()); mWindowManager.messageBox("#{sDeleteSpellError}");
} }
else else
{ {

View file

@ -50,7 +50,7 @@ void TextInputDialog::onOkClicked(MyGUI::Widget* _sender)
{ {
if (mTextEdit->getCaption() == "") if (mTextEdit->getCaption() == "")
{ {
mWindowManager.messageBox ("#{sNotifyMessage37}", std::vector<std::string>()); mWindowManager.messageBox ("#{sNotifyMessage37}");
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit); MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit);
} }
else else
@ -61,7 +61,7 @@ void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender)
{ {
if (mTextEdit->getCaption() == "") if (mTextEdit->getCaption() == "")
{ {
mWindowManager.messageBox ("#{sNotifyMessage37}", std::vector<std::string>()); mWindowManager.messageBox ("#{sNotifyMessage37}");
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit); MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit);
} }
else else

View file

@ -129,13 +129,10 @@ namespace MWGui
MWWorld::Ptr gold; MWWorld::Ptr gold;
MWWorld::ContainerStore& playerStore = mWindowManager.getInventoryWindow()->getContainerStore(); MWWorld::ContainerStore& playerStore = mWindowManager.getInventoryWindow()->getContainerStore();
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
for (MWWorld::ContainerStoreIterator it = playerStore.begin(); for (MWWorld::ContainerStoreIterator it = playerStore.begin();
it != playerStore.end(); ++it) it != playerStore.end(); ++it)
{ {
if (MWWorld::Class::get(*it).getName(*it) == gmst.find("sGold")->getString()) if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, "gold_001"))
{ {
goldFound = true; goldFound = true;
gold = *it; gold = *it;
@ -181,7 +178,7 @@ namespace MWGui
{ {
// user notification // user notification
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
messageBox("#{sBarterDialog11}", std::vector<std::string>()); messageBox("#{sBarterDialog11}");
return; return;
} }
@ -190,7 +187,7 @@ namespace MWGui
{ {
// user notification // user notification
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
messageBox("#{sBarterDialog1}", std::vector<std::string>()); messageBox("#{sBarterDialog1}");
return; return;
} }
@ -199,7 +196,7 @@ namespace MWGui
{ {
// user notification // user notification
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
messageBox("#{sBarterDialog2}", std::vector<std::string>()); messageBox("#{sBarterDialog2}");
return; return;
} }
@ -209,7 +206,7 @@ namespace MWGui
if (mPtr.getTypeName() != typeid(ESM::NPC).name()) if (mPtr.getTypeName() != typeid(ESM::NPC).name())
{ {
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
messageBox("#{sNotifyMessage9}", std::vector<std::string>()); messageBox("#{sNotifyMessage9}");
return; return;
} }
@ -245,7 +242,7 @@ namespace MWGui
if(roll > x) //trade refused if(roll > x) //trade refused
{ {
MWBase::Environment::get().getWindowManager()-> MWBase::Environment::get().getWindowManager()->
messageBox("#{sNotifyMessage9}", std::vector<std::string>()); messageBox("#{sNotifyMessage9}");
int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt(); int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt();
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterFailDisposition); MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterFailDisposition);
@ -342,6 +339,9 @@ namespace MWGui
bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item) bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item)
{ {
if (Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_001"))
return false;
int services = 0; int services = 0;
if (mPtr.getTypeName() == typeid(ESM::NPC).name()) if (mPtr.getTypeName() == typeid(ESM::NPC).name())
{ {

View file

@ -129,7 +129,7 @@ namespace MWGui
MWMechanics::NpcStats& npcStats = MWWorld::Class::get(mPtr).getNpcStats (mPtr); MWMechanics::NpcStats& npcStats = MWWorld::Class::get(mPtr).getNpcStats (mPtr);
if (npcStats.getSkill (skillId).getBase () <= pcStats.getSkill (skillId).getBase ()) if (npcStats.getSkill (skillId).getBase () <= pcStats.getSkill (skillId).getBase ())
{ {
mWindowManager.messageBox ("#{sServiceTrainingWords}", std::vector<std::string>()); mWindowManager.messageBox ("#{sServiceTrainingWords}");
return; return;
} }

View file

@ -83,7 +83,7 @@ namespace MWGui
if (canRest == 2) if (canRest == 2)
{ {
// resting underwater or mid-air not allowed // resting underwater or mid-air not allowed
mWindowManager.messageBox ("#{sNotifyMessage1}", std::vector<std::string>()); mWindowManager.messageBox ("#{sNotifyMessage1}");
mWindowManager.popGuiMode (); mWindowManager.popGuiMode ();
} }

View file

@ -57,6 +57,8 @@
#include "spellicons.hpp" #include "spellicons.hpp"
#include "merchantrepair.hpp" #include "merchantrepair.hpp"
#include "repair.hpp" #include "repair.hpp"
#include "soulgemdialog.hpp"
#include "companionwindow.hpp"
using namespace MWGui; using namespace MWGui;
@ -94,6 +96,8 @@ WindowManager::WindowManager(
, mTrainingWindow(NULL) , mTrainingWindow(NULL)
, mMerchantRepair(NULL) , mMerchantRepair(NULL)
, mRepair(NULL) , mRepair(NULL)
, mSoulgemDialog(NULL)
, mCompanionWindow(NULL)
, mPlayerName() , mPlayerName()
, mPlayerRaceId() , mPlayerRaceId()
, mPlayerAttributes() , mPlayerAttributes()
@ -186,6 +190,8 @@ WindowManager::WindowManager(
mTrainingWindow = new TrainingWindow(*this); mTrainingWindow = new TrainingWindow(*this);
mMerchantRepair = new MerchantRepair(*this); mMerchantRepair = new MerchantRepair(*this);
mRepair = new Repair(*this); mRepair = new Repair(*this);
mSoulgemDialog = new SoulgemDialog(mMessageBoxManager);
mCompanionWindow = new CompanionWindow(*this, mDragAndDrop, mMessageBoxManager);
mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this); mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this);
mLoadingScreen->onResChange (w,h); mLoadingScreen->onResChange (w,h);
@ -253,6 +259,7 @@ WindowManager::~WindowManager()
delete mQuickKeysMenu; delete mQuickKeysMenu;
delete mMerchantRepair; delete mMerchantRepair;
delete mRepair; delete mRepair;
delete mSoulgemDialog;
delete mCursor; delete mCursor;
cleanupGarbage(); cleanupGarbage();
@ -313,12 +320,10 @@ void WindowManager::updateVisible()
mTrainingWindow->setVisible(false); mTrainingWindow->setVisible(false);
mMerchantRepair->setVisible(false); mMerchantRepair->setVisible(false);
mRepair->setVisible(false); mRepair->setVisible(false);
mCompanionWindow->setVisible(false);
mHud->setVisible(mHudEnabled); mHud->setVisible(mHudEnabled);
// Mouse is visible whenever we're not in game mode
mCursor->setVisible(isGuiMode());
bool gameMode = !isGuiMode(); bool gameMode = !isGuiMode();
mInputBlocker->setVisible (gameMode); mInputBlocker->setVisible (gameMode);
@ -416,6 +421,10 @@ void WindowManager::updateVisible()
mContainerWindow->setVisible(true); mContainerWindow->setVisible(true);
mInventoryWindow->setVisible(true); mInventoryWindow->setVisible(true);
break; break;
case GM_Companion:
mCompanionWindow->setVisible(true);
mInventoryWindow->setVisible(true);
break;
case GM_Dialogue: case GM_Dialogue:
mDialogueWindow->setVisible(true); mDialogueWindow->setVisible(true);
break; break;
@ -444,8 +453,6 @@ void WindowManager::updateVisible()
case GM_Repair: case GM_Repair:
mRepair->setVisible(true); mRepair->setVisible(true);
break; break;
case GM_InterMessageBox:
break;
case GM_Journal: case GM_Journal:
mJournal->setVisible(true); mJournal->setVisible(true);
break; break;
@ -609,7 +616,7 @@ void WindowManager::messageBox (const std::string& message, const std::vector<st
else else
{ {
mMessageBoxManager->createInteractiveMessageBox(message, buttons); mMessageBoxManager->createInteractiveMessageBox(message, buttons);
pushGuiMode(GM_InterMessageBox); MWBase::Environment::get().getInputManager()->changeInputMode(isGuiMode());
} }
} }
@ -648,6 +655,7 @@ void WindowManager::onDialogueWindowBye()
void WindowManager::onFrame (float frameDuration) void WindowManager::onFrame (float frameDuration)
{ {
mMessageBoxManager->onFrame(frameDuration); mMessageBoxManager->onFrame(frameDuration);
mToolTips->onFrame(frameDuration); mToolTips->onFrame(frameDuration);
if (mDragAndDrop->mIsOnDragAndDrop) if (mDragAndDrop->mIsOnDragAndDrop)
@ -676,6 +684,7 @@ void WindowManager::onFrame (float frameDuration)
mSpellCreationDialog->checkReferenceAvailable(); mSpellCreationDialog->checkReferenceAvailable();
mEnchantingDialog->checkReferenceAvailable(); mEnchantingDialog->checkReferenceAvailable();
mContainerWindow->checkReferenceAvailable(); mContainerWindow->checkReferenceAvailable();
mCompanionWindow->checkReferenceAvailable();
mConsole->checkReferenceAvailable(); mConsole->checkReferenceAvailable();
} }
@ -1033,12 +1042,12 @@ void WindowManager::toggleVisible (GuiWindow wnd)
bool WindowManager::isGuiMode() const bool WindowManager::isGuiMode() const
{ {
return !mGuiModes.empty(); return !mGuiModes.empty() || mMessageBoxManager->isInteractiveMessageBox();
} }
bool WindowManager::isConsoleMode() const bool WindowManager::isConsoleMode() const
{ {
if (mGuiModes.back()==GM_Console) if (!mGuiModes.empty() && mGuiModes.back()==GM_Console)
return true; return true;
return false; return false;
} }
@ -1046,8 +1055,7 @@ bool WindowManager::isConsoleMode() const
MWGui::GuiMode WindowManager::getMode() const MWGui::GuiMode WindowManager::getMode() const
{ {
if (mGuiModes.empty()) if (mGuiModes.empty())
throw std::runtime_error ("getMode() called, but there is no active mode"); return GM_None;
return mGuiModes.back(); return mGuiModes.back();
} }
@ -1143,6 +1151,11 @@ void WindowManager::startEnchanting (MWWorld::Ptr actor)
mEnchantingDialog->startEnchanting (actor); mEnchantingDialog->startEnchanting (actor);
} }
void WindowManager::startSelfEnchanting(MWWorld::Ptr soulgem)
{
mEnchantingDialog->startSelfEnchanting(soulgem);
}
void WindowManager::startTraining(MWWorld::Ptr actor) void WindowManager::startTraining(MWWorld::Ptr actor)
{ {
mTrainingWindow->startTraining(actor); mTrainingWindow->startTraining(actor);
@ -1163,7 +1176,17 @@ const Translation::Storage& WindowManager::getTranslationDataStorage() const
return mTranslationDataStorage; return mTranslationDataStorage;
} }
void WindowManager::showCompanionWindow(MWWorld::Ptr actor)
{
mCompanionWindow->open(actor);
}
void WindowManager::changePointer(const std::string &name) void WindowManager::changePointer(const std::string &name)
{ {
mCursor->onCursorChange(name); mCursor->onCursorChange(name);
} }
void WindowManager::showSoulgemDialog(MWWorld::Ptr item)
{
mSoulgemDialog->show(item);
}

View file

@ -76,6 +76,8 @@ namespace MWGui
class SpellIcons; class SpellIcons;
class MerchantRepair; class MerchantRepair;
class Repair; class Repair;
class SoulgemDialog;
class CompanionWindow;
class WindowManager : public MWBase::WindowManager class WindowManager : public MWBase::WindowManager
{ {
@ -228,16 +230,22 @@ namespace MWGui
virtual bool getPlayerSleeping(); virtual bool getPlayerSleeping();
virtual void wakeUpPlayer(); virtual void wakeUpPlayer();
virtual void showCompanionWindow(MWWorld::Ptr actor);
virtual void startSpellMaking(MWWorld::Ptr actor); virtual void startSpellMaking(MWWorld::Ptr actor);
virtual void startEnchanting(MWWorld::Ptr actor); virtual void startEnchanting(MWWorld::Ptr actor);
virtual void startSelfEnchanting(MWWorld::Ptr soulgem);
virtual void startTraining(MWWorld::Ptr actor); virtual void startTraining(MWWorld::Ptr actor);
virtual void startRepair(MWWorld::Ptr actor); virtual void startRepair(MWWorld::Ptr actor);
virtual void startRepairItem(MWWorld::Ptr item); virtual void startRepairItem(MWWorld::Ptr item);
virtual void showSoulgemDialog (MWWorld::Ptr item);
virtual void changePointer (const std::string& name); virtual void changePointer (const std::string& name);
virtual const Translation::Storage& getTranslationDataStorage() const; virtual const Translation::Storage& getTranslationDataStorage() const;
void onSoulgemDialogButtonPressed (int button);
private: private:
OEngine::GUI::MyGUIManager *mGuiManager; OEngine::GUI::MyGUIManager *mGuiManager;
OEngine::Render::OgreRenderer *mRendering; OEngine::Render::OgreRenderer *mRendering;
@ -271,7 +279,9 @@ namespace MWGui
EnchantingDialog* mEnchantingDialog; EnchantingDialog* mEnchantingDialog;
TrainingWindow* mTrainingWindow; TrainingWindow* mTrainingWindow;
MerchantRepair* mMerchantRepair; MerchantRepair* mMerchantRepair;
SoulgemDialog* mSoulgemDialog;
Repair* mRepair; Repair* mRepair;
CompanionWindow* mCompanionWindow;
Translation::Storage& mTranslationDataStorage; Translation::Storage& mTranslationDataStorage;
Cursor* mCursor; Cursor* mCursor;

View file

@ -181,8 +181,7 @@ namespace MWInput
break; break;
case A_Activate: case A_Activate:
resetIdleTime(); resetIdleTime();
if( MWBase::Environment::get().getWindowManager()->isGuiMode() if( MWBase::Environment::get().getWindowManager()->isGuiMode()) {
&& MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_InterMessageBox ) {
// Pressing the activation key when a messagebox is prompting for "ok" will activate the ok button // Pressing the activation key when a messagebox is prompting for "ok" will activate the ok button
MWBase::Environment::get().getWindowManager()->enterPressed(); MWBase::Environment::get().getWindowManager()->enterPressed();
} }
@ -288,8 +287,6 @@ namespace MWInput
triedToMove = true; triedToMove = true;
mPlayer.setLeftRight (1); mPlayer.setLeftRight (1);
} }
else
mPlayer.setLeftRight (0);
if (actionIsActive(A_MoveForward)) if (actionIsActive(A_MoveForward))
{ {
@ -303,8 +300,6 @@ namespace MWInput
mPlayer.setAutoMove (false); mPlayer.setAutoMove (false);
mPlayer.setForwardBackward (-1); mPlayer.setForwardBackward (-1);
} }
else
mPlayer.setForwardBackward (0);
mPlayer.setSneak(actionIsActive(A_Sneak)); mPlayer.setSneak(actionIsActive(A_Sneak));
@ -313,8 +308,6 @@ namespace MWInput
mPlayer.setUpDown (1); mPlayer.setUpDown (1);
triedToMove = true; triedToMove = true;
} }
else
mPlayer.setUpDown (0);
if (mAlwaysRunActive) if (mAlwaysRunActive)
mPlayer.setRunState(!actionIsActive(A_Run)); mPlayer.setRunState(!actionIsActive(A_Run));
@ -378,27 +371,12 @@ namespace MWInput
void InputManager::changeInputMode(bool guiMode) void InputManager::changeInputMode(bool guiMode)
{ {
// Are we in GUI mode now? MWBase::Environment::get().getWindowManager()->setMouseVisible(guiMode);
if(guiMode) mGuiCursorEnabled = guiMode;
{ mMouseLookEnabled = !guiMode;
// Disable mouse look if (guiMode)
mMouseLookEnabled = false; mWindows.showCrosshair(false);
// if not in gui mode, the camera decides whether to show crosshair or not.
mWindows.showCrosshair (false);
// Enable GUI events
mGuiCursorEnabled = true;
}
else
{
// Enable mouse look
mMouseLookEnabled = true;
mWindows.showCrosshair (false);
// Disable GUI events
mGuiCursorEnabled = false;
}
} }
void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed) void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed)
@ -462,8 +440,7 @@ namespace MWInput
bool InputManager::keyPressed( const OIS::KeyEvent &arg ) bool InputManager::keyPressed( const OIS::KeyEvent &arg )
{ {
if(arg.key == OIS::KC_RETURN if(arg.key == OIS::KC_RETURN
&& MWBase::Environment::get().getWindowManager()->isGuiMode() && MWBase::Environment::get().getWindowManager()->isGuiMode())
&& MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_InterMessageBox )
{ {
// Pressing enter when a messagebox is prompting for "ok" will activate the ok button // Pressing enter when a messagebox is prompting for "ok" will activate the ok button
MWBase::Environment::get().getWindowManager()->enterPressed(); MWBase::Environment::get().getWindowManager()->enterPressed();
@ -544,11 +521,13 @@ namespace MWInput
{ {
resetIdleTime(); resetIdleTime();
float x = arg.state.X.rel * mCameraSensitivity * 0.2; float x = arg.state.X.rel * (1.0f/256.0f) * mCameraSensitivity;
float y = arg.state.Y.rel * mCameraSensitivity * 0.2 * (mInvertY ? -1 : 1) * mUIYMultiplier; float y = arg.state.Y.rel * (1.0f/256.0f) * mCameraSensitivity * mCameraYMultiplier * (mInvertY ? -1 : 1);
float scale = MWBase::Environment::get().getFrameDuration();
if(scale <= 0.0f) scale = 1.0f;
MWBase::World *world = MWBase::Environment::get().getWorld(); mPlayer.setYaw(x/scale);
world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, x, true); mPlayer.setPitch(-y/scale);
if (arg.state.Z.rel) if (arg.state.Z.rel)
MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.state.Z.rel); MWBase::Environment::get().getWorld()->changeVanityModeScale(arg.state.Z.rel);
@ -623,6 +602,9 @@ namespace MWInput
void InputManager::toggleInventory() void InputManager::toggleInventory()
{ {
if (MyGUI::InputManager::getInstance ().isModalAny())
return;
bool gameMode = !mWindows.isGuiMode(); bool gameMode = !mWindows.isGuiMode();
// Toggle between game mode and inventory mode // Toggle between game mode and inventory mode
@ -660,6 +642,9 @@ namespace MWInput
void InputManager::toggleJournal() void InputManager::toggleJournal()
{ {
if (MyGUI::InputManager::getInstance ().isModalAny())
return;
// Toggle between game mode and journal mode // Toggle between game mode and journal mode
bool gameMode = !mWindows.isGuiMode(); bool gameMode = !mWindows.isGuiMode();

View file

@ -1,76 +0,0 @@
#include "activators.hpp"
#include <OgreVector3.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
namespace MWMechanics
{
Activators::Activators()
{
}
void Activators::addActivator(const MWWorld::Ptr& ptr)
{
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
if(anim != NULL)
mActivators.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle, true)));
}
void Activators::removeActivator (const MWWorld::Ptr& ptr)
{
PtrControllerMap::iterator iter = mActivators.find(ptr);
if(iter != mActivators.end())
mActivators.erase(iter);
}
void Activators::updateActivator(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr)
{
PtrControllerMap::iterator iter = mActivators.find(old);
if(iter != mActivators.end())
{
CharacterController ctrl = iter->second;
mActivators.erase(iter);
ctrl.updatePtr(ptr);
mActivators.insert(std::make_pair(ptr, ctrl));
}
}
void Activators::dropActivators (const MWWorld::Ptr::CellStore *cellStore)
{
PtrControllerMap::iterator iter = mActivators.begin();
while(iter != mActivators.end())
{
if(iter->first.getCell()==cellStore)
mActivators.erase(iter++);
else
++iter;
}
}
void Activators::update(float duration, bool paused)
{
if(!paused)
{
for(PtrControllerMap::iterator iter(mActivators.begin());iter != mActivators.end();++iter)
iter->second.update(duration);
}
}
void Activators::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
{
PtrControllerMap::iterator iter = mActivators.find(ptr);
if(iter != mActivators.end())
iter->second.playGroup(groupName, mode, number);
}
void Activators::skipAnimation(const MWWorld::Ptr& ptr)
{
PtrControllerMap::iterator iter = mActivators.find(ptr);
if(iter != mActivators.end())
iter->second.skipAnim();
}
}

View file

@ -1,45 +0,0 @@
#ifndef GAME_MWMECHANICS_ACTIVATORS_H
#define GAME_MWMECHANICS_ACTOVATRS_H
#include <string>
#include <map>
#include "character.hpp"
namespace MWWorld
{
class Ptr;
class CellStore;
}
namespace MWMechanics
{
class Activators
{
typedef std::map<MWWorld::Ptr,CharacterController> PtrControllerMap;
PtrControllerMap mActivators;
public:
Activators();
void addActivator (const MWWorld::Ptr& ptr);
///< Register an animated activator
void removeActivator (const MWWorld::Ptr& ptr);
///< Deregister an activator
void updateActivator(const MWWorld::Ptr &old, const MWWorld::Ptr& ptr);
///< Updates an activator with a new Ptr
void dropActivators (const MWWorld::CellStore *cellStore);
///< Deregister all activators in the given cell.
void update (float duration, bool paused);
///< Update activator animations
void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
void skipAnimation(const MWWorld::Ptr& ptr);
};
}
#endif

View file

@ -17,6 +17,7 @@
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "creaturestats.hpp" #include "creaturestats.hpp"
#include "movement.hpp"
namespace MWMechanics namespace MWMechanics
{ {
@ -256,7 +257,7 @@ namespace MWMechanics
if(MWWorld::Class::get(iter->first).isEssential(iter->first)) if(MWWorld::Class::get(iter->first).isEssential(iter->first))
MWBase::Environment::get().getWindowManager()->messageBox( MWBase::Environment::get().getWindowManager()->messageBox(
"#{sKilledEssential}", std::vector<std::string>()); "#{sKilledEssential}");
} }
} }
@ -266,7 +267,8 @@ namespace MWMechanics
for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter) for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
{ {
Ogre::Vector3 movement = iter->second.update(duration); Movement movement;
iter->second.update(duration, movement);
mMovement.push_back(std::make_pair(iter->first, movement)); mMovement.push_back(std::make_pair(iter->first, movement));
} }
MWBase::Environment::get().getWorld()->doPhysics(mMovement, duration); MWBase::Environment::get().getWorld()->doPhysics(mMovement, duration);

View file

@ -7,6 +7,7 @@
#include <map> #include <map>
#include "character.hpp" #include "character.hpp"
#include "movement.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
namespace Ogre namespace Ogre

View file

@ -21,6 +21,8 @@
#include <OgreStringConverter.h> #include <OgreStringConverter.h>
#include "movement.hpp"
#include "../mwrender/animation.hpp" #include "../mwrender/animation.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
@ -73,6 +75,9 @@ static const struct {
{ CharState_SneakLeft, "sneakleft" }, { CharState_SneakLeft, "sneakleft" },
{ CharState_SneakRight, "sneakright" }, { CharState_SneakRight, "sneakright" },
{ CharState_TurnLeft, "turnleft" },
{ CharState_TurnRight, "turnright" },
{ CharState_Jump, "jump" }, { CharState_Jump, "jump" },
{ CharState_Death1, "death1" }, { CharState_Death1, "death1" },
@ -106,17 +111,17 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
mAnimation->setController(this); mAnimation->setController(this);
getStateInfo(mState, &mCurrentGroup); getStateInfo(mState, &mCurrentGroup);
if(ptr.getTypeName() == typeid(ESM::Activator).name()) if(MWWorld::Class::get(mPtr).isActor())
{
/* Don't accumulate with activators (they don't get moved). */
mAnimation->setAccumulation(Ogre::Vector3::ZERO);
}
else
{ {
/* Accumulate along X/Y only for now, until we can figure out how we should /* Accumulate along X/Y only for now, until we can figure out how we should
* handle knockout and death which moves the character down. */ * handle knockout and death which moves the character down. */
mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f)); mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f));
} }
else
{
/* Don't accumulate with non-actors. */
mAnimation->setAccumulation(Ogre::Vector3(0.0f));
}
if(mAnimation->hasAnimation(mCurrentGroup)) if(mAnimation->hasAnimation(mCurrentGroup))
mAnimation->play(mCurrentGroup, "stop", "stop", loop); mAnimation->play(mCurrentGroup, "stop", "stop", loop);
} }
@ -168,21 +173,20 @@ void CharacterController::markerEvent(float time, const std::string &evt)
} }
Ogre::Vector3 CharacterController::update(float duration) void CharacterController::update(float duration, Movement &movement)
{ {
Ogre::Vector3 movement(0.0f);
float speed = 0.0f; float speed = 0.0f;
if(!(getState() >= CharState_Death1)) if(!(getState() >= CharState_Death1))
{ {
const MWBase::World *world = MWBase::Environment::get().getWorld(); const MWBase::World *world = MWBase::Environment::get().getWorld();
const MWWorld::Class &cls = MWWorld::Class::get(mPtr); const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
const Ogre::Vector3 &vec = cls.getMovementVector(mPtr);
bool onground = world->isOnGround(mPtr); bool onground = world->isOnGround(mPtr);
bool inwater = world->isSwimming(mPtr); bool inwater = world->isSwimming(mPtr);
bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run); bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak);
const Ogre::Vector3 &vec = cls.getMovementVector(mPtr);
const Ogre::Vector3 &rot = cls.getRotationVector(mPtr);
speed = cls.getSpeed(mPtr); speed = cls.getSpeed(mPtr);
/* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except /* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except
@ -192,14 +196,14 @@ Ogre::Vector3 CharacterController::update(float duration)
float x = cls.getJump(mPtr); float x = cls.getJump(mPtr);
if(vec.x == 0 && vec.y == 0) if(vec.x == 0 && vec.y == 0)
movement.z += x*duration; movement.mPosition[2] += x*duration;
else else
{ {
/* FIXME: this would be more correct if we were going into a jumping state, /* FIXME: this would be more correct if we were going into a jumping state,
* rather than normal walking/idle states. */ * rather than normal walking/idle states. */
//Ogre::Vector3 lat = Ogre::Vector3(vec.x, vec.y, 0.0f).normalisedCopy(); //Ogre::Vector3 lat = Ogre::Vector3(vec.x, vec.y, 0.0f).normalisedCopy();
//movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration; //movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration;
movement.z += x * 0.707f * duration; movement.mPosition[2] += x * 0.707f * duration;
} }
//decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult; //decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult;
@ -216,7 +220,7 @@ Ogre::Vector3 CharacterController::update(float duration)
: (sneak ? CharState_SneakLeft : (isrunning ? CharState_RunLeft : CharState_WalkLeft)), true); : (sneak ? CharState_SneakLeft : (isrunning ? CharState_RunLeft : CharState_WalkLeft)), true);
// Apply any forward/backward movement manually // Apply any forward/backward movement manually
movement.y += vec.y * (speed*duration); movement.mPosition[1] += vec.y * (speed*duration);
} }
else if(vec.y != 0.0f && speed > 0.0f) else if(vec.y != 0.0f && speed > 0.0f)
{ {
@ -228,20 +232,32 @@ Ogre::Vector3 CharacterController::update(float duration)
setState(inwater ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack) setState(inwater ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack)
: (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack)), true); : (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack)), true);
// Apply any sideways movement manually // Apply any sideways movement manually
movement.x += vec.x * (speed*duration); movement.mPosition[0] += vec.x * (speed*duration);
}
else if(rot.z != 0.0f && !inwater && !sneak)
{
if(rot.z > 0.0f)
setState(CharState_TurnRight, true);
else if(rot.z < 0.0f)
setState(CharState_TurnLeft, true);
} }
else if(mAnimQueue.size() == 0) else if(mAnimQueue.size() == 0)
setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true); setState((inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)), true);
movement.mRotation[0] += rot.x * duration;
movement.mRotation[1] += rot.y * duration;
movement.mRotation[2] += rot.z * duration;
} }
if(mAnimation && !mSkipAnim) if(mAnimation && !mSkipAnim)
{ {
mAnimation->setSpeed(speed); mAnimation->setSpeed(speed);
movement += mAnimation->runAnimation(duration); Ogre::Vector3 moved = mAnimation->runAnimation(duration);
movement.mPosition[0] += moved.x;
movement.mPosition[1] += moved.y;
movement.mPosition[2] += moved.z;
} }
mSkipAnim = false; mSkipAnim = false;
return movement;
} }

View file

@ -13,6 +13,8 @@ namespace MWRender
namespace MWMechanics namespace MWMechanics
{ {
class Movement;
enum CharacterState { enum CharacterState {
CharState_SpecialIdle, CharState_SpecialIdle,
CharState_Idle, CharState_Idle,
@ -52,6 +54,9 @@ enum CharacterState {
CharState_SneakLeft, CharState_SneakLeft,
CharState_SneakRight, CharState_SneakRight,
CharState_TurnLeft,
CharState_TurnRight,
CharState_Jump, CharState_Jump,
/* Death states must be last! */ /* Death states must be last! */
@ -87,7 +92,7 @@ public:
void updatePtr(const MWWorld::Ptr &ptr); void updatePtr(const MWWorld::Ptr &ptr);
Ogre::Vector3 update(float duration); void update(float duration, Movement &movement);
void playGroup(const std::string &groupname, int mode, int count); void playGroup(const std::string &groupname, int mode, int count);
void skipAnim(); void skipAnim();

View 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;
}
}

View 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

View file

@ -178,10 +178,10 @@ namespace MWMechanics
void MechanicsManager::add(const MWWorld::Ptr& ptr) void MechanicsManager::add(const MWWorld::Ptr& ptr)
{ {
if(ptr.getTypeName() == typeid(ESM::Activator).name()) if(MWWorld::Class::get(ptr).isActor())
mActivators.addActivator(ptr);
else
mActors.addActor(ptr); mActors.addActor(ptr);
else
mObjects.addObject(ptr);
} }
void MechanicsManager::remove(const MWWorld::Ptr& ptr) void MechanicsManager::remove(const MWWorld::Ptr& ptr)
@ -189,15 +189,15 @@ namespace MWMechanics
if(ptr == mWatched) if(ptr == mWatched)
mWatched = MWWorld::Ptr(); mWatched = MWWorld::Ptr();
mActors.removeActor(ptr); mActors.removeActor(ptr);
mActivators.removeActivator(ptr); mObjects.removeObject(ptr);
} }
void MechanicsManager::updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) void MechanicsManager::updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr)
{ {
if(ptr.getTypeName() == typeid(ESM::Activator).name()) if(MWWorld::Class::get(ptr).isActor())
mActivators.updateActivator(old, ptr);
else
mActors.updateActor(old, ptr); mActors.updateActor(old, ptr);
else
mObjects.updateObject(old, ptr);
} }
@ -207,7 +207,7 @@ namespace MWMechanics
mWatched = MWWorld::Ptr(); mWatched = MWWorld::Ptr();
mActors.dropActors(cellStore); mActors.dropActors(cellStore);
mActivators.dropActivators(cellStore); mObjects.dropObjects(cellStore);
} }
@ -319,7 +319,7 @@ namespace MWMechanics
} }
mActors.update(duration, paused); mActors.update(duration, paused);
mActivators.update(duration, paused); mObjects.update(duration, paused);
} }
void MechanicsManager::restoreDynamicStats() void MechanicsManager::restoreDynamicStats()
@ -656,17 +656,17 @@ namespace MWMechanics
void MechanicsManager::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) void MechanicsManager::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
{ {
if(ptr.getTypeName() == typeid(ESM::Activator).name()) if(MWWorld::Class::get(ptr).isActor())
mActivators.playAnimationGroup(ptr, groupName, mode, number);
else
mActors.playAnimationGroup(ptr, groupName, mode, number); mActors.playAnimationGroup(ptr, groupName, mode, number);
else
mObjects.playAnimationGroup(ptr, groupName, mode, number);
} }
void MechanicsManager::skipAnimation(const MWWorld::Ptr& ptr) void MechanicsManager::skipAnimation(const MWWorld::Ptr& ptr)
{ {
if(ptr.getTypeName() == typeid(ESM::Activator).name()) if(MWWorld::Class::get(ptr).isActor())
mActivators.skipAnimation(ptr);
else
mActors.skipAnimation(ptr); mActors.skipAnimation(ptr);
else
mObjects.skipAnimation(ptr);
} }
} }

View file

@ -7,7 +7,7 @@
#include "creaturestats.hpp" #include "creaturestats.hpp"
#include "npcstats.hpp" #include "npcstats.hpp"
#include "activators.hpp" #include "objects.hpp"
#include "actors.hpp" #include "actors.hpp"
namespace Ogre namespace Ogre
@ -31,7 +31,7 @@ namespace MWMechanics
bool mClassSelected; bool mClassSelected;
bool mRaceSelected; bool mRaceSelected;
Activators mActivators; Objects mObjects;
Actors mActors; Actors mActors;
void buildPlayer(); void buildPlayer();

View file

@ -6,11 +6,14 @@ namespace MWMechanics
/// Desired movement for an actor /// Desired movement for an actor
struct Movement struct Movement
{ {
signed char mLeftRight; // 1: wants to move left, -1: wants to move right float mPosition[3];
signed char mForwardBackward; // 1:wants to move forward, -1: wants to move backward float mRotation[3];
signed char mUpDown;
Movement() : mLeftRight (0), mForwardBackward (0), mUpDown(0) {} Movement()
{
mPosition[0] = mPosition[1] = mPosition[2] = 0.0f;
mRotation[0] = mRotation[1] = mRotation[2] = 0.0f;
}
}; };
} }

View file

@ -21,8 +21,16 @@
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
MWMechanics::NpcStats::NpcStats() MWMechanics::NpcStats::NpcStats()
: mMovementFlags (0), mDrawState (DrawState_Nothing), mBounty (0) : mMovementFlags (0)
, mLevelProgress(0), mDisposition(0), mVampire (0), mReputation(0), mWerewolf (false), mWerewolfKills (0) , mDrawState (DrawState_Nothing)
, mBounty (0)
, mLevelProgress(0)
, mDisposition(0)
, mVampire (0)
, mReputation(0)
, mWerewolf (false)
, mWerewolfKills (0)
, mProfit(0)
{ {
mSkillIncreases.resize (ESM::Attribute::Length); mSkillIncreases.resize (ESM::Attribute::Length);
for (int i=0; i<ESM::Attribute::Length; ++i) for (int i=0; i<ESM::Attribute::Length; ++i)
@ -221,12 +229,12 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas
message << boost::format(MWBase::Environment::get().getWindowManager ()->getGameSettingString ("sNotifyMessage39", "")) message << boost::format(MWBase::Environment::get().getWindowManager ()->getGameSettingString ("sNotifyMessage39", ""))
% std::string("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}") % std::string("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}")
% static_cast<int> (base); % static_cast<int> (base);
MWBase::Environment::get().getWindowManager ()->messageBox(message.str(), std::vector<std::string>()); MWBase::Environment::get().getWindowManager ()->messageBox(message.str());
if (mLevelProgress >= 10) if (mLevelProgress >= 10)
{ {
// levelup is possible now // levelup is possible now
MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", std::vector<std::string>()); MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}");
} }
getSkill (skillIndex).setBase (base); getSkill (skillIndex).setBase (base);
@ -354,3 +362,13 @@ int MWMechanics::NpcStats::getWerewolfKills() const
{ {
return mWerewolfKills; return mWerewolfKills;
} }
int MWMechanics::NpcStats::getProfit() const
{
return mProfit;
}
void MWMechanics::NpcStats::modifyProfit(int diff)
{
mProfit += diff;
}

View file

@ -53,6 +53,7 @@ namespace MWMechanics
int mReputation; int mReputation;
bool mWerewolf; bool mWerewolf;
int mWerewolfKills; int mWerewolfKills;
int mProfit;
int mLevelProgress; // 0-10 int mLevelProgress; // 0-10
@ -64,6 +65,10 @@ namespace MWMechanics
NpcStats(); NpcStats();
/// for mercenary companions. starts out as 0, and changes when items are added or removed through the UI.
int getProfit() const;
void modifyProfit(int diff);
DrawState_ getDrawState() const; DrawState_ getDrawState() const;
void setDrawState (DrawState_ state); void setDrawState (DrawState_ state);

View file

@ -0,0 +1,81 @@
#include "objects.hpp"
#include <OgreVector3.h>
#include "movement.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
namespace MWMechanics
{
Objects::Objects()
{
}
void Objects::addObject(const MWWorld::Ptr& ptr)
{
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
if(anim != NULL)
mObjects.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle, true)));
}
void Objects::removeObject(const MWWorld::Ptr& ptr)
{
PtrControllerMap::iterator iter = mObjects.find(ptr);
if(iter != mObjects.end())
mObjects.erase(iter);
}
void Objects::updateObject(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr)
{
PtrControllerMap::iterator iter = mObjects.find(old);
if(iter != mObjects.end())
{
CharacterController ctrl = iter->second;
mObjects.erase(iter);
ctrl.updatePtr(ptr);
mObjects.insert(std::make_pair(ptr, ctrl));
}
}
void Objects::dropObjects (const MWWorld::Ptr::CellStore *cellStore)
{
PtrControllerMap::iterator iter = mObjects.begin();
while(iter != mObjects.end())
{
if(iter->first.getCell()==cellStore)
mObjects.erase(iter++);
else
++iter;
}
}
void Objects::update(float duration, bool paused)
{
if(!paused)
{
for(PtrControllerMap::iterator iter(mObjects.begin());iter != mObjects.end();++iter)
{
Movement movement;
iter->second.update(duration, movement);
}
}
}
void Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
{
PtrControllerMap::iterator iter = mObjects.find(ptr);
if(iter != mObjects.end())
iter->second.playGroup(groupName, mode, number);
}
void Objects::skipAnimation(const MWWorld::Ptr& ptr)
{
PtrControllerMap::iterator iter = mObjects.find(ptr);
if(iter != mObjects.end())
iter->second.skipAnim();
}
}

View file

@ -0,0 +1,45 @@
#ifndef GAME_MWMECHANICS_ACTIVATORS_H
#define GAME_MWMECHANICS_ACTOVATORS_H
#include <string>
#include <map>
#include "character.hpp"
namespace MWWorld
{
class Ptr;
class CellStore;
}
namespace MWMechanics
{
class Objects
{
typedef std::map<MWWorld::Ptr,CharacterController> PtrControllerMap;
PtrControllerMap mObjects;
public:
Objects();
void addObject (const MWWorld::Ptr& ptr);
///< Register an animated object
void removeObject (const MWWorld::Ptr& ptr);
///< Deregister an object
void updateObject(const MWWorld::Ptr &old, const MWWorld::Ptr& ptr);
///< Updates an object with a new Ptr
void dropObjects(const MWWorld::CellStore *cellStore);
///< Deregister all objects in the given cell.
void update(float duration, bool paused);
///< Update object animations
void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
void skipAnimation(const MWWorld::Ptr& ptr);
};
}
#endif

View file

@ -1,5 +1,7 @@
#include "objects.hpp" #include "objects.hpp"
#include <cmath>
#include <OgreSceneNode.h> #include <OgreSceneNode.h>
#include <OgreSceneManager.h> #include <OgreSceneManager.h>
#include <OgreEntity.h> #include <OgreEntity.h>
@ -271,28 +273,25 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, Ogre::Entity* skelBase, Ogre
info.time = Ogre::Math::RangeRandom(-500, +500); info.time = Ogre::Math::RangeRandom(-500, +500);
info.phase = Ogre::Math::RangeRandom(-500, +500); info.phase = Ogre::Math::RangeRandom(-500, +500);
// changed to linear to look like morrowind bool quadratic = lightOutQuadInLin() ? !info.interior : lightQuadratic();
bool quadratic = false;
/* // with the standard 1 / (c + d*l + d*d*q) equation the attenuation factor never becomes zero,
if (!lightOutQuadInLin) // so we ignore lights if their attenuation falls below this factor.
quadratic = lightQuadratic; const float threshold = 0.03;
else
{
quadratic = !info.interior;
}
*/
if (!quadratic) if (!quadratic)
{ {
float r = radius * lightLinearRadiusMult(); float r = radius * lightLinearRadiusMult();
float attenuation = lightLinearValue() / r; float attenuation = lightLinearValue() / r;
light->setAttenuation(r*10, 0, attenuation, 0); float activationRange = 1 / (threshold * attenuation);
light->setAttenuation(activationRange, 0, attenuation, 0);
} }
else else
{ {
float r = radius * lightQuadraticRadiusMult(); float r = radius * lightQuadraticRadiusMult();
float attenuation = lightQuadraticValue() / pow(r, 2); float attenuation = lightQuadraticValue() / std::pow(r, 2);
light->setAttenuation(r*10, 0, 0, attenuation); float activationRange = std::sqrt(1 / (threshold * attenuation));
light->setAttenuation(activationRange, 0, 0, attenuation);
} }
// If there's an AttachLight bone, attach the light to that, otherwise attach it to the base scene node // If there's an AttachLight bone, attach the light to that, otherwise attach it to the base scene node

View file

@ -262,7 +262,7 @@ void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3
ptr.getRefData().getBaseNode()->setScale(scale); ptr.getRefData().getBaseNode()->setScale(scale);
} }
bool RenderingManager::rotateObject( const MWWorld::Ptr &ptr, Ogre::Vector3 &rot, bool adjust) bool RenderingManager::rotateObject(const MWWorld::Ptr &ptr, Ogre::Vector3 &rot, bool adjust)
{ {
bool isActive = ptr.getRefData().getBaseNode() != 0; bool isActive = ptr.getRefData().getBaseNode() != 0;
bool isPlayer = isActive && ptr.getRefData().getHandle() == "player"; bool isPlayer = isActive && ptr.getRefData().getHandle() == "player";
@ -272,27 +272,19 @@ bool RenderingManager::rotateObject( const MWWorld::Ptr &ptr, Ogre::Vector3 &rot
force = mPlayer->rotate(rot, adjust); force = mPlayer->rotate(rot, adjust);
MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z); MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z);
if (!isPlayer && isActive) if (!isPlayer && isActive)
{ {
Ogre::Quaternion xr(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X); if(adjust)
Ogre::Quaternion yr(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y); {
Ogre::Quaternion zr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z); const float *objRot = ptr.getRefData().getPosition().rot;
rot.x += objRot[0];
Ogre::Quaternion xref(Ogre::Radian(-ptr.getRefData().getPosition().rot[0]), Ogre::Vector3::UNIT_X); rot.y += objRot[1];
Ogre::Quaternion yref(Ogre::Radian(-ptr.getRefData().getPosition().rot[1]), Ogre::Vector3::UNIT_Y); rot.z += objRot[2];
Ogre::Quaternion zref(Ogre::Radian(-ptr.getRefData().getPosition().rot[2]), Ogre::Vector3::UNIT_Z); }
Ogre::Quaternion newo = adjust ? (xr * yr * zr) * (xref*yref*zref) : xr * yr * zr;
Ogre::Matrix3 mat;
newo.ToRotationMatrix(mat);
Ogre::Radian ax,ay,az;
mat.ToEulerAnglesXYZ(ax,ay,az);
rot.x = -ax.valueRadians();
rot.y = -ay.valueRadians();
rot.z = -az.valueRadians();
Ogre::Quaternion newo = Ogre::Quaternion(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X) *
Ogre::Quaternion(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y) *
Ogre::Quaternion(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
ptr.getRefData().getBaseNode()->setOrientation(newo); ptr.getRefData().getBaseNode()->setOrientation(newo);
} }
else if(isPlayer) else if(isPlayer)

View file

@ -83,7 +83,7 @@ namespace MWScript
msgBox = boost::str(boost::format(msgBox) % count % itemName); msgBox = boost::str(boost::format(msgBox) % count % itemName);
} }
MWBase::Environment::get().getWindowManager()->messageBox(msgBox, std::vector<std::string>()); MWBase::Environment::get().getWindowManager()->messageBox(msgBox);
} }
} }
}; };
@ -179,7 +179,7 @@ namespace MWScript
} }
if (numRemoved > 0) if (numRemoved > 0)
MWBase::Environment::get().getWindowManager()->messageBox(msgBox, std::vector<std::string>()); MWBase::Environment::get().getWindowManager()->messageBox(msgBox);
} }
} }
}; };

View file

@ -316,5 +316,7 @@ op 0x20001f9: Drop, explicit reference
op 0x20001fa: DropSoulGem op 0x20001fa: DropSoulGem
op 0x20001fb: DropSoulGem, explicit reference op 0x20001fb: DropSoulGem, explicit reference
op 0x20001fc: OnDeath op 0x20001fc: OnDeath
op 0x20001fd: IsWerewolf
op 0x20001fe: IsWerewolf, explicit reference
opcodes 0x20001fd-0x3ffffff unused opcodes 0x20001ff-0x3ffffff unused

View file

@ -16,6 +16,30 @@ namespace MWScript
mFloats.resize (script.mData.mNumFloats, 0); mFloats.resize (script.mData.mNumFloats, 0);
} }
int Locals::getIntVar(const std::string &script, const std::string &var)
{
Compiler::Locals locals = MWBase::Environment::get().getScriptManager()->getLocals(script);
int index = locals.getIndex(var);
char type = locals.getType(var);
if(index != -1)
{
switch(type)
{
case 's':
return mShorts.at (index);
case 'l':
return mLongs.at (index);
case 'f':
return mFloats.at (index);
default:
return 0;
}
}
return 0;
}
bool Locals::setVarByInt(const std::string& script, const std::string& var, int val) bool Locals::setVarByInt(const std::string& script, const std::string& var, int val)
{ {
Compiler::Locals locals = MWBase::Environment::get().getScriptManager()->getLocals(script); Compiler::Locals locals = MWBase::Environment::get().getScriptManager()->getLocals(script);

View file

@ -17,6 +17,7 @@ namespace MWScript
void configure (const ESM::Script& script); void configure (const ESM::Script& script);
bool setVarByInt(const std::string& script, const std::string& var, int val); bool setVarByInt(const std::string& script, const std::string& var, int val);
int getIntVar (const std::string& script, const std::string& var); ///< if var does not exist, returns 0
}; };
} }

View file

@ -114,7 +114,7 @@ namespace MWScript
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
std::cerr << "exeution of script " << name << " failed." << std::endl; std::cerr << "execution of script " << name << " failed." << std::endl;
if (mVerbose) if (mVerbose)
std::cerr << "(" << e.what() << ")" << std::endl; std::cerr << "(" << e.what() << ")" << std::endl;

View file

@ -1046,6 +1046,18 @@ namespace MWScript
} }
}; };
template <class R>
class OpIsWerewolf : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push(MWWorld::Class::get(ptr).getNpcStats(ptr).isWerewolf());
}
};
const int numberOfAttributes = 8; const int numberOfAttributes = 8;
const int opcodeGetAttribute = 0x2000027; const int opcodeGetAttribute = 0x2000027;
@ -1137,6 +1149,9 @@ namespace MWScript
const int opcodeOnDeath = 0x20001fc; const int opcodeOnDeath = 0x20001fc;
const int opcodeIsWerewolf = 0x20001fd;
const int opcodeIsWerewolfExplicit = 0x20001fe;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
static const char *attributes[numberOfAttributes] = static const char *attributes[numberOfAttributes] =
@ -1252,6 +1267,8 @@ namespace MWScript
extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit); extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit);
extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath); extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath);
extensions.registerFunction ("iswerewolf", 'l', "", opcodeIsWerewolf, opcodeIsWerewolfExplicit);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -1368,6 +1385,9 @@ namespace MWScript
interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>); interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>);
interpreter.installSegment5 (opcodeOnDeath, new OpOnDeath); interpreter.installSegment5 (opcodeOnDeath, new OpOnDeath);
interpreter.installSegment5 (opcodeIsWerewolf, new OpIsWerewolf<ImplicitRef>);
interpreter.installSegment5 (opcodeIsWerewolfExplicit, new OpIsWerewolf<ExplicitRef>);
} }
} }
} }

View file

@ -62,7 +62,7 @@ namespace MWWorld
if((*itr).mPart == ESM::PRT_Head) if((*itr).mPart == ESM::PRT_Head)
{ {
if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() ) if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() )
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage13}", std::vector<std::string>()); MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage13}");
allow = false; allow = false;
break; break;
@ -90,12 +90,12 @@ namespace MWWorld
if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() ) if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() )
{ {
if(it.getType() == MWWorld::ContainerStore::Type_Clothing){ // It's shoes if(it.getType() == MWWorld::ContainerStore::Type_Clothing){ // It's shoes
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage15}", std::vector<std::string>()); MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage15}");
} }
else // It's boots else // It's boots
{ {
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage14}", std::vector<std::string>()); MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage14}");
} }
} }
break; break;

View file

@ -0,0 +1,21 @@
#include "actionsoulgem.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
namespace MWWorld
{
ActionSoulgem::ActionSoulgem(const Ptr &object)
: Action(false, object)
{
}
void ActionSoulgem::executeImp(const Ptr &actor)
{
MWBase::Environment::get().getWindowManager()->showSoulgemDialog(getTarget());
}
}

View file

@ -0,0 +1,19 @@
#ifndef GAME_MWWORLD_ACTIONSOULGEM_H
#define GAME_MWWORLD_ACTIONSOULGEM_H
#include "action.hpp"
#include "ptr.hpp"
namespace MWWorld
{
class ActionSoulgem : public Action
{
virtual void executeImp (const MWWorld::Ptr& actor);
public:
/// @param soulgem to use
ActionSoulgem (const Ptr& object);
};
}
#endif

View file

@ -127,6 +127,11 @@ namespace MWWorld
return 0; 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 MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const
{ {
throw std::runtime_error ("movement settings not supported by class"); throw std::runtime_error ("movement settings not supported by class");
@ -137,6 +142,11 @@ namespace MWWorld
return Ogre::Vector3 (0, 0, 0); return Ogre::Vector3 (0, 0, 0);
} }
Ogre::Vector3 Class::getRotationVector (const Ptr& ptr) const
{
return Ogre::Vector3 (0, 0, 0);
}
std::pair<std::vector<int>, bool> Class::getEquipmentSlots (const Ptr& ptr) const std::pair<std::vector<int>, bool> Class::getEquipmentSlots (const Ptr& ptr) const
{ {
return std::make_pair (std::vector<int>(), false); return std::make_pair (std::vector<int>(), false);
@ -179,10 +189,13 @@ namespace MWWorld
const Class& Class::get (const std::string& key) const Class& Class::get (const std::string& key)
{ {
if (key.empty())
throw std::logic_error ("Class::get(): attempting to get an empty key");
std::map<std::string, boost::shared_ptr<Class> >::const_iterator iter = sClasses.find (key); std::map<std::string, boost::shared_ptr<Class> >::const_iterator iter = sClasses.find (key);
if (iter==sClasses.end()) if (iter==sClasses.end())
throw std::logic_error ("unknown class key: " + key); throw std::logic_error ("Class::get(): unknown class key: " + key);
return *iter->second; return *iter->second;
} }
@ -241,6 +254,11 @@ namespace MWWorld
return ""; 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 MWWorld::Ptr
Class::copyToCellImpl(const Ptr &ptr, CellStore &cell) const Class::copyToCellImpl(const Ptr &ptr, CellStore &cell) const
{ {

View file

@ -150,6 +150,9 @@ namespace MWWorld
///< Return desired movement vector (determined based on movement settings, ///< Return desired movement vector (determined based on movement settings,
/// stance and stats). /// stance and stats).
virtual Ogre::Vector3 getRotationVector (const Ptr& ptr) const;
///< Return desired rotations, as euler angles.
virtual std::pair<std::vector<int>, bool> getEquipmentSlots (const Ptr& ptr) const; virtual std::pair<std::vector<int>, bool> getEquipmentSlots (const Ptr& ptr) const;
///< \return first: Return IDs of the slot this object can be equipped in; second: can object ///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped? /// stay stacked when equipped?
@ -225,12 +228,17 @@ namespace MWWorld
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
/// (default implementation: return 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 adjustScale(const MWWorld::Ptr& ptr,float& scale) const;
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) 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 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 virtual Ptr
copyToCell(const Ptr &ptr, CellStore &cell) const; copyToCell(const Ptr &ptr, CellStore &cell) const;

View file

@ -111,33 +111,28 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr)
// gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001 // gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001
// this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for detecting player gold) // this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for detecting player gold)
if (MWWorld::Class::get(ptr).getName(ptr) == esmStore.get<ESM::GameSetting>().find("sGold")->getString()) if (Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_001")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_005")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_010")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_025")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_100"))
{ {
MWWorld::LiveCellRef<ESM::Miscellaneous> *gold = MWWorld::ManualRef ref(esmStore, "Gold_001");
ptr.get<ESM::Miscellaneous>();
if (Misc::StringUtils::ciEqual(gold->mRef.mRefID, "gold_001") int count = MWWorld::Class::get(ptr).getValue(ptr) * ptr.getRefData().getCount();
|| Misc::StringUtils::ciEqual(gold->mRef.mRefID, "gold_005")
|| Misc::StringUtils::ciEqual(gold->mRef.mRefID, "gold_010") ref.getPtr().getRefData().setCount(count);
|| Misc::StringUtils::ciEqual(gold->mRef.mRefID, "gold_025") for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
|| Misc::StringUtils::ciEqual(gold->mRef.mRefID, "gold_100"))
{ {
MWWorld::ManualRef ref(esmStore, "Gold_001"); if (Misc::StringUtils::ciEqual((*iter).get<ESM::Miscellaneous>()->mRef.mRefID, "gold_001"))
int count = (ptr.getRefData().getCount() == 1) ? gold->mBase->mData.mValue : ptr.getRefData().getCount();
ref.getPtr().getRefData().setCount(count);
for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
{ {
if (Misc::StringUtils::ciEqual((*iter).get<ESM::Miscellaneous>()->mRef.mRefID, "gold_001")) (*iter).getRefData().setCount( (*iter).getRefData().getCount() + count);
{ flagAsModified();
(*iter).getRefData().setCount( (*iter).getRefData().getCount() + count); return iter;
flagAsModified();
return iter;
}
} }
return addImpl(ref.getPtr());
} }
return addImpl(ref.getPtr());
} }
// determine whether to stack or not // determine whether to stack or not

View file

@ -15,7 +15,7 @@ namespace MWWorld
{ {
if ( actor.getRefData().getHandle()=="player" && !(message.empty())) if ( actor.getRefData().getHandle()=="player" && !(message.empty()))
{ {
MWBase::Environment::get().getWindowManager() ->messageBox(message, std::vector<std::string>()); MWBase::Environment::get().getWindowManager() ->messageBox(message);
} }
} }
} }

View file

@ -69,10 +69,11 @@ namespace MWWorld
cellRef.mScale = 1; cellRef.mScale = 1;
cellRef.mFactIndex = 0; cellRef.mFactIndex = 0;
cellRef.mCharge = -1; cellRef.mCharge = -1;
cellRef.mNam9 = 0; cellRef.mGoldValue = 1;
cellRef.mEnchantmentCharge = -1;
cellRef.mTeleport = false; cellRef.mTeleport = false;
cellRef.mLockLevel = 0; cellRef.mLockLevel = 0;
cellRef.mUnam = 0; cellRef.mReferenceBlocked = 0;
} }
const Ptr& getPtr() const const Ptr& getPtr() const

Some files were not shown because too many files have changed in this diff Show more