forked from mirror/openmw-tes3mp
Merge branch 'master' into 'win10_ci'
# Conflicts: # CI/before_script.msvc.sh
This commit is contained in:
commit
739c49d59b
18 changed files with 407 additions and 361 deletions
|
@ -22,6 +22,7 @@ Programmers
|
|||
alexanderkjall
|
||||
Alexander Nadeau (wareya)
|
||||
Alexander Olofsson (Ace)
|
||||
Alex S (docwest)
|
||||
Allofich
|
||||
Andrei Kortunov (akortunov)
|
||||
AnyOldName3
|
||||
|
@ -63,6 +64,7 @@ Programmers
|
|||
Evgeniy Mineev (sandstranger)
|
||||
Federico Guerra (FedeWar)
|
||||
Fil Krynicki (filkry)
|
||||
Finbar Crago (finbar-crago)
|
||||
Florian Weber (Florianjw)
|
||||
Gašper Sedej
|
||||
gugus/gus
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
Bug #1990: Sunrise/sunset not set correct
|
||||
Bug #2222: Fatigue's effect on selling price is backwards
|
||||
Bug #2326: After a bound item expires the last equipped item of that type is not automatically re-equipped
|
||||
Bug #2455: Creatures attacks degrade armor
|
||||
Bug #2562: Forcing AI to activate a teleport door sometimes causes a crash
|
||||
Bug #2772: Non-existing class or faction freezes the game
|
||||
Bug #2835: Player able to slowly move when overencumbered
|
||||
|
@ -48,14 +49,17 @@
|
|||
Bug #4459: NotCell dialogue condition doesn't support partial matches
|
||||
Bug #4461: "Open" spell from non-player caster isn't a crime
|
||||
Bug #4469: Abot Silt Striders – Model turn 90 degrees on horizontal
|
||||
Bug #4471: Retrieve SDL window settings instead of using magic numbers
|
||||
Bug #4474: No fallback when getVampireHead fails
|
||||
Bug #4475: Scripted animations should not cause movement
|
||||
Bug #4479: "Game" category on Advanced page is getting too long
|
||||
Bug #4480: Segfalt in QuickKeysMenu when item no longer in inventory
|
||||
Feature #3276: Editor: Search- Show number of (remaining) search results and indicate a search without any results
|
||||
Feature #3641: Editor: Limit FPS in 3d preview window
|
||||
Feature #4222: 360° screenshots
|
||||
Feature #4256: Implement ToggleBorders (TB) console command
|
||||
Feature #4324: Add CFBundleIdentifier in Info.plist to allow for macOS function key shortcuts
|
||||
Feature #4345: Add equivalents for the command line commands to Launcher
|
||||
Feature #4404: Editor: All EnumDelegate fields should have their items sorted alphabetically
|
||||
Feature #4444: Per-group KF-animation files support
|
||||
Feature #4466: Editor: Add option to ignore "Base" records when running verifier
|
||||
|
||||
|
|
|
@ -452,6 +452,7 @@ fi
|
|||
add_cmake_opts -DBOOST_ROOT="$BOOST_SDK" \
|
||||
-DBOOST_LIBRARYDIR="${BOOST_SDK}/lib${BITS}-msvc-${MSVC_VER}.${LIB_SUFFIX}"
|
||||
add_cmake_opts -DBoost_COMPILER="-${TOOLSET}"
|
||||
|
||||
echo Done.
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -73,18 +73,8 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||
loadSettingBool(canLootDuringDeathAnimationCheckBox, "can loot during death animation", "Game");
|
||||
loadSettingBool(followersAttackOnSightCheckBox, "followers attack on sight", "Game");
|
||||
loadSettingBool(preventMerchantEquippingCheckBox, "prevent merchant equipping", "Game");
|
||||
loadSettingBool(showEffectDurationCheckBox, "show effect duration", "Game");
|
||||
loadSettingBool(showEnchantChanceCheckBox, "show enchant chance", "Game");
|
||||
loadSettingBool(showMeleeInfoCheckBox, "show melee info", "Game");
|
||||
loadSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
|
||||
loadSettingBool(rebalanceSoulGemValuesCheckBox, "rebalance soul gem values", "Game");
|
||||
|
||||
// Expected values are (0, 1, 2, 3)
|
||||
int showOwnedIndex = mEngineSettings.getInt("show owned", "Game");
|
||||
// Match the index with the option. Will default to 0 if invalid.
|
||||
if (showOwnedIndex >= 0 && showOwnedIndex <= 3)
|
||||
showOwnedComboBox->setCurrentIndex(showOwnedIndex);
|
||||
|
||||
// Input Settings
|
||||
loadSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
|
||||
loadSettingBool(grabCursorCheckBox, "grab cursor", "Input");
|
||||
|
@ -94,6 +84,16 @@ bool Launcher::AdvancedPage::loadSettings()
|
|||
loadSettingBool(timePlayedCheckbox, "timeplayed", "Saves");
|
||||
maximumQuicksavesComboBox->setValue(mEngineSettings.getInt("max quicksaves", "Saves"));
|
||||
|
||||
// User Interface Settings
|
||||
loadSettingBool(showEffectDurationCheckBox, "show effect duration", "Game");
|
||||
loadSettingBool(showEnchantChanceCheckBox, "show enchant chance", "Game");
|
||||
loadSettingBool(showMeleeInfoCheckBox, "show melee info", "Game");
|
||||
loadSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
|
||||
int showOwnedIndex = mEngineSettings.getInt("show owned", "Game");
|
||||
// Match the index with the option (only 0, 1, 2, or 3 are valid). Will default to 0 if invalid.
|
||||
if (showOwnedIndex >= 0 && showOwnedIndex <= 3)
|
||||
showOwnedComboBox->setCurrentIndex(showOwnedIndex);
|
||||
|
||||
// Other Settings
|
||||
QString screenshotFormatString = QString::fromStdString(mEngineSettings.getString("screenshot format", "General")).toUpper();
|
||||
if (screenshotFormatComboBox->findText(screenshotFormatString) == -1)
|
||||
|
@ -125,16 +125,8 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
saveSettingBool(canLootDuringDeathAnimationCheckBox, "can loot during death animation", "Game");
|
||||
saveSettingBool(followersAttackOnSightCheckBox, "followers attack on sight", "Game");
|
||||
saveSettingBool(preventMerchantEquippingCheckBox, "prevent merchant equipping", "Game");
|
||||
saveSettingBool(showEffectDurationCheckBox, "show effect duration", "Game");
|
||||
saveSettingBool(showEnchantChanceCheckBox, "show enchant chance", "Game");
|
||||
saveSettingBool(showMeleeInfoCheckBox, "show melee info", "Game");
|
||||
saveSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
|
||||
saveSettingBool(rebalanceSoulGemValuesCheckBox, "rebalance soul gem values", "Game");
|
||||
|
||||
int showOwnedCurrentIndex = showOwnedComboBox->currentIndex();
|
||||
if (showOwnedCurrentIndex != mEngineSettings.getInt("show owned", "Game"))
|
||||
mEngineSettings.setInt("show owned", "Game", showOwnedCurrentIndex);
|
||||
|
||||
// Input Settings
|
||||
saveSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
|
||||
saveSettingBool(grabCursorCheckBox, "grab cursor", "Input");
|
||||
|
@ -147,6 +139,15 @@ void Launcher::AdvancedPage::saveSettings()
|
|||
mEngineSettings.setInt("max quicksaves", "Saves", maximumQuicksaves);
|
||||
}
|
||||
|
||||
// User Interface Settings
|
||||
saveSettingBool(showEffectDurationCheckBox, "show effect duration", "Game");
|
||||
saveSettingBool(showEnchantChanceCheckBox, "show enchant chance", "Game");
|
||||
saveSettingBool(showMeleeInfoCheckBox, "show melee info", "Game");
|
||||
saveSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
|
||||
int showOwnedCurrentIndex = showOwnedComboBox->currentIndex();
|
||||
if (showOwnedCurrentIndex != mEngineSettings.getInt("show owned", "Game"))
|
||||
mEngineSettings.setInt("show owned", "Game", showOwnedCurrentIndex);
|
||||
|
||||
// Other Settings
|
||||
std::string screenshotFormatString = screenshotFormatComboBox->currentText().toLower().toStdString();
|
||||
if (screenshotFormatString != mEngineSettings.getString("screenshot format", "General"))
|
||||
|
|
|
@ -201,6 +201,9 @@ void CSMPrefs::State::declare()
|
|||
declareDouble ("rotate-factor", "Free rotation factor", 0.007).setPrecision(4).setRange(0.0001, 0.1);
|
||||
|
||||
declareCategory ("Rendering");
|
||||
declareInt ("framerate-limit", "FPS limit", 60).
|
||||
setTooltip("Framerate limit in 3D preview windows. Zero value means \"unlimited\".").
|
||||
setRange(0, 10000);
|
||||
declareInt ("camera-fov", "Camera FOV", 90).setRange(10, 170);
|
||||
declareBool ("camera-ortho", "Orthographic projection for camera", false);
|
||||
declareInt ("camera-ortho-size", "Orthographic projection size parameter", 100).
|
||||
|
|
|
@ -151,6 +151,9 @@ CompositeViewer::CompositeViewer()
|
|||
|
||||
connect( &mTimer, SIGNAL(timeout()), this, SLOT(update()) );
|
||||
mTimer.start( 10 );
|
||||
|
||||
int frameRateLimit = CSMPrefs::get()["Rendering"]["framerate-limit"].toInt();
|
||||
setRunMaxFrameRate(frameRateLimit);
|
||||
}
|
||||
|
||||
CompositeViewer &CompositeViewer::get()
|
||||
|
@ -168,6 +171,12 @@ void CompositeViewer::update()
|
|||
|
||||
mSimulationTime += dt;
|
||||
frame(mSimulationTime);
|
||||
|
||||
double minFrameTime = _runMaxFrameRate > 0.0 ? 1.0 / _runMaxFrameRate : 0.0;
|
||||
if (dt < minFrameTime)
|
||||
{
|
||||
OpenThreads::Thread::microSleep(1000*1000*(minFrameTime-dt));
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
@ -376,6 +385,10 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting)
|
|||
{
|
||||
mOrbitCamControl->setConstRoll(setting->isTrue());
|
||||
}
|
||||
else if (*setting=="Rendering/framerate-limit")
|
||||
{
|
||||
CompositeViewer::get().setRunMaxFrameRate(setting->toInt());
|
||||
}
|
||||
else if (*setting=="Rendering/camera-fov" ||
|
||||
*setting=="Rendering/camera-ortho" ||
|
||||
*setting=="Rendering/camera-ortho-size")
|
||||
|
|
|
@ -110,7 +110,11 @@ void CSVWorld::EnumDelegate::paint (QPainter *painter, const QStyleOptionViewIte
|
|||
int valueIndex = getValueIndex(index);
|
||||
if (valueIndex != -1)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,7,0)
|
||||
QStyleOptionViewItem itemOption(option);
|
||||
#else
|
||||
QStyleOptionViewItemV4 itemOption(option);
|
||||
#endif
|
||||
itemOption.text = mValues.at(valueIndex).second;
|
||||
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &itemOption, painter);
|
||||
}
|
||||
|
@ -171,5 +175,16 @@ CSVWorld::CommandDelegate *CSVWorld::EnumDelegateFactory::makeDelegate (
|
|||
|
||||
void CSVWorld::EnumDelegateFactory::add (int value, const QString& name)
|
||||
{
|
||||
mValues.push_back (std::make_pair (value, name));
|
||||
auto pair = std::make_pair (value, name);
|
||||
|
||||
for (auto it=mValues.begin(); it!=mValues.end(); ++it)
|
||||
{
|
||||
if (it->second > name)
|
||||
{
|
||||
mValues.insert(it, pair);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mValues.push_back(std::make_pair (value, name));
|
||||
}
|
||||
|
|
|
@ -381,33 +381,24 @@ void OMW::Engine::createWindow(Settings::Manager& settings)
|
|||
setWindowIcon();
|
||||
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
|
||||
int redSize;
|
||||
int greenSize;
|
||||
int blueSize;
|
||||
int depthSize;
|
||||
int stencilSize;
|
||||
int doubleBuffer;
|
||||
|
||||
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redSize);
|
||||
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenSize);
|
||||
SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueSize);
|
||||
SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depthSize);
|
||||
SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencilSize);
|
||||
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doubleBuffer);
|
||||
|
||||
SDL_GetWindowPosition(mWindow, &traits->x, &traits->y);
|
||||
SDL_GetWindowSize(mWindow, &traits->width, &traits->height);
|
||||
traits->red = redSize;
|
||||
traits->green = greenSize;
|
||||
traits->blue = blueSize;
|
||||
traits->depth = depthSize;
|
||||
traits->stencil = stencilSize;
|
||||
traits->doubleBuffer = doubleBuffer;
|
||||
traits->windowName = SDL_GetWindowTitle(mWindow);
|
||||
traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS);
|
||||
traits->screenNum = SDL_GetWindowDisplayIndex(mWindow);
|
||||
traits->vsync = vsync;
|
||||
// We tried to get rid of the hardcoding but failed: https://github.com/OpenMW/openmw/pull/1771
|
||||
// Here goes kcat's quote:
|
||||
// It's ultimately a chicken and egg problem, and the reason why the code is like it was in the first place.
|
||||
// It needs a context to get the current attributes, but it needs the attributes to set up the context.
|
||||
// So it just specifies the same values that were given to SDL in the hopes that it's good enough to what the window eventually gets.
|
||||
traits->red = 8;
|
||||
traits->green = 8;
|
||||
traits->blue = 8;
|
||||
traits->alpha = 0; // set to 0 to stop ScreenCaptureHandler reading the alpha channel
|
||||
traits->depth = 24;
|
||||
traits->stencil = 8;
|
||||
traits->vsync = vsync;
|
||||
traits->doubleBuffer = true;
|
||||
traits->inheritedWindowData = new SDLUtil::GraphicsWindowSDL2::WindowData(mWindow);
|
||||
|
||||
osg::ref_ptr<SDLUtil::GraphicsWindowSDL2> graphicsWindow = new SDLUtil::GraphicsWindowSDL2(traits);
|
||||
|
|
|
@ -773,22 +773,24 @@ namespace MWClass
|
|||
float x = damage / (damage + getArmorRating(ptr));
|
||||
damage *= std::max(gmst.fCombatArmorMinMult->getFloat(), x);
|
||||
int damageDiff = static_cast<int>(unmitigatedDamage - damage);
|
||||
if (damage < 1)
|
||||
damage = 1;
|
||||
damage = std::max(1.f, damage);
|
||||
damageDiff = std::max(1, damageDiff);
|
||||
|
||||
MWWorld::InventoryStore &inv = getInventoryStore(ptr);
|
||||
MWWorld::ContainerStoreIterator armorslot = inv.getSlot(hitslot);
|
||||
MWWorld::Ptr armor = ((armorslot != inv.end()) ? *armorslot : MWWorld::Ptr());
|
||||
if(!armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name())
|
||||
{
|
||||
int armorhealth = armor.getClass().getItemHealth(armor);
|
||||
armorhealth -= std::min(std::max(1, damageDiff),
|
||||
armorhealth);
|
||||
armor.getCellRef().setCharge(armorhealth);
|
||||
if (attacker.isEmpty() || (!attacker.isEmpty() && !(object.isEmpty() && !attacker.getClass().isNpc()))) // Unarmed creature attacks don't affect armor condition
|
||||
{
|
||||
int armorhealth = armor.getClass().getItemHealth(armor);
|
||||
armorhealth -= std::min(damageDiff, armorhealth);
|
||||
armor.getCellRef().setCharge(armorhealth);
|
||||
|
||||
// Armor broken? unequip it
|
||||
if (armorhealth == 0)
|
||||
armor = *inv.unequipItem(armor, ptr);
|
||||
// Armor broken? unequip it
|
||||
if (armorhealth == 0)
|
||||
armor = *inv.unequipItem(armor, ptr);
|
||||
}
|
||||
|
||||
if (ptr == MWMechanics::getPlayer())
|
||||
skillUsageSucceeded(ptr, armor.getClass().getEquipmentSkill(armor), 0);
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace MWGui
|
|||
|
||||
MyGUI::Widget* getDefaultKeyFocus() override;
|
||||
|
||||
virtual bool exit() { return false; }
|
||||
virtual bool exit() override { return false; }
|
||||
|
||||
bool mMarkedToDelete;
|
||||
|
||||
|
|
|
@ -33,44 +33,41 @@ namespace MWGui
|
|||
|
||||
QuickKeysMenu::QuickKeysMenu()
|
||||
: WindowBase("openmw_quickkeys_menu.layout")
|
||||
, mKey(std::vector<keyData>(10))
|
||||
, mSelected(nullptr)
|
||||
, mActivated(nullptr)
|
||||
, mAssignDialog(0)
|
||||
, mItemSelectionDialog(0)
|
||||
, mMagicSelectionDialog(0)
|
||||
, mSelectedIndex(-1)
|
||||
, mActivatedIndex(-1)
|
||||
|
||||
{
|
||||
getWidget(mOkButton, "OKButton");
|
||||
getWidget(mInstructionLabel, "InstructionLabel");
|
||||
|
||||
mMainWidget->setSize(mMainWidget->getWidth(),
|
||||
mMainWidget->getHeight() + (mInstructionLabel->getTextSize().height - mInstructionLabel->getHeight()));
|
||||
mMainWidget->getHeight() +
|
||||
(mInstructionLabel->getTextSize().height - mInstructionLabel->getHeight()));
|
||||
|
||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onOkButtonClicked);
|
||||
center();
|
||||
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
ItemWidget* button;
|
||||
getWidget(button, "QuickKey" + MyGUI::utility::toString(i+1));
|
||||
mKey[i].index = i+1;
|
||||
getWidget(mKey[i].button, "QuickKey" + MyGUI::utility::toString(i+1));
|
||||
mKey[i].button->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
|
||||
|
||||
button->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
|
||||
|
||||
mQuickKeyButtons.push_back(button);
|
||||
|
||||
mAssigned.push_back(Type_Unassigned);
|
||||
|
||||
unassign(button, i);
|
||||
unassign(&mKey[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void QuickKeysMenu::clear()
|
||||
{
|
||||
mActivatedIndex = -1;
|
||||
mActivated = nullptr;
|
||||
|
||||
for (int i=0; i<10; ++i)
|
||||
{
|
||||
unassign(mQuickKeyButtons[i], i);
|
||||
unassign(&mKey[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,10 +88,7 @@ namespace MWGui
|
|||
// Check if quick keys are still valid
|
||||
for (int i=0; i<10; ++i)
|
||||
{
|
||||
ItemWidget* button = mQuickKeyButtons[i];
|
||||
int type = mAssigned[i];
|
||||
|
||||
switch (type)
|
||||
switch (mKey[i].type)
|
||||
{
|
||||
case Type_Unassigned:
|
||||
case Type_HandToHand:
|
||||
|
@ -103,49 +97,55 @@ namespace MWGui
|
|||
case Type_Item:
|
||||
case Type_MagicItem:
|
||||
{
|
||||
MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
|
||||
MWWorld::Ptr item = *mKey[i].button->getUserData<MWWorld::Ptr>();
|
||||
// Make sure the item is available and is not broken
|
||||
if (item.getRefData().getCount() < 1 ||
|
||||
if (!item || item.getRefData().getCount() < 1 ||
|
||||
(item.getClass().hasItemHealth(item) &&
|
||||
item.getClass().getItemHealth(item) <= 0))
|
||||
{
|
||||
// Try searching for a compatible replacement
|
||||
std::string id = item.getCellRef().getRefId();
|
||||
item = store.findReplacement(mKey[i].id);
|
||||
|
||||
if (item)
|
||||
mKey[i].button->setUserData(MWWorld::Ptr(item));
|
||||
|
||||
item = store.findReplacement(id);
|
||||
button->setUserData(MWWorld::Ptr(item));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QuickKeysMenu::unassign(ItemWidget* key, int index)
|
||||
void QuickKeysMenu::unassign(keyData* key)
|
||||
{
|
||||
key->clearUserStrings();
|
||||
key->setItem(MWWorld::Ptr());
|
||||
while (key->getChildCount()) // Destroy number label
|
||||
MyGUI::Gui::getInstance().destroyWidget(key->getChildAt(0));
|
||||
key->button->clearUserStrings();
|
||||
key->button->setItem(MWWorld::Ptr());
|
||||
|
||||
if (index == 9)
|
||||
while (key->button->getChildCount()) // Destroy number label
|
||||
MyGUI::Gui::getInstance().destroyWidget(key->button->getChildAt(0));
|
||||
|
||||
if (key->index == 10)
|
||||
{
|
||||
mAssigned[index] = Type_HandToHand;
|
||||
key->type = Type_HandToHand;
|
||||
|
||||
MyGUI::ImageBox* image = key->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||
MyGUI::ImageBox* image = key->button->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||
MyGUI::IntCoord(14, 13, 32, 32), MyGUI::Align::Default);
|
||||
|
||||
image->setImageTexture("icons\\k\\stealth_handtohand.dds");
|
||||
image->setNeedMouseFocus(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
mAssigned[index] = Type_Unassigned;
|
||||
key->type = Type_Unassigned;
|
||||
key->id = "";
|
||||
key->name = "";
|
||||
|
||||
MyGUI::TextBox* textBox = key->createWidgetReal<MyGUI::TextBox>("SandText", MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Default);
|
||||
textBox->setTextAlign (MyGUI::Align::Center);
|
||||
textBox->setCaption (MyGUI::utility::toString(index+1));
|
||||
textBox->setNeedMouseFocus (false);
|
||||
MyGUI::TextBox* textBox = key->button->createWidgetReal<MyGUI::TextBox>("SandText",
|
||||
MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Default);
|
||||
|
||||
textBox->setTextAlign(MyGUI::Align::Center);
|
||||
textBox->setCaption(MyGUI::utility::toString(key->index));
|
||||
textBox->setNeedMouseFocus(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,19 +154,24 @@ namespace MWGui
|
|||
int index = -1;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
if (sender == mQuickKeyButtons[i] || sender->getParent () == mQuickKeyButtons[i])
|
||||
if (sender == mKey[i].button || sender->getParent() == mKey[i].button)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(index != -1);
|
||||
mSelectedIndex = index;
|
||||
mSelected = &mKey[index];
|
||||
|
||||
// prevent reallocation of zero key from Type_HandToHand
|
||||
if(mSelected->index == 10)
|
||||
return;
|
||||
|
||||
// open assign dialog
|
||||
if (!mAssignDialog)
|
||||
mAssignDialog = new QuickKeysMenuAssign(this);
|
||||
mAssignDialog->setVisible (true);
|
||||
|
||||
mAssignDialog->setVisible(true);
|
||||
}
|
||||
|
||||
void QuickKeysMenu::onOkButtonClicked (MyGUI::Widget *sender)
|
||||
|
@ -174,10 +179,9 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_QuickKeysMenu);
|
||||
}
|
||||
|
||||
|
||||
void QuickKeysMenu::onItemButtonClicked(MyGUI::Widget* sender)
|
||||
{
|
||||
if (!mItemSelectionDialog )
|
||||
if (!mItemSelectionDialog)
|
||||
{
|
||||
mItemSelectionDialog = new ItemSelectionDialog("#{sQuickMenu6}");
|
||||
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &QuickKeysMenu::onAssignItem);
|
||||
|
@ -187,43 +191,45 @@ namespace MWGui
|
|||
mItemSelectionDialog->openContainer(MWMechanics::getPlayer());
|
||||
mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyUsableItems);
|
||||
|
||||
mAssignDialog->setVisible (false);
|
||||
mAssignDialog->setVisible(false);
|
||||
}
|
||||
|
||||
void QuickKeysMenu::onMagicButtonClicked(MyGUI::Widget* sender)
|
||||
{
|
||||
if (!mMagicSelectionDialog )
|
||||
if (!mMagicSelectionDialog)
|
||||
{
|
||||
mMagicSelectionDialog = new MagicSelectionDialog(this);
|
||||
}
|
||||
mMagicSelectionDialog->setVisible(true);
|
||||
|
||||
mAssignDialog->setVisible (false);
|
||||
mAssignDialog->setVisible(false);
|
||||
}
|
||||
|
||||
void QuickKeysMenu::onUnassignButtonClicked(MyGUI::Widget* sender)
|
||||
{
|
||||
unassign(mQuickKeyButtons[mSelectedIndex], mSelectedIndex);
|
||||
mAssignDialog->setVisible (false);
|
||||
unassign(mSelected);
|
||||
mAssignDialog->setVisible(false);
|
||||
}
|
||||
|
||||
void QuickKeysMenu::onCancelButtonClicked(MyGUI::Widget* sender)
|
||||
{
|
||||
mAssignDialog->setVisible (false);
|
||||
mAssignDialog->setVisible(false);
|
||||
}
|
||||
|
||||
void QuickKeysMenu::onAssignItem(MWWorld::Ptr item)
|
||||
{
|
||||
assert (mSelectedIndex >= 0);
|
||||
ItemWidget* button = mQuickKeyButtons[mSelectedIndex];
|
||||
while (button->getChildCount()) // Destroy number label
|
||||
MyGUI::Gui::getInstance().destroyWidget(button->getChildAt(0));
|
||||
assert(mSelected);
|
||||
|
||||
mAssigned[mSelectedIndex] = Type_Item;
|
||||
while (mSelected->button->getChildCount()) // Destroy number label
|
||||
MyGUI::Gui::getInstance().destroyWidget(mSelected->button->getChildAt(0));
|
||||
|
||||
button->setItem(item, ItemWidget::Barter);
|
||||
button->setUserString ("ToolTipType", "ItemPtr");
|
||||
button->setUserData(MWWorld::Ptr(item));
|
||||
mSelected->type = Type_Item;
|
||||
mSelected->id = item.getCellRef().getRefId();
|
||||
mSelected->name = item.getClass().getName(item);
|
||||
|
||||
mSelected->button->setItem(item, ItemWidget::Barter);
|
||||
mSelected->button->setUserString("ToolTipType", "ItemPtr");
|
||||
mSelected->button->setUserData(item);
|
||||
|
||||
if (mItemSelectionDialog)
|
||||
mItemSelectionDialog->setVisible(false);
|
||||
|
@ -234,40 +240,39 @@ namespace MWGui
|
|||
mItemSelectionDialog->setVisible(false);
|
||||
}
|
||||
|
||||
void QuickKeysMenu::onAssignMagicItem (MWWorld::Ptr item)
|
||||
void QuickKeysMenu::onAssignMagicItem(MWWorld::Ptr item)
|
||||
{
|
||||
assert (mSelectedIndex >= 0);
|
||||
ItemWidget* button = mQuickKeyButtons[mSelectedIndex];
|
||||
while (button->getChildCount()) // Destroy number label
|
||||
MyGUI::Gui::getInstance().destroyWidget(button->getChildAt(0));
|
||||
assert(mSelected);
|
||||
|
||||
mAssigned[mSelectedIndex] = Type_MagicItem;
|
||||
while (mSelected->button->getChildCount()) // Destroy number label
|
||||
MyGUI::Gui::getInstance().destroyWidget(mSelected->button->getChildAt(0));
|
||||
|
||||
button->setFrame("textures\\menu_icon_select_magic_magic.dds", MyGUI::IntCoord(2, 2, 40, 40));
|
||||
button->setIcon(item);
|
||||
mSelected->type = Type_MagicItem;
|
||||
|
||||
button->setUserString ("ToolTipType", "ItemPtr");
|
||||
button->setUserData(MWWorld::Ptr(item));
|
||||
mSelected->button->setFrame("textures\\menu_icon_select_magic_magic.dds", MyGUI::IntCoord(2, 2, 40, 40));
|
||||
mSelected->button->setIcon(item);
|
||||
|
||||
mSelected->button->setUserString("ToolTipType", "ItemPtr");
|
||||
mSelected->button->setUserData(MWWorld::Ptr(item));
|
||||
|
||||
if (mMagicSelectionDialog)
|
||||
mMagicSelectionDialog->setVisible(false);
|
||||
}
|
||||
|
||||
void QuickKeysMenu::onAssignMagic (const std::string& spellId)
|
||||
void QuickKeysMenu::onAssignMagic(const std::string& spellId)
|
||||
{
|
||||
assert (mSelectedIndex >= 0);
|
||||
ItemWidget* button = mQuickKeyButtons[mSelectedIndex];
|
||||
while (button->getChildCount()) // Destroy number label
|
||||
MyGUI::Gui::getInstance().destroyWidget(button->getChildAt(0));
|
||||
assert(mSelected);
|
||||
while (mSelected->button->getChildCount()) // Destroy number label
|
||||
MyGUI::Gui::getInstance().destroyWidget(mSelected->button->getChildAt(0));
|
||||
|
||||
mAssigned[mSelectedIndex] = Type_Magic;
|
||||
mSelected->type = Type_Magic;
|
||||
mSelected->id = spellId;
|
||||
|
||||
button->setItem(MWWorld::Ptr());
|
||||
button->setUserString ("ToolTipType", "Spell");
|
||||
button->setUserString ("Spell", spellId);
|
||||
mSelected->button->setItem(MWWorld::Ptr());
|
||||
mSelected->button->setUserString("ToolTipType", "Spell");
|
||||
mSelected->button->setUserString("Spell", spellId);
|
||||
|
||||
const MWWorld::ESMStore &esmStore =
|
||||
MWBase::Environment::get().getWorld()->getStore();
|
||||
const MWWorld::ESMStore &esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
// use the icon of the first effect
|
||||
const ESM::Spell* spell = esmStore.get<ESM::Spell>().find(spellId);
|
||||
|
@ -280,14 +285,14 @@ namespace MWGui
|
|||
path.insert(slashPos+1, "b_");
|
||||
path = MWBase::Environment::get().getWindowManager()->correctIconPath(path);
|
||||
|
||||
button->setFrame("textures\\menu_icon_select_magic.dds", MyGUI::IntCoord(2, 2, 40, 40));
|
||||
button->setIcon(path);
|
||||
mSelected->button->setFrame("textures\\menu_icon_select_magic.dds", MyGUI::IntCoord(2, 2, 40, 40));
|
||||
mSelected->button->setIcon(path);
|
||||
|
||||
if (mMagicSelectionDialog)
|
||||
mMagicSelectionDialog->setVisible(false);
|
||||
}
|
||||
|
||||
void QuickKeysMenu::onAssignMagicCancel ()
|
||||
void QuickKeysMenu::onAssignMagicCancel()
|
||||
{
|
||||
mMagicSelectionDialog->setVisible(false);
|
||||
}
|
||||
|
@ -295,18 +300,17 @@ namespace MWGui
|
|||
void QuickKeysMenu::updateActivatedQuickKey()
|
||||
{
|
||||
// there is no delayed action, nothing to do.
|
||||
if (mActivatedIndex < 0)
|
||||
if (!mActivated)
|
||||
return;
|
||||
|
||||
activateQuickKey(mActivatedIndex);
|
||||
activateQuickKey(mActivated->index);
|
||||
}
|
||||
|
||||
void QuickKeysMenu::activateQuickKey(int index)
|
||||
{
|
||||
assert (index-1 >= 0);
|
||||
ItemWidget* button = mQuickKeyButtons[index-1];
|
||||
assert(index >= 1 && index <= 10);
|
||||
|
||||
QuickKeyType type = mAssigned[index-1];
|
||||
keyData *key = &mKey[index-1];
|
||||
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
|
||||
|
@ -319,117 +323,103 @@ namespace MWGui
|
|||
|| playerStats.getHitRecovery();
|
||||
|
||||
bool isReturnNeeded = playerStats.isParalyzed() || playerStats.isDead();
|
||||
if (isReturnNeeded && type != Type_Item)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDelayNeeded && type != Type_Item)
|
||||
{
|
||||
mActivatedIndex = index;
|
||||
if (isReturnNeeded)
|
||||
return;
|
||||
}
|
||||
|
||||
else if (isDelayNeeded)
|
||||
mActivated = key;
|
||||
|
||||
else
|
||||
mActivatedIndex = -1;
|
||||
mActivated = nullptr;
|
||||
|
||||
if (type == Type_Item || type == Type_MagicItem)
|
||||
|
||||
if (key->type == Type_Item || key->type == Type_MagicItem)
|
||||
{
|
||||
MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
|
||||
// Make sure the item is available and is not broken
|
||||
if (item.getRefData().getCount() < 1 ||
|
||||
(item.getClass().hasItemHealth(item) &&
|
||||
item.getClass().getItemHealth(item) <= 0))
|
||||
{
|
||||
// Try searching for a compatible replacement
|
||||
std::string id = item.getCellRef().getRefId();
|
||||
MWWorld::Ptr item = *key->button->getUserData<MWWorld::Ptr>();
|
||||
|
||||
item = store.findReplacement(id);
|
||||
button->setUserData(MWWorld::Ptr(item));
|
||||
|
||||
if (item.getRefData().getCount() < 1)
|
||||
{
|
||||
// No replacement was found
|
||||
MWBase::Environment::get().getWindowManager ()->messageBox (
|
||||
"#{sQuickMenu5} " + item.getClass().getName(item));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == Type_Magic)
|
||||
{
|
||||
std::string spellId = button->getUserString("Spell");
|
||||
|
||||
// Make sure the player still has this spell
|
||||
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
if (!spells.hasSpell(spellId))
|
||||
{
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
|
||||
MWBase::Environment::get().getWindowManager()->messageBox (
|
||||
"#{sQuickMenu5} " + spell->mName);
|
||||
return;
|
||||
}
|
||||
store.setSelectedEnchantItem(store.end());
|
||||
MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
|
||||
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
||||
}
|
||||
else if (type == Type_Item)
|
||||
{
|
||||
MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
|
||||
bool isWeapon = item.getTypeName() == typeid(ESM::Weapon).name();
|
||||
bool isTool = item.getTypeName() == typeid(ESM::Probe).name() || item.getTypeName() == typeid(ESM::Lockpick).name();
|
||||
|
||||
// delay weapon switching if player is busy
|
||||
if (isDelayNeeded && (isWeapon || isTool))
|
||||
{
|
||||
mActivatedIndex = index;
|
||||
return;
|
||||
}
|
||||
|
||||
// disable weapon switching if player is dead or paralyzed
|
||||
if (isReturnNeeded && (isWeapon || isTool))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->useItem(item);
|
||||
MWWorld::ConstContainerStoreIterator rightHand = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
// change draw state only if the item is in player's right hand
|
||||
if (rightHand != store.end() && item == *rightHand)
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Weapon);
|
||||
}
|
||||
}
|
||||
else if (type == Type_MagicItem)
|
||||
{
|
||||
MWWorld::Ptr item = *button->getUserData<MWWorld::Ptr>();
|
||||
|
||||
// retrieve ContainerStoreIterator to the item
|
||||
MWWorld::ContainerStoreIterator it = store.begin();
|
||||
for (; it != store.end(); ++it)
|
||||
{
|
||||
if (*it == item)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (it == store.end())
|
||||
item = nullptr;
|
||||
|
||||
// check the item is available and not broken
|
||||
if (!item || item.getRefData().getCount() < 1 ||
|
||||
(item.getClass().hasItemHealth(item) && item.getClass().getItemHealth(item) <= 0))
|
||||
{
|
||||
item = store.findReplacement(key->id);
|
||||
|
||||
if (!item || item.getRefData().getCount() < 1)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox(
|
||||
"#{sQuickMenu5} " + key->name);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(it != store.end());
|
||||
|
||||
// equip, if it can be equipped
|
||||
if (!item.getClass().getEquipmentSlots(item).first.empty())
|
||||
if (key->type == Type_Item)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->useItem(item);
|
||||
bool isWeapon = item.getTypeName() == typeid(ESM::Weapon).name();
|
||||
bool isTool = item.getTypeName() == typeid(ESM::Probe).name() ||
|
||||
item.getTypeName() == typeid(ESM::Lockpick).name();
|
||||
|
||||
// make sure that item was successfully equipped
|
||||
if (!store.isEquipped(item))
|
||||
// delay weapon switching if player is busy
|
||||
if (isDelayNeeded && (isWeapon || isTool))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->useItem(item);
|
||||
MWWorld::ConstContainerStoreIterator rightHand = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
// change draw state only if the item is in player's right hand
|
||||
if (rightHand != store.end() && item == *rightHand)
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Weapon);
|
||||
}
|
||||
}
|
||||
else if (key->type == Type_MagicItem)
|
||||
{
|
||||
// equip, if it can be equipped
|
||||
if (!item.getClass().getEquipmentSlots(item).first.empty())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->useItem(item);
|
||||
|
||||
// make sure that item was successfully equipped
|
||||
if (!store.isEquipped(item))
|
||||
return;
|
||||
}
|
||||
|
||||
store.setSelectedEnchantItem(it);
|
||||
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
||||
}
|
||||
}
|
||||
else if (key->type == Type_Magic)
|
||||
{
|
||||
std::string spellId = key->id;
|
||||
|
||||
// Make sure the player still has this spell
|
||||
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
||||
MWMechanics::Spells& spells = stats.getSpells();
|
||||
|
||||
if (!spells.hasSpell(spellId))
|
||||
{
|
||||
const ESM::Spell* spell =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sQuickMenu5} " + spell->mName);
|
||||
return;
|
||||
}
|
||||
|
||||
store.setSelectedEnchantItem(it);
|
||||
store.setSelectedEnchantItem(store.end());
|
||||
MWBase::Environment::get().getWindowManager()
|
||||
->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
|
||||
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
||||
}
|
||||
else if (type == Type_HandToHand)
|
||||
else if (key->type == Type_HandToHand)
|
||||
{
|
||||
store.unequipSlot(MWWorld::InventoryStore::Slot_CarriedRight, player);
|
||||
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Weapon);
|
||||
|
@ -491,9 +481,9 @@ namespace MWGui
|
|||
|
||||
for (int i=0; i<10; ++i)
|
||||
{
|
||||
ItemWidget* button = mQuickKeyButtons[i];
|
||||
ItemWidget* button = mKey[i].button;
|
||||
|
||||
int type = mAssigned[i];
|
||||
int type = mKey[i].type;
|
||||
|
||||
ESM::QuickKeys::QuickKey key;
|
||||
key.mType = type;
|
||||
|
@ -541,30 +531,29 @@ namespace MWGui
|
|||
if (i >= 10)
|
||||
return;
|
||||
|
||||
mSelectedIndex = i;
|
||||
int keyType = it->mType;
|
||||
std::string id = it->mId;
|
||||
ItemWidget* button = mQuickKeyButtons[i];
|
||||
mSelected = &mKey[i];
|
||||
mSelected->type = (QuickKeysMenu::QuickKeyType) it->mType;
|
||||
mSelected->id = it->mId;
|
||||
|
||||
switch (keyType)
|
||||
switch (mSelected->type)
|
||||
{
|
||||
case Type_Magic:
|
||||
if (MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(id))
|
||||
onAssignMagic(id);
|
||||
if (MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search(mSelected->id))
|
||||
onAssignMagic(mSelected->id);
|
||||
break;
|
||||
case Type_Item:
|
||||
case Type_MagicItem:
|
||||
{
|
||||
// Find the item by id
|
||||
MWWorld::Ptr item = store.findReplacement(id);
|
||||
MWWorld::Ptr item = store.findReplacement(mSelected->id);
|
||||
|
||||
if (item.isEmpty())
|
||||
unassign(button, i);
|
||||
unassign(&mKey[i]);
|
||||
else
|
||||
{
|
||||
if (keyType == Type_Item)
|
||||
if (mSelected->type == Type_Item)
|
||||
onAssignItem(item);
|
||||
else if (keyType == Type_MagicItem)
|
||||
else if (mSelected->type == Type_MagicItem)
|
||||
onAssignMagicItem(item);
|
||||
}
|
||||
|
||||
|
@ -572,7 +561,7 @@ namespace MWGui
|
|||
}
|
||||
case Type_Unassigned:
|
||||
case Type_HandToHand:
|
||||
unassign(button, i);
|
||||
unassign(&mKey[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,23 +55,31 @@ namespace MWGui
|
|||
|
||||
|
||||
private:
|
||||
|
||||
struct keyData {
|
||||
int index;
|
||||
ItemWidget* button;
|
||||
QuickKeysMenu::QuickKeyType type;
|
||||
std::string id;
|
||||
std::string name;
|
||||
keyData(): index(-1), button(nullptr), type(Type_Unassigned), id(""), name("") {}
|
||||
};
|
||||
|
||||
std::vector<keyData> mKey;
|
||||
keyData* mSelected;
|
||||
keyData* mActivated;
|
||||
|
||||
MyGUI::EditBox* mInstructionLabel;
|
||||
MyGUI::Button* mOkButton;
|
||||
|
||||
std::vector<ItemWidget*> mQuickKeyButtons;
|
||||
std::vector<QuickKeyType> mAssigned;
|
||||
|
||||
QuickKeysMenuAssign* mAssignDialog;
|
||||
ItemSelectionDialog* mItemSelectionDialog;
|
||||
MagicSelectionDialog* mMagicSelectionDialog;
|
||||
|
||||
int mSelectedIndex;
|
||||
int mActivatedIndex;
|
||||
|
||||
void onQuickKeyButtonClicked(MyGUI::Widget* sender);
|
||||
void onOkButtonClicked(MyGUI::Widget* sender);
|
||||
|
||||
void unassign(ItemWidget* key, int index);
|
||||
void unassign(keyData* key);
|
||||
};
|
||||
|
||||
class QuickKeysMenuAssign : public WindowModal
|
||||
|
|
|
@ -191,6 +191,9 @@ namespace MWGui
|
|||
else if (type == "ItemPtr")
|
||||
{
|
||||
mFocusObject = *focus->getUserData<MWWorld::Ptr>();
|
||||
if (!mFocusObject)
|
||||
return;
|
||||
|
||||
tooltipSize = getToolTipViaPtr(mFocusObject.getRefData().getCount(), false, checkOwned());
|
||||
}
|
||||
else if (type == "ItemModelIndex")
|
||||
|
|
|
@ -56,15 +56,15 @@ namespace MWGui
|
|||
|
||||
|
||||
/*
|
||||
* "Modal" windows cause the rest of the interface to be unaccessible while they are visible
|
||||
* "Modal" windows cause the rest of the interface to be inaccessible while they are visible
|
||||
*/
|
||||
class WindowModal : public WindowBase
|
||||
{
|
||||
public:
|
||||
WindowModal(const std::string& parLayout);
|
||||
virtual void onOpen();
|
||||
virtual void onClose();
|
||||
virtual bool exit() {return true;}
|
||||
virtual void onOpen() override;
|
||||
virtual void onClose() override;
|
||||
virtual bool exit() override {return true;}
|
||||
};
|
||||
|
||||
/// A window that cannot be the target of a drag&drop action.
|
||||
|
|
|
@ -115,14 +115,16 @@ namespace MWMechanics
|
|||
|
||||
if (Misc::Rng::roll0to99() < x)
|
||||
{
|
||||
// Reduce shield durability by incoming damage
|
||||
int shieldhealth = shield->getClass().getItemHealth(*shield);
|
||||
|
||||
shieldhealth -= std::min(shieldhealth, int(damage));
|
||||
shield->getCellRef().setCharge(shieldhealth);
|
||||
if (shieldhealth == 0)
|
||||
inv.unequipItem(*shield, blocker);
|
||||
if (!(weapon.isEmpty() && !attacker.getClass().isNpc())) // Unarmed creature attacks don't affect armor condition
|
||||
{
|
||||
// Reduce shield durability by incoming damage
|
||||
int shieldhealth = shield->getClass().getItemHealth(*shield);
|
||||
|
||||
shieldhealth -= std::min(shieldhealth, int(damage));
|
||||
shield->getCellRef().setCharge(shieldhealth);
|
||||
if (shieldhealth == 0)
|
||||
inv.unequipItem(*shield, blocker);
|
||||
}
|
||||
// Reduce blocker fatigue
|
||||
const float fFatigueBlockBase = gmst.find("fFatigueBlockBase")->getFloat();
|
||||
const float fFatigueBlockMult = gmst.find("fFatigueBlockMult")->getFloat();
|
||||
|
|
|
@ -328,7 +328,10 @@ namespace MWMechanics
|
|||
if (race->mData.mFlags & ESM::Race::Beast)
|
||||
return 0.f;
|
||||
}
|
||||
// Intended fall-through
|
||||
else
|
||||
return 0.f;
|
||||
|
||||
break;
|
||||
// Creatures can not wear armor
|
||||
case ESM::MagicEffect::BoundCuirass:
|
||||
case ESM::MagicEffect::BoundGloves:
|
||||
|
|
|
@ -608,7 +608,7 @@ namespace MWWorld
|
|||
void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) override;
|
||||
|
||||
void applyLoopingParticles(const MWWorld::Ptr& ptr);
|
||||
void applyLoopingParticles(const MWWorld::Ptr& ptr) override;
|
||||
|
||||
const std::vector<std::string>& getContentFiles() const override;
|
||||
void breakInvisibility (const MWWorld::Ptr& actor) override;
|
||||
|
|
|
@ -22,14 +22,14 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>630</width>
|
||||
<height>746</height>
|
||||
<height>791</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="scrollAreaVerticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gameGroup">
|
||||
<property name="title">
|
||||
<string>Game</string>
|
||||
<string>Game Mechanics</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="gameGroupVerticalLayout">
|
||||
<item>
|
||||
|
@ -62,46 +62,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showEffectDurationCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Show the remaining duration of magic effects and lights if this setting is true. The remaining duration is displayed in the tooltip by hovering over the magical effect. </p><p>The default value is false.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show effect duration</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showEnchantChanceCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Whether or not the chance of success will be displayed in the enchanting menu.</p><p>The default value is false.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show enchant chance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showMeleeInfoCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If this setting is true, melee weapons reach and speed will be showed on item tooltip.</p><p>The default value is false.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show melee info</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showProjectileDamageCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If this setting is true, damage bonus of arrows and bolts will be showed on item tooltip.</p><p>The default value is false.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show projectile damage</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="rebalanceSoulGemValuesCheckBox">
|
||||
<property name="toolTip">
|
||||
|
@ -112,64 +72,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignLeft">
|
||||
<widget class="QWidget" name="showOwnedGroup" native="true">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable visual clues for items owned by NPCs when the crosshair is on the object.</p><p>The default value is Off.</p></body></html></string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item alignment="Qt::AlignRight">
|
||||
<widget class="QLabel" name="showOwnedLabel">
|
||||
<property name="text">
|
||||
<string>Show owned:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="showOwnedComboBox">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Off</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tool Tip Only</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Crosshair Only</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tool Tip and Crosshair</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -357,6 +259,113 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="userInterfaceGroup">
|
||||
<property name="title">
|
||||
<string>User Interface</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="userInterfaceVerticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showEffectDurationCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Show the remaining duration of magic effects and lights if this setting is true. The remaining duration is displayed in the tooltip by hovering over the magical effect. </p><p>The default value is false.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show effect duration</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showEnchantChanceCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Whether or not the chance of success will be displayed in the enchanting menu.</p><p>The default value is false.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show enchant chance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showMeleeInfoCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If this setting is true, melee weapons reach and speed will be showed on item tooltip.</p><p>The default value is false.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show melee info</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showProjectileDamageCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If this setting is true, damage bonus of arrows and bolts will be showed on item tooltip.</p><p>The default value is false.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show projectile damage</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignLeft">
|
||||
<widget class="QWidget" name="showOwnedGroup" native="true">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable visual clues for items owned by NPCs when the crosshair is on the object.</p><p>The default value is Off.</p></body></html></string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item alignment="Qt::AlignRight">
|
||||
<widget class="QLabel" name="showOwnedLabel">
|
||||
<property name="text">
|
||||
<string>Show owned:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="showOwnedComboBox">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Off</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tool Tip Only</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Crosshair Only</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tool Tip and Crosshair</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="otherGroup">
|
||||
<property name="title">
|
||||
|
|
Loading…
Reference in a new issue