From 6c866deb1b0123c8f620448fa07cdfbb904910b8 Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Sat, 29 Mar 2014 21:23:34 -0400 Subject: [PATCH] Feature #1154 Not all NPCs get aggressive when one is attacked Partially implemented --- apps/openmw/mwbase/mechanicsmanager.hpp | 2 +- .../mwmechanics/mechanicsmanagerimp.cpp | 65 ++++++++++++------- .../mwmechanics/mechanicsmanagerimp.hpp | 2 +- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 22dda0ce0..36b8df519 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -111,7 +111,7 @@ namespace MWBase * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. * @return was the crime reported? */ - virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, + virtual bool commitCrime (const MWWorld::Ptr& offender, const MWWorld::Ptr& victim, OffenseType type, int arg=0) = 0; virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, int arg=0) = 0; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 4c8f35edb..2c51e0083 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -3,6 +3,7 @@ #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/cellstore.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -12,6 +13,8 @@ #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" +#include "aicombat.hpp" + #include #include "spellcasting.hpp" @@ -798,37 +801,55 @@ namespace MWMechanics return; commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); } - - bool MechanicsManager::commitCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg) + + bool MechanicsManager::commitCrime(const MWWorld::Ptr& offender, const MWWorld::Ptr& victim, OffenseType type, int arg) { - if (ptr.getRefData().getHandle() != "player") + if (offender.getRefData().getHandle() != "player") return false; + MWWorld::Ptr ptr; + bool reported=false; - for (Actors::PtrControllerMap::const_iterator it = mActors.begin(); it != mActors.end(); ++it) + MWWorld::CellStore* cell = victim.getCell(); + + // TODO: implement and check the distance of actors to victim using fAlarmRadius + // get all NPCs in victims cell + for (MWWorld::CellRefList::List::iterator it (cell->get().mList.begin()); it != cell->get().mList.end(); ++it) { - if (it->first != ptr && - MWBase::Environment::get().getWorld()->getLOS(ptr, it->first) && - awarenessCheck(ptr, it->first)) + MWWorld::Ptr ptr (&*it, cell); + + // offender can't be ally to themselves + if (ptr == offender) + continue; + + CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); + + // curse at the thief + if (ptr == victim && type == OT_Theft) + MWBase::Environment::get().getDialogueManager()->say(victim, "Thief"); + + // TODO: Make guards persue unless other factors, such as bounty stops them + // If the actor is a guard + + // TODO: An actor reacts differently based on different values of AI_Alarm. + // Actor has witnessed a crime. Will he report it? + if (creatureStats.getAiSetting(CreatureStats::AI_Alarm).getModified() > 0) { - // NPCs will always curse you when they notice you steal their items, even if they don't report the crime - if (it->first == victim && type == OT_Theft) - { - MWBase::Environment::get().getDialogueManager()->say(victim, "Thief"); - } + creatureStats.setAlarmed(true); + reported=true; + } + else + continue; - // Actor has witnessed a crime. Will he report it? - // (not sure, is > 0 correct?) - if (it->first.getClass().getCreatureStats(it->first).getAiSetting(CreatureStats::AI_Alarm).getModified() > 0) - { - // TODO: stats.setAlarmed(true) on NPCs within earshot - // fAlarmRadius ? - reported=true; - break; - } + // TODO: An actor reacts differently based on different values of AI_Fight and AI_Flee. + // Actor has reported the crime, will the actor fight the offender? + if (creatureStats.getAiSetting(CreatureStats::AI_Fight).getModified > 0) + { + creatureStats.getAiSequence().stack(AiCombat(offender)); + creatureStats.setHostile(true); + creatureStats.getAiSequence().execute(ptr, 0); } } - if (reported) reportCrime(ptr, victim, type, arg); return reported; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 761caf586..3327cf8b8 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -111,7 +111,7 @@ namespace MWMechanics * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. * @return was the crime reported? */ - virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, + virtual bool commitCrime (const MWWorld::Ptr& offender, const MWWorld::Ptr& victim, OffenseType type, int arg=0); virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, int arg=0);