mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-28 19:21:04 +00:00
Merge pull request #1486 from akortunov/pickpocketfix
Fix some issues with pickpocketing (bug #4131)
This commit is contained in:
commit
302e3c8b3d
@ -238,7 +238,7 @@ namespace MWBase
|
|||||||
/// Has the player stolen this item from the given owner?
|
/// Has the player stolen this item from the given owner?
|
||||||
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0;
|
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid) = 0;
|
||||||
|
|
||||||
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::ConstPtr& item, MWWorld::Ptr& victim) = 0;
|
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) = 0;
|
||||||
|
|
||||||
/// Turn actor into werewolf or normal form.
|
/// Turn actor into werewolf or normal form.
|
||||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0;
|
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0;
|
||||||
|
@ -470,6 +470,9 @@ namespace MWClass
|
|||||||
if(stats.getAiSequence().isInCombat())
|
if(stats.getAiSequence().isInCombat())
|
||||||
return std::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction(""));
|
return std::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction(""));
|
||||||
|
|
||||||
|
if(stats.getKnockedDown())
|
||||||
|
return std::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction(""));
|
||||||
|
|
||||||
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(ptr));
|
return std::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,6 +567,12 @@ namespace MWDialogue
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actor.getClass().getCreatureStats(actor).getKnockedDown())
|
||||||
|
{
|
||||||
|
// Unconscious actors can not speak
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
const ESM::Dialogue *dial = store.get<ESM::Dialogue>().find(topic);
|
const ESM::Dialogue *dial = store.get<ESM::Dialogue>().find(topic);
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ namespace MWGui
|
|||||||
|
|
||||||
bool loot = mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead();
|
bool loot = mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead();
|
||||||
|
|
||||||
if (mPtr.getTypeName() == typeid(ESM::NPC).name() && !loot)
|
if (mPtr.getClass().isNpc() && !loot)
|
||||||
{
|
{
|
||||||
// we are stealing stuff
|
// we are stealing stuff
|
||||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||||
@ -271,9 +271,8 @@ namespace MWGui
|
|||||||
MWMechanics::Pickpocket pickpocket(player, mPtr);
|
MWMechanics::Pickpocket pickpocket(player, mPtr);
|
||||||
if (pickpocket.pick(item.mBase, count))
|
if (pickpocket.pick(item.mBase, count))
|
||||||
{
|
{
|
||||||
int value = item.mBase.getClass().getValue(item.mBase) * count;
|
|
||||||
MWBase::Environment::get().getMechanicsManager()->commitCrime(
|
MWBase::Environment::get().getMechanicsManager()->commitCrime(
|
||||||
player, mPtr, MWBase::MechanicsManager::OT_Theft, value, true);
|
player, mPtr, MWBase::MechanicsManager::OT_Pickpocket, 0, true);
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
|
||||||
mPickpocketDetected = true;
|
mPickpocketDetected = true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -325,7 +325,7 @@ namespace MWGui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolTips::setFocusObject(const MWWorld::ConstPtr& focus)
|
void ToolTips::setFocusObject(const MWWorld::Ptr& focus)
|
||||||
{
|
{
|
||||||
mFocusObject = focus;
|
mFocusObject = focus;
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ namespace MWGui
|
|||||||
|
|
||||||
void setDelay(float delay);
|
void setDelay(float delay);
|
||||||
|
|
||||||
void setFocusObject(const MWWorld::ConstPtr& focus);
|
void setFocusObject(const MWWorld::Ptr& focus);
|
||||||
void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y);
|
void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y);
|
||||||
///< set the screen-space position of the tooltip for focused object
|
///< set the screen-space position of the tooltip for focused object
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ namespace MWGui
|
|||||||
private:
|
private:
|
||||||
MyGUI::Widget* mDynamicToolTipBox;
|
MyGUI::Widget* mDynamicToolTipBox;
|
||||||
|
|
||||||
MWWorld::ConstPtr mFocusObject;
|
MWWorld::Ptr mFocusObject;
|
||||||
|
|
||||||
MyGUI::IntSize getToolTipViaPtr (int count, bool image=true);
|
MyGUI::IntSize getToolTipViaPtr (int count, bool image=true);
|
||||||
///< @return requested tooltip size
|
///< @return requested tooltip size
|
||||||
|
@ -1573,7 +1573,7 @@ namespace MWGui
|
|||||||
|
|
||||||
mMessageBoxManager->clear();
|
mMessageBoxManager->clear();
|
||||||
|
|
||||||
mToolTips->setFocusObject(MWWorld::ConstPtr());
|
mToolTips->setFocusObject(MWWorld::Ptr());
|
||||||
|
|
||||||
mSelectedSpell.clear();
|
mSelectedSpell.clear();
|
||||||
mCustomMarkers.clear();
|
mCustomMarkers.clear();
|
||||||
|
@ -1232,13 +1232,17 @@ namespace MWMechanics
|
|||||||
float sqrHeadTrackDistance = std::numeric_limits<float>::max();
|
float sqrHeadTrackDistance = std::numeric_limits<float>::max();
|
||||||
MWWorld::Ptr headTrackTarget;
|
MWWorld::Ptr headTrackTarget;
|
||||||
|
|
||||||
for(PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it)
|
// Unconsious actor can not track target
|
||||||
|
if (!iter->first.getClass().getCreatureStats(iter->first).getKnockedDown())
|
||||||
{
|
{
|
||||||
if (it->first == iter->first)
|
for(PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it)
|
||||||
continue;
|
{
|
||||||
updateHeadTracking(iter->first, it->first, headTrackTarget, sqrHeadTrackDistance);
|
if (it->first == iter->first)
|
||||||
|
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)
|
if (iter->first.getClass().isNpc() && iter->first != player)
|
||||||
|
@ -840,17 +840,33 @@ namespace MWMechanics
|
|||||||
mAI = true;
|
mAI = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MechanicsManager::isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::ConstPtr& item, MWWorld::Ptr& victim)
|
bool MechanicsManager::isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim)
|
||||||
{
|
{
|
||||||
const MWWorld::CellRef& cellref = item.getCellRef();
|
const MWWorld::CellRef& cellref = target.getCellRef();
|
||||||
// there is no harm to use unlocked doors
|
// there is no harm to use unlocked doors
|
||||||
if (item.getClass().isDoor() && cellref.getLockLevel() <= 0 && ptr.getCellRef().getTrap().empty())
|
if (target.getClass().isDoor() && cellref.getLockLevel() <= 0 && ptr.getCellRef().getTrap().empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// TODO: implement a better check to check if item is owned bed
|
// TODO: implement a better check to check if target is owned bed
|
||||||
if (item.getClass().isActivator() && item.getClass().getScript(item).compare(0, 3, "Bed") != 0)
|
if (target.getClass().isActivator() && target.getClass().getScript(target).compare(0, 3, "Bed") != 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (target.getClass().isNpc())
|
||||||
|
{
|
||||||
|
if (target.getClass().getCreatureStats(target).isDead())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (target.getClass().getCreatureStats(target).getAiSequence().isInCombat())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// check if a player tries to pickpocket a target NPC
|
||||||
|
if(ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak)
|
||||||
|
|| target.getClass().getCreatureStats(target).getKnockedDown())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string& owner = cellref.getOwner();
|
const std::string& owner = cellref.getOwner();
|
||||||
bool isOwned = !owner.empty() && owner != "player";
|
bool isOwned = !owner.empty() && owner != "player";
|
||||||
|
|
||||||
@ -1084,6 +1100,10 @@ namespace MWMechanics
|
|||||||
if (it->getClass().getCreatureStats(*it).isDead())
|
if (it->getClass().getCreatureStats(*it).isDead())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Unconsious actor can not report about crime
|
||||||
|
if (it->getClass().getCreatureStats(*it).getKnockedDown())
|
||||||
|
continue;
|
||||||
|
|
||||||
if ((*it == victim && victimAware)
|
if ((*it == victim && victimAware)
|
||||||
|| (MWBase::Environment::get().getWorld()->getLOS(player, *it) && awarenessCheck(player, *it) )
|
|| (MWBase::Environment::get().getWorld()->getLOS(player, *it) && awarenessCheck(player, *it) )
|
||||||
// Murder crime can be reported even if no one saw it (hearing is enough, I guess).
|
// Murder crime can be reported even if no one saw it (hearing is enough, I guess).
|
||||||
@ -1195,12 +1215,16 @@ namespace MWMechanics
|
|||||||
// Tell everyone (including the original reporter) in alarm range
|
// Tell everyone (including the original reporter) in alarm range
|
||||||
for (std::vector<MWWorld::Ptr>::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
|
for (std::vector<MWWorld::Ptr>::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
|
||||||
{
|
{
|
||||||
if ( *it == player
|
if (*it == player
|
||||||
|| !it->getClass().isNpc() || it->getClass().getCreatureStats(*it).isDead()) continue;
|
|| !it->getClass().isNpc() || it->getClass().getCreatureStats(*it).isDead()) continue;
|
||||||
|
|
||||||
if (it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(victim))
|
if (it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(victim))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Unconsious actor can not report about crime and should not become hostile
|
||||||
|
if (it->getClass().getCreatureStats(*it).getKnockedDown())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Player's followers should not attack player, or try to arrest him
|
// Player's followers should not attack player, or try to arrest him
|
||||||
if (it->getClass().getCreatureStats(*it).getAiSequence().hasPackage(AiPackage::TypeIdFollow))
|
if (it->getClass().getCreatureStats(*it).getAiSequence().hasPackage(AiPackage::TypeIdFollow))
|
||||||
{
|
{
|
||||||
|
@ -204,8 +204,8 @@ namespace MWMechanics
|
|||||||
/// Has the player stolen this item from the given owner?
|
/// Has the player stolen this item from the given owner?
|
||||||
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid);
|
virtual bool isItemStolenFrom(const std::string& itemid, const std::string& ownerid);
|
||||||
|
|
||||||
/// @return is \a ptr allowed to take/use \a cellref or is it a crime?
|
/// @return is \a ptr allowed to take/use \a target or is it a crime?
|
||||||
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::ConstPtr& item, MWWorld::Ptr& victim);
|
virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim);
|
||||||
|
|
||||||
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf);
|
virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf);
|
||||||
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor);
|
virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user