1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-26 23:09:41 +00:00

Merge branch 'master' of git://github.com/zinnschlag/openmw

This commit is contained in:
scrawl 2013-03-31 17:40:32 +02:00
commit 55243dc093
88 changed files with 920 additions and 214 deletions

View file

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

View file

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

View file

@ -1,6 +1,8 @@
#ifndef CSM_WOLRD_COLUMNS_H
#define CSM_WOLRD_COLUMNS_H
#include <sstream>
#include <boost/lexical_cast.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

View file

@ -44,9 +44,23 @@ CSMWorld::Data::Data()
mSkills.addColumn (new UseValueColumn<ESM::Skill> (i));
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 (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst);
addModel (new IdTable (&mSkills), UniversalId::Type_Skills, UniversalId::Type_Skill);
addModel (new IdTable (&mClasses), UniversalId::Type_Classes, UniversalId::Type_Class);
}
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_GMST: mGmsts.load (reader, base); break;
case ESM::REC_SKIL: mSkills.load (reader, base); break;
case ESM::REC_CLAS: mClasses.load (reader, base); break;
default:

View file

@ -9,6 +9,7 @@
#include <components/esm/loadglob.hpp>
#include <components/esm/loadgmst.hpp>
#include <components/esm/loadskil.hpp>
#include <components/esm/loadclas.hpp>
#include "idcollection.hpp"
#include "universalid.hpp"
@ -22,6 +23,7 @@ namespace CSMWorld
IdCollection<ESM::Global> mGlobals;
IdCollection<ESM::GameSetting> mGmsts;
IdCollection<ESM::Skill> mSkills;
IdCollection<ESM::Class> mClasses;
std::vector<QAbstractItemModel *> mModels;
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_Gmsts, "Game Settings" },
{ 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
};
@ -29,6 +30,7 @@ namespace
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class" },
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker
};

View file

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

View file

@ -90,6 +90,10 @@ void CSVDoc::View::setupWorldMenu()
connect (skills, SIGNAL (triggered()), this, SLOT (addSkillsSubView()));
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);
connect (mVerify, SIGNAL (triggered()), this, SLOT (verify()));
world->addAction (mVerify);
@ -253,6 +257,11 @@ void CSVDoc::View::addSkillsSubView()
addSubView (CSMWorld::UniversalId::Type_Skills);
}
void CSVDoc::View::addClassesSubView()
{
addSubView (CSMWorld::UniversalId::Type_Classes);
}
void CSVDoc::View::abortOperation (int type)
{
mDocument->abortOperation (type);

View file

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

View file

@ -17,6 +17,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
manager.add (CSMWorld::UniversalId::Type_Skills,
new CSVDoc::SubViewFactoryWithCreateFlag<TableSubView> (false));
manager.add (CSMWorld::UniversalId::Type_Global,
new CSVDoc::SubViewFactoryWithCreateFlag<DialogueSubView> (true));
manager.add (CSMWorld::UniversalId::Type_Classes,
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
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
merchantrepair repair
merchantrepair repair soulgemdialog companionwindow
)
add_openmw_dir (mwdialogue
@ -54,7 +54,7 @@ add_openmw_dir (mwworld
containerstore actiontalk actiontake manualref player cellfunctors failedaction
cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp fallback actionrepair
esmstore store recordcmp fallback actionrepair actionsoulgem
)
add_openmw_dir (mwclass

View file

@ -25,6 +25,8 @@ namespace MWBase
virtual ~DialogueManager() {}
virtual bool isInChoice() const = 0;
virtual void startDialogue (const MWWorld::Ptr& actor) = 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.
virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons = std::vector<std::string>()) = 0;
virtual void enterPressed () = 0;
virtual int readPressedButton() = 0;
///< 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 void wakeUpPlayer() = 0;
virtual void showCompanionWindow(MWWorld::Ptr actor) = 0;
virtual void startSpellMaking(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 startRepair(MWWorld::Ptr actor) = 0;
virtual void startRepairItem(MWWorld::Ptr item) = 0;
virtual void showSoulgemDialog (MWWorld::Ptr item) = 0;
virtual void changePointer (const std::string& name) = 0;
virtual const Translation::Storage& getTranslationDataStorage() const = 0;

View file

@ -44,6 +44,11 @@ namespace MWRender
class Animation;
}
namespace MWMechanics
{
class Movement;
}
namespace MWWorld
{
class Fallback;
@ -54,7 +59,7 @@ namespace MWWorld
class ESMStore;
class RefData;
typedef std::vector<std::pair<MWWorld::Ptr,Ogre::Vector3> > PtrMovementList;
typedef std::vector<std::pair<MWWorld::Ptr,MWMechanics::Movement> > PtrMovementList;
}
namespace MWBase

View file

@ -115,7 +115,7 @@ namespace MWClass
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;
// using a key disarms the trap
ptr.getCellRef().mTrap = "";

View file

@ -98,7 +98,7 @@ namespace MWClass
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;
// using a key disarms the trap
ptr.getCellRef().mTrap = "";

View file

@ -15,6 +15,7 @@
#include "../mwworld/physicssystem.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/nullaction.hpp"
#include "../mwworld/actionsoulgem.hpp"
#include "../mwgui/tooltips.hpp"
@ -236,4 +237,13 @@ namespace MWClass
}
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.
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;
else
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;
return moveSpeed;
@ -414,14 +414,24 @@ namespace MWClass
Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
{
Ogre::Vector3 vector;
vector.x = getMovementSettings(ptr).mLeftRight;
vector.y = getMovementSettings(ptr).mForwardBackward;
vector.z = getMovementSettings(ptr).mUpDown;
return vector;
MWMechanics::Movement &movement = getMovementSettings(ptr);
Ogre::Vector3 vec(movement.mPosition);
movement.mPosition[0] = 0.0f;
movement.mPosition[1] = 0.0f;
movement.mPosition[2] = 0.0f;
return vec;
}
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
{
MWWorld::LiveCellRef<ESM::NPC> *ref =

View file

@ -96,6 +96,9 @@ namespace MWClass
///< Return desired movement vector (determined based on movement settings,
/// 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;
///< Return total weight that fits into the object. Throws an exception, if the object can't
/// hold other objects.

View file

@ -117,6 +117,8 @@ namespace MWDialogue
void DialogueManager::startDialogue (const MWWorld::Ptr& actor)
{
mLastTopic = "";
mChoice = -1;
mIsInChoice = false;
@ -127,6 +129,9 @@ namespace MWDialogue
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
updateTopics();
@ -145,8 +150,6 @@ namespace MWDialogue
{
//initialise the GUI
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();
@ -160,7 +163,7 @@ namespace MWDialogue
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
executeScript (info->mResultScript);
mLastTopic = it->mId;
mLastTopic = Misc::StringUtils::lowerCase(it->mId);
mLastDialogue = *info;
break;
}
@ -398,6 +401,11 @@ namespace MWDialogue
updateTopics();
}
bool DialogueManager::isInChoice() const
{
return mIsInChoice;
}
void DialogueManager::goodbyeSelected()
{
// 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[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))
{
mChoiceMap.clear();
mChoice = -1;
mIsInChoice = false;
std::string text = info->mResponse;
parseText (text);
@ -440,10 +446,12 @@ namespace MWDialogue
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addText (Interpreter::fixDefinesDialog(text, interpreterContext));
MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId);
executeScript (info->mResultScript);
mLastTopic = mLastTopic;
mLastDialogue = *info;
}
}
mChoiceMap.clear();
mChoice = -1;
mIsInChoice = false;
}
updateTopics();

View file

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

View file

@ -77,40 +77,40 @@ namespace MWGui
if (result == MWMechanics::Alchemy::Result_NoName)
{
mWindowManager.messageBox("#{sNotifyMessage37}", std::vector<std::string>());
mWindowManager.messageBox("#{sNotifyMessage37}");
return;
}
// check if mortar & pestle is available (always needed)
if (result == MWMechanics::Alchemy::Result_NoMortarAndPestle)
{
mWindowManager.messageBox("#{sNotifyMessage45}", std::vector<std::string>());
mWindowManager.messageBox("#{sNotifyMessage45}");
return;
}
// make sure 2 or more ingredients were selected
if (result == MWMechanics::Alchemy::Result_LessThanTwoIngredients)
{
mWindowManager.messageBox("#{sNotifyMessage6a}", std::vector<std::string>());
mWindowManager.messageBox("#{sNotifyMessage6a}");
return;
}
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);
return;
}
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);
}
else if (result == MWMechanics::Alchemy::Result_RandomFailure)
{
// potion failed
mWindowManager.messageBox("#{sNotifyMessage8}", std::vector<std::string>());
mWindowManager.messageBox("#{sNotifyMessage8}");
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

@ -145,7 +145,7 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender)
{
// user notification "i don't buy this item"
MWBase::Environment::get().getWindowManager()->
messageBox("#{sBarterDialog4}", std::vector<std::string>());
messageBox("#{sBarterDialog4}");
return;
}
}
@ -289,7 +289,7 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
{
// user notification
MWBase::Environment::get().getWindowManager()->
messageBox("#{sContentsMessage2}", std::vector<std::string>());
messageBox("#{sContentsMessage2}");
return;
}
@ -313,7 +313,7 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
object.getRefData().setCount(origCount);
// user notification
MWBase::Environment::get().getWindowManager()->
messageBox("#{sContentsMessage3}", std::vector<std::string>());
messageBox("#{sContentsMessage3}");
return;
}
@ -335,6 +335,9 @@ void ContainerBase::onContainerClicked(MyGUI::Widget* _sender)
drawItems();
mDragAndDrop->mDraggedFrom->drawItems();
mDragAndDrop->mDraggedFrom->notifyItemDragged(object, -mDragAndDrop->mDraggedCount);
notifyItemDragged(object, mDragAndDrop->mDraggedCount);
MWBase::Environment::get().getWindowManager()->setDragDrop(false);
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);

View file

@ -82,6 +82,10 @@ namespace MWGui
void setFilter(int filter); ///< set category filter
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:
bool mDisplayEquippedItems;
bool mHighlightEquippedItems;

View file

@ -228,7 +228,8 @@ void DialogueWindow::onByeClicked(MyGUI::Widget* _sender)
void DialogueWindow::onSelectTopic(const std::string& topic, int id)
{
if (!mEnabled) return;
if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
return;
int separatorPos = 0;
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);
}
else if (topic == gmst.find("sCompanionShare")->getString())
{
mWindowManager.pushGuiMode(GM_Companion);
mWindowManager.showCompanionWindow(mPtr);
}
else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused())
{
if (topic == gmst.find("sBarter")->getString())
@ -306,7 +312,10 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
{
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 =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
@ -335,9 +344,13 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
if (mServices & Service_Repair)
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();
for(std::list<std::string>::iterator it = keyWords.begin(); it != keyWords.end(); ++it)
{
mTopicsList->addItem(*it);

View file

@ -92,6 +92,11 @@ namespace MWGui
startEditing ();
}
void EnchantingDialog::startSelfEnchanting(MWWorld::Ptr soulgem)
{
/// \todo
}
void EnchantingDialog::onReferenceUnavailable ()
{
mWindowManager.removeGuiMode (GM_Dialogue);
@ -158,7 +163,7 @@ namespace MWGui
if(mEnchanting.getGemCharge()==0)
{
mWindowManager.messageBox ("#{sNotifyMessage32}", std::vector<std::string>());
mWindowManager.messageBox ("#{sNotifyMessage32}");
return;
}
@ -222,31 +227,37 @@ namespace MWGui
{
if (mEffects.size() <= 0)
{
mWindowManager.messageBox ("#{sNotifyMessage30}", std::vector<std::string>());
mWindowManager.messageBox ("#{sNotifyMessage30}");
return;
}
if (mName->getCaption ().empty())
{
mWindowManager.messageBox ("#{sNotifyMessage10}", std::vector<std::string>());
mWindowManager.messageBox ("#{sNotifyMessage10}");
return;
}
if (boost::lexical_cast<int>(mPrice->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold())
{
mWindowManager.messageBox ("#{sNotifyMessage18}", std::vector<std::string>());
mWindowManager.messageBox ("#{sNotifyMessage18}");
return;
}
if (mEnchanting.soulEmpty())
{
mWindowManager.messageBox ("#{sNotifyMessage52}", std::vector<std::string>());
mWindowManager.messageBox ("#{sNotifyMessage52}");
return;
}
if (mEnchanting.itemEmpty())
{
mWindowManager.messageBox ("#{sNotifyMessage11}", std::vector<std::string>());
mWindowManager.messageBox ("#{sNotifyMessage11}");
return;
}
if (mEnchanting.getEnchantCost() > mEnchanting.getMaxEnchantValue())
{
mWindowManager.messageBox ("#{sNotifyMessage29}");
return;
}
@ -254,7 +265,7 @@ namespace MWGui
mEnchanting.setEffect(mEffectList);
mEnchanting.create();
mWindowManager.messageBox ("#{sEnchantmentMenu12}", std::vector<std::string>());
mWindowManager.messageBox ("#{sEnchantmentMenu12}");
mWindowManager.removeGuiMode (GM_Enchanting);
}
}

View file

@ -22,6 +22,7 @@ namespace MWGui
virtual void open();
void startEnchanting(MWWorld::Ptr actor);
void startSelfEnchanting(MWWorld::Ptr soulgem);
protected:
virtual void onReferenceUnavailable();

View file

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

View file

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

View file

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

View file

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

View file

@ -3,6 +3,7 @@
#include "messagebox.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/inputmanager.hpp"
using namespace MWGui;
@ -62,7 +63,8 @@ void MessageBoxManager::onFrame (float frameDuration)
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
delete mInterMessageBoxe;
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)
{
/// \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) {
std::cout << "there is a MessageBox already" << std::endl;
return false;
throw std::runtime_error("There is a message box already");
}
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
@ -139,7 +138,8 @@ void MessageBoxManager::setMessageBoxSpeed (int speed)
void MessageBoxManager::enterPressed ()
{
mInterMessageBoxe->enterPressed();
if(mInterMessageBoxe != NULL)
mInterMessageBoxe->enterPressed();
}
int MessageBoxManager::readPressedButton ()
@ -213,10 +213,12 @@ int MessageBox::getHeight ()
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)
, mButtonPressed(-1)
{
WindowModal::open();
int fixedWidth = 500;
int textPadding = 10; // padding between text-widget and main-widget
int textButtonPadding = 20; // padding between the text-widget und the button-widget
@ -232,7 +234,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
getWidget(mButtonsWidget, "buttons");
mMessageWidget->setOverflowToTheLeft(true);
mMessageWidget->addText(message);
mMessageWidget->setCaptionWithReplacing(message);
MyGUI::IntSize textSize = mMessageWidget->getTextSize();
@ -252,7 +254,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan
std::string("MW_Button"),
dummyCoord,
MyGUI::Align::Default);
button->setCaption(*it);
button->setCaptionWithReplacing(*it);
button->eventMouseButtonClick += MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed);
@ -399,6 +401,7 @@ void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed)
if(*button == pressed)
{
mButtonPressed = index;
mMessageBoxManager.onButtonPressed(mButtonPressed);
return;
}
index++;

View file

@ -44,6 +44,13 @@ namespace MWGui
void enterPressed();
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;
private:
@ -73,7 +80,7 @@ namespace MWGui
int mNextBoxPadding;
};
class InteractiveMessageBox : public OEngine::GUI::Layout
class InteractiveMessageBox : public WindowModal
{
public:
InteractiveMessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector<std::string>& buttons);

View file

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

View file

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

View file

@ -26,7 +26,10 @@ namespace MWGui
// check if player has changed cell, or count of the reference has become 0
if ((playerCell != mCurrentPlayerCell && mCurrentPlayerCell != NULL)
|| mPtr.getRefData().getCount() == 0)
{
mPtr = MWWorld::Ptr();
onReferenceUnavailable();
}
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.";
MWBase::Environment::get().getWindowManager()->
messageBox(msg, std::vector<std::string>());
messageBox(msg);
_sender->castType<MyGUI::Button>()->setCaption(off);
}
else
@ -593,7 +593,7 @@ namespace MWGui
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().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

@ -310,25 +310,25 @@ namespace MWGui
{
if (mEffects.size() <= 0)
{
mWindowManager.messageBox ("#{sNotifyMessage30}", std::vector<std::string>());
mWindowManager.messageBox ("#{sNotifyMessage30}");
return;
}
if (mNameEdit->getCaption () == "")
{
mWindowManager.messageBox ("#{sNotifyMessage10}", std::vector<std::string>());
mWindowManager.messageBox ("#{sNotifyMessage10}");
return;
}
if (mMagickaCost->getCaption() == "0")
{
mWindowManager.messageBox ("#{sEnchantmentMenu8}", std::vector<std::string>());
mWindowManager.messageBox ("#{sEnchantmentMenu8}");
return;
}
if (boost::lexical_cast<int>(mPriceLabel->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold())
{
mWindowManager.messageBox ("#{sNotifyMessage18}", std::vector<std::string>());
mWindowManager.messageBox ("#{sNotifyMessage18}");
return;
}
@ -517,7 +517,7 @@ namespace MWGui
{
if (mEffects.size() >= 8)
{
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage28}", std::vector<std::string>());
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage28}");
return;
}
@ -528,7 +528,7 @@ namespace MWGui
{
if (it->mEffectID == effectId)
{
MWBase::Environment::get().getWindowManager()->messageBox ("#{sOnetypeEffectMessage}", std::vector<std::string>());
MWBase::Environment::get().getWindowManager()->messageBox ("#{sOnetypeEffectMessage}");
return;
}
}

View file

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

View file

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

View file

@ -178,7 +178,7 @@ namespace MWGui
{
// user notification
MWBase::Environment::get().getWindowManager()->
messageBox("#{sBarterDialog11}", std::vector<std::string>());
messageBox("#{sBarterDialog11}");
return;
}
@ -187,7 +187,7 @@ namespace MWGui
{
// user notification
MWBase::Environment::get().getWindowManager()->
messageBox("#{sBarterDialog1}", std::vector<std::string>());
messageBox("#{sBarterDialog1}");
return;
}
@ -196,7 +196,7 @@ namespace MWGui
{
// user notification
MWBase::Environment::get().getWindowManager()->
messageBox("#{sBarterDialog2}", std::vector<std::string>());
messageBox("#{sBarterDialog2}");
return;
}
@ -206,7 +206,7 @@ namespace MWGui
if (mPtr.getTypeName() != typeid(ESM::NPC).name())
{
MWBase::Environment::get().getWindowManager()->
messageBox("#{sNotifyMessage9}", std::vector<std::string>());
messageBox("#{sNotifyMessage9}");
return;
}
@ -242,7 +242,7 @@ namespace MWGui
if(roll > x) //trade refused
{
MWBase::Environment::get().getWindowManager()->
messageBox("#{sNotifyMessage9}", std::vector<std::string>());
messageBox("#{sNotifyMessage9}");
int iBarterFailDisposition = gmst.find("iBarterFailDisposition")->getInt();
MWBase::Environment::get().getDialogueManager()->applyTemporaryDispositionChange(iBarterFailDisposition);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,6 +2,8 @@
#include <OgreVector3.h>
#include "movement.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -56,7 +58,10 @@ void Activators::update(float duration, bool paused)
if(!paused)
{
for(PtrControllerMap::iterator iter(mActivators.begin());iter != mActivators.end();++iter)
iter->second.update(duration);
{
Movement movement;
iter->second.update(duration, movement);
}
}
}

View file

@ -17,6 +17,7 @@
#include "../mwbase/windowmanager.hpp"
#include "creaturestats.hpp"
#include "movement.hpp"
namespace MWMechanics
{
@ -256,7 +257,7 @@ namespace MWMechanics
if(MWWorld::Class::get(iter->first).isEssential(iter->first))
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)
{
Ogre::Vector3 movement = iter->second.update(duration);
Movement movement;
iter->second.update(duration, movement);
mMovement.push_back(std::make_pair(iter->first, movement));
}
MWBase::Environment::get().getWorld()->doPhysics(mMovement, duration);

View file

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

View file

@ -21,6 +21,8 @@
#include <OgreStringConverter.h>
#include "movement.hpp"
#include "../mwrender/animation.hpp"
#include "../mwbase/environment.hpp"
@ -73,6 +75,9 @@ static const struct {
{ CharState_SneakLeft, "sneakleft" },
{ CharState_SneakRight, "sneakright" },
{ CharState_TurnLeft, "turnleft" },
{ CharState_TurnRight, "turnright" },
{ CharState_Jump, "jump" },
{ CharState_Death1, "death1" },
@ -168,21 +173,20 @@ void CharacterController::markerEvent(float time, const std::string &evt)
}
Ogre::Vector3 CharacterController::update(float duration)
void CharacterController::update(float duration, Movement &movement)
{
Ogre::Vector3 movement(0.0f);
float speed = 0.0f;
if(!(getState() >= CharState_Death1))
{
const MWBase::World *world = MWBase::Environment::get().getWorld();
const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
const Ogre::Vector3 &vec = cls.getMovementVector(mPtr);
bool onground = world->isOnGround(mPtr);
bool inwater = world->isSwimming(mPtr);
bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
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);
/* 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);
if(vec.x == 0 && vec.y == 0)
movement.z += x*duration;
movement.mPosition[2] += x*duration;
else
{
/* FIXME: this would be more correct if we were going into a jumping state,
* rather than normal walking/idle states. */
//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.z += x * 0.707f * duration;
movement.mPosition[2] += x * 0.707f * duration;
}
//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);
// 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)
{
@ -228,20 +232,32 @@ Ogre::Vector3 CharacterController::update(float duration)
setState(inwater ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack)
: (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack)), true);
// 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)
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)
{
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;
return movement;
}

