mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 04:26:42 +00:00 
			
		
		
		
	#58 - Sneak Skill: functional sneaking
Removed sneak checking from individual actor update. Added sneak checking to Actors::update()
This commit is contained in:
		
							parent
							
								
									a65e8393bb
								
							
						
					
					
						commit
						7d5dab214c
					
				
					 3 changed files with 37 additions and 36 deletions
				
			
		| 
						 | 
					@ -226,7 +226,6 @@ namespace MWMechanics
 | 
				
			||||||
            updateDrowning(ptr, duration);
 | 
					            updateDrowning(ptr, duration);
 | 
				
			||||||
            calculateNpcStatModifiers(ptr);
 | 
					            calculateNpcStatModifiers(ptr);
 | 
				
			||||||
            updateEquippedLight(ptr, duration);
 | 
					            updateEquippedLight(ptr, duration);
 | 
				
			||||||
            updateSneak(ptr);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -711,27 +710,6 @@ namespace MWMechanics
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Actors::updateSneak (const MWWorld::Ptr& ptr)
 | 
					 | 
				
			||||||
    {  
 | 
					 | 
				
			||||||
        const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
 | 
					 | 
				
			||||||
        if (   player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak)
 | 
					 | 
				
			||||||
            && ptr != player) 
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
 | 
					 | 
				
			||||||
            int radius = esmStore.get<ESM::GameSetting>().find("fSneakUseDist")->getInt();
 | 
					 | 
				
			||||||
            bool seen = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // am I close enough and can I see the player?
 | 
					 | 
				
			||||||
            if (   (Ogre::Vector3(ptr.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(player.getRefData().getPosition().pos)) <= radius*radius)
 | 
					 | 
				
			||||||
                && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr)
 | 
					 | 
				
			||||||
                && MWBase::Environment::get().getWorld()->getLOS(player, ptr))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    seen = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            MWBase::Environment::get().getWindowManager()->setSneakVisibility(seen);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Actors::updateCrimePersuit(const MWWorld::Ptr& ptr, float duration)
 | 
					    void Actors::updateCrimePersuit(const MWWorld::Ptr& ptr, float duration)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
 | 
					        MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
 | 
				
			||||||
