lfnetwork.com mark read register faq members calendar

Thread: Henchmen scripts for the sake of...Henchmen Scripts
Thread Tools Display Modes
Post a new thread. Add a reply to this thread. Indicate all threads in this forum as read. Subscribe to this forum. RSS feed: this forum RSS feed: all forums
Old 09-21-2005, 03:42 PM   #1
Dak Vesser
Rookie
 
Dak Vesser's Avatar
 
Join Date: Sep 2004
Location: Taspir 3
Posts: 170
AI Script Templates for your creature mods

These are some really good AI templates that you can use for your mods.
I'll post new AI templates at the top of this thread.


************************************************** **************************
NewTemplate posted 10/01/05
Adding timestamps in your henchmen's debug messages

This is just a simple userdefined script I created that causes the henchmen to post a timestamped message everytime it spots a friend.

Code:
#include "k_inc_debug"

/*
In order to use this script the right way, you'll need to: 
1. Go into "k_hen_spawn01" and uncomment GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_PERCEPTION);
and then re-save & compile it as a new script for your creature's "OnSpawn"
2. Then attach this script, compile it and drop it in your creature's "OnUserDefined"
*/

void main()
{
    int nUser = GetUserDefinedEventNumber();

    if(nUser == 1002) 
    {
     object oPc = GetNearestCreature(CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, 
                     OBJECT_SELF, 1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND);

     {
 
      //*********************************** Creating the Clock **************************************       
 
      /*
      From here let's create a clock so we can have timestamps in our debug messages. This 
      formula will give us a military format: "0h:00m" to "23h:59m" It's important to know that 
      SWKotOR/SWkoTORII time is allot faster than Real Time. This is because the developers 
      configured the "Minutes/Hours" setting to 2 in the every Module. That means it only 
      takes two Real Time minutes to reach one kotOR hour. So we'll use this formula to 
      convert the 2 RT minutes into 60 KotOR minutes which will still be at the speed of 
      2 minutes but at least you'll see a 0-59 ratio. We could call it "RST" Republic
      Standard Time.

      This is my modified version of Skanzo Sylan's "Time Display" script for Neverwinter 
      Nights, that I fit to work in a SWKotOR Henchmen script.       
      */

      string sTime;
      string sMinute;
                       
      int nMinByHour = FloatToInt(HoursToSeconds(1)) / 60;
      int nHour = GetTimeHour();
      int nMinute = (60 / nMinByHour) * GetTimeMinute();
      int nSecond = GetTimeSecond();

      nMinute = nMinute + nSecond / nMinByHour;

      if(nMinute <= 9)
      sMinute = "0" + IntToString(nMinute);
      if(nMinute >= 10)
      sMinute = IntToString(nMinute);

      sTime = "SWTime: " + IntToString(nHour) + "h:" + sMinute + "m ";
      

      //******************************** Time Stamping the Message **********************************

      // When our henchmen spots a friend or anyone in the same faction, it'll post
      // a simple "hello" message on the feedback screen with a timestamp.
      
      if(GetLastPerceptionSeen())
      {
        if(GetIsFriend(GetLastPerceived()))
        {
          ActionDoCommand(SetFacingPoint(GetPosition(oPc));
          ActionPlayAnimation(ANIMATION_FIREFORGET_GREETING);
          SendMessageToPC(GetFirstPC(), sTime +"Debug Message: " 
           +GetName(OBJECT_SELF)+ " just said hello to "+GetName(oPc)+".");
        }
      }
     }       
    }
}



************************************************** **********************
"The Fake Party Member" This is a custom heartbeat script I created for non party creatures that will follow you around within a module.



Code:
// k_fpm_heartbtxx

#include "k_inc_debug"
#include "k_inc_generic"
#include "k_inc_switch"
#include "k_inc_utility"



void main()
{



            object oEnemy = GetNearestCreature(CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, OBJECT_SELF, 1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
            if(!GN_GetSpawnInCondition(SW_FLAG_AI_OFF) && !GetSoloMode())
            {
                if(GetPartyMemberByIndex(0) != OBJECT_SELF)
                {
                    if(//GetCurrentAction(OBJECT_SELF) != ACTION_FOLLOW && 
                       GetCurrentAction(OBJECT_SELF) != ACTION_WAIT  &&
                       !GetIsConversationActive() &&
                       !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE) &&
                       GetCommandable())
                    {
                       
                          if(!GN_GetIsFighting(OBJECT_SELF) && !GetIsObjectValid(oEnemy))
                           
                          
                            ClearAllActions();
                            if(GetDistanceBetween(OBJECT_SELF, GetPartyMemberByIndex(0)) < 5.0)
                            {
                             ClearAllActions();
                             ActionForceMoveToObject(GetPartyMemberByIndex(0), FALSE, 1.0);
                             //SendMessageToPC(GetFirstPC(), "Debug Message: Henchmen just executed the bWalk routine.");
                            }
                            if(GetDistanceBetween(OBJECT_SELF, GetPartyMemberByIndex(0)) > 5.0)
                            {
                             ClearAllActions();
                             ActionForceMoveToObject(GetPartyMemberByIndex(0), TRUE, 3.5);
                             //SendMessageToPC(GetFirstPC(), "Debug Message: Henchmen just executed the bRun routine.");
                            }
                          
                     }
                }
            }
            else if(GetSoloMode() && GetCurrentAction(OBJECT_SELF) == ACTION_FOLLOWLEADER)
            {
                ClearAllActions();
            }
            if(GN_GetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT))
            {
                SignalEvent(OBJECT_SELF, EventUserDefined(1001));
            }
        
   
   
}


This next one I created is an On Blocked Script. Added "Picked Lock Routine" for the Holo Droid just in case a locked door gets in its Pathway, it can unlock or attempt to unlock and open it. That way, the player won't have to Deactivate/reactivate the droid to get it back to within float range.

The reason for this is because when I added the “PC Location Jump” options in the planetary Debug section of the "g_cheatbot01" dialogue, I needed to make sure the Holo Droid could follow and or catch up.

Code:
#include "k_inc_debug"
#include "k_inc_generic"
#include "k_inc_switch"
#include "k_inc_utility"

void main()
{
    object oDoor = GetBlockingDoor();
    if(!GN_GetSpawnInCondition(SW_FLAG_AI_OFF))
    {
        if(GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE) >= 5)
        {
            if(GetIsDoorActionPossible(oDoor, DOOR_ACTION_OPEN) && 
               GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE) >= 7 )
            {
                DoDoorAction(oDoor, DOOR_ACTION_OPEN);
                SendMessageToPC(GetFirstPC(), "Debug Message: Henchmen just executed the -door open- routine...");
            }
            if(GetLocked(oDoor))
            {
                DoDoorAction(oDoor, DOOR_ACTION_UNLOCK);
                SendMessageToPC(GetFirstPC(), "Debug Message: Henchmen just executed the -picked lock- routine...");
            }
            else if(GetIsDoorActionPossible(oDoor, DOOR_ACTION_BASH))
            {
                DoDoorAction(oDoor, DOOR_ACTION_BASH);
                SendMessageToPC(GetFirstPC(), "Debug Message: Henchmen just executed the -door bash- routine...");
            }
        }
    }
    if(GN_GetSpawnInCondition(SW_FLAG_EVENT_ON_BLOCKED))
    {
        SignalEvent(OBJECT_SELF, EventUserDefined(1009));
    }
}
This is a good script if you wanna create a creature with a custom pathway through a locked door..

================================================== =====================================


Here’s a really cool Heartbeat script, I just created. I call it “The Shape Shifter”.

