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 **/
|
/** 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> getActorsFighting(const MWWorld::Ptr& actor) = 0;
|
||||||
|
|
||||||
|
virtual std::list<MWWorld::Ptr> getEnemiesNearby(const MWWorld::Ptr& actor) = 0;
|
||||||
|
|
||||||
virtual void playerLoaded() = 0;
|
virtual void playerLoaded() = 0;
|
||||||
|
|
||||||
virtual int countSavedGameRecords() const = 0;
|
virtual int countSavedGameRecords() const = 0;
|
||||||
|
|
|
@ -957,7 +957,7 @@ namespace MWInput
|
||||||
if (!MWBase::Environment::get().getWindowManager()->getRestEnabled () || MWBase::Environment::get().getWindowManager()->isGuiMode ())
|
if (!MWBase::Environment::get().getWindowManager()->getRestEnabled () || MWBase::Environment::get().getWindowManager()->isGuiMode ())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(mPlayer->isInCombat()) {//Check if in combat
|
if(mPlayer->enemiesNearby()) {//Check if in combat
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}"); //Nope,
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}"); //Nope,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,9 @@ void getRestorationPerHourOfSleep (const MWWorld::Ptr& ptr, float& health, float
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const float aiProcessingDistance = 7168;
|
||||||
|
const float sqrAiProcessingDistance = aiProcessingDistance*aiProcessingDistance;
|
||||||
|
|
||||||
class SoulTrap : public MWMechanics::EffectSourceVisitor
|
class SoulTrap : public MWMechanics::EffectSourceVisitor
|
||||||
{
|
{
|
||||||
MWWorld::Ptr mCreature;
|
MWWorld::Ptr mCreature;
|
||||||
|
@ -291,7 +294,7 @@ namespace MWMechanics
|
||||||
const ESM::Position& actor1Pos = actor1.getRefData().getPosition();
|
const ESM::Position& actor1Pos = actor1.getRefData().getPosition();
|
||||||
const ESM::Position& actor2Pos = actor2.getRefData().getPosition();
|
const ESM::Position& actor2Pos = actor2.getRefData().getPosition();
|
||||||
float sqrDist = (actor1Pos.asVec3() - actor2Pos.asVec3()).length2();
|
float sqrDist = (actor1Pos.asVec3() - actor2Pos.asVec3()).length2();
|
||||||
if (sqrDist > 7168*7168)
|
if (sqrDist > sqrAiProcessingDistance)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// pure water creatures won't try to fight with the target on the ground
|
// 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
|
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
|
/// \todo move update logic to Actor class where appropriate
|
||||||
|
|
||||||
// AI and magic effects update
|
// AI and magic effects update
|
||||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
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()
|
bool inProcessingRange = (player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
|
||||||
<= sqrProcessingDistance;
|
<= sqrAiProcessingDistance;
|
||||||
|
|
||||||
iter->second->getCharacterController()->setActive(inProcessingRange);
|
iter->second->getCharacterController()->setActive(inProcessingRange);
|
||||||
|
|
||||||
|
@ -1064,7 +1065,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
if (iter->first != player &&
|
if (iter->first != player &&
|
||||||
(player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
|
(player.getRefData().getPosition().asVec3() - iter->first.getRefData().getPosition().asVec3()).length2()
|
||||||
> sqrProcessingDistance)
|
> sqrAiProcessingDistance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (iter->first.getClass().getCreatureStats(iter->first).isParalyzed())
|
if (iter->first.getClass().getCreatureStats(iter->first).isParalyzed())
|
||||||
|
@ -1391,23 +1392,41 @@ namespace MWMechanics
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::list<MWWorld::Ptr> Actors::getActorsFighting(const MWWorld::Ptr& actor) {
|
std::list<MWWorld::Ptr> Actors::getActorsFighting(const MWWorld::Ptr& actor) {
|
||||||
std::list<MWWorld::Ptr> list;
|
std::list<MWWorld::Ptr> list;
|
||||||
std::vector<MWWorld::Ptr> neighbors;
|
std::vector<MWWorld::Ptr> neighbors;
|
||||||
osg::Vec3f position (actor.getRefData().getPosition().asVec3());
|
osg::Vec3f position (actor.getRefData().getPosition().asVec3());
|
||||||
getObjectsInRange(position,
|
getObjectsInRange(position, aiProcessingDistance, neighbors);
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fAlarmRadius")->getFloat(),
|
|
||||||
neighbors); //only care about those within the alarm disance
|
|
||||||
for(std::vector<MWWorld::Ptr>::iterator iter(neighbors.begin());iter != neighbors.end();++iter)
|
for(std::vector<MWWorld::Ptr>::iterator iter(neighbors.begin());iter != neighbors.end();++iter)
|
||||||
{
|
{
|
||||||
const MWWorld::Class &cls = iter->getClass();
|
const MWWorld::Class &cls = iter->getClass();
|
||||||
CreatureStats &stats = cls.getCreatureStats(*iter);
|
const CreatureStats &stats = cls.getCreatureStats(*iter);
|
||||||
if (!stats.isDead() && stats.getAiSequence().isInCombat(actor))
|
if (!stats.isDead() && stats.getAiSequence().isInCombat(actor))
|
||||||
list.push_front(*iter);
|
list.push_front(*iter);
|
||||||
}
|
}
|
||||||
return list;
|
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
|
void Actors::write (ESM::ESMWriter& writer, Loading::Listener& listener) const
|
||||||
{
|
{
|
||||||
writer.startRecord(ESM::REC_DCOU);
|
writer.startRecord(ESM::REC_DCOU);
|
||||||
|
|
|
@ -123,6 +123,9 @@ namespace MWMechanics
|
||||||
/**ie AiCombat is active and the target is the actor **/
|
/**ie AiCombat is active and the target is the actor **/
|
||||||
std::list<MWWorld::Ptr> getActorsFighting(const MWWorld::Ptr& 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 write (ESM::ESMWriter& writer, Loading::Listener& listener) const;
|
||||||
|
|
||||||
void readRecord (ESM::ESMReader& reader, uint32_t type);
|
void readRecord (ESM::ESMReader& reader, uint32_t type);
|
||||||
|
|
|
@ -928,7 +928,7 @@ namespace MWMechanics
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MWMechanics::isPlayerInCombat()) {
|
if(MWBase::Environment::get().getWorld()->getPlayer().enemiesNearby()) {
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1507,6 +1507,10 @@ namespace MWMechanics
|
||||||
return mActors.getActorsFighting(actor);
|
return mActors.getActorsFighting(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::list<MWWorld::Ptr> MechanicsManager::getEnemiesNearby(const MWWorld::Ptr& actor) {
|
||||||
|
return mActors.getEnemiesNearby(actor);
|
||||||
|
}
|
||||||
|
|
||||||
int MechanicsManager::countSavedGameRecords() const
|
int MechanicsManager::countSavedGameRecords() const
|
||||||
{
|
{
|
||||||
return 1 // Death counter
|
return 1 // Death counter
|
||||||
|
|
|
@ -153,6 +153,7 @@ namespace MWMechanics
|
||||||
virtual std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
virtual std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
virtual std::list<MWWorld::Ptr> getActorsFighting(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 toggleAI();
|
||||||
virtual bool isAIActive();
|
virtual bool isAIActive();
|
||||||
|
|
|
@ -258,6 +258,11 @@ namespace MWWorld
|
||||||
return MWBase::Environment::get().getMechanicsManager()->getActorsFighting(getPlayer()).size() != 0;
|
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)
|
void Player::markPosition(CellStore *markedCell, ESM::Position markedPosition)
|
||||||
{
|
{
|
||||||
mMarkedCell = markedCell;
|
mMarkedCell = markedCell;
|
||||||
|
|
|
@ -109,6 +109,8 @@ namespace MWWorld
|
||||||
///Checks all nearby actors to see if anyone has an aipackage against you
|
///Checks all nearby actors to see if anyone has an aipackage against you
|
||||||
bool isInCombat();
|
bool isInCombat();
|
||||||
|
|
||||||
|
bool enemiesNearby();
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
void write (ESM::ESMWriter& writer, Loading::Listener& progress) const;
|
||||||
|
|
Loading…
Reference in a new issue