forked from mirror/openmw-tes3mp
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
3992125b61
29 changed files with 249 additions and 116 deletions
|
@ -281,9 +281,12 @@ namespace MWClass
|
||||||
ptr.getCellRef().setLockLevel(-abs(ptr.getCellRef().getLockLevel())); //Makes lockLevel negative
|
ptr.getCellRef().setLockLevel(-abs(ptr.getCellRef().getLockLevel())); //Makes lockLevel negative
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Container::canLock(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
MWWorld::Ptr
|
MWWorld::Ptr Container::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
|
||||||
Container::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
|
|
||||||
{
|
{
|
||||||
MWWorld::LiveCellRef<ESM::Container> *ref =
|
MWWorld::LiveCellRef<ESM::Container> *ref =
|
||||||
ptr.get<ESM::Container>();
|
ptr.get<ESM::Container>();
|
||||||
|
@ -291,8 +294,7 @@ namespace MWClass
|
||||||
return MWWorld::Ptr(&cell.get<ESM::Container>().insert(*ref), &cell);
|
return MWWorld::Ptr(&cell.get<ESM::Container>().insert(*ref), &cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
void Container::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const
|
||||||
const
|
|
||||||
{
|
{
|
||||||
const ESM::ContainerState& state2 = dynamic_cast<const ESM::ContainerState&> (state);
|
const ESM::ContainerState& state2 = dynamic_cast<const ESM::ContainerState&> (state);
|
||||||
|
|
||||||
|
@ -307,8 +309,7 @@ namespace MWClass
|
||||||
readState (state2.mInventory);
|
readState (state2.mInventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
void Container::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state) const
|
||||||
const
|
|
||||||
{
|
{
|
||||||
ESM::ContainerState& state2 = dynamic_cast<ESM::ContainerState&> (state);
|
ESM::ContainerState& state2 = dynamic_cast<ESM::ContainerState&> (state);
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,8 @@ namespace MWClass
|
||||||
virtual void unlock (const MWWorld::Ptr& ptr) const;
|
virtual void unlock (const MWWorld::Ptr& ptr) const;
|
||||||
///< Unlock object
|
///< Unlock object
|
||||||
|
|
||||||
|
virtual bool canLock(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
||||||
const;
|
const;
|
||||||
///< Read additional state from \a state into \a ptr.
|
///< Read additional state from \a state into \a ptr.
|
||||||
|
|
|
@ -207,6 +207,11 @@ namespace MWClass
|
||||||
ptr.getCellRef().setLockLevel(-abs(ptr.getCellRef().getLockLevel())); //Makes lockLevel negative
|
ptr.getCellRef().setLockLevel(-abs(ptr.getCellRef().getLockLevel())); //Makes lockLevel negative
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Door::canLock(const MWWorld::Ptr &ptr) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Door::getScript (const MWWorld::Ptr& ptr) const
|
std::string Door::getScript (const MWWorld::Ptr& ptr) const
|
||||||
{
|
{
|
||||||
MWWorld::LiveCellRef<ESM::Door> *ref =
|
MWWorld::LiveCellRef<ESM::Door> *ref =
|
||||||
|
|
|
@ -47,6 +47,8 @@ namespace MWClass
|
||||||
virtual void unlock (const MWWorld::Ptr& ptr) const;
|
virtual void unlock (const MWWorld::Ptr& ptr) const;
|
||||||
///< Unlock object
|
///< Unlock object
|
||||||
|
|
||||||
|
virtual bool canLock(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return name of the script attached to ptr
|
///< Return name of the script attached to ptr
|
||||||
|
|
||||||
|
|
|
@ -312,7 +312,7 @@ namespace MWGui
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow)
|
void CharacterCreation::selectPickedClass()
|
||||||
{
|
{
|
||||||
if (mPickClassDialog)
|
if (mPickClassDialog)
|
||||||
{
|
{
|
||||||
|
@ -332,20 +332,18 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePlayerHealth();
|
updatePlayerHealth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharacterCreation::onPickClassDialogDone(WindowBase* parWindow)
|
||||||
|
{
|
||||||
|
selectPickedClass();
|
||||||
|
|
||||||
handleDialogDone(CSE_ClassChosen, GM_Birth);
|
handleDialogDone(CSE_ClassChosen, GM_Birth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::onPickClassDialogBack()
|
void CharacterCreation::onPickClassDialogBack()
|
||||||
{
|
{
|
||||||
if (mPickClassDialog)
|
selectPickedClass();
|
||||||
{
|
|
||||||
const std::string classId = mPickClassDialog->getClassId();
|
|
||||||
if (!classId.empty())
|
|
||||||
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(classId);
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeDialog(mPickClassDialog);
|
|
||||||
mPickClassDialog = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
|
||||||
|
@ -390,29 +388,7 @@ namespace MWGui
|
||||||
handleDialogDone(CSE_NameChosen, GM_Race);
|
handleDialogDone(CSE_NameChosen, GM_Race);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::onRaceDialogBack()
|
void CharacterCreation::selectRace()
|
||||||
{
|
|
||||||
if (mRaceDialog)
|
|
||||||
{
|
|
||||||
const ESM::NPC &data = mRaceDialog->getResult();
|
|
||||||
mPlayerRaceId = data.mRace;
|
|
||||||
if (!mPlayerRaceId.empty()) {
|
|
||||||
MWBase::Environment::get().getMechanicsManager()->setPlayerRace(
|
|
||||||
data.mRace,
|
|
||||||
data.isMale(),
|
|
||||||
data.mHead,
|
|
||||||
data.mHair
|
|
||||||
);
|
|
||||||
}
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeDialog(mRaceDialog);
|
|
||||||
mRaceDialog = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
|
|
||||||
{
|
{
|
||||||
if (mRaceDialog)
|
if (mRaceDialog)
|
||||||
{
|
{
|
||||||
|
@ -433,11 +409,24 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePlayerHealth();
|
updatePlayerHealth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharacterCreation::onRaceDialogBack()
|
||||||
|
{
|
||||||
|
selectRace();
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharacterCreation::onRaceDialogDone(WindowBase* parWindow)
|
||||||
|
{
|
||||||
|
selectRace();
|
||||||
|
|
||||||
handleDialogDone(CSE_RaceChosen, GM_Class);
|
handleDialogDone(CSE_RaceChosen, GM_Class);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow)
|
void CharacterCreation::selectBirthSign()
|
||||||
{
|
{
|
||||||
if (mBirthSignDialog)
|
if (mBirthSignDialog)
|
||||||
{
|
{
|
||||||
|
@ -449,24 +438,24 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePlayerHealth();
|
updatePlayerHealth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharacterCreation::onBirthSignDialogDone(WindowBase* parWindow)
|
||||||
|
{
|
||||||
|
selectBirthSign();
|
||||||
|
|
||||||
handleDialogDone(CSE_BirthSignChosen, GM_Review);
|
handleDialogDone(CSE_BirthSignChosen, GM_Review);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::onBirthSignDialogBack()
|
void CharacterCreation::onBirthSignDialogBack()
|
||||||
{
|
{
|
||||||
if (mBirthSignDialog)
|
selectBirthSign();
|
||||||
{
|
|
||||||
MWBase::Environment::get().getMechanicsManager()->setPlayerBirthsign(mBirthSignDialog->getBirthId());
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeDialog(mBirthSignDialog);
|
|
||||||
mBirthSignDialog = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
|
void CharacterCreation::selectCreatedClass()
|
||||||
{
|
{
|
||||||
if (mCreateClassDialog)
|
if (mCreateClassDialog)
|
||||||
{
|
{
|
||||||
|
@ -495,19 +484,23 @@ namespace MWGui
|
||||||
mPlayerClass = klass;
|
mPlayerClass = klass;
|
||||||
MWBase::Environment::get().getWindowManager()->setPlayerClass(klass);
|
MWBase::Environment::get().getWindowManager()->setPlayerClass(klass);
|
||||||
|
|
||||||
// Do not delete dialog, so that choices are rembered in case we want to go back and adjust them later
|
// Do not delete dialog, so that choices are remembered in case we want to go back and adjust them later
|
||||||
mCreateClassDialog->setVisible(false);
|
mCreateClassDialog->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePlayerHealth();
|
updatePlayerHealth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow)
|
||||||
|
{
|
||||||
|
selectCreatedClass();
|
||||||
|
|
||||||
handleDialogDone(CSE_ClassChosen, GM_Birth);
|
handleDialogDone(CSE_ClassChosen, GM_Birth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::onCreateClassDialogBack()
|
void CharacterCreation::onCreateClassDialogBack()
|
||||||
{
|
{
|
||||||
// Do not delete dialog, so that choices are rembered in case we want to go back and adjust them later
|
// not done in MW, but we do it for consistency with the other dialogs
|
||||||
mCreateClassDialog->setVisible(false);
|
selectCreatedClass();
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
|
||||||
|
@ -631,18 +624,7 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getSoundManager()->say(sGenerateClassSteps(mGenerateClassStep).mSound);
|
MWBase::Environment::get().getSoundManager()->say(sGenerateClassSteps(mGenerateClassStep).mSound);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::onGenerateClassBack()
|
void CharacterCreation::selectGeneratedClass()
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeDialog(mGenerateClassResultDialog);
|
|
||||||
mGenerateClassResultDialog = 0;
|
|
||||||
|
|
||||||
MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass);
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
|
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->removeDialog(mGenerateClassResultDialog);
|
MWBase::Environment::get().getWindowManager()->removeDialog(mGenerateClassResultDialog);
|
||||||
mGenerateClassResultDialog = 0;
|
mGenerateClassResultDialog = 0;
|
||||||
|
@ -656,6 +638,19 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->setPlayerClass(mPlayerClass);
|
MWBase::Environment::get().getWindowManager()->setPlayerClass(mPlayerClass);
|
||||||
|
|
||||||
updatePlayerHealth();
|
updatePlayerHealth();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharacterCreation::onGenerateClassBack()
|
||||||
|
{
|
||||||
|
selectGeneratedClass();
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharacterCreation::onGenerateClassDone(WindowBase* parWindow)
|
||||||
|
{
|
||||||
|
selectGeneratedClass();
|
||||||
|
|
||||||
handleDialogDone(CSE_ClassChosen, GM_Birth);
|
handleDialogDone(CSE_ClassChosen, GM_Birth);
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@ namespace MWGui
|
||||||
//Race dialog
|
//Race dialog
|
||||||
void onRaceDialogDone(WindowBase* parWindow);
|
void onRaceDialogDone(WindowBase* parWindow);
|
||||||
void onRaceDialogBack();
|
void onRaceDialogBack();
|
||||||
|
void selectRace();
|
||||||
|
|
||||||
//Class dialogs
|
//Class dialogs
|
||||||
void onClassChoice(int _index);
|
void onClassChoice(int _index);
|
||||||
|
@ -94,10 +95,14 @@ namespace MWGui
|
||||||
void onClassQuestionChosen(int _index);
|
void onClassQuestionChosen(int _index);
|
||||||
void onGenerateClassBack();
|
void onGenerateClassBack();
|
||||||
void onGenerateClassDone(WindowBase* parWindow);
|
void onGenerateClassDone(WindowBase* parWindow);
|
||||||
|
void selectGeneratedClass();
|
||||||
|
void selectCreatedClass();
|
||||||
|
void selectPickedClass();
|
||||||
|
|
||||||
//Birthsign dialog
|
//Birthsign dialog
|
||||||
void onBirthSignDialogDone(WindowBase* parWindow);
|
void onBirthSignDialogDone(WindowBase* parWindow);
|
||||||
void onBirthSignDialogBack();
|
void onBirthSignDialogBack();
|
||||||
|
void selectBirthSign();
|
||||||
|
|
||||||
//Review dialog
|
//Review dialog
|
||||||
void onReviewDialogDone(WindowBase* parWindow);
|
void onReviewDialogDone(WindowBase* parWindow);
|
||||||
|
|
|
@ -119,7 +119,12 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
mPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
mPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||||
mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr());
|
mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr());
|
||||||
mSortModel = new SortFilterItemModel(mTradeModel);
|
|
||||||
|
if (mSortModel) // reuse existing SortModel when possible to keep previous category/filter settings
|
||||||
|
mSortModel->setSourceModel(mTradeModel);
|
||||||
|
else
|
||||||
|
mSortModel = new SortFilterItemModel(mTradeModel);
|
||||||
|
|
||||||
mItemView->setModel(mSortModel);
|
mItemView->setModel(mSortModel);
|
||||||
|
|
||||||
mPreview->updatePtr(mPtr);
|
mPreview->updatePtr(mPtr);
|
||||||
|
|
|
@ -120,6 +120,11 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ProxyItemModel::ProxyItemModel()
|
||||||
|
: mSourceModel(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ProxyItemModel::~ProxyItemModel()
|
ProxyItemModel::~ProxyItemModel()
|
||||||
{
|
{
|
||||||
delete mSourceModel;
|
delete mSourceModel;
|
||||||
|
@ -164,4 +169,18 @@ namespace MWGui
|
||||||
return mSourceModel->getIndex(item);
|
return mSourceModel->getIndex(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProxyItemModel::setSourceModel(ItemModel *sourceModel)
|
||||||
|
{
|
||||||
|
if (mSourceModel == sourceModel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mSourceModel)
|
||||||
|
{
|
||||||
|
delete mSourceModel;
|
||||||
|
mSourceModel = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSourceModel = sourceModel;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,11 +80,15 @@ namespace MWGui
|
||||||
class ProxyItemModel : public ItemModel
|
class ProxyItemModel : public ItemModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
ProxyItemModel();
|
||||||
virtual ~ProxyItemModel();
|
virtual ~ProxyItemModel();
|
||||||
virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false);
|
virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false);
|
||||||
virtual void removeItem (const ItemStack& item, size_t count);
|
virtual void removeItem (const ItemStack& item, size_t count);
|
||||||
virtual ModelIndex getIndex (ItemStack item);
|
virtual ModelIndex getIndex (ItemStack item);
|
||||||
|
|
||||||
|
/// @note Takes ownership of the passed pointer.
|
||||||
|
void setSourceModel(ItemModel* sourceModel);
|
||||||
|
|
||||||
ModelIndex mapToSource (ModelIndex index);
|
ModelIndex mapToSource (ModelIndex index);
|
||||||
ModelIndex mapFromSource (ModelIndex index);
|
ModelIndex mapFromSource (ModelIndex index);
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -30,8 +30,12 @@ ItemView::~ItemView()
|
||||||
|
|
||||||
void ItemView::setModel(ItemModel *model)
|
void ItemView::setModel(ItemModel *model)
|
||||||
{
|
{
|
||||||
|
if (mModel == model)
|
||||||
|
return;
|
||||||
|
|
||||||
delete mModel;
|
delete mModel;
|
||||||
mModel = model;
|
mModel = model;
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ namespace
|
||||||
DisplayStateStack mStates;
|
DisplayStateStack mStates;
|
||||||
Book mTopicIndexBook;
|
Book mTopicIndexBook;
|
||||||
bool mQuestMode;
|
bool mQuestMode;
|
||||||
|
bool mOptionsMode;
|
||||||
bool mAllQuests;
|
bool mAllQuests;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -182,6 +183,7 @@ namespace
|
||||||
|
|
||||||
mQuestMode = false;
|
mQuestMode = false;
|
||||||
mAllQuests = false;
|
mAllQuests = false;
|
||||||
|
mOptionsMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustButton (char const * name, bool optional = false)
|
void adjustButton (char const * name, bool optional = false)
|
||||||
|
@ -244,6 +246,7 @@ namespace
|
||||||
|
|
||||||
void setBookMode ()
|
void setBookMode ()
|
||||||
{
|
{
|
||||||
|
mOptionsMode = false;
|
||||||
setVisible (OptionsBTN, true);
|
setVisible (OptionsBTN, true);
|
||||||
setVisible (OptionsOverlay, false);
|
setVisible (OptionsOverlay, false);
|
||||||
|
|
||||||
|
@ -253,6 +256,8 @@ namespace
|
||||||
|
|
||||||
void setOptionsMode ()
|
void setOptionsMode ()
|
||||||
{
|
{
|
||||||
|
mOptionsMode = true;
|
||||||
|
|
||||||
setVisible (OptionsBTN, false);
|
setVisible (OptionsBTN, false);
|
||||||
setVisible (OptionsOverlay, true);
|
setVisible (OptionsOverlay, true);
|
||||||
|
|
||||||
|
@ -508,6 +513,8 @@ namespace
|
||||||
|
|
||||||
void notifyNextPage(MyGUI::Widget* _sender)
|
void notifyNextPage(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
|
if (mOptionsMode)
|
||||||
|
return;
|
||||||
if (!mStates.empty ())
|
if (!mStates.empty ())
|
||||||
{
|
{
|
||||||
unsigned int & page = mStates.top ().mPage;
|
unsigned int & page = mStates.top ().mPage;
|
||||||
|
@ -523,6 +530,8 @@ namespace
|
||||||
|
|
||||||
void notifyPrevPage(MyGUI::Widget* _sender)
|
void notifyPrevPage(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
|
if (mOptionsMode)
|
||||||
|
return;
|
||||||
if (!mStates.empty ())
|
if (!mStates.empty ())
|
||||||
{
|
{
|
||||||
unsigned int & page = mStates.top ().mPage;
|
unsigned int & page = mStates.top ().mPage;
|
||||||
|
|
|
@ -783,7 +783,7 @@ namespace MWGui
|
||||||
MyGUI::Widget* markerWidget = mGlobalMap->createWidget<MyGUI::Widget>("MarkerButton",
|
MyGUI::Widget* markerWidget = mGlobalMap->createWidget<MyGUI::Widget>("MarkerButton",
|
||||||
widgetCoord, MyGUI::Align::Default);
|
widgetCoord, MyGUI::Align::Default);
|
||||||
|
|
||||||
markerWidget->setUserString("Caption_TextOneLine", name);
|
markerWidget->setUserString("Caption_TextOneLine", "#{sCell=" + name + "}");
|
||||||
|
|
||||||
setGlobalMapMarkerTooltip(markerWidget, x, y);
|
setGlobalMapMarkerTooltip(markerWidget, x, y);
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,8 @@ namespace MWGui
|
||||||
|
|
||||||
void renderGlobalMap(Loading::Listener* loadingListener);
|
void renderGlobalMap(Loading::Listener* loadingListener);
|
||||||
|
|
||||||
// adds the marker to the global map
|
/// adds the marker to the global map
|
||||||
|
/// @param name The ESM::Cell::mName
|
||||||
void addVisitedLocation(const std::string& name, int x, int y);
|
void addVisitedLocation(const std::string& name, int x, int y);
|
||||||
|
|
||||||
// reveals this cell's map on the global map
|
// reveals this cell's map on the global map
|
||||||
|
|
|
@ -347,8 +347,8 @@ namespace MWGui
|
||||||
char buffer[size];
|
char buffer[size];
|
||||||
if (std::strftime(buffer, size, "%x %X", timeinfo) > 0)
|
if (std::strftime(buffer, size, "%x %X", timeinfo) > 0)
|
||||||
text << buffer << "\n";
|
text << buffer << "\n";
|
||||||
text << "Level " << mCurrentSlot->mProfile.mPlayerLevel << "\n";
|
text << "#{sLevel} " << mCurrentSlot->mProfile.mPlayerLevel << "\n";
|
||||||
text << mCurrentSlot->mProfile.mPlayerCell << "\n";
|
text << "#{sCell=" << mCurrentSlot->mProfile.mPlayerCell << "}\n";
|
||||||
// text << "Time played: " << slot->mProfile.mTimePlayed << "\n";
|
// text << "Time played: " << slot->mProfile.mTimePlayed << "\n";
|
||||||
|
|
||||||
int hour = int(mCurrentSlot->mProfile.mInGameTime.mGameHour);
|
int hour = int(mCurrentSlot->mProfile.mInGameTime.mGameHour);
|
||||||
|
|
|
@ -71,7 +71,6 @@ namespace MWGui
|
||||||
SortFilterItemModel::SortFilterItemModel(ItemModel *sourceModel)
|
SortFilterItemModel::SortFilterItemModel(ItemModel *sourceModel)
|
||||||
: mCategory(Category_All)
|
: mCategory(Category_All)
|
||||||
, mFilter(0)
|
, mFilter(0)
|
||||||
, mShowEquipped(true)
|
|
||||||
, mSortByType(true)
|
, mSortByType(true)
|
||||||
{
|
{
|
||||||
mSourceModel = sourceModel;
|
mSourceModel = sourceModel;
|
||||||
|
@ -91,9 +90,6 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
MWWorld::Ptr base = item.mBase;
|
MWWorld::Ptr base = item.mBase;
|
||||||
|
|
||||||
if (item.mType == ItemStack::Type_Equipped && !mShowEquipped)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int category = 0;
|
int category = 0;
|
||||||
if (base.getTypeName() == typeid(ESM::Armor).name()
|
if (base.getTypeName() == typeid(ESM::Armor).name()
|
||||||
|| base.getTypeName() == typeid(ESM::Clothing).name())
|
|| base.getTypeName() == typeid(ESM::Clothing).name())
|
||||||
|
|
|
@ -24,7 +24,6 @@ namespace MWGui
|
||||||
|
|
||||||
void setCategory (int category);
|
void setCategory (int category);
|
||||||
void setFilter (int filter);
|
void setFilter (int filter);
|
||||||
void setShowEquipped (bool show) { mShowEquipped = show; }
|
|
||||||
|
|
||||||
/// Use ItemStack::Type for sorting?
|
/// Use ItemStack::Type for sorting?
|
||||||
void setSortByType(bool sort) { mSortByType = sort; }
|
void setSortByType(bool sort) { mSortByType = sort; }
|
||||||
|
@ -49,7 +48,6 @@ namespace MWGui
|
||||||
|
|
||||||
int mCategory;
|
int mCategory;
|
||||||
int mFilter;
|
int mFilter;
|
||||||
bool mShowEquipped;
|
|
||||||
bool mSortByType;
|
bool mSortByType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace MWGui
|
||||||
// figure out if player will be woken while sleeping
|
// figure out if player will be woken while sleeping
|
||||||
int x = Misc::Rng::rollDice(hoursToWait);
|
int x = Misc::Rng::rollDice(hoursToWait);
|
||||||
float fSleepRandMod = world->getStore().get<ESM::GameSetting>().find("fSleepRandMod")->getFloat();
|
float fSleepRandMod = world->getStore().get<ESM::GameSetting>().find("fSleepRandMod")->getFloat();
|
||||||
if (x < fSleepRandMod * hoursToWait)
|
if (x < static_cast<int>(fSleepRandMod * hoursToWait))
|
||||||
{
|
{
|
||||||
float fSleepRestMod = world->getStore().get<ESM::GameSetting>().find("fSleepRestMod")->getFloat();
|
float fSleepRestMod = world->getStore().get<ESM::GameSetting>().find("fSleepRestMod")->getFloat();
|
||||||
mInterruptAt = hoursToWait - int(fSleepRestMod * hoursToWait);
|
mInterruptAt = hoursToWait - int(fSleepRestMod * hoursToWait);
|
||||||
|
|
|
@ -993,7 +993,7 @@ namespace MWGui
|
||||||
if (cell->getCell()->isExterior())
|
if (cell->getCell()->isExterior())
|
||||||
{
|
{
|
||||||
if (!cell->getCell()->mName.empty())
|
if (!cell->getCell()->mName.empty())
|
||||||
mMap->addVisitedLocation ("#{sCell=" + name + "}", cell->getCell()->getGridX (), cell->getCell()->getGridY ());
|
mMap->addVisitedLocation (name, cell->getCell()->getGridX (), cell->getCell()->getGridY ());
|
||||||
|
|
||||||
mMap->cellExplored (cell->getCell()->getGridX(), cell->getCell()->getGridY());
|
mMap->cellExplored (cell->getCell()->getGridX(), cell->getCell()->getGridY());
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,15 +247,16 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
|
||||||
bool block = mPtr.getClass().getCreatureStats(mPtr).getBlock();
|
bool block = mPtr.getClass().getCreatureStats(mPtr).getBlock();
|
||||||
if(mHitState == CharState_None)
|
if(mHitState == CharState_None)
|
||||||
{
|
{
|
||||||
if (mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() < 0
|
if ((mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() < 0
|
||||||
|| mPtr.getClass().getCreatureStats(mPtr).getFatigue().getBase() == 0)
|
|| mPtr.getClass().getCreatureStats(mPtr).getFatigue().getBase() == 0)
|
||||||
|
&& mAnimation->hasAnimation("knockout"))
|
||||||
{
|
{
|
||||||
mHitState = CharState_KnockOut;
|
mHitState = CharState_KnockOut;
|
||||||
mCurrentHit = "knockout";
|
mCurrentHit = "knockout";
|
||||||
mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, false, 1, "start", "stop", 0.0f, ~0ul);
|
mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, false, 1, "start", "stop", 0.0f, ~0ul);
|
||||||
mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(true);
|
mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(true);
|
||||||
}
|
}
|
||||||
else if(knockdown)
|
else if(knockdown && mAnimation->hasAnimation("knockdown"))
|
||||||
{
|
{
|
||||||
mHitState = CharState_KnockDown;
|
mHitState = CharState_KnockDown;
|
||||||
mCurrentHit = "knockdown";
|
mCurrentHit = "knockdown";
|
||||||
|
@ -263,11 +264,15 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
|
||||||
}
|
}
|
||||||
else if (recovery)
|
else if (recovery)
|
||||||
{
|
{
|
||||||
mHitState = CharState_Hit;
|
std::string anim = chooseRandomGroup("hit");
|
||||||
mCurrentHit = chooseRandomGroup("hit");
|
if (mAnimation->hasAnimation(anim))
|
||||||
mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0);
|
{
|
||||||
|
mHitState = CharState_Hit;
|
||||||
|
mCurrentHit = anim;
|
||||||
|
mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (block)
|
else if (block && mAnimation->hasAnimation("shield"))
|
||||||
{
|
{
|
||||||
mHitState = CharState_Block;
|
mHitState = CharState_Block;
|
||||||
mCurrentHit = "shield";
|
mCurrentHit = "shield";
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace MWMechanics
|
||||||
void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick,
|
void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick,
|
||||||
std::string& resultMessage, std::string& resultSound)
|
std::string& resultMessage, std::string& resultSound)
|
||||||
{
|
{
|
||||||
if (!(lock.getCellRef().getLockLevel() > 0)) //If it's unlocked back out immediately
|
if (!(lock.getCellRef().getLockLevel() > 0) || !lock.getClass().canLock(lock)) //If it's unlocked back out immediately
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int lockStrength = lock.getCellRef().getLockLevel();
|
int lockStrength = lock.getCellRef().getLockLevel();
|
||||||
|
|
|
@ -489,8 +489,8 @@ namespace MWMechanics
|
||||||
if (!wasDead && isDead)
|
if (!wasDead && isDead)
|
||||||
MWBase::Environment::get().getMechanicsManager()->actorKilled(target, caster);
|
MWBase::Environment::get().getMechanicsManager()->actorKilled(target, caster);
|
||||||
}
|
}
|
||||||
else
|
else if (!applyInstantEffect(target, caster, EffectKey(*effectIt), magnitude))
|
||||||
applyInstantEffect(target, caster, EffectKey(*effectIt), magnitude);
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-casting a summon effect will remove the creature from previous castings of that effect.
|
// Re-casting a summon effect will remove the creature from previous castings of that effect.
|
||||||
|
@ -559,10 +559,10 @@ namespace MWMechanics
|
||||||
target.getClass().onHit(target, 0.f, true, MWWorld::Ptr(), caster, true);
|
target.getClass().onHit(target, 0.f, true, MWWorld::Ptr(), caster, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CastSpell::applyInstantEffect(const MWWorld::Ptr &target, const MWWorld::Ptr &caster, const MWMechanics::EffectKey& effect, float magnitude)
|
bool CastSpell::applyInstantEffect(const MWWorld::Ptr &target, const MWWorld::Ptr &caster, const MWMechanics::EffectKey& effect, float magnitude)
|
||||||
{
|
{
|
||||||
short effectId = effect.mId;
|
short effectId = effect.mId;
|
||||||
if (!target.getClass().isActor())
|
if (target.getClass().canLock(target))
|
||||||
{
|
{
|
||||||
if (effectId == ESM::MagicEffect::Lock)
|
if (effectId == ESM::MagicEffect::Lock)
|
||||||
{
|
{
|
||||||
|
@ -570,8 +570,9 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
if (caster == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
if (caster == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicLockSuccess}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicLockSuccess}");
|
||||||
target.getCellRef().setLockLevel(static_cast<int>(magnitude));
|
target.getClass().lock(target, static_cast<int>(magnitude));
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (effectId == ESM::MagicEffect::Open)
|
else if (effectId == ESM::MagicEffect::Open)
|
||||||
{
|
{
|
||||||
|
@ -586,47 +587,59 @@ namespace MWMechanics
|
||||||
if (caster == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
if (caster == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicOpenSuccess}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicOpenSuccess}");
|
||||||
}
|
}
|
||||||
target.getCellRef().setLockLevel(-abs(target.getCellRef().getLockLevel()));
|
target.getClass().unlock(target);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock Fail", 1.f, 1.f);
|
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock Fail", 1.f, 1.f);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (target.getClass().isActor())
|
||||||
{
|
{
|
||||||
if (effectId == ESM::MagicEffect::CurePoison)
|
switch (effectId)
|
||||||
|
{
|
||||||
|
case ESM::MagicEffect::CurePoison:
|
||||||
target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect(ESM::MagicEffect::Poison);
|
target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect(ESM::MagicEffect::Poison);
|
||||||
else if (effectId == ESM::MagicEffect::CureParalyzation)
|
return true;
|
||||||
|
case ESM::MagicEffect::CureParalyzation:
|
||||||
target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect(ESM::MagicEffect::Paralyze);
|
target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect(ESM::MagicEffect::Paralyze);
|
||||||
else if (effectId == ESM::MagicEffect::CureCommonDisease)
|
return true;
|
||||||
|
case ESM::MagicEffect::CureCommonDisease:
|
||||||
target.getClass().getCreatureStats(target).getSpells().purgeCommonDisease();
|
target.getClass().getCreatureStats(target).getSpells().purgeCommonDisease();
|
||||||
else if (effectId == ESM::MagicEffect::CureBlightDisease)
|
return true;
|
||||||
|
case ESM::MagicEffect::CureBlightDisease:
|
||||||
target.getClass().getCreatureStats(target).getSpells().purgeBlightDisease();
|
target.getClass().getCreatureStats(target).getSpells().purgeBlightDisease();
|
||||||
else if (effectId == ESM::MagicEffect::CureCorprusDisease)
|
return true;
|
||||||
|
case ESM::MagicEffect::CureCorprusDisease:
|
||||||
target.getClass().getCreatureStats(target).getSpells().purgeCorprusDisease();
|
target.getClass().getCreatureStats(target).getSpells().purgeCorprusDisease();
|
||||||
else if (effectId == ESM::MagicEffect::Dispel)
|
return true;
|
||||||
|
case ESM::MagicEffect::Dispel:
|
||||||
target.getClass().getCreatureStats(target).getActiveSpells().purgeAll(magnitude);
|
target.getClass().getCreatureStats(target).getActiveSpells().purgeAll(magnitude);
|
||||||
else if (effectId == ESM::MagicEffect::RemoveCurse)
|
return true;
|
||||||
|
case ESM::MagicEffect::RemoveCurse:
|
||||||
target.getClass().getCreatureStats(target).getSpells().purgeCurses();
|
target.getClass().getCreatureStats(target).getSpells().purgeCurses();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (target != MWBase::Environment::get().getWorld()->getPlayerPtr())
|
if (target != MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
return;
|
return false;
|
||||||
if (!MWBase::Environment::get().getWorld()->isTeleportingEnabled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (effectId == ESM::MagicEffect::DivineIntervention)
|
if (effectId == ESM::MagicEffect::DivineIntervention)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "divinemarker");
|
MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "divinemarker");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (effectId == ESM::MagicEffect::AlmsiviIntervention)
|
else if (effectId == ESM::MagicEffect::AlmsiviIntervention)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "templemarker");
|
MWBase::Environment::get().getWorld()->teleportToClosestMarker(target, "templemarker");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (effectId == ESM::MagicEffect::Mark)
|
else if (effectId == ESM::MagicEffect::Mark)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWorld()->getPlayer().markPosition(
|
MWBase::Environment::get().getWorld()->getPlayer().markPosition(
|
||||||
target.getCell(), target.getRefData().getPosition());
|
target.getCell(), target.getRefData().getPosition());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (effectId == ESM::MagicEffect::Recall)
|
else if (effectId == ESM::MagicEffect::Recall)
|
||||||
{
|
{
|
||||||
|
@ -640,8 +653,10 @@ namespace MWMechanics
|
||||||
markedPosition, false);
|
markedPosition, false);
|
||||||
action.execute(target);
|
action.execute(target);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -926,7 +941,8 @@ namespace MWMechanics
|
||||||
MWWorld::InventoryStore& inv = ptr.getClass().getInventoryStore(ptr);
|
MWWorld::InventoryStore& inv = ptr.getClass().getInventoryStore(ptr);
|
||||||
MWWorld::ContainerStoreIterator item =
|
MWWorld::ContainerStoreIterator item =
|
||||||
inv.getSlot(slot);
|
inv.getSlot(slot);
|
||||||
if (item != inv.end())
|
|
||||||
|
if (item != inv.end() && (item.getType() == MWWorld::ContainerStore::Type_Armor || item.getType() == MWWorld::ContainerStore::Type_Weapon))
|
||||||
{
|
{
|
||||||
if (!item->getClass().hasItemHealth(*item))
|
if (!item->getClass().hasItemHealth(*item))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -97,7 +97,8 @@ namespace MWMechanics
|
||||||
const ESM::EffectList& effects, ESM::RangeType range, bool reflected=false, bool exploded=false);
|
const ESM::EffectList& effects, ESM::RangeType range, bool reflected=false, bool exploded=false);
|
||||||
|
|
||||||
/// @note \a caster can be any type of object, or even an empty object.
|
/// @note \a caster can be any type of object, or even an empty object.
|
||||||
void applyInstantEffect (const MWWorld::Ptr& target, const MWWorld::Ptr& caster, const MWMechanics::EffectKey& effect, float magnitude);
|
/// @return was the target suitable for the effect?
|
||||||
|
bool applyInstantEffect (const MWWorld::Ptr& target, const MWWorld::Ptr& caster, const MWMechanics::EffectKey& effect, float magnitude);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,6 +208,38 @@ namespace
|
||||||
std::vector<osg::Node*> mToRemove;
|
std::vector<osg::Node*> mToRemove;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RemoveTriBipVisitor : public osg::NodeVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RemoveTriBipVisitor()
|
||||||
|
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void apply(osg::Geode &node)
|
||||||
|
{
|
||||||
|
const std::string toFind = "tri bip";
|
||||||
|
if (Misc::StringUtils::ciCompareLen(node.getName(), toFind, toFind.size()) == 0)
|
||||||
|
{
|
||||||
|
// Not safe to remove in apply(), since the visitor is still iterating the child list
|
||||||
|
mToRemove.push_back(&node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove()
|
||||||
|
{
|
||||||
|
for (std::vector<osg::Node*>::iterator it = mToRemove.begin(); it != mToRemove.end(); ++it)
|
||||||
|
{
|
||||||
|
osg::Node* node = *it;
|
||||||
|
if (node->getNumParents())
|
||||||
|
node->getParent(0)->removeChild(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<osg::Node*> mToRemove;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
|
@ -898,7 +930,7 @@ namespace MWRender
|
||||||
return movement;
|
return movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly)
|
void Animation::setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature)
|
||||||
{
|
{
|
||||||
if (mObjectRoot)
|
if (mObjectRoot)
|
||||||
{
|
{
|
||||||
|
@ -933,6 +965,13 @@ namespace MWRender
|
||||||
removeDrawableVisitor.remove();
|
removeDrawableVisitor.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isCreature)
|
||||||
|
{
|
||||||
|
RemoveTriBipVisitor removeTriBipVisitor;
|
||||||
|
mObjectRoot->accept(removeTriBipVisitor);
|
||||||
|
removeTriBipVisitor.remove();
|
||||||
|
}
|
||||||
|
|
||||||
NodeMapVisitor visitor;
|
NodeMapVisitor visitor;
|
||||||
mObjectRoot->accept(visitor);
|
mObjectRoot->accept(visitor);
|
||||||
mNodeMap = visitor.getNodeMap();
|
mNodeMap = visitor.getNodeMap();
|
||||||
|
@ -1308,7 +1347,7 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
if (!model.empty())
|
if (!model.empty())
|
||||||
{
|
{
|
||||||
setObjectRoot(model, false, false);
|
setObjectRoot(model, false, false, false);
|
||||||
if (animated)
|
if (animated)
|
||||||
addAnimSource(model);
|
addAnimSource(model);
|
||||||
|
|
||||||
|
|
|
@ -273,7 +273,7 @@ protected:
|
||||||
* @param baseonly If true, then any meshes or particle systems in the model are ignored
|
* @param baseonly If true, then any meshes or particle systems in the model are ignored
|
||||||
* (useful for NPCs, where only the skeleton is needed for the root, and the actual NPC parts are then assembled from separate files).
|
* (useful for NPCs, where only the skeleton is needed for the root, and the actual NPC parts are then assembled from separate files).
|
||||||
*/
|
*/
|
||||||
void setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly);
|
void setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature);
|
||||||
|
|
||||||
/* Adds the keyframe controllers in the specified model as a new animation source. Note that
|
/* Adds the keyframe controllers in the specified model as a new animation source. Note that
|
||||||
* the filename portion of the provided model name will be prepended with 'x', and the .nif
|
* the filename portion of the provided model name will be prepended with 'x', and the .nif
|
||||||
|
|
|
@ -24,7 +24,7 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr,
|
||||||
|
|
||||||
if(!model.empty())
|
if(!model.empty())
|
||||||
{
|
{
|
||||||
setObjectRoot(model, false, false);
|
setObjectRoot(model, false, false, true);
|
||||||
|
|
||||||
if((ref->mBase->mFlags&ESM::Creature::Bipedal))
|
if((ref->mBase->mFlags&ESM::Creature::Bipedal))
|
||||||
addAnimSource("meshes\\xbase_anim.nif");
|
addAnimSource("meshes\\xbase_anim.nif");
|
||||||
|
@ -42,7 +42,7 @@ CreatureWeaponAnimation::CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const
|
||||||
|
|
||||||
if(!model.empty())
|
if(!model.empty())
|
||||||
{
|
{
|
||||||
setObjectRoot(model, true, false);
|
setObjectRoot(model, true, false, true);
|
||||||
|
|
||||||
if((ref->mBase->mFlags&ESM::Creature::Bipedal))
|
if((ref->mBase->mFlags&ESM::Creature::Bipedal))
|
||||||
addAnimSource("meshes\\xbase_anim.nif");
|
addAnimSource("meshes\\xbase_anim.nif");
|
||||||
|
|
|
@ -378,7 +378,7 @@ void NpcAnimation::updateNpcBase()
|
||||||
: "meshes\\wolf\\skin.1st.nif");
|
: "meshes\\wolf\\skin.1st.nif");
|
||||||
smodel = Misc::ResourceHelpers::correctActorModelPath(smodel, mResourceSystem->getVFS());
|
smodel = Misc::ResourceHelpers::correctActorModelPath(smodel, mResourceSystem->getVFS());
|
||||||
|
|
||||||
setObjectRoot(smodel, true, true);
|
setObjectRoot(smodel, true, true, false);
|
||||||
|
|
||||||
if(mViewMode != VM_FirstPerson)
|
if(mViewMode != VM_FirstPerson)
|
||||||
{
|
{
|
||||||
|
|
|
@ -144,6 +144,11 @@ namespace MWWorld
|
||||||
throw std::runtime_error ("class does not support unlocking");
|
throw std::runtime_error ("class does not support unlocking");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Class::canLock(const Ptr &ptr) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Class::setRemainingUsageTime (const Ptr& ptr, float duration) const
|
void Class::setRemainingUsageTime (const Ptr& ptr, float duration) const
|
||||||
{
|
{
|
||||||
throw std::runtime_error ("class does not support time-based uses");
|
throw std::runtime_error ("class does not support time-based uses");
|
||||||
|
|
|
@ -161,6 +161,8 @@ namespace MWWorld
|
||||||
virtual void unlock (const Ptr& ptr) const;
|
virtual void unlock (const Ptr& ptr) const;
|
||||||
///< Unlock object (default implementation: throw an exception)
|
///< Unlock object (default implementation: throw an exception)
|
||||||
|
|
||||||
|
virtual bool canLock (const Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void setRemainingUsageTime (const Ptr& ptr, float duration) const;
|
virtual void setRemainingUsageTime (const Ptr& ptr, float duration) const;
|
||||||
///< Sets the remaining duration of the object, such as an equippable light
|
///< Sets the remaining duration of the object, such as an equippable light
|
||||||
/// source. (default implementation: throw an exception)
|
/// source. (default implementation: throw an exception)
|
||||||
|
|
|
@ -228,6 +228,7 @@ namespace MWWorld
|
||||||
if (findExteriorPosition (mStartCell, pos))
|
if (findExteriorPosition (mStartCell, pos))
|
||||||
{
|
{
|
||||||
changeToExteriorCell (pos);
|
changeToExteriorCell (pos);
|
||||||
|
fixPosition(getPlayerPtr());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2623,12 +2624,10 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
|
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
|
||||||
|
|
||||||
// Get the target to use for "on touch" effects
|
// Get the target to use for "on touch" effects, using the facing direction from Head node
|
||||||
MWWorld::Ptr target;
|
MWWorld::Ptr target;
|
||||||
float distance = 192.f; // ??
|
float distance = 192.f; // ??
|
||||||
osg::Vec3f hitPosition = actor.getRefData().getPosition().asVec3();
|
osg::Vec3f hitPosition = actor.getRefData().getPosition().asVec3();
|
||||||
|
|
||||||
// For NPCs use facing direction from Head node
|
|
||||||
osg::Vec3f origin(actor.getRefData().getPosition().asVec3());
|
osg::Vec3f origin(actor.getRefData().getPosition().asVec3());
|
||||||
|
|
||||||
MWRender::Animation* anim = mRendering->getAnimation(actor);
|
MWRender::Animation* anim = mRendering->getAnimation(actor);
|
||||||
|
@ -2651,13 +2650,33 @@ namespace MWWorld
|
||||||
osg::Vec3f direction = orient * osg::Vec3f(0,1,0);
|
osg::Vec3f direction = orient * osg::Vec3f(0,1,0);
|
||||||
osg::Vec3f dest = origin + direction * distance;
|
osg::Vec3f dest = origin + direction * distance;
|
||||||
|
|
||||||
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(origin, dest, actor);
|
// For actor targets, we want to use bounding boxes (physics raycast).
|
||||||
target = result.mHitObject;
|
// This is to give a slight tolerance for errors, especially with creatures like the Skeleton that would be very hard to aim at otherwise.
|
||||||
hitPosition = result.mHitPos;
|
// For object targets, we want the detailed shapes (rendering raycast).
|
||||||
|
// If we used the bounding boxes for static objects, then we would not be able to target e.g. objects lying on a shelf.
|
||||||
|
|
||||||
// don't allow casting on non-activatable objects
|
MWPhysics::PhysicsSystem::RayResult result1 = mPhysics->castRay(origin, dest, actor, MWPhysics::CollisionType_Actor);
|
||||||
if (!target.isEmpty() && !target.getClass().isActor() && target.getClass().getName(target).empty())
|
|
||||||
target = MWWorld::Ptr();
|
MWRender::RenderingManager::RayResult result2 = mRendering->castRay(origin, dest, true, true);
|
||||||
|
|
||||||
|
float dist1 = FLT_MAX;
|
||||||
|
float dist2 = FLT_MAX;
|
||||||
|
|
||||||
|
if (result1.mHit)
|
||||||
|
dist1 = (origin - result1.mHitPos).length();
|
||||||
|
if (result2.mHit)
|
||||||
|
dist2 = (origin - result2.mHitPointWorld).length();
|
||||||
|
|
||||||
|
if (dist1 <= dist2 && result1.mHit)
|
||||||
|
{
|
||||||
|
target = result1.mHitObject;
|
||||||
|
hitPosition = result1.mHitPos;
|
||||||
|
}
|
||||||
|
else if (result2.mHit)
|
||||||
|
{
|
||||||
|
target = result2.mHitObject;
|
||||||
|
hitPosition = result2.mHitPointWorld;
|
||||||
|
}
|
||||||
|
|
||||||
std::string selectedSpell = stats.getSpells().getSelectedSpell();
|
std::string selectedSpell = stats.getSpells().getSelectedSpell();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue