From a1d9f11b04dbff794889d816ee4bb31fab05bb32 Mon Sep 17 00:00:00 2001 From: rexelion Date: Tue, 7 Nov 2017 11:43:21 +0000 Subject: [PATCH 01/12] use fProjectileMaxSpeed for ranged weapons distance --- apps/openmw/mwmechanics/aicombataction.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index d44498966..df636dd56 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -115,6 +115,7 @@ namespace MWMechanics isRanged = false; static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatDistance")->getFloat(); + static const float fProjectileMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get().find("fProjectileMaxSpeed")->getFloat(); if (mWeapon.isEmpty()) { @@ -128,7 +129,7 @@ namespace MWMechanics if (weapon->mData.mType >= ESM::Weapon::MarksmanBow) { isRanged = true; - return 1000.f; + return fProjectileMaxSpeed; } else return weapon->mData.mReach * fCombatDistance; From cab00024615730360fba3f66fc2cfb058acabea3 Mon Sep 17 00:00:00 2001 From: rexelion Date: Tue, 7 Nov 2017 17:57:23 +0000 Subject: [PATCH 02/12] Backing up distance is now dependent on opponents's weapon range; don't back up from ranged oponents --- apps/openmw/mwmechanics/aicombat.cpp | 49 ++++++++++++++-------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 68d282d0c..cd9211a3f 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -490,6 +490,28 @@ namespace MWMechanics void AiCombatStorage::startCombatMove(bool isDistantCombat, float distToTarget, float rangeAttack, const MWWorld::Ptr& actor, const MWWorld::Ptr& target) { + // get the range of the target's weapon + float rangeAttackOfTarget = 0.f; + MWWorld::Ptr targetWeapon = MWWorld::Ptr(); + const MWWorld::Class& targetClass = target.getClass(); + + if (targetClass.hasInventoryStore(target)) + { + MWMechanics::WeaponType weapType = WeapType_None; + MWWorld::ContainerStoreIterator weaponSlot = + MWMechanics::getActiveWeapon(targetClass.getCreatureStats(target), targetClass.getInventoryStore(target), &weapType); + if (weapType != WeapType_PickProbe && weapType != WeapType_Spell && weapType != WeapType_None && weapType != WeapType_HandToHand) + targetWeapon = *weaponSlot; + } + + std::shared_ptr targetWeaponAction(new ActionWeapon(targetWeapon)); + + bool isRangedCombat = false; + if (targetWeaponAction.get()) + { + rangeAttackOfTarget = targetWeaponAction->getCombatRange(isRangedCombat); + } + if (mMovement.mPosition[0] || mMovement.mPosition[1]) { mTimerCombatMove = 0.1f + 0.1f * Misc::Rng::rollClosedProbability(); @@ -498,28 +520,6 @@ namespace MWMechanics // dodge movements (for NPCs and bipedal creatures) else if (actor.getClass().isBipedal(actor)) { - // get the range of the target's weapon - float rangeAttackOfTarget = 0.f; - MWWorld::Ptr targetWeapon = MWWorld::Ptr(); - const MWWorld::Class& targetClass = target.getClass(); - - if (targetClass.hasInventoryStore(target)) - { - MWMechanics::WeaponType weapType = WeapType_None; - MWWorld::ContainerStoreIterator weaponSlot = - MWMechanics::getActiveWeapon(targetClass.getCreatureStats(target), targetClass.getInventoryStore(target), &weapType); - if (weapType != WeapType_PickProbe && weapType != WeapType_Spell && weapType != WeapType_None && weapType != WeapType_HandToHand) - targetWeapon = *weaponSlot; - } - - std::shared_ptr targetWeaponAction (new ActionWeapon(targetWeapon)); - - if (targetWeaponAction.get()) - { - bool isRangedCombat = false; - rangeAttackOfTarget = targetWeaponAction->getCombatRange(isRangedCombat); - } - // apply sideway movement (kind of dodging) with some probability // if actor is within range of target's weapon if (distToTarget <= rangeAttackOfTarget && Misc::Rng::rollClosedProbability() < 0.25) @@ -533,13 +533,14 @@ namespace MWMechanics // Below behavior for backing up during ranged combat differs from vanilla. // Vanilla is observed as backing up only as far as fCombatDistance or // opponent's weapon range, or not backing up if opponent is also using a ranged weapon - if (isDistantCombat && distToTarget < rangeAttack / 4) + if (isDistantCombat) { // actor should not back up into water if (MWBase::Environment::get().getWorld()->isUnderwater(MWWorld::ConstPtr(actor), 0.5f)) return; - mMovement.mPosition[1] = -1; + if (!isRangedCombat && distToTarget <= rangeAttackOfTarget*1.5) // Don't back up if the target is wielding ranged weapon + mMovement.mPosition[1] = -1; } } From 983c33c4c89209ef6679743cd9f17654d4265eb4 Mon Sep 17 00:00:00 2001 From: rexelion Date: Thu, 9 Nov 2017 14:23:26 +0000 Subject: [PATCH 03/12] don't use a pointer for ActionWeapon --- apps/openmw/mwmechanics/aicombat.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index cd9211a3f..6e3268831 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -504,13 +504,8 @@ namespace MWMechanics targetWeapon = *weaponSlot; } - std::shared_ptr targetWeaponAction(new ActionWeapon(targetWeapon)); - bool isRangedCombat = false; - if (targetWeaponAction.get()) - { - rangeAttackOfTarget = targetWeaponAction->getCombatRange(isRangedCombat); - } + rangeAttackOfTarget = ActionWeapon(targetWeapon).getCombatRange(isRangedCombat); if (mMovement.mPosition[0] || mMovement.mPosition[1]) { From 3604b73d6016aaa62808e888e47c2da27d4c109c Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 4 Oct 2017 21:25:22 +0400 Subject: [PATCH 04/12] Move onTakeItem() to item models --- apps/openmw/mwgui/container.cpp | 33 +++-------------------- apps/openmw/mwgui/containeritemmodel.cpp | 24 +++++++++++++++-- apps/openmw/mwgui/containeritemmodel.hpp | 1 + apps/openmw/mwgui/inventoryitemmodel.cpp | 15 +++++++++++ apps/openmw/mwgui/inventoryitemmodel.hpp | 1 + apps/openmw/mwgui/itemmodel.cpp | 9 +++++++ apps/openmw/mwgui/itemmodel.hpp | 2 ++ apps/openmw/mwgui/pickpocketitemmodel.cpp | 29 ++++++++++++++++++-- apps/openmw/mwgui/pickpocketitemmodel.hpp | 4 +++ apps/openmw/mwgui/sortfilteritemmodel.cpp | 4 +++ apps/openmw/mwgui/sortfilteritemmodel.hpp | 2 ++ 11 files changed, 91 insertions(+), 33 deletions(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 74ed4fff9..be3cb1522 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -8,13 +8,13 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/dialoguemanager.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwmechanics/actorutil.hpp" #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwmechanics/pickpocket.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/actorutil.hpp" #include "countdialog.hpp" #include "inventorywindow.hpp" @@ -142,8 +142,7 @@ namespace MWGui if (mPtr.getClass().isNpc() && !loot) { // we are stealing stuff - MWWorld::Ptr player = MWMechanics::getPlayer(); - mModel = new PickpocketItemModel(player, new InventoryItemModel(container), + mModel = new PickpocketItemModel(mPtr, new InventoryItemModel(container), !mPtr.getClass().getCreatureStats(mPtr).getKnockedDown()); } else @@ -271,32 +270,8 @@ namespace MWGui bool ContainerWindow::onTakeItem(const ItemStack &item, int count) { - MWWorld::Ptr player = MWMechanics::getPlayer(); - // TODO: move to ItemModels - if (dynamic_cast(mModel) - && !mPtr.getClass().getCreatureStats(mPtr).getKnockedDown()) - { - MWMechanics::Pickpocket pickpocket(player, mPtr); - if (pickpocket.pick(item.mBase, count)) - { - MWBase::Environment::get().getMechanicsManager()->commitCrime( - player, mPtr, MWBase::MechanicsManager::OT_Pickpocket, 0, true); - MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); - mPickpocketDetected = true; - return false; - } - else - player.getClass().skillUsageSucceeded(player, ESM::Skill::Sneak, 1); - } - else - { - // Looting a dead corpse is considered OK - if (mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead()) - return true; - else - MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item.mBase, mPtr, count); - } - return true; + // TODO: mPickpocketDetected = true; + return mModel->onTakeItem(item.mBase, count); } } diff --git a/apps/openmw/mwgui/containeritemmodel.cpp b/apps/openmw/mwgui/containeritemmodel.cpp index 479638672..ee89f1350 100644 --- a/apps/openmw/mwgui/containeritemmodel.cpp +++ b/apps/openmw/mwgui/containeritemmodel.cpp @@ -2,12 +2,15 @@ #include +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/actorutil.hpp" + #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/actorutil.hpp" @@ -183,4 +186,21 @@ void ContainerItemModel::update() } } +bool ContainerItemModel::onTakeItem(const MWWorld::Ptr &item, int count) +{ + if (mItemSources.empty()) + return false; + + MWWorld::Ptr target = mItemSources[0]; + + // Looting a dead corpse is considered OK + if (target.getClass().isActor() && target.getClass().getCreatureStats(target).isDead()) + return true; + + MWWorld::Ptr player = MWMechanics::getPlayer(); + MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, target, count); + + return true; +} + } diff --git a/apps/openmw/mwgui/containeritemmodel.hpp b/apps/openmw/mwgui/containeritemmodel.hpp index c6ecafd46..a0dbc2cf9 100644 --- a/apps/openmw/mwgui/containeritemmodel.hpp +++ b/apps/openmw/mwgui/containeritemmodel.hpp @@ -26,6 +26,7 @@ namespace MWGui virtual void removeItem (const ItemStack& item, size_t count); virtual void update(); + virtual bool onTakeItem(const MWWorld::Ptr &item, int count); private: std::vector mItemSources; diff --git a/apps/openmw/mwgui/inventoryitemmodel.cpp b/apps/openmw/mwgui/inventoryitemmodel.cpp index 222243ec1..b807a58f4 100644 --- a/apps/openmw/mwgui/inventoryitemmodel.cpp +++ b/apps/openmw/mwgui/inventoryitemmodel.cpp @@ -9,6 +9,9 @@ #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" + namespace MWGui { @@ -116,4 +119,16 @@ void InventoryItemModel::update() } } +bool InventoryItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const +{ + // Looting a dead corpse is considered OK + if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead()) + return true; + + MWWorld::Ptr player = MWMechanics::getPlayer(); + MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, mActor, count); + + return true; +} + } diff --git a/apps/openmw/mwgui/inventoryitemmodel.hpp b/apps/openmw/mwgui/inventoryitemmodel.hpp index f58ee2939..95afeb5d4 100644 --- a/apps/openmw/mwgui/inventoryitemmodel.hpp +++ b/apps/openmw/mwgui/inventoryitemmodel.hpp @@ -22,6 +22,7 @@ namespace MWGui virtual MWWorld::Ptr moveItem (const ItemStack& item, size_t count, ItemModel* otherModel); virtual void update(); + virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; protected: MWWorld::Ptr mActor; diff --git a/apps/openmw/mwgui/itemmodel.cpp b/apps/openmw/mwgui/itemmodel.cpp index ffcf9075e..5a6afdf02 100644 --- a/apps/openmw/mwgui/itemmodel.cpp +++ b/apps/openmw/mwgui/itemmodel.cpp @@ -129,6 +129,11 @@ namespace MWGui return true; } + bool ItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + { + return true; + } + ProxyItemModel::ProxyItemModel() : mSourceModel(NULL) @@ -198,4 +203,8 @@ namespace MWGui mSourceModel = sourceModel; } + bool ProxyItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + { + return mSourceModel->onTakeItem (item, count); + } } diff --git a/apps/openmw/mwgui/itemmodel.hpp b/apps/openmw/mwgui/itemmodel.hpp index bc6be8023..c4a3a03e8 100644 --- a/apps/openmw/mwgui/itemmodel.hpp +++ b/apps/openmw/mwgui/itemmodel.hpp @@ -75,6 +75,7 @@ namespace MWGui /// Is the player allowed to insert items into this model? (default true) virtual bool allowedToInsertItems() const; + virtual bool onTakeItem(const MWWorld::Ptr &item, int count); private: ItemModel(const ItemModel&); @@ -94,6 +95,7 @@ namespace MWGui virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false); virtual void removeItem (const ItemStack& item, size_t count); virtual ModelIndex getIndex (ItemStack item); + virtual bool onTakeItem(const MWWorld::Ptr &item, int count); /// @note Takes ownership of the passed pointer. void setSourceModel(ItemModel* sourceModel); diff --git a/apps/openmw/mwgui/pickpocketitemmodel.cpp b/apps/openmw/mwgui/pickpocketitemmodel.cpp index ec4b378a0..e610854c1 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.cpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.cpp @@ -3,15 +3,24 @@ #include #include +#include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/pickpocket.hpp" + #include "../mwworld/class.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" + namespace MWGui { - PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& thief, ItemModel *sourceModel, bool hideItems) + PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& actor, ItemModel *sourceModel, bool hideItems) + : mActor(actor) { + MWWorld::Ptr player = MWMechanics::getPlayer(); mSourceModel = sourceModel; - int chance = thief.getClass().getSkill(thief, ESM::Skill::Sneak); + int chance = player.getClass().getSkill(player, ESM::Skill::Sneak); mSourceModel->update(); @@ -75,4 +84,20 @@ namespace MWGui return false; } + bool PickpocketItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const + { + MWWorld::Ptr player = MWMechanics::getPlayer(); + MWMechanics::Pickpocket pickpocket(player, mActor); + if (pickpocket.pick(item, count)) + { + MWBase::Environment::get().getMechanicsManager()->commitCrime( + player, mActor, MWBase::MechanicsManager::OT_Pickpocket, 0, true); + MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); + return false; + } + else + player.getClass().skillUsageSucceeded(player, ESM::Skill::Sneak, 1); + + return true; + } } diff --git a/apps/openmw/mwgui/pickpocketitemmodel.hpp b/apps/openmw/mwgui/pickpocketitemmodel.hpp index 1b08ec485..ad8788da7 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.hpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.hpp @@ -18,6 +18,10 @@ namespace MWGui virtual void update(); virtual void removeItem (const ItemStack& item, size_t count); virtual bool allowedToInsertItems() const; + virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; + + protected: + MWWorld::Ptr mActor; private: std::vector mHiddenItems; diff --git a/apps/openmw/mwgui/sortfilteritemmodel.cpp b/apps/openmw/mwgui/sortfilteritemmodel.cpp index e294ebe07..932f362fb 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.cpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.cpp @@ -311,4 +311,8 @@ namespace MWGui std::sort(mItems.begin(), mItems.end(), cmp); } + bool SortFilterItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + { + return mSourceModel->onTakeItem (item, count); + } } diff --git a/apps/openmw/mwgui/sortfilteritemmodel.hpp b/apps/openmw/mwgui/sortfilteritemmodel.hpp index 6ddb019b0..e99726b0f 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.hpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.hpp @@ -29,6 +29,8 @@ namespace MWGui /// Use ItemStack::Type for sorting? void setSortByType(bool sort) { mSortByType = sort; } + bool onTakeItem(const MWWorld::Ptr &item, int count); + static const int Category_Weapon = (1<<1); static const int Category_Apparel = (1<<2); static const int Category_Misc = (1<<3); From ac33ff94827188d2623a042120ad51874ae7253b Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 4 Oct 2017 22:37:08 +0400 Subject: [PATCH 05/12] Move onDropItem() check to item models --- apps/openmw/mwgui/container.cpp | 24 ++-------------- apps/openmw/mwgui/containeritemmodel.cpp | 34 +++++++++++++++++++++-- apps/openmw/mwgui/containeritemmodel.hpp | 5 +++- apps/openmw/mwgui/inventoryitemmodel.cpp | 2 +- apps/openmw/mwgui/inventoryitemmodel.hpp | 3 +- apps/openmw/mwgui/itemmodel.cpp | 14 ++++++++-- apps/openmw/mwgui/itemmodel.hpp | 7 +++-- apps/openmw/mwgui/pickpocketitemmodel.cpp | 12 +++++++- apps/openmw/mwgui/pickpocketitemmodel.hpp | 1 + apps/openmw/mwgui/sortfilteritemmodel.cpp | 7 ++++- apps/openmw/mwgui/sortfilteritemmodel.hpp | 3 +- 11 files changed, 79 insertions(+), 33 deletions(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index be3cb1522..3fa07b070 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -100,28 +100,10 @@ namespace MWGui void ContainerWindow::dropItem() { - if (mPtr.getTypeName() == typeid(ESM::Container).name()) - { - // check container organic flag - MWWorld::LiveCellRef* ref = mPtr.get(); - if (ref->mBase->mFlags & ESM::Container::Organic) - { - MWBase::Environment::get().getWindowManager()-> - messageBox("#{sContentsMessage2}"); - return; - } + bool success = mModel->onDropItem(mDragAndDrop->mItem.mBase, mDragAndDrop->mDraggedCount); - // check that we don't exceed container capacity - MWWorld::Ptr item = mDragAndDrop->mItem.mBase; - float weight = item.getClass().getWeight(item) * mDragAndDrop->mDraggedCount; - if (mPtr.getClass().getCapacity(mPtr) < mPtr.getClass().getEncumbrance(mPtr) + weight) - { - MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage3}"); - return; - } - } - - mDragAndDrop->drop(mModel, mItemView); + if (success) + mDragAndDrop->drop(mModel, mItemView); } void ContainerWindow::onBackgroundSelected() diff --git a/apps/openmw/mwgui/containeritemmodel.cpp b/apps/openmw/mwgui/containeritemmodel.cpp index ee89f1350..ef7aa8215 100644 --- a/apps/openmw/mwgui/containeritemmodel.cpp +++ b/apps/openmw/mwgui/containeritemmodel.cpp @@ -10,6 +10,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" #include "../mwmechanics/actorutil.hpp" @@ -185,8 +186,37 @@ void ContainerItemModel::update() } } } +bool ContainerItemModel::onDropItem(const MWWorld::Ptr &item, int count) const +{ + if (mItemSources.empty()) + return false; -bool ContainerItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + MWWorld::Ptr target = mItemSources[0]; + + if (target.getTypeName() != typeid(ESM::Container).name()) + return true; + + // check container organic flag + MWWorld::LiveCellRef* ref = target.get(); + if (ref->mBase->mFlags & ESM::Container::Organic) + { + MWBase::Environment::get().getWindowManager()-> + messageBox("#{sContentsMessage2}"); + return false; + } + + // check that we don't exceed container capacity + float weight = item.getClass().getWeight(item) * count; + if (target.getClass().getCapacity(target) < target.getClass().getEncumbrance(target) + weight) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage3}"); + return false; + } + + return true; +} + +bool ContainerItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const { if (mItemSources.empty()) return false; @@ -196,7 +226,7 @@ bool ContainerItemModel::onTakeItem(const MWWorld::Ptr &item, int count) // Looting a dead corpse is considered OK if (target.getClass().isActor() && target.getClass().getCreatureStats(target).isDead()) return true; - + MWWorld::Ptr player = MWMechanics::getPlayer(); MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, target, count); diff --git a/apps/openmw/mwgui/containeritemmodel.hpp b/apps/openmw/mwgui/containeritemmodel.hpp index a0dbc2cf9..fb57096ef 100644 --- a/apps/openmw/mwgui/containeritemmodel.hpp +++ b/apps/openmw/mwgui/containeritemmodel.hpp @@ -18,6 +18,10 @@ namespace MWGui ContainerItemModel (const MWWorld::Ptr& source); virtual bool allowedToUseItems() const; + + virtual bool onDropItem(const MWWorld::Ptr &item, int count) const; + virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; + virtual ItemStack getItem (ModelIndex index); virtual ModelIndex getIndex (ItemStack item); virtual size_t getItemCount(); @@ -26,7 +30,6 @@ namespace MWGui virtual void removeItem (const ItemStack& item, size_t count); virtual void update(); - virtual bool onTakeItem(const MWWorld::Ptr &item, int count); private: std::vector mItemSources; diff --git a/apps/openmw/mwgui/inventoryitemmodel.cpp b/apps/openmw/mwgui/inventoryitemmodel.cpp index b807a58f4..aed08feb1 100644 --- a/apps/openmw/mwgui/inventoryitemmodel.cpp +++ b/apps/openmw/mwgui/inventoryitemmodel.cpp @@ -124,7 +124,7 @@ bool InventoryItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const // Looting a dead corpse is considered OK if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead()) return true; - + MWWorld::Ptr player = MWMechanics::getPlayer(); MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, mActor, count); diff --git a/apps/openmw/mwgui/inventoryitemmodel.hpp b/apps/openmw/mwgui/inventoryitemmodel.hpp index 95afeb5d4..c5ca80eed 100644 --- a/apps/openmw/mwgui/inventoryitemmodel.hpp +++ b/apps/openmw/mwgui/inventoryitemmodel.hpp @@ -15,6 +15,8 @@ namespace MWGui virtual ModelIndex getIndex (ItemStack item); virtual size_t getItemCount(); + virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; + virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false); virtual void removeItem (const ItemStack& item, size_t count); @@ -22,7 +24,6 @@ namespace MWGui virtual MWWorld::Ptr moveItem (const ItemStack& item, size_t count, ItemModel* otherModel); virtual void update(); - virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; protected: MWWorld::Ptr mActor; diff --git a/apps/openmw/mwgui/itemmodel.cpp b/apps/openmw/mwgui/itemmodel.cpp index 5a6afdf02..25dce728a 100644 --- a/apps/openmw/mwgui/itemmodel.cpp +++ b/apps/openmw/mwgui/itemmodel.cpp @@ -129,7 +129,12 @@ namespace MWGui return true; } - bool ItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + bool ItemModel::onDropItem(const MWWorld::Ptr &item, int count) const + { + return true; + } + + bool ItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const { return true; } @@ -203,7 +208,12 @@ namespace MWGui mSourceModel = sourceModel; } - bool ProxyItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + bool ProxyItemModel::onDropItem(const MWWorld::Ptr &item, int count) const + { + return mSourceModel->onDropItem (item, count); + } + + bool ProxyItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const { return mSourceModel->onTakeItem (item, count); } diff --git a/apps/openmw/mwgui/itemmodel.hpp b/apps/openmw/mwgui/itemmodel.hpp index c4a3a03e8..78c646e33 100644 --- a/apps/openmw/mwgui/itemmodel.hpp +++ b/apps/openmw/mwgui/itemmodel.hpp @@ -75,7 +75,8 @@ namespace MWGui /// Is the player allowed to insert items into this model? (default true) virtual bool allowedToInsertItems() const; - virtual bool onTakeItem(const MWWorld::Ptr &item, int count); + virtual bool onDropItem(const MWWorld::Ptr &item, int count) const; + virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; private: ItemModel(const ItemModel&); @@ -92,10 +93,12 @@ namespace MWGui bool allowedToUseItems() const; + virtual bool onDropItem(const MWWorld::Ptr &item, int count) const; + virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; + virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false); virtual void removeItem (const ItemStack& item, size_t count); virtual ModelIndex getIndex (ItemStack item); - virtual bool onTakeItem(const MWWorld::Ptr &item, int count); /// @note Takes ownership of the passed pointer. void setSourceModel(ItemModel* sourceModel); diff --git a/apps/openmw/mwgui/pickpocketitemmodel.cpp b/apps/openmw/mwgui/pickpocketitemmodel.cpp index e610854c1..ba8fd7d75 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.cpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.cpp @@ -4,6 +4,7 @@ #include #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/pickpocket.hpp" #include "../mwworld/class.hpp" @@ -80,12 +81,21 @@ namespace MWGui bool PickpocketItemModel::allowedToInsertItems() const { - // don't allow "reverse pickpocket" (yet) + // don't allow "reverse pickpocket" (it will be handled by scripts after 1.0) + return false; + } + + bool PickpocketItemModel::onDropItem(const MWWorld::Ptr &item, int count) + { + // don't allow "reverse pickpocket" (it will be handled by scripts after 1.0) return false; } bool PickpocketItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const { + if (mActor.getClass().getCreatureStats(mActor).getKnockedDown()) + return mSourceModel->onTakeItem(item, count); + MWWorld::Ptr player = MWMechanics::getPlayer(); MWMechanics::Pickpocket pickpocket(player, mActor); if (pickpocket.pick(item, count)) diff --git a/apps/openmw/mwgui/pickpocketitemmodel.hpp b/apps/openmw/mwgui/pickpocketitemmodel.hpp index ad8788da7..a759cd993 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.hpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.hpp @@ -18,6 +18,7 @@ namespace MWGui virtual void update(); virtual void removeItem (const ItemStack& item, size_t count); virtual bool allowedToInsertItems() const; + virtual bool onDropItem(const MWWorld::Ptr &item, int count) const; virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; protected: diff --git a/apps/openmw/mwgui/sortfilteritemmodel.cpp b/apps/openmw/mwgui/sortfilteritemmodel.cpp index 932f362fb..15c7fbfcb 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.cpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.cpp @@ -311,7 +311,12 @@ namespace MWGui std::sort(mItems.begin(), mItems.end(), cmp); } - bool SortFilterItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + bool SortFilterItemModel::onDropItem(const MWWorld::Ptr &item, int count) const + { + return mSourceModel->onDropItem (item, count); + } + + bool SortFilterItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const { return mSourceModel->onTakeItem (item, count); } diff --git a/apps/openmw/mwgui/sortfilteritemmodel.hpp b/apps/openmw/mwgui/sortfilteritemmodel.hpp index e99726b0f..fa8d836b5 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.hpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.hpp @@ -29,7 +29,8 @@ namespace MWGui /// Use ItemStack::Type for sorting? void setSortByType(bool sort) { mSortByType = sort; } - bool onTakeItem(const MWWorld::Ptr &item, int count); + bool onDropItem(const MWWorld::Ptr &item, int count) const; + bool onTakeItem(const MWWorld::Ptr &item, int count) const; static const int Category_Weapon = (1<<1); static const int Category_Apparel = (1<<2); From 3694b6ec90369c9e070ac785d08a3a6496afadfd Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 4 Oct 2017 23:26:06 +0400 Subject: [PATCH 06/12] Move onClose() check to item models --- apps/openmw/mwgui/container.cpp | 24 +------------------ apps/openmw/mwgui/container.hpp | 2 -- apps/openmw/mwgui/containeritemmodel.cpp | 4 ++-- apps/openmw/mwgui/containeritemmodel.hpp | 4 ++-- apps/openmw/mwgui/inventoryitemmodel.cpp | 2 +- apps/openmw/mwgui/inventoryitemmodel.hpp | 2 +- apps/openmw/mwgui/itemmodel.cpp | 17 ++++++++----- apps/openmw/mwgui/itemmodel.hpp | 12 ++++++---- apps/openmw/mwgui/pickpocketitemmodel.cpp | 29 +++++++++++++++++++++-- apps/openmw/mwgui/pickpocketitemmodel.hpp | 7 ++++-- apps/openmw/mwgui/sortfilteritemmodel.cpp | 13 ++++++---- apps/openmw/mwgui/sortfilteritemmodel.hpp | 5 ++-- 12 files changed, 70 insertions(+), 51 deletions(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 3fa07b070..03c7b54be 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -12,9 +12,7 @@ #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwmechanics/pickpocket.hpp" #include "../mwmechanics/creaturestats.hpp" -#include "../mwmechanics/actorutil.hpp" #include "countdialog.hpp" #include "inventorywindow.hpp" @@ -33,7 +31,6 @@ namespace MWGui ContainerWindow::ContainerWindow(DragAndDrop* dragAndDrop) : WindowBase("openmw_container_window.layout") , mDragAndDrop(dragAndDrop) - , mPickpocketDetected(false) , mSortModel(NULL) , mModel(NULL) , mSelectedItem(-1) @@ -114,7 +111,6 @@ namespace MWGui void ContainerWindow::setPtr(const MWWorld::Ptr& container) { - mPickpocketDetected = false; mPtr = container; bool loot = mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead(); @@ -159,24 +155,7 @@ namespace MWGui { WindowBase::onClose(); - if (dynamic_cast(mModel) - // Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened) - && !MWBase::Environment::get().getWindowManager()->containsMode(GM_Container) - // If it was already detected while taking an item, no need to check now - && !mPickpocketDetected - ) - { - MWWorld::Ptr player = MWMechanics::getPlayer(); - MWMechanics::Pickpocket pickpocket(player, mPtr); - if (pickpocket.finish()) - { - MWBase::Environment::get().getMechanicsManager()->commitCrime( - player, mPtr, MWBase::MechanicsManager::OT_Pickpocket, 0, true); - MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); - mPickpocketDetected = true; - return; - } - } + mModel->onClose(); } void ContainerWindow::onCloseButtonClicked(MyGUI::Widget* _sender) @@ -252,7 +231,6 @@ namespace MWGui bool ContainerWindow::onTakeItem(const ItemStack &item, int count) { - // TODO: mPickpocketDetected = true; return mModel->onTakeItem(item.mBase, count); } diff --git a/apps/openmw/mwgui/container.hpp b/apps/openmw/mwgui/container.hpp index 50c69da3b..cf02d165d 100644 --- a/apps/openmw/mwgui/container.hpp +++ b/apps/openmw/mwgui/container.hpp @@ -44,8 +44,6 @@ namespace MWGui private: DragAndDrop* mDragAndDrop; - bool mPickpocketDetected; - MWGui::ItemView* mItemView; SortFilterItemModel* mSortModel; ItemModel* mModel; diff --git a/apps/openmw/mwgui/containeritemmodel.cpp b/apps/openmw/mwgui/containeritemmodel.cpp index ef7aa8215..8e42b3ebc 100644 --- a/apps/openmw/mwgui/containeritemmodel.cpp +++ b/apps/openmw/mwgui/containeritemmodel.cpp @@ -186,7 +186,7 @@ void ContainerItemModel::update() } } } -bool ContainerItemModel::onDropItem(const MWWorld::Ptr &item, int count) const +bool ContainerItemModel::onDropItem(const MWWorld::Ptr &item, int count) { if (mItemSources.empty()) return false; @@ -216,7 +216,7 @@ bool ContainerItemModel::onDropItem(const MWWorld::Ptr &item, int count) const return true; } -bool ContainerItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const +bool ContainerItemModel::onTakeItem(const MWWorld::Ptr &item, int count) { if (mItemSources.empty()) return false; diff --git a/apps/openmw/mwgui/containeritemmodel.hpp b/apps/openmw/mwgui/containeritemmodel.hpp index fb57096ef..e8d1c5328 100644 --- a/apps/openmw/mwgui/containeritemmodel.hpp +++ b/apps/openmw/mwgui/containeritemmodel.hpp @@ -19,8 +19,8 @@ namespace MWGui virtual bool allowedToUseItems() const; - virtual bool onDropItem(const MWWorld::Ptr &item, int count) const; - virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; + virtual bool onDropItem(const MWWorld::Ptr &item, int count); + virtual bool onTakeItem(const MWWorld::Ptr &item, int count); virtual ItemStack getItem (ModelIndex index); virtual ModelIndex getIndex (ItemStack item); diff --git a/apps/openmw/mwgui/inventoryitemmodel.cpp b/apps/openmw/mwgui/inventoryitemmodel.cpp index aed08feb1..c9f55d352 100644 --- a/apps/openmw/mwgui/inventoryitemmodel.cpp +++ b/apps/openmw/mwgui/inventoryitemmodel.cpp @@ -119,7 +119,7 @@ void InventoryItemModel::update() } } -bool InventoryItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const +bool InventoryItemModel::onTakeItem(const MWWorld::Ptr &item, int count) { // Looting a dead corpse is considered OK if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead()) diff --git a/apps/openmw/mwgui/inventoryitemmodel.hpp b/apps/openmw/mwgui/inventoryitemmodel.hpp index c5ca80eed..38730bd4d 100644 --- a/apps/openmw/mwgui/inventoryitemmodel.hpp +++ b/apps/openmw/mwgui/inventoryitemmodel.hpp @@ -15,7 +15,7 @@ namespace MWGui virtual ModelIndex getIndex (ItemStack item); virtual size_t getItemCount(); - virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; + virtual bool onTakeItem(const MWWorld::Ptr &item, int count); virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false); virtual void removeItem (const ItemStack& item, size_t count); diff --git a/apps/openmw/mwgui/itemmodel.cpp b/apps/openmw/mwgui/itemmodel.cpp index 25dce728a..c59bc8bf4 100644 --- a/apps/openmw/mwgui/itemmodel.cpp +++ b/apps/openmw/mwgui/itemmodel.cpp @@ -129,12 +129,12 @@ namespace MWGui return true; } - bool ItemModel::onDropItem(const MWWorld::Ptr &item, int count) const + bool ItemModel::onDropItem(const MWWorld::Ptr &item, int count) { return true; } - bool ItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const + bool ItemModel::onTakeItem(const MWWorld::Ptr &item, int count) { return true; } @@ -208,13 +208,18 @@ namespace MWGui mSourceModel = sourceModel; } - bool ProxyItemModel::onDropItem(const MWWorld::Ptr &item, int count) const + void ProxyItemModel::onClose() { - return mSourceModel->onDropItem (item, count); + mSourceModel->onClose(); } - bool ProxyItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const + bool ProxyItemModel::onDropItem(const MWWorld::Ptr &item, int count) { - return mSourceModel->onTakeItem (item, count); + return mSourceModel->onDropItem(item, count); + } + + bool ProxyItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + { + return mSourceModel->onTakeItem(item, count); } } diff --git a/apps/openmw/mwgui/itemmodel.hpp b/apps/openmw/mwgui/itemmodel.hpp index 78c646e33..d50718e5d 100644 --- a/apps/openmw/mwgui/itemmodel.hpp +++ b/apps/openmw/mwgui/itemmodel.hpp @@ -75,8 +75,11 @@ namespace MWGui /// Is the player allowed to insert items into this model? (default true) virtual bool allowedToInsertItems() const; - virtual bool onDropItem(const MWWorld::Ptr &item, int count) const; - virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; + virtual void onClose() + { + } + virtual bool onDropItem(const MWWorld::Ptr &item, int count); + virtual bool onTakeItem(const MWWorld::Ptr &item, int count); private: ItemModel(const ItemModel&); @@ -93,8 +96,9 @@ namespace MWGui bool allowedToUseItems() const; - virtual bool onDropItem(const MWWorld::Ptr &item, int count) const; - virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; + virtual void onClose(); + virtual bool onDropItem(const MWWorld::Ptr &item, int count); + virtual bool onTakeItem(const MWWorld::Ptr &item, int count); virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool setNewOwner=false); virtual void removeItem (const ItemStack& item, size_t count); diff --git a/apps/openmw/mwgui/pickpocketitemmodel.cpp b/apps/openmw/mwgui/pickpocketitemmodel.cpp index ba8fd7d75..b073ef73f 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.cpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.cpp @@ -17,7 +17,7 @@ namespace MWGui { PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& actor, ItemModel *sourceModel, bool hideItems) - : mActor(actor) + : mActor(actor), mPickpocketDetected(false) { MWWorld::Ptr player = MWMechanics::getPlayer(); mSourceModel = sourceModel; @@ -91,11 +91,35 @@ namespace MWGui return false; } - bool PickpocketItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const + void PickpocketItemModel::onClose() + { + // Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened) + if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Container) + // If it was already detected while taking an item, no need to check now + || mPickpocketDetected) + return; + + MWWorld::Ptr player = MWMechanics::getPlayer(); + MWMechanics::Pickpocket pickpocket(player, mActor); + if (pickpocket.finish()) + { + MWBase::Environment::get().getMechanicsManager()->commitCrime( + player, mActor, MWBase::MechanicsManager::OT_Pickpocket, 0, true); + MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); + mPickpocketDetected = true; + } + } + + bool PickpocketItemModel::onTakeItem(const MWWorld::Ptr &item, int count) { if (mActor.getClass().getCreatureStats(mActor).getKnockedDown()) return mSourceModel->onTakeItem(item, count); + return stealItem(item, count); + } + + bool PickpocketItemModel::stealItem(const MWWorld::Ptr &item, int count) + { MWWorld::Ptr player = MWMechanics::getPlayer(); MWMechanics::Pickpocket pickpocket(player, mActor); if (pickpocket.pick(item, count)) @@ -103,6 +127,7 @@ namespace MWGui MWBase::Environment::get().getMechanicsManager()->commitCrime( player, mActor, MWBase::MechanicsManager::OT_Pickpocket, 0, true); MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); + mPickpocketDetected = true; return false; } else diff --git a/apps/openmw/mwgui/pickpocketitemmodel.hpp b/apps/openmw/mwgui/pickpocketitemmodel.hpp index a759cd993..9aa686c39 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.hpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.hpp @@ -18,11 +18,14 @@ namespace MWGui virtual void update(); virtual void removeItem (const ItemStack& item, size_t count); virtual bool allowedToInsertItems() const; - virtual bool onDropItem(const MWWorld::Ptr &item, int count) const; - virtual bool onTakeItem(const MWWorld::Ptr &item, int count) const; + virtual void onClose(); + virtual bool onDropItem(const MWWorld::Ptr &item, int count); + virtual bool onTakeItem(const MWWorld::Ptr &item, int count); protected: MWWorld::Ptr mActor; + bool mPickpocketDetected; + bool stealItem(const MWWorld::Ptr &item, int count); private: std::vector mHiddenItems; diff --git a/apps/openmw/mwgui/sortfilteritemmodel.cpp b/apps/openmw/mwgui/sortfilteritemmodel.cpp index 15c7fbfcb..1ee3cf631 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.cpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.cpp @@ -311,13 +311,18 @@ namespace MWGui std::sort(mItems.begin(), mItems.end(), cmp); } - bool SortFilterItemModel::onDropItem(const MWWorld::Ptr &item, int count) const + void SortFilterItemModel::onClose() { - return mSourceModel->onDropItem (item, count); + mSourceModel->onClose(); } - bool SortFilterItemModel::onTakeItem(const MWWorld::Ptr &item, int count) const + bool SortFilterItemModel::onDropItem(const MWWorld::Ptr &item, int count) { - return mSourceModel->onTakeItem (item, count); + return mSourceModel->onDropItem(item, count); + } + + bool SortFilterItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + { + return mSourceModel->onTakeItem(item, count); } } diff --git a/apps/openmw/mwgui/sortfilteritemmodel.hpp b/apps/openmw/mwgui/sortfilteritemmodel.hpp index fa8d836b5..98da8d8c9 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.hpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.hpp @@ -29,8 +29,9 @@ namespace MWGui /// Use ItemStack::Type for sorting? void setSortByType(bool sort) { mSortByType = sort; } - bool onDropItem(const MWWorld::Ptr &item, int count) const; - bool onTakeItem(const MWWorld::Ptr &item, int count) const; + void onClose(); + bool onDropItem(const MWWorld::Ptr &item, int count); + bool onTakeItem(const MWWorld::Ptr &item, int count); static const int Category_Weapon = (1<<1); static const int Category_Apparel = (1<<2); From 69a56eaea3fee303e3ef58d58d5ca6bd43668143 Mon Sep 17 00:00:00 2001 From: rexelion Date: Fri, 10 Nov 2017 10:44:53 +0000 Subject: [PATCH 07/12] don't initialise rangeAttackOfTarget --- apps/openmw/mwmechanics/aicombat.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 6e3268831..07fb455f3 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -491,7 +491,6 @@ namespace MWMechanics void AiCombatStorage::startCombatMove(bool isDistantCombat, float distToTarget, float rangeAttack, const MWWorld::Ptr& actor, const MWWorld::Ptr& target) { // get the range of the target's weapon - float rangeAttackOfTarget = 0.f; MWWorld::Ptr targetWeapon = MWWorld::Ptr(); const MWWorld::Class& targetClass = target.getClass(); @@ -505,7 +504,7 @@ namespace MWMechanics } bool isRangedCombat = false; - rangeAttackOfTarget = ActionWeapon(targetWeapon).getCombatRange(isRangedCombat); + float rangeAttackOfTarget = ActionWeapon(targetWeapon).getCombatRange(isRangedCombat); if (mMovement.mPosition[0] || mMovement.mPosition[1]) { From a02124f884018ab23d6d78538f6b2222ebaefd6c Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 5 Oct 2017 11:12:43 +0400 Subject: [PATCH 08/12] Handle item owners during pickpocketing --- apps/openmw/mwbase/mechanicsmanager.hpp | 3 +-- apps/openmw/mwgui/pickpocketitemmodel.cpp | 11 ++++++++-- .../mwmechanics/mechanicsmanagerimp.cpp | 22 ++++++++++++++----- .../mwmechanics/mechanicsmanagerimp.hpp | 2 +- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 398439ad8..7a33d6e57 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -140,7 +140,7 @@ namespace MWBase /// Utility to check if taking this item is illegal and calling commitCrime if so /// @param container The container the item is in; may be empty for an item in the world virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container, - int count) = 0; + int count, bool alarm = true) = 0; /// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 0; /// Attempt sleeping in a bed. If this is illegal, call commitCrime. @@ -250,7 +250,6 @@ namespace MWBase virtual void cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId) = 0; virtual void confiscateStolenItemToOwner(const MWWorld::Ptr &player, const MWWorld::Ptr &item, const MWWorld::Ptr& victim, int count) = 0; - virtual bool isAttackPrepairing(const MWWorld::Ptr& ptr) = 0; virtual bool isRunning(const MWWorld::Ptr& ptr) = 0; virtual bool isSneaking(const MWWorld::Ptr& ptr) = 0; diff --git a/apps/openmw/mwgui/pickpocketitemmodel.cpp b/apps/openmw/mwgui/pickpocketitemmodel.cpp index b073ef73f..4c32eafcd 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.cpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.cpp @@ -7,6 +7,7 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/pickpocket.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" #include "../mwbase/environment.hpp" @@ -76,7 +77,6 @@ namespace MWGui void PickpocketItemModel::removeItem (const ItemStack &item, size_t count) { ProxyItemModel::removeItem(item, count); - /// \todo check if player is detected } bool PickpocketItemModel::allowedToInsertItems() const @@ -115,7 +115,14 @@ namespace MWGui if (mActor.getClass().getCreatureStats(mActor).getKnockedDown()) return mSourceModel->onTakeItem(item, count); - return stealItem(item, count); + bool success = stealItem(item, count); + if (success) + { + MWWorld::Ptr player = MWMechanics::getPlayer(); + MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, mActor, count, false); + } + + return success; } bool PickpocketItemModel::stealItem(const MWWorld::Ptr &item, int count) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 2c7b6a500..a4e258ada 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1024,7 +1024,7 @@ namespace MWMechanics } void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, const MWWorld::Ptr& container, - int count) + int count, bool alarm) { if (ptr != getPlayer()) return; @@ -1053,19 +1053,29 @@ namespace MWMechanics return; Owner owner; - owner.first = ownerCellRef->getOwner(); owner.second = false; - if (owner.first.empty()) + if (!container.isEmpty() && container.getClass().isActor()) { - owner.first = ownerCellRef->getFaction(); - owner.second = true; + // "container" is an actor inventory, so just take actor's ID + owner.first = ownerCellRef->getRefId(); } + else + { + owner.first = ownerCellRef->getOwner(); + if (owner.first.empty()) + { + owner.first = ownerCellRef->getFaction(); + owner.second = true; + } + } + Misc::StringUtils::lowerCaseInPlace(owner.first); if (!Misc::StringUtils::ciEqual(item.getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId)) mStolenItems[Misc::StringUtils::lowerCase(item.getCellRef().getRefId())][owner] += count; - commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); + if (alarm) + commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index ee4cf28af..baee5233e 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -135,7 +135,7 @@ namespace MWMechanics /// Utility to check if taking this item is illegal and calling commitCrime if so /// @param container The container the item is in; may be empty for an item in the world virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container, - int count); + int count, bool alarm = true); /// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item); /// Attempt sleeping in a bed. If this is illegal, call commitCrime. From 99517d83ea2116577c5f893b723c019fc6645b5b Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 10 Nov 2017 09:43:22 +0400 Subject: [PATCH 09/12] Bound items detection refactoring --- apps/openmw/mwbase/mechanicsmanager.hpp | 1 + apps/openmw/mwgui/itemmodel.cpp | 34 +--------------- .../mwmechanics/mechanicsmanagerimp.cpp | 39 +++++++++++++++++++ .../mwmechanics/mechanicsmanagerimp.hpp | 2 + 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 7a33d6e57..5fb3bd400 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -238,6 +238,7 @@ namespace MWBase /// Has the player stolen this item from the given owner? virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0; + virtual bool isBoundItem(const MWWorld::Ptr& item) = 0; virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) = 0; /// Turn actor into werewolf or normal form. diff --git a/apps/openmw/mwgui/itemmodel.cpp b/apps/openmw/mwgui/itemmodel.cpp index c59bc8bf4..834c351dc 100644 --- a/apps/openmw/mwgui/itemmodel.cpp +++ b/apps/openmw/mwgui/itemmodel.cpp @@ -9,6 +9,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" namespace MWGui { @@ -23,38 +24,7 @@ namespace MWGui if (base.getClass().getEnchantment(base) != "") mFlags |= Flag_Enchanted; - static std::set boundItemIDCache; - - // If this is empty then we haven't executed the GMST cache logic yet; or there isn't any sMagicBound* GMST's for some reason - if (boundItemIDCache.empty()) - { - // Build a list of known bound item ID's - const MWWorld::Store &gameSettings = MWBase::Environment::get().getWorld()->getStore().get(); - - for (MWWorld::Store::iterator currentIteration = gameSettings.begin(); currentIteration != gameSettings.end(); ++currentIteration) - { - const ESM::GameSetting ¤tSetting = *currentIteration; - std::string currentGMSTID = currentSetting.mId; - Misc::StringUtils::lowerCaseInPlace(currentGMSTID); - - // Don't bother checking this GMST if it's not a sMagicBound* one. - const std::string& toFind = "smagicbound"; - if (currentGMSTID.compare(0, toFind.length(), toFind) != 0) - continue; - - // All sMagicBound* GMST's should be of type string - std::string currentGMSTValue = currentSetting.getString(); - Misc::StringUtils::lowerCaseInPlace(currentGMSTValue); - - boundItemIDCache.insert(currentGMSTValue); - } - } - - // Perform bound item check and assign the Flag_Bound bit if it passes - std::string tempItemID = base.getCellRef().getRefId(); - Misc::StringUtils::lowerCaseInPlace(tempItemID); - - if (boundItemIDCache.count(tempItemID) != 0) + if (MWBase::Environment::get().getMechanicsManager()->isBoundItem(base)) mFlags |= Flag_Bound; } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index a4e258ada..92031b80b 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -840,6 +840,45 @@ namespace MWMechanics mAI = true; } + bool MechanicsManager::isBoundItem(const MWWorld::Ptr& item) + { + static std::set boundItemIDCache; + + // If this is empty then we haven't executed the GMST cache logic yet; or there isn't any sMagicBound* GMST's for some reason + if (boundItemIDCache.empty()) + { + // Build a list of known bound item ID's + const MWWorld::Store &gameSettings = MWBase::Environment::get().getWorld()->getStore().get(); + + for (MWWorld::Store::iterator currentIteration = gameSettings.begin(); currentIteration != gameSettings.end(); ++currentIteration) + { + const ESM::GameSetting ¤tSetting = *currentIteration; + std::string currentGMSTID = currentSetting.mId; + Misc::StringUtils::lowerCaseInPlace(currentGMSTID); + + // Don't bother checking this GMST if it's not a sMagicBound* one. + const std::string& toFind = "smagicbound"; + if (currentGMSTID.compare(0, toFind.length(), toFind) != 0) + continue; + + // All sMagicBound* GMST's should be of type string + std::string currentGMSTValue = currentSetting.getString(); + Misc::StringUtils::lowerCaseInPlace(currentGMSTValue); + + boundItemIDCache.insert(currentGMSTValue); + } + } + + // Perform bound item check and assign the Flag_Bound bit if it passes + std::string tempItemID = item.getCellRef().getRefId(); + Misc::StringUtils::lowerCaseInPlace(tempItemID); + + if (boundItemIDCache.count(tempItemID) != 0) + return true; + + return false; + } + bool MechanicsManager::isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) { if (target.isEmpty()) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index baee5233e..bf3b7c79c 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -204,6 +204,8 @@ namespace MWMechanics /// Has the player stolen this item from the given owner? virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid); + virtual bool isBoundItem(const MWWorld::Ptr& item); + /// @return is \a ptr allowed to take/use \a target or is it a crime? virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim); From 03f129b53c97a5032c5862606c0d0f93a40abc38 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 11 Nov 2017 11:54:18 +0400 Subject: [PATCH 10/12] remove redundant allowedToInsertItems() function from ItemModel --- apps/openmw/mwgui/container.cpp | 7 +++---- apps/openmw/mwgui/itemmodel.cpp | 5 ----- apps/openmw/mwgui/itemmodel.hpp | 3 --- apps/openmw/mwgui/pickpocketitemmodel.cpp | 6 ------ apps/openmw/mwgui/pickpocketitemmodel.hpp | 1 - 5 files changed, 3 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 03c7b54be..444eaff85 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -52,10 +52,9 @@ namespace MWGui void ContainerWindow::onItemSelected(int index) { - if (mDragAndDrop->mIsOnDragAndDrop) + if (mDragAndDrop->mIsOnDragAndDrop && mModel) { - if (mModel && mModel->allowedToInsertItems()) - dropItem(); + dropItem(); return; } @@ -105,7 +104,7 @@ namespace MWGui void ContainerWindow::onBackgroundSelected() { - if (mDragAndDrop->mIsOnDragAndDrop && mModel && mModel->allowedToInsertItems()) + if (mDragAndDrop->mIsOnDragAndDrop && mModel) dropItem(); } diff --git a/apps/openmw/mwgui/itemmodel.cpp b/apps/openmw/mwgui/itemmodel.cpp index 834c351dc..e3f38a54c 100644 --- a/apps/openmw/mwgui/itemmodel.cpp +++ b/apps/openmw/mwgui/itemmodel.cpp @@ -94,11 +94,6 @@ namespace MWGui return true; } - bool ItemModel::allowedToInsertItems() const - { - return true; - } - bool ItemModel::onDropItem(const MWWorld::Ptr &item, int count) { return true; diff --git a/apps/openmw/mwgui/itemmodel.hpp b/apps/openmw/mwgui/itemmodel.hpp index d50718e5d..e8e348a8a 100644 --- a/apps/openmw/mwgui/itemmodel.hpp +++ b/apps/openmw/mwgui/itemmodel.hpp @@ -72,9 +72,6 @@ namespace MWGui /// Is the player allowed to use items from this item model? (default true) virtual bool allowedToUseItems() const; - - /// Is the player allowed to insert items into this model? (default true) - virtual bool allowedToInsertItems() const; virtual void onClose() { } diff --git a/apps/openmw/mwgui/pickpocketitemmodel.cpp b/apps/openmw/mwgui/pickpocketitemmodel.cpp index 4c32eafcd..e85715e87 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.cpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.cpp @@ -79,12 +79,6 @@ namespace MWGui ProxyItemModel::removeItem(item, count); } - bool PickpocketItemModel::allowedToInsertItems() const - { - // don't allow "reverse pickpocket" (it will be handled by scripts after 1.0) - return false; - } - bool PickpocketItemModel::onDropItem(const MWWorld::Ptr &item, int count) { // don't allow "reverse pickpocket" (it will be handled by scripts after 1.0) diff --git a/apps/openmw/mwgui/pickpocketitemmodel.hpp b/apps/openmw/mwgui/pickpocketitemmodel.hpp index 9aa686c39..83caf2ffd 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.hpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.hpp @@ -17,7 +17,6 @@ namespace MWGui virtual size_t getItemCount(); virtual void update(); virtual void removeItem (const ItemStack& item, size_t count); - virtual bool allowedToInsertItems() const; virtual void onClose(); virtual bool onDropItem(const MWWorld::Ptr &item, int count); virtual bool onTakeItem(const MWWorld::Ptr &item, int count); From f0649849b87be452acbab3307a145992c16f0101 Mon Sep 17 00:00:00 2001 From: rexelion Date: Sat, 11 Nov 2017 12:00:23 +0000 Subject: [PATCH 11/12] changed variable name to be more descriptive --- apps/openmw/mwmechanics/aicombat.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 07fb455f3..ee1013fe4 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -503,8 +503,8 @@ namespace MWMechanics targetWeapon = *weaponSlot; } - bool isRangedCombat = false; - float rangeAttackOfTarget = ActionWeapon(targetWeapon).getCombatRange(isRangedCombat); + bool targetUsesRanged = false; + float rangeAttackOfTarget = ActionWeapon(targetWeapon).getCombatRange(targetUsesRanged); if (mMovement.mPosition[0] || mMovement.mPosition[1]) { @@ -524,16 +524,17 @@ namespace MWMechanics } } - // Below behavior for backing up during ranged combat differs from vanilla. - // Vanilla is observed as backing up only as far as fCombatDistance or - // opponent's weapon range, or not backing up if opponent is also using a ranged weapon + // Backing up behaviour + // Actor backs up slightly further away than opponent's weapon range + // (in vanilla - only as far as oponent's weapon range), + // or not at all if opponent is using a ranged weapon if (isDistantCombat) { // actor should not back up into water if (MWBase::Environment::get().getWorld()->isUnderwater(MWWorld::ConstPtr(actor), 0.5f)) return; - if (!isRangedCombat && distToTarget <= rangeAttackOfTarget*1.5) // Don't back up if the target is wielding ranged weapon + if (!targetUsesRanged && distToTarget <= rangeAttackOfTarget*1.5) // Don't back up if the target is wielding ranged weapon mMovement.mPosition[1] = -1; } } From 8c0dcd8b2b8276f2030bd00053540febe7df6874 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 11 Nov 2017 19:46:59 +0400 Subject: [PATCH 12/12] Do not track a nearest actor during combat and pursue (bug #4179) --- apps/openmw/mwmechanics/actors.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index a144911c5..ce8ad8f66 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1230,8 +1230,13 @@ namespace MWMechanics float sqrHeadTrackDistance = std::numeric_limits::max(); MWWorld::Ptr headTrackTarget; + MWMechanics::CreatureStats& stats = iter->first.getClass().getCreatureStats(iter->first); + // Unconsious actor can not track target - if (!iter->first.getClass().getCreatureStats(iter->first).getKnockedDown()) + // Also actors in combat and pursue mode do not bother to headtrack + if (!stats.getKnockedDown() && + !stats.getAiSequence().isInCombat() && + !stats.getAiSequence().hasPackage(AiPackage::TypeIdPursue)) { for(PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it) { @@ -1239,8 +1244,9 @@ namespace MWMechanics continue; updateHeadTracking(iter->first, it->first, headTrackTarget, sqrHeadTrackDistance); } - iter->second->getCharacterController()->setHeadTrackTarget(headTrackTarget); } + + iter->second->getCharacterController()->setHeadTrackTarget(headTrackTarget); } if (iter->first.getClass().isNpc() && iter->first != player)