Dak Vesser Posted February 10, 2006 Share Posted February 10, 2006 Just a small #include script, that I whipped up creating these two functions. void FPM_FollowLeader(); void FPM_Debug(); Here’s a description. FPM_FollowLeader: You can use this const function if you want the creature to follow the current party leader. Unlike “void ActionMoveToObject()”, This one will make a much smoother, less jittery movement. Using this new function, the creature can now walk, if close enough, run if too far, and back away if too close also will turn to follow whoever was switched to take lead. FPM_Debug; When adding this function along with FPM_FollowLeader(), It’ll send messages to the pc, reporting the current movement changes, plus the distances, and time. It’ll also send a barkString, showing the reports right in the game. However, you’ll need to type <CUSTOM210> in four StrRef slots in your dialog.tlk: 10865, 10866, 10867, and 10868. Otherwise you’ll see a blank barkstring repeating over again. I used this function for adjusting distances and changes. [size=1]// k_inc_fpm [color=#FFFF33]- Updated Feb 11, 2006[/color] // // Fake Party Member // Created by Dak Vesser // [color=#FFFF33]// Updates are in yellow.[/color] // Note: // This is a preprocessor/Include file which was created to co-function with a creature's // main AI HeartBeat script for SWKotOR/SWKotOR2 TSL.. // This file does NOT go to your Override folder // Place it in the folder where your nwnnsscomp.exe is located. // So you can use these two fuctions in your main script files /////////////////////////////////////////////////////////////////////////////////////////////////// //Sets a creature to follow //the current party leader. void FPM_FollowLeader(); //displays a barkstring with reports of //the creature's current movement changes. void FPM_Debug(); //Edited //If FPM_Debug has been added //to your main script along with FPM_FollowLeader, //then this integer will allow the FPM_Debug //function to automatically detect your changes //in distance settings from the FPM_FollowLeader //function & trigger the debug messages to //fire based on your new changes. This //will save us allot of time in debugging our mods, for sure!!! int nDebugMark = 0; /////////////////////////////////////////////////////////////////////////////////////////////////// //Function 1.. //FPM_FollowLeader() will allow a creature to follow the partyleader without being //added to the table. Unlike "ActionMoveToObject()", this will be a more smoother, //less shaky durring movement. Plus the creature using this function, will be able to //walk if close enough, run if too far, or back away if too close to the PC. /////////////////////////////////////////////////////////////////////////////////////////////////// void FPM_FollowLeader() { //object oLdr = GetFirstPC(); // follows only the pc. object oLdr = GetPartyMemberByIndex(0); vector vLdr = GetPosition(oLdr); float fLength = (GetDistanceBetween(OBJECT_SELF, oLdr)); [color=#FFFF33]int nRun = IsRunning(oLdr);// Returns 0 = walking, 1= running.[/color] [color=#FFFF33]if(nRun == 0)// If the leader is walking, { if(fLength >= 1.9)// and if the Leader is out side this range,[/color] { ClearAllActions();[color=#FFFF33]// Creature swithes to Walk Mode.[/color] nDebugMark = 1; ActionForceMoveToObject(oLdr, FALSE, 1.5, 9.0);[color=#FFFF33]// Creature walks to the Leader [/color] } } [color=#FFFF33]if(nRun == 1)// If the Leader is Running, { ClearAllActions();// Creature switches 2 Run Mode,[/color] nDebugMark = 2; ActionForceMoveToObject(oLdr, TRUE, 3.5);[color=#FFFF33]// Creature runs to the leader[/color] } if(fLength <= 1.8)[color=#FFFF33]// If the Leader stops and the Creature is within this range,[/color] { ClearAllActions();[color=#FFFF33]// Creature stops and swithes 2 StandBy Mode. // This Stops ActionForceMoveToObject from repeating.[/color] nDebugMark = 3; SetFacingPoint(vLdr);[color=#FFFF33]// Creature faces the leader.[/color] } if(fLength <= 0.8)[color=#FFFF33]// if the leader is too close and needs the way cleared[/color] { ClearAllActions();[color=#FFFF33]// Creature switches to Reverse Mode and clears a path[/color] nDebugMark = 4; ActionMoveAwayFromObject(oLdr, TRUE, 1.5);[color=#FFFF33]// Creature moves back to this range.[/color] [color=#FFFF33] } if(fLength >= 7.5)// If the creature is at or beyond this range from the leader,[/color] [color=#FFFF33]{ ClearAllActions();// Creature switches back into run Mode to catch up. nDebugMark = 2; DelayCommand(1.0, ActionForceMoveToObject(oLdr, TRUE, 5.5)); } if(fLength >= 6.5)// If the creature is beyond this range from the leader, { // ClearAllactions(); will not be used so that the other conditionals // can override this action. Should be a low priority within this block. nDebugMark = 2; ActionForceMoveToObject(oLdr, TRUE, 3.5);// Creature switches back into run Mode to catch up. } if(fLength >= 22.0) // If the Creature is beyond this range from the leader, { ClearAllActions(); nDebugMark = 2; ActionForceMoveToObject(oLdr, TRUE, 9.3);// Creature runs to catch up. }[/color] } /////////////////////////////////////////////////////////////////////////////////////////////////// //If you decide to use this funtion, then you'll need to add "<CUSTOM210>" into your dialog.tlk //slots: 10867, 10868, 10866, and 10865. Otherwise you'll end up seeing an empty BarkString //continuously popping up. //This Function is for the purpose of adjusting distances, timing, and movement changing //over to the void FPM_FollowLeader const. Tweak it to your own liking. /////////////////////////////////////////////////////////////////////////////////////////////////// void FPM_Debug() { string sMinute; string sTime; //The clock 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 "; object oLdr = GetPartyMemberByIndex(0); float fLength = (GetDistanceBetween(OBJECT_SELF, oLdr)); int CUSTOM210 = 210; string sDebug; if(nDebugMark == 1) { SendMessageToPC(oLdr, sTime + GetName(OBJECT_SELF)+ " is now in Walk Mode, following " +GetName(oLdr) +"." +" Distance: "+ FloatToString(fLength,0,2)); sDebug = sTime + GetName(OBJECT_SELF)+ " is now in Walk Mode, following " +GetName(oLdr) +"." +" Distance: "+ FloatToString(fLength,0,2); SetCustomToken(CUSTOM210, sDebug); BarkString(oLdr,10867);// Add <CUSTOM210> to slot 10867 in your dialog.tlk } if(nDebugMark == 2) { SendMessageToPC(oLdr, sTime + GetName(OBJECT_SELF)+ " is now in Run Mode, following " +GetName(oLdr)+ "." +" Distance: "+ FloatToString(fLength,0,2)); sDebug = sTime + GetName(OBJECT_SELF)+ " is now in Run Mode, following " +GetName(oLdr)+ "." +" Distance: "+ FloatToString(fLength,0,2); SetCustomToken(CUSTOM210, sDebug); BarkString(oLdr,10868);// Add <CUSTOM210> to slot 10868 in your dialog.tlk } if(nDebugMark == 3) { SendMessageToPC(oLdr,sTime + GetName(OBJECT_SELF)+ " is now in Standby Mode, pending " +GetName(oLdr)+ "'s next movement."+" Distance: "+ FloatToString(fLength,0,2)); sDebug = sTime + GetName(OBJECT_SELF)+ " is now in Standby Mode, pending " +GetName(oLdr)+ "'s next movement."+" Distance: "+ FloatToString(fLength,0,2); SetCustomToken(CUSTOM210,sDebug); BarkString(oLdr, 10866);// Add <CUSTOM210> to slot 10866 in your dialog.tlk } if(nDebugMark == 4) { SendMessageToPC(oLdr,sTime + GetName(OBJECT_SELF)+ " is now in Reverse Mode, getting out of " +GetName(oLdr)+"'s way."+" Distance: "+ FloatToString(fLength,0,2)); sDebug = sTime + GetName(OBJECT_SELF)+ " is now in Reverse Mode, getting out of " +GetName(oLdr)+"'s way."+" Distance: "+ FloatToString(fLength,0,2); SetCustomToken(CUSTOM210,sDebug); BarkString(oLdr, 10865);// Add <CUSTOM210> to slot 10865 in your dialog.tlk } } [/size] Use these functions in your creature's main HeartBeat script. Make sure to add #include "k_inc_fpm" in it so your compiler won't error.... {Edited} Do not use these functions on a party member, or a creature that you're going to add to the party table. {Tip} It's better to add these functions to a modified "k_hen_heartbt", not a "k_def_heartbt" script, since the intention is to make a creature "act" like a party member, or somewhat... hope you guys enjoy this... Link to comment Share on other sites More sharing options...
ChAiNz.2da Posted February 10, 2006 Share Posted February 10, 2006 VERY nice! So nice in fact... it has a permanent home in the Tutorials Section Scripting Area Link to comment Share on other sites More sharing options...
rgdelta Posted February 10, 2006 Share Posted February 10, 2006 Very Nice Link to comment Share on other sites More sharing options...
Dak Vesser Posted February 10, 2006 Author Share Posted February 10, 2006 Here's an example of how these new const functions would be applied to a modified henchmen heart beat script: [size=1]#include "k_inc_generic" #include "k_inc_switch" #include "k_inc_utility" [color=#FFFF33]#include "k_inc_fpm"[/color] 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_WAIT && !GetIsConversationActive() && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE) && GetCommandable()) { if(!GN_GetIsFighting(OBJECT_SELF) && !GetIsObjectValid(oEnemy)) ClearAllActions(); [color=#FFFF33]FPM_FollowLeader(); FPM_Debug();[/color] } } } else if(GetSoloMode() && GetCurrentAction(OBJECT_SELF) == ACTION_FOLLOWLEADER) { ClearAllActions(); } if(GN_GetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT)) { SignalEvent(OBJECT_SELF, EventUserDefined(1001)); } }[/size] Very simple as we can see.. Thanx ChAiNz, for adding this to the tutorial section.. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.