Skip to content

Commit

Permalink
Added AiBreathe package (feature #1374)
Browse files Browse the repository at this point in the history
  • Loading branch information
akortunov committed Jul 25, 2017
1 parent 12871dd commit 548814b
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 4 deletions.
2 changes: 1 addition & 1 deletion apps/openmw/CMakeLists.txt
Expand Up @@ -81,7 +81,7 @@ add_openmw_dir (mwclass

add_openmw_dir (mwmechanics
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
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning
character actors objects aistate coordinateconverter trading aiface
Expand Down
11 changes: 11 additions & 0 deletions apps/openmw/mwmechanics/actors.cpp
Expand Up @@ -25,6 +25,8 @@
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/statemanager.hpp"

#include "../mwmechanics/aibreathe.hpp"

#include "spellcasting.hpp"
#include "npcstats.hpp"
#include "creaturestats.hpp"
Expand Down Expand Up @@ -814,6 +816,15 @@ namespace MWMechanics
if (stats.getTimeToStartDrowning() == -1.f)
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();
bool knockedOutUnderwater = (ctrl->isKnockedOut() && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3())));
if((world->isSubmerged(ptr) || knockedOutUnderwater)
Expand Down
54 changes: 54 additions & 0 deletions apps/openmw/mwmechanics/aibreathe.cpp
@@ -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 changes: 28 additions & 0 deletions apps/openmw/mwmechanics/aibreathe.hpp
@@ -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

5 changes: 3 additions & 2 deletions apps/openmw/mwmechanics/aipackage.hpp
Expand Up @@ -41,12 +41,13 @@ namespace MWMechanics
TypeIdFollow = 3,
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..
TypeIdCombat = 5,
TypeIdPursue = 6,
TypeIdAvoidDoor = 7,
TypeIdFace = 8
TypeIdFace = 8,
TypeIdBreathe = 9
};

///Default constructor
Expand Down
3 changes: 2 additions & 1 deletion apps/openmw/mwmechanics/aisequence.cpp
Expand Up @@ -182,7 +182,8 @@ bool isActualAiPackage(int packageTypeId)
return (packageTypeId != AiPackage::TypeIdCombat
&& packageTypeId != AiPackage::TypeIdPursue
&& 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)
Expand Down

0 comments on commit 548814b

Please sign in to comment.