Fix the enemy nearby check (Bug #3423)

pull/1/head
scrawl 9 years ago
parent dfc2f3469a
commit f417d7780a

@ -193,6 +193,8 @@ namespace MWBase
/** ie AiCombat is active and the target is the actor **/
virtual std::list<MWWorld::Ptr> getActorsFighting(const MWWorld::Ptr& actor) = 0;
virtual std::list<MWWorld::Ptr> getEnemiesNearby(const MWWorld::Ptr& actor) = 0;
virtual void playerLoaded() = 0;
virtual int countSavedGameRecords() const = 0;

@ -957,7 +957,7 @@ namespace MWInput
if (!MWBase::Environment::get().getWindowManager()->getRestEnabled () || MWBase::Environment::get().getWindowManager()->isGuiMode ())
return;
if(mPlayer->isInCombat()) {//Check if in combat
if(mPlayer->enemiesNearby()) {//Check if in combat
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}"); //Nope,
return;
}

@ -145,6 +145,9 @@ void getRestorationPerHourOfSleep (const MWWorld::Ptr& ptr, float& health, float
namespace MWMechanics
{
const float aiProcessingDistance = 7168;
const float sqrAiProcessingDistance = aiProcessingDistance*aiProcessingDistance;
class SoulTrap : public MWMechanics::EffectSourceVisitor
{
MWWorld::Ptr mCreature;
@ -291,7 +294,7 @@ namespace MWMechanics
const ESM::Position& actor1Pos = actor1.getRefData().getPosition();
const ESM::Position& actor2Pos = actor2.getRefData().getPosition();
float sqrDist = (actor1Pos.asVec3() - actor2Pos.asVec3()).length2();
if (sqrDist > 7168*7168)
if (sqrDist > sqrAiProcessingDistance)
return;
// pure water creatures won't try to fight with the target on the ground
@ -974,19 +977,17 @@ namespace MWMechanics
int hostilesCount = 0; // need to know this to play Battle music
// AI processing is only done within distance of 7168 units to the player. Note the "AI distance" slider doesn't affect this
// (it only does some throttling for targets beyond the "AI distance", so doesn't give any guarantees as to whether AI will be enabled or not)
// This distance could be made configurable later, but the setting must be marked with a big warning:
// using higher values will make a quest in Bloodmoon harder or impossible to complete (bug #1876)
const float sqrProcessingDistance = 7168*7168;
/// \todo move update logic to Actor class where appropriate
// AI and magic effects update
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
{
// AI processing is only done within distance of 7168 units to the player. Note the "AI distance" slider doesn't affect this
// (it only does some throttling for targets beyond the "AI distance", so doesn't give any guarantees as to whether AI will be enabled or not)
// This distance could be made configurable later, but the setting must be marked with a big warning:
// using higher values will make a quest in Bloodmoon harder or impossible to complete (bug #1876)
bool inProcessingRange = (player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
<= sqrProcessingDistance;
<= sqrAiProcessingDistance;
iter->second->getCharacterController()->setActive(inProcessingRange);
@ -1064,7 +1065,7 @@ namespace MWMechanics
{
if (iter->first != player &&
(player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
> sqrProcessingDistance)
> sqrAiProcessingDistance)
continue;
if (iter->first.getClass().getCreatureStats(iter->first).isParalyzed())
@ -1391,23 +1392,41 @@ namespace MWMechanics
return list;
}
std::list<MWWorld::Ptr> Actors::getActorsFighting(const MWWorld::Ptr& actor) {
std::list<MWWorld::Ptr> list;
std::vector<MWWorld::Ptr> neighbors;
osg::Vec3f position (actor.getRefData().getPosition().asVec3());
getObjectsInRange(position,
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fAlarmRadius")->getFloat(),
neighbors); //only care about those within the alarm disance
getObjectsInRange(position, aiProcessingDistance, neighbors);
for(std::vector<MWWorld::Ptr>::iterator iter(neighbors.begin());iter != neighbors.end();++iter)
{
const MWWorld::Class &cls = iter->getClass();
CreatureStats &stats = cls.getCreatureStats(*iter);
const CreatureStats &stats = cls.getCreatureStats(*iter);
if (!stats.isDead() && stats.getAiSequence().isInCombat(actor))
list.push_front(*iter);
}
return list;
}
std::list<MWWorld::Ptr> Actors::getEnemiesNearby(const MWWorld::Ptr& actor)
{
std::list<MWWorld::Ptr> list;
std::vector<MWWorld::Ptr> neighbors;
osg::Vec3f position (actor.getRefData().getPosition().asVec3());
getObjectsInRange(position, aiProcessingDistance, neighbors);
for(std::vector<MWWorld::Ptr>::iterator iter(neighbors.begin());iter != neighbors.end();++iter)
{
const CreatureStats &stats = iter->getClass().getCreatureStats(*iter);
if (stats.isDead())
continue;
if (stats.getAiSequence().isInCombat(actor) || MWBase::Environment::get().getMechanicsManager()->isAggressive(*iter, actor))
list.push_back(*iter);
}
return list;
}
void Actors::write (ESM::ESMWriter& writer, Loading::Listener& listener) const
{
writer.startRecord(ESM::REC_DCOU);

@ -123,6 +123,9 @@ namespace MWMechanics
/**ie AiCombat is active and the target is the actor **/
std::list<MWWorld::Ptr> getActorsFighting(const MWWorld::Ptr& actor);
/// Unlike getActorsFighting, also returns actors that *would* fight the given actor if they saw him.
std::list<MWWorld::Ptr> getEnemiesNearby(const MWWorld::Ptr& actor);
void write (ESM::ESMWriter& writer, Loading::Listener& listener) const;
void readRecord (ESM::ESMReader& reader, uint32_t type);

@ -928,7 +928,7 @@ namespace MWMechanics
return true;
}
if(MWMechanics::isPlayerInCombat()) {
if(MWBase::Environment::get().getWorld()->getPlayer().enemiesNearby()) {
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}");
return true;
}
@ -1507,6 +1507,10 @@ namespace MWMechanics
return mActors.getActorsFighting(actor);
}
std::list<MWWorld::Ptr> MechanicsManager::getEnemiesNearby(const MWWorld::Ptr& actor) {
return mActors.getEnemiesNearby(actor);
}
int MechanicsManager::countSavedGameRecords() const
{
return 1 // Death counter

@ -153,6 +153,7 @@ namespace MWMechanics
virtual std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
virtual std::list<MWWorld::Ptr> getActorsFighting(const MWWorld::Ptr& actor);
virtual std::list<MWWorld::Ptr> getEnemiesNearby(const MWWorld::Ptr& actor);
virtual bool toggleAI();
virtual bool isAIActive();

@ -258,6 +258,11 @@ namespace MWWorld
return MWBase::Environment::get().getMechanicsManager()->getActorsFighting(getPlayer()).size() != 0;
}
bool Player::enemiesNearby()
{
return MWBase::Environment::get().getMechanicsManager()->getEnemiesNearby(getPlayer()).size() != 0;
}
void Player::markPosition(CellStore *markedCell, ESM::Position markedPosition)
{
mMarkedCell = markedCell;

@ -109,6 +109,8 @@ namespace MWWorld
///Checks all nearby actors to see if anyone has an aipackage against you
bool isInCombat();
bool enemiesNearby();
void clear();
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;

Loading…
Cancel
Save