mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-30 19:41:34 +00:00
new alternate
This commit is contained in:
commit
eadad7a4b3
12 changed files with 108 additions and 46 deletions
|
@ -80,7 +80,9 @@
|
|||
Bug #6386: Artifacts in water reflection due to imprecise screen-space coordinate computation
|
||||
Bug #6396: Inputting certain Unicode characters triggers an assertion
|
||||
Bug #6416: Morphs are applied to the wrong target
|
||||
Bug #6417: OpenMW doesn't always use the right node to accumulate movement
|
||||
Bug #6429: Wyrmhaven: Can't add AI packages to player
|
||||
Bug #6433: Items bound to Quick Keys sometimes do not appear until the Quick Key menu is opened.
|
||||
Feature #890: OpenMW-CS: Column filtering
|
||||
Feature #1465: "Reset" argument for AI functions
|
||||
Feature #2554: Modifying an object triggers the instances table to scroll to the corresponding record
|
||||
|
|
|
@ -69,6 +69,7 @@ namespace MWGui
|
|||
class DialogueWindow;
|
||||
class WindowModal;
|
||||
class JailScreen;
|
||||
class MessageBox;
|
||||
|
||||
enum ShowInDialogueMode {
|
||||
ShowInDialogueMode_IfPossible,
|
||||
|
@ -145,6 +146,7 @@ namespace MWBase
|
|||
virtual MWGui::CountDialog* getCountDialog() = 0;
|
||||
virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0;
|
||||
virtual MWGui::TradeWindow* getTradeWindow() = 0;
|
||||
virtual const std::vector<MWGui::MessageBox*> getActiveMessageBoxes() = 0;
|
||||
|
||||
/// Make the player use an item, while updating GUI state accordingly
|
||||
virtual void useItem(const MWWorld::Ptr& item, bool force=false) = 0;
|
||||
|
|
|
@ -170,6 +170,12 @@ namespace MWGui
|
|||
return false;
|
||||
}
|
||||
|
||||
const std::vector<MessageBox*> MessageBoxManager::getActiveMessageBoxes()
|
||||
{
|
||||
return mMessageBoxes;
|
||||
}
|
||||
|
||||
|
||||
int MessageBoxManager::readPressedButton (bool reset)
|
||||
{
|
||||
int pressed = mLastButtonPressed;
|
||||
|
@ -211,6 +217,11 @@ namespace MWGui
|
|||
mMainWidget->setPosition(pos);
|
||||
}
|
||||
|
||||
const std::string MessageBox::getMessage()
|
||||
{
|
||||
return mMessage;
|
||||
}
|
||||
|
||||
int MessageBox::getHeight ()
|
||||
{
|
||||
return mMainWidget->getHeight()+mNextBoxPadding;
|
||||
|
|
|
@ -49,6 +49,8 @@ namespace MWGui
|
|||
|
||||
void setVisible(bool value);
|
||||
|
||||
const std::vector<MessageBox*> getActiveMessageBoxes();
|
||||
|
||||
private:
|
||||
std::vector<MessageBox*> mMessageBoxes;
|
||||
InteractiveMessageBox* mInterMessageBoxe;
|
||||
|
@ -63,6 +65,7 @@ namespace MWGui
|
|||
public:
|
||||
MessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message);
|
||||
void setMessage (const std::string& message);
|
||||
const std::string getMessage();
|
||||
int getHeight ();
|
||||
void update (int height);
|
||||
void setVisible(bool value);
|
||||
|
@ -73,7 +76,7 @@ namespace MWGui
|
|||
|
||||
protected:
|
||||
MessageBoxManager& mMessageBoxManager;
|
||||
const std::string& mMessage;
|
||||
const std::string mMessage;
|
||||
MyGUI::EditBox* mMessageWidget;
|
||||
int mBottomPadding;
|
||||
int mNextBoxPadding;
|
||||
|
|
|
@ -79,41 +79,45 @@ namespace MWGui
|
|||
delete mMagicSelectionDialog;
|
||||
}
|
||||
|
||||
inline void QuickKeysMenu::validate(int index)
|
||||
{
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
|
||||
switch (mKey[index].type)
|
||||
{
|
||||
case Type_Unassigned:
|
||||
case Type_HandToHand:
|
||||
case Type_Magic:
|
||||
break;
|
||||
case Type_Item:
|
||||
case Type_MagicItem:
|
||||
{
|
||||
MWWorld::Ptr item = *mKey[index].button->getUserData<MWWorld::Ptr>();
|
||||
// Make sure the item is available and is not broken
|
||||
if (!item || item.getRefData().getCount() < 1 ||
|
||||
(item.getClass().hasItemHealth(item) &&
|
||||
item.getClass().getItemHealth(item) <= 0))
|
||||
{
|
||||
// Try searching for a compatible replacement
|
||||
item = store.findReplacement(mKey[index].id);
|
||||
|
||||
if (item)
|
||||
mKey[index].button->setUserData(MWWorld::Ptr(item));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QuickKeysMenu::onOpen()
|
||||
{
|
||||
WindowBase::onOpen();
|
||||
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
|
||||
|
||||
// Check if quick keys are still valid
|
||||
for (int i=0; i<10; ++i)
|
||||
// Quick key index
|
||||
for (int index = 0; index < 10; ++index)
|
||||
{
|
||||
switch (mKey[i].type)
|
||||
{
|
||||
case Type_Unassigned:
|
||||
case Type_HandToHand:
|
||||
case Type_Magic:
|
||||
break;
|
||||
case Type_Item:
|
||||
case Type_MagicItem:
|
||||
{
|
||||
MWWorld::Ptr item = *mKey[i].button->getUserData<MWWorld::Ptr>();
|
||||
// Make sure the item is available and is not broken
|
||||
if (!item || item.getRefData().getCount() < 1 ||
|
||||
(item.getClass().hasItemHealth(item) &&
|
||||
item.getClass().getItemHealth(item) <= 0))
|
||||
{
|
||||
// Try searching for a compatible replacement
|
||||
item = store.findReplacement(mKey[i].id);
|
||||
|
||||
if (item)
|
||||
mKey[i].button->setUserData(MWWorld::Ptr(item));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
validate(index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,11 +333,13 @@ namespace MWGui
|
|||
assert(index >= 1 && index <= 10);
|
||||
|
||||
keyData *key = &mKey[index-1];
|
||||
|
||||
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
|
||||
const MWMechanics::CreatureStats &playerStats = player.getClass().getCreatureStats(player);
|
||||
|
||||
validate(index-1);
|
||||
|
||||
// Delay action executing,
|
||||
// if player is busy for now (casting a spell, attacking someone, etc.)
|
||||
bool isDelayNeeded = MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player)
|
||||
|
|
|
@ -76,7 +76,8 @@ namespace MWGui
|
|||
|
||||
void onQuickKeyButtonClicked(MyGUI::Widget* sender);
|
||||
void onOkButtonClicked(MyGUI::Widget* sender);
|
||||
|
||||
// Check if quick key is still valid
|
||||
inline void validate(int index);
|
||||
void unassign(keyData* key);
|
||||
};
|
||||
|
||||
|
|
|
@ -771,6 +771,11 @@ namespace MWGui
|
|||
mMessageBoxManager->removeStaticMessageBox();
|
||||
}
|
||||
|
||||
const std::vector<MWGui::MessageBox*> WindowManager::getActiveMessageBoxes()
|
||||
{
|
||||
return mMessageBoxManager->getActiveMessageBoxes();
|
||||
}
|
||||
|
||||
int WindowManager::readPressedButton ()
|
||||
{
|
||||
return mMessageBoxManager->readPressedButton();
|
||||
|
|
|
@ -187,6 +187,7 @@ namespace MWGui
|
|||
MWGui::CountDialog* getCountDialog() override;
|
||||
MWGui::ConfirmationDialog* getConfirmationDialog() override;
|
||||
MWGui::TradeWindow* getTradeWindow() override;
|
||||
const std::vector<MWGui::MessageBox*> getActiveMessageBoxes() override;
|
||||
|
||||
/// Make the player use an item, while updating GUI state accordingly
|
||||
void useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions=false) override;
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "../mwmechanics/npcstats.hpp"
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
|
||||
#include "../mwgui/messagebox.hpp"
|
||||
|
||||
#include "actions.hpp"
|
||||
#include "bindingsmanager.hpp"
|
||||
|
||||
|
@ -40,6 +42,7 @@ namespace MWInput
|
|||
, mSneaking(false)
|
||||
, mAttemptJump(false)
|
||||
, mTimeIdle(0.f)
|
||||
, mOverencumberedMessage("#{sNotifyMessage59}")
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -96,7 +99,17 @@ namespace MWInput
|
|||
if (playerPtr.getClass().getEncumbrance(playerPtr) > playerPtr.getClass().getCapacity(playerPtr))
|
||||
{
|
||||
player.setAutoMove (false);
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage59}");
|
||||
std::vector<MWGui::MessageBox*> msgboxs = MWBase::Environment::get().getWindowManager()->getActiveMessageBoxes();
|
||||
const std::vector<MWGui::MessageBox*>::iterator it = std::find_if(msgboxs.begin(), msgboxs.end(), [=](MWGui::MessageBox*& msgbox)
|
||||
{
|
||||
return (msgbox->getMessage() == mOverencumberedMessage);
|
||||
});
|
||||
|
||||
// if an overencumbered messagebox is already present, reset its expiry timer, otherwise create new one.
|
||||
if (it != msgboxs.end())
|
||||
(*it)->mCurrentTime = 0;
|
||||
else
|
||||
MWBase::Environment::get().getWindowManager()->messageBox(mOverencumberedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@ namespace MWInput
|
|||
bool mSneaking;
|
||||
bool mAttemptJump;
|
||||
|
||||
const std::string mOverencumberedMessage;
|
||||
|
||||
float mTimeIdle;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -624,9 +624,8 @@ namespace MWRender
|
|||
return;
|
||||
|
||||
const NodeMap& nodeMap = getNodeMap();
|
||||
|
||||
for (SceneUtil::KeyframeHolder::KeyframeControllerMap::const_iterator it = animsrc->mKeyframes->mKeyframeControllers.begin();
|
||||
it != animsrc->mKeyframes->mKeyframeControllers.end(); ++it)
|
||||
const auto& controllerMap = animsrc->mKeyframes->mKeyframeControllers;
|
||||
for (SceneUtil::KeyframeHolder::KeyframeControllerMap::const_iterator it = controllerMap.begin(); it != controllerMap.end(); ++it)
|
||||
{
|
||||
std::string bonename = Misc::StringUtils::lowerCase(it->first);
|
||||
NodeMap::const_iterator found = nodeMap.find(bonename);
|
||||
|
@ -652,14 +651,32 @@ namespace MWRender
|
|||
SceneUtil::AssignControllerSourcesVisitor assignVisitor(mAnimationTimePtr[0]);
|
||||
mObjectRoot->accept(assignVisitor);
|
||||
|
||||
// Determine the movement accumulation bone if necessary
|
||||
if (!mAccumRoot)
|
||||
{
|
||||
NodeMap::const_iterator found = nodeMap.find("bip01");
|
||||
if (found == nodeMap.end())
|
||||
found = nodeMap.find("root bone");
|
||||
|
||||
if (found != nodeMap.end())
|
||||
mAccumRoot = found->second;
|
||||
// Priority matters! bip01 is preferred.
|
||||
static const std::array<std::string, 2> accumRootNames =
|
||||
{
|
||||
"bip01",
|
||||
"root bone"
|
||||
};
|
||||
NodeMap::const_iterator found = nodeMap.end();
|
||||
for (const std::string& name : accumRootNames)
|
||||
{
|
||||
found = nodeMap.find(name);
|
||||
if (found == nodeMap.end())
|
||||
continue;
|
||||
for (SceneUtil::KeyframeHolder::KeyframeControllerMap::const_iterator it = controllerMap.begin(); it != controllerMap.end(); ++it)
|
||||
{
|
||||
if (Misc::StringUtils::lowerCase(it->first) == name)
|
||||
{
|
||||
mAccumRoot = found->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mAccumRoot)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,8 +56,6 @@ static const char exec_err[] = "!!! Failed to exec debug process\n";
|
|||
|
||||
static char argv0[PATH_MAX];
|
||||
|
||||
static char altstack[SIGSTKSZ];
|
||||
|
||||
|
||||
static struct {
|
||||
int signum;
|
||||
|
@ -475,9 +473,10 @@ int crashCatcherInstallHandlers(int argc, char **argv, int num_signals, int *sig
|
|||
|
||||
/* Set an alternate signal stack so SIGSEGVs caused by stack overflows
|
||||
* still run */
|
||||
static char* altstack = new char [SIGSTKSZ];
|
||||
altss.ss_sp = altstack;
|
||||
altss.ss_flags = 0;
|
||||
altss.ss_size = sizeof(altstack);
|
||||
altss.ss_size = SIGSTKSZ;
|
||||
sigaltstack(&altss, nullptr);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
|
|
Loading…
Reference in a new issue