Basically it makes the Henchmen do a random appearance change using the RollDice method equaling to d10(1). I also added a fire effect for every time it changes. I created two versions, one for the “Fake Party Member”, and the other, for the “Real Party Member”. This first Script switches from 10 different droids, and the second script switches from 10 different organics. But of course you can change'em to what ever you want..

For the “Fake Party Member” or the creature that’s going to follow the one in lead;


Code:
#include "k_inc_debug"
#include "k_inc_generic"
#include "k_inc_switch"
#include "k_inc_utility"


int iRollDice = d10(1); //From 1-10, what number will the dice land on? Well, It's up to the game engine now.
void main()
{
     
    

            effect eBlind = EffectVisualEffect(VFX_PRO_DRAIN);

            object oEnemy = GetNearestCreature(CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, OBJECT_SELF, 1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
            if(!GN_GetSpawnInCondition(SW_FLAG_AI_OFF) && !GetSoloMode())

            {
                if(GetPartyMemberByIndex(0) != OBJECT_SELF)
                {
                    if(//GetCurrentAction(OBJECT_SELF) != ACTION_FOLLOW && 
                       GetCurrentAction(OBJECT_SELF) != ACTION_WAIT  &&
                       !GetIsConversationActive() &&
                       !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE) &&
                       GetCommandable())
                    {
                       
                          if(!GN_GetIsFighting(OBJECT_SELF) && !GetIsObjectValid(oEnemy))
                           
                          
                            ClearAllActions();
                            if(GetDistanceBetween(OBJECT_SELF, GetPartyMemberByIndex(0)) < 5.0)
                            {
                             ClearAllActions();
                             ActionForceMoveToObject(GetPartyMemberByIndex(0), FALSE, 1.5);
                             //SendMessageToPC(GetFirstPC(), "Debug Message: -Holo- Droid just executed the bRun routine.");
                            }
                            if(GetDistanceBetween(OBJECT_SELF, GetPartyMemberByIndex(0)) > 5.0)
                            {
                             ClearAllActions();
                             ActionForceMoveToObject(GetPartyMemberByIndex(0), TRUE, 3.5);
                             //SendMessageToPC(GetFirstPC(), "Debug Message: -Holo- Droid just executed the bWalk routine.");
                            }
                            if(d100(1) > 51)  //50% Chance of a random switch, meaning how fast.          
                            {
                                                                       
                              switch(iRollDice)    //Generated Number
                              {
                                case 1:
                                ClearAllActions();
                                ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 64));
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, OBJECT_SELF, 1.0f);
                                //SendMessageToPC(GetFirstPC(), "Henchmen's Case 1 is now Active: Droid_Sentry transformation.");
                                break;
                                case 2:
                                ClearAllActions();
                                ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 57));
            
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, OBJECT_SELF, 1.0f);
                                //SendMessageToPC(GetFirstPC(), "Henchmen's Case 2 is now Active: Droid_Astro_01 transformation.");
                                break;
                                case 3:
                                ClearAllActions();
                                ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 59));
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, OBJECT_SELF, 1.0f);
                                //SendMessageToPC(GetFirstPC(), "Henchmen's Case 3 is now Active: Droid_Mark_Four transformation.");
                                break;
                                case 4:
                                ClearAllActions();
                                ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 60));
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, OBJECT_SELF, 1.0f);
                                //SendMessageToPC(GetFirstPC(), "Henchmen's Case 4 is now Active: Droid_Mark_One transformation.");
                                break;
                                case 5:
                                ClearAllActions();
                                ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 65));
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, OBJECT_SELF, 1.0f);
                                //SendMessageToPC(GetFirstPC(), "Henchmen's Case 5 is now Active: Droid_Spyder transformation.");
                                break;
                                case 6:
                                ClearAllActions();
                                ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 61));
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, OBJECT_SELF, 1.0f);
                                //SendMessageToPC(GetFirstPC(), "Henchmen's Case 6 is now Active: Droid_Mark_Two transformation.");
                                break;
                                case 7:
                                ClearAllActions();
                                ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 538 ));
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, OBJECT_SELF, 1.0f);
                                //SendMessageToPC(GetFirstPC(), "Henchmen's Case 7 is now Active: Droid_NPC_hk50 transformation.");
                                break;
                                case 8:
                                ClearAllActions();
                                ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 581));
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, OBJECT_SELF, 1.0f);
                                //SendMessageToPC(GetFirstPC(), "Henchmen's Case 8 is now Active: Droid_Mining_Mark_Two_B transformation.");
                                break;
                                case 9:
                                ClearAllActions();
                                ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 630));
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, OBJECT_SELF, 1.0f);
                                //SendMessageToPC(GetFirstPC(), "Henchmen's Case 9 is now Active: Droid_MineFloating transformation.");
                                break;
                                case 10:
                                ClearAllActions();
                                ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 555));
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, OBJECT_SELF, 1.0f);
                                //SendMessageToPC(GetFirstPC(), "Henchmen's Case 10 is now Active: Droid_Construction_Medium transformation.");
                                break;
                               }
                              
                            }
                     }
                }
            }
            else if(GetSoloMode() && GetCurrentAction(OBJECT_SELF) == ACTION_FOLLOWLEADER)
            {
                ClearAllActions();
            }
            if(GN_GetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT))//Close this gap so it reads _HEARTBEAT!!!
            {
                SignalEvent(OBJECT_SELF, EventUserDefined(1001));
            }

        
   
   
}


For the “Real Party Member” or the creature that’s going to be added to the Party table;

Code:
#include "k_inc_debug"
#include "k_inc_generic"
#include "k_inc_switch"
#include "k_inc_utility"


int iRollDice = d10(1); //From 1-10, what number will the dice land on? Well, It's up to the game engine now.
void main()
{
    effect eFire = EffectVisualEffect(VFX_PRO_DRAIN);//Gives a Fire Glow effect on switching.
    object oEnemy = GetNearestCreature(CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, OBJECT_SELF, 1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
    if(!GN_GetSpawnInCondition(SW_FLAG_AI_OFF) && !GetSoloMode())
    {
        if(GetPartyMemberByIndex(0) != OBJECT_SELF)
        {
            if(IsObjectPartyMember(OBJECT_SELF) &&  
               //GetCurrentAction(OBJECT_SELF) != ACTION_FOLLOW &&
               GetCurrentAction(OBJECT_SELF) != ACTION_MOVETOPOINT &&
               //GetCurrentAction(OBJECT_SELF) != ACTION_WAIT &&
               GetCurrentAction(OBJECT_SELF) != ACTION_FOLLOWLEADER &&
               !GetIsConversationActive() &&
               //GetDistanceBetween(OBJECT_SELF, GetPartyMemberByIndex(0)) > 4.5 &&
               !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE) &&
               GetCommandable())
            {
                if(!GN_GetIsFighting(OBJECT_SELF) && !GetIsObjectValid(oEnemy))
                {

                    ClearAllActions();
 		    ActionFollowLeader();
                    
                     if(d100(1) > 41)  //60% Chance of a random switch, meaning how fast.          
                     {
                      switch(iRollDice)    //Generated Number
                      {
                       case 1:
                       ClearAllActions();
                       ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 653 ));
                       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFire, OBJECT_SELF, 1.0f);
                       //SendMessageToPC(GetFirstPC(), "Henchmen's Case 1 is now Active: Twilek_Assasin_02 transformation.");
                       break;
                       case 2:
                       ClearAllActions();
                       ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 22 ));
                       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFire, OBJECT_SELF, 1.0f);
                       //SendMessageToPC(GetFirstPC(), "Henchmen's Case 2 is now Active: Unique_Darth_Revan transformation.");                       
                       break;
                       case 3:
                       ClearAllActions();
                       ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 52 ));
                       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFire, OBJECT_SELF, 1.0f);
                       //SendMessageToPC(GetFirstPC(), "Henchmen's Case 3 is now Active: Unique_Vandar transformation.");
                       break;
                       case 4:
                       ClearAllActions();
                       ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 79 ));
                       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFire, OBJECT_SELF, 1.0f);
                       //SendMessageToPC(GetFirstPC(), "Henchmen's Case 4 is now Active: Creature_Rakghoul transformation.");
                       break;
                       case 5:
                       ClearAllActions();
                       ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 249 ));
                       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFire, OBJECT_SELF, 1.0f);
                       //SendMessageToPC(GetFirstPC(), "Henchmen's Case 5 is now Active: Creature_Kath_Hound_B03 transformation.");
                       break;
                       case 6:
                       ClearAllActions();
                       ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 274 ));
                       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFire, OBJECT_SELF, 1.0f);
                       //SendMessageToPC(GetFirstPC(), "Henchmen's Case 6 is now Active: Alien_Wookie_Male_05 transformation.");
                       break;
                       case 7:
                       ClearAllActions();
                       ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 457 ));
                       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFire, OBJECT_SELF, 1.0f);
                       //SendMessageToPC(GetFirstPC(), "Henchmen's Case 7 is now Active: Party_NPC_Visas transformation.");
                       break;
                       case 8:
                       ClearAllActions();
                       ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 491 ));
                       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFire, OBJECT_SELF, 1.0f);
                       //SendMessageToPC(GetFirstPC(), "Henchmen's Case 8 is now Active: Unique_Darth_Traya transformation.");
                       break;
                       case 9:
                       ClearAllActions();
                       ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 458 ));
                       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFire, OBJECT_SELF, 1.0f);
                       //SendMessageToPC(GetFirstPC(), "Henchmen's Case 9 is now Active: Unique_Darth_Sion transformation.");
                       break;
                       case 10:
                       ClearAllActions();
                       ActionDoCommand(ChangeObjectAppearance(OBJECT_SELF, 553 ));
                       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFire, OBJECT_SELF, 1.0f);
                       //SendMessageToPC(GetFirstPC(), "Henchmen's Case 10 is now Active: Creature_Laigrek_01 transformation.");
                       break;
                       }
                     }
                   
               }  
            }
        }
    }
    else if(GetSoloMode() && GetCurrentAction(OBJECT_SELF) == ACTION_FOLLOWLEADER)
    {
        ClearAllActions();
    }
    if(GN_GetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT))// Close this gap so it reads as HEARTBEAT!!!
    {
        SignalEvent(OBJECT_SELF, EventUserDefined(1001));
    }

}
Note: When you have two routines on top of one another in an AI script, such as: void ActionForceMoveToObject; to Move to the Object, and void Switch(iRollDice) to start the random Case switching, The Henchmen can only call for ONE Routine at a time - meaning, It can't move to the oObject and Switch appearances at the same time.. So If it is infact switching appearances then It won't move until a ClearAllActions() is called, or if the party leader moved into float range of the void ActionForceMoveToObject routine.

Also, The Odds of a Party Member Shape shifting is a little bit higher than the Non Party Script and that's because it's calling for the Void ActionFollowLeader(); Routine more often and ignores the Switching. But when it is Switching, then it's ignoring the Void ActionFollowLeader();..

Well, Hope you guys like these.

These scripts are using SWkoTOR II TSL Appearances.

Last edited by Darth InSidious; 08-02-2009 at 02:33 PM. Reason: Removed size tags.
Dak Vesser is offline   you may: quote & reply,
Post a new thread. Add a reply to this thread. Indicate all threads in this forum as read. Subscribe to this forum. RSS feed: this forum RSS feed: all forums
Go Back   LucasForums > Network > Knights of the Old Republic > Editing / Modding > Holowan Laboratories > Tutorials: Scripting > Henchmen scripts for the sake of...Henchmen Scripts

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 08:19 PM.

LFNetwork, LLC ©2002-2011 - All rights reserved.
Powered by vBulletin®
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.