forked from mirror/openmw-tes3mp
Fix the enemy nearby check (Bug #3423)
This commit is contained in:
parent
dfc2f3469a
commit
f417d7780a
8 changed files with 51 additions and 15 deletions
|
@ -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…
Reference in a new issue