View file

@ -13,6 +13,8 @@ namespace MWRender
namespace MWMechanics
{
class Movement;
enum CharacterState {
CharState_SpecialIdle,
CharState_Idle,
@ -52,6 +54,9 @@ enum CharacterState {
CharState_SneakLeft,
CharState_SneakRight,
CharState_TurnLeft,
CharState_TurnRight,
CharState_Jump,
/* Death states must be last! */
@ -87,7 +92,7 @@ public:
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 skipAnim();

View file

@ -6,11 +6,14 @@ namespace MWMechanics
/// Desired movement for an actor
struct Movement
{
signed char mLeftRight; // 1: wants to move left, -1: wants to move right
signed char mForwardBackward; // 1:wants to move forward, -1: wants to move backward
signed char mUpDown;
float mPosition[3];
float mRotation[3];
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"
MWMechanics::NpcStats::NpcStats()
: mMovementFlags (0), mDrawState (DrawState_Nothing), mBounty (0)
, mLevelProgress(0), mDisposition(0), mVampire (0), mReputation(0), mWerewolf (false), mWerewolfKills (0)
: mMovementFlags (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);
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", ""))
% std::string("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}")
% 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)
{
// levelup is possible now
MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", std::vector<std::string>());
MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}");
}
getSkill (skillIndex).setBase (base);
@ -354,3 +362,13 @@ int MWMechanics::NpcStats::getWerewolfKills() const
{
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;
bool mWerewolf;
int mWerewolfKills;
int mProfit;
int mLevelProgress; // 0-10
@ -64,6 +65,10 @@ namespace MWMechanics
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;
void setDrawState (DrawState_ state);

View file

@ -262,37 +262,29 @@ void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3
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 isPlayer = isActive && ptr.getRefData().getHandle() == "player";
bool force = true;
if (isPlayer)
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)
{
Ogre::Quaternion xr(Ogre::Radian(-rot.x), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yr(Ogre::Radian(-rot.y), Ogre::Vector3::UNIT_Y);
Ogre::Quaternion zr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Z);
Ogre::Quaternion xref(Ogre::Radian(-ptr.getRefData().getPosition().rot[0]), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yref(Ogre::Radian(-ptr.getRefData().getPosition().rot[1]), Ogre::Vector3::UNIT_Y);
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();
if(adjust)
{
const float *objRot = ptr.getRefData().getPosition().rot;
rot.x += objRot[0];
rot.y += objRot[1];
rot.z += objRot[2];
}
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);
}
else if(isPlayer)

View file

@ -83,7 +83,7 @@ namespace MWScript
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)
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 0x20001fb: DropSoulGem, explicit reference
op 0x20001fc: OnDeath
op 0x20001fd: IsWerewolf
op 0x20001fe: IsWerewolf, explicit reference
opcodes 0x20001fd-0x3ffffff unused
opcodes 0x20001ff-0x3ffffff unused

View file

@ -15,6 +15,30 @@ namespace MWScript
mFloats.clear();
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)
{

View file

@ -17,6 +17,7 @@ namespace MWScript
void configure (const ESM::Script& script);
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)
{
std::cerr << "exeution of script " << name << " failed." << std::endl;
std::cerr << "execution of script " << name << " failed." << std::endl;
if (mVerbose)
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 opcodeGetAttribute = 0x2000027;
@ -1137,6 +1149,9 @@ namespace MWScript
const int opcodeOnDeath = 0x20001fc;
const int opcodeIsWerewolf = 0x20001fd;
const int opcodeIsWerewolfExplicit = 0x20001fe;
void registerExtensions (Compiler::Extensions& extensions)
{
static const char *attributes[numberOfAttributes] =
@ -1252,6 +1267,8 @@ namespace MWScript
extensions.registerInstruction ("lowerrank", "", opcodeLowerRank, opcodeLowerRankExplicit);
extensions.registerFunction ("ondeath", 'l', "", opcodeOnDeath);
extensions.registerFunction ("iswerewolf", 'l', "", opcodeIsWerewolf, opcodeIsWerewolfExplicit);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
@ -1368,6 +1385,9 @@ namespace MWScript
interpreter.installSegment5 (opcodeLowerRankExplicit, new OpLowerRank<ExplicitRef>);
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(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;
break;
@ -90,12 +90,12 @@ namespace MWWorld
if(actor == MWBase::Environment::get().getWorld()->getPlayer().getPlayer() )
{
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
{
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage14}", std::vector<std::string>());
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage14}");
}
}
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

@ -142,6 +142,11 @@ namespace MWWorld
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
{
return std::make_pair (std::vector<int>(), false);
@ -184,10 +189,13 @@ namespace MWWorld
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);
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;
}

View file

@ -150,6 +150,9 @@ namespace MWWorld
///< Return desired movement vector (determined based on movement settings,
/// 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;
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
/// stay stacked when equipped?

View file

@ -15,7 +15,7 @@ namespace MWWorld
{
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

@ -42,14 +42,14 @@ namespace MWWorld
if (mAutoMove)
value = 1;
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[1] = value;
}
void Player::setLeftRight (int value)
{
MWWorld::Ptr ptr = getPlayer();
MWWorld::Class::get (ptr).getMovementSettings (ptr).mLeftRight = value;
MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[0] = value;
}
void Player::setForwardBackward (int value)
@ -61,14 +61,14 @@ namespace MWWorld
if (mAutoMove)
value = 1;
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[1] = value;
}
void Player::setUpDown(int value)
{
MWWorld::Ptr ptr = getPlayer();
MWWorld::Class::get (ptr).getMovementSettings (ptr).mUpDown = value;
MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[2] = value;
}
void Player::setRunState(bool run)
@ -84,6 +84,22 @@ namespace MWWorld
MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Sneak, sneak);
}
void Player::setYaw(float yaw)
{
MWWorld::Ptr ptr = getPlayer();
MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[2] = yaw;
}
void Player::setPitch(float pitch)
{
MWWorld::Ptr ptr = getPlayer();
MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[0] = pitch;
}
void Player::setRoll(float roll)
{
MWWorld::Ptr ptr = getPlayer();
MWWorld::Class::get(ptr).getMovementSettings(ptr).mRotation[1] = roll;
}
MWMechanics::DrawState_ Player::getDrawState()
{
MWWorld::Ptr ptr = getPlayer();

View file

@ -67,6 +67,10 @@ namespace MWWorld
void setRunState(bool run);
void setSneak(bool sneak);
void setYaw(float yaw);
void setPitch(float pitch);
void setRoll(float roll);
};
}
#endif

View file

@ -13,6 +13,7 @@
#include "../mwbase/scriptmanager.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/movement.hpp"
#include "../mwrender/sky.hpp"
#include "../mwrender/player.hpp"
@ -805,18 +806,15 @@ namespace MWWorld
mPhysics->scaleObject(ptr);
}
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
void World::rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust)
{
Ogre::Vector3 rot;
rot.x = Ogre::Degree(x).valueRadians();
rot.y = Ogre::Degree(y).valueRadians();
rot.z = Ogre::Degree(z).valueRadians();
if (mRendering->rotateObject(ptr, rot, adjust))
{
// rotate physically iff renderer confirm so
float *objRot = ptr.getRefData().getPosition().rot;
objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z;
objRot[0] = rot.x;
objRot[1] = rot.y;
objRot[2] = rot.z;
if (ptr.getRefData().getBaseNode() != 0) {
mPhysics->rotateObject(ptr);
@ -824,6 +822,14 @@ namespace MWWorld
}
}
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
{
rotateObjectImp(ptr, Ogre::Vector3(Ogre::Degree(x).valueRadians(),
Ogre::Degree(y).valueRadians(),
Ogre::Degree(z).valueRadians()),
adjust);
}
void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos)
{
copyObjectToCell(ptr,Cell,pos);
@ -873,13 +879,18 @@ namespace MWWorld
player = iter;
continue;
}
Ogre::Vector3 vec = mPhysics->move(iter->first, iter->second, duration,
rotateObjectImp(iter->first, Ogre::Vector3(iter->second.mRotation), true);
Ogre::Vector3 vec = mPhysics->move(iter->first, Ogre::Vector3(iter->second.mPosition), duration,
!isSwimming(iter->first) && !isFlying(iter->first));
moveObjectImp(iter->first, vec.x, vec.y, vec.z);
}
if(player != actors.end())
{
Ogre::Vector3 vec = mPhysics->move(player->first, player->second, duration,
rotateObjectImp(player->first, Ogre::Vector3(player->second.mRotation), true);
Ogre::Vector3 vec = mPhysics->move(player->first, Ogre::Vector3(player->second.mPosition), duration,
!isSwimming(player->first) && !isFlying(player->first));
moveObjectImp(player->first, vec.x, vec.y, vec.z);
}

View file

@ -90,6 +90,8 @@ namespace MWWorld
int getDaysPerMonth (int month) const;
void rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust);
bool moveObjectImp (const Ptr& ptr, float x, float y, float z);
///< @return true if the active cell (cell player is in) changed

View file

@ -106,6 +106,12 @@ namespace Compiler
mLoc.mLiteral.clear();
return true;
}
else if (c==':')
{
// treat : as a whitespace :(
mLoc.mLiteral.clear();
return true;
}
else if (std::isdigit (c))
{
bool cont = false;

View file

@ -35,4 +35,18 @@ void Class::save(ESMWriter &esm)
esm.writeHNOString("DESC", mDescription);
}
void Class::blank()
{
mName.clear();
mDescription.clear();
mData.mAttribute[0] = mData.mAttribute[1] = 0;
mData.mSpecialization = 0;
mData.mIsPlayable = 0;
mData.mCalc = 0;
for (int i=0; i<5; ++i)
for (int i2=0; i2<2; ++i2)
mData.mSkills[i][i2] = 0;
}
}

View file

@ -65,6 +65,10 @@ struct Class
void load(ESMReader &esm);
void save(ESMWriter &esm);
void blank();
///< Set record to default state (does not touch the ID/index).
};
}
#endif

View file

@ -2,6 +2,8 @@
#include <sstream>
#include <components/misc/stringops.hpp>
#include "esmreader.hpp"
#include "esmwriter.hpp"
@ -103,8 +105,9 @@ void Skill::load(ESMReader &esm)
// create an ID from the index and the name (only used in the editor and likely to change in the
// future)
mId = getIndexToId (mIndex);
mId = indexToId (mIndex);
}
void Skill::save(ESMWriter &esm)
{
esm.writeHNT("INDX", mIndex);
@ -120,7 +123,7 @@ void Skill::save(ESMWriter &esm)
mDescription.clear();
}
std::string Skill::getIndexToId (int index)
std::string Skill::indexToId (int index)
{
std::ostringstream stream;

View file

@ -79,7 +79,7 @@ struct Skill
void blank();
///< Set record to default state (does not touch the ID/index).
static std::string getIndexToId (int index);
static std::string indexToId (int index);
};
}
#endif

View file

@ -80,6 +80,7 @@ set(MYGUI_FILES
openmw_persuasion_dialog.layout
openmw_merchantrepair.layout
openmw_repair.layout
openmw_companion_window.layout
smallbars.png
DejaVuLGCSansMono.ttf
markers.png

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Window" layer="Windows" position="0 0 600 300" name="_Main">
<!-- Items -->
<Widget type="Widget" skin="MW_Box" position="5 5 575 225" name="box" align="Left Top Stretch">
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 567 217" name="ItemView" align="Left Top Stretch">
<Property key="CanvasAlign" value="Left Top"/>
<Widget type="Button" skin="" name="Items" position="0 0 567 217" name="Items" align="Left Top Stretch"/>
</Widget>
</Widget>
<Widget type="HBox" position="5 235 575 24" align="Bottom HStretch">
<Widget type="MWDynamicStat" skin="MW_ChargeBar_Blue" position="8 8 212 24" name="EncumbranceBar" align="Left Top HStretch">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" name="ProfitLabel">
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CloseButton">
<Property key="Caption" value="#{sClose}"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Window" layer="Windows" position="900 500 600 300" name="_Main">
<Widget type="Window" skin="MW_Window" layer="Windows" position="0 0 600 300" name="_Main">
<!-- Items -->
<Widget type="Widget" skin="MW_Box" position="5 5 575 225" name="box" align="Left Top Stretch">

View file

@ -70,18 +70,18 @@
<!-- Available effects -->
<Widget type="TextBox" skin="NormalText" position="12 148 300 24">
<Widget type="TextBox" skin="NormalText" position="12 108 300 24">
<Property key="Caption" value="#{sMagicEffects}"/>
</Widget>
<Widget type="MWList" skin="MW_SimpleList" position="12 176 202 169" name="AvailableEffects">
<Widget type="MWList" skin="MW_SimpleList" position="12 136 202 209" name="AvailableEffects">
</Widget>
<!-- Used effects -->
<Widget type="TextBox" skin="NormalText" position="226 148 300 24">
<Widget type="TextBox" skin="NormalText" position="226 108 300 24">
<Property key="Caption" value="#{sEffects}"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="226 176 316 169">
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 308 161" name="UsedEffects">
<Widget type="Widget" skin="MW_Box" position="226 136 316 209">
<Widget type="ScrollView" skin="MW_ScrollViewH" position="4 4 308 201" name="UsedEffects">
<Property key="CanvasAlign" value="Left Top"/>
</Widget>
</Widget>

View file

@ -6,8 +6,7 @@
<Widget type="Widget" skin="" position="0 0 224 223" align="Left Top" name="LeftPane">
<!-- Player encumbrance -->
<Widget type="ProgressBar" skin="MW_Progress_Blue" position="8 8 212 24" name="EncumbranceBar" align="Left Top HStretch">
<Widget type="TextBox" skin="ProgressText" position="0 0 212 24" align="Center Stretch" name="EncumbranceBarT"/>
<Widget type="MWDynamicStat" skin="MW_ChargeBar_Blue" position="8 8 212 24" name="EncumbranceBar" align="Left Top HStretch">
</Widget>
<!-- Avatar -->

View file

@ -158,6 +158,11 @@
<Child type="TextBox" skin="SandTextC" offset = "0 0 204 18" align = "ALIGN_RIGHT ALIGN_TOP ALIGN_STRETCH" name = "BarText" />
</Skin>
<Skin name = "MW_ChargeBar_Blue" size = "204 18">
<Child type="ProgressBar" skin="MW_Progress_Blue" offset = "0 0 204 18" align = "ALIGN_RIGHT ALIGN_TOP ALIGN_STRETCH" name = "Bar" />
<Child type="TextBox" skin="SandTextC" offset = "0 0 204 18" align = "ALIGN_RIGHT ALIGN_TOP ALIGN_STRETCH" name = "BarText" />
</Skin>
<Skin name = "MW_DynamicStat_Red" size = "204 18">
<Child type="TextBox" skin="SandText" offset = "0 0 100 18" align = "ALIGN_LEFT ALIGN_TOP" name = "Text" />
<Child type="ProgressBar" skin="MW_Progress_Red" offset = "74 0 130 18" align = "ALIGN_RIGHT ALIGN_TOP" name = "Bar" />

View file

@ -89,18 +89,19 @@ namespace Physic
}
void PhysicActor::setScale(float scale){
Ogre::Vector3 position = getPosition();
Ogre::Quaternion rotation = getRotation();
//We only need to change the scaled box translation, box rotations remain the same.
mBoxScaledTranslation = mBoxScaledTranslation / mBody->getCollisionShape()->getLocalScaling().getX();
mBoxScaledTranslation *= scale;
if(mBody){
mEngine->dynamicsWorld->removeRigidBody(mBody);
mEngine->dynamicsWorld->removeRigidBody(mRaycastingBody);
delete mBody;
delete mRaycastingBody;
}
//Create the newly scaled rigid body
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation);
mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, getPosition(), getRotation());
mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, getPosition(), getRotation(), 0, 0, true);
mEngine->addRigidBody(mBody, false, mRaycastingBody); //Add rigid body to dynamics world, but do not add to object map
}
Ogre::Vector3 PhysicActor::getHalfExtents() const