On Perception Event

Asset Information and Discussion for Scripting, Area Design, and More

Moderators: Moderator, Developer, DM

Dagesh
Posts: 891
Joined: Mon Jan 16, 2012 11:03 pm

On Perception Event

Unread post by Dagesh »

AI On Perception Event
Breakdown is like this:

If this script fires because someone disappeared in front of me while I'm fighting
-Fight the nearest enemy I can see
-Look around for the nearest enemy I can hear

If I'm not fighting
-I see an enemy!
--Tell allies I see someone and fight!
-I don't see an enemy but I hear one
--Buff with certain spells if I have them and move to the location I heard the enemy
(Note: NPC moves to location NOT to PC which prevents the following of NPCs)
Hidden: show

Code: Select all

//:://////////////////////////////////////////////////
//:: NW_C2_DEFAULT2
/*
  Default OnPerception event handler for NPCs.

  Handles behavior when perceiving a creature for the
  first time.
 */
//:://////////////////////////////////////////////////

const float REACTION_DISTANCE = 7.0;

#include "nw_i0_generic"
//#include "_inc_ai"

void main()
{

    // Created an AI system that can be switched
	// at the drop of a variable   
	//if( RunAIScript( EVENT_PERCEIVE ) == TRUE ){ return; }

    object oPercep = GetLastPerceived();
    if( !GetIsEnemy( oPercep ) )
    {//* NOTE: This will null functions for friendly NPCs
        return;
    }//* NOTE: This will null functions for friendly NPCs

    int bSeen = GetLastPerceptionSeen();
    int bHeard = GetLastPerceptionHeard();
    if (bHeard == FALSE)
    {
        // Has someone vanished in front of me?
        bHeard = GetLastPerceptionVanished();
    }

    if( GetIsInCombat(OBJECT_SELF) && 
		GetIsEnemy( oPercep ) )
    {// in combat

        if( GetLastPerceptionVanished() || 
			GetLastPerceptionInaudible() )
        {// someone disappeared!
            object oTarget = GetNearestCreature( CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN );
            if( GetIsObjectValid( oTarget ) )
            {// Found a new enemy and closest enemy is seen!!
                // Fight the new guy
				DetermineCombatRound( oTarget );
            }// Found a new enemy and closest enemy is seen!!
            else
            {// Closest enemy is not seen!!
                oTarget = GetNearestCreature( CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_HEARD );
                if( GetIsObjectValid( oTarget ) )
                {// Closest enemy is heard!!
                    ClearAllActions();
                    if( GetSkillRank( SKILL_SPOT ) > 5 )
                    {// Go into detection mode
                        ActionDoCommand( SetActionMode( OBJECT_SELF, ACTION_MODE_DETECT, TRUE ) );
                    }// Go into detection mode
                    if( GetArea( OBJECT_SELF ) == GetArea( oTarget ) )
                    {// If target is in my area
                        location lTarget = GetLocation( oTarget );
                        // Move to where I heard the target
						ActionMoveToLocation( lTarget, TRUE );
                    }// If target is in my area
                }// Closest enemy is heard!!
                else
                {// enemy is neither seen nor heard
                    ClearAllActions(1);
                    // I swear I heard or saw someone over there
					ActionMoveToLocation( GetLocation( oPercep ), TRUE );
                    //return;
                }// enemy is neither seen nor heard
            }// Closest enemy is not seen!!

        }// someone disappeared!

    }// in combat

    else if( GetIsEnemy( oPercep ) && bSeen )
    {// I see enemy and I am not fighting!!

        if( !GetHasEffect( EFFECT_TYPE_SLEEP ) )
        {// I am not asleep

            if( GetBehaviorState( NW_FLAG_BEHAVIOR_SPECIAL ) )
            {// I have special behavior
                DetermineSpecialBehavior();
            }// I have special behavior
            else
            {// I have no special behavior
                SetFacingPoint( GetPosition( oPercep ) );
				// Say something for allies to hear
                SpeakString( "NW_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK );
				// Attack the enemy I see
                DetermineCombatRound( oPercep );
            }// I have no special behavior

        }// I am not asleep

    }// I see enemy and I am not fighting!!
    else
    {// We are not fighting and enemy not seen
		if( bHeard && GetIsEnemy( oPercep ) )
		{// enemy is heard
			// * don't want creatures wandering too far after noises
			if ( GetDistanceToObject( oPercep ) <= REACTION_DISTANCE )
			{
				if( GetHasSpell( SPELL_TRUE_SEEING ) &&
				!GetHasSpellEffect( SPELL_TRUE_SEEING ) )
				{
					ActionCastSpellAtObject(SPELL_TRUE_SEEING, OBJECT_SELF);
				}
				if( GetHasSpell( SPELL_SEE_INVISIBILITY )  &&
				!GetHasSpellEffect( SPELL_SEE_INVISIBILITY ) )
				{
					ActionCastSpellAtObject(SPELL_SEE_INVISIBILITY, OBJECT_SELF);
				}
				if( GetHasSpell( SPELL_INVISIBILITY_PURGE ) &&
				GetHasSpellEffect( SPELL_INVISIBILITY, oPercep ) )
				{
					//ActionCastSpellAtLocation( SPELL_INVISIBILITY_PURGE, GetLocation( oPercep ) );
					ActionCastSpellAtObject(SPELL_INVISIBILITY_PURGE, OBJECT_SELF);
				}
				if( GetIsPC( oPercep ) || 
				GetIsObjectValid( GetMaster( oPercep ) ) )
				{// if perception is a PC or henchie
					ActionMoveToLocation( GetLocation( oPercep ), TRUE );
				}// if perception is a PC or henchie					
			}
		}
    }// We are not fighting and enemy not seen

    // Send the user-defined event if appropriate
    if( GetSpawnInCondition( NW_FLAG_PERCIEVE_EVENT ) && 
		GetLastPerceptionSeen() )
    {
        SignalEvent( OBJECT_SELF, EventUserDefined( EVENT_PERCEIVE ) );
    }
}
ουκ εστιν ωδε, ηγερθη γαρ καθως ειπεν



PCs:
Rorick Runegraph (Check out Rorick's Rune of Light)
Ckalthea Chenfur
Aeric
Squire Brevin of Lathander

Return to “NWN2 Toolset Development”