diff --git a/CHANGELOG.md b/CHANGELOG.md index 15464b1d7..3219edd9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Bug #923: Editor: Operations-Multithreading is broken Bug #1317: Erene Llenim in Seyda Neen does not walk around + Bug #1405: Water rendering glitch near Seyda Neen lighthouse Bug #1621: "Error Detecting Morrowind Installation" in the default directory Bug #2216: Creating a clone of the player stops you moving. Bug #2387: Casting bound weapon spell doesn't switch to "ready weapon" mode @@ -23,6 +24,10 @@ Bug #2475: cumulative stacks of 100 point fortify skill speechcraft boosts do not apply correctly Bug #2498: Editor: crash when issuing undo command after the table subview is closed Bug #2500: Editor: object table - can't undo delete record + Bug #2518: OpenMW detect spell returns false positives + Bug #2521: NPCs don't react to stealing when inventory menu is open. + Bug #2525: Can't click on red dialogue choice [rise of house telvanni][60fffec] + Bug #2530: GetSpellEffects not working as in vanilla Feature #139: Editor: Global Search & Replace Feature #1219: Editor: Add dialogue mode only columns Feature #2024: Hotkey for hand to hand (i.e. unequip any weapon) @@ -34,6 +39,7 @@ Feature #2505: Editor: optionally show a line number column in the script editor Feature #2512: Editor: Offer use of monospace fonts in the script editor as an option Feature #2514: Editor: focus on ID input field on clone/add + Feature #2519: it is not possible to change icons that appear on the map after casting the Detect spells Task #2460: OS X: Use Application Support directory as user data path Task #2516: Editor: Change References / Referenceables terminology diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 8404b9523..192bdf2ce 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -251,7 +251,7 @@ namespace MWClass float hitchance = MWMechanics::getHitChance(ptr, victim, ref->mBase->mData.mCombat); - if(OEngine::Misc::Rng::rollProbability() >= hitchance/100.0f) + if(OEngine::Misc::Rng::roll0to99() >= hitchance) { victim.getClass().onHit(victim, 0.0f, false, MWWorld::Ptr(), ptr, false); MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 1d58dc87e..3ca57aca8 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -515,7 +515,7 @@ namespace MWClass float hitchance = MWMechanics::getHitChance(ptr, victim, ptr.getClass().getSkill(ptr, weapskill)); - if (OEngine::Misc::Rng::rollProbability() >= hitchance / 100.0f) + if (OEngine::Misc::Rng::roll0to99() >= hitchance) { othercls.onHit(victim, 0.0f, false, weapon, ptr, false); MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr); diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index b928738dd..0b9fd65d2 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -485,6 +485,12 @@ namespace MWDialogue executeScript (info->mResultScript); } + else + { + mChoice = -1; + mIsInChoice = false; + MWBase::Environment::get().getWindowManager()->getDialogueWindow()->clearChoices(); + } } } diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 80b246e84..9aa8a8ea1 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -594,6 +594,8 @@ namespace MWGui MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWBase::Environment::get().getWorld()->breakInvisibility(player); + MWBase::Environment::get().getMechanicsManager()->itemTaken(player, object, MWWorld::Ptr(), count); + // add to player inventory // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object MWWorld::Ptr newObject = *player.getClass().getContainerStore (player).add (object, object.getRefData().getCount(), player); @@ -612,8 +614,6 @@ namespace MWGui throw std::runtime_error("Added item not found"); mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count); - MWBase::Environment::get().getMechanicsManager()->itemTaken(player, newObject, MWWorld::Ptr(), count); - MWBase::Environment::get().getWindowManager()->updateSpellWindow(); } diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 02e8ffdfe..9adfeffe8 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -300,17 +300,17 @@ namespace MWGui MarkerUserData markerPos; MyGUI::IntPoint widgetPos = getMarkerPosition(marker.mWorldX, marker.mWorldY, markerPos); - MyGUI::IntCoord widgetCoord(widgetPos.left - 4, - widgetPos.top - 4, - 8, 8); - MarkerWidget* markerWidget = mLocalMap->createWidget("MarkerButton", + MyGUI::IntCoord widgetCoord(widgetPos.left - 8, + widgetPos.top - 8, + 16, 16); + MarkerWidget* markerWidget = mLocalMap->createWidget("CustomMarkerButton", widgetCoord, MyGUI::Align::Default); markerWidget->setDepth(Local_MarkerAboveFogLayer); markerWidget->setUserString("ToolTipType", "Layout"); markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine"); markerWidget->setUserString("Caption_TextOneLine", MyGUI::TextIterator::toTagsString(marker.mNote)); - markerWidget->setNormalColour(MyGUI::Colour(1.0f, 0.3f, 0.3f)); - markerWidget->setHoverColour(MyGUI::Colour(1.0f, 0.5f, 0.5f)); + markerWidget->setNormalColour(MyGUI::Colour(0.6f, 0.6f, 0.6f)); + markerWidget->setHoverColour(MyGUI::Colour(1.0f, 1.0f, 1.0f)); markerWidget->setUserData(marker); markerWidget->setNeedMouseFocus(true); customMarkerCreated(markerWidget); @@ -468,21 +468,17 @@ namespace MWGui return; std::string markerTexture; - MyGUI::Colour markerColour; if (type == MWBase::World::Detect_Creature) { - markerTexture = "textures\\menu_map_dcreature.dds"; - markerColour = MyGUI::Colour(1,0,0,1); + markerTexture = "textures\\detect_animal_icon.dds"; } if (type == MWBase::World::Detect_Key) { - markerTexture = "textures\\menu_map_dkey.dds"; - markerColour = MyGUI::Colour(0,1,0,1); + markerTexture = "textures\\detect_key_icon.dds"; } if (type == MWBase::World::Detect_Enchantment) { - markerTexture = "textures\\menu_map_dmagic.dds"; - markerColour = MyGUI::Colour(0,0,1,1); + markerTexture = "textures\\detect_enchantment_icon.dds"; } int counter = 0; @@ -499,7 +495,7 @@ namespace MWGui widgetCoord, MyGUI::Align::Default); markerWidget->setDepth(Local_MarkerAboveFogLayer); markerWidget->setImageTexture(markerTexture); - markerWidget->setColour(markerColour); + markerWidget->setImageCoord(MyGUI::IntCoord(0,0,8,8)); markerWidget->setNeedMouseFocus(false); mMagicMarkerWidgets.push_back(markerWidget); } diff --git a/apps/openmw/mwgui/pickpocketitemmodel.cpp b/apps/openmw/mwgui/pickpocketitemmodel.cpp index bc7c5528e..b8ac20f99 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.cpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.cpp @@ -20,7 +20,7 @@ namespace MWGui { for (size_t i = 0; igetItemCount(); ++i) { - if (chance <= OEngine::Misc::Rng::roll0to99()) + if (OEngine::Misc::Rng::roll0to99() > chance) mHiddenItems.push_back(mSourceModel->getItem(i)); } } diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index 57b02940e..76a1d51e5 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -127,13 +127,7 @@ namespace MWGui bool SpellBuyingWindow::playerHasSpell(const std::string &id) { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - MWMechanics::Spells& playerSpells = player.getClass().getCreatureStats (player).getSpells(); - for (MWMechanics::Spells::TIterator it = playerSpells.begin(); it != playerSpells.end(); ++it) - { - if (Misc::StringUtils::ciEqual(id, it->first)) - return true; - } - return false; + return player.getClass().getCreatureStats(player).getSpells().hasSpell(id); } void SpellBuyingWindow::onSpellButtonClick(MyGUI::Widget* _sender) diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index f74b06891..94905dd9e 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -155,8 +155,9 @@ namespace MWGui if (!region->mSleepList.empty()) { // figure out if player will be woken while sleeping + int x = OEngine::Misc::Rng::rollDice(hoursToWait); float fSleepRandMod = world->getStore().get().find("fSleepRandMod")->getFloat(); - if (OEngine::Misc::Rng::rollProbability() > fSleepRandMod) + if (x > fSleepRandMod * hoursToWait) { float fSleepRestMod = world->getStore().get().find("fSleepRestMod")->getFloat(); mInterruptAt = hoursToWait - int(fSleepRestMod * hoursToWait); diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index c5fc34507..045f0108c 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -187,7 +187,7 @@ namespace MWMechanics int skillValue = attacker.getClass().getSkill(attacker, weapon.getClass().getEquipmentSkill(weapon)); - if (OEngine::Misc::Rng::rollProbability() >= getHitChance(attacker, victim, skillValue) / 100.0f) + if (OEngine::Misc::Rng::roll0to99() >= getHitChance(attacker, victim, skillValue)) { victim.getClass().onHit(victim, 0.0f, false, projectile, attacker, false); MWMechanics::reduceWeaponCondition(0.f, false, weapon, attacker); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index da8d49db0..c829154e2 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -737,7 +737,7 @@ namespace MWMechanics float x = 0; float y = 0; - float roll = OEngine::Misc::Rng::rollClosedProbability() * 100; + int roll = OEngine::Misc::Rng::roll0to99(); if (type == PT_Admire) { diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 04225b43e..b1829964b 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -143,6 +143,20 @@ namespace MWMechanics return mSelectedSpell; } + bool Spells::isSpellActive(const std::string &id) const + { + TContainer::const_iterator found = mSpells.find(id); + if (found != mSpells.end()) + { + const ESM::Spell *spell = + MWBase::Environment::get().getWorld()->getStore().get().find (id); + + return (spell->mData.mType==ESM::Spell::ST_Ability || spell->mData.mType==ESM::Spell::ST_Blight || + spell->mData.mType==ESM::Spell::ST_Disease || spell->mData.mType==ESM::Spell::ST_Curse); + } + return false; + } + bool Spells::hasCommonDisease() const { for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index 064b2c1e5..6b4149939 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -98,6 +98,9 @@ namespace MWMechanics const std::string getSelectedSpell() const; ///< May return an empty string. + bool isSpellActive(const std::string& id) const; + ///< Are we under the effects of the given spell ID? + bool hasCommonDisease() const; bool hasBlightDisease() const; diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 29f586a65..38106340a 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -595,7 +595,8 @@ namespace MWScript std::string id = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); - runtime.push(ptr.getClass().getCreatureStats(ptr).getActiveSpells().isSpellActive(id)); + const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + runtime.push(stats.getActiveSpells().isSpellActive(id) || stats.getSpells().isSpellActive(id)); } }; diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index d825b085e..80f46e457 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -515,14 +515,8 @@ namespace MWScript Interpreter::Type_Integer value = 0; - for (MWMechanics::Spells::TIterator iter ( - ptr.getClass().getCreatureStats (ptr).getSpells().begin()); - iter!=ptr.getClass().getCreatureStats (ptr).getSpells().end(); ++iter) - if (iter->first==id) - { - value = 1; - break; - } + if (ptr.getClass().getCreatureStats(ptr).getSpells().hasSpell(id)) + value = 1; runtime.push (value); } diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index d7036d6b1..672b6046b 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -120,6 +120,7 @@ namespace MWWorld /// Call functor (ref) for each reference. functor must return a bool. Returning /// false will abort the iteration. + /// \attention This function also lists deleted (count 0) objects! /// \return Iteration completed? /// /// \note Creatures and NPCs are handled last. diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 8d689240b..f5a9b8960 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -256,12 +256,13 @@ namespace MWWorld insertCell (*cell, true, loadingListener); mRendering.cellAdded (cell); - bool waterEnabled = cell->getCell()->hasWater(); + bool waterEnabled = cell->getCell()->hasWater() || cell->isExterior(); mRendering.setWaterEnabled(waterEnabled); + float waterLevel = cell->isExterior() ? -1.f : cell->getWaterLevel(); if (waterEnabled) { - mPhysics->enableWater(cell->getWaterLevel()); - mRendering.setWaterHeight(cell->getWaterLevel()); + mPhysics->enableWater(waterLevel); + mRendering.setWaterHeight(waterLevel); } else mPhysics->disableWater(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 013386f8f..0f8110624 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2956,7 +2956,7 @@ namespace MWWorld Ogre::Vector3(mDetector.getRefData().getPosition().pos)) >= mSquaredDist) return true; - if (!ptr.getRefData().isEnabled()) + if (!ptr.getRefData().isEnabled() || ptr.getRefData().isDeleted()) return true; // Consider references inside containers as well (except if we are looking for a Creature, they cannot be in containers) diff --git a/files/mygui/openmw_resources.xml b/files/mygui/openmw_resources.xml index 423281a62..305cb0c0d 100644 --- a/files/mygui/openmw_resources.xml +++ b/files/mygui/openmw_resources.xml @@ -31,6 +31,15 @@ + + + + + + + + +