| 
						 | 
					@ -872,12 +850,12 @@ namespace MWMechanics
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // AI and magic effects update
 | 
					            // AI and magic effects update
 | 
				
			||||||
            for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
 | 
					            for (PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (!iter->first.getClass().getCreatureStats(iter->first).isDead())
 | 
					                if (!iter->first.getClass().getCreatureStats(iter->first).isDead())
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    updateActor(iter->first, duration);
 | 
					                    updateActor(iter->first, duration);
 | 
				
			||||||
                    if(iter->first.getTypeName() == typeid(ESM::NPC).name())
 | 
					                    if (iter->first.getTypeName() == typeid(ESM::NPC).name())
 | 
				
			||||||
                        updateNpc(iter->first, duration, paused);
 | 
					                        updateNpc(iter->first, duration, paused);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -887,11 +865,11 @@ namespace MWMechanics
 | 
				
			||||||
            // Reaching the text keys may trigger Hit / Spellcast (and as such, particles),
 | 
					            // Reaching the text keys may trigger Hit / Spellcast (and as such, particles),
 | 
				
			||||||
            // so updating VFX immediately after that would just remove the particle effects instantly.
 | 
					            // so updating VFX immediately after that would just remove the particle effects instantly.
 | 
				
			||||||
            // There needs to be a magic effect update in between.
 | 
					            // There needs to be a magic effect update in between.
 | 
				
			||||||
            for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
 | 
					            for (PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
 | 
				
			||||||
                iter->second->updateContinuousVfx();
 | 
					                iter->second->updateContinuousVfx();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Animation/movement update
 | 
					            // Animation/movement update
 | 
				
			||||||
            for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
 | 
					            for (PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (iter->first.getClass().getCreatureStats(iter->first).getMagicEffects().get(
 | 
					                if (iter->first.getClass().getCreatureStats(iter->first).getMagicEffects().get(
 | 
				
			||||||
                            ESM::MagicEffect::Paralyze).mMagnitude > 0)
 | 
					                            ESM::MagicEffect::Paralyze).mMagnitude > 0)
 | 
				
			||||||
| 
						 | 
					@ -900,7 +878,7 @@ namespace MWMechanics
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Kill dead actors, update some variables
 | 
					            // Kill dead actors, update some variables
 | 
				
			||||||
            for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();iter++)
 | 
					            for (PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();iter++)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                const MWWorld::Class &cls = MWWorld::Class::get(iter->first);
 | 
					                const MWWorld::Class &cls = MWWorld::Class::get(iter->first);
 | 
				
			||||||
                CreatureStats &stats = cls.getCreatureStats(iter->first);
 | 
					                CreatureStats &stats = cls.getCreatureStats(iter->first);
 | 
				
			||||||
| 
						 | 
					@ -908,7 +886,7 @@ namespace MWMechanics
 | 
				
			||||||
                //KnockedOutOneFrameLogic
 | 
					                //KnockedOutOneFrameLogic
 | 
				
			||||||
                //Used for "OnKnockedOut" command
 | 
					                //Used for "OnKnockedOut" command
 | 
				
			||||||
                //Put here to ensure that it's run for PRECISELY one frame.
 | 
					                //Put here to ensure that it's run for PRECISELY one frame.
 | 
				
			||||||
                if(stats.getKnockedDown() && !stats.getKnockedDownOneFrame() && !stats.getKnockedDownOverOneFrame()) { //Start it for one frame if nessesary
 | 
					                if (stats.getKnockedDown() && !stats.getKnockedDownOneFrame() && !stats.getKnockedDownOverOneFrame()) { //Start it for one frame if nessesary
 | 
				
			||||||
                    stats.setKnockedDownOneFrame(true);
 | 
					                    stats.setKnockedDownOneFrame(true);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (stats.getKnockedDownOneFrame() && !stats.getKnockedDownOverOneFrame()) { //Turn off KnockedOutOneframe
 | 
					                else if (stats.getKnockedDownOneFrame() && !stats.getKnockedDownOverOneFrame()) { //Turn off KnockedOutOneframe
 | 
				
			||||||
| 
						 | 
					@ -926,7 +904,7 @@ namespace MWMechanics
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // If it's the player and God Mode is turned on, keep it alive
 | 
					                // If it's the player and God Mode is turned on, keep it alive
 | 
				
			||||||
                if(iter->first.getRefData().getHandle()=="player" &&
 | 
					                if (iter->first.getRefData().getHandle()=="player" &&
 | 
				
			||||||
                    MWBase::Environment::get().getWorld()->getGodModeState())
 | 
					                    MWBase::Environment::get().getWorld()->getGodModeState())
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    MWMechanics::DynamicStat<float> stat (stats.getHealth());
 | 
					                    MWMechanics::DynamicStat<float> stat (stats.getHealth());
 | 
				
			||||||
| 
						 | 
					@ -942,7 +920,7 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Make sure spell effects with CasterLinked flag are removed
 | 
					                // Make sure spell effects with CasterLinked flag are removed
 | 
				
			||||||
                // TODO: would be nice not to do this all the time...
 | 
					                // TODO: would be nice not to do this all the time...
 | 
				
			||||||
                for(PtrControllerMap::iterator iter2(mActors.begin());iter2 != mActors.end();++iter2)
 | 
					                for (PtrControllerMap::iterator iter2(mActors.begin());iter2 != mActors.end();++iter2)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    MWMechanics::ActiveSpells& spells = iter2->first.getClass().getCreatureStats(iter2->first).getActiveSpells();
 | 
					                    MWMechanics::ActiveSpells& spells = iter2->first.getClass().getCreatureStats(iter2->first).getActiveSpells();
 | 
				
			||||||
                    spells.purge(iter->first.getRefData().getHandle());
 | 
					                    spells.purge(iter->first.getRefData().getHandle());
 | 
				
			||||||
| 
						 | 
					@ -967,10 +945,38 @@ namespace MWMechanics
 | 
				
			||||||
                    stats.setMagicEffects(MWMechanics::MagicEffects());
 | 
					                    stats.setMagicEffects(MWMechanics::MagicEffects());
 | 
				
			||||||
                    calculateCreatureStatModifiers(iter->first, 0);
 | 
					                    calculateCreatureStatModifiers(iter->first, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if(cls.isEssential(iter->first))
 | 
					                    if (cls.isEssential(iter->first))
 | 
				
			||||||
                        MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}");
 | 
					                        MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // if player is in sneak state see if anyone detects him
 | 
				
			||||||
 | 
					            const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
 | 
				
			||||||
 | 
					            if (player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
 | 
				
			||||||
 | 
					                const int radius = esmStore.get<ESM::GameSetting>().find("fSneakUseDist")->getInt();
 | 
				
			||||||
 | 
					                bool detected = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for (PtrControllerMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (iter->first == player)  // not the player
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // is the player in range and can they be detected
 | 
				
			||||||
 | 
					                    if (   (Ogre::Vector3(iter->first.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(player.getRefData().getPosition().pos)) <= radius*radius)
 | 
				
			||||||
 | 
					                        && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, iter->first)
 | 
				
			||||||
 | 
					                        && MWBase::Environment::get().getWorld()->getLOS(player, iter->first))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        detected = true;
 | 
				
			||||||
 | 
					                        MWBase::Environment::get().getWindowManager()->setSneakVisibility(false);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (!detected)
 | 
				
			||||||
 | 
					                    MWBase::Environment::get().getWindowManager()->setSneakVisibility(true);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    void Actors::restoreDynamicStats(bool sleep)
 | 
					    void Actors::restoreDynamicStats(bool sleep)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,8 +44,6 @@ namespace MWMechanics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration);
 | 
					            void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void updateSneak (const MWWorld::Ptr& ptr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public:
 | 
					        public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Actors();
 | 
					            Actors();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,9 +131,6 @@ namespace MWWorld
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MWWorld::Ptr ptr = getPlayer();
 | 
					        MWWorld::Ptr ptr = getPlayer();
 | 
				
			||||||
        ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak);
 | 
					        ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!sneak)
 | 
					 | 
				
			||||||
            MWBase::Environment::get().getWindowManager()->setSneakVisibility(false);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Player::yaw(float yaw)
 | 
					    void Player::yaw(float yaw)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue