diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 170e6705a..bb6f5741d 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -513,8 +513,6 @@ namespace MWBase virtual void explodeSpell (const Ogre::Vector3& origin, const MWWorld::Ptr& object, const ESM::EffectList& effects, const MWWorld::Ptr& caster, const std::string& id, const std::string& sourceName) = 0; - - virtual void resetCrimes(const MWWorld::Ptr& ptr) = 0; }; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 92be89f2f..11469c1a9 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -29,6 +29,9 @@ #include "aicombat.hpp" #include "aifollow.hpp" +#include "aipersue.hpp" + +#include "../mwbase/dialoguemanager.hpp" //------------------------ namespace { @@ -175,14 +178,16 @@ namespace MWMechanics adjustMagicEffects (ptr); if (ptr.getClass().getCreatureStats(ptr).needToRecalcDynamicStats()) calculateDynamicStats (ptr); + calculateCreatureStatModifiers (ptr, duration); // AI if(MWBase::Environment::get().getMechanicsManager()->isAIActive()) { - CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr); - //engage combat or not? + CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + + //engage combat or not? if(ptr != player && !creatureStats.isHostile()) { ESM::Position playerpos = player.getRefData().getPosition(); @@ -214,7 +219,7 @@ namespace MWMechanics creatureStats.setHostile(true); } } - + updateCrimePersuit(ptr, duration); creatureStats.getAiSequence().execute (ptr,duration); } @@ -711,6 +716,48 @@ namespace MWMechanics } } + void Actors::updateCrimePersuit(const MWWorld::Ptr& ptr, float duration) + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + int bounty = player.getClass().getNpcStats(player).getBounty(); + + // TODO: Move me! I shouldn't be here... + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); + float cutoff = float(esmStore.get().find("iCrimeThreshold")->getInt()) * + float(esmStore.get().find("iCrimeThresholdMultiplier")->getInt()) * + esmStore.get().find("fCrimeGoldDiscountMult")->getFloat(); + + if (ptr != player) + { + CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); + // Alarmed or not, I will kill you because you've commited heinous against the empire + if ((!creatureStats.isAlarmed() || creatureStats.isAlarmed()) && + ptr.getClass().isClass(ptr, "Guard") && bounty >= cutoff && !creatureStats.isHostile()) + creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player))); + else if (creatureStats.isAlarmed()) + { + MWBase::Environment::get().getDialogueManager()->say(ptr, "Thief"); + if(bounty == 0) + { + creatureStats.setAlarmed(false); + creatureStats.setHostile(false); + if (ptr.getClass().isClass(ptr, "Guard")) + creatureStats.getAiSequence().stopPersue(); + creatureStats.getAiSequence().stopCombat(); + + } + + if (ptr.getClass().isClass(ptr, "Guard") && !creatureStats.isHostile()) + creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player))); + else if (!creatureStats.isHostile()) + { + creatureStats.getAiSequence().stack(AiCombat(player)); + creatureStats.setHostile(true); + } + } + } + } + Actors::Actors() {} Actors::~Actors() diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 4b18ac862..d61d74258 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -42,6 +42,8 @@ namespace MWMechanics void updateEquippedLight (const MWWorld::Ptr& ptr, float duration); + void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration); + public: Actors(); diff --git a/apps/openmw/mwmechanics/aipersue.cpp b/apps/openmw/mwmechanics/aipersue.cpp index 21239860f..36e18946c 100644 --- a/apps/openmw/mwmechanics/aipersue.cpp +++ b/apps/openmw/mwmechanics/aipersue.cpp @@ -19,10 +19,8 @@ MWMechanics::AiPersue *MWMechanics::AiPersue::clone() const { return new AiPersue(*this); } -bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor,float duration) +bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration) { - //TODO: Guards should not dialague with player after crime reset - MWBase::World *world = MWBase::Environment::get().getWorld(); ESM::Position pos = actor.getRefData().getPosition(); Movement &movement = actor.getClass().getMovementSettings(actor); diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index feed8d182..a358917de 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -14,7 +14,7 @@ namespace MWMechanics CreatureStats::CreatureStats() : mLevel (0), mDead (false), mDied (false), mFriendlyHits (0), mTalkedTo (false), mAlarmed (false), - mAttacked (false), mHostile (false), + mAttacked (false), mHostile (false), mAssaulted(false), mAttackingOrSpell(false), mIsWerewolf(false), mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mHitRecovery(false), mBlock(false), @@ -316,6 +316,16 @@ namespace MWMechanics mHostile = hostile; } + bool CreatureStats::isAssaulted() const + { + return mAssaulted; + } + + void CreatureStats::setAssaulted (bool assaulted) + { + mAssaulted = assaulted; + } + bool CreatureStats::getCreatureTargetted() const { std::string target; diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 20a9a5799..7db895dab 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -39,6 +39,7 @@ namespace MWMechanics bool mAlarmed; bool mAttacked; bool mHostile; + bool mAssaulted; bool mAttackingOrSpell; bool mKnockdown; bool mHitRecovery; @@ -186,6 +187,10 @@ namespace MWMechanics void setHostile (bool hostile); + bool isAssaulted() const; + + void setAssaulted (bool assaulted); + bool getCreatureTargetted() const; float getEvasion() const; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 8714e3eaf..2edb3d177 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1,5 +1,6 @@ #include "mechanicsmanagerimp.hpp" +#include "npcstats.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" @@ -12,10 +13,6 @@ #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" -#include "aicombat.hpp" -#include "aipersue.hpp" -#include "aiactivate.hpp" - #include #include "spellcasting.hpp" @@ -827,11 +824,6 @@ namespace MWMechanics else if (type == OT_Theft) alarm = esmStore.get().find("iAlarmStealing")->getInt(); - // what is the bounty cutoff? To high the guards will attack - float cutoff = float(esmStore.get().find("iCrimeThreshold")->getInt()) * - float(esmStore.get().find("iCrimeThresholdMultiplier")->getInt()) * - esmStore.get().find("fCrimeGoldDiscountMult")->getFloat(); - // Innocent until proven guilty bool reported = false; @@ -846,8 +838,9 @@ namespace MWMechanics CreatureStats& creatureStats = MWWorld::Class::get(*it).getCreatureStats(*it); - // Did a witness see the crime? - if ( MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) ) + // Was the crime seen or the victim assulted? + if ( ( MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) ) || + type == OT_Assault) { // Say something! // TODO: Add more messages @@ -858,7 +851,6 @@ namespace MWMechanics if (creatureStats.getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm) { reported = true; - reportCrime(ptr, victim, type, arg); // Tell everyone else for (std::vector::iterator it1 = neighbors.begin(); it1 != neighbors.end(); ++it1) @@ -870,38 +862,13 @@ namespace MWMechanics CreatureStats& creatureStats1 = MWWorld::Class::get(*it1).getCreatureStats(*it1); if (creatureStats1.getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm) creatureStats1.setAlarmed(true); - - // was the witness a guard? - if (it1->getClass().isClass(*it1, "Guard")) - { - // will the guard try to kill the player? - if (ptr.getClass().getNpcStats(ptr).getBounty() >= cutoff) - { - creatureStats1.getAiSequence().stack(AiCombat(ptr)); - creatureStats1.setHostile(true); - creatureStats1.getAiSequence().execute(*it1,0); - } - else // will the guard persue the player? - { - creatureStats1.getAiSequence().stack(AiPersue(ptr.getClass().getId(ptr))); - creatureStats1.getAiSequence().execute(*it1,0); - } - } - // will the witness fight the player? - else if (creatureStats1.getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm || - type == OT_Assault) - { - creatureStats1.getAiSequence().stack(AiCombat(ptr)); - creatureStats1.setHostile(true); - creatureStats1.getAiSequence().execute(*it1,0); - } } break; // Someone saw the crime and everyone has been told - } + } } } - if (reported) - MWBase::Environment::get().getWorld()->getPlayer().addPlayerWitnesses(neighbors); + if(reported) + reportCrime(ptr, victim, type, arg); return reported; } diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 781a34368..cd29e2c91 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -810,11 +810,8 @@ namespace MWScript public: virtual void execute(Interpreter::Runtime &runtime) { - MWBase::World* world = MWBase::Environment::get().getWorld(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); player.getClass().getNpcStats(player).setBounty(0); - world->confiscateStolenItems(player); - world->resetCrimes(player); } }; @@ -823,10 +820,8 @@ namespace MWScript public: virtual void execute(Interpreter::Runtime &runtime) { - MWBase::World* world = MWBase::Environment::get().getWorld(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); player.getClass().getNpcStats(player).setBounty(0); - world->resetCrimes(player); } }; diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 7db2afb3f..6d551ecf1 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -274,17 +274,4 @@ namespace MWWorld return false; } - - void Player::addPlayerWitnesses(std::vector witnesses) - { - mWitnesses.insert(mWitnesses.end(), witnesses.begin(), witnesses.end()); - } - std::vector Player::getPlayerWitnesses() const - { - return mWitnesses; - } - void Player::resetPlayerWitnesses() - { - mWitnesses.clear(); - } } diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index 001d3b7a6..b41e6fc9f 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -96,10 +96,6 @@ namespace MWWorld void write (ESM::ESMWriter& writer) const; bool readRecord (ESM::ESMReader& reader, int32_t type); - - void addPlayerWitnesses(std::vector witnesses); - std::vector getPlayerWitnesses() const; - void resetPlayerWitnesses(); }; } #endif diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 954b8e126..f3e404c35 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2765,33 +2765,12 @@ namespace MWWorld // TODO: Sleep the player - resetCrimes(player); - std::vector buttons; buttons.push_back("#{sOk}"); MWBase::Environment::get().getWindowManager()->messageBox(message, buttons); } } - void World::resetCrimes(const MWWorld::Ptr& ptr) - { - // Reset witnesses to the players crimes - std::vector neighbors = mPlayer->getPlayerWitnesses(); - for (std::vector::iterator it = neighbors.begin(); it != neighbors.end(); ++it) - { - // Reset states - // TODO: More research is needed to complete this list - it->getClass().getCreatureStats(*it).setHostile(false); - it->getClass().getCreatureStats(*it).setAlarmed(false); - - // Stop guard persue - if(it->getClass().isClass(*it, "Guard")) - it->getClass().getCreatureStats(*it).getAiSequence().stopPersue(); - - } - mPlayer->resetPlayerWitnesses(); - } - void World::spawnRandomCreature(const std::string &creatureList) { const ESM::CreatureLevList* list = getStore().get().find(creatureList); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 06d49ad24..42f52cb61 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -611,7 +611,6 @@ namespace MWWorld virtual void explodeSpell (const Ogre::Vector3& origin, const MWWorld::Ptr& object, const ESM::EffectList& effects, const MWWorld::Ptr& caster, const std::string& id, const std::string& sourceName); - virtual void resetCrimes(const MWWorld::Ptr& ptr); }; }