mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-11-04 06:56:41 +00:00 
			
		
		
		
	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
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										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,
 | 
			
		||||
                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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue