forked from teamnwah/openmw-tes3coop
Added AiBreathe package (feature #1374)
This commit is contained in:
parent
12871dd8da
commit
548814bfbc
6 changed files with 99 additions and 4 deletions
|
@ -81,7 +81,7 @@ add_openmw_dir (mwclass
|
||||||
|
|
||||||
add_openmw_dir (mwmechanics
|
add_openmw_dir (mwmechanics
|
||||||
mechanicsmanagerimp stat creaturestats magiceffects movement actorutil
|
mechanicsmanagerimp stat creaturestats magiceffects movement actorutil
|
||||||
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor
|
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor aibreathe
|
||||||
aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting
|
aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting
|
||||||
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning
|
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning
|
||||||
character actors objects aistate coordinateconverter trading aiface
|
character actors objects aistate coordinateconverter trading aiface
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
#include "../mwbase/statemanager.hpp"
|
#include "../mwbase/statemanager.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/aibreathe.hpp"
|
||||||
|
|
||||||
#include "spellcasting.hpp"
|
#include "spellcasting.hpp"
|
||||||
#include "npcstats.hpp"
|
#include "npcstats.hpp"
|
||||||
#include "creaturestats.hpp"
|
#include "creaturestats.hpp"
|
||||||
|
@ -814,6 +816,15 @@ namespace MWMechanics
|
||||||
if (stats.getTimeToStartDrowning() == -1.f)
|
if (stats.getTimeToStartDrowning() == -1.f)
|
||||||
stats.setTimeToStartDrowning(fHoldBreathTime);
|
stats.setTimeToStartDrowning(fHoldBreathTime);
|
||||||
|
|
||||||
|
if (ptr.getClass().isNpc() && stats.getTimeToStartDrowning() < fHoldBreathTime / 2)
|
||||||
|
{
|
||||||
|
if(ptr != MWMechanics::getPlayer() ) {
|
||||||
|
MWMechanics::AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
||||||
|
if(seq.getTypeId() != MWMechanics::AiPackage::TypeIdBreathe) //Only add it once
|
||||||
|
seq.stack(MWMechanics::AiBreathe(), ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
bool knockedOutUnderwater = (ctrl->isKnockedOut() && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3())));
|
bool knockedOutUnderwater = (ctrl->isKnockedOut() && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3())));
|
||||||
if((world->isSubmerged(ptr) || knockedOutUnderwater)
|
if((world->isSubmerged(ptr) || knockedOutUnderwater)
|
||||||
|
|
54
apps/openmw/mwmechanics/aibreathe.cpp
Normal file
54
apps/openmw/mwmechanics/aibreathe.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include "aibreathe.hpp"
|
||||||
|
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
|
#include "npcstats.hpp"
|
||||||
|
|
||||||
|
#include "movement.hpp"
|
||||||
|
#include "steering.hpp"
|
||||||
|
|
||||||
|
MWMechanics::AiBreathe::AiBreathe()
|
||||||
|
: AiPackage()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MWMechanics::AiBreathe::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
|
||||||
|
{
|
||||||
|
static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fHoldBreathTime")->getFloat();
|
||||||
|
|
||||||
|
const MWWorld::Class& actorClass = actor.getClass();
|
||||||
|
if (actorClass.isNpc())
|
||||||
|
{
|
||||||
|
if (actorClass.getNpcStats(actor).getTimeToStartDrowning() < fHoldBreathTime / 2)
|
||||||
|
{
|
||||||
|
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);
|
||||||
|
|
||||||
|
actor.getClass().getMovementSettings(actor).mPosition[1] = 1;
|
||||||
|
smoothTurn(actor, -180, 0);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MWMechanics::AiBreathe *MWMechanics::AiBreathe::clone() const
|
||||||
|
{
|
||||||
|
return new AiBreathe(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
int MWMechanics::AiBreathe::getTypeId() const
|
||||||
|
{
|
||||||
|
return TypeIdBreathe;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int MWMechanics::AiBreathe::getPriority() const
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
28
apps/openmw/mwmechanics/aibreathe.hpp
Normal file
28
apps/openmw/mwmechanics/aibreathe.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef GAME_MWMECHANICS_AIBREATHE_H
|
||||||
|
#define GAME_MWMECHANICS_AIBREATHE_H
|
||||||
|
|
||||||
|
#include "aipackage.hpp"
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
/// \brief AiPackage to have an actor resurface to breathe
|
||||||
|
// The AI will go up if lesser than half breath left
|
||||||
|
class AiBreathe : public AiPackage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AiBreathe();
|
||||||
|
|
||||||
|
virtual AiBreathe *clone() const;
|
||||||
|
|
||||||
|
virtual bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration);
|
||||||
|
|
||||||
|
virtual int getTypeId() const;
|
||||||
|
|
||||||
|
virtual unsigned int getPriority() const;
|
||||||
|
|
||||||
|
virtual bool canCancel() const { return false; }
|
||||||
|
virtual bool shouldCancelPreviousAi() const { return false; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -41,12 +41,13 @@ namespace MWMechanics
|
||||||
TypeIdFollow = 3,
|
TypeIdFollow = 3,
|
||||||
TypeIdActivate = 4,
|
TypeIdActivate = 4,
|
||||||
|
|
||||||
// These 4 are not really handled as Ai Packages in the MW engine
|
// These 5 are not really handled as Ai Packages in the MW engine
|
||||||
// For compatibility do *not* return these in the getCurrentAiPackage script function..
|
// For compatibility do *not* return these in the getCurrentAiPackage script function..
|
||||||
TypeIdCombat = 5,
|
TypeIdCombat = 5,
|
||||||
TypeIdPursue = 6,
|
TypeIdPursue = 6,
|
||||||
TypeIdAvoidDoor = 7,
|
TypeIdAvoidDoor = 7,
|
||||||
TypeIdFace = 8
|
TypeIdFace = 8,
|
||||||
|
TypeIdBreathe = 9
|
||||||
};
|
};
|
||||||
|
|
||||||
///Default constructor
|
///Default constructor
|
||||||
|
|
|
@ -182,7 +182,8 @@ bool isActualAiPackage(int packageTypeId)
|
||||||
return (packageTypeId != AiPackage::TypeIdCombat
|
return (packageTypeId != AiPackage::TypeIdCombat
|
||||||
&& packageTypeId != AiPackage::TypeIdPursue
|
&& packageTypeId != AiPackage::TypeIdPursue
|
||||||
&& packageTypeId != AiPackage::TypeIdAvoidDoor
|
&& packageTypeId != AiPackage::TypeIdAvoidDoor
|
||||||
&& packageTypeId != AiPackage::TypeIdFace);
|
&& packageTypeId != AiPackage::TypeIdFace
|
||||||
|
&& packageTypeId != AiPackage::TypeIdBreathe);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
|
void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration)
|
||||||
|
|
Loading…
Reference in a new issue