"""NWScript standard library source: k_inc_* and other included NSS content for KotOR/TSL."""

from __future__ import annotations

KOTOR_LIBRARY = {
    "k_inc_cheat": b"""//:: k_inc_cheat
/*
    This will be localized area for all
    Cheat Bot scripting.
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
#include "k_inc_debug"
//Takes a PLANET_ Constant
void CH_SetPlanetaryGlobal(int nPlanetConstant);
//Makes the specified party member available to the PC
void CH_SetPartyMemberAvailable(int nNPC);
//::///////////////////////////////////////////////
//:: Set Planet Local
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    VARIABLE = K_CURRENT_PLANET
        Endar Spire     5
        Taris           10
        Dantooine       15
        --Kashyyk       20
        --Manaan        25
        --Korriban      30
        --Tatooine      35
        Leviathan       40
        Unknown World   45
        Star Forge      50
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2002
//:://////////////////////////////////////////////
void CH_SetPlanetaryGlobal(int nPlanetConstant)
{
    if(nPlanetConstant == PLANET_ENDAR_SPIRE)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 5);
    }
    else if(nPlanetConstant == PLANET_TARIS)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 10);
    }
    else if(nPlanetConstant == PLANET_DANTOOINE)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 15);
    }
    else if(nPlanetConstant == PLANET_KASHYYYK)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 20);
    }
    else if(nPlanetConstant == PLANET_KORRIBAN)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 30);
    }
    else if(nPlanetConstant == PLANET_MANAAN)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 25);
    }
    else if(nPlanetConstant == PLANET_TATOOINE)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 35);
    }
    else if(nPlanetConstant == PLANET_LEVIATHAN)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 40);
    }
    else if(nPlanetConstant == PLANET_UNKNOWN_WORLD)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 45);
    }
    else if(nPlanetConstant == PLANET_STAR_FORGE)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 50);
    }
}
//::///////////////////////////////////////////////
//:: Make NPC Available
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets an NPC as available
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2002
//:://////////////////////////////////////////////
void CH_SetPartyMemberAvailable(int nNPC)
{
    if(nNPC == NPC_BASTILA)
    {
        AddAvailableNPCByTemplate(NPC_BASTILA, "p_bastilla");
    }
    else if(nNPC == NPC_CANDEROUS)
    {
        AddAvailableNPCByTemplate(NPC_CANDEROUS, "p_cand");
    }
    else if(nNPC == NPC_CARTH)
    {
        AddAvailableNPCByTemplate(NPC_CARTH, "p_carth");
    }
    else if(nNPC == NPC_HK_47)
    {
        AddAvailableNPCByTemplate(NPC_HK_47, "p_hk47");
    }
    else if(nNPC == NPC_JOLEE)
    {
        AddAvailableNPCByTemplate(NPC_JOLEE, "p_jolee");
    }
    else if(nNPC == NPC_JUHANI)
    {
        AddAvailableNPCByTemplate(NPC_JUHANI, "p_juhani");
    }
    else if(nNPC == NPC_MISSION)
    {
        AddAvailableNPCByTemplate(NPC_MISSION, "p_mission");
    }
    else if(nNPC == NPC_T3_M4)
    {
        AddAvailableNPCByTemplate(NPC_T3_M4, "p_t3m4");
    }
    else if(nNPC == NPC_ZAALBAR)
    {
        AddAvailableNPCByTemplate(NPC_ZAALBAR, "p_zaalbar");
    }
}
""",
    "k_inc_dan": b"""#include "k_inc_generic"
#include "k_inc_utility"
int ROMANCE_DONE = 4;
int JUHANI_RESCUED = 1;
int JEDI_TRAINING_DONE = 7;
int JEDI_PATH_GUARDIAN = 1;
int JEDI_PATH_SENTINEL = 2;
int JEDI_PATH_CONSULAR = 3;
int DROID_STARTED = 1;
int DROID_DESTROYED = 2;
int DROID_DECEIVED = 3;
int DROID_RETURNED = 4;
int DROID_HELPED = 5;
int DROID_FINISHED = 6;
string sBastilaTag = "bastila";
string sCarthTag = "carth";
string sCouncilTag = "dan13_WP_council";
string SABER_BLUE = "g_w_lghtsbr01";
string SABER_GREEN = "g_w_lghtsbr03";
string SABER_GOLD = "g_w_lghtsbr04";
string WANDERING_HOUND_TAG = "dan_wanderhound";
//places an instance of a character based on the tag/template
// **TAG MUST BE THE SAME AS TEMPLATE**
void PlaceNPC(string sTag, string sLocation = "");
//Get Carth's Object
object GetCarth();
//Gets Bastila's object
object GetBastila();
//gets the center of the council chamber
vector GetChamberCenter();
// creature move along a waypoint path. Not interuptable.
void PlotMove(string sWayPointTag,int nFirst, int nLast, int nRun = FALSE);
// creature move along a waypoint path. Not interuptable. Destroys self at the end
void PlotLeave(string sWayPointTag,int nFirst, int nLast, int nRun = FALSE);
// returns true is a trigger has not been fired yet
// intended for one shot triggers
int HasNeverTriggered();
//returns true if, on Korriban, the player has convinced Yuthura to come to Dantooine.
int YuthuraHasDefected();
//Sets the progression of the Elise plot on Dantooine
void SetElisePlot(int nValue);
// returns true if the player has started the Elise plot
int ElisePlotStarted();
// returns true if the player has agreed to help the droid after it has returned to elise
int GetDroidHelped();
// returns true if c369 has been spoken to
int GetEliseDroidMet();
//  the Elise plot has not started yet
int GetElisePlotNeverStared();
// returns true if Elise has gone to the Jedi compund
int GetEliseInCompound();
// returns true if the Elise plot is over
int GetElisePlotDone();
//returns true if Elise's droid was returned to her
int GetEliseDroidReturned();
// changes the PC to a new Jedi Class and gives them the required xperience to level Up
void TurnPlayerIntoJedi();
//checks for a color crystal in the players inventory and creates a saber of that color
object CreateFirstLightsaber();
//creates droids for the danm14ab cutscene
void StartDroid(string sLetter, int nNum);
//
void WraperShowLevelUpGUI();
//void main(){}
// returns number of the remaining wndering hounds on the level
int GetNumberOfWanderingKathHounds();
// spawns the number of Kath hounds. recursive
void SpawnWanderingKathHound(int nNumberOfHounds);
void PlaceNPC(string sTag, string sLocation = "")
{
    if(!GetIsObjectValid(GetObjectByTag(sTag)))
    {
        CreateObject(OBJECT_TYPE_CREATURE,sTag,GetLocation(GetObjectByTag("POST_" + sTag + sLocation)));
    }
}
object GetCarth()
{
    return GetObjectByTag(sCarthTag);
}
object GetBastila()
{
    return GetObjectByTag(sBastilaTag);
}
vector GetChamberCenter()
{
    return GetPosition(GetObjectByTag(sCouncilTag));
}
void PlotMove(string sWayPointTag,int nFirst, int nLast, int nRun = FALSE)
{
    int nInc = 1;
    object oWP;
    int nIdx;
    if(nFirst > nLast)
    {
        nInc = -1;
    }
    for(nIdx = nFirst - nInc; abs(nLast - nIdx) > 0 && abs(nLast - nIdx) <= abs((nLast - nFirst) + 1); nIdx = nIdx + nInc)
    {
        oWP = GetObjectByTag(sWayPointTag + IntToString(nIdx + nInc));
        if(GetIsObjectValid(oWP))
        {
            ActionForceMoveToObject(oWP,nRun,3.0f,5.0f);
        }
    }
    ActionDoCommand(SetCommandable(TRUE));
    SetCommandable(FALSE);
}
void PlotLeave(string sWayPointTag,int nFirst, int nLast, int nRun = FALSE)
{
    int nInc = 1;
    object oWP;
    int nIdx;
    object oSelf = OBJECT_SELF;
    if(nFirst > nLast)
    {
        nInc = -1;
    }
    for(nIdx = nFirst - nInc; abs(nLast - nIdx) > 0 && abs(nLast - nIdx) <= abs((nLast - nFirst) + 1); nIdx = nIdx + nInc)
    {
        oWP = GetObjectByTag(sWayPointTag + IntToString(nIdx + nInc));
        if(GetIsObjectValid(oWP))
        {
            ActionForceMoveToObject(oWP,nRun,3.0f,5.0f);
        }
    }
    ActionDoCommand(DestroyObject(OBJECT_SELF));
    SetCommandable(FALSE);
}
int HasNeverTriggered()
{
    int bReturn;
    if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_01) == FALSE)
    {
        bReturn = TRUE;
        UT_SetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_01,TRUE);
    }
    return bReturn;
}
int YuthuraHasDefected()
{
    return GetGlobalNumber("KOR_FINAL_TEST") == 7;
}
void SetElisePlot(int nValue)
{
    SetGlobalNumber("DAN_ELISE_PLOT",nValue);
}
int ElisePlotStarted()
{
    return GetGlobalNumber("DAN_ELISE_PLOT") == DROID_STARTED;
}
int GetDroidHelped()
{
    return GetGlobalNumber("DAN_ELISE_PLOT") == DROID_HELPED;
}
int GetEliseDroidMet()
{
    return GetGlobalNumber("DAN_ELISE_PLOT") > DROID_STARTED &&
           GetGlobalNumber("DAN_ELISE_PLOT") < DROID_FINISHED;
}
int GetElisePlotNeverStared()
{
    return GetGlobalNumber("DAN_ELISE_PLOT") == 0;
}
int GetEliseInCompound()
{
    return GetGlobalBoolean("DAN_ELISE_COMPOUND");
}
int GetElisePlotDone()
{
    return GetGlobalNumber("DAN_ELISE_PLOT") >= DROID_FINISHED;
}
int GetEliseDroidReturned()
{
    return GetGlobalNumber("DAN_ELISE_PLOT") == DROID_RETURNED ||
           GetGlobalNumber("DAN_ELISE_PLOT") == DROID_HELPED;
}
void TurnPlayerIntoJedi()
{
    object oPC = GetFirstPC();
/*    int nXP = GetXP(oPC);
   // AurPostString("Current XP: " + IntToString(nXP),5,5,5.0);
    int nLevel = GetHitDice(oPC);
   // AurPostString("Current Level: " + IntToString(nLevel),5,6,5.0);
    int nXPNeeded = 1000 * FloatToInt((IntToFloat(nLevel) / 2.0) * (IntToFloat(nLevel) + 1.0));
   // AurPostString("XP Needed" + IntToString(nXPNeeded),5,7,5.0);
    int nSaved = nXP - nXPNeeded;
   // AurPostString("Extra: " + IntToString(nSaved),5,8,5.0);
    if(nSaved > 0)
    {
        SetGlobalBoolean("DAN_EXTRA",TRUE);
        int nLow = nSaved & 0xff;
        AurPostString(IntToString(nLow),5,9,5.0);
        int nHigh = (nSaved >> 8) & 0xff;
        AurPostString(IntToString(nHigh),5,10,5.0);
       // if (nLow > 0)
       // {
           SetGlobalNumber("DAN_EXTRA_XP",nLow - 128);
       // }
      //  if (nHigh > 0)
        //{
            SetGlobalNumber("DAN_EXTRA_XP2",nHigh - 128);
       //}
    } */
    int nJediPath = GetGlobalNumber("DAN_PATH_STATE");
    if(nJediPath > 0)
    {
        if(nJediPath == JEDI_PATH_GUARDIAN)
        {
            AddMultiClass(CLASS_TYPE_JEDIGUARDIAN,oPC);
        }
        else if (nJediPath == JEDI_PATH_SENTINEL)
        {
            AddMultiClass(CLASS_TYPE_JEDISENTINEL,oPC);
        }
        else if (nJediPath == JEDI_PATH_CONSULAR)
        {
            AddMultiClass(CLASS_TYPE_JEDICONSULAR,oPC);
        }
      //  int nLevel = GetHitDice(oPC);
      //  int nXPNeeded = 1000 * (nLevel / 2) * (nLevel + 1);
      //  SetXP(oPC,nXPNeeded);
    }
    //ShowLevelUpGUI();
    CancelPostDialogCharacterSwitch();
    NoClicksFor(0.6);
    DelayCommand(0.5,WraperShowLevelUpGUI());
}
object CreateFirstLightsaber()
{
    object oPC = GetFirstPC();
    object oSaber;
    object oCrystal = GetItemPossessedBy(GetFirstPC(),"dan13_plotcrys");
    SetPlotFlag(oCrystal,FALSE);
    DestroyObject(oCrystal);
   /* if(GetIsObjectValid(oSaber))
    {
        AssignCommand(oPC,ActionEquipItem(oSaber,INVENTORY_SLOT_RIGHTWEAPON));
    }*/
    int nJediPath = GetGlobalNumber("DAN_PATH_STATE");
    if(nJediPath > 0)
    {
        if(nJediPath == JEDI_PATH_GUARDIAN)
        {
            oSaber = CreateItemOnObject(SABER_BLUE,oPC);
        }
        else if (nJediPath == JEDI_PATH_SENTINEL)
        {
            oSaber = CreateItemOnObject(SABER_GOLD,oPC);
        }
        else if (nJediPath == JEDI_PATH_CONSULAR)
        {
            oSaber = CreateItemOnObject(SABER_GREEN,oPC);
        }
    }
    if(GetIsObjectValid(oSaber))
    {
      // ExecuteScript("k_pdan_player03",oPC);
        DelayCommand(0.1,AssignCommand(oPC,ActionEquipItem(oSaber,INVENTORY_SLOT_RIGHTWEAPON)));
    }
    return oSaber;
}
void StartDroid(string sLetter, int nNum)
{
    string sBase = "danm14aa_WP_droid";
    string sStartTag = sBase + sLetter + "_01";
    string sEndTag = sBase + sLetter + "_0" + IntToString(nNum);
    location lStart = GetLocation(GetObjectByTag(sStartTag));
    location lEnd = GetLocation(GetObjectByTag(sEndTag));
    object oDroid = CreateObject(OBJECT_TYPE_CREATURE, "pdan_mwdroid",lStart);
    AssignCommand(oDroid,ActionWait(0.5));
    AssignCommand(oDroid,ActionMoveToLocation(lEnd));
/*    if(GetIsObjectValid(GetObjectByTag(sTag + sLetter + "_01")))
    {
        PrintString("Aidan--FoundDroidWP");
    }
    else
    {
        PrintString("Aidan--Can't Find DroidWP");
    }*/
   // object oDroid = CreateObject(OBJECT_TYPE_CREATURE, "pdan_mwdroid",GetLocation(GetObjectByTag(sTag + sLetter + "_01")));
  //  AssignCommand(oDroid,ActionMoveToObject(GetObjectByTag(sTag + sLetter + "_0" + IntToString(nNum))));
}
void WraperShowLevelUpGUI()
{
    int bAdd = GetGlobalBoolean("DAN_EXTRA");
    int nHigh =(GetGlobalNumber("DAN_EXTRA_XP2") + 128) << 8;
   // AurPostString(IntToString(nHigh),5,12,5.0);
    int nLow = GetGlobalNumber("DAN_EXTRA_XP") + 128;
   // AurPostString(IntToString(nLow),5,13,5.0);
    int nExtra = nHigh  | nLow;
   // AurPostString("Extra Saved: " + IntToString(nExtra),5,14,5.0);
    if(bAdd)
    {
       // AurPostString("Setting: " + IntToString(nExtra),5,15,5.0);
        GiveXPToCreature(GetFirstPC(),nExtra);
    }
    SetGlobalNumber("DAN_EXTRA_XP",0);
    SetGlobalNumber("DAN_EXTRA_XP2",0);
    ShowLevelUpGUI();
}
int GetNumberOfWanderingKathHounds()
{
    int nNumber;
   // int nNumber2;
    int nCount = GetStringLength(WANDERING_HOUND_TAG);
    object oHound = GetFirstObjectInArea();
    while(GetIsObjectValid(oHound))
    {
     //   AurPostString("Tag: " + GetTag(oHound),5,3,5.0);
        if(GetStringLeft(GetTag(oHound),nCount) == WANDERING_HOUND_TAG)
        {
            nNumber++;
        }
       // nNumber2++;
        oHound = GetNextObjectInArea();
       // AurPostString("Tag: " + GetTag(oHound),5,4,5.0);
    }
    //AurPostString("Number of Objects: " + IntToString(nNumber2),5,5,5.0);
   // AurPostString("Number of Objects: " + IntToString(nNumber),5,6,5.0);
    return nNumber;
}
void SpawnWanderingKathHound(int nNumberOfHounds)
{
    string sHound = WANDERING_HOUND_TAG + IntToString(nNumberOfHounds);
    location lSpawn = GetLocation(GetObjectByTag( "WP_" + sHound + "_01" ));
    CreateObject(OBJECT_TYPE_CREATURE,sHound,lSpawn);
    nNumberOfHounds--;
    if(nNumberOfHounds > 0)
    {
        SpawnWanderingKathHound(nNumberOfHounds);
    }
}
""",
    "k_inc_debug": b"""//::///////////////////////////////////////////////
//:: KOTOR Debug Include
//:: k_inc_debug
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This contains the functions for inserting
    debug information into the scripts.
    This include will use Db as its two letter
    function prefix.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//:://////////////////////////////////////////////
//Inserts a print string into the log file for debugging purposes.
void Db_MyPrintString(string sString);
//Makes the object running the script say a speak string.
void Db_MySpeakString(string sString);
//Makes the nearest PC say a speakstring.
void Db_AssignPCDebugString(string sString);
//Basically, a wrapper for AurPostString
void Db_PostString(string sString = "",int x = 5,int y = 5,float fShow = 1.0);
//::///////////////////////////////////////////////
//:: Debug Print String
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Inserts a print string into the log file for
    debugging purposes.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//:://////////////////////////////////////////////
void Db_MyPrintString(string sString)
{
    if(!ShipBuild())
    {
        PrintString(sString);
    }
}
//::///////////////////////////////////////////////
//:: Debug Speak String
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Makes the object running the script say a
    speak string.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//:://////////////////////////////////////////////
void Db_MySpeakString(string sString)
{
    SpeakString(sString);
}
//::///////////////////////////////////////////////
//:: Assign PC Debug String
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Assigns the nearest PC a speakstring for debug
    purposes.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//:://////////////////////////////////////////////
void Db_AssignPCDebugString(string sString)
{
    object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
    if(GetIsObjectValid(oPC))
    {
        AssignCommand(oPC, SpeakString(sString));
    }
}
//::///////////////////////////////////////////////
//:: Db_PostString
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//Basically, a wrapper for AurPostString
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
void Db_PostString(string sString = "",int x = 5,int y = 5,float fShow = 1.0)
{
    if(!ShipBuild())
    {
        AurPostString(sString,x,y,fShow);
    }
}
""",
    "k_inc_drop": b"""//::///////////////////////////////////////////////
//:: KOTOR Treasure drop Include
//:: k_inc_drop
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
// Contains the functions for handling creatures dropping random treasure
//Only human creatures not of the beast subrace willdrop treasure dependant
//on their hit dice
//:://////////////////////////////////////////////
//:: Created By: Aidan Scanlan On: 02/06/03
//:://////////////////////////////////////////////
int DR_HIGH_LEVEL = 15;
int DR_MEDIUM_LEVEL = 10;
int DR_LOW_LEVEL = 5;
int DR_SUBRACE_BEAST = 2;
//Checks for treasure drop conditions. Returns True if treasure will drop
int DR_SpawnCreatureTreasure(object oTarget = OBJECT_SELF);
//Dependant on the level of a creature drops treasure from a list
void DR_CreateRandomTreasure(object oTarget = OBJECT_SELF);
// creates a low level treasure: med pack/repair, frag grenade, credits
void DR_CreateLowTreasure();
// creates midlevel treasure: adv-med/repair, any gredade, stims, credits
void DR_CreateMidTreasure();
// creates high treasure: adv stims, grenades, ultra med/repair, credits
void DR_CreateHighTreasure();
// Creates 1-4 credits
void DR_CreateFillerCredits();
/////////////////////////////////////////////////////////////////////////
//Checks for treasure drop conditions. Returns True if treasure will drop
int DR_SpawnCreatureTreasure(object oTarget = OBJECT_SELF)
{
    int nRace = GetRacialType(oTarget);
    int nFaction = GetStandardFaction(oTarget);
    int nSubRace = GetSubRace(oTarget);
    if(Random(4) == 0 &&
       nRace != RACIAL_TYPE_DROID &&
       nSubRace != DR_SUBRACE_BEAST)
    {
        //AurPostString("will drop",5,5,5.0);
        DR_CreateRandomTreasure(oTarget);
        return TRUE;
    }
    return FALSE;
}
//Dependant on the level of a creature drops treasure from a list
void DR_CreateRandomTreasure(object oTarget = OBJECT_SELF)
{
    int nLevel = GetHitDice(oTarget);
    if (nLevel > DR_HIGH_LEVEL)
    {
        DR_CreateHighTreasure();
        if(Random(2) == 0)
        {
            DR_CreateHighTreasure();
        }
        if(Random(2) == 0)
        {
            DR_CreateMidTreasure();
        }
    }
    else if (nLevel <= DR_HIGH_LEVEL && nLevel > DR_MEDIUM_LEVEL)
    {
        DR_CreateMidTreasure();
        if(Random(3) == 0)
        {
            DR_CreateHighTreasure();
        }
        if(Random(2) == 0)
        {
            DR_CreateMidTreasure();
        }
    }
    else if (nLevel <= DR_MEDIUM_LEVEL && nLevel > DR_LOW_LEVEL)
    {
        DR_CreateMidTreasure();
        if(Random(2) == 0)
        {
            DR_CreateLowTreasure();
        }
    }
    else
    {
        DR_CreateLowTreasure();
        if(Random(3) == 0)
        {
            DR_CreateLowTreasure();
        }
        if(Random(4) == 0)
        {
            DR_CreateMidTreasure();
        }
    }
}
// creates a low level treasure: med pack/repair, frag grenade, credits
void DR_CreateLowTreasure()
{
   //AurPostString("dropping low",5,6,5.0);
    string sTemplate;
    int nStack = 1;
    int nRandom = Random(6);
    switch(nRandom)
    {
        case 0: sTemplate = "g_i_drdrepeqp001";  //repair kit
        break;
        case 1:
            sTemplate = "g_i_credits001";// 5 stack
            nStack = 5;
            DR_CreateFillerCredits();
        break;
        case 2:
            sTemplate = "g_i_credits002";  //10 stack
            nStack = 10;
            DR_CreateFillerCredits();
        break;
        case 3:
            sTemplate = "g_i_credits003";  // 25 stack
            nStack = 25;
            DR_CreateFillerCredits();
        break;
        case 4: sTemplate = "g_i_medeqpmnt01";// med kit
        break;
        case 5: sTemplate = "g_w_fraggren01"; // frag grenade
        break;
    }
    CreateItemOnObject(sTemplate,OBJECT_SELF,nStack);
}
// creates midlevel treasure: adv-med/repair, any gredade, stims, credits
void DR_CreateMidTreasure()
{
    string sTemplate;
    int nStack = 1;
    int nRandom = Random(15);
    switch (nRandom)
    {
        case 0: sTemplate = "g_i_drdrepeqp002";  //advanced repair kit
        break;
        case 1:
            sTemplate = "g_i_credits004";  // 50 stack
            nStack = 50;
            DR_CreateFillerCredits();
        break;
        case 2: sTemplate = "g_i_medeqpmnt02"; //advanced med pack
        break;
        case 3: sTemplate = "g_i_cmbtshot001"; //battle stimulant
        break;
        case 4: sTemplate = "g_i_adrnaline003";  //adrenal stamina
        break;
        case 5: sTemplate = "g_i_adrnaline002"; // adrenal alacrity
        break;
        case 6: sTemplate = "g_i_adrnaline001"; // adrenal strength
        break;
        case 7:
            sTemplate = "g_w_stungren01";  // stun grenade
            nStack = 2;
        break;
        case 8:
            sTemplate = "g_w_fraggren01";  // fragmentation grenade
            nStack = 2;
        break;
        case 9: sTemplate = "g_w_poisngren01"; // poison gredade
        break;
        case 10: sTemplate = "g_w_sonicgren01"; // sonic grenade
        break;
        case 11: sTemplate = "g_w_adhsvgren001"; // adhesive grenade
        break;
        case 12: sTemplate = "g_w_cryobgren001";// cryo grenade
        break;
        case 13: sTemplate = "g_w_iongren01";// ion grenade
        break;
    }
    CreateItemOnObject(sTemplate,OBJECT_SELF,nStack);
}
// creates high treasure: adv stims, grenades, ultra med/repair, credits
void DR_CreateHighTreasure()
{
    string sTemplate;
    int nStack = 1;
    int nRandom = Random(16);
    switch (nRandom)
    {
        case 0: sTemplate = "g_i_drdrepeqp003";  //super repair kit
        break;
        case 1: sTemplate = "g_w_thermldet01"; //Thermal detinator
        break;
        case 2: sTemplate = "g_i_medeqpmnt03"; //life pack
        break;
        case 3: sTemplate = "g_i_cmbtshot003";//speed stim
        break;
        case 4: sTemplate = "g_i_cmbtshot002"; //hyper battle stim
        break;
        case 5: sTemplate = "g_i_adrnaline006"; //huper adrenal stamina
        break;
        case 6: sTemplate = "g_i_adrnaline005"; //hyper adrenal alacrity
        break;
        case 7: sTemplate = "g_i_adrnaline004";// hyper adrenal strength
        break;
        case 8:
        sTemplate = "g_w_poisngren01"; // poison gredade
        nStack = 2;
        break;
        case 9:
        sTemplate = "g_w_sonicgren01"; // sonic grenade
        nStack = 2;
        break;
        case 10:
        sTemplate = "g_w_adhsvgren001"; // adhesive grenade
        nStack = 2;
        break;
        case 11:
        sTemplate = "g_w_cryobgren001";// cryo grenade
        nStack = 2;
        break;
        case 12:
        sTemplate = "g_w_firegren001";// plasma grenade
        nStack = 2;
        break;
        case 13:
        sTemplate = "g_w_iongren01";// ion grenade
        nStack = 2;
        break;
        case 14:
        sTemplate = "g_i_credits015";
        nStack = Random(50) + 50;
        break;
        case 15: sTemplate = "g_w_firegren001";// plasma grenade
        break;
    }
    CreateItemOnObject(sTemplate,OBJECT_SELF,nStack);
}
// Creates 1-4 credits
void DR_CreateFillerCredits()
{
    CreateItemOnObject("g_i_credits015",OBJECT_SELF,Random(4) + 1);
}
""",
    "k_inc_ebonhawk": b"""//:: k_inc_ebonhawk
/*
     Ebon Hawk include file
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
//This checks the Star Map plot to see if it is at state 30.
int EBO_CheckStarMapPlot();
//Bastila intiates conversation with the PC
void EBO_BastilaStartConversation2();
//Should Bastila intiates conversation with the PC
int EBO_ShouldBastilaStartConversation();
//Bastila intiates conversation with the PC
void EBO_BastilaStartConversation2();
//Advances the state of the bounty hunters plot after galaxy map selections are made
void EBO_PlayBountyHunterCutScene();
//Play the current cutscene for taking off from the planet.
void EBO_PlayTakeOff(int nCurrentPlanet);
//Play the corrent cutscene for landing on the planet.
void EBO_PlayLanding(int nDestination);
//Creates items on the PC based on the NPC they are talking to.
void EBO_CreateEquipmentOnPC();
//Checks if the PC needs equipment based on the NPC they are talking to.
int EBO_GetIsEquipmentNeeded();
//Determines the number items held with specific tags
int EBO_CheckInventoryNumbers(string sTag1, string sTag2 = "", string sTag3 = "", string sTag4 = "");
//Returns the scripting constant for the current planet.
int EBO_GetCurrentPlanet();
//Returns the scripting constant for the future planet.
int EBO_GetFuturePlanet();
//Returns the correct K_CURRENT_PLANET value when a Planetary.2DA index is passed in.
int EBO_GetPlanetFrom2DA(int nPlanetIndex);
//Starts the correct sequence based on the planet being traveled to.
void EBO_PlayRenderSequence();
//::///////////////////////////////////////////////
//:: Check Star Map
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    If the variable K_STAR_MAP is at 30 and
    the variable K_CAPTURED_LEV = 5 then
    run the leviathan module.
    K_CAPTURED_LEV States
    0 = Pre Leviathan
    5 = Captured
    10 = Escaped
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 3, 2002
//:://////////////////////////////////////////////
int EBO_CheckStarMapPlot()
{
    int nStarMap = GetGlobalNumber("K_STAR_MAP");
    int nLev = GetGlobalBoolean("K_CAPTURED_LEV");
    if(nStarMap >= 40 && nLev == 5)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 40);
        //This will be removed when the new galaxy map is rolled out.
        StartNewModule("ebo_m40aa");
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Bastila Start Vision Conversation
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This function gets bastila to start the
    appropriate cutscene dialogue with the PC
    You can use k_vis_[PLANET] == FALSE to see
    if they have been their before and seen the
    planet vision. This applies to Dantooine,
    Manaan, Korriban, Tatooine and Kashyyyk.
    Also set the script so that if Ebon_Vision !=99
    then it fires the dialog file ebo_bast_vision
    and has Bastila init dialog on the Ebon Hawk.
    (If Ebon_Vision==99 the dialog will not fire,
    but it should still play the vision.
    15 to 35
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 3, 2002
//:://////////////////////////////////////////////
void EBO_BastilaStartConversation()
{
    int nPlanet = GetGlobalNumber("K_CURRENT_PLANET");
    int nVision = GetGlobalNumber("Ebon_Vision");
    int nFLAG = FALSE;
    if( (nPlanet == 15 || nPlanet == 20 || nPlanet == 25 || nPlanet == 30 || nPlanet == 35) && nVision != 99)
    {
        object oBast = GetNearestObjectByTag("Bastila");
        if(GetIsObjectValid(oBast))
        {
            if(nPlanet == 15 && !GetGlobalBoolean("k_vis_dantooine"))
            {
                nFLAG = TRUE;
                SetGlobalBoolean("k_vis_dantooine",1);
            }
            else if(nPlanet == 20 && !GetGlobalBoolean("k_vis_kashyyyk"))
            {
                nFLAG = TRUE;
                SetGlobalBoolean("k_vis_kashyyyk",1);
            }
            else if(nPlanet == 25 && !GetGlobalBoolean("k_vis_manaan"))
            {
                nFLAG = TRUE;
                SetGlobalBoolean("k_vis_manaan",1);
            }
            else if(nPlanet == 30 && !GetGlobalBoolean("k_vis_korriban"))
            {
                nFLAG = TRUE;
                SetGlobalBoolean("k_vis_korriban",1);
            }
            else if(nPlanet == 35 && !GetGlobalBoolean("k_vis_tatooine"))
            {
                nFLAG = TRUE;
                SetGlobalBoolean("k_vis_tatooine",1);
            }
            if(nFLAG == TRUE)
            {
                //HoldWorldFadeInForDialog();
                object oPC = GetFirstPC();
                AurPostString("I am going to talk", 5, 6, 4.0);
                AurPostString("Bastila is Valid = " + IntToString(GetIsObjectValid(oBast)), 5,7,4.0);
                AurPostString("PC is Valid = " + IntToString(GetIsObjectValid(oPC)), 5,8,4.0);
                AssignCommand(oBast, ActionStartConversation(oPC, "ebo_bast_vision", FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE));
            }
        }
    }
}
//::///////////////////////////////////////////////
//::Calo Nord / Bandon Variable Advancement
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This plot involves the PC being tracked across the galaxy.
    Plot is tracked with the K_KALO_BANDON variable
    1 - Leaving Dantooine --> Cutscene with Calo Nord = 0, set to 10.
    2 - On 3rd Star Map Planet --> Next villain encounter will spawn Nord = 10, set to 20
    3 - Leaving 3rd Starmap Planet --> Darth Bandon cutscene = 20, set to 30.
    4 - On 4th Star Map planet --> Darth Bandon Attacks = 30, set to 99
    Trigger have been placed on all the creamy middle planets to simulate
    the ambush
    10 - 1st Map Activated - Set K_KALO_BANDON to 10
    30 - 3rd Map Activated - Set K_KALO_BANDON to 30
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
void EBO_PlayBountyHunterCutScene()
{
    int nStar = GetGlobalNumber("K_STAR_MAP");
    if(nStar == 10)
    {
        //NOTE - PLAY FIRST CUTSCENE WITH CALO NORD HERE
        SetGlobalNumber("K_KALO_BANDON", 10);
    }
    else if(nStar == 30)
    {
        //NOTE - PLAY SECOND CUTSCENE WITH DARTH BANDON HERE
        SetGlobalNumber("K_KALO_BANDON", 30);
    }
}
//::///////////////////////////////////////////////
//::Play Appropriate Travel Cutscenes
//::Calo Nord / Bandon Variable Advancement
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    K_STAR_MAP variable
    0 - No maps activated
    10 - 1st Map Activated
    20 - 2nd Map Activated
    30 - 3rd Map Activated
    40 - 4th Map Activated
    50 - 5th Map Activated
World Variables
    Global Number Variable: Planet Settings
    VARIABLE = K_CURRENT_PLANET
        Endar Spire     5
        Taris           10
        Dantooine       15
        --Kashyyk       20
        --Manaan        25
        --Korriban      30
        --Tatooine      35
        Leviathan       40
        Unknown World   45
        Star Forge      50
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
string EBO_PlayTakeOff(int nCurrentPlanet)
{
    int nPlanet = nCurrentPlanet;//GetGlobalNumber("K_CURRENT_PLANET");
    if(nPlanet == 15)
    {
        PlayMovie("05_2c");
    }
    else if(nPlanet == 20)
    {
        PlayMovie("05_4c");
    }
    else if(nPlanet == 25)
    {
        PlayMovie("05_5c");
    }
    else if(nPlanet == 30)
    {
        PlayMovie("05_7c");
    }
    else if(nPlanet == 35)
    {
        PlayMovie("05_3c");
    }
    else if(nPlanet == 40)
    {
        //PlayMovie("");
    }
    else if(nPlanet == 45)
    {
        PlayMovie("05_8c");
    }
    return "NULL";
}
string EBO_PlayLanding(int nDestination)
{
    int nPlanet = GetGlobalNumber("K_CURRENT_PLANET");
    if(nPlanet == 15)
    {
        PlayMovie("05_2a");
    }
    else if(nPlanet == 20)
    {
        PlayMovie("05_4a");
    }
    else if(nPlanet == 25)
    {
        PlayMovie("05_5a");
    }
    else if(nPlanet == 30)
    {
        PlayMovie("05_7a");
    }
    else if(nPlanet == 35)
    {
        PlayMovie("05_3a");
    }
    else if(nPlanet == 40)
    {
        //PlayMovie("");
    }
    else if(nPlanet == 45)
    {
        PlayMovie("05_8a");
    }
    return "NULL";
}
//::///////////////////////////////////////////////
//:: Does the PC need equipment
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the PCs inventory and determines based
    on OBJECT_SELF whether the PC needs equipment
    Returns true if the PC has enough of the selected
    item.
    The number of items given out is now tracked as
    of Feb 25, 2003.  The NPCs will not give out
    more items than the current setting of the
    star map variable + 5.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 19, 2002
//:://////////////////////////////////////////////
int EBO_GetIsEquipmentNeeded()
{
    int nNumber, nGlobal;
    string sTag = GetTag(OBJECT_SELF);
    int nStarMap = (GetGlobalNumber("K_STAR_MAP")*2) + 10;
    if(sTag == "zaalbar")
    {
        nNumber = EBO_CheckInventoryNumbers("G_w_StunGren01","g_w_iongren01","g_w_adhsvgren001");
        nGlobal = GetGlobalNumber("K_ZAALBAR_ITEMS");
        if((nNumber <= 10 && nGlobal < nStarMap) || nGlobal == 0)
        {
            return FALSE;
        }
        return TRUE;
    }
    else if(sTag == "jolee")
    {
        nNumber = EBO_CheckInventoryNumbers("g_I_medeqpmnt01","G_I_MEDEQPMNT02","g_I_medeqpmnt03");
        nGlobal = GetGlobalNumber("K_JOLEE_ITEMS");
        if((nNumber <= 10 && nGlobal < nStarMap) || nGlobal == 0)
        {
            return FALSE;
        }
        return TRUE;
    }
    else if(sTag == "mission")
    {
        nNumber = EBO_CheckInventoryNumbers("g_i_secspike01","G_I_SECSPIKE02");
        nGlobal = GetGlobalNumber("K_MISSION_ITEMS");
        if((nNumber <= 10 && nGlobal <= nStarMap) || nGlobal == 0)
        {
            return FALSE;
        }
        return TRUE;
    }
    else if(sTag == "cand")
    {
        nNumber = EBO_CheckInventoryNumbers("g_i_adrnaline001","G_I_ADRNALINE002","g_i_adrnaline003", "g_i_cmbtshot001");
        nGlobal = GetGlobalNumber("K_CAND_ITEMS");
        PrintString("Number = " + IntToString(nNumber));
        PrintString("Global = " + IntToString(nGlobal));
        PrintString("StarMap = " + IntToString(nStarMap));
        if((nNumber <= 10 && nGlobal <= nStarMap) || nGlobal == 0)
        {
            return FALSE;
        }
        return TRUE;
    }
    else if(sTag == "t3m4")
    {
        nNumber = EBO_CheckInventoryNumbers("K_COMPUTER_SPIKE");
        nGlobal = GetGlobalNumber("K_T3M4_ITEMS");
        if((nNumber <= 10 && nGlobal <= nStarMap) || nGlobal == 0)
        {
            return FALSE;
        }
        return TRUE;
    }
    return TRUE;
}
//::///////////////////////////////////////////////
//:: NPC Item Creation
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Determines who the person being talked to is
    and what items the character should receive.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 19, 2002
//:://////////////////////////////////////////////
void EBO_CreateEquipmentOnPC()
{
    int nCount;
    string sTag = GetTag(OBJECT_SELF);
    object oProxy;
    if(sTag == "zaalbar")
    {
        int nRand = d3();
        if(nRand == 1)
        {
            oProxy = CreateItemOnObject("g_w_stungren01", GetFirstPC());
        }
        else if(nRand == 2)
        {
            oProxy = CreateItemOnObject("g_w_iongren01", GetFirstPC());
        }
        else if(nRand == 3)
        {
            oProxy = CreateItemOnObject("g_w_adhsvgren001", GetFirstPC());
        }
        nCount = GetGlobalNumber("K_ZAALBAR_ITEMS");
        nCount++;
        SetGlobalNumber("K_ZAALBAR_ITEMS", nCount);
    }
    else if(sTag == "jolee")
    {
        int nLevel = GetHitDice(GetFirstPC());
        if(nLevel <= 4)
        {
            oProxy = CreateItemOnObject("G_I_MEDEQPMNT01", GetFirstPC());
        }
        else if(nLevel > 4 && nLevel <= 10)
        {
            oProxy = CreateItemOnObject("G_I_MEDEQPMNT02", GetFirstPC());
        }
        else if(nLevel > 10)
        {
            oProxy = CreateItemOnObject("G_I_MEDEQPMNT03", GetFirstPC());
        }
        nCount = GetGlobalNumber("K_JOLEE_ITEMS");
        nCount++;
        SetGlobalNumber("K_JOLEE_ITEMS", nCount);
    }
    else if(sTag == "mission")
    {
        int nLevel = GetHitDice(GetFirstPC());
        if(nLevel <= 7)
        {
            oProxy = CreateItemOnObject("g_i_secspike01", GetFirstPC());
        }
        else if(nLevel > 7)
        {
            oProxy = CreateItemOnObject("g_i_secspike02", GetFirstPC());
        }
        nCount = GetGlobalNumber("K_MISSION_ITEMS");
        nCount++;
        SetGlobalNumber("K_MISSION_ITEMS", nCount);
    }
    else if(sTag == "cand")
    {
        int nRand = d4();
        if(nRand == 1)
        {
            oProxy = CreateItemOnObject("G_I_ADRNALINE001", GetFirstPC());
        }
        else if(nRand == 2)
        {
            oProxy = CreateItemOnObject("G_I_ADRNALINE002", GetFirstPC());
        }
        else if(nRand == 3)
        {
            oProxy = CreateItemOnObject("G_I_ADRNALINE003", GetFirstPC());
        }
        else if(nRand == 4)
        {
            oProxy = CreateItemOnObject("G_I_CMBTSHOT001", GetFirstPC());
        }
        nCount = GetGlobalNumber("K_CAND_ITEMS");
        nCount++;
        SetGlobalNumber("K_CAND_ITEMS", nCount);
    }
    else if(sTag == "t3m4")
    {
        oProxy = CreateItemOnObject("G_I_PROGSPIKE01", GetFirstPC());
        nCount = GetGlobalNumber("K_T3M4_ITEMS");
        nCount++;
        SetGlobalNumber("K_T3M4_ITEMS", nCount);
    }
}
//::///////////////////////////////////////////////
//:: Count Inventory Items
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Counts and totals up to four different items
    within the PCs inventory.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 19, 2002
//:://////////////////////////////////////////////
int EBO_CheckInventoryNumbers(string sTag1, string sTag2 = "", string sTag3 = "", string sTag4 = "")
{
    int nNumber;
    object oGrenade;
    if(sTag1 != "")
    {
        oGrenade = GetItemPossessedBy(GetFirstPC(), sTag1);
        if(GetIsObjectValid(oGrenade))
        {
            nNumber += GetNumStackedItems(oGrenade);
        }
    }
    if(sTag2 != "")
    {
        oGrenade = GetItemPossessedBy(GetFirstPC(), sTag2);
        if(GetIsObjectValid(oGrenade))
        {
            nNumber += GetNumStackedItems(oGrenade);
        }
    }
    if(sTag3 != "")
    {
        oGrenade = GetItemPossessedBy(GetFirstPC(), sTag3);
        if(GetIsObjectValid(oGrenade))
        {
            nNumber += GetNumStackedItems(oGrenade);
        }
    }
    if(sTag4 != "")
    {
        oGrenade = GetItemPossessedBy(GetFirstPC(), sTag4);
        if(GetIsObjectValid(oGrenade))
        {
            nNumber += GetNumStackedItems(oGrenade);
        }
    }
    return nNumber;
}
//::///////////////////////////////////////////////
//:: Get Planet Constant
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Uses K_CURRENT_PLANET to return the current
    planets scripting constant
    0    Endar Spire     5
    1    Taris           10
    2    Dantooine       15
    3    --Kashyyk       20
    4    --Manaan        25
    5    --Korriban      30
    6    --Tatooine      35
    7    Leviathan       40
    8    Unknown World   45
    9    Star Forge      50
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 1, 2002
//:://////////////////////////////////////////////
int EBO_GetCurrentPlanet()
{
    int nPlanet = GetGlobalNumber("K_CURRENT_PLANET");
    if(nPlanet == 5)
    {
        return PLANET_ENDAR_SPIRE;
    }
    else if(nPlanet == 10)
    {
        return PLANET_TARIS;
    }
    else if(nPlanet == 15)
    {
        return PLANET_DANTOOINE;
    }
    else if(nPlanet == 20)
    {
        return PLANET_KASHYYYK;
    }
    else if(nPlanet == 25)
    {
        return PLANET_MANAAN;
    }
    else if(nPlanet == 30)
    {
        return PLANET_KORRIBAN;
    }
    else if(nPlanet == 35)
    {
        return PLANET_TATOOINE;
    }
    else if(nPlanet == 40)
    {
        return PLANET_LEVIATHAN;
    }
    else if(nPlanet == 45)
    {
        return PLANET_UNKNOWN_WORLD;
    }
    else if(nPlanet == 50)
    {
        return PLANET_STAR_FORGE;
    }
    return -1;
}
//::///////////////////////////////////////////////
//:: Get Planet Constant
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Uses K_FUTURE_PLANET to return the current
    planets scripting constant
    0    Endar Spire     5
    1    Taris           10
    2    Dantooine       15
    3    --Kashyyk       20
    4    --Manaan        25
    5    --Korriban      30
    6    --Tatooine      35
    7    Leviathan       40
    8    Unknown World   45
    9    Star Forge      50
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 1, 2002
//:://////////////////////////////////////////////
int EBO_GetFuturePlanet()
{
    int nPlanet = GetGlobalNumber("K_FUTURE_PLANET");
    if(nPlanet == 5)
    {
        return PLANET_ENDAR_SPIRE;
    }
    else if(nPlanet == 10)
    {
        return PLANET_TARIS;
    }
    else if(nPlanet == 15)
    {
        return PLANET_DANTOOINE;
    }
    else if(nPlanet == 20)
    {
        return PLANET_KASHYYYK;
    }
    else if(nPlanet == 25)
    {
        return PLANET_MANAAN;
    }
    else if(nPlanet == 30)
    {
        return PLANET_KORRIBAN;
    }
    else if(nPlanet == 35)
    {
        return PLANET_TATOOINE;
    }
    else if(nPlanet == 40)
    {
        return PLANET_LEVIATHAN;
    }
    else if(nPlanet == 45)
    {
        return PLANET_UNKNOWN_WORLD;
    }
    else if(nPlanet == 50)
    {
        return PLANET_STAR_FORGE;
    }
    else if(nPlanet == 55)
    {
        return PLANET_LIVE_01;
    }
    else if(nPlanet == 60)
    {
        return PLANET_LIVE_02;
    }
    else if(nPlanet == 65)
    {
        return PLANET_LIVE_03;
    }
    else if(nPlanet == 70)
    {
        return PLANET_LIVE_04;
    }
    else if(nPlanet == 75)
    {
        return PLANET_LIVE_05;
    }
    return -1;
}
int EBO_GetPlanetFrom2DA(int nPlanetIndex)
{
/*Scripting Constants              2DA Values
int PLANET_ENDAR_SPIRE      = 0;   0          Endar_Spire
int PLANET_TARIS            = 1;   1          Taris
int PLANET_EBON_HAWK        = 2;   2          Ebon_Hawk
int PLANET_DANTOOINE        = 3;   3          Dantooine
int PLANET_TATOOINE         = 4;   4          Tatooine
int PLANET_KASHYYYK         = 5;   5          Kashyyyk
int PLANET_MANAAN           = 6;   6          Manaan
int PLANET_KORRIBAN         = 7;   7          Korriban
int PLANET_LEVIATHAN        = 8;   8          Leviathan
int PLANET_UNKNOWN_WORLD    = 9;   9          Unknown_World
int PLANET_STAR_FORGE       = 10;  10         Star_Forge
Plot Values
0    Endar Spire     5
1    Taris           10
3    Dantooine       15
5    --Kashyyk       20
6    --Manaan        25
7    --Korriban      30
4    --Tatooine      35
8    Leviathan       40
9    Unknown World   45
10   Star Forge      50
*/
    if(nPlanetIndex == PLANET_ENDAR_SPIRE)
    {
        return 5;
    }
    else if(nPlanetIndex == PLANET_TARIS)
    {
        return 10;
    }
    else if(nPlanetIndex == PLANET_EBON_HAWK)
    {
        return -1;
    }
    else if(nPlanetIndex == PLANET_DANTOOINE)
    {
        return 15;
    }
    else if(nPlanetIndex == PLANET_TATOOINE)
    {
        return 35;
    }
    else if(nPlanetIndex == PLANET_KASHYYYK)
    {
        return 20;
    }
    else if(nPlanetIndex == PLANET_MANAAN)
    {
        return 25;
    }
    else if(nPlanetIndex == PLANET_KORRIBAN)
    {
        return 30;
    }
    else if(nPlanetIndex == PLANET_LEVIATHAN)
    {
        return 40;
    }
    else if(nPlanetIndex == PLANET_UNKNOWN_WORLD)
    {
        return 45;
    }
    else if(nPlanetIndex == PLANET_STAR_FORGE)
    {
        return 50;
    }
    else if(nPlanetIndex == PLANET_LIVE_01)
    {
        return 55;
    }
    else if(nPlanetIndex == PLANET_LIVE_02)
    {
        return 60;
    }
    else if(nPlanetIndex == PLANET_LIVE_03)
    {
        return 65;
    }
    else if(nPlanetIndex == PLANET_LIVE_04)
    {
        return 70;
    }
    else if(nPlanetIndex == PLANET_LIVE_05)
    {
        return 75;
    }
    return -1;
}
//::///////////////////////////////////////////////
//:: Start Render/Stunt Sequence
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Starts the correct sequence based on the
    planet being traveled to.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 9, 2002
//:://////////////////////////////////////////////
void EBO_PlayRenderSequence()
{
    int nSelected = GetSelectedPlanet();
    nSelected = EBO_GetPlanetFrom2DA(nSelected);
    SetGlobalNumber("K_FUTURE_PLANET", nSelected);
    int nCurrent = GetGlobalNumber("K_CURRENT_PLANET");
}
//::///////////////////////////////////////////////
//:: Should Bastila Start Vision Conversation
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This function returns true if bastila should
    start a cutscene dialogue with the PC
    You can use k_vis_[PLANET] == FALSE to see
    if they have been their before and seen the
    planet vision. This applies to Dantooine,
    Manaan, Korriban, Tatooine and Kashyyyk.
    Also set the script so that if Ebon_Vision !=99
    then it fires the dialog file ebo_bast_vision
    and has Bastila init dialog on the Ebon Hawk.
    (If Ebon_Vision==99 the dialog will not fire,
    but it should still play the vision.
    15 to 35
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 3, 2002
//:://////////////////////////////////////////////
int EBO_ShouldBastilaStartConversation()
{
    int nPlanet = GetGlobalNumber("K_CURRENT_PLANET");
    int nVision = GetGlobalNumber("Ebon_Vision");
    int nFLAG = FALSE;
    if( (nPlanet == 15 || nPlanet == 20 || nPlanet == 25 || nPlanet == 30 || nPlanet == 35) && nVision != 99)
    {
        //object oBast = GetNearestObjectByTag("Bastila");
        //if(GetIsObjectValid(oBast))
        //{
            if(nPlanet == 15 && !GetGlobalBoolean("k_vis_dantooine"))
            {
                nFLAG = TRUE;
                SetGlobalBoolean("k_vis_dantooine",1);
            }
            else if(nPlanet == 20 && !GetGlobalBoolean("k_vis_kashyyyk"))
            {
                nFLAG = TRUE;
                SetGlobalBoolean("k_vis_kashyyyk",1);
            }
            else if(nPlanet == 25 && !GetGlobalBoolean("k_vis_manaan"))
            {
                nFLAG = TRUE;
                SetGlobalBoolean("k_vis_manaan",1);
            }
            else if(nPlanet == 30 && !GetGlobalBoolean("k_vis_korriban"))
            {
                nFLAG = TRUE;
                SetGlobalBoolean("k_vis_korriban",1);
            }
            else if(nPlanet == 35 && !GetGlobalBoolean("k_vis_tatooine"))
            {
                nFLAG = TRUE;
                SetGlobalBoolean("k_vis_tatooine",1);
            }
            if(nFLAG == TRUE)
            {
                //AurPostString("k_vis_kashyyyk = " + IntToString(GetGlobalBoolean("k_vis_kashyyyk")), 5, 6, 3.0);
                //AurPostString("k_vis_manaan = " + IntToString(GetGlobalBoolean("k_vis_manaan")), 5, 7, 3.0);
                //AurPostString("k_vis_korriban = " + IntToString(GetGlobalBoolean("k_vis_korriban")), 5, 8, 3.0);
                //AurPostString("k_vis_tatooine = " + IntToString(GetGlobalBoolean("k_vis_tatooine")), 5, 9, 3.0);
                return TRUE;
                //HoldWorldFadeInForDialog();
                //object oPC = GetFirstPC();
                //AssignCommand(oBast, ActionStartConversation(oPC, "ebo_bast_vision", FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE));
            }
        //}
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Bastila Start Conversation
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 17,
//:://////////////////////////////////////////////
void EBO_BastilaStartConversation2()
{
    object oPC = GetFirstPC();
    object oBast = GetNearestObjectByTag("Bastila_Starter");
    if(GetIsObjectValid(oBast))
    {
        //AurPostString("Ebon_Vision = " + IntToString(GetGlobalNumber("Ebon_Vision")), 5, 6, 4.0);
        //AurPostString("Firing Bastila's Conversation", 5, 7, 4.0);
        AssignCommand(oBast, ActionStartConversation(oPC, "ebo_bast_vision", FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE, "Bastila"));
    }
}
""",
    "k_inc_end": b"""#include "k_inc_utility"
#include "k_inc_generic"
string sTraskTag = "end_trask";
string sTraskWP = "endwp_tarsk01";
string sCarthTag = "Carth";
string SOLDIER_WEAPON = "g_w_blstrrfl001";
string SOLDIER_ITEM01 = "g_i_adrnaline003";
string SOLDIER_ITEM02 = "";
string SCOUT_WEAPON = "g_w_blstrpstl001";
string SCOUT_ITEM01 = "g_i_adrnaline002";
string SCOUT_ITEM02 = "g_i_implant101";
string SCOUNDREL_WEAPON = "g_w_blstrpstl001";
string SCOUNDREL_ITEM01 = "g_i_secspike01";
string SCOUNDREL_ITEM02 = "g_i_progspike01";
int ROOM3_DEAD = 3;
int ROOM5_DEAD = 4;
int ROOM7_DEAD = 2;
int TRASK_DEFAULT = -1;
int TRASK_MUST_GET_GEAR = 0;
int TRASK_GEAR_DONE = 1;
int TRASK_TARGET_DONE = 2;
int TRASK_MUST_EQUIP = 3;
int TRASK_EQUIP_DONE = 4;
int TRASK_MUST_MAP = 5;
int TRASK_MAP_DONE = 6;
int TRASK_MUST_SWITCH = 7;
int TRASK_SWITCH_DONE = 8;
int TRASK_SWITCH_REMIND = 9;
int TRASK_CARTH_BRIDGE = 10;
int TRASK_BRIDGE_DONE = 11;
int TRASK_MUST_DOOR = 12;
int TRASK_DOOR_DONE = 13;
int TRASK_ROOM3_DONE = 14;
int TRASK_MUST_MEDPACK = 15;
int TRASK_COMBAT_WARNING = 16;
int TRASK_COMBAT_WARNING2 = 17;
int TRASK_COMPUTER_DONE = 18;
int TRASK_MUST_DROID = 19;
int TRASK_DROID_DONE = 20;
int TRASK_MUST_MAP_02 = 21;
int TRASK_NOTHING_02 = 22;
//int TRASK_COMBAT_WARNING = 27;
int TRASK_LEVEL_INIT = 28;
int TRASK_MUST_LEVEL = 29;
int TRASK_PARTY_LEVEL = 30;
int TRASK_LEVEL_DONE = 31;
string LOCKER_TAG = "end_locker01";
string STEALTH_UNIT = "g_i_belt010";
//returns Trask's object id
object GetTrask();
// checks if the conditions for passing the healing stage have been met
int HealingDone();
// returns Carth's object id
object GetCarth();
// checks if this has never been done before. uses sw 10
int HasNeverTriggered();
// Has Trask initiate with the pc at any distance
void TalkTrask();
// returns the effect from the corridor explosion
effect CorridorExplosion();
//spawns equipment into the first locker dependent on the players class
void SpawnStartingEquipment();
// returns if the door has been sliced (uses plot 2)
int GetIsSecureDoorSliced(object oDoor = OBJECT_SELF);
// sets the slice state of the door (uses plot 2)
void SetSecureDoorSliced(int bState, object oDoor = OBJECT_SELF);
// returns if the door has been repaired (uses plot 3)
int GetIsDamagedDoorRepaired(object oDoor = OBJECT_SELF);
// sets the repaired state of the door (uses plot 3)
void SetDamagedDoorRepaired(int bState, object oDoor = OBJECT_SELF);
// returns the value of the trask dialouge state global
int GetTraskState();
//sets the trask dialouge global
void SetTraskState(int nValue);
// returns true if there is somethin equipped in the weapon or body slots
int GetHasEquippedSomething();
// Checks if Trask is already waiting to initiate
int GetTraskWillInitiate();
// Sets the flag for Trask waiting to initiate
void SetTraskWillInitiate(int nValue);
//returns Carth dialgue state
int GetCarthState();
//sets Carth dialogue state
void SetCarthState(int nValue);
// plays an explosion
void PlayExplosion(string sWP = "end_explode01", int bWithShake = TRUE, int bWithRumble = TRUE);
//returns a cutscene invisible placeable based on the given number
object GetCutsceneObject(int nObjectNumber);
//////////////////////////////////////////////////////////////////////////
object GetTrask()
{
    return GetObjectByTag(sTraskTag);
}
int HealingDone()
{
    int bDone;
    object oPC = GetFirstPC();
    int bHasMedPack = GetIsObjectValid(GetItemPossessedBy(oPC,"g_i_medeqpmnt01"));
    int bFullHitPoints = GetCurrentHitPoints(oPC) == GetMaxHitPoints(oPC);
    if(bFullHitPoints || bHasMedPack == FALSE)
    {
        bDone = TRUE;
    }
    return bDone;
}
object GetCarth()
{
    return GetObjectByTag("Carth");
}
int HasNeverTriggered()
{
    int bReturn;
    if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_10) == FALSE)
    {
        bReturn = TRUE;
        UT_SetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_10,TRUE);
    }
    return bReturn;
}
void TalkTrask()
{
    object oTrask = GetTrask();
    if(GetPartyMemberByIndex(0) == oTrask)
    {
        SetPartyLeader(NPC_PLAYER);
    }
   // AurPostString("Trask trying to talk" + IntToString(GetTraskState()),5,5,5.0);
    NoClicksFor(0.5);
    DelayCommand(0.1,SignalEvent(oTrask,EventUserDefined(50)));
}
effect CorridorExplosion()
{
    effect eZap = EffectBeam(VFX_BEAM_LIGHTNING_DARK_L,GetObjectByTag("end_zap01"),BODY_NODE_CHEST);
    return EffectLinkEffects(EffectDamage(5),eZap);
}
object GetSpeaker()
{
    return GetPartyMemberByIndex(1);
}
object GetListener()
{
    return GetPartyMemberByIndex(0);
}
void SpawnStartingEquipment()
{
    object oLocker = GetObjectByTag(LOCKER_TAG);
    int nClass = GetClassByPosition(1,GetFirstPC());
    if(nClass == CLASS_TYPE_SCOUNDREL)
    {
        CreateItemOnObject(SCOUNDREL_WEAPON,oLocker);
        CreateItemOnObject(SCOUNDREL_ITEM01,oLocker);
        CreateItemOnObject(SCOUNDREL_ITEM02,oLocker);
    }
    else if(nClass == CLASS_TYPE_SCOUT)
    {
        CreateItemOnObject(SCOUT_WEAPON,oLocker);
        CreateItemOnObject(SCOUT_ITEM01,oLocker);
        CreateItemOnObject(SCOUT_ITEM02,oLocker);
    }
    else if(nClass == CLASS_TYPE_SOLDIER)
    {
        CreateItemOnObject(SOLDIER_WEAPON,oLocker);
        CreateItemOnObject(SOLDIER_ITEM01,oLocker);
        CreateItemOnObject(SOLDIER_ITEM02,oLocker);
    }
    if(GetHasSkill(SKILL_STEALTH,GetFirstPC()))
    {
        CreateItemOnObject(STEALTH_UNIT,oLocker);
    }
}
int GetIsSecureDoorSliced(object oDoor = OBJECT_SELF)
{
    return UT_GetPlotBooleanFlag(oDoor,SW_PLOT_BOOLEAN_02);
}
void SetSecureDoorSliced(int bState, object oDoor = OBJECT_SELF)
{
    UT_SetPlotBooleanFlag(oDoor,SW_PLOT_BOOLEAN_02,bState);
}
int GetIsDamagedDoorRepaired(object oDoor = OBJECT_SELF)
{
    return UT_GetPlotBooleanFlag(oDoor,SW_PLOT_BOOLEAN_03);
}
void SetDamagedDoorRepaired(int bState, object oDoor = OBJECT_SELF)
{
    UT_SetPlotBooleanFlag(oDoor,SW_PLOT_BOOLEAN_03,bState);
}
int GetTraskState()
{
    return GetGlobalNumber("END_TRASK_DLG");
}
void SetTraskState(int nValue)
{
  //  AurPostString("New State" + IntToString(nValue),5,7,2.0);
    SetGlobalNumber("END_TRASK_DLG",nValue);
   // AurPostString("Set: " + IntToString(nValue),5,10,3.0);
}
int GetHasEquippedSomething()
{
    int bItemEquipped = FALSE;
    object oPC = GetFirstPC();
    if(GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON,oPC)) ||
       GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_LEFTWEAPON,oPC)) ||
       GetIsObjectValid(GetItemInSlot(INVENTORY_SLOT_BODY,oPC)) )
    {
            bItemEquipped = TRUE;
    }
    return bItemEquipped;
}
int GetTraskWillInitiate()
{
    return UT_GetPlotBooleanFlag(GetTrask(),SW_PLOT_BOOLEAN_03);
}
void SetTraskWillInitiate(int nValue)
{
    UT_SetPlotBooleanFlag(GetTrask(),SW_PLOT_BOOLEAN_03,nValue);
}
int GetCarthState()
{
    return GetGlobalNumber("END_CARTH_DLG");
}
void SetCarthState(int nValue)
{
    SetGlobalNumber("END_CARTH_DLG",nValue);
}
void PlayExplosion(string sWP = "end_explode01", int bWithShake = TRUE, int bWithRumble = TRUE)
{
    location lExplode = GetLocation(GetNearestObjectByTag(sWP));
    effect eExplode = EffectVisualEffect(VFX_FNF_GRENADE_FRAGMENTATION);
    effect eShake = EffectVisualEffect(VFX_IMP_SCREEN_SHAKE);
    ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eExplode,lExplode);
    if(bWithShake)
    {
        ApplyEffectToObject(DURATION_TYPE_INSTANT,eShake,GetFirstPC());
    }
    if(bWithRumble)
    {
        PlayRumblePattern(14);
    }
}
object GetCutsceneObject(int nObjectNumber)
{
    return GetObjectByTag("end01_sceneobj0" + IntToString(nObjectNumber));
}
""",
    "k_inc_endgame": b"""//::///////////////////////////////////////////////
//:: Name k_inc_endgame
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
     This include houses all of the stunt/render
     calls for the end game. This will be for
     modules sta_m45ac and sta_m45ad.
*/
//:://////////////////////////////////////////////
//:: Created By: Brad Prince
//:: Created On: Mar 6, 2003
//:://////////////////////////////////////////////
///////////////////////
// LIGHT SIDE scenes //
///////////////////////
// SCENE 1 BO2 - Player kills Bastila on sta_m45ac
void ST_PlayBastilaLight();
// SCENE 2 C01 - Player returns after watching SCENE 1.
void ST_PlayReturnToStarForgeLight();
// SCENE 3 A - Star Forge under attack.
void ST_PlayStarForgeUnderAttack();
// SCENE 4 B - End game credits - Light.
void ST_PlayEndCreditsLight();
//////////////////////////////////////////////////
//////////////////////
// DARK SIDE scenes //
//////////////////////
// SCENE 1 B01 - Bastila leaves party to meditate before generator puzzle.
void ST_PlayBastilaDark();
// SCENE 2 C - Player returns after watching SCENE 1.
void ST_PlayReturnToStarForgeDark();
// SCENE 3 A - The Republic dies.
void ST_PlayRepublicDies();
// SCENE 4 B - The Sith Ceremony.
void ST_PlaySithCeremony();
// SCENE 5 C - End game credits - Dark.
void ST_PlayEndCreditsDark();
//////////////////////////////////////////////////
//                  FUNCTIONS                   //
//////////////////////////////////////////////////
///////////////////////
// LIGHT SIDE scenes //
///////////////////////
// SCENE 1 BO2 - Player kills Bastila on sta_m45ac
void ST_PlayBastilaLight()
{
    StartNewModule("STUNT_50a","", "50b");
}
// SCENE 2 C01 - Player returns after watching SCENE 1.
void ST_PlayReturnToStarForgeLight()
{
    StartNewModule("sta_m45ac","K_LAST_LOCATION", "50");
}
// SCENE 3 A - Star Forge under attack.
void ST_PlayStarForgeUnderAttack()
{
    StartNewModule("STUNT_56a","", "56");
}
// SCENE 4 B - End game credits - Light.
void ST_PlayEndCreditsLight()
{
    StartNewModule("STUNT_57","", "56b");
}
//////////////////////////////////////////////////
//////////////////////
// DARK SIDE scenes //
//////////////////////
// SCENE 1 B01 - Bastila leaves party to meditate before generator puzzle.
void ST_PlayBastilaDark()
{
    StartNewModule("STUNT_51a","", "54");
}
// SCENE 2 C - Player returns after watching SCENE 1.
void ST_PlayReturnToStarForgeDark()
{
    StartNewModule("sta_m45ac","sta_bast_pc_move0", "51b");
}
// SCENE 3 A - The Republic dies.
void ST_PlayRepublicDies()
{
    StartNewModule("STUNT_54a","", "51");
}
// SCENE 4 B - The Sith Ceremony.
void ST_PlaySithCeremony()
{
    StartNewModule("STUNT_55a","", "54b");
}
// SCENE 5 C - End game credits - Dark.
void ST_PlayEndCreditsDark()
{
    StartNewModule("STUNT_57","", "56b");
}
""",
    "k_inc_force": b"""//:: k_inc_force
/*
    v1.0
    Force Powers Include for KOTOR
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
float fLightningDuration = 1.0;
//These variables are set in the script run area.
int SWFP_PRIVATE_SAVE_TYPE;
int SWFP_PRIVATE_SAVE_VERSUS_TYPE;
int SWFP_DAMAGE;
int SWFP_DAMAGE_TYPE;
int SWFP_DAMAGE_VFX;
int SWFP_HARMFUL;
int SWFP_SHAPE;
//Runs the script section for the particular force power.
void  Sp_RunForcePowers();
//Immunity and Resist Spell check for the force power.
//The eDamage checks whether the target is immune to the damage effect
int Sp_BlockingChecks(object oTarget, effect eEffect, effect eEffect2, effect eDamage);
//Makes the necessary saving throws
int Sp_MySavingThrows(object oTarget);
//Remove an effect of a specific type
void Sp_RemoveSpecificEffect(int nEffectTypeID, object oTarget);
//Remove an effect from a specific force power.
void Sp_RemoveSpellEffects(int nSpell_ID, object oCaster, object oTarget);
// Delays the application of a spell effect by an amount determined by distance.
float Sp_GetSpellEffectDelay(location SpellTargetLocation, object oTarget);
//Randomly delays the effect application for a default of 0.0 to 0.75 seconds
float Sp_GetRandomDelay(float fMinimumTime = 0.0, float MaximumTime = 0.75);
//Gets a saving throw appropriate to the jedi using the force power.
int Sp_GetJediDCSave();
///Apply effects in a sphere shape.
void Sp_SphereSaveHalf(object oAnchor, float fSize, int nCounter, effect eLink1, float fDuration1, effect eLink2, float fDuration);
//Apply effects to a single target.
void Sp_SingleTarget(object oAnchor, effect eLink1, float fDuration1, effect eLink2, float fDuration2);
//Apply effect to an area and negate on a save.
void Sp_SphereBlocking(object oAnchor, float fSize, int nCounter, effect eLink1, float fDuration1, effect eLink2, float fDuration);
// /Apply effect to an object and negate on a save.
void Sp_SingleTargetBlocking(object oAnchor, effect eLink1, float fDuration1, effect eLink2, float fDuration2);
//Apply effects for a for power.
void Sp_ApplyForcePowerEffects(float fTime, effect eEffect, object oTarget);
//Apply effects to targets.
void Sp_ApplyEffects(int nBlocking, object oAnchor, float fSize, int nCounter, effect eLink1, float fDuration1, effect eLink2, float fDuration2, int nRacial = RACIAL_TYPE_ALL);
//Removes all effects from the spells , Knights Mind, Mind Mastery and Battle Meditation
void Sp_RemoveBuffSpell();
//Prints a string for the spell stript
void SP_MyPrintString(string sString);
//Posts a string for the spell script
void SP_MyPostString(string sString, int n1 = 5, int n2 = 10, float fTime = 4.0);
//Interates through given a time period and a damage amount and hurts someone.  Checks if the person is in conversation.
void SP_InterativeDamage(effect eDamage, int nSecondsRemaining, object oTarget);
//Checks to see if the target is a Turret
int SP_CheckAppearanceTurret(object oTarget, int nFeedback = FALSE);
//Checks to see if the target is a Mark 1, 2, 4 or Spyder Droid
int SP_CheckAppearanceGeoDroid(object oTarget);
//Checks if the character already has Energy Resistance and Improved Energy Resistance
int SP_CheckEnergyResistance(object oTarget);
//This checks all of the delayed effect applications to make sure the target is still hostile and has not surrendered
void SP_MyApplyEffectToObject(int nDurationType, effect eEffect, object oTarget, float fDuration=0.0);
//Checks droids appearance type and if they have shields up
int SP_CheckAppearanceGeoDroidShields(object oTarget, int nFeedback = FALSE);
//Check push compatibility, if true is passed in for the Whirlwind an addition check for shields is made
int SP_CheckForcePushViability(object oTarget, int Whirlwind);
//Removes the spell's effects regardless of caster
void Sp_RemoveSpellEffectsGeneral(int nSpell_ID, object oTarget);
//::///////////////////////////////////////////////
//:: Apply Delayed Effect
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This checks all of the delayed effect applications
    to make sure the target is still hostile and has
    not surrendered
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 20, 2003
//:://////////////////////////////////////////////
void SP_MyApplyEffectToObject(int nDurationType, effect eEffect, object oTarget, float fDuration=0.0)
{
    if(GetIsEnemy(oTarget))
    {
        ApplyEffectToObject(nDurationType, eEffect, oTarget, fDuration);
    }
}
//::///////////////////////////////////////////////
//:: Interative Damage
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Interates through given a time period and a
    damage amount and hurts someone.  Checks if
    the person is in conversation.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 5, 2003
//:://////////////////////////////////////////////
void SP_InterativeDamage(effect eDamage, int nSecondsRemaining, object oTarget)
{
    if(GetIsObjectValid(oTarget))
    {
        if(!GetIsConversationActive() && !GetIsDead(oTarget) && GetIsEnemy(oTarget))
        {
             if (nSecondsRemaining % 2 == 0)
             {
                  ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
             }
             --nSecondsRemaining;
             if (nSecondsRemaining > 0)
             {
                DelayCommand(1.0f, SP_InterativeDamage(eDamage, nSecondsRemaining, oTarget));
             }
        }
    }
}
//::///////////////////////////////////////////////
//:: Blocking Checks
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Does the Spell Resistance and Immunity
    Checks
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 15, 2002
//:://////////////////////////////////////////////
int Sp_BlockingChecks(object oTarget, effect eEffect1, effect eEffect2, effect eDamage)
{
    int nReturn = FALSE;
    //MODIFIED by Preston Watamaniuk on April 11th
    //Put the immunity check in place for Force Powers.
    if(GetIsLinkImmune(oTarget, eEffect1) || GetIsLinkImmune(oTarget, eEffect2) || GetIsLinkImmune(oTarget, eDamage))
    {
        DisplayFeedBackText(oTarget, 1);
        nReturn = TRUE;
    }
    if(ResistForce(OBJECT_SELF, oTarget))
    {
        DisplayFeedBackText(oTarget, 0);
        nReturn = TRUE;
    }
    if(nReturn == TRUE)
    {
        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
    }
    return nReturn;
}
int Sp_MySavingThrows(object oTarget)
{
    int nSave;
    if(SWFP_PRIVATE_SAVE_TYPE == SAVING_THROW_FORT)
    {
        nSave = FortitudeSave(oTarget, Sp_GetJediDCSave(), SWFP_PRIVATE_SAVE_VERSUS_TYPE);
        SP_MyPrintString("Fort Save = " + IntToString(nSave) + " For DC of " + IntToString(Sp_GetJediDCSave()));
    }
    else if(SWFP_PRIVATE_SAVE_TYPE == SAVING_THROW_REFLEX)
    {
        nSave = ReflexSave(oTarget, Sp_GetJediDCSave(), SWFP_PRIVATE_SAVE_VERSUS_TYPE);
        SP_MyPrintString("Reflex Save = " + IntToString(nSave)+" For DC of " + IntToString(Sp_GetJediDCSave()));
    }
    else if(SWFP_PRIVATE_SAVE_TYPE == SAVING_THROW_WILL)
    {
        nSave = WillSave(oTarget, Sp_GetJediDCSave(), SWFP_PRIVATE_SAVE_VERSUS_TYPE);
        SP_MyPrintString("Will Save = " + IntToString(nSave)+" For DC of " + IntToString(Sp_GetJediDCSave()));
    }
    if(nSave > 0)
    {
        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
        DisplayFeedBackText(oTarget, 2);
    }
    return nSave;
}
void Sp_RemoveSpellEffects(int nSpell_ID, object oCaster, object oTarget)
{
    //Declare major variables
    int bValid = FALSE;
    effect eAOE;
    if(GetHasSpellEffect(nSpell_ID, oTarget))
    {
        //Search through the valid effects on the target.
        eAOE = GetFirstEffect(oTarget);
        while (GetIsEffectValid(eAOE) && bValid == FALSE)
        {
            //
            if (GetEffectCreator(eAOE) == oCaster)
            {
                //If the effect was created by the spell then remove it
                if(GetEffectSpellId(eAOE) == nSpell_ID)
                {
                    RemoveEffect(oTarget, eAOE);
                    bValid = TRUE;
                }
            }
            //Get next effect on the target
            eAOE = GetNextEffect(oTarget);
        }
    }
}
void Sp_RemoveSpellEffectsGeneral(int nSpell_ID, object oTarget)
{
    //Declare major variables
    int bValid = FALSE;
    effect eAOE;
    if(GetHasSpellEffect(nSpell_ID, oTarget))
    {
        //Search through the valid effects on the target.
        eAOE = GetFirstEffect(oTarget);
        while (GetIsEffectValid(eAOE) && bValid == FALSE)
        {
            //If the effect was created by the spell then remove it
            if(GetEffectSpellId(eAOE) == nSpell_ID)
            {
                RemoveEffect(oTarget, eAOE);
                bValid = TRUE;
            }
            //Get next effect on the target
            eAOE = GetNextEffect(oTarget);
        }
    }
}
void Sp_RemoveSpecificEffect(int nEffectTypeID, object oTarget)
{
    //Declare major variables
    //Get the object that is exiting the AOE
    int bValid = FALSE;
    effect eAOE;
    //Search through the valid effects on the target.
    eAOE = GetFirstEffect(oTarget);
    while (GetIsEffectValid(eAOE))
    {
        if (GetEffectType(eAOE) == nEffectTypeID)
        {
            //If the effect was created by the spell then remove it
            bValid = TRUE;
            RemoveEffect(oTarget, eAOE);
        }
        //Get next effect on the target
        eAOE = GetNextEffect(oTarget);
    }
}
float Sp_GetSpellEffectDelay(location SpellTargetLocation, object oTarget)
{
    float fDelay;
    return fDelay = GetDistanceBetweenLocations(SpellTargetLocation, GetLocation(oTarget))/20;
}
float Sp_GetRandomDelay(float fMinimumTime = 0.4, float MaximumTime = 1.1)
{
    float fRandom = MaximumTime - fMinimumTime;
    int nRandom;
    if(fRandom < 0.0)
    {
        return 0.0;
    }
    else
    {
        nRandom = FloatToInt(fRandom  * 10.0);
        nRandom = Random(nRandom) + 1;
        fRandom = IntToFloat(nRandom);
        fRandom /= 10.0;
        return fRandom + fMinimumTime;
    }
}
int Sp_GetJediDCSave()
{
    int nDC = GetSpellSaveDC();
    return nDC;
}
void Sp_ApplyForcePowerEffects(float fTime, effect eEffect, object oTarget)
{
    float fDelay;
    int nRoll = d6();
    fDelay = IntToFloat(nRoll)/10.0;
    if(fTime == 1000.0)
    {
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
    }
    else if(fTime == 0.0)
    {
        DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget));
    }
    else
    {
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oTarget, fTime);
    }
}
int SP_CheckEnergyResistance(object oTarget)
{
    if(GetHasSpellEffect(FORCE_POWER_RESIST_COLD_HEAT_ENERGY, oTarget) || GetHasSpellEffect(FORCE_POWER_RESIST_POISON_DISEASE_SONIC, oTarget))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Runs the specified force power.
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Runs the script for the particular force power.
    SWFP_HARMFUL = ;
    SWFP_PRIVATE_SAVE_TYPE;
    SWFP_PRIVATE_SAVE_VERSUS_TYPE;
    SWFP_DAMAGE;
    SWFP_DAMAGE_TYPE;
    SWFP_DAMAGE_VFX;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 30, 2002
//:://////////////////////////////////////////////
void  Sp_RunForcePowers()
{
    object oTarget = GetSpellTargetObject();
    effect eLink1, eLink2;
    effect eInvalid;
    SWFP_SHAPE = SHAPE_SPHERE;
    //P.W. (June 8) This makes the Taris Calo Nord immune to Force Push, breaks the cutscene if not.
    if(GetTag(oTarget) == "Calo082" && GetSpellId() == FORCE_POWER_FORCE_PUSH)
    {
        DisplayFeedBackText(oTarget, 1);
        return;
    }
    switch (GetSpellId())
    {
        /*
        AFFLICTION
        */
        case FORCE_POWER_AFFLICTION:
        {
            /*
            SWFP_HARMFUL = TRUE;
            eLink1 = EffectPoison(POISON_ABILITY_SCORE_AVERAGE);
            effect eLink3 = EffectLinkEffects(eLink1, EffectMovementSpeedDecrease(50));
            eLink3 = SetEffectIcon(eLink3, 1);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink1, oTarget);
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink3, oTarget, 21.0);
            */
            SWFP_HARMFUL = TRUE;
            eLink1 = EffectPoison(POISON_ABILITY_SCORE_AVERAGE);
            eLink1 = EffectLinkEffects(eLink1, EffectMovementSpeedDecrease(50));
            eLink1 = SetEffectIcon(eLink1, 23);
            if(!GetIsPoisoned(oTarget))
            {
                Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 1000.0, eInvalid, 0.0);
            }
        }
        break;
        /*
        CHOKE
        */
        case FORCE_POWER_CHOKE:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            SWFP_DAMAGE = (GetHitDice(OBJECT_SELF)*2)/3;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            SWFP_DAMAGE_VFX = VFX_IMP_CHOKE;
            eLink1 = EffectAbilityDecrease(ABILITY_CONSTITUTION, 4);
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityDecrease(ABILITY_STRENGTH, 4));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityDecrease(ABILITY_DEXTERITY, 4));
            eLink1 = SetEffectIcon(eLink1, 3);
            effect eChoke = EffectChoke();
            effect eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
            int nResist = Sp_BlockingChecks(oTarget, eChoke, eDamage, eInvalid);
            int nSaves;
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if(nResist == 0)
            {
                nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_CHOKE), oTarget);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eChoke, oTarget, 6.0);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 24.0);
                    int nIdx = 1;
                    float fDelay;
                    SP_InterativeDamage(eDamage, 7, oTarget);
                }
            }
            if(nResist > 0 || nSaves > 0)
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        /*
        CURE
        */
        //MODIFIED by Preston Watamaniuk March 28
        // Remove cure poison and reduced the amount by 5
        case FORCE_POWER_CURE:
        {
            SWFP_HARMFUL = FALSE;
            int nHeal = GetAbilityModifier(ABILITY_WISDOM) + GetAbilityModifier(ABILITY_CHARISMA) + 5 + GetHitDice(OBJECT_SELF);
            effect eVis =  EffectVisualEffect(VFX_IMP_CURE);
            int nCnt = 0;
            object oParty;
            if(IsObjectPartyMember(OBJECT_SELF))
            {
                oParty = GetPartyMemberByIndex(nCnt);
            }
            else
            {
                oParty = OBJECT_SELF;
            }
            while(nCnt < 3)
            {
                if(GetIsObjectValid(oParty) &&
                   GetRacialType(oParty) != RACIAL_TYPE_DROID &&
                   GetDistanceBetween(OBJECT_SELF, oParty) < 15.0)
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), FALSE));
                    //Sp_RemoveSpecificEffect(EFFECT_TYPE_POISON, oParty);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oParty);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHeal), oParty);
                }
                nCnt++;
                if(IsObjectPartyMember(OBJECT_SELF))
                {
                   oParty = GetPartyMemberByIndex(nCnt);
                }
                else
                {
                   oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt);
                }
            }
        }
        break;
        /*
        DEATH FIELD
        */
        case FORCE_POWER_DEATH_FIELD:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_DARK_SIDE;
            int nDamTest = GetHitDice(OBJECT_SELF);
            if(nDamTest > 10)
            {
                nDamTest = 10;
            }
            SWFP_DAMAGE = d4(nDamTest);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_DARK_SIDE;
            SWFP_DAMAGE_VFX = VFX_PRO_DEATH_FIELD;
            int nHealCount;
            int nDamage = SWFP_DAMAGE/2;
            effect eDamage;
            effect eBeam = EffectBeam(VFX_BEAM_DEATH_FIELD_TENTACLE, OBJECT_SELF, BODY_NODE_HEAD);
            effect eVFX = EffectVisualEffect(VFX_PRO_DEATH_FIELD);
            object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 12.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            while(GetIsObjectValid(oTarget))
            {
                int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eDamage);
                if((GetRacialType(oTarget) == RACIAL_TYPE_HUMAN &&
                   GetRacialType(oTarget) != RACIAL_TYPE_DROID) || GetObjectType(oTarget) == OBJECT_TYPE_PLACEABLE)
                {
                    if(GetIsEnemy(oTarget))
                    {
                        SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                        if(nResist == 0)
                        {
                            int nSaves = Sp_MySavingThrows(oTarget);
                            if(nSaves == FALSE)
                            {
                                eDamage =  EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                                nHealCount += SWFP_DAMAGE;
                            }
                            else
                            {
                                eDamage =  EffectDamage(nDamage, SWFP_DAMAGE_TYPE);
                                nHealCount += nDamage;
                            }
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, fLightningDuration);
                        }
                        else
                        {
                            //effect eBeam2 = EffectBeam(VFX_BEAM_DEATH_FIELD_TENTACLE, OBJECT_SELF, BODY_NODE_HEAD, TRUE);
                            //ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, fLightningDuration);
                        }
                    }
                }
                oTarget = GetNextObjectInShape(SHAPE_SPHERE, 12.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            }
            if(GetCurrentHitPoints(OBJECT_SELF) < GetMaxHitPoints(OBJECT_SELF) && nHealCount > 0)
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), OBJECT_SELF);
            }
        }
        break;
        /*
        DRAIN LIFE
        */
        case FORCE_POWER_DRAIN_LIFE:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            int nDam = GetHitDice(OBJECT_SELF);
            int nDamTest = GetHitDice(OBJECT_SELF);
            if(nDamTest > 10)
            {
                nDamTest = 10;
            }
            SWFP_DAMAGE = d4(nDamTest);
            SWFP_DAMAGE_TYPE= DAMAGE_TYPE_DARK_SIDE;
            SWFP_DAMAGE_VFX = VFX_PRO_DRAIN;
            //Set up the drain effect link for the target
            effect eBeam = EffectBeam(VFX_BEAM_DRAIN_LIFE, OBJECT_SELF, BODY_NODE_HAND);
            effect eVFX = EffectVisualEffect(SWFP_DAMAGE_VFX);
            //Set up the link to Heal the user by the same amount.
            effect eHeal;
            effect eDamage = EffectDamage(SWFP_DAMAGE, DAMAGE_TYPE_DARK_SIDE);
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, fLightningDuration);
            DelayCommand(0.3, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget));
            int nResist = Sp_BlockingChecks(oTarget, eDamage, eInvalid, eInvalid);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if(GetRacialType(oTarget) != RACIAL_TYPE_DROID)
            {
                if(nResist == 0)
                {
                    int nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves > 0)
                    {
                        SWFP_DAMAGE /= 2;
                    }
                    eDamage = EffectDamage(SWFP_DAMAGE,  DAMAGE_TYPE_DARK_SIDE);
                    if(GetCurrentHitPoints(OBJECT_SELF) < GetMaxHitPoints(OBJECT_SELF) && SWFP_DAMAGE > 0)
                    {
                        eHeal = EffectHeal(SWFP_DAMAGE);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, OBJECT_SELF);
                    }
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                }
            }
        }
        break;
        /*
        DESTROY DROID
        */
        case FORCE_POWER_DROID_DESTROY:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_ELECTRICAL;
            eLink1 = EffectBeam(VFX_BEAM_DROID_DESTROY, oTarget, BODY_NODE_CHEST);
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_PRO_LIGHTNING_L));
            eLink2 = EffectDroidStun();
            eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(1008));
            eLink2 = SetEffectIcon(eLink2, 5);
            effect eLink3 = EffectBeam(VFX_BEAM_DROID_DESTROY, OBJECT_SELF, BODY_NODE_HAND);
            eLink3 = EffectLinkEffects(eLink3, EffectVisualEffect(VFX_PRO_LIGHTNING_L));
            int nDamage = d6(GetHitDice(OBJECT_SELF));
            int nApply = nDamage/2;
            effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_ELECTRICAL);;
            effect eSaveDamage = EffectDamage(nApply, DAMAGE_TYPE_ELECTRICAL);
            //Apply Effects to the first droid targeted.
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
            int nSaves;
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink3, oTarget, fLightningDuration);
            if(nResist == 0)
            {
                nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage , oTarget);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, 12.0);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eSaveDamage , oTarget);
                }
            }
            else
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
            //Start going through all hostile droids around the primary target
            object oSecond = GetFirstObjectInShape(SHAPE_SPHERE, 6.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            while(GetIsObjectValid(oSecond))
            {
                if(oSecond != oTarget && GetIsEnemy(oSecond) && GetRacialType(oSecond) == RACIAL_TYPE_DROID)
                {
                    nResist = Sp_BlockingChecks(oSecond, eLink1, eLink2, eInvalid);
                    SignalEvent(oSecond, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    if(nResist == 0)
                    {
                        nSaves = Sp_MySavingThrows(oSecond);
                        //Apply the beam effect and hit regardless because damage is still done.
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oSecond, fLightningDuration);
                        if(nSaves == 0)
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage , oSecond);
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oSecond, 12.0);
                        }
                        else
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eSaveDamage , oSecond);
                        }
                    }
                }
                oSecond = GetNextObjectInShape(SHAPE_SPHERE, 6.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            }
        }
        break;
        /*
        DISABLE DROID
        */
        case FORCE_POWER_DROID_DISABLE:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_ELECTRICAL;
            eLink1 = EffectBeam(VFX_BEAM_DROID_DESTROY, oTarget, BODY_NODE_CHEST);
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_PRO_LIGHTNING_L));
            eLink2 = EffectDroidStun();
            eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(1008));
            eLink2 = SetEffectIcon(eLink2, 4);
            effect eLink3 = EffectBeam(VFX_BEAM_DROID_DISABLE, OBJECT_SELF, BODY_NODE_HAND);
            eLink3 = EffectLinkEffects(eLink3, EffectVisualEffect(VFX_PRO_LIGHTNING_L));
            int nDamage = GetHitDice(OBJECT_SELF);
            int nApply = nDamage/2;
            effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_ELECTRICAL);;
            effect eSaveDamage = EffectDamage(nApply, DAMAGE_TYPE_ELECTRICAL);
            //Apply Effects to the first droid targeted.
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
            int nSaves;
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink3, oTarget, fLightningDuration);
            if(nResist == 0)
            {
                nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage , oTarget);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, 12.0);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eSaveDamage , oTarget);
                }
            }
            else
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
            //Start going through all hostile droids around the primary target
            object oSecond = GetFirstObjectInShape(SHAPE_SPHERE, 5.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            while(GetIsObjectValid(oSecond))
            {
                if(oSecond != oTarget && GetIsEnemy(oSecond) && GetRacialType(oSecond) == RACIAL_TYPE_DROID)
                {
                    nResist = Sp_BlockingChecks(oSecond, eLink1, eLink2, eInvalid);
                    SignalEvent(oSecond, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    if(nResist == 0)
                    {
                        nSaves = Sp_MySavingThrows(oSecond);
                        //Apply the beam effect and hit regardless because damage is still done.
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oSecond, fLightningDuration);
                        if(nSaves == 0)
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage , oSecond);
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oSecond, 12.0);
                        }
                        else
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eSaveDamage , oSecond);
                        }
                    }
                }
                oSecond = GetNextObjectInShape(SHAPE_SPHERE, 5.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            }
        }
        break;
        /*
        STUN DROID
        */
        case FORCE_POWER_DROID_STUN:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_ELECTRICAL;
            SWFP_DAMAGE = GetHitDice(OBJECT_SELF);
            SWFP_DAMAGE_TYPE= DAMAGE_TYPE_ELECTRICAL;
            eLink1 = EffectBeam(2065, OBJECT_SELF, BODY_NODE_HAND); //P.W.(May 19, 2003) New Droid Stun Beam Effect added
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_PRO_LIGHTNING_S));
            eLink2 = EffectDroidStun();
            eLink2 = SetEffectIcon(eLink2, 30);
            eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(1007));  //P.W.(May 19, 2003) Linked the smoke to Link 2
            effect eDamage;
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fLightningDuration);
            if(nResist == 0)
            {
                int nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    eDamage = EffectDamage(SWFP_DAMAGE, DAMAGE_TYPE_ELECTRICAL);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, 12.0);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                }
                else
                {
                    eDamage = EffectDamage(SWFP_DAMAGE/2, DAMAGE_TYPE_ELECTRICAL);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                }
            }
            else
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        /*
        FEAR
        */
        case FORCE_POWER_FEAR:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_FEAR;
            eLink1 = EffectHorrified();
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(1041));
            eLink1 = SetEffectIcon(eLink1, 6);
            Sp_ApplyEffects(TRUE, oTarget, 0.0, 1, eLink1, 6.0, eInvalid, 0.0);
        }
        break;
        /*
        FORCE ARMOR
        */
        case FORCE_POWER_FORCE_ARMOR:
        {
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectACIncrease(6, AC_DODGE_BONUS);
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 6));
            eLink1 = SetEffectIcon(eLink1, 7);
            eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
            eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
            //MODIFIED by Preston Watamaniuk on March 12
            //Make sure these Force Powers do not stack
            /*
            if(!GetHasSpellEffect(FORCE_POWER_FORCE_AURA) &&
               !GetHasSpellEffect(FORCE_POWER_FORCE_ARMOR) &&
               !GetHasSpellEffect(FORCE_POWER_FORCE_SHIELD))
            {
                Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 20.0, eLink2, 3.0);
            }
            */
            //Modified by Preston Watamaniuk on Sept 2
            //Make sure the old power is replaced by a new version if the same or more powerful
            if(GetHasSpellEffect(FORCE_POWER_FORCE_AURA))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_FORCE_AURA, oTarget);
            }
            else if(GetHasSpellEffect(FORCE_POWER_FORCE_SHIELD))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_FORCE_SHIELD, oTarget);
            }
            else if(GetHasSpellEffect(FORCE_POWER_FORCE_ARMOR))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_FORCE_ARMOR, oTarget);
            }
            Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 20.0, eLink2, 3.0);
        }
        break;
        /*
        FORCE AURA
        */
        case FORCE_POWER_FORCE_AURA:
        {
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectACIncrease(2, AC_DODGE_BONUS);
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 2));
            eLink1 = SetEffectIcon(eLink1, 8);
            eLink2 = EffectVisualEffect(VFX_PRO_FORCE_AURA);
            //Modified by Preston Watamaniuk on Sept 2
            //Make sure the old power is replaced by a new version if the same or more powerful
            if(GetHasSpellEffect(FORCE_POWER_FORCE_AURA))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_FORCE_AURA, oTarget);
            }
            //MODIFIED by Preston Watamaniuk on March 12
            //Make sure these Force Powers do not stack
            if(!GetHasSpellEffect(FORCE_POWER_FORCE_ARMOR) &&
               !GetHasSpellEffect(FORCE_POWER_FORCE_SHIELD))
            {
                Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 20.0, eLink2, 3.0);
            }
        }
        break;
        /*
        FORCE BREACH
        */
        case FORCE_POWER_FORCE_BREACH:
        {
            effect eBuff = GetFirstEffect(oTarget);
            int bValid = FALSE;
            while(GetIsEffectValid(eBuff))
            {
                if(GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_AURA ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_SHIELD ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_ARMOR ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_MIND ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_KNIGHT_MIND ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_MIND_MASTERY ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_SPEED_BURST ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_KNIGHT_SPEED ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_SPEED_MASTERY ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_RESIST_COLD_HEAT_ENERGY ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_RESIST_POISON_DISEASE_SONIC ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_RESIST_FORCE ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_IMMUNITY)
                 {
                    RemoveEffect(oTarget, eBuff);
                 }
                 eBuff = GetNextEffect(oTarget);
            }
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId()));
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FORCE_BREACH), oTarget);
        }
        break;
        /*
        FORCE IMMUNITY
        */
        case FORCE_POWER_FORCE_IMMUNITY:
        {
            SWFP_HARMFUL = FALSE;
            int nSR = 15 + GetHitDice(OBJECT_SELF);
            eLink1 = EffectForceResistanceIncrease(nSR);
            eLink1 = SetEffectIcon(eLink1, 9);
            eLink2 = EffectVisualEffect(VFX_PRO_RESIST_FORCE);
            if(GetHasSpellEffect(FORCE_POWER_RESIST_FORCE))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_RESIST_FORCE, oTarget);
            }
            else if(GetHasSpellEffect(FORCE_POWER_FORCE_IMMUNITY))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_FORCE_IMMUNITY, oTarget);
            }
            Sp_ApplyEffects(TRUE, oTarget, 0.0, 1, eLink1, 60.0, eLink2, 1.0);
        }
        break;
        /*
        FORCE PUSH
        */
        case FORCE_POWER_FORCE_PUSH:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            SWFP_DAMAGE = GetHitDice(OBJECT_SELF);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            eLink1 = EffectForcePushed();
            eLink2 = EffectStunned();
            eLink2 = SetEffectIcon(eLink2, 11);
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_IMP_FORCE_PUSH));
            effect eDamage = EffectDamage(GetHitDice(OBJECT_SELF), SWFP_DAMAGE_TYPE);
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eDamage);
            if(SP_CheckForcePushViability(oTarget, FALSE))
            {
                if(nResist == FALSE)
                {
                    int nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves == FALSE)
                    {
                        eDamage = EffectDamage(GetHitDice(OBJECT_SELF), SWFP_DAMAGE_TYPE);
                        DelayCommand(0.4, SP_MyApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget));
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 0.1);
                        DelayCommand(2.55, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, 2.0));
                    }
                    else
                    {
                        eDamage = EffectDamage(GetHitDice(OBJECT_SELF)/2, SWFP_DAMAGE_TYPE);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 0.1);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FORCE_PUSH), oTarget);
                    }
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                }
            }
        }
        break;
        /*
        FORCE VALOR
        */
        case FORCE_POWER_FORCE_MIND:
        {
            SWFP_HARMFUL = FALSE;
            SWFP_SHAPE = SHAPE_SPHERE;
            eLink1 = EffectSavingThrowIncrease(SAVING_THROW_FORT,2);
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_REFLEX, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CHARISMA, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_DEXTERITY, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_INTELLIGENCE, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_WISDOM, 2));
            eLink2 = EffectVisualEffect(VFX_IMP_MIND_FORCE);
            eLink1 = SetEffectIcon(eLink1, 10);
            Sp_RemoveBuffSpell();
            Sp_ApplyEffects(FALSE, OBJECT_SELF, 30.0, 1000, eLink1, 20.0, eLink2, 0.0);
        }
        break;
        /*
        FORCE SHIELD
        */
        case FORCE_POWER_FORCE_SHIELD:
        {
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectACIncrease(4, AC_DODGE_BONUS);
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 4));
            eLink1 = SetEffectIcon(eLink1, 12);
            eLink2 = EffectVisualEffect(VFX_PRO_FORCE_SHIELD);
            //Modified by Preston Watamaniuk on Sept 2
            //Make sure the old power is replaced by a new version if the same or more powerful
            if(GetHasSpellEffect(FORCE_POWER_FORCE_AURA))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_FORCE_AURA, oTarget);
            }
            else if(GetHasSpellEffect(FORCE_POWER_FORCE_SHIELD))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_FORCE_SHIELD, oTarget);
            }
            //MODIFIED by Preston Watamaniuk on March 12
            //Make sure these Force Powers do not stack
            if(!GetHasSpellEffect(FORCE_POWER_FORCE_ARMOR))
            {
                Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 20.0, eLink2, 3.0);
            }
        }
        break;
        /*
        FORCE STORM
        */
        case FORCE_POWER_FORCE_STORM:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            int nDamage = GetHitDice(OBJECT_SELF);
            if(nDamage > 10)
            {
                nDamage = 10;
            }
            SWFP_DAMAGE = d6(nDamage);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_ELECTRICAL;
            effect eBeam = EffectBeam(2061, OBJECT_SELF, BODY_NODE_HEAD);
            effect eVis = EffectVisualEffect(VFX_PRO_LIGHTNING_L);
            effect eForce;
            effect eDam;
            object oUse = GetFirstObjectInShape(SHAPE_SPHERE, 12.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            while(GetIsObjectValid(oUse))
            {
                //Make Immunity Checks
                if(GetIsEnemy(oUse))
                {
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    if(!ResistForce(OBJECT_SELF, oUse))
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oUse);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oUse, fLightningDuration);
                        if(!WillSave(oUse, Sp_GetJediDCSave()))
                        {
                            eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                            eForce = EffectDamageForcePoints(SWFP_DAMAGE);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
                        }
                        else
                        {
                            eDam = EffectDamage(SWFP_DAMAGE/2, SWFP_DAMAGE_TYPE);
                            eForce = EffectDamageForcePoints(SWFP_DAMAGE/2);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
                        }
                    }
                    else
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                    }
                }
                oUse = GetNextObjectInShape(SHAPE_SPHERE, 12.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            }
        }
        break;
        /*
        FORCE WAVE
        */
        case FORCE_POWER_FORCE_WAVE:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            SWFP_DAMAGE = GetHitDice(OBJECT_SELF) + GetHitDice(OBJECT_SELF)/2;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            effect eVis = EffectVisualEffect(VFX_IMP_FORCE_PUSH);
            eLink1 = EffectForcePushed();
            eLink2 = EffectStunned();
            eLink2 = SetEffectIcon(eLink2, 13);
            effect eDam;
            effect eForce;
            object oUse = GetFirstObjectInShape(SHAPE_SPHERE, 15.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_FORCE_WAVE), GetLocation(OBJECT_SELF));
            while(GetIsObjectValid(oUse))
            {
                //Make Immunity Checks
                if(GetIsEnemy(oUse))
                {
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    if(!ResistForce(OBJECT_SELF, oUse))
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oUse);
                        if(!ReflexSave(oUse, Sp_GetJediDCSave()))
                        {
                            eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                            DelayCommand(0.4, SP_MyApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse));
                            if(SP_CheckForcePushViability(oUse, FALSE))
                            {
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oUse, 0.2);
                            }
                            DelayCommand(2.55, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oUse, 6.0));
                        }
                        else
                        {
                            if(SP_CheckForcePushViability(oUse, FALSE))
                            {
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oUse, 0.2);
                            }
                            eDam = EffectDamage(SWFP_DAMAGE/2, SWFP_DAMAGE_TYPE);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
                        }
                    }
                }
                oUse = GetNextObjectInShape(SHAPE_SPHERE, 15.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            }
        }
        break;
        /*
        FORCE WHIRLWIND
        */
        case FORCE_POWER_FORCE_WHIRLWIND:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            SWFP_DAMAGE = GetHitDice(OBJECT_SELF)/3;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            effect eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
            //SP_MyPostString(IntToString(SP_CheckAppearanceGeoDroidShields(oTarget)),5,5,3.0);
            if(SP_CheckForcePushViability(oTarget, TRUE))
            {
                eLink1 = EffectWhirlWind();
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_IMP_FORCE_WHIRLWIND));
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_FORCE_WHIRLWIND));
                eLink1 = SetEffectIcon(eLink1, 14);
                int nResist = Sp_BlockingChecks(oTarget, eLink1, eDamage, eInvalid);
                int nSaves;
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                if(nResist == 0)
                {
                    nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves == 0)
                    {
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 9.0);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDamage, oTarget);
                        int nIdx = 1;
                        float fDelay;
                        SP_InterativeDamage(eDamage, 13, oTarget);
                    }
                }
                if(nResist > 0 || nSaves > 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                }
            }
            //Force Push all enemies away from the target is they meet the conditions.
            SP_MyPrintString("");
            eLink2 = EffectForcePushTargeted(GetLocation(oTarget));
            object oSecond = GetFirstObjectInShape(SHAPE_SPHERE, 5.0, GetLocation(oTarget));
            while(GetIsObjectValid(oSecond))
            {
                if(SP_CheckForcePushViability(oSecond, FALSE) == TRUE && GetIsEnemy(oSecond, OBJECT_SELF) && oSecond != oTarget)
                {
                    //P.W. (June 8) - Put this check in so Calo Nord does not move during the fight on Taris
                    if(GetTag(oTarget) != "Calo082")
                    {
                        SignalEvent(oSecond, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                        int nResist2 = Sp_BlockingChecks(oSecond, eLink2,eInvalid,eInvalid);
                        if(nResist2 == 0)
                        {
                            int nSaves2 = Sp_MySavingThrows(oSecond);
                            if(nSaves2 == 0)
                            {
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oSecond, 0.2);
                            }
                        }
                    }
                }
                oSecond = GetNextObjectInShape(SHAPE_SPHERE, 5.0, GetLocation(oTarget));
                SP_MyPrintString("");
            }
        }
        break;
        /*
        HEAL
        */
        //MODIFIED by Preston Watamaniuk March 28
        //Cut the heal in half
        case FORCE_POWER_HEAL:
        {
            SWFP_HARMFUL = FALSE;
            int nHeal = GetAbilityModifier(ABILITY_WISDOM) + GetAbilityModifier(ABILITY_CHARISMA) + 10 + GetHitDice(OBJECT_SELF);
            effect eVis =  EffectVisualEffect(VFX_IMP_HEAL);
            int nCnt = 0;
            object oParty;
            if(IsObjectPartyMember(OBJECT_SELF))
            {
                oParty = GetPartyMemberByIndex(nCnt);
            }
            else
            {
                oParty = OBJECT_SELF;
            }
            while(nCnt < 3)
            {
                if(GetIsObjectValid(oParty) &&
                   GetRacialType(oParty) != RACIAL_TYPE_DROID &&
                   GetDistanceBetween(OBJECT_SELF, oParty) < 15.0)
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    Sp_RemoveSpecificEffect(EFFECT_TYPE_POISON, oParty);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oParty);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHeal), oParty);
                }
                nCnt++;
                if(IsObjectPartyMember(OBJECT_SELF))
                {
                   oParty = GetPartyMemberByIndex(nCnt);
                }
                else
                {
                   oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt, CREATURE_TYPE_RACIAL_TYPE, RACIAL_TYPE_HUMAN);
                }
            }
        }
        break;
        /*
        HORROR
        */
        case FORCE_POWER_HORROR:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_FEAR;
            eLink1 = EffectHorrified();
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(1042));
            eLink1 = SetEffectIcon(eLink1, 16);
            Sp_ApplyEffects(TRUE, oTarget, 5.0, 1000, eLink1, 12.0, eInvalid, 0.0, RACIAL_TYPE_HUMAN);
        }
        break;
        /*
        INSANITY
        */
        case FORCE_POWER_INSANITY:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_FEAR;
            eLink1 = EffectHorrified();
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(1043));
            eLink1 = SetEffectIcon(eLink1, 17);
            Sp_ApplyEffects(TRUE, oTarget, 10.0, 1000, eLink1, 12.0, eInvalid, 0.0, RACIAL_TYPE_HUMAN);
            //ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(1043), oTarget);
        }
        break;
        /*
        KILL
        */
        case FORCE_POWER_KILL:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            effect eDeath = EffectDeath();
            effect eDamage;
            effect eChoke = EffectChoke();
            eChoke = SetEffectIcon(eChoke, 18);
            effect eVFX = EffectVisualEffect(VFX_IMP_CHOKE);
            int nResist = Sp_BlockingChecks(oTarget, eDeath, eDamage, eChoke);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if(nResist == 0)
            {
                int nSaves = Sp_MySavingThrows(oTarget);
                int nDamage = GetHitDice(OBJECT_SELF);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget);
                eDamage = EffectDamage(nDamage, DAMAGE_TYPE_BLUDGEONING);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eChoke, oTarget, 6.0);
                    nDamage = (GetMaxHitPoints(oTarget))/2;
                    nDamage = nDamage/3;
                    //This will do damage over time to make the effect look more dramatic
                    eDamage = EffectDamage(nDamage, DAMAGE_TYPE_BLUDGEONING);
                    SP_InterativeDamage(eDamage, 7, oTarget);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                }
            }
            else
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        /*
        KNIGHT VALOR
        */
        case FORCE_POWER_KNIGHT_MIND:
        {
            SWFP_HARMFUL = FALSE;
            SWFP_SHAPE = SHAPE_SPHERE;
            eLink1 = EffectSavingThrowIncrease(SAVING_THROW_ALL,3);
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CHARISMA, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_DEXTERITY, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_INTELLIGENCE, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_WISDOM, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectImmunity(IMMUNITY_TYPE_POISON));
            eLink1 = SetEffectIcon(eLink1, 19);
            eLink2 = EffectVisualEffect(1033);
            Sp_RemoveBuffSpell();
            //Sp_SphereSaveHalf(OBJECT_SELF, 30.0, 1000, eLink1, 20.0);
            Sp_ApplyEffects(TRUE, OBJECT_SELF, 30.0, 1000, eLink1, 20.0, eLink2, 0.0);
        }
        break;
        /*
        LIGHTSABER THROW
        */
        case FORCE_POWER_LIGHT_SABER_THROW:
        {
            SWFP_HARMFUL = TRUE;
            eLink1 = EffectLightsaberThrow(oTarget);
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, OBJECT_SELF, 3.0);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
        }
        break;
        /*
        ADVANCED LIGHTSABER THROW
        */
        case FORCE_POWER_LIGHT_SABER_THROW_ADVANCED:
        {
            SWFP_HARMFUL = TRUE;
            object oTarget2, oTarget3;
            oTarget2 = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, oTarget, 1);
            if(GetIsObjectValid(oTarget2) && GetDistanceBetween(oTarget, oTarget2) <= 5.0)
            {
                oTarget3 = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, oTarget, 2);
                if(GetIsObjectValid(oTarget3) && GetDistanceBetween(oTarget, oTarget3) <= 5.0)
                {
                    SP_MyPrintString("Target 1 = " + ObjectToString(oTarget) +
                                " Target 2 = " + ObjectToString(oTarget2) +
                                " Target 3 = " + ObjectToString(oTarget3));
                    eLink1 = EffectLightsaberThrow(oTarget, oTarget2, oTarget3);
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    SignalEvent(oTarget2, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    SignalEvent(oTarget3, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                }
                else
                {
                    SP_MyPrintString("Target 1 = " + ObjectToString(oTarget) +
                                " Target 2 = " + ObjectToString(oTarget2));
                    eLink1 = EffectLightsaberThrow(oTarget, oTarget2);
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    SignalEvent(oTarget2, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                }
            }
            else
            {
                SP_MyPrintString("Target 1 = " + ObjectToString(oTarget));
                eLink1 = EffectLightsaberThrow(oTarget);
                oTarget2 = OBJECT_INVALID;
            }
            SP_MyPrintString("Apply Throwsaber Effect");
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, OBJECT_SELF, 3.0);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
        }
        break;
        /*
        LIGHTNING
        */
        case FORCE_POWER_LIGHTNING:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_ELECTRICAL;
            int nDamage = GetHitDice(OBJECT_SELF);
            if(nDamage > 10)
            {
                nDamage = 10;
            }
            SWFP_DAMAGE = d6(nDamage);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_ELECTRICAL;
            SWFP_DAMAGE_VFX = VFX_PRO_LIGHTNING_L; //1036 - With sound
            SWFP_SHAPE = SHAPE_SPELLCYLINDER;
            effect eLightning = EffectBeam(VFX_BEAM_LIGHTNING_DARK_L, OBJECT_SELF, BODY_NODE_HAND);
            effect eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
            object oUse = GetFirstObjectInShape(SWFP_SHAPE, 17.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            effect eBump = EffectVisualEffect(SWFP_DAMAGE_VFX);
            int nCnt = 1;
            // This will need to be changed to a double while get nearest in shape script.
            //ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(1036), OBJECT_SELF);
            while(GetIsObjectValid(oUse))
            {
                if(GetIsEnemy(oUse))
                {
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    //Make Immunity Checks
                    if(!ResistForce(OBJECT_SELF, oUse))
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eBump, oUse);
                        if(!WillSave(oUse, Sp_GetJediDCSave(), SWFP_PRIVATE_SAVE_VERSUS_TYPE))
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            //ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
                        }
                        else
                        {
                            SWFP_DAMAGE /= 2;
                            eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                        }
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLightning, oUse, fLightningDuration);
                    }
                    else
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
                    }
                }
                nCnt++;
                oUse = GetNextObjectInShape(SWFP_SHAPE, 17.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            }
        }
        break;
        /*
        MASTER VALOR
        */
        case FORCE_POWER_MIND_MASTERY:
        {
            SWFP_HARMFUL = FALSE;
            SWFP_SHAPE = SHAPE_SPHERE;
            eLink1 = EffectSavingThrowIncrease(SAVING_THROW_ALL,5);
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CHARISMA, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_DEXTERITY, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_INTELLIGENCE, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_WISDOM, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectImmunity(IMMUNITY_TYPE_POISON));
            eLink1 = SetEffectIcon(eLink1, 21);
            eLink2 = EffectVisualEffect(VFX_IMP_MIND_MASTERY);
            Sp_RemoveBuffSpell();
            Sp_ApplyEffects(TRUE, OBJECT_SELF, 30.0, 1000, eLink1, 20.0, eLink2, 0.0);
        }
        break;
        /*
        PLAGUE
        */
        case FORCE_POWER_PLAGUE:
        {
            SWFP_HARMFUL = TRUE;
            eLink1 = EffectPoison(POISON_ABILITY_SCORE_VIRULENT);
            eLink1 = EffectLinkEffects(eLink1, EffectMovementSpeedDecrease(50));
            eLink1 = SetEffectIcon(eLink1, 23);
            if(!GetIsPoisoned(oTarget))
            {
                Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 1000.0, eInvalid, 0.0);
            }
        }
        break;
        /*
        IMPROVED ENERGY RESISTANCE
        */
        case FORCE_POWER_RESIST_COLD_HEAT_ENERGY:
        {
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectDamageResistance(DAMAGE_TYPE_COLD, 15);
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_FIRE, 15));
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SONIC, 15));
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_BLASTER, 15));
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 15));
            eLink1 = EffectLinkEffects(eLink1, EffectImmunity(IMMUNITY_TYPE_POISON));
            eLink1 = SetEffectIcon(eLink1, 24);
            eLink2 = EffectVisualEffect(VFX_PRO_RESIST_POISON);
            if(!SP_CheckEnergyResistance(OBJECT_SELF) && !IsObjectPartyMember(OBJECT_SELF))
            {
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, OBJECT_SELF, 120.0);
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, OBJECT_SELF, 1.0);
            }
            else if(IsObjectPartyMember(OBJECT_SELF))
            {
                int nCnt = 0;
                object oParty;
                for(nCnt; nCnt < 3; nCnt++)
                {
                    oParty = GetPartyMemberByIndex(nCnt);
                    if(GetIsObjectValid(oParty))
                    {
                        if(!SP_CheckEnergyResistance(oParty))
                        {
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oParty, 120.0);
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oParty, 1.0);
                        }
                    }
                }
            }
            //Sp_ApplyEffects(FALSE, oTarget, 10.0, 3, eLink1, 120.0, eLink2, 1.0);
        }
        break;
        /*
        RESIST FORCE 1
        */
        case FORCE_POWER_RESIST_FORCE:
        {
            SWFP_HARMFUL = FALSE;
            int nSR = 10 + GetHitDice(OBJECT_SELF);
            eLink1 = EffectForceResistanceIncrease(nSR);
            eLink1 = SetEffectIcon(eLink1, 25);
            eLink2 = EffectVisualEffect(VFX_PRO_RESIST_FORCE);
            if(GetHasSpellEffect(FORCE_POWER_RESIST_FORCE))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_RESIST_FORCE, oTarget);
            }
            if(!GetHasSpellEffect(FORCE_POWER_FORCE_IMMUNITY))
            {
                Sp_ApplyEffects(TRUE, oTarget, 0.0, 1, eLink1, 60.0, eLink2, 1.0);
            }
        }
        break;
        /*
        RESIST ENERGY
        */
        case FORCE_POWER_RESIST_POISON_DISEASE_SONIC:
        {
            if(!SP_CheckEnergyResistance(OBJECT_SELF))
            {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectDamageResistance(DAMAGE_TYPE_COLD, 15);
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_FIRE, 15));
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SONIC, 15));
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 15));
                eLink1 = SetEffectIcon(eLink1, 26);
                eLink2 = EffectVisualEffect(VFX_PRO_RESIST_ELEMENTS);
                Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 120.0, eLink2, 1.0);
            }
        }
        break;
        /*
        SHOCK
        */
        case FORCE_POWER_SHOCK:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_ELECTRICAL;
            int nDamage = GetHitDice(OBJECT_SELF);
            if(nDamage > 10)
            {
                nDamage = 10;
            }
            SWFP_DAMAGE = d6(nDamage);
            SP_MyPostString(IntToString(SWFP_DAMAGE),5,5,4.0);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_ELECTRICAL;
            SWFP_DAMAGE_VFX = VFX_PRO_LIGHTNING_S;
            effect eDamage = EffectDamage(SWFP_DAMAGE, DAMAGE_TYPE_ELECTRICAL);
            effect eDamage2 = EffectDamage(SWFP_DAMAGE/2, DAMAGE_TYPE_ELECTRICAL);
            int nSaves = Sp_MySavingThrows(oTarget);
            int nResist = Sp_BlockingChecks(oTarget, eDamage, eInvalid, eInvalid);
            eLink1 = EffectBeam(2066, OBJECT_SELF, BODY_NODE_HAND); //P.W.(May 19, 2003) Changed to Shock beam effect.
            if(nResist == 0)
            {
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fLightningDuration);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_PRO_LIGHTNING_S), oTarget);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage2, oTarget);
                }
            }
            //Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, fLightningDuration, eInvalid, 0.0);
        }
        break;
        /*
        STASIS
        */
        case FORCE_POWER_HOLD:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            eLink1 = EffectParalyze();
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_HOLD));
            eLink1 = SetEffectIcon(eLink1, 15);
            eLink2 = EffectMovementSpeedDecrease(50);
            eLink2 = EffectLinkEffects(eLink2, EffectACDecrease(4));
            eLink2 = SetEffectIcon(eLink2, 15);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            //Make Immunity Checks
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
            if(nResist == 0)
            {
                int nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 12.0);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, 12.0);
                }
            }
            else
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        /*
        STASIS FIELD
        */
        case FORCE_POWER_SLEEP:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            eLink1 = EffectParalyze();
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_HOLD));
            eLink1 = SetEffectIcon(eLink1, 27);
            eLink2 = EffectMovementSpeedDecrease(50);
            eLink2 = EffectLinkEffects(eLink2, EffectACDecrease(4));
            eLink2 = SetEffectIcon(eLink2, 27);
            oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 10.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            while(GetIsObjectValid(oTarget))
            {
                if(GetIsEnemy(oTarget) && GetRacialType(oTarget) != RACIAL_TYPE_DROID)
                {
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    //Make Immunity Checks
                    int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
                    if(nResist == 0)
                    {
                        int nSaves = Sp_MySavingThrows(oTarget);
                        if(nSaves == 0)
                        {
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 12.0);
                        }
                        else
                        {
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, 12.0);
                        }
                    }
                }
                oTarget = GetNextObjectInShape(SHAPE_SPHERE, 10.0, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            }
        }
        break;
        /*
        SLOW
        */
        case FORCE_POWER_SLOW:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            eLink1 = EffectMovementSpeedDecrease(50);
            eLink1 = EffectLinkEffects(eLink1, EffectACDecrease(2));
            eLink1 = EffectLinkEffects(eLink1, EffectAttackDecrease(2));
            //eLink1 = EffectLinkEffects(eLink1, EffectDamageDecrease(2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowDecrease(SAVING_THROW_REFLEX,2));
            eLink2 = EffectVisualEffect(VFX_PRO_AFFLICT);
            eLink1 = SetEffectIcon(eLink1, 28);
            Sp_ApplyEffects(TRUE, oTarget, 0.0, 1, eLink1, 30.0, eLink2, 1.0);
        }
        break;
        /*
        BURST OF SPEED
        */
        case FORCE_POWER_SPEED_BURST:
        {
            if(!GetHasSpellEffect(FORCE_POWER_KNIGHT_SPEED) &&
               !GetHasSpellEffect(FORCE_POWER_SPEED_MASTERY))
            {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectMovementSpeedIncrease(99);
                eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(2));
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_KNIGHTS_SPEED));
                eLink1 = SetEffectIcon(eLink1, 2);
                if(OBJECT_SELF == GetPartyMemberByIndex(0))
                {
                    eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_SPEED));
                }
                if(GetHasSpellEffect(FORCE_POWER_SPEED_BURST, oTarget))
                {
                    Sp_RemoveSpellEffectsGeneral(FORCE_POWER_SPEED_BURST, oTarget);
                }
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, 36.0, eInvalid, 0.0);
            }
        }
        break;
        /*
        KNIGHT SPEED
        */
        case FORCE_POWER_KNIGHT_SPEED:
        {
            if(!GetHasSpellEffect(FORCE_POWER_SPEED_MASTERY))
            {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectMovementSpeedIncrease(99);
                eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(4));
                eLink1 = EffectLinkEffects(eLink1, EffectModifyAttacks(1));
                eLink1 = SetEffectIcon(eLink1, 20);
                if(OBJECT_SELF == GetPartyMemberByIndex(0))
                {
                    eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_SPEED));
                    //eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_IMP_SPEED_KNIGHT));
                }
                if(GetHasSpellEffect(FORCE_POWER_SPEED_BURST, oTarget))
                {
                    Sp_RemoveSpellEffectsGeneral(FORCE_POWER_SPEED_BURST, oTarget);
                }
                if(GetHasSpellEffect(FORCE_POWER_KNIGHT_SPEED, oTarget))
                {
                    Sp_RemoveSpellEffectsGeneral(FORCE_POWER_KNIGHT_SPEED, oTarget);
                }
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, 36.0, eInvalid, 0.0);
            }
        }
        break;
        /*
        MASTER SPEED
        */
        case FORCE_POWER_SPEED_MASTERY:
        {
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectMovementSpeedIncrease(99);
            eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(4));
            eLink1 = EffectLinkEffects(eLink1, EffectModifyAttacks(2));
            eLink1 = SetEffectIcon(eLink1, 22);
            if(OBJECT_SELF == GetPartyMemberByIndex(0))
            {
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_SPEED));
                //eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_IMP_SPEED_MASTERY));
            }
            if(GetHasSpellEffect(FORCE_POWER_SPEED_BURST, oTarget))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_SPEED_BURST, oTarget);
            }
            if(GetHasSpellEffect(FORCE_POWER_KNIGHT_SPEED, oTarget))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_KNIGHT_SPEED, oTarget);
            }
            if(GetHasSpellEffect(FORCE_POWER_SPEED_MASTERY, oTarget))
            {
                Sp_RemoveSpellEffectsGeneral(FORCE_POWER_SPEED_MASTERY, oTarget);
            }
            Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, 36.0, eInvalid, 0.0);
        }
        break;
        /*
        STUN
        */
        case FORCE_POWER_STUN:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_MIND_AFFECTING;
            eLink1 = EffectStunned();
            //eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_HOLD));
            eLink1 = SetEffectIcon(eLink1, 29);
            eLink2 = EffectMovementSpeedDecrease(50);
            eLink2 = EffectLinkEffects(eLink2, EffectACDecrease(4));
            eLink1 = SetEffectIcon(eLink1, 29);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            //Make Immunity Checks
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
            int nSaves;
            if(nResist == 0)
            {
                nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 9.0);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, 9.0);
                }
            }
            if(nResist > 0 || nSaves > 0)
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        /*
        SUPRESS FORCE
        */
        case FORCE_POWER_SUPRESS_FORCE:
        {
            effect eBuff = GetFirstEffect(oTarget);
            int bValid = FALSE;
            while(GetIsEffectValid(eBuff))
            {
                if(GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_AURA ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_SHIELD ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_MIND ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_KNIGHT_MIND ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_SPEED_BURST ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_KNIGHT_SPEED ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_RESIST_FORCE ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_RESIST_POISON_DISEASE_SONIC)
                 {
                    RemoveEffect(oTarget, eBuff);
                 }
                 eBuff = GetNextEffect(oTarget);
            }
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId()));
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FORCE_BREACH), oTarget);
        }
        break;
        /*
        WOUND
        */
        case FORCE_POWER_WOUND:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            SWFP_DAMAGE = (GetHitDice(OBJECT_SELF)*2)/3;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            effect eChoke = EffectChoke();
            eChoke = SetEffectIcon(eChoke, 31);
            effect eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
            int nResist = Sp_BlockingChecks(oTarget, eChoke, eDamage, eInvalid);
            int nSaves;
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if(nResist == 0)
            {
                nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_CHOKE), oTarget);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eChoke, oTarget, 6.0);
                    int nIdx = 1;
                    float fDelay;
                    SP_InterativeDamage(eDamage, 7, oTarget);
                }
            }
            if(nResist > 0 || nSaves > 0)
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        case SPECIAL_ABILITY_BODY_FUEL:
        {
            effect eBody = EffectBodyFuel();
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBody, OBJECT_SELF, 30.0);
        }
        break;
        case SPECIAL_ABILITY_ENHANCED_SENSES:
        {
            effect eAC = EffectACDecrease(6);
            effect eAware = EffectSkillIncrease(SKILL_AWARENESS, 10);
            effect eSee = EffectTrueSeeing();
            eLink1 = EffectLinkEffects(eAC, eAware);
            eLink1 = EffectLinkEffects(eLink1, eAware);
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, OBJECT_SELF, RoundsToSeconds(10));
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_MIND_FORCE), OBJECT_SELF);
        }
        break;
        case SPECIAL_ABILITY_PSYCHIC_STANCE:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_MIND_AFFECTING;
            eLink1 = EffectPsychicStatic();
            Sp_ApplyEffects(TRUE, oTarget, 10.0, 1000, eLink1, 20.0, eInvalid, 0.0);
        }
        break;
        /*
        Rage
        This ability allows Zaalbar to fly into a rage.
        When Zaalbar flies into a rage he gains +4 to his Strength and Constitution.  He also gains a +2 bonus on
        Fortitude and Will saves.  While raging Zaalbar cannot use any skills.  He also has a -4 penalty to his Defense rating.
        Interface: Mystical.  It takes one round to initiate the rage.
        Prerequisites: Nothing.  This is a unique NPC power.
        */
        case SPECIAL_ABILITY_RAGE:
        {
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_FORT, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 4));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 4));
            eLink1 = EffectLinkEffects(eLink1, EffectACDecrease(4));
            Sp_ApplyEffects(TRUE, OBJECT_SELF, 0.0, 1, eLink1, 30.0, eInvalid, 0.0);
        }
        break;
        case 83: //Monster Slam Attack
        {
            SP_MyPrintString("I am attempting to use monster slam");
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            SWFP_DAMAGE = GetHitDice(OBJECT_SELF);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            eLink1 = EffectForcePushed();
            eLink2 = EffectStunned();
            effect eDamage = EffectDamage(GetHitDice(OBJECT_SELF), SWFP_DAMAGE_TYPE);
            if(!ReflexSave(oTarget, 15))
            {
                eDamage = EffectDamage(GetHitDice(OBJECT_SELF), SWFP_DAMAGE_TYPE);
                DelayCommand(0.5, SP_MyApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget));
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 0.25);
                DelayCommand(2.55, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, 3.0));
            }
            else
            {
                eDamage = EffectDamage(GetHitDice(OBJECT_SELF)/2, SWFP_DAMAGE_TYPE);
                DelayCommand(0.5, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 0.25));
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FORCE_PUSH), oTarget);
            }
        }
        break;
        case 130: //Fire Breath Weapon
        {
            oTarget = GetSpellTargetObject();
            int nDC = 15;
            int nDamage = 40;
            effect eBeam = EffectBeam(2053, OBJECT_SELF, BODY_NODE_HEAD);
            effect eVFX = EffectVisualEffect(1039);
            effect eBump = EffectVisualEffect(2062);
            effect eHorror = EffectHorrified();
            eHorror = SetEffectIcon(eHorror, 57);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget);
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, 1.0);
            if(GetHitDice(oTarget) < 7 || FortitudeSave(oTarget, 15) == FALSE)
            {
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eHorror, oTarget, 3.0);
            }
            DelayCommand(0.33, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBump, oTarget, 1.5));
            if(ReflexSave(oTarget, nDC, SAVING_THROW_TYPE_FIRE))
            {
                nDamage /= 2;
            }
            effect eDam = EffectDamage(nDamage, DAMAGE_TYPE_FIRE);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
        }
        break;
        case 131:
        {
            int nVFX = 3002;
            int nDC = 15;
            effect eDex = EffectAbilityDecrease(ABILITY_DEXTERITY, 3);
            eDex = SetEffectIcon(eDex, 41);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(nVFX), OBJECT_SELF);
            oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 10.0, GetSpellTargetLocation());
            while(GetIsObjectValid(oTarget))
            {
                if(GetIsEnemy(oTarget))
                {
                    if(!FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_SONIC))
                    {
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDex, oTarget, 30.0);
                    }
                }
                oTarget = GetNextObjectInShape(SHAPE_SPHERE, 4.0, GetSpellTargetLocation());
            }
        }
    }
}
//::///////////////////////////////////////////////
//:: While Loop Effect Delivery
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Uses these values to deliver the effects in the
    loop.
    SWFP_PRIVATE_SAVE_TYPE;
    SWFP_PRIVATE_SAVE_VERSUS_TYPE;
    SWFP_DAMAGE;
    SWFP_DAMAGE_TYPE;
    SWFP_DAMAGE_VFX;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 2, 2002
//:://////////////////////////////////////////////
void Sp_ApplyEffects(int nBlocking, object oAnchor, float fSize, int nCounter, effect eLink1, float fDuration1, effect eLink2, float fDuration2, int nRacial = RACIAL_TYPE_ALL)
{
    int nCnt = 0;
    object oTarget;
    //By setting the counter to 1 you specify a single target.
    //By setting the counter to 1000, you specify all targets in a shape.
    //By setting the counter to another number you specify that many targets maximum.
    if(nCounter > 1)
    {
        oTarget = GetFirstObjectInShape(SWFP_SHAPE, fSize, GetLocation(oAnchor));
    }
    else if(nCounter == 1)
    {
        oTarget = oAnchor;
    }
    while(GetIsObjectValid(oTarget) && nCnt < nCounter)
    {
        if(nRacial == GetRacialType(oTarget) || nRacial == RACIAL_TYPE_ALL)
        {
            int nIdx = 0; // Index for the for loop link application.
            effect eUse;  // Current effect to use
            float fUse;   // Current duration to use
            int nDamage;  // The damage as set from SWFP_DAMAGE
            int bFizzle;  // Tracks whether the Fizzle has played on the caster yet or not.
            effect eDamage; // The damage effect which will be linked after the saves are done and checked with blocking.
            if((GetIsEnemy(oTarget) && SWFP_HARMFUL == TRUE) || (GetIsFriend(oTarget) && SWFP_HARMFUL == FALSE))
            {
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                //eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                int nResist = FALSE;
                int nSaves = -1;
                if(SWFP_HARMFUL == TRUE)
                {
                    nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eDamage);
                }
                //By adding another index the number of links added to this function can increase.
                for(nIdx; nIdx <= 1; nIdx++)
                {
                    if(nIdx == 0)
                    {
                        eUse = eLink1;
                        fUse = fDuration1;
                    }
                    else
                    {
                        eUse = eLink2;
                        fUse = fDuration2;
                    }
                    if(nResist == FALSE)
                    {
                        //MODIFIED by Preston Watamaniuk March 23
                         //Moved the save call down to here from up above with the resist inorder to help
                         //feedback system not make useless save calls.
                        //MODIFIED by Preston Watamaniuk March 24
                         //Made the default value of nSave -1 so that I only do it once.
                        //MODIFIED by Preston Watamaniuk April 5
                         //Made sure to set nSaves to FALSE so that it would fall through the function.
                        if(SWFP_HARMFUL == TRUE && nSaves == -1)
                        {
                            nSaves = Sp_MySavingThrows(oTarget);
                        }
                        else
                        {
                            nSaves = FALSE;
                        }
                        if(nSaves == FALSE)
                        {
                            if(nIdx == 1 && SWFP_DAMAGE > 0)
                            //Damage effects are always linked to the eDamage effect which is kept seperate from
                            //all other eLink types coming in.
                            {
                                eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                                eDamage = EffectLinkEffects(eDamage, EffectVisualEffect(SWFP_DAMAGE_VFX));
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                            }
                            if(GetIsEffectValid(eUse))
                            {
                                Sp_ApplyForcePowerEffects(fUse, eUse, oTarget);
                            }
                        }
                        //If the blocking flag is true then do not apply any effects on a save.
                        else if(nSaves > 0 && nBlocking == FALSE)
                        {
                            if(nIdx == 1 && SWFP_DAMAGE > 0)
                            {
                                SWFP_DAMAGE /= 2;
                                eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                                eDamage = EffectLinkEffects(eDamage, EffectVisualEffect(SWFP_DAMAGE_VFX));
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                            }
                            if(GetIsEffectValid(eUse))
                            {
                                Sp_ApplyForcePowerEffects(fUse, eUse, oTarget);
                            }
                        }
                    }
                    if(nResist > 0 || (nSaves > 0 && nBlocking > 0))
                    {
                        if(bFizzle == FALSE)
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                            bFizzle = TRUE;
                        }
                    }
                }
                nCnt++;
            }
        }
        oTarget = GetNextObjectInShape(SWFP_SHAPE, fSize, GetLocation(oAnchor), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
    }
}
//::///////////////////////////////////////////////
//:: Remove Buff Bonuses
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Goes through and removes all of the bonuses
    from people in a 30m radius from Force Mind,
    Knight Mind, Mind Mastery and Battle Meditation
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 7, 2002
//:://////////////////////////////////////////////
void Sp_RemoveBuffSpell()
{
    object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF));
    while(GetIsObjectValid(oTarget))
    {
        if(GetFactionEqual(oTarget))
        {
            //Declare major variables
            int bValid = FALSE;
            effect eAOE;
            if(GetHasSpellEffect(FORCE_POWER_FORCE_MIND, oTarget) ||
               GetHasSpellEffect(FORCE_POWER_MIND_MASTERY, oTarget) ||
               GetHasSpellEffect(FORCE_POWER_KNIGHT_MIND, oTarget) ||
               GetHasSpellEffect(SPECIAL_ABILITY_BATTLE_MEDITATION, oTarget))
            {
                //Search through the valid effects on the target.
                eAOE = GetFirstEffect(oTarget);
                while (GetIsEffectValid(eAOE) && bValid == FALSE)
                {
                    //If the effect was created by the spell then remove it
                    if(GetEffectSpellId(eAOE) == FORCE_POWER_FORCE_MIND ||
                       GetEffectSpellId(eAOE) == FORCE_POWER_MIND_MASTERY ||
                       GetEffectSpellId(eAOE) == FORCE_POWER_KNIGHT_MIND ||
                       GetEffectSpellId(eAOE) == SPECIAL_ABILITY_BATTLE_MEDITATION)
                    {
                        RemoveEffect(oTarget, eAOE);
                    }
                    //Get next effect on the target
                    eAOE = GetNextEffect(oTarget);
                }
            }
        }
        oTarget = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF));
    }
}
//::///////////////////////////////////////////////
//:: Check for Appearance Type Turret
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks to see if the target is a Turret
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 10, 2003
//:://////////////////////////////////////////////
int SP_CheckAppearanceTurret(object oTarget, int nFeedback = FALSE)
{
    int nCheck = FALSE;
    SP_MyPostString("Appearance = " + IntToString(GetAppearanceType(oTarget)));
    if(GetAppearanceType(oTarget) == 182 || GetAppearanceType(oTarget) == 183)
    {
        if(nFeedback == TRUE)
        {
            DisplayFeedBackText(oTarget, 1);
        }
        nCheck = TRUE;
    }
    return nCheck;
}
//::///////////////////////////////////////////////
//:: Check Droid Appearance Type
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks to see if the target is a Mark 1, 2, 4
    or Spyder Droid
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 10, 2003
//:://////////////////////////////////////////////
int SP_CheckAppearanceGeoDroid(object oTarget)
{
    int nCheck = FALSE;
    if(GetAppearanceType(oTarget) == 59 ||
       GetAppearanceType(oTarget) == 60 ||
       GetAppearanceType(oTarget) == 61 ||
       GetAppearanceType(oTarget) == 65)
    {
        nCheck = TRUE;
    }
    return nCheck;
}
//::///////////////////////////////////////////////
//:: Check Droid Appearance Type and and Shields
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks to see if the target is a Mark 1, 2, 4
    or Spyder Droid and has a shield activated
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 10, 2003
//:://////////////////////////////////////////////
int SP_CheckAppearanceGeoDroidShields(object oTarget, int nFeedback = FALSE)
{
    int nCheck = FALSE;
    if(GetAppearanceType(oTarget) == 59 ||
       GetAppearanceType(oTarget) == 60 ||
       GetAppearanceType(oTarget) == 61 ||
       GetAppearanceType(oTarget) == 65)
    {
        if(GetHasSpellEffect(110, oTarget) ||
           GetHasSpellEffect(111, oTarget) ||
           GetHasSpellEffect(112, oTarget) ||
           GetHasSpellEffect(113, oTarget) ||
           GetHasSpellEffect(114, oTarget) ||
           GetHasSpellEffect(115, oTarget))
         {
            if(nFeedback == TRUE)
            {
                DisplayFeedBackText(oTarget, 1);
            }
            nCheck = TRUE;
         }
    }
    return nCheck;
}
//::///////////////////////////////////////////////
//:: Force Push Viability
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns TRUE if the target can be force pushed
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2003
//:://////////////////////////////////////////////
int SP_CheckForcePushViability(object oTarget, int Whirlwind)
{
    int bValid = FALSE;
    SP_MyPrintString("Push Check Start");
    if(GetCreatureSize(oTarget) != CREATURE_SIZE_LARGE &&
       GetCreatureSize(oTarget) != CREATURE_SIZE_HUGE)
    {
        SP_MyPrintString("Size is OK");
        if(SP_CheckAppearanceTurret(oTarget) == FALSE)
        {
            SP_MyPrintString("I am not a turret");
            if((Whirlwind == TRUE && SP_CheckAppearanceGeoDroidShields(oTarget) == FALSE) ||
                Whirlwind == FALSE)
            {
                SP_MyPrintString("I am whirlwind without droid shiled or not whirlwind");
                if(GetCreatureMovmentType(oTarget) != MOVEMENT_SPEED_IMMOBILE)
                {
                    SP_MyPrintString("Returning Push True");
                    bValid = TRUE;
                }
            }
        }
    }
    if(bValid == FALSE)
    {
        DisplayFeedBackText(oTarget, 1);
    }
    return bValid;
}
void SP_MyPrintString(string sString)
{
    if(!ShipBuild())
    {
        sString = "SPELL GENERIC DEBUG STRING: " + sString;
        PrintString(sString);
    }
}
void SP_MyPostString(string sString, int n1 = 5, int n2 = 10, float fTime = 4.0)
{
    sString = "DEBUG: " + sString;
    AurPostString(sString,10,10,3.0);
}
""",
    "k_inc_generic": b"""//:: k_inc_generic
/*
    v1.5
    Generic Include for KOTOR
    Post Clean Up as of March 3, 2003
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
#include "k_inc_gensupport"
#include "k_inc_walkways"
#include "k_inc_drop"
struct tLastRound
{
    int nLastAction;
    int nLastActionID;
    int nLastTalentCode;
    object oLastTarget;
    int nTalentSuccessCode;
    int nIsLastTargetDebil;
    int nLastCombo;
    int nLastComboIndex;
    int nCurrentCombo;
    int nBossSwitchCurrent;
};
struct tLastRound tPR;
//LOCAL BOOLEANS RANGE FROM 0 to 96
int AMBIENT_PRESENCE_DAY_ONLY = 1;        //POSSIBLE CUT
int AMBIENT_PRESENCE_NIGHT_ONLY = 2;      //POSSIBLE CUT
int AMBIENT_PRESENCE_ALWAYS_PRESENT = 3;
int SW_FLAG_EVENT_ON_PERCEPTION =   20;
int SW_FLAG_EVENT_ON_ATTACKED   =   21;
int SW_FLAG_EVENT_ON_DAMAGED    =   22;
int SW_FLAG_EVENT_ON_FORCE_AFFECTED = 23;
int SW_FLAG_EVENT_ON_DISTURBED = 24;
int SW_FLAG_EVENT_ON_COMBAT_ROUND_END = 25;
int SW_FLAG_EVENT_ON_DIALOGUE    = 26;
int SW_FLAG_EVENT_ON_DEATH       = 27;
int SW_FLAG_EVENT_ON_HEARTBEAT   = 28;
//int SW_FLAG_AMBIENT_ANIMATIONS = 29;          located in k_inc_walkways
//int SW_FLAG_AMBIENT_ANIMATIONS_MOBILE = 30;   located in k_inc_walkways
int SW_FLAG_FAST_BUFF            = 31;   //POSSIBLE CUT
int SW_FLAG_ASC_IS_BUSY          = 32;   //POSSIBLE CUT
int SW_FLAG_ASC_AGGRESSIVE_MODE  = 33;   //POSSIBLE CUT
int SW_FLAG_AMBIENT_DAY_ONLY     = 40;   //POSSIBLE CUT
int SW_FLAG_AMBIENT_NIGHT_ONLY   = 43;   //POSSIBLE CUT
int SW_FLAG_EVENT_ON_SPELL_CAST_AT = 44;
int SW_FLAG_EVENT_ON_BLOCKED     = 45;
int SW_FLAG_ON_DIALOGUE_COMPUTER = 48;
int SW_FLAG_FORMATION_POSITION_0 = 49;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_1 = 50;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_2 = 51;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_3 = 52;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_4 = 53;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_5 = 54;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_6 = 55;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_7 = 56;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_8 = 57;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_9 = 58;   //POSSIBLE CUT
//int SW_FLAG_TARGET_FRIEND      = 59;        Located in k_inc_gensupport
int SW_FLAG_COMMONER_BEHAVIOR    = 60;
int SW_FLAG_SPECTATOR_STATE      = 61;
int SW_FLAG_AI_OFF               = 62;
int SW_CANDEROUS_COMBAT_REGEN    = 63;
int SW_FLAG_BOSS_AI              = 64;
int SW_FLAG_SHIELD_USED          = 65;
int SW_FLAG_EVENT_ON_DIALOGUE_END = 66;
int SW_FLAG_RESISTANCES_APPLIED  = 67;
int SW_FLAG_EVENT_DIALOGUE_END   = 68;   //User defined event
//This flag is set when the creature percieves a hostile for the first time.
//Used to eliminate the delay a creature puts on his perception event when first seeing a hostile.
int SW_FLAG_STATE_AGITATED       = 69;
int SW_FLAG_MALAK_AI_ON          = 70;
int SW_FLAG_DYNAMIC_COMBAT_ZONE  = 71;
int SW_FLAG_EVENT_ON_DIALOGUE_INTERRUPT  = 72;
//TALENT ROUTINES
int GEN_TALENT_SUPRESS_FORCE = 1;
int GEN_TALENT_REMOVE_POISON = 2;
int GEN_TALENT_HEALING       = 3;
int GEN_TALENT_BUFF          = 4;
//Sets the NPC listening patterns for the purposes of shouts
void GN_SetListeningPatterns();
//Determines what combat actions the character is going to take.
void GN_DetermineCombatRound(object oIntruder = OBJECT_INVALID);
// Function used by the On Dialogue script to determine what to do when a NPC gets shout
void GN_RespondToShout(object oShouter, int nShoutIndex, object oIntruder = OBJECT_INVALID);
//Sets the day night patterns for the creature.  Uses the AMBIENCE_ constants.
void GN_SetDayNightPresence(int nPresenceSetting);
//Sets the attack target depending on whether oTarget or oIntruder is Valid
object GN_DetermineAttackTarget(object oIntruder = OBJECT_INVALID);
//Makes the character flee the center of an explosion
void GN_DodgeGrenade(object oIntruder);
//Resets the formation booleans on a character.
void GN_ResetFormationBooleans();
//Checks which position on a character is free.
void GN_MoveToFormation(object oAnchor, int nFormationType);
//Runs the default AI routine
int GN_RunDefaultAIRoutine(object oIntruder = OBJECT_INVALID);
//Runs the Aid AI routine
int GN_RunAidAIRoutine(object oIntruder = OBJECT_INVALID);
//Runs the Grenade Thrower AI
int GN_RunGrenadeAIRoutine(object oIntruder = OBJECT_INVALID);
//Runs the Jedi Support AI routine
int GN_RunJediSupportAIRoutine(object oIntruder = OBJECT_INVALID);
//Runs the Boss AI Routine
int GN_RunBossAIRoutine(object oIntruder = OBJECT_INVALID);
//Run Boss Grenade AI Routine
int GN_RunBossGrenadeAI();
//Run Boss AOE Force Power Routine
int GN_RunBossAOEPowerRoutine();
//Runs special AI just for Darth Malak on the Star Forge
int GN_RunMalakAIRoutine();
//Run Boss Targeted Routine
int GN_RunBossTargetedRoutine();
//Sets up struct tLastRound to allow for a single point of determination.
void GN_SetLastRoundData();
//Makes the person or droid activate a shield
int GN_ActivateForceField();
//Makes the person activate Resist Elements and Resist Force.
int GN_ActivateResistances();
//Resets a Droid to his deactivated animation
void GN_ResetDroidDeactivationState(object oDroid = OBJECT_SELF);
//Checks the target and the droid utility use to make sure they are compatible
talent GN_CheckDroidUtilityUsage(object oTarget, talent tUse);
//Checks the target and the force power to make sure that a lightsaber is not thrown from close range.
talent GN_CheckThrowLightSaberUsage(object oTarget, talent tUse);
//Checks the target and the force power to make sure that a non-droid force power is used against a droid
talent GN_CheckNonDroidForcePower(object oTarget, talent tUse);
//Performs a series of checks in case the combat portion of DetermineCombatRound falls through.
int GN_DoPostDCRChecks();
//A void version of do post DCR checks for use with action do command.
void GN_ActionDoPostDCRChecks();
//Determine Combat Round Targeting Funtions
//This function returns an object if OBJECT_SELF is poisoned, or if any party member is poisoned.
object GN_CheckIfPoisoned();
//This function returns an object if OBJECT_SELF is below 50% health, or if any party member is injured.
object GN_CheckIfInjured();
//This checks the last hostile target and determines the best attack action based on the last round.
int GN_GetAttackTalentCode(object oTarget);
//Pass in a talent type and a target to have object_self use the talent
int GN_TalentMasterRoutine(int nTalentConstant, object oTarget);
//Determines where in the current combo the character is and what to do next based on AI style, and combat info.
talent GN_GetComboMove(int nBoss = FALSE);
//Plays an Ambient Animation depending on the spawn in condition selected.
void GN_PlayAmbientAnimation();
// This causes peasants to flee when people
int GN_CommonAI();
//Should Commoners run away.  This returns a yes or no based on a set of conditions
int GN_CheckShouldFlee();
void GN_DetermineCombatRound(object oIntruder = OBJECT_INVALID)
{
    GN_MyPrintString("");
    GN_MyPrintString("GENERIC DEBUG *************** START DETERMINE COMBAT ROUND " + GN_ReturnDebugName(OBJECT_SELF));
    GN_SetLastRoundData();
    int nPartyAI = GetPartyAIStyle(); //Determines how the party should react to intruders
    int nNPC_AI = GetNPCAIStyle(OBJECT_SELF); //Determines how the individual should react in combat
    GN_MyPrintString("GENERIC DEBUG *************** AI STYLE = " + GN_ReturnAIStyle());
    if(!GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR)
    && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE)
    && !GN_GetSpawnInCondition(SW_FLAG_AI_OFF)
    //MODIFIED by Preston Watamaniuk on March 27
    //Put this back in to cancel Determine Combat when user actions are present.
    && !GetUserActionsPending())
    {
        if(GetPartyMemberByIndex(0) != OBJECT_SELF && !GetPlayerRestrictMode())
        {
            if((IsObjectPartyMember(OBJECT_SELF) && !GetPlayerRestrictMode()) || !IsObjectPartyMember(OBJECT_SELF))
            {
                if(nNPC_AI == NPC_AISTYLE_MELEE_ATTACK)
                {
                    if(GetIsObjectValid(oIntruder))
                    {
                        ClearAllActions();
                        ActionAttack(oIntruder);
                        return;
                    }
                    else
                    {
                        object oDefault = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
                        if(GetIsObjectValid(oDefault))
                        {
                            ClearAllActions();
                            ActionAttack(oDefault);
                            return;
                        }
                    }
                    return;
                }
                //Always try and run a force field at the beginning of combat.
                if(GN_ActivateForceField() == TRUE)
                {
                    GN_MyPrintString("GENERIC DEBUG *************** Terminating AI from Shields");
                    return;
                }
                //Always try to use Force Resistance at the beginning of combat.
                if(GN_ActivateResistances() == TRUE){return;}
                //P.W. (June 9) - Malak AI put into the generics
                if(GN_GetSpawnInCondition(SW_FLAG_MALAK_AI_ON) == TRUE)
                {
                    if(GN_RunMalakAIRoutine() == TRUE){return;}
                }
                //If the boss flag is set then the creature will run the boss AI first.
                if(GN_GetSpawnInCondition(SW_FLAG_BOSS_AI) == TRUE)
                {
                    if(GN_RunBossAIRoutine(oIntruder) == TRUE){return;}
                }
                if(nNPC_AI == NPC_AISTYLE_DEFAULT_ATTACK)
                {
                     //ACTIVE
                     if(GN_RunDefaultAIRoutine(oIntruder) == TRUE)
                     {
                        return;
                     }
                }
                else if(nNPC_AI == NPC_AISTYLE_GRENADE_THROWER)
                {
                     //ACTIVE
                     if(GN_RunGrenadeAIRoutine(oIntruder) == TRUE){return;}
                }
                else if(nNPC_AI == NPC_AISTYLE_JEDI_SUPPORT)
                {
                     //ACTIVE
                     if(GN_RunJediSupportAIRoutine(oIntruder) == TRUE){return;}
                }
            }
        }
    }
    if(GN_DoPostDCRChecks())
    {
        GN_MyPrintString("GENERIC DEBUG *************** DETERMINE COMBAT ROUND END");
    }
    GN_MyPrintString("GENERIC DEBUG *************** WARNING DETERMINE COMBAT ROUND FAILURE");
}
//::///////////////////////////////////////////////
//:: Do Post Determine Combat Round Checks
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Performs a series of checks in case the combat
    portion of DetermineCombatRound falls through.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 25, 2003
//:://////////////////////////////////////////////
int GN_DoPostDCRChecks()
{
    GN_MyPrintString("GENERIC DEBUG *************** Post DCR Checks for " + GN_ReturnDebugName(OBJECT_SELF));
    if(GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR) && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE))
    {
        //MODIFIED by Preston Watamaniuk on May 29, 2003
        //Changed the commoner subroutine to make sure it walks ways at the end of battles.
        if(GN_CommonAI())
        {
            return TRUE;
        }
    }
    else if(GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Clear 1000");
        ClearAllActions();
        return TRUE;
    }
    //If all combat actions fail, then return to Walkways
    //P.W.(May 22, 2003) - Added check to make sure a waypoint path is set out for the creature. If then do not clear all actions.
    if(!IsObjectPartyMember(OBJECT_SELF) && GN_CheckWalkWays(OBJECT_SELF) == TRUE)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Clear 1100");
        ClearAllActions();
        //MODIFIED by Preston Watamaniuk on May15, 2003
        //Put this delay command in so that bark bubble do not disapear so quickly off conversations.
        DelayCommand(1.0, GN_WalkWayPoints());
        return TRUE;
    }
    else if(GetPartyMemberByIndex(0) != OBJECT_SELF &&
            !GetIsObjectValid(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF,1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN)) &&
            IsObjectPartyMember(OBJECT_SELF))
    {
        if(!GetSoloMode())
        {
            GN_PostString("NO TARGET: FOLLOW LEADER");
            CancelCombat(OBJECT_SELF);
            GN_MyPrintString("GENERIC DEBUG *************** Clear 1200");
            ClearAllActions();
            ActionFollowLeader();
        }
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: GN_ActionDoPostDCRChecks
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    A form of the DCR checks that can be run as
    an actions.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 29, 2003
//:://////////////////////////////////////////////
void GN_ActionDoPostDCRChecks()
{
    int nx = GN_DoPostDCRChecks();
}
//:://////////////////////////////////////////////
//:: Run Default AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Runs the default AI for an NPC. Returns FALSE
    if they cannot do anything.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
int GN_RunDefaultAIRoutine(object oIntruder)
{
    object oTarget, oClose;
    int nTalentCode;
    talent tUse;
    oTarget = GN_CheckIfPoisoned();
    if(GetIsObjectValid(oTarget))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_REMOVE_POISON, oTarget)) {return TRUE;}
    }
    oTarget = GN_CheckIfInjured();
    if(GetIsObjectValid(oTarget))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_HEALING, oTarget)) {return TRUE;}
    }
    tUse = GN_GetComboMove();
    int nFriend = GetLocalBoolean(OBJECT_SELF, SW_FLAG_TARGET_FRIEND);
    if(nFriend == TRUE)
    {
        if(GetNPCAIStyle(OBJECT_SELF) == NPC_AISTYLE_JEDI_SUPPORT)
        {
            oTarget = GetPartyMemberByIndex(0);
        }
        else
        {
            oTarget = OBJECT_SELF;
        }
    }
    else
    {
        oTarget = tPR.oLastTarget;
        oClose = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF,1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
        GN_MyPrintString("GENERIC DEBUG *************** Default AI Debug Start *************************");
        GN_MyPrintString("GENERIC DEBUG *************** Intruder    = " + GN_ReturnDebugName(oIntruder));
        GN_MyPrintString("GENERIC DEBUG *************** Last Target = " + GN_ReturnDebugName(oTarget));
        GN_MyPrintString("GENERIC DEBUG *************** Closest     = " + GN_ReturnDebugName(oClose));
        //GN_MyPrintString("GENERIC DEBUG *************** " + GN_ReturnDebugName(OBJECT_SELF) + "I see an enemy = " + IntToString(GetIsObjectValid(oClose)));
        //MODIFIED by Preston Watamaniuk on June 3, 2003
        //I put this check in to make sure the party members only attack what you want until that things dies or leaves.
        if(IsObjectPartyMember(OBJECT_SELF) && GetIsObjectValid(oTarget) && !GetIsDead(oTarget) && GetObjectSeen(oTarget))
        {
            oTarget = oTarget; //Just put this here to show that the target is being used.
        }
        //MODIFIED by Preston Watamaniuk on May 15, 2003
        //Made it so the intruder object is always used if they can be seen and are valid.
        else if(GetIsObjectValid(oIntruder) && GetObjectSeen(oIntruder))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Intruder becomes Target");
            oTarget = oIntruder;
        }
        else if(GetIsObjectValid(oClose) && GetObjectSeen(oClose))
        {
            if((!GetIsObjectValid(oTarget) ||
               !GetIsEnemy(oTarget) ||
               GetIsDead(oTarget) ||
               GetCurrentHitPoints(oTarget) < GetCurrentHitPoints(oClose)))
               {
                  GN_MyPrintString("GENERIC DEBUG *************** Closest becomes Target");
                  oTarget = oClose;
               }
        }
    }
    //MODIFIED by Preston Watamaniuk on April 22, 2003
    //Put this check in to allow Droids to use their special abilities in a more logical manner. Passes in the talent and the target
    //and double checks that the usage is logical.
    if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID)
    {
        tUse = GN_CheckDroidUtilityUsage(oTarget, tUse);
    }
    tUse = GN_CheckThrowLightSaberUsage(oTarget, tUse);
    tUse = GN_CheckNonDroidForcePower(oTarget, tUse);
    GN_MyPrintString("GENERIC DEBUG *************** Default AI Debug End ***************************");
    GN_MyPrintString("GENERIC DEBUG *************** Target = " + GN_ReturnDebugName(oTarget) + " is Enemy: " + IntToString(GetIsEnemy(oTarget)));
    if(GetIsObjectValid(oTarget))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Clear 1300");
        ClearAllActions();
        if(GN_EquipAppropriateWeapon())
        {
           GN_MyPrintString("GENERIC DEBUG *************** Switching Weapons");
        }
        if(GetIsTalentValid(tUse) && GetIsEnemy(oTarget))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Using Talent on Target");
            ActionUseTalentOnObject(tUse, oTarget);
            return TRUE;
        }
        else if(GetIsEnemy(oTarget))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Action Attack by Default");
            ActionAttack(oTarget);
            return TRUE;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Default AI has failed to do an action");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Jedi Aid AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    AI that concentrates on keeping the party healed,
    poison free.  If the party is doing ok then the Jedi
    will attempt to use Force Powers. If they are unable
    to use force powers they will run default AI.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 20, 2003
//:://////////////////////////////////////////////
int GN_RunAidAIRoutine(object oIntruder = OBJECT_INVALID)
{
    object oPoisoned = GN_CheckIfPoisoned();
    if(GetIsObjectValid(oPoisoned))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_REMOVE_POISON, oPoisoned)) {return TRUE;}
    }
    object oInjured = GN_CheckIfInjured();
    if(GetIsObjectValid(oInjured))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_HEALING, oInjured)) {return TRUE;}
    }
    return GN_RunDefaultAIRoutine(oIntruder);
}
//::///////////////////////////////////////////////
//:: Grenade AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Trys to use a grenades on targets not surrounded
    by enemies
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17, 2003
//:://////////////////////////////////////////////
int GN_RunGrenadeAIRoutine(object oIntruder = OBJECT_INVALID)
{
    if(IsObjectPartyMember(OBJECT_SELF) || d100() > 50)
    {
        int nDroid = FALSE;
        talent tUse;
        object oTarget = GN_FindGrenadeTarget();
        if(GetRacialType(oTarget) == RACIAL_TYPE_DROID)
        {
            nDroid = TRUE;
        }
        tUse = GN_GetGrenadeTalent(nDroid);
        if(GetIsObjectValid(oTarget) && GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Clear 1400");
            ClearAllActions();
            ActionUseTalentOnObject(tUse, oTarget);
            return TRUE;
        }
        GN_MyPrintString("GENERIC DEBUG *************** Grenade AI Failure");
        return GN_RunDefaultAIRoutine(oIntruder);
    }
    GN_MyPrintString("GENERIC DEBUG *************** Grenade AI Fall Through");
    return GN_RunDefaultAIRoutine(oIntruder);
}
//::///////////////////////////////////////////////
//:: Jedi Support
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This will make the Jedi use Force Powers before
    everything else.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17, 2003
//:://////////////////////////////////////////////
int GN_RunJediSupportAIRoutine(object oIntruder = OBJECT_INVALID)
{
    object oPoisoned = GN_CheckIfPoisoned();
    talent tUse;
    object oTarget;
    //P.W (May 27, 2003) - Made a change so that Droids can use Jedi Support. Its just defaul AI with an AI check however.
    if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID)
    {
        return GN_RunDefaultAIRoutine();
    }
    if(GN_TalentMasterRoutine(GEN_TALENT_BUFF, OBJECT_SELF))
    {
        return TRUE;
    }
    if(GetIsObjectValid(oPoisoned))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_REMOVE_POISON, oPoisoned)) {return TRUE;}
    }
    object oInjured = GN_CheckIfInjured();
    if(GetIsObjectValid(oInjured))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_HEALING, oInjured)) {return TRUE;}
    }
    oTarget = GN_FindAOETarget();
    GN_MyPrintString("GENERIC DEBUG *************** Jedi Support AI: AOE Target = " + GN_ITS(GetIsObjectValid(oTarget)));
    if(GetIsObjectValid(oTarget))
    {
        if(GetRacialType(oTarget) == RACIAL_TYPE_DROID)
        {
            tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_FORCE_POWER, TRUE);
        }
        else
        {
            tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_FORCE_POWER);
        }
    }
    else
    {
        GN_MyPrintString("GENERIC DEBUG *************** Jedi Support AI: Inside the Party AI Section");
        oTarget = GN_DetermineAttackTarget();
        GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Initial oFind Search = " + GN_ReturnDebugName(oTarget));
        if(GetIsObjectValid(oTarget))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Jedi Support AI: Valid oTarget Set As = " + GN_ReturnDebugName(oTarget));
            if(GetRacialType(oTarget) == RACIAL_TYPE_DROID)
            {
                tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_NPC, TRUE);
            }
            else
            {
                tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_NPC);
            }
        }
    }
    tUse = GN_CheckThrowLightSaberUsage(oTarget, tUse);
    tUse = GN_CheckNonDroidForcePower(oTarget, tUse);
    if(GetIsObjectValid(oTarget) && GetIsTalentValid(tUse))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Clear 1450");
        ClearAllActions();
        ActionUseTalentOnObject(tUse, oTarget);
        return TRUE;
    }
    GN_MyPrintString("GENERIC DEBUG *************** Jedi Support AI: Fall Through");
    return GN_RunDefaultAIRoutine();
}
//::///////////////////////////////////////////////
//:: Boss AI: Grenade
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Run Boss Grenade AI Routine
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 2, 2003
//:://////////////////////////////////////////////
int GN_RunBossGrenadeAI()
{
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Grenade Function Starting");
    talent tUse;
    object oCheck = GN_FindGrenadeTarget();
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Grenade Target = " + GN_ITS(GetIsObjectValid(oCheck)));
    int nDroid;
    if(GetIsObjectValid(oCheck))
    {
         if(GetRacialType(oCheck) == RACIAL_TYPE_DROID)
         {
            nDroid == TRUE;
         }
         tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_GRENADE, nDroid);
         if(GetIsTalentValid(tUse))
         {
            GN_MyPrintString("GENERIC DEBUG *************** Clear 1460");
            ClearAllActions();
            ActionUseTalentOnObject(tUse, oCheck);
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Success");
            return TRUE;
         }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Failure");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Boss AI: AOE Power
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Run Boss AOE Force Power Routine
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 2, 2003
//:://////////////////////////////////////////////
int GN_RunBossAOEPowerRoutine()
{
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Function Starting");
    talent tUse;
    object oCheck = GN_FindAOETarget();
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Target = " + GN_ITS(GetIsObjectValid(oCheck)));
    int nDroid;
    if(GetIsObjectValid(oCheck))
    {
         if(GetRacialType(oCheck) == RACIAL_TYPE_DROID)
         {
            nDroid == TRUE;
         }
         tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_FORCE_POWER, nDroid);
         if(GetIsTalentValid(tUse))
         {
            ClearAllActions();
            ActionUseTalentOnObject(tUse, oCheck);
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Success");
            return TRUE;
         }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Failure");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Boss AI: Targeting
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This will make boss monsters use targeted
    super powers.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 2, 2003
//:://////////////////////////////////////////////
int GN_RunBossTargetedRoutine()
{
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Start Targeted Action Routine");
    talent tUse;
    object oTarget;
    int nDroid;
    int nRand = d6();
    int nCnt = 1;
    if(nRand < 4){nRand = 1;}
    if(nRand == 4){nRand = 2;}
    if(nRand == 5){nRand = 3;}
    if(nRand == 6){nRand = 4;}
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Get the #" + GN_ITS(nRand) + " target");
    object oFind = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Initial oFind Search = " + GN_ReturnDebugName(oFind));
    while(GetIsObjectValid(oFind) && nCnt <= nRand)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Valid oFind = " + GN_ReturnDebugName(oFind) + " nCnt = " + GN_ITS(nCnt));
        if(GetIsObjectValid(oFind))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Valid oTarget Set As = " + GN_ReturnDebugName(oFind));
            oTarget = oFind;
        }
        nCnt++;
        oFind = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
    }
    //DEBUG STATEMENTS
    int nX = TRUE;
    if(nX == TRUE)
    {
        if(GetIsTalentValid(tUse))
        {
            if(GetTypeFromTalent(tUse) == TALENT_TYPE_FEAT)
            {
                GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Talent Feat = " + GN_ITS(GetIdFromTalent(tUse)));
            }
            else if(GetTypeFromTalent(tUse) == TALENT_TYPE_FORCE)
            {
                GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Talent Power = " + GN_ITS(GetIdFromTalent(tUse)));
            }
        }
    }
    if(GetIsObjectValid(oTarget))
    {
        if(GetRacialType(oTarget) == RACIAL_TYPE_DROID)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Get Boss Combat Move AI Droid");
            nDroid = TRUE;
        }
        tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_NPC, nDroid);
        tUse = GN_CheckThrowLightSaberUsage(oTarget, tUse);
        tUse = GN_CheckNonDroidForcePower(oTarget, tUse);
        //MODIFIED by Preston Watamaniuk on April 2, 2003
        //Added this check to make the Droid setting was used for non-specific attacks.
        GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Target = " + GN_ITS(GetIsObjectValid(oTarget)));
        GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Talent = " + GN_ITS(GetIsTalentValid(tUse)));
        if(GetIsTalentValid(tUse) && GetIsObjectValid(oTarget))
        {
            ClearAllActions();
            ActionUseTalentOnObject(tUse, oTarget);
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Targeted Power Success");
            return TRUE;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Targeted Failure");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Boss AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This will make boss monsters buff themselves
    and use more force powers or utility devices
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 31, 2003
//:://////////////////////////////////////////////
int GN_RunBossAIRoutine(object oIntruder = OBJECT_INVALID)
{
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI Start");
    object oTarget = GN_CheckIfInjured();
    if(GetIsObjectValid(oTarget))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_HEALING, oTarget)) {return TRUE;}
    }
    if(GN_EquipAppropriateWeapon())
    {
       GN_MyPrintString("GENERIC DEBUG *************** Switching Weapons");
    }
    if(GN_RunBossGrenadeAI() == TRUE) {return TRUE;}
    else if(GN_RunBossAOEPowerRoutine() == TRUE) {return TRUE;}
    else if(GN_RunBossTargetedRoutine() ==  TRUE) {return TRUE;}
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Fall Through");
    return GN_RunDefaultAIRoutine();
}
//::///////////////////////////////////////////////
//:: Malak AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This AI is just for Darth Malak on the Star
    Forge. It assumes there is only the PC and
    no one else.
    Malak's Force Powers
        Master Speed
        Force Push
        Throw Lightsaber (15)
        Affliction
        Force Resistance
        Imp. Energy Resist
        Lightning (15)
        Force Breach
    This routine is an add-on for boss ai.  It
    tests certain conditions that could be
    occurring in the Malak fight and reacts to them
    in a more agressive manner.
    1. K_END_JEDI_LEFT - Will track the total number
       of entombed Jedi left in the fight.
    2. K_END_MALAK_JEDI_USED - Will track the number
    of Jedi's Malak has personally used in the fight.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 29, 2003
//:://////////////////////////////////////////////
int GN_RunMalakAIRoutine()
{
    GN_MyPrintString("GENERIC DEBUG *************** Malak AI Start");
    int nJediLeft = GetGlobalNumber("K_END_JEDI_LEFT");
    int nMalakUsed = GetGlobalNumber("K_END_MALAK_JEDI_USED");
    object oPC = GetFirstPC();
    int bJedi, bDist, bAttack;
    float fDist = GetDistanceBetween(OBJECT_SELF, oPC);
    //Check to see if Malak need to become more aggressive
    //Test the number of Jedi to see if the player has used any
    if(((8 - nJediLeft) < nMalakUsed))
    {
        bJedi = TRUE;
    }
    //Check to see if the player is running away
    GN_MyPrintString("GENERIC DEBUG *************** Malak Distance to PC = " + FloatToString(GetDistanceBetween(OBJECT_SELF, oPC),4,4));
    if(fDist > 10.0)
    {
        bDist = TRUE;
    }
    if(bDist == TRUE)
    {
        /*
            AI REACTION 2 - Player is keeping his distance.
            1. Force Breach if the player is using speed
            OR
            2. Use Action Attack to Force Jump
        */
        GN_MyPrintString("GENERIC DEBUG *************** Clear 1480");
        ClearAllActions();
        if(GetHasSpellEffect(FORCE_POWER_SPEED_BURST, oPC) ||
           GetHasSpellEffect(FORCE_POWER_KNIGHT_SPEED, oPC) ||
           GetHasSpellEffect(FORCE_POWER_SPEED_MASTERY, oPC))
        {
            talent tBreach = TalentSpell(FORCE_POWER_FORCE_BREACH);
            if(GetIsTalentValid(tBreach))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Using Breach");
                ActionUseTalentOnObject(tBreach, oPC);
            }
            bAttack = TRUE;
        }
        else
        {
            if(fDist > 10.0)
            {
                int nRoll = d3();
                int nPower = -1;
                if(nRoll == 1)
                {
                    nPower = FORCE_POWER_LIGHTNING;
                }
                else if(nRoll == 2)
                {
                    nPower = FORCE_POWER_LIGHT_SABER_THROW;
                }
                else if(nRoll > 2)
                {
                    bAttack = TRUE;
                }
                if(nPower != -1)
                {
                    talent tPower = TalentSpell(nPower);
                    if(GetIsTalentValid(tPower))
                    {
                        GN_MyPrintString("GENERIC DEBUG *************** Malak Using Force Power");
                        ActionUseTalentOnObject(tPower, oPC);
                        return TRUE;
                    }
                }
            }
            bAttack = TRUE;
        }
    }
    if(bAttack == TRUE)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Malak Attacking");
        ActionAttack(oPC);
        return TRUE;
    }
    GN_MyPrintString("GENERIC DEBUG *************** Malak AI Drop Out");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Shield Activation
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Organic Shields are 99 to 107
    Droid shields are 110 to 115
    Scans through all of the shield talents to
    see if the target has a shield to use. If the
    shield is used then the person will never use
    another one. Party members will never use this
    function.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 31, 2003
//:://////////////////////////////////////////////
int GN_ActivateForceField()
{
    GN_MyPrintString("GENERIC DEBUG *************** Starting Forcefield Search");
    GN_MyPrintString("GENERIC DEBUG *************** Shield Boolean (" + GN_ITS(SW_FLAG_SHIELD_USED) + ") = " + GN_ITS(GN_GetSpawnInCondition(SW_FLAG_SHIELD_USED)));
    if(GN_GetSpawnInCondition(SW_FLAG_SHIELD_USED) == FALSE && !IsObjectPartyMember(OBJECT_SELF))
    {
        int nCnt, nStop;
        int bValid = FALSE;
        talent tShield;
        if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID)
        {
            nCnt = 110;
            nStop = 115;
        }
        else
        {
            nCnt = 99;
            nStop = 107;
        }
        while(bValid == FALSE && nCnt <= nStop)
        {
            tShield = TalentSpell(nCnt);
            if(GetCreatureHasTalent(tShield))
            {
                bValid = TRUE;
            }
            else
            {
                nCnt++;
            }
        }
        if(GetCreatureHasTalent(tShield))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Clear 1700");
            ClearAllActions();
            ActionUseTalentOnObject(tShield, OBJECT_SELF);
            GN_SetSpawnInCondition(SW_FLAG_SHIELD_USED);
            return TRUE;
        }
        else
        {
            GN_MyPrintString("GENERIC DEBUG *************** Forcefield Search Fallthrough");
            GN_SetSpawnInCondition(SW_FLAG_SHIELD_USED);
            return FALSE;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Forcefield Search Fallthrough");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Resistance Activation
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    20 Resist Force
    41 Force Immunity
    Checks to see if the character has resist force
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 31, 2003
//:://////////////////////////////////////////////
//Makes the person activate Resist Elements and Resist Force.
int GN_ActivateResistances()
{
    int bValid = FALSE;
    if(GN_GetSpawnInCondition(SW_FLAG_RESISTANCES_APPLIED) == FALSE && !IsObjectPartyMember(OBJECT_SELF))
    {
        if(GetHitDice(GetFirstPC()) >= 15 || GN_GetSpawnInCondition(SW_FLAG_BOSS_AI))
        {
            talent tResist = TalentSpell(FORCE_POWER_RESIST_FORCE);
            talent tImmune = TalentSpell(FORCE_POWER_FORCE_IMMUNITY);
            talent tUse;
            if(GetCreatureHasTalent(tImmune))
            {
                tUse = tImmune;
                bValid = TRUE;
            }
            else if(GetCreatureHasTalent(tResist))
            {
                tUse = tResist;
                bValid = TRUE;
            }
            if(bValid == TRUE)
            {
                GN_MyPrintString("GENERIC DEBUG *************** Clear 1710");
                ClearAllActions();
                ActionUseTalentOnObject(tUse, OBJECT_SELF);
            }
            GN_SetSpawnInCondition(SW_FLAG_RESISTANCES_APPLIED);
        }
    }
    return bValid;
}
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Respond to Shout                                           ========  =       =   =======   =       =  =========   ========
//:: Copyright (c) 2001 Bioware Corp.                          =          =       =  =       =  =       =      =      =
//:://////////////////////////////////////////////             =          =       =  =       =  =       =      =      =
/*//                                                           =          =       =  =       =  =       =      =      =
    Catches the shouts and determines the best                 =========  =========  =       =  =       =      =      =========
    course of action for them                                          =  =       =  =       =  =       =      =              =
                                                                       =  =       =  =       =  =       =      =              =
    SetListenPattern(OBJECT_SELF, "GEN_I_WAS_ATTACKED", 1);            =  =       =  =       =  =       =      =              =
    SetListenPattern(OBJECT_SELF, "GEN_I_SEE_AN_ENEMY", 15);   ========   =       =   =======     ======       =      ========
*///
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 16, 2002
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void GN_RespondToShout(object oShouter, int nShoutIndex, object oIntruder = OBJECT_INVALID)
{
    GN_MyPrintShoutString("");
    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Respond to Shout Started for " + GN_ReturnDebugName(OBJECT_SELF));
    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Intruder Object = " + GN_ReturnDebugName(oIntruder));
    int nFLAG; //This determines whether the object walksway points instead of attacking.
    int nPartyAI = GetPartyAIStyle(); //Determines how the party should react to intruders
    int nNPC_AI = GetNPCAIStyle(OBJECT_SELF); //Determines how the individual should react in combat
    //MODIFIED by Preston Watamaniuk May 9
    //Put this check into disable shouts being heard by people from different combat zones.
    if(GetLocalNumber(oShouter, SW_NUMBER_COMBAT_ZONE) == GetLocalNumber(OBJECT_SELF, SW_NUMBER_LAST_COMBO) ||
       GetLocalNumber(oShouter, SW_NUMBER_COMBAT_ZONE) == 0 ||
       GetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBAT_ZONE) == 0 ||
       IsObjectPartyMember(OBJECT_SELF))
    {
        if(!GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR)
           && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE)
           && !GN_GetSpawnInCondition(SW_FLAG_AI_OFF)
           && !GetUserActionsPending())
        {
            GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Check 1 Pass");
            if(nShoutIndex == 1 && GetIsFriend(oShouter) && oShouter != OBJECT_SELF)
            {
                if((IsObjectPartyMember(OBJECT_SELF) && IsObjectPartyMember(oShouter) && GetSoloMode() == FALSE) ||
                    !IsObjectPartyMember(OBJECT_SELF))
                {
                    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Check 2 Pass");
                    if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()) && !GetIsObjectValid(GetAttackTarget()))
                    {
                        GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Check 3 Pass");
                        if(GetPartyMemberByIndex(0) != OBJECT_SELF && nPartyAI != PARTY_AISTYLE_PASSIVE && !GetPlayerRestrictMode())
                        {
                            GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Check 3 Pass");
                            if((IsObjectPartyMember(OBJECT_SELF) && !GetPlayerRestrictMode()) || !IsObjectPartyMember(OBJECT_SELF))
                            {
                                GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Check 5 Pass");
                                GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Intruder = " + GN_ReturnDebugName(oIntruder));
                                if(GetObjectSeen(oIntruder))
                                {
                                    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Shout: Determine Combat Round");
                                    GN_MyPrintString("GENERIC SHOUT DEBUG *************** Shout Clear 1800");
                                    ClearAllActions();
                                    GN_DetermineCombatRound(oIntruder);
                                }
                                else if(GetIsObjectValid(oIntruder))
                                {
                                    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Shout: Move To Intruder");
                                    GN_MyPrintString("GENERIC SHOUT DEBUG ***************= Shout Clear 1900");
                                    ClearAllActions();
                                    float fDistance = 5.0;
                                    /*
                                    if(!GetObjectSeen(oIntruder))
                                    {
                                        fDistance = 3.0;
                                    }
                                    */
                                    //P.W. (June 8) - Put this check in to try and reduce the instances of NPCs running right up
                                    //to their enemies with blasters.
                                    if(GetDistanceBetween(OBJECT_SELF, oIntruder) < 20.0 && !GetObjectSeen(oIntruder))
                                    {
                                        ActionMoveToObject(oIntruder, TRUE, 2.0);
                                    }
                                    else
                                    {
                                        if(GN_GetWeaponType(OBJECT_SELF) == 1)
                                        {
                                            ActionMoveToObject(oIntruder, TRUE, 4.0);
                                        }
                                        else
                                        {
                                            ActionMoveToObject(oIntruder, TRUE, 15.0);
                                        }
                                    }
                                }
                                //MODIFIED by Preston Watamaniuk on May 16th
                                //Added this check to make Party Members attack after the PC engages in combat.
                                else if(IsObjectPartyMember(OBJECT_SELF))
                                {
                                    oIntruder = GetAttackTarget(oShouter);
                                    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Attack Intruder = " + GN_ReturnDebugName(oIntruder));
                                    if(GetIsObjectValid(oIntruder))
                                    {
                                        GN_DetermineCombatRound(oIntruder);
                                    }
                                    else
                                    {
                                        oIntruder = GetSpellTarget(oShouter);
                                        GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Spell Intruder = " + GN_ReturnDebugName(oIntruder));
                                        if(GetIsObjectValid(oIntruder))
                                        {
                                            GN_DetermineCombatRound(oIntruder);
                                        }
                                    }
                                }
                            }
                            //I AM IN COMBAT
                            else if(nShoutIndex == 15 && GetIsFriend(oShouter) && oShouter != OBJECT_SELF)
                            {
                                if(GetCurrentAction(OBJECT_SELF) == ACTION_INVALID)
                                {
                                    if(GetObjectSeen(oIntruder))
                                    {
                                        GN_MyPrintString("GENERIC SHOUT DEBUG *************** Clear 2000");
                                        ClearAllActions();
                                        GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Attack Intruder = " + GN_ReturnDebugName(oIntruder));
                                        GN_DetermineCombatRound(oIntruder);
                                        //GN_SetSpawnInCondition(SW_FLAG_SHOUTED_AT);
                                    }
                                    else if(GetIsObjectValid(oIntruder))
                                    {
                                        GN_MyPrintString("GENERIC SHOUT DEBUG *************** Clear 2100");
                                        ClearAllActions();
                                        ActionMoveToObject(oIntruder, TRUE, 5.0);
                                        //GN_SetSpawnInCondition(SW_FLAG_SHOUTED_AT);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        else if(GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE))
        {
            GN_MyPrintString("GENERIC SHOUT DEBUG *************** Clear 2200");
            ClearAllActions();
            return;
        }
    }
    /*
    if(!GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR)
       && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE)
       && !GN_GetSpawnInCondition(SW_FLAG_AI_OFF))
    {
        if(GetPartyMemberByIndex(0) != OBJECT_SELF && nPartyAI != PARTY_AISTYLE_PASSIVE && !GetPlayerRestrictMode())
        {
            //P.W.(June 5) It looks stupid, but do not take this out.
            if(GetCurrentAction(OBJECT_SELF) == ACTION_QUEUEEMPTY && !GetUserActionsPending() && !IsObjectPartyMember(OBJECT_SELF))
            {
                if((IsObjectPartyMember(OBJECT_SELF) && IsObjectPartyMember(oShouter) && GetSoloMode() == FALSE) ||
                    !IsObjectPartyMember(OBJECT_SELF))
                {
                    GN_MyPrintString("GENERIC SHOUT DEBUG *************** Hail Mary activated by " + GN_ReturnDebugName(OBJECT_SELF));
                    GN_MyPrintString("GENERIC SHOUT DEBUG *************** Hail Mary Shout Clear 2110");
                    GN_DetermineCombatRound();
                }
            }
        }
    }
    */
    GN_MyPrintShoutString("");
}
//::///////////////////////////////////////////////
//:: SetListeningPatterns
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the correct listen checks on the NPC by
    determining what talents they possess or what
    class they use.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 24, 2001
//:://////////////////////////////////////////////
void GN_SetListeningPatterns()
{
    SetListening(OBJECT_SELF, TRUE);
    SetListenPattern(OBJECT_SELF, "GEN_I_WAS_ATTACKED", 1);
    SetListenPattern(OBJECT_SELF, "GEN_I_AM_DEAD", 3);
    SetListenPattern(OBJECT_SELF, "GEN_CALL_TO_ARMS", 6);
    if(GetHasSpell(FORCE_POWER_SUPRESS_FORCE) || GetHasSpell(FORCE_POWER_FORCE_BREACH))
    {
        SetListenPattern(OBJECT_SELF, "GEN_SUPRESS_FORCE", 9);
    }
    SetListenPattern(OBJECT_SELF, "GEN_GRENADE_TOSSED", 12);
    SetListenPattern(OBJECT_SELF, "GEN_I_SEE_AN_ENEMY", 14);
    SetListenPattern(OBJECT_SELF, "GEN_COMBAT_ACTIVE", 15);
    GN_SetUpWayPoints();
    string sTag = GetTag(OBJECT_SELF);
    if(sTag != "Carth" &&
       sTag != "Bastila" &&
       sTag != "Cand" &&
       sTag != "HK47" &&
       sTag != "Jolee" &&
       sTag != "Juhani" &&
       sTag != "Mission" &&
       sTag != "T3M4" &&
       sTag != "Zaalbar" &&
       !GetIsPC(OBJECT_SELF))
    {
        DR_SpawnCreatureTreasure(OBJECT_SELF);
    }
    //MODIFIED by Preston Watamaniuk on May 8, 2003
    //Added functionality for dynamic or encounter creatures
    //to latch onto a Zone Controller.
    //GN_MyPrintString("ZONE DEBUG *****************" + IntToString(GetIsEncounterCreature()) + " " + GN_ReturnDebugName(OBJECT_SELF));
    if(GN_GetSpawnInCondition(SW_FLAG_DYNAMIC_COMBAT_ZONE) || GetIsEncounterCreature())
    {
        string sController;
        int nCount = 1;
        object oController, oTest;
        float fNear;
        float fClosest = 100.0;
        for(nCount; nCount < 40; nCount++)
        {
            if(nCount < 10)
            {
                sController = "ZoneController" + "0" + IntToString(nCount);
            }
            else
            {
                sController = "ZoneController" + IntToString(nCount);
            }
            oTest = GetObjectByTag(sController);
            if(GetIsObjectValid(oTest))
            {
                fNear = GetDistanceBetween(OBJECT_SELF, oTest);
                //GN_MyPrintString("ZONING DEBUG ***************** Controller Distance = " + GN_ReturnDebugName(oController) + " " + FloatToString(fNear, 4, 2));
                if(fNear < fClosest)
                {
                    fClosest = fNear;
                    oController = oTest;
                }
            }
        }
        if(GetIsObjectValid(oController) && fClosest < 30.0)
        {
            //GN_MyPrintString("ZONING DEBUG ***************** Setup Controller = " + GN_ReturnDebugName(oController));
            int nZone = StringToInt(GetStringRight(GetTag(oController), 2));
            SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBAT_ZONE, nZone);
        }
    }
}
//::///////////////////////////////////////////////
//:: Check for Poison
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks if someone in the party is poisoned.
    If the person is a non-party NPC then they
    check if they are poisoned.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
object GN_CheckIfPoisoned()
{
    GN_MyPrintString("GENERIC DEBUG *************** Starting Poison Check");
    effect ePoison;
    if(IsObjectPartyMember(OBJECT_SELF))
    {
        int nCnt = 0;
        for(nCnt; nCnt > 2; nCnt++)
        {
            ePoison = GetFirstEffect(GetPartyMemberByIndex(nCnt));
            while(GetIsEffectValid(ePoison))
            {
                if(GetEffectType(ePoison) == EFFECT_TYPE_POISON)
                {
                    return GetPartyMemberByIndex(nCnt);
                }
                ePoison = GetNextEffect(GetPartyMemberByIndex(nCnt));
            }
        }
    }
    else
    {
        ePoison = GetFirstEffect(OBJECT_SELF);
        while(GetIsEffectValid(ePoison))
        {
            if(GetEffectType(ePoison) == EFFECT_TYPE_POISON)
            {
                return OBJECT_SELF;
            }
            ePoison = GetNextEffect(OBJECT_SELF);
        }
    }
    GN_MyPrintString("GENERIC DEBUG ***************  Returning Invalid Poison Object");
    return OBJECT_INVALID;
}
//::///////////////////////////////////////////////
//:: Check for Injuries
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns member index +1 or false depending on
    whether the object belongs in the PCs party.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
object GN_CheckIfInjured()
{
    GN_MyPrintString("GENERIC DEBUG ***************  Starting Injury Check Function");
    if(IsObjectPartyMember(OBJECT_SELF) || GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID)
    {
        object oP0=GetPartyMemberByIndex(0);
        object oP1=GetPartyMemberByIndex(1);
        object oP2=GetPartyMemberByIndex(2);
        float fDown00 = 10.0;
        float fDown01 = 10.0;
        float fDown02 = 10.0;
        if(GetIsObjectValid(oP0) && GetRacialType(oP0) != RACIAL_TYPE_DROID)
        {
            fDown00 = IntToFloat(GetCurrentHitPoints(oP0)) / IntToFloat(GetMaxHitPoints(oP0));
        }
        if(GetIsObjectValid(oP1)&& GetRacialType(oP0) != RACIAL_TYPE_DROID)
        {
            fDown01 = IntToFloat(GetCurrentHitPoints(oP1)) / IntToFloat(GetMaxHitPoints(oP1));
        }
        if(GetIsObjectValid(oP2) && GetRacialType(oP0) != RACIAL_TYPE_DROID)
        {
            fDown02 = IntToFloat(GetCurrentHitPoints(oP2)) / IntToFloat(GetMaxHitPoints(oP2));
        }
        if(GetIsObjectValid(oP0) && !GetIsDead(oP0) && (fDown00 < 0.5 && fDown00 > 0.0))
        {
            GN_MyPrintString("GENERIC DEBUG ***************  Return oP0");
            return oP0;
        }
        else if(GetIsObjectValid(oP1) && !GetIsDead(oP1) && (fDown00 < 0.5 && fDown00 > 0.0))
        {
            GN_MyPrintString("GENERIC DEBUG ***************  Return oP1");
            return oP1;
        }
        else if(GetIsObjectValid(oP2) && !GetIsDead(oP2) && (fDown00 < 0.5 && fDown00 > 0.0))
        {
            GN_MyPrintString("GENERIC DEBUG ***************  Return oP2");
            return oP2;
        }
    }
    else
    {
        float fNPC = IntToFloat(GetCurrentHitPoints(OBJECT_SELF)) / IntToFloat(GetMaxHitPoints(OBJECT_SELF));
        if(fNPC < 0.5)
        {
            return OBJECT_SELF;
        }
    }
    return OBJECT_INVALID;
}
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Generic Talent Routines
//:: Copyright (c) 2001 Bioware Corp.
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int GN_TalentMasterRoutine(int nTalentConstant, object oTarget)
{
    if(GetIsObjectValid(oTarget))
    {
        talent tSpe11_01, tSpe11_02, tSpe11_03, tSpe11_04, tSpe11_05, tSpe11_06, tSpe11_07, tUse;
        int nTalent;
        int bValid = FALSE;
        int bHostile = FALSE;
        if(nTalentConstant == GEN_TALENT_SUPRESS_FORCE)
        {
            nTalent = 0xf021; //Any Area, No Harmful, Dispel, Ranged
        }
        else if(nTalentConstant == GEN_TALENT_REMOVE_POISON)
        {
            bValid = FALSE;
            tSpe11_01 = TalentSpell(FORCE_POWER_HEAL);
            tSpe11_02 = TalentSpell(FORCE_POWER_CURE);
            tSpe11_03 = TalentSpell(67); //Remove Poison Item
            if(GetCreatureHasTalent(tSpe11_01) || GetCreatureHasTalent(tSpe11_02))
            {
                bValid = TRUE;
                if(GetCreatureHasTalent(tSpe11_01))
                {
                    tUse = tSpe11_01;
                }
                else
                {
                    tUse = tSpe11_02;
                }
            }
            else if(GetCreatureHasTalent(tSpe11_03) && oTarget == OBJECT_SELF)
            {
                bValid = TRUE;
                tUse = tSpe11_03;
            }
            //nTalent = 0xff4f;
        }
        else if(nTalentConstant == GEN_TALENT_HEALING)
        {
            bValid = FALSE;
            GN_MyPrintString("GENERIC DEBUG *************** Starting Heal Talent Checks " + GN_ReturnDebugName(OBJECT_SELF));
            tSpe11_01 = TalentSpell(FORCE_POWER_HEAL);
            tSpe11_02 = TalentSpell(FORCE_POWER_CURE);
            if(GetRacialType(OBJECT_SELF) != RACIAL_TYPE_DROID)
            {
                tSpe11_05 = GetCreatureTalentBest(0x1408, 20);
            }
            else
            {
                tSpe11_05 = TalentSpell(128);
                if(!GetCreatureHasTalent(tSpe11_05))
                {
                    tSpe11_05 = TalentSpell(127);
                    if(!GetCreatureHasTalent(tSpe11_05))
                    {
                        tSpe11_05 = TalentSpell(84);
                    }
                }
            }
            tSpe11_06 = TalentSpell(FORCE_POWER_DRAIN_LIFE);
            tSpe11_07 = TalentSpell(FORCE_POWER_DEATH_FIELD);
            tUse;
            bValid = FALSE;
            if(GetCreatureHasTalent(tSpe11_01) || GetCreatureHasTalent(tSpe11_02))
            {
                GN_MyPrintString("GENERIC DEBUG *************** I have Heal or Cure");
                bValid = TRUE;
                if(GetCreatureHasTalent(tSpe11_01))
                {
                    tUse = tSpe11_01;
                }
                else
                {
                    tUse = tSpe11_02;
                }
            }
            else if(GetIsTalentValid(tSpe11_05) ||
                    GetCreatureHasTalent(tSpe11_06) ||
                    GetCreatureHasTalent(tSpe11_07))
            {
                if(oTarget == OBJECT_SELF)
                {
                    if(GetCreatureHasTalent(tSpe11_07) && !IsObjectPartyMember(OBJECT_SELF))
                    {
                        GN_MyPrintString("GENERIC DEBUG *************** I have Death Field");
                        bValid = TRUE;
                        bHostile = TRUE;
                        tUse = tSpe11_07;
                    }
                    else if(GetCreatureHasTalent(tSpe11_06) && !IsObjectPartyMember(OBJECT_SELF))
                    {
                        GN_MyPrintString("GENERIC DEBUG *************** I have Drain Life");
                        bValid = TRUE;
                        bHostile = TRUE;
                        tUse = tSpe11_06;
                    }
                    else
                    {
                        GN_MyPrintString("GENERIC DEBUG *************** I have a Med Pack");
                        bValid = TRUE;
                        tUse = tSpe11_05;
                    }
                }
            }
        }
        else if(nTalentConstant == GEN_TALENT_BUFF)
        {
            bValid = FALSE;
            tSpe11_01 = TalentSpell(36); //Master Valor
            tSpe11_02 = TalentSpell(33); //Knight Valor
            tSpe11_03 = TalentSpell(22); //Valor
            int bBuff = FALSE;
            if(GetCreatureHasTalent(tSpe11_01))
            {
                bBuff = TRUE;
                tUse = tSpe11_01;
            }
            else if(GetCreatureHasTalent(tSpe11_02))
            {
                bBuff = TRUE;
                tUse = tSpe11_02;
            }
            else if(GetCreatureHasTalent(tSpe11_03))
            {
                bBuff = TRUE;
                tUse = tSpe11_03;
            }
            GN_MyPrintString("GENERIC DEBUG *************** Spell Effect 22" + GN_ITS(GetHasSpellEffect(22)));
            GN_MyPrintString("GENERIC DEBUG *************** Spell Effect 33" + GN_ITS(GetHasSpellEffect(33)));
            GN_MyPrintString("GENERIC DEBUG *************** Spell Effect 36" + GN_ITS(GetHasSpellEffect(36)));
            if(!GetHasSpellEffect(22) &&
               !GetHasSpellEffect(33) &&
               !GetHasSpellEffect(36) &&
               bBuff == TRUE)
            {
                GN_MyPrintString("GENERIC DEBUG *************** I do have VALOR");
                bValid = TRUE;
            }
            else
            {
                GN_MyPrintString("GENERIC DEBUG *************** I do not have VALOR");
                bValid = FALSE;
            }
        }
        if(bValid == TRUE && bHostile == FALSE)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Clear 2300");
            int nSpell = GetIdFromTalent(tUse);
            GN_MyPrintString("GENERIC DEBUG *************** Spells.2DA ID = " + GN_ITS(nSpell));
            ClearAllActions();
            ActionUseTalentOnObject(tUse, OBJECT_SELF);
            return TRUE;
        }
        else if(bValid == TRUE && bHostile == TRUE)
        {
            oTarget = GN_GetActivePartyMember(TRUE);
            if(GetIsObjectValid(oTarget))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Hostile Heal Targeted On: " + GN_ReturnDebugName(oTarget));
                GN_MyPrintString("GENERIC DEBUG *************** Clear 2400");
                ClearAllActions();
                ActionUseTalentOnObject(tUse, oTarget);
                return TRUE;
            }
        }
        talent tUse2 = GetCreatureTalentBest(nTalent, 20);
        if(GetIsTalentValid(tUse) && !GetHasSpellEffect(GetIdFromTalent(tUse)))
        {
            if(GetIsObjectValid(oTarget))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Clear 2500");
                ClearAllActions();
                GN_MyPrintString("GENERIC DEBUG *************** Target = " + GetName(oTarget) + " Talent Code = " + IntToString(nTalent));
                ActionUseTalentOnObject(tUse, OBJECT_SELF);
                return TRUE;
            }
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** " + GN_ReturnDebugName(OBJECT_SELF) + " VP = " + GN_ITS(GetCurrentHitPoints())+ "/" + GN_ITS(GetMaxHitPoints()) );
    GN_MyPrintString("GENERIC DEBUG *************** Healing Not Used");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Last Round Setup
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the following struct up so that Last Rounds
    information is easier to access.
    int nLastAction;
    int nLastActionID;
    int nLastTalentCode;
    object oLastTarget;
    int nTalentSuccessCode;
    int nIsLastTargetDebil;
    int nLastCombo;
    int nLastComboIndex;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 26, 2002
//:://////////////////////////////////////////////
void GN_SetLastRoundData()
{
     talent tTalent;
     tPR.oLastTarget = GetLastHostileTarget();
     tPR.nIsLastTargetDebil = GetIsDebilitated(tPR.oLastTarget);
     tPR.nLastAction = GetLastAttackAction();
     if(tPR.nLastAction == ACTION_CASTSPELL)
     {
        tPR.nLastActionID = GetLastForcePowerUsed();
        tPR.nTalentSuccessCode = GetWasForcePowerSuccessful();
        tTalent = TalentSpell(tPR.nLastActionID);
        tPR.nLastTalentCode = GetCategoryFromTalent(tTalent);
     }
     else if(tPR.nLastAction == ACTION_ATTACKOBJECT)
     {
        tPR.nLastActionID = GetLastCombatFeatUsed();
        tPR.nTalentSuccessCode = GetLastAttackResult();
        tTalent = TalentFeat(tPR.nLastActionID);
        tPR.nLastTalentCode = GetCategoryFromTalent(tTalent);
     }
     //tPR.nLastCombo = GetLocalNumber(OBJECT_SELF, SW_NUMBER_LAST_COMBO);
     tPR.nLastComboIndex = GetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX);
     tPR.nCurrentCombo = GetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE);
}
//::///////////////////////////////////////////////
//:: Combo Sub Routine
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This function determines what move to do
    based on the last part of the combo performed.
    int nLastAction;
    int nLastActionID;
    int nLastTalentCode;
    object oLastTarget;
    int nTalentSuccessCode;
    int nIsLastTargetDebil;
    int nLastCombo;
    int nLastComboIndex;
    int nCurrentCombo;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 27, 2002
//:://////////////////////////////////////////////
talent GN_GetComboMove(int nBoss = FALSE)
{
    int nRand;
    int nCombo;
    talent tUse;
    int nNPC_AI = GetNPCAIStyle(OBJECT_SELF); //Determines how the individual should react in combat
    GN_MyPrintString("GENERIC DEBUG *************** Starting GetComboMove");
    //Is the last combo done?
    if(tPR.nLastComboIndex == 4 || tPR.nLastComboIndex == 0)
    {
        //If so then set the local numbers controlling the combo to 0;
        SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, 0);
        SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE, 0);
        nRand = d6();
        if(nRand > 0)//This nRand check is place here in case we need to limit combo use later
        {
            //If a Jedi use the jedi routines.
            if(GetLevelByClass(CLASS_TYPE_JEDICONSULAR) > 0 ||
               GetLevelByClass(CLASS_TYPE_JEDIGUARDIAN) > 0 ||
               GetLevelByClass(CLASS_TYPE_JEDISENTINEL) > 0)
            {
                nCombo = GN_GetStandardJediCombo(nBoss);
                GN_MyPrintString("GENERIC DEBUG *************** Starting Jedi Combo " + GN_FetchComboString(nCombo));
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, 1);
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE, nCombo);
                return GN_GetNextTalentInCombo(nCombo);
            }
            //If a Droid use these routines
            else if(GetLevelByClass(CLASS_TYPE_COMBATDROID) > 0 ||
                    GetLevelByClass(CLASS_TYPE_EXPERTDROID) > 0)
            {
                nCombo = GN_GetStandardDroidCombo(nBoss);
                GN_MyPrintString("GENERIC DEBUG *************** Starting Droid Combo " + GN_FetchComboString(nCombo));
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, 1);
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE, nCombo);
                return GN_GetNextTalentInCombo(nCombo);
            }
            //All others.
            else
            {
                nCombo = GN_GetStandardNPCCombo(nBoss);
                GN_MyPrintString("GENERIC DEBUG *************** Starting NPC Combo " + GN_FetchComboString(nCombo));
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, 1);
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE, nCombo);
                return GN_GetNextTalentInCombo(nCombo);
            }
        }
        else//returning an invalid Talent here will mean action attack.
        {
            return tUse;
        }
    }
    else//if(tPR.nTalentSuccessCode > 0)
    {
        //If the PC is already in a combo then continue that combo
        GN_MyPrintString("GENERIC DEBUG *************** Continuing Combo " + GN_FetchComboString(tPR.nCurrentCombo));
        return GN_GetNextTalentInCombo(tPR.nCurrentCombo);
    }
    return tUse;
}
//::///////////////////////////////////////////////
//:: Check Droid Utility Usage
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the target and the droid utility use
    to make sure they are compatible
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 22, 2003
//:://////////////////////////////////////////////
talent GN_CheckDroidUtilityUsage(object oTarget, talent tUse)
{
    int bSwitch;
    GN_MyPrintString("GENERIC DEBUG *************** Starting Droid Talent Double Check");
    if(GetTypeFromTalent(tUse) == TALENT_TYPE_FORCE)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Droid Talent is a Spell");
        if(GetIdFromTalent(tUse) == 116 || GetIdFromTalent(tUse) == 117) //STUN RAY
        {
            if(GetRacialType(oTarget) == RACIAL_TYPE_HUMAN)
            {
                return tUse;
            }
            else
            {
                bSwitch = TRUE;
            }
        }
        if(GetIdFromTalent(tUse) == 118 || GetIdFromTalent(tUse) == 119) //SHIELD DISRUPTOR
        {
            if(GetHasSpellEffect(99, oTarget) || GetHasSpellEffect(100, oTarget) || GetHasSpellEffect(101, oTarget) ||
               GetHasSpellEffect(102, oTarget) || GetHasSpellEffect(103, oTarget) || GetHasSpellEffect(104, oTarget) ||
               GetHasSpellEffect(105, oTarget) || GetHasSpellEffect(106, oTarget) || GetHasSpellEffect(107, oTarget) ||
               GetHasSpellEffect(110, oTarget) || GetHasSpellEffect(111, oTarget) || GetHasSpellEffect(112, oTarget) ||
               GetHasSpellEffect(113, oTarget) || GetHasSpellEffect(114, oTarget) || GetHasSpellEffect(115, oTarget))
            {
                return tUse;
            }
            else
            {
                bSwitch = TRUE;
            }
        }
    }
    if(bSwitch == TRUE)
    {
        talent tFeat = GetCreatureTalentBest(0x1181, 20);
        if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
        {
            return tFeat;
        }
        else
        {
            talent Invalid;
            return Invalid;
        }
    }
    return tUse;
}
//::///////////////////////////////////////////////
//:: Throw Lightsaber Check
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the target and the force power to make
    sure that a lightsaber is not thrown from close
    range.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 24, 2003
//:://////////////////////////////////////////////
talent GN_CheckThrowLightSaberUsage(object oTarget, talent tUse)
{
    int bSwitch = FALSE;
    if(GetTypeFromTalent(tUse) == TALENT_TYPE_FORCE)
    {
        if(GetIdFromTalent(tUse) == FORCE_POWER_LIGHT_SABER_THROW || GetIdFromTalent(tUse) == FORCE_POWER_LIGHT_SABER_THROW_ADVANCED)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Lightsaber Throw Check = " + FloatToString(GetDistanceBetween(OBJECT_SELF, oTarget),4,2));
            if(GetDistanceBetween(OBJECT_SELF, oTarget) < 10.0)
            {
                bSwitch = TRUE;
            }
        }
    }
    if(bSwitch == TRUE)
    {
        talent tFeat = GetCreatureTalentBest(0x1104, 20);
        if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
        {
            return tFeat;
        }
        else
        {
            talent Invalid;
            return Invalid;
        }
    }
    return tUse;
}
//::///////////////////////////////////////////////
//:: Check Droid Force Power Usage
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the force power and makes sure it can
    be used on a droid.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On:May 12, 2003
//:://////////////////////////////////////////////
talent GN_CheckNonDroidForcePower(object oTarget, talent tUse)
{
    int bSwitch = FALSE;
    if(GetTypeFromTalent(tUse) == TALENT_TYPE_FORCE)
    {
        if(GetIdFromTalent(tUse) == FORCE_POWER_HOLD ||
           GetIdFromTalent(tUse) == FORCE_POWER_HORROR ||
           GetIdFromTalent(tUse) == FORCE_POWER_INSANITY ||
           GetIdFromTalent(tUse) == FORCE_POWER_KILL ||
           GetIdFromTalent(tUse) == FORCE_POWER_PLAGUE ||
           GetIdFromTalent(tUse) == FORCE_POWER_SLEEP ||
           GetIdFromTalent(tUse) == FORCE_POWER_SLOW ||
           GetIdFromTalent(tUse) == FORCE_POWER_STUN ||
           GetIdFromTalent(tUse) == FORCE_POWER_WOUND ||
           GetIdFromTalent(tUse) == FORCE_POWER_AFFLICTION ||
           GetIdFromTalent(tUse) == FORCE_POWER_CHOKE ||
           GetIdFromTalent(tUse) == FORCE_POWER_DEATH_FIELD ||
           GetIdFromTalent(tUse) == FORCE_POWER_DRAIN_LIFE ||
           GetIdFromTalent(tUse) == FORCE_POWER_FEAR)
        {
            if(GetRacialType(oTarget) == RACIAL_TYPE_DROID)
            {
                bSwitch = TRUE;
            }
        }
    }
    if(bSwitch == TRUE)
    {
        talent tFeat = GetCreatureTalentBest(0x1104, 20);
        if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
        {
            return tFeat;
        }
        else
        {
            talent Invalid;
            return Invalid;
        }
    }
    return tUse;
}
//::///////////////////////////////////////////////
//:: Play Ambient Animations
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Play the correct animations based on the
    spawn in condition selected.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 4, 2002
//:://////////////////////////////////////////////
void GN_PlayAmbientAnimation()
{
    if(!GetIsInConversation(OBJECT_SELF))
    {
        location lLocal;
        vector vFrnd;
        int nRoll = d2();
        object oFriend = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nRoll, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
        if(!GetIsObjectValid(oFriend))
        {
            oFriend = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, OBJECT_SELF, nRoll, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
        }
        object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
        int nHDMe = GetHitDice(OBJECT_SELF);
        int nHDOther = GetHitDice(oFriend);
        if(!GN_CheckShouldFlee() || !GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR))
        {
            if(GN_GetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS))
            {
                vFrnd = GetPosition(oFriend);
                nRoll = d6();
                if(GetIsObjectValid(oFriend) && GetDistanceBetween(oFriend, OBJECT_SELF) < 5.0 && !IsObjectPartyMember(oFriend))
                {
                    SetFacingPoint(vFrnd);
                    GN_MyPrintString("GENERIC DEBUG *************** Clear 2600");
                    ClearAllActions();
                    if(nRoll == 1 || nRoll == 2)
                    {
                        ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 3.0);
                    }
                    else if(nRoll == 3)
                    {
                        ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING, 1.0, 3.0);
                    }
                    else if(nRoll == 4)
                    {
                        ActionPlayAnimation(ANIMATION_LOOPING_TALK_FORCEFUL, 1.0, 3.0);
                    }
                    else if(nRoll == 5)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT);
                    }
                    else if(nRoll == 6)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT);
                    }
                }
                else
                {
                    nRoll = d8();
                    if(nRoll == 1)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_BORED, 1.0);
                    }
                    else if(nRoll == 2)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0);
                    }
                    else if(nRoll == 3)
                    {
                        ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 3.0);
                    }
                    else if(nRoll == 4 || nRoll == 5)
                    {
                        if(GetGender(OBJECT_SELF) == GENDER_MALE)
                        {
                            GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
                            ActionPlayAnimation(ANIMATION_LOOPING_PAUSE3, 1.0, 20.4);
                            ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
                        }
                        else if(GetGender(OBJECT_SELF) == GENDER_FEMALE)
                        {
                            GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
                            ActionPlayAnimation(ANIMATION_LOOPING_PAUSE3, 1.0, 13.3);
                            ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
                        }
                    }
                    else if(nRoll == 6)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT);
                    }
                    else if(nRoll == 7)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT);
                    }
                    else if(nRoll == 8)
                    {
                        GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
                        ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 5.0);
                        ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
                    }
                }
            }
            else if(GN_GetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS_MOBILE))
            {
                nRoll = d8();
                GN_MyPrintString("GENERIC DEBUG *************** Clear 2700");
                ClearAllActions();
                if(nRoll == 1)
                {
                    ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 2.0);
                }
                else if(nRoll == 2)
                {
                    ActionPlayAnimation(ANIMATION_FIREFORGET_TAUNT, 1.0);
                }
                else if(nRoll == 3)
                {
                    //ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
                    //ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
                }
                else if(nRoll == 4)
                {
                    ActionPlayAnimation(ANIMATION_FIREFORGET_VICTORY1, 1.0);
                }
                else if(nRoll >= 5)
                {
                    ActionRandomWalk();
                }
            }
        }
        else if(GN_CheckShouldFlee() && GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR))
        {
            GN_CommonAI();
        }
    }
}
//::///////////////////////////////////////////////
//:: Commoner AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    If ever engaged in combat they will flee.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 18, 2002
//:://////////////////////////////////////////////
int GN_CommonAI()
{
    GN_MyPrintString("GENERIC DEBUG *************** Start Commoner AI");
    object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
    object oFlee;
    int bValid = TRUE;
    int nIdx = 1;
    object oNeutral = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL);
    while(GetIsObjectValid(oNeutral) && bValid == TRUE)
    {
        if(GetStandardFaction(oNeutral) == STANDARD_FACTION_HOSTILE_1 ||
            GetStandardFaction(oNeutral) == STANDARD_FACTION_HOSTILE_2 ||
            GetStandardFaction(oNeutral) == STANDARD_FACTION_INSANE)
        {
            if(GetDistanceBetween(OBJECT_SELF, oNeutral) <= 20.0)
            {
                oFlee = oNeutral;
                bValid = FALSE;
            }
        }
        else
        {
            nIdx++;
            oNeutral = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, OBJECT_SELF, nIdx);
        }
    }
    if(GetIsObjectValid(oEnemy))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Clear 2710");
        ClearAllActions();
        ActionMoveAwayFromObject(oEnemy, TRUE, 20.0);
        DelayCommand(0.2, ActionDoCommand(GN_ActionDoPostDCRChecks()));
        return TRUE;
    }
    else if(GetIsObjectValid(oFlee))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Object Flee = " + GN_ReturnDebugName(oFlee));
        GN_MyPrintString("GENERIC DEBUG *************** Clear 2720");
        ClearAllActions();
        ActionMoveAwayFromObject(oFlee, TRUE, 20.0);
        DelayCommand(0.2, ActionDoCommand(GN_ActionDoPostDCRChecks()));
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Should Commoner Flee
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks a number of conditions for a commoner
    to flee.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 20, 2002
//:://////////////////////////////////////////////
int GN_CheckShouldFlee()
{
    int nIdx = 1;
    object oNeutral = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
    object oHostile = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
    while(GetIsObjectValid(oNeutral) || GetIsObjectValid(oHostile))
    {
        if(GetIsObjectValid(oHostile))
        {
            return TRUE;
        }
        if(GetIsObjectValid(oNeutral))
        {
            if(GetStandardFaction(oNeutral) == STANDARD_FACTION_HOSTILE_1 ||
                GetStandardFaction(oNeutral) == STANDARD_FACTION_HOSTILE_2 ||
                GetStandardFaction(oNeutral) == STANDARD_FACTION_INSANE)
            {
                return TRUE;
            }
        }
        nIdx++;
        oNeutral = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, OBJECT_SELF, nIdx, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Reset Deactivated Droid
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Resets a Droid to his deactivated animation
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 25, 2003
//:://////////////////////////////////////////////
void GN_ResetDroidDeactivationState(object oDroid = OBJECT_SELF)
{
    /*
    GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT, FALSE);
    ClearAllActions();
    ActionPlayAnimation(ANIMATION_LOOPING_DEACTIVATE, 1.0, 900.0);
    ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT, TRUE));
    */
    ClearAllActions();
    ActionPlayAnimation(ANIMATION_LOOPING_DEACTIVATE, 1.0, -1.0);
    GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT, FALSE);
}
//::///////////////////////////////////////////////
//:: Determine Attack Target
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the nearest seen target and oIntruder
    for a valid attack target.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 7, 2002
//:://////////////////////////////////////////////
object GN_DetermineAttackTarget(object oIntruder = OBJECT_INVALID)
{
    GN_MyPrintString("GENERIC DEBUG *************** Starting: Determine Attack Target");
    int nPartyAI = GetPartyAIStyle();
    int nNPC_AI = GetNPCAIStyle(OBJECT_SELF);
    object oTarget;
    object oLastTarget = GetLastHostileTarget();
    GN_MyPrintString("GENERIC DEBUG *************** Intruder = " + IntToString(GetIsObjectValid(oIntruder)) + " Last Target = " + IntToString(GetIsObjectValid(oLastTarget)));
    if(GetIsObjectValid(oIntruder) && !GetIsDead(oIntruder) && !GetIsDebilitated(oIntruder))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Intruder Target Returned = " + ObjectToString(oIntruder));
        return oIntruder;
    }
    else if(GetIsObjectValid(oLastTarget) && !GetIsDead(oLastTarget) && !GetIsDebilitated(oLastTarget))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Last Target Returned = " + ObjectToString(oIntruder));
        return oLastTarget;
    }
    else
    {
        if(nPartyAI == PARTY_AISTYLE_AGGRESSIVE)
        {
            int nCnt = 1;
            GN_MyPrintString("GENERIC DEBUG *************** Getting nearest target - 249");
            object oATarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
            oTarget = oATarget;
            while(!GetIsDebilitated(oTarget) && GetIsObjectValid(oTarget))
            {
                nCnt++;
                oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
            }
            if(!GetIsObjectValid(oTarget) && GetIsObjectValid(oATarget))
            {
                oTarget = oATarget;
            }
        }
        else if(nPartyAI == PARTY_AISTYLE_DEFENSIVE)
        {
            int nCnt = 0;
            object oHostile;
            while(!GetIsObjectValid(oHostile) && nCnt < 3)
            {
                oHostile = GetLastHostileActor(GetPartyMemberByIndex(nCnt));
                nCnt++;
            }
            if(GetIsObjectValid(oHostile))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Getting nearest target - 262");
                oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
            }
            else
            {
                oHostile = GetLastHostileTarget(GetPartyMemberByIndex(0));
                if(GetIsObjectValid(oHostile))
                {
                    GN_MyPrintString("GENERIC DEBUG *************** Getting nearest target - 269");
                    oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
                }
            }
        }
        else if(nPartyAI != PARTY_AISTYLE_PASSIVE)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Getting nearest target - 275");
            oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
        }
        else
        {
            GN_MyPrintString("GENERIC DEBUG *************** Getting nearest target - 279");
            oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
        }
    }
    if(GetIsObjectValid(oTarget))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Attack Target From Determine Attack Target = " + GN_ReturnDebugName(oTarget));
        return oTarget;
    }
    GN_MyPrintString("GENERIC DEBUG *************** No Attack Targets Found");
    return OBJECT_INVALID;
}
//::///////////////////////////////////////////////
//:: Return Talent Code
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This function determines the state of the selected
    attack target and what should be done to them.
    If the target is last rounds target then they
    will try not to use failed attack types.
    NOTE: The functionality for area attacks and
    specialized talent use will be coded here.
    For the time being, I will just try to get
    the appropriate cascade of talents being used.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetAttackTalentCode(object oTarget)
{
    GN_MyPrintString("GENERIC DEBUG *************** Starting: Getting Talent Attack Code");
    int nPreviousTalentCode;
    //GN_MyPrintString("GENERIC DEBUG *************** Cooked Return Code  0x0100");
    GN_MyPrintString("GENERIC DEBUG *************** Debilitated = " + IntToString(GetIsDebilitated(oTarget)));
    if(!GetIsDead(oTarget) && GetIsObjectValid(oTarget) && !GetIsDebilitated(oTarget) && GetLastHostileTarget() == oTarget)
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Talent Code: Before GetPreviousTalent");
        nPreviousTalentCode = GN_GetPreviousTalentCode();
        //GN_MyPrintString("GENERIC DEBUG *************** Talent Code: Before If Compare");
        if(GN_CompareTalents(nPreviousTalentCode, 0xf2ff))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Talent Code: 0xff1f");
            if(GN_GetHasViableTalent(0xff1f))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Return Code 0xff1f");
                return 0xff1f;
            }
            if(GN_GetHasViableTalent(0x0100))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf1ff");
                return 0xf1ff;
            }
        }
        else if(GN_CompareTalents(nPreviousTalentCode, 0xff1f))
        {
            if(GN_GetHasViableTalent(0xf1f0))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf1ff");
                return 0xf1ff;
            }
        }
    }
    else if(!GetIsDead(oTarget) && GetIsObjectValid(oTarget) && !GetIsDebilitated(oTarget) && GetLastHostileTarget() != oTarget)
    {
        if(GN_GetHasViableTalent(0xf3ff))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf3ff");
            return 0xf3ff;
        }
        if(GN_GetHasViableTalent(0xf2ff))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf2ff");
            return 0xf2ff;
        }
        if(GN_GetHasViableTalent(0xff1f))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xff1f");
            return 0xff1f;
        }
        if(GN_GetHasViableTalent(0xf1ff))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf1ff");
            return 0xf1ff;
        }
    }
    else if(!GetIsDead(oTarget) && GetIsObjectValid(oTarget) && GetIsDebilitated(oTarget))
    {
        if(GN_GetHasViableTalent(0xf1ff))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf1ff");
            return 0xf1ff;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xffff");
    return 0xffff;
}
//this function was cut from the generics but is needed
//here to keep scripts from breaking.
void GN_SetDayNightPresence(int nPresenceSetting)
{
}
""",
    "k_inc_gensupport": b"""//:: k_inc_gensupport
/*
    v1.0
    Support Include for k_inc_generic
    NOTE - To get these functions
    use k_inc_generic
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
//BOSS ATTACK TYPES
int SW_BOSS_ATTACK_TYPE_GRENADE = 1;
int SW_BOSS_ATTACK_TYPE_FORCE_POWER = 2;
int SW_BOSS_ATTACK_TYPE_NPC = 3;
int SW_BOSS_ATTACK_TYPE_PC = 4;
int SW_BOSS_ATTACK_ANY = 5;
int SW_BOSS_ATTACK_DROID = 6;
//LOCAL NUMBERS
int SW_NUMBER_COMBO_ROUTINE = 3;
int SW_NUMBER_COMBO_INDEX = 4;
int SW_NUMBER_LAST_COMBO = 5;
int SW_NUMBER_ROUND_COUNTER = 6;
int SW_NUMBER_COMBAT_ZONE = 7;
//COMBO CONSTANTS
int SW_COMBO_RANGED_FEROCIOUS = 1;
int SW_COMBO_RANGED_AGGRESSIVE = 2;
int SW_COMBO_RANGED_DISCIPLINED = 3;
int SW_COMBO_RANGED_CAUTIOUS = 4;
int SW_COMBO_MELEE_FEROCIOUS = 5;
int SW_COMBO_MELEE_AGGRESSIVE = 6;
int SW_COMBO_MELEE_DISCIPLINED = 7;
int SW_COMBO_MELEE_CAUTIOUS = 8;
int SW_COMBO_BUFF_PARTY = 9;
int SW_COMBO_BUFF_DEBILITATE = 10;
int SW_COMBO_BUFF_DAMAGE = 11;
int SW_COMBO_BUFF_DEBILITATE_DESTROY = 12;
int SW_COMBO_SUPRESS_DEBILITATE_DESTROY = 13;
int SW_COMBO_SITH_ATTACK = 14;
int SW_COMBO_BUFF_ATTACK = 15;
int SW_COMBO_SITH_CONFOUND = 16;
int SW_COMBO_JEDI_SMITE = 17;
int SW_COMBO_SITH_TAUNT = 18;
int SW_COMBO_SITH_BLADE = 19;
int SW_COMBO_SITH_CRUSH = 20;
int SW_COMBO_JEDI_CRUSH = 21;
int SW_COMBO_SITH_BRUTALIZE = 22;
int SW_COMBO_SITH_DRAIN = 23;
int SW_COMBO_SITH_ESCAPE = 24;
int SW_COMBO_JEDI_BLITZ = 25;
int SW_COMBO_SITH_SPIKE = 26;
int SW_COMBO_SITH_SCYTHE = 27;
int SW_COMBO_DROID_UTILITIES = 28;
int SW_COMBO_DROID_UTILITIES_2 = 29;
int SW_COMBO_INVALID = 30;
int SW_FLAG_TARGET_FRIEND = 59;
//****SUPPORT FUNCTIONS FOR THE GENERICS**************************************************************************
//Returns the number targets attacking the passed in object
int GN_GetAttackers(object oTarget);
//Returns the index of the party member passed in or false if the object is not a party member.
int GN_CheckNPCIsInParty(object oNPC);
//Checks whether the attempted spell or attack targets are true
int GN_CheckAttemptedSpellAttackTarget();
//Determines if the object has a valid attempted spell or attack target or a valid attack target.
int GN_GetIsFighting(object oFighting);
//Compares to talent codes to see if specific bits are true.
int GN_CompareTalents(int nTalent1, int nTalent2);
// Returns the talent code for the previous round.
int GN_GetPreviousTalentCode();
//Takes a spell constant and passes back the code
int GN_GetSpellTalentCode(int nSpell);
//Takes a feat constant and passes back the code
int GN_GetFeatTalentCode(int nFeat);
//Searchs for viable talents that can be used by the user and passes back yes or no according to whether one is found.
int GN_GetHasViableTalent(int nTalentCode);
//Returns the exclusion code for the talent based on the racial type of the creature passed in.
int GN_GetExclusionCode(object oTarget);
//This takes a combo constant and returns a talent.
talent GN_GetNextTalentInCombo(int nCombo);
//Determines if a combo is valid for the object in question
int GN_GetIsComboValid(int nComboType);
//Does the Jedi have a damaging Force Power
int GN_GetHasDamagingForcePower();
//Gets a random combo for a default AI Jedi
int GN_GetStandardJediCombo(int nBoss = FALSE);
//Gets a random combo for a default AI Droid
int GN_GetStandardDroidCombo(int nBoss = FALSE);
//Gets a random combo for a default AI NPC
int GN_GetStandardNPCCombo(int nBoss = FALSE);
// Returns 2 for Ranged and 1 for Melee weapons, checking the basetype
int GN_GetWeaponType(object oTarget = OBJECT_SELF);
//Gets the NPC to eqyuip a melee = 1 or ranged = 2 weapon.
int GN_EquipAppropriateWeapon();
//Returns a talent for the boss to perform in combat.
talent GN_GetBossCombatMove(int nBossAttackType, int nDroid = FALSE);
//Get Boss AOE Force Powers
talent GN_GetAOEForcePower(int nDroid = FALSE);
//Get Boss Single Target Force Powers
talent GN_GetTargetedForcePower(int nDroid = FALSE);
//Returns the number of party members who are active
int GN_GetActivePartyMemberCount();
//Returns the active party member who is not Member(0)
object GN_GetActivePartyMember(int nDrainTarget = FALSE);
//This function returns an active party member. They must not be dead.  The debilitated parameter will
//ignore those party members already debilitated.
object GN_ReturnActivePartyMember(int nDebil = FALSE);
//****VERIFICATION FOR COMMANDS FOR COMBOS**************************************************************************
//Check Push Series
int GN_CheckSeriesForcePush();
//Check Armor Series
int GN_CheckSeriesArmor();
//Check Fear Series
int GN_CheckSeriesFear();
//Check Hold Series
int GN_CheckSeriesHold();
//Check Poison Series
int GN_CheckSeriesAfflict();
//Check Saber Throw Series
int GN_CheckSeriesSaberThrow();
//Check Lightning Series
int GN_CheckSeriesLightning();
//Check Jump Series
int GN_CheckSeriesJump();
//Check Choke Series
int GN_CheckSeriesChoke();
//Check Drain Life Series
int GN_CheckSeriesDrainLife();
//Check Speed Series
int GN_CheckSeriesSpeed();
//Checks if the droid has utility items
int GN_CheckSeriesDroidUtilities();
//Checks Mind Series
int GN_CheckSeriesMind();
//Checks Resist Series
int GN_CheckSeriesResist();
//Checks Force Immunity Series();
int GN_CheckSeriesForceImmunity();
//Checks the Breach Series
int GN_CheckSeriesBreach();
//****GET COMMANDS FOR COMBOS**************************************************************************
//Fetch Series Force Push Power
int GN_GetSeriesForcePush();
//Fetch Series Force Armor Power
int GN_GetSeriesForceArmor();
//Fetch Series Fear Power
int GN_GetSeriesFear();
//Fetch Series Hold Power
int GN_GetSeriesHold();
//Fetch Series Afflict Power
int GN_GetSeriesAfflict();
//Fetch Series Saber Throw Power
int GN_GetSeriesSaberThrow();
//Fetch Series Lightning Power
int GN_GetSeriesLightning();
//Fetch Series Jump Power
int GN_GetSeriesJump();
//Fetch Series Choke Power
int GN_GetSeriesChoke();
//Fetch Series Drain Life Power
int GN_GetSeriesDrainLife();
//Fetch Series Speed Power
int GN_GetSeriesSpeed();
//Fetch Melee Feat
int GN_GetSeriesMeleeFeat();
//Fetch Ranged Feat
int GN_GetSeriesRangedFeat();
//Fetch Mind Series
int GN_GetSeriesMind();
//Fetch Resist Series
int GN_GetSeriesResist();
//Fetch Force Immunity Series();
int GN_GetSeriesForceImmunity();
//Fetch the Breach Series
int GN_GetSeriesBreach();
//****DEBUG COMMANDS FOR THE GENERICS**************************************************************************
//Basically, a wrapper for AurPostString
void GN_PostString(string sString = "",int x = 10,int y = 10,float fShow = 4.0);
//Makes the object running the script say a speak string.
void GN_MySpeakString(string sString);
//Makes the nearest PC say a speakstring.
void GN_AssignPCDebugString(string sString);
//Inserts a print string into the log file for debugging purposes.
void GN_MyPrintString(string sString);
//Prints to the log file the shout received by a target.
void GN_PrintShoutType(object oShouter, int nShout);
//Returns the object ID and name appended to each other.
string GN_ReturnDebugName(object oTarget);
//Returns a string of the combo being used.
string GN_FetchComboString(int nCombo);
//Checks the friendly fire on the target out to 3.5m by default.
int GN_CheckFriendlyFireOnTarget(object oTarget, float fDistance = 4.0);
//Checks the enemies around a target object.
int GN_CheckEnemyGroupingOnTarget(object oTarget, float fDistance = 4.0);
//Searches the area and marks a group as a viable target for a grenade
object GN_FindGrenadeTarget();
//Searches the area and marks a group as a viable target for a AOE force power
object GN_FindAOETarget();
//Returns a grenade appropriate to the target
talent GN_GetGrenadeTalent(int nDroid = FALSE);
//Returns the AI style in a string
string GN_ReturnAIStyle(object oTarget = OBJECT_SELF);
//Prints a string from a int
string GN_ITS(int sFutureString);
//These debug commands are used for debugging shouts only
void GN_PostShoutString(string sString = "",int x = 10,int y = 10,float fShow = 4.0);
//These debug commands are used for debugging shouts o
void GN_MyPrintShoutString(string sString);
//::///////////////////////////////////////////////
//:: Get Attackers
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the number objects attacking the object;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
int GN_GetAttackers(object oTarget)
{
    int nCnt = 0;
    object oAttacker = GetFirstAttacker(oTarget);
    while(GetIsObjectValid(oAttacker))
    {
        nCnt++;
        oAttacker = GetNextAttacker(oTarget);
    }
    return nCnt;
}
//::///////////////////////////////////////////////
//:: Am I a party member
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns member index +1 or false depending on
    whether the object belongs in the PCs party.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
int GN_CheckNPCIsInParty(object oNPC)
{
    if(GetPartyMemberByIndex(0) == oNPC)
    {
        return 1;
    }
    else if(GetPartyMemberByIndex(1) == oNPC)
    {
        return 2;
    }
    else if(GetPartyMemberByIndex(2) == oNPC)
    {
        return 3;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: GetAttempted Spell or Attack Target State
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns true if the spell or attack target is
    true
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 8, 2002
//:://////////////////////////////////////////////
int GN_CheckAttemptedSpellAttackTarget()
{
    object oAttack = GetAttemptedAttackTarget();
    object oSpell = GetAttemptedSpellTarget();
    if(GetIsObjectValid(oAttack) || GetIsObjectValid(oSpell))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: GetIsFighting
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks if the passed object has an Attempted
    Attack or Spell Target
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
int GN_GetIsFighting(object oFighting)
{
    object oAttack = GetAttemptedAttackTarget();
    object oSpellTarget = GetAttemptedSpellTarget();
    object oAttacking = GetAttackTarget();
    object oMove = GetAttemptedMovementTarget();
    if(GetTag(OBJECT_SELF) == "DEBUG")
    {
        GN_ReturnDebugName(OBJECT_SELF);
        GN_PostString("Attempted Attack Target = " + IntToString(GetIsObjectValid(oAttack)), 10,20, 4.0);
        GN_PostString("Attempted Spell Target = " + IntToString(GetIsObjectValid(oSpellTarget)), 10,22, 4.0);
        GN_PostString("Attack Target = " + IntToString(GetIsObjectValid(oAttacking)), 10,24, 4.0);
        GN_PostString("Move Target = " + IntToString(GetIsObjectValid(oMove)), 10,26, 4.0);
    }
    if(GetIsObjectValid(oAttack) || GetIsObjectValid(oSpellTarget) || GetIsObjectValid(oAttacking) ||
     (GetIsObjectValid(oMove) && GetIsEnemy(oMove)))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Compare Talents
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the bits of Talent 1 against the bits
    of Talent 2 to see if 1 is true.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 12, 2002
//:://////////////////////////////////////////////
int GN_CompareTalents(int nTalent1, int nTalent2)
{
    if(nTalent1 & nTalent2)
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Comparison of " + IntToString(nTalent1) + " / " + IntToString(nTalent2));
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Get Last Talent Code
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Determines the last talent that was used
    by OBJECT_SELF
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetPreviousTalentCode()
{
    int nAction = GetLastAttackAction();
    int nFeatSpell;
    if(nAction == ACTION_CASTSPELL)
    {
        nFeatSpell = GetLastForcePowerUsed();
        nFeatSpell = GN_GetSpellTalentCode(nFeatSpell);
    }
    else if(nAction == ACTION_ATTACKOBJECT)
    {
        nFeatSpell = GetLastCombatFeatUsed();
        nFeatSpell = GN_GetFeatTalentCode(nFeatSpell);
    }
    return nFeatSpell;
}
//::///////////////////////////////////////////////
//:: Get Spell Talent Code
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the talent code for a particular spell
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetSpellTalentCode(int nSpell)
{
    talent tSpell = TalentSpell(nSpell);
    return GetCategoryFromTalent(tSpell);
}
//::///////////////////////////////////////////////
//:: Get Feat Talent Code
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the talent code for a particular feat
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetFeatTalentCode(int nFeat)
{
    talent tFeat = TalentSpell(nFeat);
    return GetCategoryFromTalent(tFeat);
}
//::///////////////////////////////////////////////
//:: Get Has Viable Talent
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Takes a talent code and searches for a viable
    talent from the bunch
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetHasViableTalent(int nTalentCode)
{
    talent tTest = GetCreatureTalentBest(nTalentCode, 20);
    if(GetIsTalentValid(tTest))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Get Exclusion Code
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns an exclusion code based on the Racial
    Type of the target
    0x00 = None
    0x01 = Organic
    0x02 = Droid
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetExclusionCode(object oTarget)
{
    int nRacial = GetRacialType(oTarget);
    if(nRacial == RACIAL_TYPE_DROID)
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Exclusion Used: 0x01");
        return 0x01;
    }
    else if(nRacial == RACIAL_TYPE_HUMAN)
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Exclusion Used: 0x02");
        return 0x02;
    }
    //GN_MyPrintString("GENERIC DEBUG *************** Exclusion Used: 0x03");
    return 0x03;
}
//::///////////////////////////////////////////////
//:: Get Jedi Combo
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a proper Jedi Combo for Standard AI
int SW_COMBO_RANGED_FEROCIOUS = 1;
int SW_COMBO_RANGED_AGGRESSIVE = 2;
int SW_COMBO_RANGED_DISCIPLINED = 3;
int SW_COMBO_RANGED_CAUTIOUS = 4;
int SW_COMBO_MELEE_FEROCIOUS = 5;
int SW_COMBO_MELEE_AGGRESSIVE = 6;
int SW_COMBO_MELEE_DISCIPLINED = 7;
int SW_COMBO_MELEE_CAUTIOUS = 8;
int SW_COMBO_BUFF_PARTY = 9;
int SW_COMBO_BUFF_DEBILITATE = 10;
int SW_COMBO_BUFF_DAMAGE = 11;
int SW_COMBO_BUFF_DEBILITATE_DESTROY = 12;
int SW_COMBO_SUPRESS_DEBILITATE_DESTROY = 13;
int SW_COMBO_SITH_ATTACK = 14;
int SW_COMBO_BUFF_ATTACK = 15;
int SW_COMBO_SITH_CONFOUND = 16;
int SW_COMBO_JEDI_SMITE = 17;
int SW_COMBO_SITH_TAUNT = 18;
int SW_COMBO_SITH_BLADE = 19;
int SW_COMBO_SITH_CRUSH = 20;
int SW_COMBO_JEDI_CRUSH = 21;
int SW_COMBO_SITH_BRUTALIZE = 22;
int SW_COMBO_SITH_DRAIN = 23;
int SW_COMBO_SITH_ESCAPE = 24;
int SW_COMBO_JEDI_BLITZ = 25;
int SW_COMBO_SITH_SPIKE = 26;
int SW_COMBO_SITH_SCYTHE = 27;
int SW_COMBO_DROID_UTILITIES = 28;
int SW_COMBO_DROID_UTILITIES_2 = 29;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 28, 2002
//:://////////////////////////////////////////////
int GN_GetStandardJediCombo(int nBoss = FALSE)
{
    int nBool;
    int nRand;
    while(nBool == FALSE)
    {
        if(nBoss == FALSE)
        {
            nRand = Random(23)+1;
            if(nRand == 1 || nRand == 2) {return SW_COMBO_MELEE_FEROCIOUS;}
            else if(nRand == 3 || nRand == 4) {return SW_COMBO_MELEE_AGGRESSIVE;}
            else if(nRand == 5 || nRand == 6) {return SW_COMBO_MELEE_DISCIPLINED;}
            else if(nRand == 7 || nRand == 8 || nRand == 9) {return SW_COMBO_MELEE_CAUTIOUS;}
            else if(nRand >= 10 || nRand <= 24)
            {
                nRand = nRand+3;
            }
        }
        else
        {
            nRand = Random(15);
            nRand = nRand + 13;
        }
        nBool = GN_GetIsComboValid(nRand);
        //GN_MyPrintString("GENERIC DEBUG *************** Jedi Combo " + GN_FetchComboString(nRand) + " is " + IntToString(nBool));
    }
    return nRand;
}
//::///////////////////////////////////////////////
//:: Get Droid Combo
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a proper Droid Combo for Standard AI
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 28, 2002
//:://////////////////////////////////////////////
int GN_GetStandardDroidCombo(int nBoss = FALSE)
{
    //GN_MyPrintString("GENERIC DEBUG *************** Droid Combo Selection Started");
    int nBool = FALSE;
    int nRand = d6();
    while(nBool == FALSE)
    {
        if(nRand == 1){nRand = SW_COMBO_RANGED_AGGRESSIVE;}
        else if(nRand == 2){nRand = SW_COMBO_RANGED_CAUTIOUS;}
        else if(nRand == 3){nRand = SW_COMBO_RANGED_DISCIPLINED;}
        else if(nRand == 4){nRand = SW_COMBO_RANGED_FEROCIOUS;}
        else if(nRand == 5 || nRand == 6)
        {
            if((IsObjectPartyMember(OBJECT_SELF) && GetNPCAIStyle(OBJECT_SELF) == NPC_AISTYLE_JEDI_SUPPORT) ||
                !IsObjectPartyMember(OBJECT_SELF))
            {
                if(nRand == 5)
                {
                    nRand = SW_COMBO_DROID_UTILITIES;
                }
                else if(nRand == 6)
                {
                    nRand = SW_COMBO_DROID_UTILITIES_2;
                }
            }
            else
            {
                nRand = SW_COMBO_INVALID;
            }
        }
        nBool = GN_GetIsComboValid(nRand);
        //GN_MyPrintString("GENERIC DEBUG *************** Droid Combo Picked " + GN_FetchComboString(nRand) + " is " + IntToString(nBool));
        if(nBool == FALSE)
        {
            nRand = d6();
        }
    }
    //GN_MyPrintString("GENERIC DEBUG *************** Returning Combo Returned = " + GN_FetchComboString(nRand));
    return nRand;
}
//::///////////////////////////////////////////////
//:: Get NPC Combo
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a proper NPC Combo for Standard AI
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 28, 2002
//:://////////////////////////////////////////////
int GN_GetStandardNPCCombo(int nBoss = FALSE)
{
    int nBool;
    int nRand = d4();
    if(GN_GetWeaponType() != 0)
    {
        while(nBool == FALSE)
        {
            if(GN_GetWeaponType() == 1)
            {
                if(nRand == 1){nRand = SW_COMBO_MELEE_AGGRESSIVE;}
                else if(nRand == 2){nRand = SW_COMBO_MELEE_CAUTIOUS;}
                else if(nRand == 3){nRand = SW_COMBO_MELEE_DISCIPLINED;}
                else if(nRand == 4){nRand = SW_COMBO_MELEE_FEROCIOUS;}
            }
            else if(GN_GetWeaponType() == 2)
            {
                if(nRand == 1){nRand = SW_COMBO_RANGED_AGGRESSIVE;}
                else if(nRand == 2){nRand = SW_COMBO_RANGED_CAUTIOUS;}
                else if(nRand == 3){nRand = SW_COMBO_RANGED_DISCIPLINED;}
                else if(nRand == 4){nRand = SW_COMBO_RANGED_FEROCIOUS;}
            }
            nBool = GN_GetIsComboValid(nRand);
            if(nBool == FALSE)
            {
                nRand = d6();
            }
        }
    }
    else
    {
        nRand = 2;
    }
    //GN_MyPrintString("GENERIC DEBUG *************** NPC Combo " + GN_FetchComboString(nRand) + " is " + IntToString(nBool));
    return nRand;
}
//::///////////////////////////////////////////////
//:: Get Next Talent In Combo
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Looks at the combo id and returns an ability
    usable by the NPC which matches the next
    feat in the combo.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 27, 2002
//:://////////////////////////////////////////////
talent GN_GetNextTalentInCombo(int nCombo)
{
    SetLocalBoolean(OBJECT_SELF, SW_FLAG_TARGET_FRIEND, FALSE);
    int nLocal = GetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX);
    //GN_MyPrintString("GENERIC DEBUG *************** Combo Index " + IntToString(nLocal));
    talent tUse, tInvalid;
    int nID = -1;
    int nFeat = FALSE;
    int nBuff = FALSE;
    //Sith Attack(PUSH, CHOKE, JUMP)
    if(nCombo == SW_COMBO_SITH_ATTACK)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesChoke();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesForcePush();
        }
        else
        {
            nID = GN_GetSeriesJump();
        }
    }
    //Buff Attack(ARMOR, SPEED, FEAT)
    else if(nCombo == SW_COMBO_BUFF_ATTACK)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesForceArmor();
            nBuff = TRUE;
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesSpeed();
            nBuff = TRUE;
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Sith Confound (FEAR, FEAT, FEAT)
    else if(nCombo == SW_COMBO_SITH_CONFOUND)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesLightning();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Jedi Smite (HOLD, FEAT, FEAT)
    else if(nCombo == SW_COMBO_JEDI_SMITE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesHold();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Sith Taunt (CHOKE, POISON, FEAT)
    else if(nCombo == SW_COMBO_SITH_TAUNT)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesChoke();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesAfflict();
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Sith Blade (SLOW, PUSH, THROW)
    else if(nCombo == SW_COMBO_SITH_BLADE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesAfflict();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesForcePush();
        }
        else
        {
            nID = GN_GetSeriesSaberThrow();
        }
    }
    //Sith Crush (PUSH, SHOCK, JUMP)
    else if(nCombo == SW_COMBO_SITH_CRUSH)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesLightning();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesForcePush();
        }
        else
        {
            nID = GN_GetSeriesJump();
        }
    }
    //Jedi Crush (HOLD, THROW, JUMP)
    else if(nCombo == SW_COMBO_JEDI_CRUSH)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesHold();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesForcePush();
        }
        else
        {
            nID = GN_GetSeriesJump();
        }
    }
    //Sith Brutalize (CHOKE, DRAIN, PUSH)
    else if(nCombo == SW_COMBO_SITH_BRUTALIZE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesChoke();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesDrainLife();
        }
        else
        {
            nID = GN_GetSeriesForcePush();
        }
    }
    //Sith Drain (FEAT, DRAIN, FEAT)
    else if(nCombo == SW_COMBO_SITH_DRAIN)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesDrainLife();
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Sith Escape (DRAIN, PUSH, THROW)
    else if(nCombo == SW_COMBO_SITH_ESCAPE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesDrainLife();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesForcePush();
        }
        else
        {
            nID = GN_GetSeriesSaberThrow();
        }
    }
    //Jedi Blitz (FEAT, FEAT, PUSH)
    else if(nCombo == SW_COMBO_JEDI_BLITZ)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            nID = GN_GetSeriesForcePush();
        }
    }
    //Sith Spike (PUSH, SLOW, FEAT)
    else if(nCombo == SW_COMBO_SITH_SPIKE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesAfflict();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            nID = GN_GetSeriesForcePush();
        }
    }
    //Sith Scythe (DRAIN, FEAR, FEAT)
    else if(nCombo == SW_COMBO_SITH_SCYTHE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesDrainLife();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesBreach();
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Melee Ferocious (USE 3 FEATS)
    else if(nCombo == SW_COMBO_MELEE_FEROCIOUS)
    {
        nID = GN_GetSeriesMeleeFeat();
        nFeat = TRUE;
    }
    //Melee Aggressive (USE 2 FEATS)
    else if(nCombo == SW_COMBO_MELEE_AGGRESSIVE)
    {
        if(nLocal == 1 || nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee/Ranged Breather");
        }
    }
    //Melee Discipline (USE 1 FEAT)
    else if(nCombo == SW_COMBO_MELEE_DISCIPLINED)
    {
        if(nLocal == 1 || nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee/Ranged Breather");
        }
    }
    else if(nCombo == SW_COMBO_MELEE_CAUTIOUS || nCombo == SW_COMBO_RANGED_CAUTIOUS)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Melee/Ranged Breather");
    }
    //Melee Cautious (USE NO FEATS) //This does not require a check. It will return an invalid talent
    //Ranged Cautious (USE NO FEATS) //This does not require a check. It will return an invalid talent
    //Ranged Ferocious (USE 3 FEATS)
    else if(nCombo == SW_COMBO_RANGED_FEROCIOUS)
    {
        nID = GN_GetSeriesRangedFeat();
        nFeat = TRUE;
    }
    //Ranged Aggressive (USE 2 FEATS)
    else if(nCombo == SW_COMBO_RANGED_AGGRESSIVE)
    {
        if(nLocal == 1 || nLocal == 2)
        {
            nID = GN_GetSeriesRangedFeat();
            nFeat = TRUE;
        }
        else
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee/Ranged Breather");
        }
    }
    //Ranged Discipline (USE 1 FEAT)
    else if(nCombo == SW_COMBO_RANGED_DISCIPLINED)
    {
        if(nLocal == 1 || nLocal == 2)
        {
            nID = GN_GetSeriesRangedFeat();
            nFeat = TRUE;
        }
        else
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee/Ranged Breather");
        }
    }
    //Buff Party
    else if(nCombo == SW_COMBO_BUFF_PARTY)
    {
        tUse = GetCreatureTalentRandom(0xf8ff);
    }
    //Buff & Debilitate (BUFF & 2 DEBILITATE ENEMY)
    else if(nCombo == SW_COMBO_BUFF_DEBILITATE)
    {
        if(nLocal == 1)
        {
            tUse = GetCreatureTalentRandom(0xf8ff);
        }
        else
        {
            tUse = GetCreatureTalentRandom(0xf2ff);
        }
    }
    //Buff & Damage (BUFF  & 2 DAMAGE ENEMY)
    else if(nCombo == SW_COMBO_BUFF_DAMAGE)
    {
        if(nLocal == 1)
        {
            tUse = GetCreatureTalentRandom(0xf8ff);
        }
        else
        {
            tUse = GetCreatureTalentRandom(0xf1ff);
        }
    }
    //Buff, Debilitate & Destroy (1 BUFF, 1 DEBILITATE, 1 DESTROY)
    else if(nCombo == SW_COMBO_BUFF_DEBILITATE_DESTROY)
    {
        if(nLocal == 1)
        {
            tUse = GetCreatureTalentRandom(0xf8ff);
        }
        if(nLocal == 2)
        {
            tUse = GetCreatureTalentRandom(0xf2ff);
        }
        if(nLocal == 3)
        {
            tUse = GetCreatureTalentRandom(0x1101);
        }
    }
    //Supress, Debilitate & Destroy (1 Supress, 1 DEBILITATE, 1 DESTROY)
    else if(nCombo == SW_COMBO_SUPRESS_DEBILITATE_DESTROY)
    {
        if(nLocal == 1)
        {
            tUse = GetCreatureTalentRandom(0xf1ff);
        }
        if(nLocal == 2)
        {
            tUse = GetCreatureTalentRandom(0xf2ff);
        }
        if(nLocal == 3)
        {
            tUse = GetCreatureTalentRandom(0x1101);
        }
    }
    else if(nCombo == SW_COMBO_DROID_UTILITIES)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesRangedFeat();
            nFeat = TRUE;
        }
        if(nLocal == 2)
        {
            nID = GN_GetSeriesRangedFeat();
            nFeat = TRUE;
        }
        if(nLocal == 3)
        {
            tUse = GetCreatureTalentRandom(0x8000);
        }
    }
    else if(nCombo == SW_COMBO_DROID_UTILITIES_2)
    {
        if(nLocal == 1)
        {
            tUse = GetCreatureTalentRandom(0x8000);
        }
        if(nLocal == 2)
        {
            nID = GN_GetSeriesRangedFeat();
            nFeat = TRUE;
        }
        if(nLocal == 3)
        {
            tUse = GetCreatureTalentRandom(0x8000);
        }
    }
    //Increments the Local number so that the progression through the Combo continues even if the talent fails
    nLocal++;
    SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, nLocal);
    if(!GetIsTalentValid(tUse) || !GetCreatureHasTalent(tUse))
    {
        //GN_MyPrintString("GENERIC DEBUG *************** ID = " + IntToString(nID));
        if(nID != -1 && nFeat == FALSE)
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Spell ID = " + IntToString(nID));
            tUse = TalentSpell(nID);
        }
        else if(nID != -1 && nFeat == TRUE)
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Feat ID = " + IntToString(nID));
            tUse = TalentFeat(nID);
        }
    }
    else
    {
        nID = GetIdFromTalent(tUse);
        //GN_MyPrintString("GENERIC DEBUG *************** Preselected ID = " + IntToString(nID));
    }
    //Use GetCreatureHasTalent here to make the talent is currently usable - ie enough force points.
    //Currently it terminates the script, so do not use it.
    if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Returning Valid Talent");
        return tUse;
    }
    //GN_MyPrintString("GENERIC DEBUG *************** Returning Invalid Talent");
    return tInvalid;
}
//::///////////////////////////////////////////////
//:: Force Power Get Functions
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns an ability based.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 27, 2002
//:://////////////////////////////////////////////
int GN_GetSeriesForcePush()
{
    if(GetHasSpell(FORCE_POWER_FORCE_WAVE))
    {
        return FORCE_POWER_FORCE_WAVE;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_WHIRLWIND))
    {
        return FORCE_POWER_FORCE_WHIRLWIND;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_PUSH))
    {
        return FORCE_POWER_FORCE_PUSH;
    }
    return -1;
}
int GN_GetSeriesForceArmor()
{
    if(GetHasSpell(FORCE_POWER_FORCE_ARMOR))
    {
        return FORCE_POWER_FORCE_ARMOR;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_SHIELD))
    {
        return FORCE_POWER_FORCE_SHIELD;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_AURA))
    {
        return FORCE_POWER_FORCE_AURA;
    }
    return -1;
}
int GN_GetSeriesFear()
{
    if(GetHasSpell(FORCE_POWER_INSANITY))
    {
        return FORCE_POWER_INSANITY;
    }
    else if(GetHasSpell(FORCE_POWER_HORROR))
    {
        return FORCE_POWER_HORROR;
    }
    else if(GetHasSpell(FORCE_POWER_FEAR))
    {
        return FORCE_POWER_FEAR;
    }
    return -1;
}
int GN_GetSeriesHold()
{
    if(GetHasSpell(FORCE_POWER_SLEEP))
    {
        return FORCE_POWER_SLEEP;
    }
    else if(GetHasSpell(FORCE_POWER_HOLD))
    {
        return FORCE_POWER_HOLD;
    }
    else if(GetHasSpell(FORCE_POWER_STUN))
    {
        return FORCE_POWER_STUN;
    }
    return -1;
}
int GN_GetSeriesAfflict()
{
    if(GetHasSpell(FORCE_POWER_PLAGUE))
    {
        return FORCE_POWER_PLAGUE;
    }
    else if(GetHasSpell(FORCE_POWER_AFFLICTION))
    {
        return FORCE_POWER_AFFLICTION;
    }
    else if(GetHasSpell(FORCE_POWER_SLOW))
    {
        return FORCE_POWER_SLOW;
    }
    return -1;
}
int GN_GetSeriesSaberThrow()
{
    if(GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW_ADVANCED))
    {
        return FORCE_POWER_LIGHT_SABER_THROW_ADVANCED;
    }
    else if(GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW))
    {
        return FORCE_POWER_LIGHT_SABER_THROW;
    }
    return -1;
}
int GN_GetSeriesLightning()
{
    if(GetHasSpell(FORCE_POWER_FORCE_STORM))
    {
        return FORCE_POWER_FORCE_STORM;
    }
    else if(GetHasSpell(FORCE_POWER_LIGHTNING))
    {
        return FORCE_POWER_LIGHTNING;
    }
    else if(GetHasSpell(FORCE_POWER_SHOCK))
    {
        return FORCE_POWER_SHOCK;
    }
    return -1;
}
int GN_GetSeriesJump()
{
    if(GetHasSpell(FORCE_POWER_FORCE_JUMP_ADVANCED))
    {
        return FORCE_POWER_FORCE_JUMP_ADVANCED;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_JUMP))
    {
        return FORCE_POWER_FORCE_JUMP;
    }
    return -1;
}
int GN_GetSeriesChoke()
{
    if(GetHasSpell(FORCE_POWER_KILL))
    {
        return FORCE_POWER_KILL;
    }
    else if(GetHasSpell(FORCE_POWER_CHOKE))
    {
        return FORCE_POWER_CHOKE;
    }
    else if(GetHasSpell(FORCE_POWER_WOUND))
    {
        return FORCE_POWER_WOUND;
    }
    return -1;
}
int GN_GetSeriesDrainLife()
{
    if(GetHasSpell(FORCE_POWER_DEATH_FIELD))
    {
        return FORCE_POWER_DEATH_FIELD;
    }
    else if(GetHasSpell(FORCE_POWER_DRAIN_LIFE))
    {
        return FORCE_POWER_DRAIN_LIFE;
    }
    return -1;
}
int GN_GetSeriesSpeed()
{
    if(GetHasSpell(FORCE_POWER_SPEED_MASTERY))
    {
        return FORCE_POWER_SPEED_MASTERY;
    }
    else if(GetHasSpell(FORCE_POWER_KNIGHT_SPEED))
    {
        return FORCE_POWER_KNIGHT_SPEED;
    }
    else if(GetHasSpell(FORCE_POWER_SPEED_BURST))
    {
        return FORCE_POWER_SPEED_BURST;
    }
    return -1;
}
int GN_GetSeriesMeleeFeat()
{
    talent tUse = GetCreatureTalentBest(0x1104, 20);
    if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
    {
        int nID = GetIdFromTalent(tUse);
        return nID;
    }
    return -1;
}
int GN_GetSeriesRangedFeat()
{
    talent tUse = GetCreatureTalentBest(0x1181, 20);
    if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
    {
        int nID = GetIdFromTalent(tUse);
        return nID;
    }
    return -1;
}
int GN_GetSeriesMind()
{
    if(GetHasSpell(FORCE_POWER_MIND_MASTERY))
    {
        return FORCE_POWER_MIND_MASTERY;
    }
    else if(GetHasSpell(FORCE_POWER_KNIGHT_MIND))
    {
        return FORCE_POWER_KNIGHT_MIND;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_MIND))
    {
        return FORCE_POWER_FORCE_MIND;
    }
    return -1;
}
int GN_GetSeriesResist()
{
    if(GetHasSpell(FORCE_POWER_RESIST_COLD_HEAT_ENERGY))
    {
        return FORCE_POWER_RESIST_COLD_HEAT_ENERGY;
    }
    else if(GetHasSpell(FORCE_POWER_RESIST_POISON_DISEASE_SONIC))
    {
        return FORCE_POWER_RESIST_POISON_DISEASE_SONIC;
    }
    return -1;
}
int GN_GetSeriesForceImmunity()
{
    if(GetHasSpell(FORCE_POWER_FORCE_IMMUNITY))
    {
        return FORCE_POWER_FORCE_IMMUNITY;
    }
    else if(GetHasSpell(FORCE_POWER_RESIST_FORCE))
    {
        return FORCE_POWER_RESIST_FORCE;
    }
    return -1;
}
int GN_GetSeriesBreach()
{
    if(GetHasSpell(FORCE_POWER_FORCE_BREACH))
    {
        return FORCE_POWER_FORCE_BREACH;
    }
    else if(GetHasSpell(FORCE_POWER_SUPRESS_FORCE))
    {
        return FORCE_POWER_SUPRESS_FORCE;
    }
    return -1;
}
//::///////////////////////////////////////////////
//:: Force Power Series Checks
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks if a Jedi has 1 in a force power series
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 27, 2002
//:://////////////////////////////////////////////
int GN_CheckSeriesForcePush()
{
    if(GetHasSpell(FORCE_POWER_FORCE_PUSH) || GetHasSpell(FORCE_POWER_FORCE_WHIRLWIND) || GetHasSpell(FORCE_POWER_FORCE_WAVE))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesArmor()
{
    if(GetHasSpell(FORCE_POWER_FORCE_ARMOR) || GetHasSpell(FORCE_POWER_FORCE_SHIELD) || GetHasSpell(FORCE_POWER_FORCE_AURA))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesFear()
{
    if(GetHasSpell(FORCE_POWER_FEAR) || GetHasSpell(FORCE_POWER_HORROR) || GetHasSpell(FORCE_POWER_INSANITY))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesHold()
{
    if(GetHasSpell(FORCE_POWER_STUN) || GetHasSpell(FORCE_POWER_HOLD) || GetHasSpell(FORCE_POWER_SLEEP))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesAfflict()
{
    if(GetHasSpell(FORCE_POWER_SLOW) || GetHasSpell(FORCE_POWER_AFFLICTION) || GetHasSpell(FORCE_POWER_PLAGUE))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesSaberThrow()
{
    if(GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW) || GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW_ADVANCED))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesLightning()
{
    if(GetHasSpell(FORCE_POWER_SHOCK) || GetHasSpell(FORCE_POWER_LIGHTNING) || GetHasSpell(FORCE_POWER_FORCE_STORM))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesJump()
{
    if(GetHasSpell(FORCE_POWER_FORCE_JUMP) || GetHasSpell(FORCE_POWER_FORCE_JUMP_ADVANCED))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesChoke()
{
    if(GetHasSpell(FORCE_POWER_CHOKE) || GetHasSpell(FORCE_POWER_WOUND) || GetHasSpell(FORCE_POWER_KILL))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesDrainLife()
{
    if(GetHasSpell(FORCE_POWER_DRAIN_LIFE) || GetHasSpell(FORCE_POWER_DEATH_FIELD))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesSpeed()
{
    if(GetHasSpell(FORCE_POWER_SPEED_BURST) || GetHasSpell(FORCE_POWER_SPEED_MASTERY) || GetHasSpell(FORCE_POWER_KNIGHT_SPEED))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesMind()
{
    if(GetHasSpell(FORCE_POWER_MIND_MASTERY) || GetHasSpell(FORCE_POWER_KNIGHT_MIND) || GetHasSpell(FORCE_POWER_FORCE_MIND))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesResist()
{
    if(GetHasSpell(FORCE_POWER_RESIST_COLD_HEAT_ENERGY) || GetHasSpell(FORCE_POWER_RESIST_POISON_DISEASE_SONIC))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesForceImmunity()
{
    if(GetHasSpell(FORCE_POWER_RESIST_FORCE) || GetHasSpell(FORCE_POWER_FORCE_IMMUNITY))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesBreach()
{
    if(GetHasSpell(FORCE_POWER_SUPRESS_FORCE) || GetHasSpell(FORCE_POWER_FORCE_BREACH))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesDroidUtilities()
{
    talent tUse = GetCreatureTalentRandom(0x8000);
    /*
    if(GetHasSpell(116) || GetHasSpell(117) || GetHasSpell(118) ||
       GetHasSpell(119) || GetHasSpell(120) || GetHasSpell(121) ||
       GetHasSpell(121) || GetHasSpell(122) || GetHasSpell(123) ||
       GetHasSpell(124) || GetHasSpell(125))
    */
    if(GetIsTalentValid(tUse))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Is Combo Valid
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets a combo constant and determines if the
    NPC can perform the stated combo
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 27, 2002
//:://////////////////////////////////////////////
int GN_GetIsComboValid(int nComboType)
{
    //P.W (May 27, 2003) - Made allowances for an invalid effect to be passed in.
    if(nComboType == SW_COMBO_INVALID)
    {
        return FALSE;
    }
    talent tTest, tTest2;
    if(nComboType == SW_COMBO_MELEE_FEROCIOUS ||
            nComboType == SW_COMBO_MELEE_AGGRESSIVE ||
            nComboType == SW_COMBO_MELEE_DISCIPLINED)
    {
        tTest = GetCreatureTalentRandom(0x1104); //Only Melee feats use this code
        if(GetIsTalentValid(tTest) && GetCreatureHasTalent(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_RANGED_CAUTIOUS)
    {
        return TRUE;
    }
    else if(nComboType == SW_COMBO_RANGED_FEROCIOUS ||
       nComboType == SW_COMBO_RANGED_AGGRESSIVE ||
       nComboType == SW_COMBO_RANGED_DISCIPLINED)
    {
        //These are the only ranged feats in the game and therefore it is better to use a feat constant not a talent code
        //given that 0x1101 is also used by some force powers.
        if(GetHasFeat(FEAT_SNIPER_SHOT) || GetHasFeat(FEAT_IMPROVED_SNIPER_SHOT) || GetHasFeat(FEAT_MASTER_SNIPER_SHOT) ||
           GetHasFeat(FEAT_POWER_BLAST) || GetHasFeat(FEAT_IMPROVED_POWER_BLAST) || GetHasFeat(82) || //Master Power Blast
           GetHasFeat(FEAT_RAPID_SHOT) || GetHasFeat(FEAT_MULTI_SHOT) || GetHasFeat(92))//92 = IMRPOVED_RAPID_SHOT
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_MELEE_CAUTIOUS)
    {
        return TRUE;
    }
    else if(nComboType == SW_COMBO_BUFF_PARTY)
    {
        tTest = GetCreatureTalentRandom(0xf8ff);
        if(GetIsTalentValid(tTest) && GetCreatureHasTalent(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_BUFF_DEBILITATE)
    {
        tTest = GetCreatureTalentRandom(0xf8ff);
        tTest2 = GetCreatureTalentRandom(0xf2ff);
        if(GetIsTalentValid(tTest) && GetIsTalentValid(tTest2)
           && GetCreatureHasTalent(tTest)
           && GetCreatureHasTalent(tTest2))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_BUFF_DAMAGE)
    {
        tTest = GetCreatureTalentRandom(0xf8ff);
        if(GetIsTalentValid(tTest) && GN_GetHasDamagingForcePower())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_BUFF_DEBILITATE_DESTROY)
    {
        tTest = GetCreatureTalentRandom(0xf8ff);
        tTest2 = GetCreatureTalentRandom(0xf2ff);
        if(GetIsTalentValid(tTest) && GetIsTalentValid(tTest2) && GN_GetHasDamagingForcePower())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SUPRESS_DEBILITATE_DESTROY)
    {
        tTest = GetCreatureTalentRandom(0xff2f);
        tTest2 = GetCreatureTalentRandom(0xf2ff);
        if(GetIsTalentValid(tTest) && GetIsTalentValid(tTest2) && GN_GetHasDamagingForcePower())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_ATTACK)
    {
        if(GN_CheckSeriesForcePush() && GN_CheckSeriesChoke() && GN_CheckSeriesJump())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_BUFF_ATTACK)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesArmor() && GN_CheckSeriesSpeed() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_CONFOUND)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesLightning() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_JEDI_SMITE)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesHold() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_TAUNT)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesChoke() && GN_CheckSeriesAfflict() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_BLADE)
    {
        if(GN_CheckSeriesAfflict() && GN_CheckSeriesForcePush() && GN_CheckSeriesSaberThrow())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_CRUSH)
    {
        if(GN_CheckSeriesLightning() && GN_CheckSeriesForcePush() && GN_CheckSeriesJump())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_JEDI_CRUSH)
    {
        if(GN_CheckSeriesHold() && GN_CheckSeriesForcePush() && GN_CheckSeriesJump())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_JEDI_CRUSH)
    {
        if(GN_CheckSeriesChoke() && GN_CheckSeriesDrainLife() && GN_CheckSeriesForcePush())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_DRAIN)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesDrainLife() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_ESCAPE)
    {
        if(GN_CheckSeriesDrainLife() && GN_CheckSeriesForcePush() && GN_CheckSeriesSaberThrow())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_JEDI_BLITZ)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesForcePush() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_SPIKE)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesForcePush() && GN_CheckSeriesAfflict() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_SCYTHE)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesDrainLife() && GN_CheckSeriesBreach() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_DROID_UTILITIES || nComboType == SW_COMBO_DROID_UTILITIES_2)
    {
        object oItem1 = GetItemInSlot(INVENTORY_SLOT_LEFTARM);
        object oItem2 = GetItemInSlot(INVENTORY_SLOT_RIGHTARM);
        GN_MyPrintString("GENERIC DEBUG *************** Droid Items = " + GN_ReturnDebugName(oItem1) + " / " + GN_ReturnDebugName(oItem2));
        if(GN_CheckSeriesDroidUtilities())
        {
            GN_MyPrintString("GENERIC DEBUG *************** Droid Utility Check is TRUE");
            return TRUE;
        }
        GN_MyPrintString("GENERIC DEBUG *************** Droid Utility Check is FALSE");
    }
    return FALSE;
}
int GN_GetHasDamagingForcePower()
{
    if(GetHasSpell(FORCE_POWER_CHOKE) ||
       GetHasSpell(FORCE_POWER_DEATH_FIELD) ||
       GetHasSpell(FORCE_POWER_DRAIN_LIFE) ||
       GetHasSpell(FORCE_POWER_DROID_DESTROY) ||
       GetHasSpell(FORCE_POWER_DROID_DISABLE) ||
       GetHasSpell(FORCE_POWER_FORCE_PUSH) ||
       GetHasSpell(FORCE_POWER_FORCE_STORM) ||
       GetHasSpell(FORCE_POWER_FORCE_WAVE) ||
       GetHasSpell(FORCE_POWER_FORCE_WHIRLWIND) ||
       GetHasSpell(FORCE_POWER_KILL) ||
       GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW) ||
       GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW_ADVANCED) ||
       GetHasSpell(FORCE_POWER_LIGHTNING) ||
       GetHasSpell(FORCE_POWER_SHOCK) ||
       GetHasSpell(FORCE_POWER_WOUND))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Get Weapon Type
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Return 1 if the object is a Melee Weapon and
    2 if the weapon is a Ranged Weapon
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 2, 2002
//:://////////////////////////////////////////////
int GN_GetWeaponType(object oTarget = OBJECT_SELF)
{
    object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON,oTarget);
    //GN_MyPrintString("GENERIC DEBUG *************** Valid Weapon = " + GN_ITS(GetIsObjectValid(oItem)));
    if(GetIsObjectValid(oItem))
    {
        if( GetBaseItemType(oItem) == BASE_ITEM_BLASTER_CARBINE ||
           GetBaseItemType(oItem) == BASE_ITEM_BLASTER_PISTOL ||
           GetBaseItemType(oItem) == BASE_ITEM_BLASTER_RIFLE ||
           GetBaseItemType(oItem) == BASE_ITEM_BOWCASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_DISRUPTER_PISTOL ||
           GetBaseItemType(oItem) == BASE_ITEM_DISRUPTER_RIFLE ||
           GetBaseItemType(oItem) == BASE_ITEM_HEAVY_BLASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_HEAVY_REPEATING_BLASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_HOLD_OUT_BLASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_ION_BLASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_ION_RIFLE ||
           GetBaseItemType(oItem) == BASE_ITEM_REPEATING_BLASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_SONIC_PISTOL ||
           GetBaseItemType(oItem) == BASE_ITEM_SONIC_RIFLE ||
           GetBaseItemType(oItem) == BASE_ITEM_SONIC_PISTOL )
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Ranged Weapon Equipped");
            return 2;
        }
        else if( GetBaseItemType(oItem) == BASE_ITEM_DOUBLE_BLADED_LIGHTSABER ||
           GetBaseItemType(oItem) == BASE_ITEM_DOUBLE_BLADED_SWORD ||
           GetBaseItemType(oItem) == BASE_ITEM_GAMMOREAN_BATTLEAXE ||
           GetBaseItemType(oItem) == BASE_ITEM_GHAFFI_STICK ||
           GetBaseItemType(oItem) == BASE_ITEM_LIGHTSABER ||
           GetBaseItemType(oItem) == BASE_ITEM_LONG_SWORD ||
           GetBaseItemType(oItem) == BASE_ITEM_QUARTER_STAFF ||
           GetBaseItemType(oItem) == BASE_ITEM_SHORT_LIGHTSABER ||
           GetBaseItemType(oItem) == BASE_ITEM_SHORT_SWORD ||
           GetBaseItemType(oItem) == BASE_ITEM_STUN_BATON ||
           GetBaseItemType(oItem) == BASE_ITEM_VIBRO_BLADE ||
           GetBaseItemType(oItem) == BASE_ITEM_VIBRO_DOUBLE_BLADE ||
           GetBaseItemType(oItem) == BASE_ITEM_VIBRO_SWORD ||
           GetBaseItemType(oItem) == BASE_ITEM_WOOKIE_WARBLADE )
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee Weapon Equipped");
            return 1;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Return No Weapon Type");
    return 0;
}
//
//::///////////////////////////////////////////////
//:: Equip Appropriate Weapon
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets the NPC to eqyuip a melee = 1 or
    ranged = 2 weapon.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 13, 2003
//:://////////////////////////////////////////////
int GN_EquipAppropriateWeapon()
{
    object oItem;
    if(GetIsObjectValid(GetAttackTarget()) &&
       GetDistanceBetween(GetAttackTarget(), OBJECT_SELF) <= 3.0 &&
       GN_GetWeaponType() != 1 &&
       GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HUMAN &&
       !IsObjectPartyMember(OBJECT_SELF))
    {
        oItem = GetFirstItemInInventory();
        while(GetIsObjectValid(oItem))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Checking Melee Weapon");
            if( GetBaseItemType(oItem) == BASE_ITEM_DOUBLE_BLADED_LIGHTSABER ||
               GetBaseItemType(oItem) == BASE_ITEM_DOUBLE_BLADED_SWORD ||
               GetBaseItemType(oItem) == BASE_ITEM_GAMMOREAN_BATTLEAXE ||
               GetBaseItemType(oItem) == BASE_ITEM_GHAFFI_STICK ||
               GetBaseItemType(oItem) == BASE_ITEM_LIGHTSABER ||
               GetBaseItemType(oItem) == BASE_ITEM_LONG_SWORD ||
               GetBaseItemType(oItem) == BASE_ITEM_QUARTER_STAFF ||
               GetBaseItemType(oItem) == BASE_ITEM_SHORT_LIGHTSABER ||
               GetBaseItemType(oItem) == BASE_ITEM_SHORT_SWORD ||
               GetBaseItemType(oItem) == BASE_ITEM_STUN_BATON ||
               GetBaseItemType(oItem) == BASE_ITEM_VIBRO_BLADE ||
               GetBaseItemType(oItem) == BASE_ITEM_VIBRO_DOUBLE_BLADE ||
               GetBaseItemType(oItem) == BASE_ITEM_VIBRO_SWORD ||
               GetBaseItemType(oItem) == BASE_ITEM_WOOKIE_WARBLADE )
            {
                GN_MyPrintString("GENERIC DEBUG *************** Equipping Melee Weapon");
                //ActionEquipItem(oItem, INVENTORY_SLOT_RIGHTWEAPON, TRUE);
                ActionEquipMostDamagingMelee();
                return TRUE;
            }
            else
            {
              oItem = GetNextItemInInventory();
            }
        }
    }
    else if(GN_GetWeaponType() != 2 &&
            GetLevelByClass(CLASS_TYPE_JEDICONSULAR) == 0 &&
            GetLevelByClass(CLASS_TYPE_JEDIGUARDIAN) == 0 &&
            GetLevelByClass(CLASS_TYPE_JEDISENTINEL) == 0 &&
            //GetIsObjectValid(GetAttackTarget()) &&
            GetDistanceBetween(GetAttemptedAttackTarget(), OBJECT_SELF) > 3.0 &&
            !IsObjectPartyMember(OBJECT_SELF))
    {
        oItem = GetFirstItemInInventory();
        while(GetIsObjectValid(oItem))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Checking Ranged Weapon");
            if( GetBaseItemType(oItem) == BASE_ITEM_BLASTER_CARBINE ||
               GetBaseItemType(oItem) == BASE_ITEM_BLASTER_PISTOL ||
               GetBaseItemType(oItem) == BASE_ITEM_BLASTER_RIFLE ||
               GetBaseItemType(oItem) == BASE_ITEM_BOWCASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_DISRUPTER_PISTOL ||
               GetBaseItemType(oItem) == BASE_ITEM_DISRUPTER_RIFLE ||
               GetBaseItemType(oItem) == BASE_ITEM_HEAVY_BLASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_HEAVY_REPEATING_BLASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_HOLD_OUT_BLASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_ION_BLASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_ION_RIFLE ||
               GetBaseItemType(oItem) == BASE_ITEM_REPEATING_BLASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_SONIC_PISTOL ||
               GetBaseItemType(oItem) == BASE_ITEM_SONIC_RIFLE ||
               GetBaseItemType(oItem) == BASE_ITEM_SONIC_PISTOL )
              {
                GN_MyPrintString("GENERIC DEBUG *************** Equipping Ranged Weapon");
                //ActionEquipItem(oItem, INVENTORY_SLOT_RIGHTWEAPON, TRUE);
                ActionEquipMostDamagingRanged();
                return TRUE;
              }
              else
              {
                oItem = GetNextItemInInventory();
              }
         }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Should not currently change weapons");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Check Friendly Fire on Target
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Takes a target object and a radius and
    returns how many friendly targets
    are in that zone.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17, 2003
//:://////////////////////////////////////////////
int GN_CheckFriendlyFireOnTarget(object oTarget, float fDistance = 4.0)
{
    int nCnt, nHD, nMyHD;
    nMyHD = GetHitDice(OBJECT_SELF);
    object oCheck = GetFirstObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
    while(GetIsObjectValid(oCheck))
    {
        //P.W.(May 20, 2003) - Put a dead check here for whether the person being checked is dead.
        if(GetIsFriend(oCheck) && !GetIsDead(oCheck))
        {
            nCnt++;
        }
        oCheck = GetNextObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
    }
    return nCnt;
}
//::///////////////////////////////////////////////
//:: Check For Enemies Around Target
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Takes a target object and a radius and
    returns how many targets of the enemy faction
    are in that zone.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2001
//:://////////////////////////////////////////////
int GN_CheckEnemyGroupingOnTarget(object oTarget, float fDistance = 4.0)
{
    int nCnt;
    object oCheck = GetFirstObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
    while(GetIsObjectValid(oCheck))
    {
        //P.W.(May 20, 2003) - Put a dead check here for whether the person being checked is dead.
        if(GetIsEnemy(oCheck) && !GetIsDead(oCheck))
        {
            nCnt++;
        }
        oCheck = GetNextObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
    }
    return nCnt;
}
//::///////////////////////////////////////////////
//:: Find Grenade Target
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and marks a group as a viable
    target for a grenade
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17m 2003
//:://////////////////////////////////////////////
object GN_FindGrenadeTarget()
{
    int nMinimum = 0;
    if(IsObjectPartyMember(OBJECT_SELF))
    {
        nMinimum = 1;
    }
    int nFriend = 0;
    int nEnemy = 0;
    int nEnemyCnt = 0;
    object oFinal;
    object oCheck = GetFirstObjectInShape(SHAPE_SPHERE, 40.0, GetLocation(OBJECT_SELF));
    while(GetIsObjectValid(oCheck))
    {
        if(GetObjectSeen(oCheck) && !GetIsDead(oCheck))
        {
            nFriend = GN_CheckFriendlyFireOnTarget(oCheck);
            nEnemy = GN_CheckEnemyGroupingOnTarget(oCheck);
            //GN_MyPrintString("GENERIC DEBUG *************** Friends " + GN_ITS(nFriend) + "Enemies" + GN_ITS(nEnemy));
            if(nEnemy > nMinimum && nFriend == 0 && nEnemyCnt < nEnemy)
            {
                oFinal = oCheck;
                nEnemyCnt = nEnemy;
            }
        }
        oCheck = GetNextObjectInShape(SHAPE_SPHERE, 40.0, GetLocation(OBJECT_SELF));
    }
    return oFinal;
}
//::///////////////////////////////////////////////
//:: Find Grenade Target
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and marks a group as a
    viable target for a AOE force power
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17m 2003
//:://////////////////////////////////////////////
object GN_FindAOETarget()
{
    int nEnemy = 0;
    int nEnemyCnt = 0;
    object oFinal;
    object oCheck = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF));
    while(GetIsObjectValid(oCheck))
    {
        nEnemy = GN_CheckEnemyGroupingOnTarget(oCheck,4.0);
        if(nEnemy > 2 && nEnemyCnt < nEnemy)
        {
            oFinal = oCheck;
            nEnemyCnt = nEnemy;
        }
        oCheck = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF));
    }
    return oFinal;
}
//::///////////////////////////////////////////////
//:: Get Grenade Talent
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a talent based on the target.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17, 2003
//:://////////////////////////////////////////////
talent GN_GetGrenadeTalent(int nDroid = FALSE)
{
    talent tUse;
    int n87, n88, n89, n90, n91, n92, n93, n94, n95;
    int nRand = 0;
    int bValid = FALSE;
    int nCnt = 87;
    for(nCnt; nCnt < 96; nCnt++)
    {
        tUse = TalentSpell(nCnt);
        if(GetCreatureHasTalent(tUse))
        {
            switch(nCnt)
            {
                case 87:
                {
                    n87 = TRUE;
                    nRand++;
                }
                break;
                case 88:
                {
                    if(nDroid == FALSE)
                    {
                        n88 = TRUE;
                        nRand++;
                    }
                }
                break;
                case 89:
                {
                    n89 = TRUE;
                    nRand++;
                }
                break;
                case 90:
                {
                    if(nDroid == FALSE)
                    {
                        n90 = TRUE;
                        nRand++;
                    }
                }
                break;
                case 91:
                {
                    if(nDroid == FALSE)
                    {
                        n91 = TRUE;
                        nRand++;
                    }
                }
                break;
                case 92:
                {
                    if(nDroid == FALSE)
                    {
                        n92 = TRUE;
                        nRand++;
                    }
                }
                break;
                case 93:
                {
                    if(nDroid == FALSE)
                    {
                        n93 = TRUE;
                        nRand++;
                    }
                }
                break;
                case 94:
                {
                    n94 = TRUE;
                    nRand++;
                }
                break;
                case 95:
                {
                    if(nDroid == TRUE)
                    {
                        n95 = TRUE;
                        nRand++;
                    }
                }
                break;
            }
        }
    }
    int nRoll;
    if(nRand > 0)
    {
        nRoll = Random(nRand) + 1;
    }
    else
    {
        nRoll = 0;
    }
    //GN_MyPrintString("GENERIC DEBUG *************** Roll = " + GN_ITS(nRoll));
    if(nRand > 0)
    {
        //FRAG GRENADE
        if(nRoll == 1 && n87 == TRUE)
        {
            return tUse = TalentSpell(87);
        }
        if(nRoll > 1 && n87 == TRUE)
        {
            nRoll--;
        }
        //STUN GRENADE
        if(nRoll == 1 && n88 == TRUE)
        {
            return tUse = TalentSpell(88);
        }
        if(nRoll > 1 && n88 == TRUE)
        {
            nRoll--;
        }
        //THERMAL DETONATOR
        if(nRoll == 1 && n89 == TRUE)
        {
            return tUse = TalentSpell(89);
        }
        if(nRoll > 1 && n89 == TRUE)
        {
            nRoll--;
        }
        //POISON
        if(nRoll == 1 && n90 == TRUE)
        {
            return tUse = TalentSpell(90);
        }
        if(nRoll > 1 && n90 == TRUE)
        {
            nRoll--;
        }
        //SONIC
        if(nRoll == 1 && n91 == TRUE)
        {
            return tUse = TalentSpell(91);
        }
        if(nRoll > 1 && n91 == TRUE)
        {
            nRoll--;
        }
        //ADHESIVE
        if(nRoll == 1 && n92 == TRUE)
        {
            return tUse = TalentSpell(92);
        }
        if(nRoll > 1 && n92 == TRUE)
        {
            nRoll--;
        }
        //CRYOBAN
        if(nRoll == 1 && n93 == TRUE)
        {
            return tUse = TalentSpell(93);
        }
        if(nRoll > 1 && n93 == TRUE)
        {
            nRoll--;
        }
        //PLASMA
        if(nRoll == 1 && n94 == TRUE)
        {
            return tUse = TalentSpell(94);
        }
        if(nRoll > 1 && n94 == TRUE)
        {
            nRoll--;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Grenade Selection Failure");
    talent tNull;
    return tNull;
    return tNull;
}
//::///////////////////////////////////////////////
//:: Get Boss Combat Move
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a talent for the boss to perform
    in combat.  This function will try and pick a
    talent which will inflict maximum damage
    on the party via area of effect spells, grenades
    and debilitating effects.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 2, 2003
//:://////////////////////////////////////////////
talent GN_GetBossCombatMove(int nBossAttackType, int nDroid = FALSE)
{
    talent tInvalid;
    talent tUse;
    int bValid = FALSE;
    if(nBossAttackType == SW_BOSS_ATTACK_TYPE_GRENADE || nBossAttackType == SW_BOSS_ATTACK_ANY)
    {
        tUse = GN_GetGrenadeTalent(nDroid);
        if(GetIsTalentValid(tUse))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Grenade Talent Chosen");
            return tUse;
        }
    }
    if(nBossAttackType == SW_BOSS_ATTACK_TYPE_FORCE_POWER || nBossAttackType == SW_BOSS_ATTACK_ANY)
    {
        tUse = GN_GetAOEForcePower(nDroid);
        if(GetIsTalentValid(tUse))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Force Power Talent Chosen");
            return tUse;
        }
    }
    if(nBossAttackType == SW_BOSS_ATTACK_TYPE_NPC || nBossAttackType == SW_BOSS_ATTACK_ANY)
    {
        if(d100() > 50)
        {
            tUse = GN_GetTargetedForcePower(nDroid);
            if(GetIsTalentValid(tUse))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Targeted Force Power Talent Chosen");
                return tUse;
            }
            tUse = GN_GetAOEForcePower(nDroid);
            if(GetIsTalentValid(tUse))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Force Power Talent Chosen");
                return tUse;
            }
        }
        if(GN_GetWeaponType() == 1)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Melee Feat Talent Chosen");
            tUse = GetCreatureTalentRandom(0x1104); //Only melee feats use this code
        }
        else
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Range Feat Talent Chosen");
            tUse = GetCreatureTalentRandom(0x1111); //Only ranged feats use this code
        }
        if(GetIsTalentValid(tUse))
        {
            return tUse;
        }
    }
    else if(nBossAttackType == SW_BOSS_ATTACK_TYPE_PC || nBossAttackType == SW_BOSS_ATTACK_ANY)
    {
        if(d100() > 70)
        {
            tUse = GN_GetTargetedForcePower(nDroid);
            if(GetIsTalentValid(tUse))
            {
                return tUse;
            }
            tUse = GN_GetAOEForcePower(nDroid);
            if(GetIsTalentValid(tUse))
            {
                return tUse;
            }
        }
        tUse = GetCreatureTalentRandom(0x1104); //Only melee feats use this code
        if(GetIsTalentValid(tUse))
        {
            return tUse;
        }
        GN_MyPrintString("GENERIC DEBUG *************** Boss AI: No Feats Available");
    }
    //Comment this out so that the boss AI handles the failure not this function.
    /*
    if(!GetIsTalentValid(tUse) && nBossAttackType != SW_BOSS_ATTACK_ANY)
    {
        tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_ANY);
    }
    */
    return tUse;
}
//::///////////////////////////////////////////////
//:: Get AOE Force Power
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks and returns a random force power that
    can effect more than 1 target.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 2, 2003
//:://////////////////////////////////////////////
talent GN_GetAOEForcePower(int nDroid = FALSE)
{
    talent tUse;
    int nHorror, nInsanity, nStorm, nWave, nSaber, nLightning, nSleep, nStunDroid, nKillDroid, nHowl, nCnt;
    //MODIFIED by Preston Watamaniuk on April 27, 2003
    //Removed Death Field so that it would be used exlusively for Healing.
    //MODIFIED by Preston Watamaniuk on May 14, 2003
    //Put a check into make sure that the same AOE power is not used over and over.
    int nLastForcePower = GetLastForcePowerUsed(OBJECT_SELF);
    GN_MyPrintString("GENERIC DEBUG *************** Last Force Power Used = " + GN_ITS(nLastForcePower));
    //THIS SECTION DETERMINES WHICH POWERS ARE APPLICABLE
    if(GetHasSpell(FORCE_POWER_HORROR) && nDroid == FALSE && nLastForcePower != FORCE_POWER_HORROR)
    {
        nHorror = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_INSANITY) && nDroid == FALSE && nLastForcePower != FORCE_POWER_INSANITY)
    {
        nInsanity = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_FORCE_STORM) && nLastForcePower != FORCE_POWER_FORCE_STORM)
    {
        nStorm = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_FORCE_WAVE) && nLastForcePower != FORCE_POWER_FORCE_WAVE)
    {
        nWave = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW_ADVANCED) && nLastForcePower != FORCE_POWER_LIGHT_SABER_THROW_ADVANCED)
    {
        nSaber = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_LIGHTNING) && nLastForcePower != FORCE_POWER_LIGHTNING)
    {
        nLightning = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_SLEEP) && nDroid == FALSE && nLastForcePower != FORCE_POWER_SLEEP)//Now Mass Stasis
    {
        nSleep = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_DROID_STUN) && nDroid == TRUE && nLastForcePower != FORCE_POWER_DROID_STUN)
    {
        nStunDroid = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_DROID_DESTROY) && nDroid == TRUE && nLastForcePower != FORCE_POWER_DROID_DESTROY)
    {
        nKillDroid = 1;
        nCnt++;
    }
    talent tHowl  = TalentSpell(131);
    if(GetCreatureHasTalent(tHowl)) //Sonic Howl
    {
        nHowl = 1;
        nCnt++;
    }
    //THIS SECTION DETERMINES WHICH POWER TO USE
    int nRoll;
    if(nCnt > 0)
    {
        nRoll = Random(nCnt) + 1;
    }
    else
    {
        nRoll = 0;
    }
    //Horror
    if(nHorror == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_HORROR);
        nRoll--;
    }
    if(nHorror == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Insanity
    if(nInsanity == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_INSANITY);
        nRoll--;
    }
    if(nHorror == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Force Storm
    if(nStorm == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_FORCE_STORM);
        nRoll--;
    }
    if(nStorm == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Force Wave
    if(nWave == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_FORCE_WAVE);
        nRoll--;
    }
    if(nWave == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Advanced Saber Throw
    if(nSaber == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_LIGHT_SABER_THROW_ADVANCED);
        nRoll--;
    }
    if(nSaber == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Lightning
    if(nLightning == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_LIGHTNING);
        nRoll--;
    }
    if(nLightning == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Mass Stasis
    if(nSleep == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_SLEEP);
        nRoll--;
    }
    if(nSleep == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Stun Droid
    if(nStunDroid == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_DROID_STUN);
        nRoll--;
    }
    if(nStunDroid == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Destroy Droid
    if(nKillDroid == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_DROID_DESTROY);
        nRoll--;
    }
    if(nKillDroid == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Sonic Howl
    if(nKillDroid == 1 && nRoll == 1)
    {
        tUse = TalentSpell(131);
        nRoll--;
    }
    if(nHowl == 1 && nRoll > 1)
    {
        nRoll--;
    }
    GN_MyPrintString("GENERIC DEBUG *************** Force Power Returned = " + GN_ITS(GetIdFromTalent(tUse)));
    return tUse;
}
//::///////////////////////////////////////////////
//:: Get Targeted Force Power
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks and returns a random force power that
    can effect 1 target.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 2, 2003
//:://////////////////////////////////////////////
talent GN_GetTargetedForcePower(int nDroid = FALSE)
{
    talent tUse;
    int nChoke, nAfflict, nPlague, nPush, nWind, nLightning, nKill, nHorror, nWound, nStasis, nDroid, nKnock, nHowl, nCnt;
    if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID)
    {
        tUse = GetCreatureTalentRandom(0x8000);
        if(GetIsTalentValid(tUse))
        {
            return tUse;
        }
    }
    //MODIFIED by Preston Watamaniuk on April 27, 2003
    //Removed Drain Life so that it would be used exlusively for Healing.
    if(GetHasSpell(FORCE_POWER_CHOKE) && nDroid == FALSE)
    {
        nChoke = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_AFFLICTION) && nDroid == FALSE)
    {
        nAfflict = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_PLAGUE) && nDroid == FALSE)
    {
        nPlague = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_FORCE_PUSH))
    {
        nPush = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_FORCE_WHIRLWIND))
    {
        nWind = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_LIGHTNING))
    {
        nLightning = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_KILL) && nDroid == FALSE)
    {
        nKill = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_HORROR) && nDroid == FALSE)
    {
        nHorror = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_WOUND) && nDroid == FALSE)
    {
        nWound = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_HOLD))
    {
        nStasis = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_DROID_DISABLE) && nDroid == TRUE)
    {
        nDroid = 1;
        nCnt++;
    }
    talent tSlam  = TalentSpell(83);
    if(GetCreatureHasTalent(tSlam)) //Monster Slam
    {
        nKnock = 1;
        nCnt++;
    }
    //THIS SECTION DETERMINES WHICH POWER TO USE
    int nRoll;
    if(nCnt > 0)
    {
        nRoll = Random(nCnt) + 1;
    }
    else
    {
        nRoll = 0;
    }
    //Choke
    if(nChoke == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_CHOKE);
        nRoll--;
    }
    if(nChoke == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Affliction
    if(nAfflict == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_AFFLICTION);
        nRoll--;
    }
    if(nAfflict == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Plague
    if(nPlague == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_AFFLICTION);
        nRoll--;
    }
    if(nPlague == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Force Push
    if(nPush == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_FORCE_PUSH);
        nRoll--;
    }
    if(nPush == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Force Whirlwind
    if(nWind == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_FORCE_WHIRLWIND);
        nRoll--;
    }
    if(nWind == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Lightning
    if(nLightning == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_LIGHTNING);
        nRoll--;
    }
    if(nLightning == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Kill
    if(nKill == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_KILL);
        nRoll--;
    }
    if(nKill == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Horror
    if(nHorror == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_HORROR);
        nRoll--;
    }
    if(nHorror == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Wound
    if(nWound== 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_WOUND);
        nRoll--;
    }
    if(nWound == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Stasis
    if(nStasis== 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_HOLD);
        nRoll--;
    }
    if(nStasis == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Disable Droid
    if(nDroid== 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_DROID_DISABLE);
        nRoll--;
    }
    if(nDroid == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Monster Slam
    if(nKnock == 1 && nRoll == 1)
    {
        tUse = TalentSpell(83);
        nRoll--;
    }
    if(nKnock == 1 && nRoll > 1)
    {
        nRoll--;
    }
    return tUse;
}
//::///////////////////////////////////////////////
//:: Get Active Party Member Count
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the number of party members who
    are active
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 2, 2003
//:://////////////////////////////////////////////
int GN_GetActivePartyMemberCount()
{
    object oNPC1 = GetPartyMemberByIndex(0);
    object oNPC2 = GetPartyMemberByIndex(1);
    object oNPC3 = GetPartyMemberByIndex(2);
    int nCnt = 0;
    if(GetIsObjectValid(oNPC1) && GetCurrentHitPoints(oNPC1) > 0 && GetObjectSeen(oNPC1))
    {
        nCnt++;
    }
    if(GetIsObjectValid(oNPC2) && GetCurrentHitPoints(oNPC2) > 0 && GetObjectSeen(oNPC2))
    {
        nCnt++;
    }
    if(GetIsObjectValid(oNPC3) && GetCurrentHitPoints(oNPC3) > 0 && GetObjectSeen(oNPC3))
    {
        nCnt++;
    }
    return nCnt;
}
//::///////////////////////////////////////////////
//:: Get Active Party Member
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a party member who is active a not
    currently controlled by the PC.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 2, 2003
//:://////////////////////////////////////////////
/*
    MODIFIED by Preston Watamaniuk on March 8, 2003
    Added some functionality so that the Drain Life
    will be targeted on the 0 Index as well as the
    other party members. Also if Drain = TRUE then
    no droids will be returned.
    This function will return the nearest non-droid
    enemy if the party is freindly.
*/
//:://////////////////////////////////////////////
object GN_GetActivePartyMember(int nDrainTarget = FALSE)
{
    object oNPC1 = GetPartyMemberByIndex(0);
    object oNPC2 = GetPartyMemberByIndex(1);
    object oNPC3 = GetPartyMemberByIndex(2);
    object oTarget;
    int nCnt = 0;
    int nRoll;
    int nNPC1 = FALSE;
    int nNPC2 = FALSE;
    int nNPC3 = FALSE;
    if(GetIsObjectValid(oNPC2) && GetCurrentHitPoints(oNPC2) > 0 && GetObjectSeen(oNPC2))
    {
        if(GetRacialType(oNPC2) != RACIAL_TYPE_DROID || nDrainTarget == FALSE)
        {
            nCnt++;
            nNPC2 = TRUE;
        }
    }
    if(GetIsObjectValid(oNPC3) && GetCurrentHitPoints(oNPC3) > 0 && GetObjectSeen(oNPC3))
    {
        if(GetRacialType(oNPC3) != RACIAL_TYPE_DROID || nDrainTarget == FALSE)
        {
            nCnt++;
            nNPC3 = TRUE;
        }
    }
    if(nDrainTarget == TRUE)
    {
        if(GetIsObjectValid(oNPC1) && GetCurrentHitPoints(oNPC1) > 0 && GetObjectSeen(oNPC1))
        {
            if(GetRacialType(oNPC1) != RACIAL_TYPE_DROID)
            {
                nCnt++;
                nNPC1 = TRUE;
            }
        }
    }
    if(nCnt == 0)
    {
        oTarget = OBJECT_INVALID;
    }
    else if(nCnt == 1)
    {
        if(nNPC2 == TRUE){oTarget = oNPC2;}
        else if(nNPC3 == TRUE){oTarget = oNPC3;}
        else if(nNPC1 == TRUE){oTarget = oNPC1;}
    }
    else if(nCnt == 2)
    {
        nRoll = d100();
        if(nNPC1 == TRUE && nNPC2 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC1;}
            else{oTarget = oNPC2;}
        }
        else if(nNPC1 == TRUE && nNPC3 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC1;}
            else{oTarget = oNPC3;}
        }
        else if(nNPC2 == TRUE && nNPC3 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC2;}
            else{oTarget = oNPC3;}
        }
    }
    else if(nCnt == 3)
    {
        nRoll = d100();
        if(nRoll <= 33){oTarget = oNPC1;}
        else if(nRoll > 33 && nRoll <= 66) {oTarget = oNPC2;}
        else if(nRoll > 66 && nRoll <= 100) {oTarget = oNPC3;}
    }
    //MODIFIED by Preston Watamaniuk on May 18, 2003
    //Changed the racial type to Human from Droid.
    if(!GetIsEnemy(oTarget, OBJECT_SELF) && nDrainTarget == TRUE)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Searching for Alternate Target");
        oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_RACIAL_TYPE, RACIAL_TYPE_HUMAN);
        GN_MyPrintString("GENERIC DEBUG *************** Alternate Target = " + GN_ReturnDebugName(oTarget));
    }
    GN_MyPrintString("GENERIC DEBUG *************** Heal Drain Target = " + GN_ITS(nDrainTarget));
    GN_MyPrintString("GENERIC DEBUG *************** Get Active Party Member: " + GN_ReturnDebugName(oTarget));
    return oTarget;
}
//::///////////////////////////////////////////////
//:: Return Active Party Member
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This function returns an active party member.
    They must not be dead.  The debilitated
    parameter will ignore those party members
    already debilitated.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2003
//:://////////////////////////////////////////////
object GN_ReturnActivePartyMember(int nDebil = FALSE)
{
    object oNPC1 = GetPartyMemberByIndex(0);
    object oNPC2 = GetPartyMemberByIndex(1);
    object oNPC3 = GetPartyMemberByIndex(2);
    object oTarget;
    int nCnt = 0;
    int nRoll;
    int nNPC1 = FALSE;
    int nNPC2 = FALSE;
    int nNPC3 = FALSE;
    if(GetIsObjectValid(oNPC2) && GetCurrentHitPoints(oNPC2) > 0 && GetObjectSeen(oNPC2))
    {
        if(nDebil == FALSE || !GetIsDebilitated(oNPC2))
        {
            nCnt++;
            nNPC2 = TRUE;
        }
    }
    if(GetIsObjectValid(oNPC3) && GetCurrentHitPoints(oNPC3) > 0 && GetObjectSeen(oNPC3))
    {
        if(nDebil == FALSE || !GetIsDebilitated(oNPC2))
        {
            nCnt++;
            nNPC3 = TRUE;
        }
    }
    if(GetIsObjectValid(oNPC1) && GetCurrentHitPoints(oNPC1) > 0 && GetObjectSeen(oNPC1))
    {
        if(nDebil == FALSE || !GetIsDebilitated(oNPC2))
        {
            nCnt++;
            nNPC1 = TRUE;
        }
    }
    if(nCnt == 0)
    {
        oTarget = OBJECT_INVALID;
    }
    else if(nCnt == 1)
    {
        if(nNPC2 == TRUE){oTarget = oNPC2;}
        else if(nNPC3 == TRUE){oTarget = oNPC3;}
        else if(nNPC1 == TRUE){oTarget = oNPC1;}
    }
    else if(nCnt == 2)
    {
        nRoll = d100();
        if(nNPC1 == TRUE && nNPC2 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC1;}
            else{oTarget = oNPC2;}
        }
        else if(nNPC1 == TRUE && nNPC3 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC1;}
            else{oTarget = oNPC3;}
        }
        else if(nNPC2 == TRUE && nNPC3 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC2;}
            else{oTarget = oNPC3;}
        }
    }
    else if(nCnt == 3)
    {
        nRoll = d100();
        if(nRoll <= 33){oTarget = oNPC1;}
        else if(nRoll > 33 && nRoll <= 66) {oTarget = oNPC2;}
        else if(nRoll > 66 && nRoll <= 100) {oTarget = oNPC3;}
    }
    return oTarget;
}
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Generic Include Debug Commands
//:: Copyright (c) 2001 Bioware Corp.
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void GN_MySpeakString(string sString)
{
    //SpeakString(sString);
}
void GN_AssignPCDebugString(string sString)
{
    object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
    if(GetIsObjectValid(oPC))
    {
        AssignCommand(oPC, SpeakString(sString));
    }
}
void GN_PostString(string sString = "",int x = 10,int y = 10,float fShow = 4.0)
{
    //AurPostString(sString,x,y,fShow);
}
void GN_MyPrintString(string sString)
{
    if(!ShipBuild())
    {
        PrintString(sString);
    }
}
void GN_PostShoutString(string sString = "",int x = 10,int y = 10,float fShow = 4.0)
{
    //AurPostString(sString,x,y,fShow);
}
void GN_MyPrintShoutString(string sString)
{
    if(!ShipBuild())
    {
        //PrintString(sString);
    }
}
void GN_PrintShoutType(object oShouter, int nShout)
{
    /*
    //I WAS ATTACKED
    if(nShout == 1)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " ATTACKED");
    }
    //I WAS KILLED
    else if(nShout == 3)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " KILLED");
    }
    //CALL TO ARMS
    else if(nShout == 6)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " CALL TO ARMS");
    }
    //SUPRESS FORCE
    else if(nShout == 9)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " WANTS FORCE SUPPRESSED");
    }
    //FLEE FROM GRENADES
    else if(nShout == 12)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " GRENADE THROWN");
    }
    //I SEE AN ENEMY
    else if(nShout == 15)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " SEES AN ENEMY");
    }
    */
}
string GN_ReturnDebugName(object oTarget)
{
    string sName = GetName(oTarget) + "_" + ObjectToString(oTarget);
    return sName;
}
string GN_FetchComboString(int nCombo)
{
    if(nCombo == SW_COMBO_RANGED_FEROCIOUS){return "SW_COMBO_RANGED_FEROCIOUS";}
    else if(nCombo == SW_COMBO_RANGED_AGGRESSIVE){return "SW_COMBO_RANGED_AGGRESSIVE";}
    else if(nCombo == SW_COMBO_RANGED_DISCIPLINED){return "SW_COMBO_RANGED_DISCIPLINED";}
    else if(nCombo == SW_COMBO_RANGED_CAUTIOUS){return "SW_COMBO_RANGED_CAUTIOUS";}
    else if(nCombo == SW_COMBO_MELEE_FEROCIOUS){return "SW_COMBO_MELEE_FEROCIOUS";}
    else if(nCombo == SW_COMBO_MELEE_AGGRESSIVE){return "SW_COMBO_MELEE_AGGRESSIVE";}
    else if(nCombo == SW_COMBO_MELEE_DISCIPLINED){return "SW_COMBO_MELEE_DISCIPLINED";}
    else if(nCombo == SW_COMBO_MELEE_CAUTIOUS){return "SW_COMBO_MELEE_CAUTIOUS";}
    else if(nCombo == SW_COMBO_BUFF_PARTY){return "SW_COMBO_BUFF_PARTY";}
    else if(nCombo == SW_COMBO_BUFF_DEBILITATE){return "SW_COMBO_BUFF_DEBILITATE";}
    else if(nCombo == SW_COMBO_BUFF_DAMAGE){return "SW_COMBO_BUFF_DAMAGE";}
    else if(nCombo == SW_COMBO_BUFF_DEBILITATE_DESTROY){return "SW_COMBO_BUFF_DEBILITATE_DESTROY";}
    else if(nCombo == SW_COMBO_SUPRESS_DEBILITATE_DESTROY){return "SW_COMBO_SUPRESS_DEBILITATE_DESTROY";}
    else if(nCombo == SW_COMBO_SITH_ATTACK){return "SW_COMBO_SITH_ATTACK";}
    else if(nCombo == SW_COMBO_BUFF_ATTACK){return "SW_COMBO_BUFF_ATTACK";}
    else if(nCombo == SW_COMBO_SITH_CONFOUND){return "SW_COMBO_SITH_CONFOUND";}
    else if(nCombo == SW_COMBO_JEDI_SMITE){return "SW_COMBO_JEDI_SMITE";}
    else if(nCombo == SW_COMBO_SITH_TAUNT){return "SW_COMBO_SITH_TAUNT";}
    else if(nCombo == SW_COMBO_SITH_BLADE){return "SW_COMBO_SITH_BLADE";}
    else if(nCombo == SW_COMBO_SITH_CRUSH){return "SW_COMBO_SITH_CRUSH";}
    else if(nCombo == SW_COMBO_JEDI_CRUSH){return "SW_COMBO_JEDI_CRUSH";}
    else if(nCombo == SW_COMBO_SITH_BRUTALIZE){return "SW_COMBO_SITH_BRUTALIZE";}
    else if(nCombo == SW_COMBO_SITH_DRAIN){return "SW_COMBO_SITH_DRAIN";}
    else if(nCombo == SW_COMBO_SITH_ESCAPE){return "SW_COMBO_SITH_ESCAPE";}
    else if(nCombo == SW_COMBO_JEDI_BLITZ){return "SW_COMBO_JEDI_BLITZ";}
    else if(nCombo == SW_COMBO_SITH_SPIKE){return "SW_COMBO_SITH_SPIKE";}
    else if(nCombo == SW_COMBO_SITH_SCYTHE){return "SW_COMBO_SITH_SCYTHE";}
    else if(nCombo == SW_COMBO_DROID_UTILITIES){return "SW_COMBO_DROID_UTILITIES";}
    return "NO COMBO SELECTED";
}
//::///////////////////////////////////////////////
//:: Return AI Style
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the AI style in a string
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 28, 2003
//:://////////////////////////////////////////////
string GN_ReturnAIStyle(object oTarget = OBJECT_SELF)
{
    if(GetNPCAIStyle(oTarget) == NPC_AISTYLE_AID)
    {
        return "NPC_AISTYLE_AID";
    }
    else if(GetNPCAIStyle(oTarget) == NPC_AISTYLE_GRENADE_THROWER)
    {
        return "NPC_AISTYLE_GRENADE_THROWER";
    }
    else if(GetNPCAIStyle(oTarget) == NPC_AISTYLE_JEDI_SUPPORT)
    {
        return "NPC_AISTYLE_JEDI_SUPPORT";
    }
    else if(GetNPCAIStyle(oTarget) == NPC_AISTYLE_DEFAULT_ATTACK)
    {
        return "NPC_AISTYLE_DEFAULT_ATTACK";
    }
    int nAI = GetNPCAIStyle(oTarget);
    string sAI = IntToString(nAI);
    sAI = "No Valid AI Set, state = " + sAI;
    return sAI;
}
string GN_ITS(int sFutureString)
{
    return IntToString(sFutureString);
}
""",
    "k_inc_kas": b"""//::///////////////////////////////////////////////
//:: Include
//:: k_inc_kas
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This is the include file for Kashyyyk.
*/
//:://////////////////////////////////////////////
//:: Created By: John Winski
//:: Created On: July 29, 2002
//:://////////////////////////////////////////////
#include "k_inc_utility"
#include "k_inc_generic"
int GetGorwookenSpawnGlobal()
{
    return GetGlobalBoolean("kas_SpawnGorwook");
}
void SetGorwookenSpawnGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_SpawnGorwook", bValue);
    }
    return;
}
int GetEliBeenKilledGlobal()
{
    return GetGlobalBoolean("kas_elikilled");
}
void SetEliBeenKilledGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_elikilled", bValue);
    }
    return;
}
int GetJaarakConfessedGlobal()
{
    return GetGlobalBoolean("kas_JaarakConfessed");
}
void SetJaarakConfessedGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_JaarakConfessed", bValue);
    }
    return;
}
int GetKashyyykPazaakStateGlobal()
{
    return GetGlobalNumber("tat_kashpazstate");
}
void SetKashyyykPazaakStateGlobal(int bValue)
{
    SetGlobalNumber("tat_kashpazstate", bValue);
    return;
}
int GetGuardToldGlobal()
{
    return GetGlobalBoolean("kas_GuardTold");
}
void SetGuardToldGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_GuardTold", bValue);
    }
    return;
}
int GetPoacherPlotStateGlobal()
{
return GetGlobalNumber("kas_poacherstate");
}
void SetPoacherPlotStateGlobal(int bValue)
{
SetGlobalNumber("kas_poacherstate", bValue);
return;
}
int GetPlayerToldOfPoachersGlobal()
{
    return GetGlobalBoolean("kas_ToldPoachers");
}
void SetPlayerToldOfPoachersGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_ToldPoachers", bValue);
    }
    return;
}
int GetChuundarTalkGlobal()
{
    return GetGlobalBoolean("kas_TalkChuundar");
}
void SetChuundarTalkGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_TalkChuundar", bValue);
    }
    return;
}
int GetHelpedFreyyrGlobal()
{
    return GetGlobalBoolean("kas_HelpedFreyyr");
}
void SetHelpedFreyyrGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_HelpedFreyyr", bValue);
    }
    return;
}
int GetFreyyrDeadGlobal()
{
    return GetGlobalBoolean("kas_FreyyrDead");
}
void SetFreyyrDeadGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_FreyyrDead", bValue);
    }
    return;
}
int GetChuundarDeadGlobal()
{
    return GetGlobalBoolean("kas_ChuundarDead");
}
void SetChuundarDeadGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_ChuundarDead", bValue);
    }
    return;
}
int GetComputerTalkGlobal()
{
    return GetGlobalBoolean("kas_ComputerTalk");
}
void SetComputerTalkGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_ComputerTalk", bValue);
    }
    return;
}
int GetStarMapRecievedGlobal()
{
    return GetGlobalBoolean("kas_StarMap");
}
void SetStarMapRecievedGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_StarMap", bValue);
    }
    return;
}
int GetJaarakBoltsGlobal()
{
    return GetGlobalBoolean("kas_JaarakBolts");
}
void SetJaarakBoltsGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_JaarakBolts", bValue);
    }
    return;
}
int GetJaarakDeadGlobal()
{
    return GetGlobalBoolean("kas_JaarakDead");
}
void SetJaarakDeadGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_JaarakDead", bValue);
    }
    return;
}
int GetJaarakFreeGlobal()
{
    return GetGlobalBoolean("kas_JaarakFree");
}
void SetJaarakFreeGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_JaarakFree", bValue);
    }
    return;
}
int GetRorworrMissingGlobal()
{
    return GetGlobalBoolean("kas_RorworrMiss");
}
void SetRorworrMissingGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_RorworrMiss", bValue);
    }
    return;
}
int GetDroidTalkGlobal()
{
    return GetGlobalBoolean("kas_DroidTalk");
}
void SetDroidTalkGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_DroidTalk", bValue);
    }
    return;
}
int GetChuundarRewardGlobal()
{
    return GetGlobalBoolean("kas_ChuundReward");
}
void SetChuundarRewardGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_ChuundReward", bValue);
    }
    return;
}
int GetMandalorianPlotGlobal()
{
    return GetGlobalNumber("kas_MandalorPlot");
}
void SetMandalorianPlotGlobal(int bValue)
{
    SetGlobalNumber("kas_MandalorPlot", bValue);
    return;
}
int GetAskedJanosForRewardLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for xxJanos.02 in area kas_m22aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01);
}
void SetAskedJanosForRewardLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for xxJanos.02 in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetJanosPaidLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for Janos in area kas_m22aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01);
}
void SetJanosPaidLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for Janos in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetJanosOfficeLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for Janos in area kas_m22aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02);
}
void SetJanosOfficeLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for Janos in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetPlayerAskedAboutSlavesLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for Janos in area kas_m22aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03);
}
void SetPlayerAskedAboutSlavesLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for Janos in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetPlayerAskedAboutSuppliesLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_04 for Janos in area kas_m22aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_04);
}
void SetPlayerAskedAboutSuppliesLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_04 for Janos in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetJoleeHomeLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for area kas_m24aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01);
}
void SetJoleeHomeLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetJoleeInfoLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for area kas_m24aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_02);
}
void SetJoleeInfoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetPoachersRunoffLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for the area kas_m24aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03);
}
void SetPoachersRunoffLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for the area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetPoachersKilledLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_04 for the area kas_m24aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_04);
}
void SetPoachersKilledLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_04 for the area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetForceFieldLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for area kas_m24aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_05);
}
void SetForceFieldLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetOpenForceFieldLocal()
{
    // This uses SW_PLOT_BOOLEAN_06 for area kas_m24aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_06);
}
void SetOpenForceFieldLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_06 for area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_06, bValue);
    }
    return;
}
int GetForceFieldInfoLocal()
{
    // This uses SW_PLOT_BOOLEAN_07 for area kas_m24aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_07);
}
void SetForceFieldInfoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_07 for area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_07, bValue);
    }
    return;
}
int GetEnteredShadowlandsLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_08 for area kas_m24aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_08);
}
void SetEnteredShadowlandsLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_08 for area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_08, bValue);
    }
    return;
}
int GetJoleeTalkLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_09 for area kas_m24aa.
    return UT_GetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_09);
}
void SetJoleeTalkLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_09 for area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_09, bValue);
    }
    return;
}
int GetUllerBerriesLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the uller.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetUllerBerriesLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the uller.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetFreyyrSpawnGlobal()
{
    // This uses SW_PLOT_BOOLEAN_01 for area kas_m23ad.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01);
}
void SetFreyyrSpawnGlobal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for area kas_m23ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetFreyyrBeatLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Freyyr in area kas_m25aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetFreyyrBeatLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Freyyr in area kas_m25aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetComputerShutdownLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the computer in area kas_m25aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetComputerShutdownLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the computer in area kas_m25aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetRecognizedRevanLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for the computer in area kas_m25aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetRecognizedRevanLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for the computer in area kas_m25aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetComputerAttackLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for the computer in area kas_m25aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetComputerAttackLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for the computer in area kas_m25aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetHealChanceLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Grrrwahrr in area kas_m25aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetHealChanceLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Grrrwahrr in area kas_m25aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetEvilHurtLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Grrrwahrr in area kas_m25aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetEvilHurtLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Grrrwahrr in area kas_m25aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetFreyyrMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Freyyr in area kas_m23ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetFreyyrMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Freyyr in area kas_m23ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetZaalbarMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for area kas_m23ad.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_02);
}
void SetZaalbarMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for area kas_m23ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetAskAboutComputerLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for area kas_m23ad.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_03);
}
void SetAskAboutComputerLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for area kas_m23ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetFreyyrUpsetLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for area kas_m23ad.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_04);
}
void SetFreyyrUpsetLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for area kas_m23ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetFinalBattleLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for area kas_m23ad.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_05);
}
void SetFinalBattleLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for area kas_m23ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetFadeOffLocal()
{
    // This uses SW_PLOT_BOOLEAN_06 for area kas_m23ad.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_06);
}
void SetFadeOffLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_06 for area kas_m23ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_06, bValue);
    }
    return;
}
int GetJaarakTrialLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for area kas_m23ac.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01);
}
void SetJaarakTrialLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for area kas_m23ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetJaarakAngeredOnceLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Woorwill in area kas_m23ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetJaarakAngeredOnceLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the computer in area kas_m23ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetRorworrDescribedOnceLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Woorwill in area kas_m23ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetRorworrDescribedOnceLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for the computer in area kas_m23ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetRorworrGoneSinceLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Woorwill in area kas_m23ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetRorworrGoneSinceLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for the computer in area kas_m23ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetJaarakAccusedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for area kas_m23ab.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01);
}
void SetJaarakAccusedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for area kas_m23ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetPoachersDeadGlobal()
{
    return GetGlobalNumber("kas_PoachersDead");
}
void SetPoachersDeadGlobal(int bValue)
{
    SetGlobalNumber("kas_PoachersDead", bValue);
    return;
}
int GetEmittersOffGlobal()
{
    return GetGlobalNumber("kas_EmittersOff");
}
void SetEmittersOffGlobal(int bValue)
{
    SetGlobalNumber("kas_EmittersOff", bValue);
    return;
}
int GetPoacherJobLocal()
{
    // This was changed from a local to a global because I needed to turn
    // all tach in kas_m24aa and kas_m25aa hostile.
    return GetGlobalBoolean("kas_PoacherJob");
}
void SetPoacherJobLocal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("kas_PoacherJob", bValue);
    }
    return;
}
int GetPoacherThreatenLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the officer in area kas_m24aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetPoacherThreatenLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the officer in area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetPoacherRunLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the officer in area kas_m24aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02);
}
void SetPoacherRunLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the officer in area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetPoacherAlarmLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for each guard in area kas_m24aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01);
}
void SetPoacherAlarmLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for each guard in area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetDesertLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for each guard in area kas_m24aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02);
}
void SetDesertLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for each guard in area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetDroidNorthLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the busted droid in area kas_m24aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetDroidNorthLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the busted droid in area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetGuardThreatenedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the guard at the exit to area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetGuardThreatenedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the guard at the exit to area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetScientistThreatenedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the sceintist in area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetScientistThreatenedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the sceintist in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetDroidSouthLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for the busted droid in area kas_m24aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetDroidSouthLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for the busted droid in area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetWorrroznorRewardLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Worrroznor in area kas_m23ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetWorrroznorRewardLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Worrroznor in area kas_m23ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetKashyyykPazaakPlayedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Pazzak on alien player in the area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetKashyyykPazaakPlayedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Pazzak on alien player in the area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetKashyyykLostLastGameLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Pazzak on alien player in the area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetKashyyykLostLastGameLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Pazzak on alien player in the area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetToldOfKashyyykPazaakLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Pazzak on alien player in the area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetToldOfKashyyykPazaakLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Pazzak on alien player in the area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetAskDehnoLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Captain Dehno in area kas_m22ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetAskDehnoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Captain Dehno in area kas_m22ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetDehnoPaidLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Captain Dehno in area kas_m22ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetDehnoPaidLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Captain Dehno in area kas_m22ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetChorrawlMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Chorrawl in area kas_m22ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetChorrawlMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Chorrawl in area kas_m22ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetDroidShutdownLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the supply droid in area kas_m22ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetDroidShutdownLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the supply droid in area kas_m22ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetEliSaidKoltoLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for the Eli in area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetEliSaidKoltoLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the Eli in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetEliSaidKorribanLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for the Eli in area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetEliSaidKorribanLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for the Eli in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetEliSaidSwoopLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for the Eli in area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetEliSaidSwoopLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_04 for the Eli in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetEliDeadLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the Matton Dasol in area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetEliDeadLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the Matton Dasol in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetMattonShopLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for the Matton Dasol in area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetMattonShopLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for the Matton Dasol in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetWookieeGuardZaalbarLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for the wookiee guard in area kas_m22ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetWookieeGuardZaalbarLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for the wookiee guard in area kas_m22ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetMattonGaveReward()
{
    // This uses SW_PLOT_BOOLEAN_03 for the Matton Dasol in area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetMattonGaveReward(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for the Matton Dasol in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetMattonLeaveShopLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for the Matton Dasol in area kas_m22aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetMattonLeaveShopLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for the Matton Dasol in area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetEmitterShutdown()
{
    // This uses SW_PLOT_BOOLEAN_01 for the emitters in area kas_m24aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetEmitterShutdown(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the emitters in area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetEmitterDamagedLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for the emitters in area kas_m24aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetEmitterDamagedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for the emitters in area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetForceFieldOpenLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_10 for the forcefield in area kas_m24aa.
    return UT_GetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_10);
}
void SetForceFieldOpenLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_10 for the forcefield in area kas_m24aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_10, bValue);
    }
    return;
}
int GetWookieHealedLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area kas_m25aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01);
}
void SetWookieHealedLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area kas_m25aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetAngryTachLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the area kas_m25aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02);
}
void SetAngryTachLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the area kas_m25aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetFreyyrJobLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for the area kas_m25aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03);
}
void SetFreyyrJobLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for the area kas_m25aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetZaalbarTalk1Local(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area kas_m22aa.
    return UT_GetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_01);
}
void SetZaalbarTalk1Local(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetPartyTalk1Local(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the area kas_m22aa.
    return UT_GetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_02);
}
void SetPartyTalk1Local(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetWookieRebelsLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for the area kas_m22aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03);
}
void SetWookieRebelsLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for the area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetWookieCapturedLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_04 for the area kas_m22aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_04);
}
void SetWookieCapturedLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_04 for the area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetKomadSpawnLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_05 for the area kas_m22aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_05);
}
void SetKomadSpawnLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_05 for the area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetRebelFight1Local(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_06 for the area kas_m22aa.
    return UT_GetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_06);
}
void SetRebelFight1Local(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_06 for the area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_06, bValue);
    }
    return;
}
int GetRebelFight2Local(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_07 for the area kas_m22aa.
    return UT_GetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_07);
}
void SetRebelFight2Local(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_07 for the area kas_m22aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_07, bValue);
    }
    return;
}
int GetZaalbarTalk2Local(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area kas_m22ab.
    return UT_GetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_01);
}
void SetZaalbarTalk2Local(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area kas_m22ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetPartyTalk2Local(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the area kas_m22ab.
    return UT_GetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_02);
}
void SetPartyTalk2Local(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the area kas_m22ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetWookieRebels2Local(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for the area kas_m22ab.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03);
}
void SetWookieRebels2Local(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_03 for the area kas_m22ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetChorrawlFightLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_04 for the area kas_m22ab.
    return UT_GetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_04);
}
void SetChorrawlFightLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_04 for the area kas_m22ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}""",
    "k_inc_lev": b"""//::///////////////////////////////////////////////
//:: k_inc_lev
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
  include file for leviathan
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 26, 2002
//:://////////////////////////////////////////////
#include "k_inc_debug"
#include "k_inc_utility"
//mark an object for cleanup by the LEV_CleanupDeadObjects function
void LEV_MarkForCleanup(object obj);
//destroy all objects whose PLOT_10 flag has been set
void LEV_CleanupDeadObjects(object oArea);
//mark object for cleanup and move to nearest exit
void LEV_LeaveArea(object obj = OBJECT_SELF, int bRun = FALSE);
//fill container with treasure from table
void LEV_AddTreasureToContainer(object oContainer,int iTable,int iAmount);
//strip inventory from oTarget and put it in oDest
void LEV_StripCharacter(object oTarget,object oDest);
//::///////////////////////////////////////////////
//:: LEV_MarkForCleanup
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//mark an object for cleanup by the TAR_CleanupDeadObjects function
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 26, 2002
//:://////////////////////////////////////////////
void LEV_MarkForCleanup(object obj)
{
  UT_SetPlotBooleanFlag(obj,SW_PLOT_BOOLEAN_10,TRUE);
}
//::///////////////////////////////////////////////
//:: LEV_CleanupDeadObjects
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//destroy all objects whose PLOT_10 flag has been set
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 15, 2002
//:://////////////////////////////////////////////
void LEV_CleanupDeadObjects(object oArea)
{
  object obj;
  obj = GetFirstObjectInArea(oArea);
  //Db_PostString("START CLEANUP...",5,7,5.0);
  while(GetIsObjectValid(obj))
  {
    //Db_PostString("FOUND OBJ",5,6,5.0);
    if(UT_GetPlotBooleanFlag(obj,SW_PLOT_BOOLEAN_10))
    {
      //Db_PostString("CLEANING UP OBJECT",5,5,5.0);
      DestroyObject(obj);
    }
    obj = GetNextObjectInArea(oArea);
  }
}
//::///////////////////////////////////////////////
//:: LEV_LeaveArea
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//mark object for cleanup and move to nearest exit
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 26, 2002
//:://////////////////////////////////////////////
void LEV_LeaveArea(object obj = OBJECT_SELF, int bRun = FALSE)
{
  object oExit = GetNearestObjectByTag("plev_wpnpcext");
  LEV_MarkForCleanup(obj);
  if(GetIsObjectValid(oExit))
  {
    UT_PlotMoveObject(oExit,bRun);
  }
}
//fill container with treasure from table
void LEV_AddTreasureToContainer(object oContainer,int iTable,int iAmount)
{
  int i;
  if(!GetIsObjectValid(oContainer))
  {
    return;
  }
  for(i = 0;i < iAmount;i++)
  {
    switch(iTable)
    {
    case 0:
      switch(Random(3))
      {
      case 0:
        CreateItemOnObject("G_I_CREDITS001",oContainer,Random(30) + 10);
        break;
      case 1:
        CreateItemOnObject("G_I_DRDREPEQP002",oContainer);
        break;
      case 2:
        CreateItemOnObject("G_I_MEDEQPMNT04",oContainer);
        break;
      default:
        CreateItemOnObject("G_I_MEDEQPMNT02",oContainer);
      }
      break;
    }
  }
}
void LEV_StripCharacter(object oTarget,object oDest)
{
  object oItem;
  if(!GetIsObjectValid(oTarget) || !GetIsObjectValid(oDest))
  {
    return;
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_BELT,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_BODY,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_HANDS,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_HEAD,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_IMPLANT,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_LEFTARM,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_LEFTWEAPON,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTARM,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  oItem = GetFirstItemInInventory(oTarget);
  while(GetIsObjectValid(oItem))
  {
    GiveItem(oItem,oDest);
    oItem = GetFirstItemInInventory(oTarget);
  }
}
""",
    "k_inc_man": b"""//:: Name
/*
     Desc
*/
//:: Created By:
//:: Copyright (c) 2002 Bioware Corp.
#include "k_inc_generic"
#include "k_inc_utility"
int SHIP_TAKEOFF_CUTSCENE = 1;
int SHIP_LANDING_CUTSCENE = 2;
int NONE = 0;
int QUEEDLE = 1;
int CASSANDRA = 2;
int JAX = 3;
int QUEEDLE_CHAMP = 4;
int QUEEDLE_TIME = 3012;
int CASSANDRA_TIME = 2702;
int JAX_TIME = 2548;
int CHAMP_TIME = 2348;
int PLOT_HARVEST_STOPPED = 3;
int PLOT_KOLTO_DESTROYED = 4;
//effect EFFECT_STEAM = EffectDamage(15);
int STEAM_DAMAGE_AMOUNT = 25;
string RACE_DEFAULT = GetStringByStrRef(32289);
string STEAM_PLACEABLE = "man27_visstm0";
string ROLAND_TAG = "man26_repdip";
void PlaceShip(string sTag,location lLoc);
void RemoveShip(string sTag);
void PlaceNPC(string sTag);
// switches current player models to envirosuit models.
void DonSuits();
// switches the envirosuit model back to the regular player models
void RemoveSuits();
// deactivates all turrets on the map with the corresponding tag
// if no tag is given it will default to the tag of the calling object
void DeactivateTurrets(string sTag = "");
//used to make a given condition only fire once
//***note uses SW_PLOT_BOOLEAN_10***
int HasNeverTriggered();
// Sets a global to track who the player is racing
void SetOpponent(int nOpponent);
//Returns thte current race opponent
int GetOpponent();
//Sets a cutom token in racetime format
void SetTokenRaceTime(int nToken, int nRacerTime);
//returns the main plot global for Manaan
int GetManaanMainPlotVariable();
// returns true if poison has been released if the Hrakert rift
int KoltoDestroyed();
// Removes instances and deactives Selkath encounters
void ClearSelkathFromThisLevel();
// Opens the water door based on the tag og the button
void OpenAssociatedDoor();
// Closes the water door based on the tag og the button
void CloseAssociatedDoor();
// returns the state of a water room TRUE == full
int GetRoomFull(string sRoom);
// sets the water room to nValue
void SetRoomFull(string sRoom, int nValue);
// CLoses all water doors
void CloseAllWaterDoors();
//checks if there is water on either side of the door, if not the door opens
void OpenWaterDoor(string sRoom1,string sRoom2 = "");
//switches water filled rooms accross the corridor
void SwitchWaterRooms();
//returns True if the steam vent is active
int GetIsVentActive(object oVent = OBJECT_SELF);
//sets the state of the Vent and playes the appropriate animation
void SetVentActive(int bState,object oVent = OBJECT_SELF);
// Gives the correct readout for the various water displays
void ActivateWaterDisplays(string sRoom,int nValue);
//plays the required looping animation for the injecter display
void PlayInjecterAnimation(int nLevel);
//plays the required looping animation for the container display
void PlayContainerAnimation(int nLevel);
//initates the sitting animations for the sitting placeables
void InitiateSitters();
// returns true if the staramp was found on Manaan
int GetManaanStarMapFound();
//Turns off AI on party members (if any) for curscene purposes
void TurnOffPartyAI();
//Turns on AI on party members (if any)
void TurnOnPartyAI();
//roland is in post plot state uses SW_PLOT_BOOLEAN05
int GetRolandIsPostPlot();
//toggles the post plot state of Roland
void SetRolandIsPostPlot(int nValue);
//returns the plot global for the missing Selkath youth plot
//used primarily by Shealas(manm26ab) and Sasha (man27aa)
int GetMissingSelkathPlotVariable();
//Sets the plot global for the missing Selkath youth plot
//used primarily by Shealas(manm26ab) and Sasha (man27aa)
void SetMissingSelkathPlotVariable(int nValue);
// returns true if Sasha has been killed
int GetIsSashaDead();
// Sets the variable tracking wheather Sasha is alive
void SetIsSashaDead();
////////////////////////////////////////////////////////////////////////////////
void RemoveShip(string sTag)
{
    object oShip = GetObjectByTag(sTag);
    if(GetIsObjectValid(oShip))
    {
        DestroyObject(oShip);
    }
}
void PlaceShip(string sTag,location lLoc)
{
    object oShip = GetObjectByTag(sTag);
    if(GetIsObjectValid(oShip) == FALSE)
    {
        CreateObject(OBJECT_TYPE_PLACEABLE,sTag,lLoc);
    }
}
void PlaceNPC(string sTag)
{
    if(!GetIsObjectValid(GetObjectByTag(sTag)))
    {
        CreateObject(OBJECT_TYPE_CREATURE,sTag,GetLocation(GetObjectByTag("POST_" + sTag)));
    }
}
void DonSuits()
{
    object oPC;
    int nMax = GetPartyMemberCount();
    int nIdx;
    effect eChange = EffectDisguise(DISGUISE_TYPE_ENVIRONMENTSUIT);
    for(nIdx = 0;nIdx < nMax; nIdx++)
    {
        ApplyEffectToObject(DURATION_TYPE_PERMANENT,eChange,GetPartyMemberByIndex(nIdx));
    }
}
void RemoveSuits()
{
    int nDisguize = EFFECT_TYPE_DISGUISE;//replace with effect constant
    object oPC;
    effect eEffect;
    int nMax = GetPartyMemberCount();
    int nIdx;
    for(nIdx = 0;nIdx < nMax; nIdx++)
    {
        oPC = GetPartyMemberByIndex(nIdx);
        eEffect = GetFirstEffect(oPC);
        while(GetIsEffectValid(eEffect))
        {
            if(GetEffectType(eEffect) == nDisguize)
            {
                RemoveEffect(oPC,eEffect);
            }
            eEffect = GetNextEffect(oPC);
        }
    /*  if(GetTag(oPC) == "Bastila")
        {
            ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectDisguise(4),oPC);
        }
        if(GetTag(oPC) == "Carth")
        {
            ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectDisguise(6),oPC);
        }*/
    }
}
void DeactivateTurrets(string sTag = "")
{
    if(sTag == "")
    {
        sTag = GetTag(OBJECT_SELF);
    }
    int nNth = 0;
    object oTurret = GetObjectByTag(sTag,nNth);
    while(GetIsObjectValid(oTurret))
    {
        if(oTurret != OBJECT_SELF &&
           GetObjectType(oTurret) == OBJECT_TYPE_CREATURE)
        {
            ChangeToStandardFaction(oTurret,STANDARD_FACTION_NEUTRAL);
        }
        nNth++;
        oTurret = GetObjectByTag(sTag,nNth);
    }
}
//This global indicates that Hukta threatened player
int GetHuktaThreatenedPlayerGlobal()
{
    return GetGlobalBoolean("man_HuktaThreatened");
}
void SetHuktaThreatenedPlayerGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("man_HuktaThreatened", bValue);
    }
    return;
}
//This global indicates that the player lost his last race
int GetPlayerLostLastRaceGlobal()
{
    return GetGlobalBoolean("man_PlayerLostLast");
}
void SetPlayerLostLastRaceGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("man_PlayerLostLast", bValue);
    }
    return;
}
//This global measures the state of the swoop races on Manaan
int GetManaanRaceStateGlobal()
{
    return GetGlobalNumber("man_ManaanRaceState");
}
void SetManaanRaceStateGlobal(int bValue)
{
    SetGlobalNumber("man_ManaanRaceState", bValue);
    return;
}
//This global measures the state of Queedle during the swoop races on Manaan
int GetQueedleStateGlobal()
{
    return GetGlobalNumber("tat_QueedleState");
}
void SetQueedleStateGlobal(int bValue)
{
    SetGlobalNumber("tat_QueedleState", bValue);
    return;
}
//This global indicates that player gave money to Queedle
int GetQueedleUpgradeGlobal()
{
    return GetGlobalBoolean("man_QueedleUpgrade");
}
void SetQueedleUpgradeGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("man_QueedleUpgrade", bValue);
    }
    return;
}
//This global indicates that player has angered Hukta by winning against him
int GetHuktaMadGlobal()
{
    return GetGlobalBoolean("man_HuktaMad");
}
void SetHuktaMadGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("man_HuktaMad", bValue);
    }
    return;
}
int GetPlayerNotPaidLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Race Coordinator in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetPlayerNotPaidLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Race Coordinator in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetObjectByTag("man26_swpreg"), SW_PLOT_BOOLEAN_01, bValue);
    }
}
int GetPlayerPersuadedOnceLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Race Coordinator in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetPlayerPersuadedOnceLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Race Coordinator in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
}
int GetCasandraMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Casandra in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetCasandraMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Casandra in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
}
int GetToldCasandraNameLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Casandra in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetToldCasandraNameLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Casandra in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
}
int GetToldHuktaNameLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Hukta in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetToldHuktaNameLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Hukta in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
}
int GetQueedleMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Queedle in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetQueedleMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Queedle in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
}
int GetToldQueedleNameLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Queedle in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetToldQueedleNameLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Queedle in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
}
int GetQueedleLeavingLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Queedle in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetQueedleLeavingLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Queedle in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
}
int GetQueedleToldAboutMoneyLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for Queedle in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetQueedleToldAboutMoneyLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for Queedle in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04, bValue);
    }
}
int GetQueedleGaveMoneyBackLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for Queedle in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05);
}
void SetQueedleGaveMoneyBackLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for Queedle in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05, bValue);
    }
}
int GetSwoopStoreInitialLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Yortal in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetSwoopStoreInitialLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Yortal in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
}
int GetSwoopSithMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for swoop sith in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetSwoopSithMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for swoop sith in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
}
int GetSecondSwoopSithMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for second swoop sith in the area man_26ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetSecondSwoopSithMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for second swoop sith in the area man_26ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
}
int HasNeverTriggered()
{
    int bReturn;
    if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_10) == FALSE)
    {
        bReturn = TRUE;
        UT_SetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_10,TRUE);
    }
    return bReturn;
}
void SetOpponent(int nOpponent)
{
    SetGlobalNumber("MAN_SWOOP_OPP",nOpponent);
}
int GetOpponent()
{
    return GetGlobalNumber("MAN_SWOOP_OPP");
}
void SetTokenRaceTime(int nToken, int nRacerTime)
{
    // calculate the time components
    int nMinutes = nRacerTime/6000;
    int nSeconds = (nRacerTime - (nMinutes * 6000)) / 100;
    int nFractions =  nRacerTime - ((nMinutes * 6000) + (nSeconds * 100));
    //building the time string
    string sTime = IntToString(nMinutes) + ":";
    if (nSeconds < 10)
    {
        sTime = sTime + "0";
    }
    sTime = sTime + IntToString(nSeconds) + ":";
    if(nFractions < 10)
    {
        sTime = sTime + "0";
    }
    sTime = sTime + IntToString(nFractions);
    SetCustomToken(nToken,sTime);
}
void DestroyFish(object oArea)
{
    object oFish = GetFirstObjectInArea(oArea,OBJECT_TYPE_PLACEABLE);
    while (GetIsObjectValid(oFish))
    {
        string sTag = GetTag(oFish);
        string sPlaceable = GetStringLeft(sTag,10);
        if (sPlaceable == "FirixaFish")
        {
            DestroyObject(oFish);
        }
        oFish = GetNextObjectInArea(oArea,OBJECT_TYPE_PLACEABLE);
    }
  /*  object oCreature = GetFirstObjectInArea(oArea);
    while (GetIsObjectValid(oCreature))
    {
        if(GetRacialType(oCreature) == RACIAL_TYPE_HUMAN)
        {
            DestroyObject(oCreature);
        }
        oCreature =GetNextObjectInArea(oArea);
    }
    object oEnc = GetFirstObjectInArea(oArea,OBJECT_TYPE_ENCOUNTER);
    while (GetIsObjectValid(oEnc))
    {
        SetEncounterActive(FALSE,oEnc);
        oEnc = GetNextObjectInArea(oArea,OBJECT_TYPE_ENCOUNTER);
    } */
}
int GetManaanMainPlotVariable()
{
    return GetGlobalNumber("MAN_PLANET_PLOT");
}
int KoltoDestroyed()
{
    return GetGlobalNumber("MAN_PLANET_PLOT") == PLOT_KOLTO_DESTROYED;
}
void ClearSelkathFromThisLevel()
{
    string sTag = "man28_inssel";
    int nLength = GetStringLength(sTag);
    object oSelkath = GetFirstObjectInArea(OBJECT_SELF,OBJECT_TYPE_ALL);
    while(GetIsObjectValid(oSelkath))
    {
        if(GetObjectType(oSelkath) == OBJECT_TYPE_CREATURE)
        {
            if(GetStringLeft(GetTag(oSelkath),nLength) == sTag)
            {
                DelayCommand(0.1,DestroyObject(oSelkath,0.0,TRUE));
            }
        }
        if(GetObjectType(oSelkath) == OBJECT_TYPE_ENCOUNTER)
        {
            if(GetEncounterActive(oSelkath))
            {
                SetEncounterActive(FALSE,oSelkath);
            }
        }
        oSelkath = GetNextObjectInArea(OBJECT_SELF,OBJECT_TYPE_ALL);
    }
}
void OpenAssociatedDoor()
{
    string sNum = GetStringRight(GetTag(OBJECT_SELF),1);
    object oDoor = GetObjectByTag("man27_h2o0" + sNum);
    AssignCommand(oDoor,ActionOpenDoor(oDoor));
}
void CloseAssociatedDoor()
{
    string sNum = GetStringRight(GetTag(OBJECT_SELF),1);
    object oDoor = GetObjectByTag("man27_h2o0" + sNum);
    AssignCommand(oDoor,ActionCloseDoor(oDoor));
}
int GetRoomFull(string sRoom)
{
    int bFilled = FALSE;
    if(sRoom != "")
    {
        bFilled = GetGlobalBoolean("MAN_WATER_" + sRoom);
    }
    return bFilled;
}
void SetRoomFull(string sRoom, int nValue)
{
    if (GetRoomFull(sRoom) != nValue)
    {
        SetGlobalBoolean("MAN_WATER_" + sRoom,nValue);
        ActivateWaterDisplays(sRoom,nValue);
    }
}
void CloseAllWaterDoors()
{
    object oDoor = GetFirstObjectInArea(GetArea(OBJECT_SELF),OBJECT_TYPE_DOOR);
    while(GetIsObjectValid(oDoor))
    {
        if(GetStringLeft(GetTag(oDoor),9) == "man27_h2o")
        {
            AssignCommand(oDoor,ActionCloseDoor(oDoor));
        }
        oDoor = GetNextObjectInArea(GetArea(OBJECT_SELF),OBJECT_TYPE_DOOR);
    }
}
void OpenWaterDoor(string sRoom1,string sRoom2 = "")
{
    if(!GetRoomFull(sRoom1) && !GetRoomFull(sRoom2))
    {
        ActionOpenDoor(OBJECT_SELF);
    }
    else
    {
        BarkString(GetPartyMemberByIndex(0),32128);
    }
}
void SwitchWaterRooms()
{
        if (GetRoomFull("A"))
    {
        SetRoomFull("A",FALSE);
        SetRoomFull("B",TRUE);
    }
    else if(GetRoomFull("B"))
    {
        SetRoomFull("A",TRUE);
        SetRoomFull("B",FALSE);
    }
    if (GetRoomFull("C"))
    {
        SetRoomFull("C",FALSE);
        SetRoomFull("D",TRUE);
    }
    else if(GetRoomFull("D"))
    {
        SetRoomFull("C",TRUE);
        SetRoomFull("D",FALSE);
    }
    if (GetRoomFull("E"))
    {
        SetRoomFull("E",FALSE);
        SetRoomFull("F",TRUE);
    }
    else if(GetRoomFull("F"))
    {
        SetRoomFull("E",TRUE);
        SetRoomFull("F",FALSE);
    }
}
int GetIsVentActive(object oVent = OBJECT_SELF)
{
    return UT_GetPlotBooleanFlag(oVent,SW_PLOT_BOOLEAN_04);
}
void SetVentActive(int bState,object oVent = OBJECT_SELF)
{
    int nNth = 0;
    object oSteam = GetObjectByTag(STEAM_PLACEABLE + GetStringRight(GetTag(oVent),1),nNth );
    while(GetIsObjectValid(oSteam))
    {
        if(bState)
        {
            //AurPostString(GetTag(oVent) + " on",5,5 + StringToInt(GetStringRight(GetTag(oVent),1)),5.0f);
            AssignCommand(oSteam,PlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
        }
        else
        {
            AssignCommand(oSteam,PlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
        }
        nNth++;
        oSteam = GetObjectByTag(STEAM_PLACEABLE + GetStringRight(GetTag(oVent),1),nNth );
    }
    UT_SetPlotBooleanFlag(oVent,SW_PLOT_BOOLEAN_04,bState);
}
void ActivateWaterDisplays(string sRoom,int nValue)
{
    int nNth = 0;
    object oDisplay = GetObjectByTag("man27_waterlvl" + sRoom,nNth);
    while (GetIsObjectValid(oDisplay))
    {
        if(nValue)
        {
            AssignCommand(oDisplay,ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
        }
        else
        {
            AssignCommand(oDisplay,ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
        }
        nNth++;
        oDisplay = GetObjectByTag("man27_waterlvl" + sRoom,nNth);
    }
}
void PlayInjecterAnimation(int nLevel)
{
    int nAnim;
    object oInjector = GetObjectByTag("man28_inject");
    if(nLevel == 0)
    {
        nAnim = ANIMATION_PLACEABLE_ANIMLOOP04;
    }
    else if(nLevel == 1)
    {
        nAnim = ANIMATION_PLACEABLE_ANIMLOOP03;
    }
    else if(nLevel == 2)
    {
        nAnim = ANIMATION_PLACEABLE_ANIMLOOP02;
    }
    else if(nLevel >= 3)
    {
        nAnim = ANIMATION_PLACEABLE_ANIMLOOP01;
    }
    AssignCommand(oInjector, ActionPlayAnimation(nAnim));
}
void PlayContainerAnimation(int nLevel)
{
    int nAnim;
    object oInjector = GetObjectByTag("man28_contain");
    if(nLevel == 0)
    {
       //AurPostString("level 0",5,5,5.0);
        nAnim = ANIMATION_PLACEABLE_ANIMLOOP06;
    }
    else if(nLevel == 1)
    {
        nAnim = ANIMATION_PLACEABLE_ANIMLOOP05;
    }
    else if(nLevel == 2)
    {
        nAnim = ANIMATION_PLACEABLE_ANIMLOOP04;
    }
    else if(nLevel == 3)
    {
        nAnim = ANIMATION_PLACEABLE_ANIMLOOP03;
    }
    else if(nLevel == 4)
    {
        nAnim = ANIMATION_PLACEABLE_ANIMLOOP02;
    }
    else if(nLevel >= 3)
    {
        nAnim = ANIMATION_PLACEABLE_ANIMLOOP01;
    }
    AssignCommand(oInjector, ActionPlayAnimation(nAnim));
}
void InitiateSitters()
{
    int nNth = 0;
    object oPlaceable = GetObjectByTag("man_drinking",nNth);
    while (GetIsObjectValid(oPlaceable))
    {
        AssignCommand(oPlaceable,ActionPlayAnimation(ANIMATION_PLACEABLE_ANIMLOOP02));
        nNth++;
        oPlaceable = GetObjectByTag("man_drinking",nNth);
    }
    nNth = 0;
    oPlaceable = GetObjectByTag("man_cards",nNth);
    while (GetIsObjectValid(oPlaceable))
    {
        AssignCommand(oPlaceable,ActionPlayAnimation(ANIMATION_PLACEABLE_ANIMLOOP03));
        nNth++;
        oPlaceable = GetObjectByTag("man_cards",nNth);
    }
    nNth = 0;
    oPlaceable = GetObjectByTag("man_sitting",nNth);
    while (GetIsObjectValid(oPlaceable))
    {
        AssignCommand(oPlaceable,ActionPlayAnimation(ANIMATION_PLACEABLE_ANIMLOOP01));
        nNth++;
        oPlaceable = GetObjectByTag("man_sitting",nNth);
    }
}
int GetManaanStarMapFound()
{
    return GetGlobalBoolean("MAN_STARMAP_FOUND");
}
void TurnOffPartyAI()
{
    int nIdx;
    object oNPC;
    for(nIdx = 0; nIdx <= 2; nIdx++)
    {
       oNPC = GetPartyMemberByIndex(nIdx);
       if(GetIsObjectValid(oNPC) &&
          GetFirstPC() != oNPC)
       {
            ExecuteScript("k_pman_aioff",oNPC);
       }
    }
}
void TurnOnPartyAI()
{
    int nIdx;
    object oNPC;
    for(nIdx = 0; nIdx <= 2; nIdx++)
    {
       oNPC = GetPartyMemberByIndex(nIdx);
       if(GetIsObjectValid(oNPC) &&
          GetFirstPC() != oNPC)
       {
            ExecuteScript("k_pman_aion",oNPC);
       }
    }
}
int GetRolandIsPostPlot()
{
    object oRoland = GetObjectByTag(ROLAND_TAG);
    int nReturn;
    if(GetIsObjectValid(oRoland))
    {
        nReturn = UT_GetPlotBooleanFlag(oRoland,SW_PLOT_BOOLEAN_05);
    }
    else
    {
        nReturn = FALSE;
    }
    return nReturn;
}
void SetRolandIsPostPlot(int nValue)
{
    object oRoland = GetObjectByTag(ROLAND_TAG);
    if(GetIsObjectValid(oRoland))
    {
        UT_SetPlotBooleanFlag(oRoland,SW_PLOT_BOOLEAN_05,nValue);
    }
}
int GetMissingSelkathPlotVariable()
{
    return GetGlobalNumber("MAN_MISSING_PLOT");
}
void SetMissingSelkathPlotVariable(int nValue)
{
    SetGlobalNumber("MAN_MISSING_PLOT",nValue);
}
int GetIsSashaDead()
{
    return GetGlobalBoolean("MAN_KILLS_DONE");
}
void SetIsSashaDead()
{
    SetGlobalBoolean("MAN_KILLS_DONE",TRUE);
}
""",
    "k_inc_stunt": b"""//:: Stunt/Render Include
/*
     This Include File runs
     the stunt and cutscenes
     for the game.
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
//INDIVIDUAL STUNT MODULE CALLS ******************************************************************************************************
//LEV_A: Pulled out of hyperspace by the Leviathan, load STUNT_16
void ST_PlayLevCaptureStunt();
//LEV_A: Capture by the Leviathan, load ebo_m40aa
void ST_PlayLevCaptureStunt02();
//Load Turret Module Opening 07_3
void ST_PlayStuntTurret_07_3();
//Plays the Bastila torture scene
void ST_PlayBastilaTorture();
//Load Turret Module Opening 07_4
void ST_PlayStuntTurret_07_4();
//Load Leviathan Bombardment Stunt_06 covered by Render 5
void ST_PlayTarisEscape();
//Load Stunt_07 covered by Render 6a and 05_1C
void ST_PlayTarisEscape02();
//Load the Fighter Mini-Game m12ab covered by Render 07_3
void ST_PlayTarisEscape03();
//Load Dantooine module covered by hyperspace and dant landing
void ST_PlayDantooineLanding();
//Leaving Dantooine for the first time, going to STUNT_12 covered by Dant takeoff and hyperspace
void ST_PlayDantooineTakeOff();
//Plays the correct vision based on the value of K_FUTURE_PLANET from a stunt module
void ST_PlayVisionStunt();
//Plays the correct vision based on the value of K_FUTURE_PLANET with a take-off
void ST_PlayVisionStunt02();
//Plays the starforge approach
void ST_PlayStarForgeApproach();
//Plays the Damage Ebon Hawk Stunt scene
void ST_PlayStunt35();
//Shows the crash landing on the Unknown World
void ST_PlayUnknownWorldLanding();
//Shows the take-off from the Unknown World
void ST_PlayUnknownWorldTakeOff();
//Landing on the Star Forge
void ST_PlayStarForgeLanding();
//Goes to the Leviathan Mini-Game covered by the Escape Render
void ST_PlayLeviathanEscape01();
//UBER FUNCTIONS *********************************************************************************************************************
//This determines what to play after a Fighter Mini Game is run
void ST_PlayPostTurret();
//Play the appropriate take off render
string ST_GetTakeOffRender();
//Play the appropriate landing render
string ST_GetLandingRender();
//Plays the appropriate landing sequence for the chosen planet unless Lev or Star Forge
void ST_PlayGenericLanding();
//This determines what planet the PC is taking off of and plays the STUNT_14 in the appropriate manner
void ST_PlayStunt14();
//Checks if the planet designated as K_FUTURE_PLANET has had a vision played for it
int ST_VisionPlayed();
//With no cutscene between planets the game can go to a vision or straight to another planet.
void ST_PlayPlanetToPlanet();
//Play the transition from a vision to a particular planet.  This is only called at the end of a Vision STUNT_00
void ST_PlayVisionLanding();
//Fetches the correct Starmap Vision Render
string ST_GetStarmapVisionRender();
//This gets the current planet that the character is on and determines what skybox to set for the Ebon Hawk.
void ST_SetEbonHawkSkyBox();
// Fetches the correct Starmap Vision Render for the planet the player is currently on
string ST_GetCurrentStarmapVisionRender();
// Allows the Ebon Hawk to continue to the selected planet after the Leviathan unless that planet is Dantooine.
void ST_PlayPostEbo_m40ad();
void ST_MyPrintString(string sString);
void ST_MyPostString(string sString);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////// SINGLE STUNT/RENDER CALLS /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Load Leviathan Bombardment Stunt_06 covered by Render 5
void ST_PlayTarisEscape()
{
    StartNewModule("STUNT_06", "", "05");
}
//Load Stunt_07 covered by Render 6a and 05_1C
void ST_PlayTarisEscape02()
{
    StartNewModule("STUNT_07", "", "06a", "05_1C");
}
//Load the Fighter Mini-Game m12ab covered by Render 07_3
void ST_PlayTarisEscape03()
{
    SetGlobalNumber("K_TURRET_SKYBOX", 5);
    StartNewModule("m12ab", "", "11a");
}
//Load Dantooine danm13 module covered by hyperspace and dant landing
void ST_PlayDantooineLanding()
{
    SetGlobalNumber("K_CURRENT_PLANET", 15);
    StartNewModule("danm13","","05_2A");
}
//LEV_A: Pulled out of hyperspace by the Leviathan, load STUNT_16
void ST_PlayLevCaptureStunt()
{
    string sRender = ST_GetTakeOffRender();
    SetGlobalNumber("K_CURRENT_PLANET", 40);
    StartNewModule("STUNT_16", "",  sRender, "08");
}
//LEV_A: Capture by the Leviathan, load ebo_m40aa
void ST_PlayLevCaptureStunt02()
{
    StartNewModule("ebo_m40aa","", "17");
}
//Plays the Bastila torture scene
void ST_PlayBastilaTorture()
{
    StartNewModule("STUNT_18", "", ST_GetTakeOffRender(), "08");
}
//Load Turret Module Opening 07_3
void ST_PlayStuntTurret_07_3()
{
    StartNewModule("m12ab","",  "11a");
}
//Load Turret Module Opening 07_4
void ST_PlayStuntTurret_07_4()
{
    StartNewModule("m12ab","",  "11a");
}
//Leaving Dantooine for the first time
void ST_PlayDantooineTakeOff()
{
    StartNewModule("STUNT_12","", "05_2C", "08");
}
//Plays the correct vision based on the value of K_FUTURE_PLANET
void ST_PlayVisionStunt()
{
    StartNewModule("STUNT_00","", "07_1");
}
//Plays the correct vision based on the value of K_FUTURE_PLANET with a take-off
void ST_PlayVisionStunt02()
{
    StartNewModule("STUNT_00","", ST_GetTakeOffRender(), "08");
}
//Plays the starforge approach
void ST_PlayStarForgeApproach()
{
    StartNewModule("STUNT_34", "", "33");
}
//Plays the Damage Ebon Hawk Stunt scene
void ST_PlayStunt35()
{
    StartNewModule("STUNT_35", "", "07_2");
}
//Shows the crash landing on the Unknown World
void ST_PlayUnknownWorldLanding()
{
    SetGlobalNumber("K_CURRENT_PLANET", 45);
    StartNewModule("ebo_m41aa","", "05_8A");
}
//Shows the take-off from the Unknown World
void ST_PlayUnknownWorldTakeOff()
{
    /*
        STUNT_44    05_8C   5_9 = DARK SIDE   1
        STUNT_42    05_8C   5_9 = LIGHT SIDE  2
    */
    int nChoice = GetGlobalNumber("G_FINALCHOICE");
    if(nChoice == 1)
    {
        StartNewModule("STUNT_44", "", "05_8C", "5_9");
    }
    else if(nChoice == 2)
    {
        StartNewModule("STUNT_42", "", "05_8C", "5_9");
    }
    if(nChoice == 1 || nChoice == 2)
    {
        SetGlobalNumber("K_KOTOR_MASTER", 60);
    }
}
//Landing on the Star Forge
void ST_PlayStarForgeLanding()
{
    StartNewModule("ebo_m12aa", "", "43");
    SetGlobalNumber("K_CURRENT_PLANET", 50);
}
//Goes to the Leviathan Mini-Game covered by the Escape Render
void ST_PlayLeviathanEscape01()
{
    SetGlobalNumber("K_TURRET_SKYBOX", 10);
    StartNewModule("m12ab", "", "17a", "11a");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////// GENERIC RENDER HANDLER ////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//::///////////////////////////////////////////////
//:: Play Post Turret Sequence
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
   This determines what to play after a Fighter
   Mini Game is run
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 14, 2002
//:://////////////////////////////////////////////
void ST_PlayPostTurret()
{
    ST_MyPrintString(" Start: ST_PlayPostTurret()");
    SetGlobalNumber("K_TURRET_SKYBOX", -1);
    int nStarMap = GetGlobalNumber("K_STAR_MAP");
    int nKOTOR = GetGlobalNumber("K_KOTOR_MASTER");
    int nSimu = GetGlobalBoolean("K_HK47_SIMULATION");
    int nRandom = GetGlobalBoolean("K_RANDOM_MINI_GAME");
    ST_MyPostString("Firing Play Post Turret " + IntToString(nSimu));
    if(nSimu == TRUE)
    {
        SetGlobalBoolean("K_HK47_SIMULATION", FALSE);
        StartNewModule("ebo_m12aa", "K_MINI_GAME");
    }
    else if(nRandom == TRUE)
    {
        SetGlobalBoolean("K_RANDOM_MINI_GAME", FALSE);
        StartNewModule("ebo_m12aa", "", "11b", ST_GetLandingRender());
        SetGlobalNumber("K_CURRENT_PLANET", GetGlobalNumber("K_FUTURE_PLANET"));
    }
    else if(nStarMap == 0 && nKOTOR == 10) //Blasting Off Taris for Dantooine
    {
        //MODIFIED by Preston Watamaniuk, March 6, 2003
        //Add this variable so I could get the space skybox to show up on the Taris To Dantooine Run
        SetGlobalBoolean("K_SPACE_SKYBOX_ON", TRUE);
        StartNewModule("ebo_m12aa", "K_TARIS_DESTROYED","11b");
    }
    else if(nStarMap == 40 && nKOTOR == 20) //Blasting Off the Leviathan
    {
        StartNewModule("ebo_m40ad", "","11b");
    }
    else if(nStarMap == 50 && nKOTOR == 40) //Landing on the Unknown World
    {
        ST_PlayStunt35();
    }
}
//::///////////////////////////////////////////////
//:: Play STUNT_14 Cutscene
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This determines what planet the PC is taking
    off of and plays the STUNT_14 in the
    appropriate manner
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 14, 2002
//:://////////////////////////////////////////////
void ST_PlayStunt14()
{
    ST_MyPrintString(" Start: ST_PlayStunt14()");
    StartNewModule("STUNT_14","",  ST_GetTakeOffRender());
}
//::///////////////////////////////////////////////
//:: Play Landing Sequence
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Plays the appropriate landing sequence for the
    chosen planet unless Lev or Star Forge
    Sets K_CURRENT_PLANET as well.   Note that
    this is played after a stunt module between
    planets.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 14, 2002
//:://////////////////////////////////////////////
void ST_PlayGenericLanding()
{
    ST_MyPrintString(" Start: ST_PlayGenericLanding()");
    if(ST_VisionPlayed() == TRUE)
    {
        StartNewModule("ebo_m12aa","",  ST_GetLandingRender());
        SetGlobalNumber("K_CURRENT_PLANET", GetGlobalNumber("K_FUTURE_PLANET"));
    }
    else
    {
        ST_PlayVisionStunt();
    }
}
//::///////////////////////////////////////////////
//:: Play Planet to Planet
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    With no cutscene between planets the game can
    go to a vision or straight to another planet.
    If interrupted by a vision then this will be
    finished by a call in ST_PlayVisionLanding
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 14, 2002
//:://////////////////////////////////////////////
void ST_PlayPlanetToPlanet()
{
    ST_MyPrintString(" Start: ST_PlayPlanetToPlanet()");
    int nRoll = d100();
    if(ST_VisionPlayed() == TRUE)
    {
        //MODIFIED by Preston Watamaniuk, March 6, 2003
        //I have put a 50% chance of being ambushed by Sith Fighters when doing a straight planet to planet transition.
        if(nRoll > 50)
        {
            ST_MyPrintString(" Start: Random Mini-Game Attack");
            //Set this so that the function ST_PlayPostTurret will know what to do.
            SetGlobalBoolean("K_RANDOM_MINI_GAME", TRUE);
            StartNewModule("m12ab", "", ST_GetTakeOffRender(), "11a");
        }
        else
        {
            StartNewModule("ebo_m12aa","",  ST_GetTakeOffRender(), "08", ST_GetLandingRender());
            SetGlobalNumber("K_CURRENT_PLANET", GetGlobalNumber("K_FUTURE_PLANET"));
        }
    }
    else
    {
        ST_PlayVisionStunt02();
    }
}
//::///////////////////////////////////////////////
//:: Play Vision Stunt and Landing
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    If the landing is broken by a STUNT_00 then
    the landing will be finished with this function.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 14, 2002
//:://////////////////////////////////////////////
void ST_PlayVisionLanding()
{
    ST_MyPrintString(" Start: ST_PlayVisionLanding()");
    int nFUTURE = GetGlobalNumber("K_FUTURE_PLANET");
    if(nFUTURE == 20 ||
       nFUTURE == 25 ||
       nFUTURE == 30 ||
       nFUTURE == 35)
    {
        StartNewModule("ebo_m12aa","", ST_GetStarmapVisionRender(), ST_GetLandingRender());
        SetGlobalNumber("K_CURRENT_PLANET", GetGlobalNumber("K_FUTURE_PLANET"));
    }
}
//::///////////////////////////////////////////////
//:: Play Post ebo_m40ad
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Allows the Ebon Hawk to continue to the
    selected planet after the Leviathan unless
    that planet is Dantooine.
    0    Endar Spire     5
    1    Taris           10
    2    Dantooine       15
    3    --Kashyyk       20
    4    --Manaan        25
    5    --Korriban      30
    6    --Tatooine      35
    7    Leviathan       40
    8    Unknown World   45
    9    Star Forge      50
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: March 21, 2003
//:://////////////////////////////////////////////
void ST_PlayPostEbo_m40ad()
{
    ST_MyPrintString(" Start: ST_PlayGenericLanding()");
    int nFPlanet = GetGlobalNumber("K_FUTURE_PLANET");
    if(nFPlanet == 15)
    {
        if(GetGlobalBoolean("K_STAR_MAP_KASHYYYK") == FALSE)
        {
            nFPlanet = 20;
        }
        else if(GetGlobalBoolean("K_STAR_MAP_MANAAN") == FALSE)
        {
            nFPlanet = 25;
        }
        else if(GetGlobalBoolean("K_STAR_MAP_KORRIBAN") == FALSE)
        {
            nFPlanet = 30;
        }
        else if(GetGlobalBoolean("K_STAR_MAP_TATOOINE") == FALSE)
        {
            nFPlanet = 35;
        }
    }
    SetGlobalNumber("K_FUTURE_PLANET", nFPlanet);
    if(ST_VisionPlayed() == TRUE)
    {
        StartNewModule("ebo_m12aa","",  ST_GetLandingRender());
        SetGlobalNumber("K_CURRENT_PLANET", nFPlanet);
    }
    else
    {
        ST_PlayVisionStunt();
    }
}
//::///////////////////////////////////////////////
//:: Get Take-Off Render
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the appropriate take off render based
    on the K_CURRENT_PLANET variable
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 14, 2002
//:://////////////////////////////////////////////
string ST_GetTakeOffRender()
{
    int nCURRENT = GetGlobalNumber("K_CURRENT_PLANET");
    if(nCURRENT == 15)
    {
        return "05_2c";
    }
    else if(nCURRENT == 20)
    {
        return "05_4c";
    }
    else if(nCURRENT == 25)
    {
        return "05_5c";
    }
    else if(nCURRENT == 30)
    {
        return "05_7C";
    }
    else if(nCURRENT == 35)
    {
        return "05_3c";
    }
    else if(nCURRENT == 40)
    {
        return  "NULL";
    }
    else if(nCURRENT == 45)
    {
        return "05_8c";
    }
    else if(nCURRENT == 55)
    {
        return "LIVE_1c";
    }
    else if(nCURRENT == 60)
    {
        return "LIVE_2c";
    }
    else if(nCURRENT == 65)
    {
        return "LIVE_3c";
    }
    else if(nCURRENT == 70)
    {
        return "LIVE_4c";
    }
    else if(nCURRENT == 75)
    {
        return "LIVE_5c";
    }
    else if(nCURRENT == 80)
    {
        return "LIVE_6c";
    }
    return "NULL";
}
//::///////////////////////////////////////////////
//:: Get Landing Render
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the appropriate landing render based
    on the K_FUTURE_PLANET variable
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 14, 2002
//:://////////////////////////////////////////////
string ST_GetLandingRender()
{
    int nFUTURE = GetGlobalNumber("K_FUTURE_PLANET");
    if(nFUTURE == 15)
    {
        return "05_2a";
    }
    else if(nFUTURE == 20)
    {
        return "05_4a";
    }
    else if(nFUTURE == 25)
    {
        return "05_5a";
    }
    else if(nFUTURE == 30)
    {
        return "05_7a";
    }
    else if(nFUTURE == 35)
    {
        return "05_3a";
    }
    else if(nFUTURE == 40)
    {
        return  "NULL";
    }
    else if(nFUTURE == 55)
    {
        return "LIVE_1a";
    }
    else if(nFUTURE == 60)
    {
        return "LIVE_2a";
    }
    else if(nFUTURE == 65)
    {
        return "LIVE_3a";
    }
    else if(nFUTURE == 70)
    {
        return "LIVE_4a";
    }
    else if(nFUTURE == 75)
    {
        return "LIVE_5a";
    }
    else if(nFUTURE == 80)
    {
        return "LIVE_6a";
    }
    return  "NULL";
}
//::///////////////////////////////////////////////
//:: Has Vision Played
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks if the planet designated as
    K_FUTURE_PLANET has had a vision played for it
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watmanaiuk
//:: Created On: Dec 14, 2002
//:://////////////////////////////////////////////
int ST_VisionPlayed()
{
    int nVision = GetGlobalNumber("Ebon_Vision");
    int nFUTURE = GetGlobalNumber("K_FUTURE_PLANET");
    ST_MyPrintString(" Start: ST_VisionPlayed()");
    ST_MyPrintString(" nFuture = " + IntToString(nFUTURE));
    ST_MyPrintString("k_vis_kashyyyk2  = " + IntToString(GetGlobalBoolean("k_vis_kashyyyk2")));
    ST_MyPrintString("k_vis_manaan2  = " + IntToString(GetGlobalBoolean("k_vis_manaan2")));
    ST_MyPrintString("k_vis_korriban2  = " + IntToString(GetGlobalBoolean("k_vis_korriban2")));
    ST_MyPrintString("k_vis_tatooine2  = " + IntToString(GetGlobalBoolean("k_vis_tatooine2")));
    if(nFUTURE == 20 && GetGlobalBoolean("k_vis_kashyyyk2") == FALSE)
    {
        SetGlobalBoolean("k_vis_kashyyyk2", TRUE);
        return FALSE;
    }
    else if(nFUTURE == 25 && GetGlobalBoolean("k_vis_manaan2") == FALSE)
    {
        SetGlobalBoolean("k_vis_manaan2", TRUE);
        return FALSE;
    }
    else if(nFUTURE == 30 && GetGlobalBoolean("k_vis_korriban2") == FALSE)
    {
        SetGlobalBoolean("k_vis_korriban2", TRUE);
        return FALSE;
    }
    else if(nFUTURE == 35 && GetGlobalBoolean("k_vis_tatooine2") == FALSE)
    {
        SetGlobalBoolean("k_vis_tatooine2", TRUE);
        return FALSE;
    }
    ST_MyPrintString("Returning True");
    return TRUE;
}
//::///////////////////////////////////////////////
//:: Fetch Starmap Render
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Fetches the correct Starmap Vision Render
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 14, 2002
//:://////////////////////////////////////////////
string ST_GetStarmapVisionRender()
{
    int nFUTURE = GetGlobalNumber("K_FUTURE_PLANET");
    if(nFUTURE == 20)
    {
        return "0C";
    }
    else if(nFUTURE == 25)
    {
        return "0B";
    }
    else if(nFUTURE == 30)
    {
        return "0D";
    }
    else if(nFUTURE == 35)
    {
        return "0A";
    }
    return "NULL";
}
//::///////////////////////////////////////////////
//:: Set Ebon Hawk Skybox
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This gets the current planet that the character
    is on and determines what skybox to set for
    the Ebon Hawk.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: March 6, 2003
//:://////////////////////////////////////////////
void ST_SetEbonHawkSkyBox()
{
    int nFUTURE = GetGlobalNumber("K_CURRENT_PLANET");
    if(GetGlobalBoolean("K_SPACE_SKYBOX_ON") == TRUE)
    {
        ST_MyPrintString("Firing Anim 09 for Space");
        ST_MyPrintString("New Print Line Confirmation");
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP09);
        SetGlobalBoolean("K_SPACE_SKYBOX_ON", FALSE);
    }
    else if(nFUTURE == 15)
    {
        ST_MyPrintString("Firing Anim 02 for Dantooine");
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP02);
    }
    else if(nFUTURE == 20)
    {
        ST_MyPrintString("Firing Anim 01 for Kashyyyk");
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP01);
    }
    else if(nFUTURE == 25)
    {
        ST_MyPrintString("Firing Anim 06 for Manaan");
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP06);
    }
    else if(nFUTURE == 30)
    {
        ST_MyPrintString("Firing Anim 05 for Korriban");
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP05);
    }
    else if(nFUTURE == 35)
    {
        ST_MyPrintString("Firing Anim 04 for Tatooine");
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP04);
    }
    else if(nFUTURE == 40)
    {
        ST_MyPrintString("Firing Anim 08 for Leviathan");
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP08);
    }
    else if(nFUTURE == 45)
    {
        ST_MyPrintString("Firing Anim 07 for Unknown World");
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP07);
    }
    else if(nFUTURE == 50)
    {
        ST_MyPrintString("Firing Anim 03 for Star Forge");
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP03);
    }
    //MODIFIED by Preston Watamaniuk on May 10, 2003
    //Skybox added for live planets.
    else if(nFUTURE > 50)
    {
        ST_MyPrintString("Firing Anim 10 for all live content planets");
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP10);
    }
    else
    {
        PlayRoomAnimation("m12aa_01q", ANIMATION_ROOM_SCRIPTLOOP09);
    }
}
void ST_MyPrintString(string sString)
{
    PrintString("RENDER/STUNT Debug ****************** " + sString);
}
void ST_MyPostString(string sString)
{
    AurPostString("RENDER/STUNT Debug ****************** " + sString, 10, 10, 4.0);
}
//::///////////////////////////////////////////////
//:: Fetch Starmap Render
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Fetches the correct Starmap Vision Render
    for the planet the player is currently on
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: March 13, 2003
//:://////////////////////////////////////////////
string ST_GetCurrentStarmapVisionRender()
{
    int nFUTURE = GetGlobalNumber("K_CURRENT_PLANET");
    if(nFUTURE == 20)
    {
        return "0C";
    }
    else if(nFUTURE == 25)
    {
        return "0B";
    }
    else if(nFUTURE == 30)
    {
        return "0D";
    }
    else if(nFUTURE == 35)
    {
        return "0A";
    }
    return "NULL";
}
""",
    "k_inc_switch": b"""//:: k_inc_switch
/*
     A simple include defining all of the
     events in the game as constants.
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
//DEFAULT AI EVENTS
int KOTOR_DEFAULT_EVENT_ON_HEARTBEAT           = 1001;
int KOTOR_DEFAULT_EVENT_ON_PERCEPTION          = 1002;
int KOTOR_DEFAULT_EVENT_ON_COMBAT_ROUND_END    = 1003;
int KOTOR_DEFAULT_EVENT_ON_DIALOGUE            = 1004;
int KOTOR_DEFAULT_EVENT_ON_ATTACKED            = 1005;
int KOTOR_DEFAULT_EVENT_ON_DAMAGE              = 1006;
int KOTOR_DEFAULT_EVENT_ON_DEATH               = 1007;
int KOTOR_DEFAULT_EVENT_ON_DISTURBED           = 1008;
int KOTOR_DEFAULT_EVENT_ON_BLOCKED             = 1009;
int KOTOR_DEFAULT_EVENT_ON_FORCE_AFFECTED      = 1010;
int KOTOR_DEFAULT_EVENT_ON_GLOBAL_DIALOGUE_END = 1011;
int KOTOR_DEFAULT_EVENT_ON_PATH_BLOCKED        = 1012;
//HENCHMEN AI EVENTS
int KOTOR_HENCH_EVENT_ON_HEARTBEAT           = 2001;
int KOTOR_HENCH_EVENT_ON_PERCEPTION          = 2002;
int KOTOR_HENCH_EVENT_ON_COMBAT_ROUND_END    = 2003;
int KOTOR_HENCH_EVENT_ON_DIALOGUE            = 2004;
int KOTOR_HENCH_EVENT_ON_ATTACKED            = 2005;
int KOTOR_HENCH_EVENT_ON_DAMAGE              = 2006;
int KOTOR_HENCH_EVENT_ON_DEATH               = 2007;
int KOTOR_HENCH_EVENT_ON_DISTURBED           = 2008;
int KOTOR_HENCH_EVENT_ON_BLOCKED             = 2009;
int KOTOR_HENCH_EVENT_ON_FORCE_AFFECTED      = 2010;
int KOTOR_HENCH_EVENT_ON_GLOBAL_DIALOGUE_END = 2011;
int KOTOR_HENCH_EVENT_ON_PATH_BLOCKED        = 2012;
int KOTOR_HENCH_EVENT_ON_ENTER_5m            = 2013;
int KOTOR_HENCH_EVENT_ON_EXIT_5m             = 2014;
//MISC AI EVENTS
int KOTOR_MISC_DETERMINE_COMBAT_ROUND                = 3001;
int KOTOR_MISC_DETERMINE_COMBAT_ROUND_ON_PC          = 3002;
int KOTOR_MISC_DETERMINE_COMBAT_ROUND_ON_INDEX_ZERO  = 3003;
""",
    "k_inc_tar": b"""//::///////////////////////////////////////////////
//:: k_inc_tar
//:: k_inc_tar
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
  include file for taris
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
#include "k_inc_debug"
#include "k_inc_utility"
//performs a standard creature transformation where the original creature
//is destroyed and a new creature is put in its place.  returns a reference
//to the new creature.
object TAR_TransformCreature(object oTarget = OBJECT_INVALID,string sTemplate = "");
//test routine for walking waypoints
void TAR_WalkWaypoints();
//mark an object for cleanup by the TAR_CleanupDeadObjects function
void TAR_MarkForCleanup(object obj = OBJECT_SELF);
//destroy all objects whose PLOT_10 flag has been set
void TAR_CleanupDeadObjects(object oArea);
//make object do an uninterruptible path move
void TAR_PlotMovePath(string sWayPointTag,int nFirst, int nLast, int nRun = FALSE);
//make object do an uninterruptible move to an object
void TAR_PlotMoveObject(object oTarget,int nRun = FALSE);
//make object do an uninterruptible move to a location
void TAR_PlotMoveLocation(location lTarget,int nRun = FALSE);
//check for rukil's apprentice journal
int TAR_PCHasApprenticeJournal();
//return number of promised land journals player has
int TAR_GetNumberPromisedLandJournals();
//toggle the state of sith armor
void TAR_ToggleSithArmor();
//fill container with treasure from table
void TAR_AddTreasureToContainer(object oContainer,int iTable,int iAmount);
//returns TRUE if object is wearing sith armor
int TAR_GetWearingSithArmor(object oTarget = OBJECT_INVALID);
//strip sith armor from party, equipping another appropriate item (if available)
//returns the sith armor object if it was being worn
object TAR_StripSithArmor();
//teleport party member
void TAR_TeleportPartyMember(object oPartyMember, location lDest);
//makes the sith armor equippable
void TAR_EnableSithArmor();
//strip all items from an object
void TAR_StripCharacter(object oTarget,object oDest);
//::///////////////////////////////////////////////
//:: TAR_TransformCreature
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//performs a standard creature transformation where the original creature
//is destroyed and a new creature is put in its place.  returns a reference
//to the new creature.
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
object TAR_TransformCreature(object oTarget = OBJECT_INVALID,string sTemplate = "")
{
  if(GetIsObjectValid(oTarget) && sTemplate != "")
  {
    location lPlace = GetLocation(oTarget);
    DestroyObject(oTarget,0.0,TRUE);
    return(CreateObject(OBJECT_TYPE_CREATURE,sTemplate,lPlace));
  }
  else
  {
    return(OBJECT_INVALID);
  }
}
//::///////////////////////////////////////////////
//:: TAR_WalkWaypoints
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//test routine for walking waypoints
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 29, 2002
//:://////////////////////////////////////////////
void TAR_WalkWaypoints()
{
  object oNextWP = OBJECT_INVALID;
  string sWPPath = "";
  if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_01))
  {
    sWPPath = "ptar_testwp1";
  }
  else if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_02))
  {
    sWPPath = "ptar_testwp2";
  }
  else if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_03))
  {
    sWPPath = "ptar_testwp3";
  }
  else if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_04))
  {
    sWPPath = "ptar_testwp4";
  }
  else if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_05))
  {
    sWPPath = "ptar_testwp5";
  }
  else
  {
    sWPPath = "ptar_testwp6";
  }
  if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_06))
  {
    sWPPath = sWPPath + "_1";
    UT_SetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_06,FALSE);
  }
  else
  {
    sWPPath = sWPPath + "_0";
    UT_SetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_06,TRUE);
  }
  oNextWP = GetObjectByTag(sWPPath);
  Db_PostString("MOVING TO " + GetTag(oNextWP),5,5,2.0);
  //ClearAllActions();
  ActionForceMoveToObject(oNextWP);
  ActionDoCommand(TAR_WalkWaypoints());
}
//::///////////////////////////////////////////////
//:: TAR_MarkForCleanup
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//mark an object for cleanup by the TAR_CleanupDeadObjects function
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 16, 2002
//:://////////////////////////////////////////////
void TAR_MarkForCleanup(object obj = OBJECT_SELF)
{
  UT_SetPlotBooleanFlag(obj,SW_PLOT_BOOLEAN_10,TRUE);
}
//::///////////////////////////////////////////////
//:: TAR_CleanupDeadObjects
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//destroy all objects whose PLOT_10 flag has been set
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 15, 2002
//:://////////////////////////////////////////////
void TAR_CleanupDeadObjects(object oArea)
{
  object obj;
  obj = GetFirstObjectInArea(oArea);
  //Db_PostString("START CLEANUP...",5,7,5.0);
  while(GetIsObjectValid(obj))
  {
    //Db_PostString("FOUND OBJ",5,6,5.0);
    if(UT_GetPlotBooleanFlag(obj,SW_PLOT_BOOLEAN_10))
    {
      //Db_PostString("CLEANING UP OBJECT",5,5,5.0);
      DestroyObject(obj,0.0,TRUE);
    }
    obj = GetNextObjectInArea(oArea);
  }
}
//::///////////////////////////////////////////////
//:: TAR_PlotMovePath
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make object do an uninterruptible path move
//based on code done by Aidan (actually, pretty much a copy)
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 16, 2002
//:://////////////////////////////////////////////
void TAR_PlotMovePath(string sWayPointTag,int nFirst, int nLast, int nRun = FALSE)
{
    int nInc = 1;
    object oWP;
    int nIdx;
    if(nFirst > nLast)
    {
        nInc = -1;
    }
    for(nIdx = nFirst - nInc; abs(nLast - nIdx) > 0 && abs(nLast - nIdx) <= abs((nLast - nFirst) + 1); nIdx = nIdx + nInc)
    {
        oWP = GetObjectByTag(sWayPointTag + IntToString(nIdx + nInc));
        if(GetIsObjectValid(oWP))
        {
            ActionForceMoveToObject(oWP,nRun);
        }
    }
    ActionDoCommand(SetCommandable(TRUE));
    SetCommandable(FALSE);
}
//::///////////////////////////////////////////////
//:: TAR_PlotMoveObject
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make object do an uninterruptible move to an object
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 16, 2002
//:://////////////////////////////////////////////
void TAR_PlotMoveObject(object oTarget,int nRun = FALSE)
{
  ActionForceMoveToObject(oTarget,nRun);
  ActionDoCommand(SetCommandable(TRUE));
  SetCommandable(FALSE);
}
//::///////////////////////////////////////////////
//:: TAR_PlotMoveObject
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make object do an uninterruptible move to a location
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 16, 2002
//:://////////////////////////////////////////////
void TAR_PlotMoveLocation(location lTarget,int nRun = FALSE)
{
  ActionForceMoveToLocation(lTarget,nRun);
  ActionDoCommand(SetCommandable(TRUE));
  SetCommandable(FALSE);
}
//::///////////////////////////////////////////////
//:: TAR_PCHasApprenticeJournal
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//check for rukil's apprentice journal
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 21, 2002
//:://////////////////////////////////////////////
int TAR_PCHasApprenticeJournal()
{
  return(GetIsObjectValid(GetItemPossessedBy(GetFirstPC(),"ptar_appjournal")));
}
//::///////////////////////////////////////////////
//:: TAR_GetNumberPromisedLandJournals
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//return number of promised land journals player has
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 21, 2002
//:://////////////////////////////////////////////
int TAR_GetNumberPromisedLandJournals()
{
  object oInv;
  int iJournals = 0;
  oInv = GetFirstItemInInventory(GetFirstPC());
  while(GetIsObjectValid(oInv))
  {
    if(GetTag(oInv) == "ptar_rukjournal")
    {
      Db_PostString("JOURNALS - " + IntToString(GetNumStackedItems(oInv)),5,5,5.0);
      iJournals += GetNumStackedItems(oInv);
    }
    oInv = GetNextItemInInventory(GetFirstPC());
  }
  return(iJournals);
}
//::///////////////////////////////////////////////
//:: TAR_ToggleSithArmor
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//toggle the state of sith armor
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Oct. 8, 2002
//:://////////////////////////////////////////////
void TAR_ToggleSithArmor()
{
  int i;
  object obj;
  obj = GetItemActivated();
  if(GetTag(obj) != "ptar_sitharmor")
  {
    return;
  }
  i = 1;
  obj = GetNearestCreature(CREATURE_TYPE_RACIAL_TYPE,RACIAL_TYPE_ALL,GetFirstPC(),i);
  while(GetIsObjectValid(obj))
  {
    if(GetDistanceBetween(obj,GetFirstPC()) < 10.0 && !IsObjectPartyMember(obj))
    {
      ActionStartConversation(GetFirstPC(),"ptar_armor_dlg");
      return;
    }
    i++;
    obj = GetNearestCreature(CREATURE_TYPE_RACIAL_TYPE,RACIAL_TYPE_ALL,GetFirstPC(),i);
  }
  ActionStartConversation(GetFirstPC(),"ptar_armon_dlg");
  SetGlobalBoolean("TAR_SITHARMOR",!GetGlobalBoolean("TAR_SITHARMOR"));
}
//fill container with treasure from table
void TAR_AddTreasureToContainer(object oContainer,int iTable,int iAmount)
{
  int i;
  if(!GetIsObjectValid(oContainer))
  {
    return;
  }
  for(i = 0;i < iAmount;i++)
  {
    switch(iTable)
    {
    case 0:
      switch(Random(3))
      {
      case 0:
        CreateItemOnObject("G_I_CREDITS001",oContainer,Random(20) + 1);
        break;
      case 1:
        CreateItemOnObject("G_I_DRDREPEQP001",oContainer);
        break;
      case 2:
        CreateItemOnObject("G_I_MEDEQPMNT04",oContainer);
        break;
      default:
        CreateItemOnObject("G_I_MEDEQPMNT01",oContainer);
      }
      break;
    case 1:
      switch(Random(11))
      {
      case 0:
        CreateItemOnObject("G_W_BLSTRPSTL001",oContainer);
        break;
      case 1:
        CreateItemOnObject("G_I_SECSPIKE01",oContainer);
        break;
      case 2:
        CreateItemOnObject("G_I_PROGSPIKE01",oContainer);
        break;
      case 3:
        CreateItemOnObject("G_A_CLASS5001",oContainer);
        break;
      case 4:
        CreateItemOnObject("G_W_FRAGGREN01",oContainer);
        break;
      case 5:
        CreateItemOnObject("G_W_STUNGREN01",oContainer);
        break;
      case 6:
        CreateItemOnObject("G_W_IONGREN01",oContainer);
        break;
      case 7:
        CreateItemOnObject("G_W_SONICGREN01",oContainer);
        break;
      case 8:
        CreateItemOnObject("G_W_VBROSHORT01",oContainer);
        break;
      case 9:
        CreateItemOnObject("G_W_STUNBATON01",oContainer);
        break;
      default:
        CreateItemOnObject("G_I_CREDITS001",oContainer,Random(40) + 20);
        break;
      }
      break;
    case 2:
      switch(Random(5))
      {
      case 0:
        CreateItemOnObject("G_W_BLSTRPSTL001",oContainer);
        break;
      case 1:
        CreateItemOnObject("G_W_QTRSTAFF01",oContainer);
        break;
      case 2:
        CreateItemOnObject("G_I_MEDEQPMNT01",oContainer);
        break;
      case 3:
        CreateItemOnObject("G_A_CLASS4001",oContainer);
        break;
      default:
        CreateItemOnObject("G_I_CREDITS001",oContainer,Random(20) + 1);
        break;
      }
      break;
    }
  }
}
int TAR_GetWearingSithArmor(object oTarget = OBJECT_INVALID)
{
  int i;
  object obj;
  object oArmorItem = GetItemInSlot(INVENTORY_SLOT_BODY,oTarget);
  if(!GetIsObjectValid(oTarget))
  {
    for(i = 0;i < GetPartyMemberCount();i++)
    {
      obj = GetPartyMemberByIndex(i);
      oArmorItem = GetItemInSlot(INVENTORY_SLOT_BODY,obj);
      if(GetTag(oArmorItem) == "ptar_sitharmor")
      {
        return(TRUE);
      }
    }
    return(FALSE);
  }
  return(GetTag(oArmorItem) == "ptar_sitharmor");
}
//strip sith armor from target, equipping another appropriate item (if available)
object TAR_StripSithArmor()
{
  object oArmor = OBJECT_INVALID;
  object obj;
  object oTarget;
  int i;
  Db_PostString("STRIPPING ARMOR = " + GetTag(oTarget),5,7,5.0);
  for(i = 0;i < GetPartyMemberCount();i++)
  {
    oTarget = GetPartyMemberByIndex(i);
    if(TAR_GetWearingSithArmor(oTarget))
    {
      Db_PostString("ARMOR STRIPPED",5,8,5.0);
      oArmor = GetItemInSlot(INVENTORY_SLOT_BODY,oTarget);
      SetCommandable(TRUE,oTarget);
      AssignCommand(oTarget,ActionUnequipItem(oArmor));
      obj = GetFirstItemInInventory(oTarget);
      while(GetIsObjectValid(obj))
      {
        if(GetBaseItemType(obj) == BASE_ITEM_BASIC_CLOTHING)
        {
          Db_PostString("PUT ON NEW ITEM",5,9,5.0);
          AssignCommand(oTarget,ActionEquipItem(obj,INVENTORY_SLOT_BODY,TRUE));
          break;
        }
        obj = GetNextItemInInventory(oTarget);
      }
    }
    else if(GetIsObjectValid(obj = GetItemPossessedBy(oTarget,"ptar_sitharmor")))
    {
      oArmor = obj;
      Db_PostString("ARMOR FOUND",5,9,5.0);
    }
  }
  return(oArmor);
}
//teleport party member
void TAR_TeleportPartyMember(object oPartyMember, location lDest)
{
  if(!GetIsObjectValid(oPartyMember))
  {
    return;
  }
  SetCommandable(TRUE,oPartyMember);
  AssignCommand(oPartyMember,ClearAllActions());
  AssignCommand(oPartyMember,ActionJumpToLocation(lDest));
}
//makes the sith armor equippable
void TAR_EnableSithArmor()
{
  int i;
  object obj;
  object oArmor;
  for(i = 0;i < GetPartyMemberCount();i++)
  {
    obj = GetPartyMemberByIndex(i);
    if(GetIsObjectValid(oArmor = GetItemPossessedBy(obj,"ptar_sitharmor")))
    {
      SetItemNonEquippable(oArmor,FALSE);
    }
  }
}
void TAR_StripCharacter(object oTarget,object oDest)
{
  object oItem;
  if(!GetIsObjectValid(oTarget) || !GetIsObjectValid(oDest))
  {
    return;
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_BELT,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_BODY,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_HANDS,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_HEAD,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_IMPLANT,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_LEFTARM,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_LEFTWEAPON,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTARM,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  if(GetIsObjectValid(oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON,oTarget)))
  {
    GiveItem(oItem,oDest);
  }
  oItem = GetFirstItemInInventory(oTarget);
  while(GetIsObjectValid(oItem))
  {
    GiveItem(oItem,oDest);
    oItem = GetFirstItemInInventory(oTarget);
  }
}
""",
    "k_inc_tat": b"""//::///////////////////////////////////////////////
//:: Include
//:: k_inc_tat
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This is the include file for Tatooine.
*/
//:://////////////////////////////////////////////
//:: Created By: John Winski
//:: Created On: September 3, 2002
//:://////////////////////////////////////////////
#include "k_inc_utility"
#include "k_inc_generic"
// racer constants
int NONE = 0;
int GARM = 1;
int YUKA = 2;
int ZORIIS = 3;
// race time constants
int GARM_TIME = 2600;
int YUKA_TIME = 2470;
int ZORIIS_TIME = 2350;
string RACE_DEFAULT = GetStringByStrRef(32289);
int GetGammoreansDeadGlobal()
{
    return GetGlobalBoolean("tat_GammoreansDead");
}
void SetGammoreansDeadGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_GammoreansDead", bValue);
    }
    return;
}
int GetMetKomadLodgeGlobal()
{
    return GetGlobalBoolean("tat_MetKomadLodge");
}
void SetMetKomadLodgeGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_MetKomadLodge", bValue);
    }
    return;
}
int GetSharinaAccusedGurkeGlobal()
{
    return GetGlobalBoolean("tat_SharinaAccused");
}
void SetSharinaAccusedGurkeGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_SharinaAccused", bValue);
    }
    return;
}
int GetKraytDeadGlobal()
{
    return GetGlobalBoolean("tat_KraytDead");
}
void SetKraytDeadGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_KraytDead", bValue);
    }
    return;
}
int GetKraytFightGlobal()
{
    return GetGlobalBoolean("tat_KraytFight");
}
void SetKraytFightGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_KraytFight", bValue);
    }
    return;
}
int GetTalkedToConserveGlobal()
{
    return GetGlobalBoolean("tat_talkconserve");
}
void SetTalkedToConserveGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_talkconserve", bValue);
    }
    return;
}
int GetUsedChokeOnCzerkaGlobal()
{
    return GetGlobalBoolean("tat_chokedczerka");
}
void SetUsedChokeOnCzerkaGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_chokedczerka", bValue);
    }
    return;
}
int GetTatooineRacerGlobal()
{
    return GetGlobalBoolean("tat_SwoopRacer");
}
void SetTatooineRacerGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_SwoopRacer", bValue);
    }
    return;
}
int GetLostLastRaceGlobal()
{
    return GetGlobalBoolean("tat_LostLastRace");
}
void SetLostLastRaceGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_LostLastRace", bValue);
    }
    return;
}
int GetTanisDeadGlobal()
{
    return GetGlobalBoolean("tat_TanisDead");
}
void SetTanisDeadGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_TanisDead", bValue);
    }
    return;
}
int GetPlayerDestroyedOneGlobal()
{
    return GetGlobalBoolean("tat_OneDroidDead");
}
void SetPlayerDestroyedOneGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_OneDroidDead", bValue);
    }
    return;
}
int GetTanisGiveUpGlobal()
{
    return GetGlobalBoolean("tat_TanisGiveUp");
}
void SetTanisGiveUpGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_TanisGiveUp", bValue);
    }
    return;
}
int GetAskAboutHuntGlobal()
{
    return GetGlobalBoolean("tat_AskAboutHunt");
}
void SetAskAboutHuntGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_AskAboutHunt", bValue);
    }
    return;
}
int GetGammoreanWarningGlobal()
{
    return GetGlobalBoolean("tat_TrustGammNot");
}
void SetGammoreanWarningGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_TrustGammNot", bValue);
    }
    return;
}
int GetGammoreanGoneGlobal()
{
    return GetGlobalBoolean("tat_GammGone");
}
void SetGammoreanGoneGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_GammGone", bValue);
    }
    return;
}
int GetGammoreanBribeGlobal()
{
    return GetGlobalBoolean("tat_GammBribe");
}
void SetGammoreanBribeGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_GammBribe", bValue);
    }
    return;
}
int GetRaceCompleteGlobal()
{
    return GetGlobalNumber("tat_RaceComplete");
}
void SetRaceCompleteGlobal(int bValue)
{
    SetGlobalNumber("tat_RaceComplete", bValue);
    return;
}
int GetSandHistoryStateGlobal()
{
    return GetGlobalNumber("tat_SandHistory");
}
void SetSandHistoryStateGlobal(int bValue)
{
    SetGlobalNumber("tat_SandHistory", bValue);
    return;
}
int GetToldHowToBeWarriorGlobal()
{
    return GetGlobalNumber("tat_SandWarrior");
}
void SetToldHowToBeWarriorGlobal(int bValue)
{
    SetGlobalNumber("tat_SandWarrior", bValue);
    return;
}
int GetRaceWonNotPaidGlobal()
{
    return GetGlobalBoolean("tat_NotPaid");
}
void SetRaceWonNotPaidGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_NotPaid", bValue);
    }
    return;
}
int GetSharinaPaidFullGlobal()
{
    return GetGlobalBoolean("tat_SharinaPaidFull");
}
void SetSharinaPaidFullGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_SharinaPaidFull", bValue);
    }
    return;
}
int GetTalkTanisGlobal()
{
    return GetGlobalBoolean("tat_TalkTanis");
}
void SetTalkTanisGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_TalkTanis", bValue);
    }
    return;
}
int GetMadTanisGlobal()
{
    return GetGlobalBoolean("tat_MadTanis");
}
void SetMadTanisGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_MadTanis", bValue);
    }
    return;
}
int GetTanisSavedGlobal()
{
    return GetGlobalBoolean("tat_TanisSaved");
}
void SetTanisSavedGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_TanisSaved", bValue);
    }
    return;
}
int GetTuskenJobGlobal()
{
    return GetGlobalBoolean("tat_TuskenJob");
}
void SetTuskenJobGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_TuskenJob", bValue);
    }
    return;
}
int GetJawaCaptiveGlobal()
{
    return GetGlobalNumber("tat_JawaCaptive");
}
void SetJawaCaptiveGlobal(int bValue)
{
    SetGlobalNumber("tat_JawaCaptive", bValue);
    return;
}
int GetIzizCaptiveGlobal()
{
    return GetGlobalNumber("tat_IzizCaptive");
}
void SetIzizCaptiveGlobal(int bValue)
{
    SetGlobalNumber("tat_IzizCaptive", bValue);
    return;
}
int GetIzizGotMadGlobal()
{
    return GetGlobalNumber("tat_IzizGotMad");
}
void SetIzizGotMadGlobal(int bValue)
{
    SetGlobalNumber("tat_IzizGotMad", bValue);
    return;
}
int GetGriffCaptiveGlobal()
{
    return GetGlobalNumber("tat_GriffCaptive");
}
void SetGriffCaptiveGlobal(int bValue)
{
    SetGlobalNumber("tat_GriffCaptive", bValue);
    return;
}
int GetMissionCaptiveGlobal()
{
    return GetGlobalNumber("tat_MissCaptive");
}
void SetMissionCaptiveGlobal(int bValue)
{
    SetGlobalNumber("tat_MissCaptive", bValue);
    return;
}
int GetFazzaPazzakStateGlobal()
{
    return GetGlobalNumber("tat_fazzpazzstate");
}
void SetFazzaPazzakStateGlobal(int bValue)
{
    SetGlobalNumber("tat_fazzpazzstate", bValue);
    return;
}
int GetGriffGreetaGlobal()
{
    return GetGlobalBoolean("tat_GriffGreeta");
}
void SetGriffGreetaGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_GriffGreeta", bValue);
    }
    return;
}
int GetGriffPortGlobal()
{
    return GetGlobalBoolean("tat_GriffPort");
}
void SetGriffPortGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_GriffPort", bValue);
    }
    return;
}
int GetDockingPaidLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the Czerka official in area kas_m17ab.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01);
}
void SetDockingPaidLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the Czerka official in area kas_m17ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetPlayerWarnedAboutQuestionsLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Sand People Storyteller in area tat_20aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetPlayerWarnedAboutQuestionsLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Sand People Storyteller in area tat_20aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetHK47CriticisedOnceLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Sand People Storyteller in area tat_20aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetHK47CriticisedOnceLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Sand People Storyteller in area tat_20aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetDorakNamedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Dorak Quinn in area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetDorakNamedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the Dorak Quinn in area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetGurkePissedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m17ad.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01);
}
void SetGurkePissedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetGurkeNamedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Gurke in area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetGurkeNamedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Gurke in area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetJunixTatooineInfoLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Junix Nard in area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetJunixTatooineInfoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Junix nard in area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetJunixSaidSwoopLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Junix nard in area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetJunixSaidSwoopLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Junix nard in area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetJunixSaidKorribanLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Junix nard in area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetJunixSaidKorribanLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Junix nard in area tat_m17afd.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetJunixSaidKoltoLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for Junix nard in area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetJunixSaidKoltoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for Junix nard in area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetJunixSaidWookieeLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for Junix nard in area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05);
}
void SetJunixSaidWookieeLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for Junix nard in area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetCelisNicoInfoLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m17ae.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01);
}
void SetCelisNicoInfoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m17ae.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetBulliedNicoLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for the area tat_m17ae.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_02);
}
void SetBulliedNicoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for the area tat_m17ae.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetCelisDealLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for the area tat_m17ae.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_03);
}
void SetCelisDealLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for the area tat_m17ae.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetNicoHappyLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Nico in the area tat_m17ae.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetNicoHappyLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Nico in the area kas_m17ae.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetNicoTalkTimesSubstituteLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Nico in the area tat_m17ae.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetNicoTalkTimesSubstituteLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Nico in the area tat_m17ae.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetMottaPaidThePlayerLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Motta in the area tat_m17ae.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetMottaPaidThePlayerLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Motta in the area tat_m17ae.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetGarmNamedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Garm Totryl in the area tat_m17ae.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetGarmNamedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Garm Totryl in the area tat_m17ae.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetYukarNamedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Yuka Rill in the area tat_m17ae.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetYukarNamedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Yuka Rill in the area tat_m17ae.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetYukarMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Yuka Rill in the area tat_m17ae.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetYukarMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Yuka Rill in the area tat_m17ae.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetZoriisNamedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Zoriis Bafka in the area tat_m17ae.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetZoriisNamedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Zoriis Bafka in the area tat_m17ae.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetHK47InfoLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Yuka Laka in the area tat_m17ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetHK47InfoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Yuka Laka in the area tat_m17ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetHK47SoldLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for Yuka Laka in the area tat_m17ac.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02);
}
void SetHK47SoldLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for Yuka Laka in the area tat_m17ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetYukalPersuadeLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Yuka Laka in the area tat_m17ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetYukalPersuadeLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Yuka Laka in the area tat_m17ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetYukaHKFourThousandLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for Yuka Laka in the area tat_m17ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetYukaHKFourThousandLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for Yuka Laka in the area tat_m17ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetYukaHKThreeThousandLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for Yuka Laka in the area tat_m17ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05);
}
void SetYukaHKThreeThousandLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for Yuka Laka in the area tat_m17ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetYukaHKTwentyFiveHundredLocal()
{
    // This uses SW_PLOT_BOOLEAN_06 for Yuka Laka in the area tat_m17ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_06);
}
void SetYukaHKTwentyFiveHundredLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_06 for Yuka Laka in the area tat_m17ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_06, bValue);
    }
    return;
}
int GetYukaThreatenedOverPriceLocal()
{
    // This uses SW_PLOT_BOOLEAN_07 for Yuka Laka in the area tat_m17ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_07);
}
void SetYukaThreatenedOverPriceLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_07 for Yuka Laka in the area tat_m17ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_07, bValue);
    }
    return;
}
int GetYukaSaidSwoopChampionLocal()
{
    // This uses SW_PLOT_BOOLEAN_08 for Yuka Laka in the area tat_m17ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_08);
}
void SetYukaSaidSwoopChampionLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_08 for Yuka Laka in the area tat_m17ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_08, bValue);
    }
    return;
}
int GetYukaSaidKoltoGoneLocal()
{
    // This uses SW_PLOT_BOOLEAN_09 for Yuka Laka in the area tat_m17ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_09);
}
void SetYukaSaidKoltoGoneLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_09 for Yuka Laka in the area tat_m17ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_09, bValue);
    }
    return;
}
int GetYukaSaidWookieesRevoltedGlobal()
// set when yuka talks about wookies
{
    return GetGlobalBoolean("tat_YukaWookiees");
}
void SetYukaSaidWookieesRevoltedGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_YukaWookiees", bValue);
    }
    return;
}
int GetYukaSaidPowerStruggleGlobal()
// set when yuka talks about power struggle
{
    return GetGlobalBoolean("tat_YukaStruggle");
}
void SetYukaSaidPowerStruggleGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_YukaStruggle", bValue);
    }
    return;
}
int GetPlayerRacedAtAllGlobal()
// set when yuka talks about power struggle
{
    return GetGlobalBoolean("tat_playerhasraced");
}
void SetPlayerRacedAtAllGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_playerhasraced", bValue);
    }
    return;
}
int GetGandroffMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Gandroff in the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetGandroffMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Gandroff in the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetGandroffNameLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Gandroff in the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetGandroffNameLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Gandroff in the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetGandrofForceNoTalkLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Gandroff in the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetGandrofForceNoTalkLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Gandroff in the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetPazzakLastGameLostLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Pazzak on Furko Nellis in the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetPazzakLastGameLostLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Pazzak on Furko Nellis in the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetPazzakGame1WonLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Pazzak on Furko Nellis in the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetPazzakGame1WonLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Pazzak on Furko Nellis in the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetPazzakGame2WonLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Pazzak on Furko Nellis in the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetPazzakGame2WonLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Pazzak on Furko Nellis in the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetPazzakGame3WonLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for Pazzak on Furko Nellis in the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetPazzakGame3WonLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for Pazzak on Furko Nellis in the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetPazzakJustPlayedLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for Pazzak on Furko Nellis in the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05);
}
void SetPazzakJustPlayedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for Pazzak on Furko Nellis in the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetFazzaPazzakPlayedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Pazzak on alien player in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetFazzaPazzakPlayedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Pazzak on alien player in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetFazzaLostLastGameLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Pazzak on alien player in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetFazzaLostLastGameLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Pazzak on alien player in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetToldOfFazzaPazzakLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Pazzak on alien player in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetToldOfFazzaPazzakLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Pazzak on alien player in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetKomadNameLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for komad in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetKomadNameLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Komad in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetKomadMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for komad in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetKomadMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Komad in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetTanisNameLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Tanis in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetTanisNameLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Tanis in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetQuestionTanisAboutWifeLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Tanis in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetQuestionTanisAboutWifeLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Tanis in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetTanisIgnoredLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Tanis in the area tat_m18aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetTanisIgnoredLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Tanis in the area tat_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetGammoreanAmbushLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the ambush droid in the area tat_m18aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01);
}
void SetGammoreanAmbushLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the ambush droid in the area tat_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetAskedTanisForPaymentLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Tanis in the area tat_m18aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetAskedTanisForPaymentLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Tanis in the area tat_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetAskedTanisForCreditsLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Tanis in the area tat_m18aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetAskedTanisForCreditsLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Tanis in the area tat_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetAskedTanisToGiveUpLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for Tanis in the area tat_m18aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetAskedTanisToGiveUpLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for Tanis in the area tat_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetTanisShoutLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_05 for Tanis in the area tat_m18aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_05);
}
void SetTanisShoutLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_05 for Tanis in the area tat_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetDroidExplodeLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_06 for Tanis in the area tat_m18aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_06);
}
void SetDroidExplodeLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_06 for Tanis in the area tat_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_06, bValue);
    }
    return;
}
int GetTanisCallLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_07 for Tanis in the area tat_m18aa.
    return UT_GetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_07);
}
void SetTanisCallLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_07 for Tanis in the area tat_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(oTarget, SW_PLOT_BOOLEAN_07, bValue);
    }
    return;
}
int GetOfficeMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Czerka officer in the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetOfficeMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Czerka officer in the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetOfficeNamedLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Czerka officer in the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetOfficeNamedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Czerka officer in the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetVaporatorPriceDroppedLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for greeta holda in the area tat_m17ag.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetVaporatorPriceDroppedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for greeta holda in the area tat_m17ag.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetVaporatorGivenLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for greeta holda in the area tat_m17ag.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetVaporatorGivenLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for greeta holda in the area tat_m17ag.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetGreetaSaidSwoopLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for greeta holda in the area tat_m17ag.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetGreetaSaidSwoopLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for greeta holda in the area tat_m17ag.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetGreetaSaidKorribanLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for greeta holda in the area tat_m17ag.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05);
}
void SetGreetaSaidKorribanLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for greeta holda in the area tat_m17ag.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetGreetaSaidKoltoLocal()
{
    // This uses SW_PLOT_BOOLEAN_06 for greeta holda in the area tat_m17ag.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_06);
}
void SetGreetaSaidKoltoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_06 for greeta holda in the area tat_m17ag.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_06, bValue);
    }
    return;
}
int GetToldOfBountyLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Czerka protocol officer in the area tat_m17ag.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetToldOfBountyLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Czerka protocol officer in the area tat_m17ag.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetChieftainStickGivenLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Czerka protocol officer in the area tat_m17ag.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetChieftainStickGivenLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Czerka protocol officer in the area tat_m17ag.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetAskedIzizStarMapLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for iziz in the area tat_m17aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetAskedIzizStarMapLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for iziz in the area tat_m17aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetIzizMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for iziz in the area tat_m17aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetIzizMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for iziz in the area tat_m17aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetIzizRewardedLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for iziz in the area tat_m17aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetIzizRewardedLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for iziz in the area tat_m17aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetIzizPaidMoreLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for iziz in the area tat_m17aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetIzizPaidMoreLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for iziz in the area tat_m17aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetMechMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for mechanic in the area tat_m17aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetMechMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for mechanic in the area tat_m17aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetForcedMechanicLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for mechanic in the area tat_m17aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetForcedMechanicLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for mechanic in the area tat_m17aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetForcedNoTalkLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for mechanic in the area tat_m17aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetForcedNoTalkLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for mechanic in the area tat_m17aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetGateGuardMadLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the gate guard in the area tat_m17aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetGateGuardMadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the gate guard in the area tat_m17aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetPlayerSaidNoHuntLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Komad in the area tat_m18ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetPlayerSaidNoHuntLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Komad in the area tat_m18ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetPlayerSaidYesHuntLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Komad in the area tat_m18ac.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetPlayerSaidYesHuntLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Komad in the area tat_m18ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetTwoSaidSwoopLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for twohead in the area tat_m17ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetTwoSaidSwoopLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for twohead in the area tat_m17ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetTwoSaidKorribanLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for twohead in the area tat_m17ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetTwoSaidKorribanLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for twohead in the area tat_m17ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetTwoSaidKoltoLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for twohead in the area tat_m17ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetTwoSaidKoltoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for twohead in the area tat_m17ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetTwoSaidWookieeLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for two head in the area tat_m17ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetTwoSaidWookieeLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for two head in the area tat_m17ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetTwoAskedAboutSelfLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for two head in the area tat_m17ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05);
}
void SetTwoAskedAboutSelfLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for two head in the area tat_m17ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetTwoAskedAboutTatooineLocal()
{
    // This uses SW_PLOT_BOOLEAN_06 for two head in the area tat_m17ab.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_06);
}
void SetTwoAskedAboutTatooineLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_06 for two head in the area tat_m17ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_06, bValue);
    }
    return;
}
int GetFazzaSaidSwoopLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for Fazza in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02);
}
void SetFazzaSaidSwoopLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for Fazza in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetFazzaSaidKorribanLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Fazza in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03);
}
void SetFazzaSaidKorribanLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Fazza in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetFazzaSaidKoltoLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for Fazza in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04);
}
void SetFazzaSaidKoltoLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for Fazza in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetFazzaSaidWookieeLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for Fazza in the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05);
}
void SetFazzaSaidWookieeLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for Fazza in the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetTalkedToKomadLocal()
{
    // This uses SW_PLOT_BOOLEAN_03 for Komad in the area tat_m18ac.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_03);
}
void SetTalkedToKomadLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for Komad in the area tat_m18ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetDragonSpawnLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m18ac.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01);
}
void SetDragonSpawnLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m18ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetDragonPearlLocal()
{
    // This uses SW_PLOT_BOOLEAN_02 for the area tat_m18ac.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_02);
}
void SetDragonPearlLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_02 for the area tat_m18ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
int GetTuskenAmbush2Local()
{
    // This uses SW_PLOT_BOOLEAN_03 for the area tat_m18ac.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_03);
}
void SetTuskenAmbush2Local(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_03 for the area tat_m18ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_03, bValue);
    }
    return;
}
int GetHelenaSpawnLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m17af.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetHelenaSpawnLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m17af.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetTuskenAmbushLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the area kas_m18aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01);
}
void SetTuskenAmbushLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area kas_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetBanthaFollowLocal()
{
    // This uses SW_PLOT_BOOLEAN_04 for the area tat_m18ac.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_04);
}
void SetBanthaFollowLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_04 for the area tat_m18ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_04, bValue);
    }
    return;
}
int GetBanthaLuredLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for the area tat_m18ac.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_05);
}
void SetBanthaLuredLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for the area tat_m18ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetKomadReadyLocal()
{
    // This uses SW_PLOT_BOOLEAN_06 for the area tat_m18ac.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_06);
}
void SetKomadReadyLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_06 for the area tat_m18ac.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_06, bValue);
    }
    return;
}
int GetFailedFixLocal()
{
    // This uses SW_PLOT_BOOLEAN_05 for the area kas_m18aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_05);
}
void SetFailedFixLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_05 for the area kas_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_05, bValue);
    }
    return;
}
int GetDroid1RiddleLocal()
{
    // This uses SW_PLOT_BOOLEAN_06 for the area kas_m18aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_06);
}
void SetDroid1RiddleLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_06 for the area kas_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_06, bValue);
    }
    return;
}
int GetDroid2RiddleLocal()
{
    // This uses SW_PLOT_BOOLEAN_07 for the area kas_m18aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_07);
}
void SetDroid2RiddleLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_07 for the area kas_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_07, bValue);
    }
    return;
}
int GetDroid3RiddleLocal()
{
    // This uses SW_PLOT_BOOLEAN_08 for the area kas_m18aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_08);
}
void SetDroid3RiddleLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_08 for the area kas_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_08, bValue);
    }
    return;
}
int GetDroid4RiddleLocal()
{
    // This uses SW_PLOT_BOOLEAN_09 for the area kas_m18aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_09);
}
void SetDroid4RiddleLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_09 for the area kas_m18aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_09, bValue);
    }
    return;
}
int GetSharinaWaitLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the area kas_m17aa.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01);
}
void SetSharinaWaitLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area kas_m17aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetGriffSpawnLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m20aa and tat_m17ag.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetGriffSpawnLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m20aa and tat_m17ag.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetGriffSawMissionLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for Griff in the area kas_m20aa.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetGriffSawMissionLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for Griff in the area kas_m20aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
// sets the current opponent variable
void SetOpponent(int nOpponent)
{
    SetGlobalNumber("TAT_SWOOP_OPP",nOpponent);
}
// retuens the current opponent variable
int GetOpponent()
{
    return GetGlobalNumber("TAT_SWOOP_OPP");
}
// sets the dialouge tokens based on an integer and creates it in the format
// mm:ss:ff
void SetTokenRaceTime(int nToken, int nRacerTime)
{
    // calculate the time components
    int nMinutes = nRacerTime/6000;
    int nSeconds = (nRacerTime - (nMinutes * 6000)) / 100;
    int nFractions =  nRacerTime - ((nMinutes * 6000) + (nSeconds * 100));
    //building the time string
    string sTime = IntToString(nMinutes) + ":";
    if (nSeconds < 10)
    {
        sTime = sTime + "0";
    }
    sTime = sTime + IntToString(nSeconds) + ":";
    if(nFractions < 10)
    {
        sTime = sTime + "0";
    }
    sTime = sTime + IntToString(nFractions);
    SetCustomToken(nToken,sTime);
}
// Checks if SW_PLOT_BOOLEAN_10 has been set. if not returns true and sets the boolean
int HasNeverTriggered()
{
    int bReturn;
    if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_10) == FALSE)
    {
        bReturn = TRUE;
        UT_SetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_10,TRUE);
    }
    return bReturn;
}
// Checks if SW_PLOT_BOOLEAN_09 has been set. if not returns true and sets the boolean
int FirstRace()
{
    int bReturn;
    if(UT_GetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_09) == FALSE)
    {
        bReturn = TRUE;
        UT_SetPlotBooleanFlag(OBJECT_SELF,SW_PLOT_BOOLEAN_09,TRUE);
    }
    return bReturn;
}
int GetKomadHuntEndGlobal()
{
    return GetGlobalBoolean("tat_KomadHuntEnd");
}
void SetKomadHuntEndGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_KomadHuntEnd", bValue);
    }
    return;
}
int GetPlayerAttemptedOfficialRaceGlobal()
{
    return GetGlobalBoolean("tat_oneofficialrace");
}
void SetPlayerAttemptedOfficialRaceGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_oneofficialrace", bValue);
    }
    return;
}
int GetPlayerGotFreeRaceGlobal()
{
    return GetGlobalBoolean("tat_freeracegiven");
}
void SetPlayerGotFreeRaceGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_freeracegiven", bValue);
    }
    return;
}
int GetKraytMapGlobal()
{
    return GetGlobalBoolean("tat_KraytMap");
}
void SetKraytMapGlobal(int bValue)
{
    if (bValue == TRUE || bValue == FALSE)
    {
        SetGlobalBoolean("tat_KraytMap", bValue);
    }
    return;
}
int GetKomadHuntingLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m17ad.
    return UT_GetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01);
}
void SetKomadHuntingLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m17ad.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(OBJECT_SELF, SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
int GetTuskenDoneLocal()
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m18ab.
    return UT_GetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01);
}
void SetTuskenDoneLocal(int bValue)
{
    // This uses SW_PLOT_BOOLEAN_01 for the area tat_m18ab.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(OBJECT_SELF), SW_PLOT_BOOLEAN_01, bValue);
    }
    return;
}
void EquipBasicClothing(object oTarget)
{
    int bFound = FALSE;
    object oParty1 = GetPartyMemberByIndex(0);
    object oParty2 = GetPartyMemberByIndex(1);
    object oParty3 = GetPartyMemberByIndex(2);
    object oItem = GetFirstItemInInventory(oTarget);
    //Issue 1  Make sure the same clothing is not equipped.
    //Issue 2  Make sure that they already have clothing.
    //Issue 3  If they do not have clothing then spawn and equip.
    //Issue 4  If they are wearing basic clothing ignore them.
    /*
    while(GetIsObjectValid(oItem) == TRUE && bFound == FALSE)
    {
        if (//GetBaseItemType(oItem) == BASE_ITEM_JEDI_ROBE &&
           (//GetLevelByClass(CLASS_TYPE_JEDICONSULAR, oTarget) > 0 ||
            //GetLevelByClass(CLASS_TYPE_JEDIGUARDIAN, oTarget) > 0 ||
            //GetLevelByClass(CLASS_TYPE_JEDISENTINEL, oTarget) > 0) &&
            GetItemInSlot(INVENTORY_SLOT_BODY, oParty1) != oItem &&
            GetItemInSlot(INVENTORY_SLOT_BODY, oParty2) != oItem &&
            GetItemInSlot(INVENTORY_SLOT_BODY, oParty3) != oItem)
        {
            AssignCommand(oTarget, ActionEquipItem(oItem, INVENTORY_SLOT_BODY,TRUE));
            bFound = TRUE;
        }
        oItem = GetNextItemInInventory(oTarget);
    }
    */
    oItem = GetFirstItemInInventory(oTarget);
    while(GetIsObjectValid(oItem) == TRUE && bFound == FALSE)
    {
        if (GetBaseItemType(oItem) == BASE_ITEM_BASIC_CLOTHING &&
            GetItemInSlot(INVENTORY_SLOT_BODY, oParty1) != oItem &&
            GetItemInSlot(INVENTORY_SLOT_BODY, oParty2) != oItem &&
            GetItemInSlot(INVENTORY_SLOT_BODY, oParty3) != oItem)
        {
            AssignCommand(oTarget, ActionEquipItem(oItem, INVENTORY_SLOT_BODY, TRUE));
            bFound = TRUE;
        }
        oItem = GetNextItemInInventory(oTarget);
    }
    if (bFound == FALSE)
    {
        oItem = CreateItemOnObject("G_A_CLOTHES01", oTarget);
        AssignCommand(oTarget, ActionEquipItem(oItem, INVENTORY_SLOT_BODY,TRUE));
    }
}
void RemoveSandpeopleDisguise()
{
    object oPC = GetFirstPC();
    object oParty1 = GetPartyMemberByIndex(0);
    object oParty2 = GetPartyMemberByIndex(1);
    object oParty3 = GetPartyMemberByIndex(2);
    object oArmor = GetItemInSlot(INVENTORY_SLOT_BODY, oParty1);
    if (GetTag(oArmor) == "tat17_sandperdis")
    {
        AssignCommand(oParty1, ClearAllActions());
        AssignCommand(oParty1, ActionUnequipItem(oArmor));
        AssignCommand(oParty1, ActionDoCommand(SetItemNonEquippable(oArmor, TRUE)));
        EquipBasicClothing(oParty1);
    }
    oArmor = GetItemInSlot(INVENTORY_SLOT_BODY, oParty2);
    if (GetTag(oArmor) == "tat17_sandperdis")
    {
        AssignCommand(oParty2, ClearAllActions());
        AssignCommand(oParty2, ActionUnequipItem(oArmor));
        AssignCommand(oParty2, ActionDoCommand(SetItemNonEquippable(oArmor, TRUE)));
        EquipBasicClothing(oParty2);
    }
    oArmor = GetItemInSlot(INVENTORY_SLOT_BODY, oParty3);
    if (GetTag(oArmor) == "tat17_sandperdis")
    {
        AssignCommand(oParty3, ClearAllActions());
        AssignCommand(oParty3, ActionUnequipItem(oArmor));
        AssignCommand(oParty3, ActionDoCommand(SetItemNonEquippable(oArmor, TRUE)));
        EquipBasicClothing(oParty3);
    }
    ActionWait(1.0);
    object oItem = GetFirstItemInInventory(oPC);
    while (GetIsObjectValid(oItem) == TRUE)
    {
        if (GetTag(oItem) == "tat17_sandperdis")
        {
            SetItemNonEquippable(oItem, TRUE);
        }
        oItem = GetNextItemInInventory(oPC);
    }
}
void DestroySandpeopleDisguise()
{
    object oPC = GetFirstPC();
    object oParty1 = GetPartyMemberByIndex(0);
    object oParty2 = GetPartyMemberByIndex(1);
    object oParty3 = GetPartyMemberByIndex(2);
    object oArmor = GetItemInSlot(INVENTORY_SLOT_BODY, oParty1);
    if (GetTag(oArmor) == "tat17_sandperdis")
    {
        AssignCommand(oParty1, ClearAllActions());
        AssignCommand(oParty1, ActionUnequipItem(oArmor));
        DestroyObject(oArmor);
        //EquipBasicClothing(oParty1);
    }
    oArmor = GetItemInSlot(INVENTORY_SLOT_BODY, oParty2);
    if (GetTag(oArmor) == "tat17_sandperdis")
    {
        AssignCommand(oParty2, ClearAllActions());
        AssignCommand(oParty2, ActionUnequipItem(oArmor));
        DestroyObject(oArmor);
        //EquipBasicClothing(oParty2);
    }
    oArmor = GetItemInSlot(INVENTORY_SLOT_BODY, oParty3);
    if (GetTag(oArmor) == "tat17_sandperdis")
    {
        AssignCommand(oParty3, ClearAllActions());
        AssignCommand(oParty3, ActionUnequipItem(oArmor));
        DestroyObject(oArmor);
        //EquipBasicClothing(oParty3);
    }
    ActionWait(1.0);
    object oItem = GetFirstItemInInventory(oPC);
    while (GetIsObjectValid(oItem) == TRUE)
    {
        if (GetTag(oItem) == "tat17_sandperdis")
        {
            DestroyObject(oItem);
        }
        oItem = GetNextItemInInventory(oPC);
    }
}
void SandpeopleDisguiseUsable()
{
    object oPC = GetFirstPC();
    object oItem = GetFirstItemInInventory(oPC);
    while (GetIsObjectValid(oItem) == TRUE)
    {
        if (GetTag(oItem) == "tat17_sandperdis")
        {
            SetItemNonEquippable(oItem, FALSE);
        }
        oItem = GetNextItemInInventory(oPC);
    }
}
int GetTuskenContainerLocal(object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the the area tat_m20aa.
    return UT_GetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_02);
}
void SetTuskenContainerLocal(int bValue, object oTarget = OBJECT_SELF)
{
    // This uses SW_PLOT_BOOLEAN_02 for the the area tat_m20aa.
    if (bValue == TRUE || bValue == FALSE)
    {
        UT_SetPlotBooleanFlag(GetArea(oTarget), SW_PLOT_BOOLEAN_02, bValue);
    }
    return;
}
""",
    "k_inc_treasure": b"""//:: k_inc_treasure
/*
     contains code for filling containers using treasure tables
*/
//:: Created By:  Jason Booth
//:: Copyright (c) 2002 Bioware Corp.
//
//  March 15, 2003  J.B.
//      removed parts and spikes from tables
//
//constants for container types
int SWTR_DEBUG = TRUE;  //set to false to disable console/file logging
int SWTR_TABLE_CIVILIAN_CONTAINER = 1;
int SWTR_TABLE_MILITARY_CONTAINER_LOW = 2;
int SWTR_TABLE_MILITARY_CONTAINER_MID = 3;
int SWTR_TABLE_MILITARY_CONTAINER_HIGH = 4;
int SWTR_TABLE_CORPSE_CONTAINER_LOW = 5;
int SWTR_TABLE_CORPSE_CONTAINER_MID = 6;
int SWTR_TABLE_CORPSE_CONTAINER_HIGH = 7;
int SWTR_TABLE_SHADOWLANDS_CONTAINER_LOW = 8;
int SWTR_TABLE_SHADOWLANDS_CONTAINER_MID = 9;
int SWTR_TABLE_SHADOWLANDS_CONTAINER_HIGH = 10;
int SWTR_TABLE_DROID_CONTAINER_LOW = 11;
int SWTR_TABLE_DROID_CONTAINER_MID = 12;
int SWTR_TABLE_DROID_CONTAINER_HIGH = 13;
int SWTR_TABLE_RAKATAN_CONTAINER = 14;
int SWTR_TABLE_SANDPERSON_CONTAINER = 15;
//Fill an object with treasure from the specified table
//This is the only function that should be used outside this include file
void SWTR_PopulateTreasure(object oContainer,int iTable,int iItems = 1,int bUnique = TRUE);
//for internal debugging use only, output string to the log file and console if desired
void SWTR_Debug_PostString(string sStr,int bConsole = TRUE,int x = 5,int y = 5,float fTime = 5.0)
{
  if(SWTR_DEBUG)
  {
    if(bConsole)
    {
      AurPostString("SWTR_DEBUG - " + sStr,x,y,fTime);
    }
    PrintString("SWTR_DEBUG - " + sStr);
  }
}
//return whether i>=iLow and i<=iHigh
int SWTR_InRange(int i,int iLow,int iHigh)
{
  if(i >= iLow && i <= iHigh)
  {
    return(TRUE);
  }
  else
  {
    return(FALSE);
  }
}
//returns whether sTemplate is not in sFilter
int SWTR_IsUnique(string sTemplate,string sFilter)
{
  if(sFilter == "")
  {
    return(TRUE);
  }
  if(FindSubString(sFilter,sTemplate) >= 0)
  {
    return(FALSE);
  }
  else
  {
    return(TRUE);
  }
}
//turn a given quantity into appropriate format for a treasure blob (string)
string SWTR_GetQuantity(int iCount)
{
  string str = IntToString(iCount);
  string pad = "0";
  int length = 4;
  while(GetStringLength(str) < length)
  {
    str = pad + str;
  }
  return("[" + str + "]");
}
//get a single treasure blob (string) from specified table
//use sFilter to maintain uniqueness
string SWTR_GetTreasure(int iTable,string sFilter = "")
{
  int iRoll;
  string sTemplate;
  int bFound = FALSE;
  string sObjDesc = "";
  string sQuantity;
  //first, generate a random number (0-99) and then, using the specified table
  //lookup the treasure
  do {
    iRoll = Random(100);
    switch(iTable)
    {
    case 1:  //civilian container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,84) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(20)+1);
        bFound = TRUE;
      }
      /*
      sTemplate = "G_A_CLOTHES01";
      if(SWTR_InRange(iRoll,25,34) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_A_CLOTHES02";
      if(SWTR_InRange(iRoll,35,44) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_A_CLOTHES03";
      if(SWTR_InRange(iRoll,45,54) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_A_CLOTHES04";
      if(SWTR_InRange(iRoll,55,64) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_A_CLOTHES05";
      if(SWTR_InRange(iRoll,65,74) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_A_CLOTHES06";
      if(SWTR_InRange(iRoll,75,84) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,85,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,90,94) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt01";
      if(SWTR_InRange(iRoll,85,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 2:  //low level military container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,9) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(20)+1);
        bFound = TRUE;
      }
      sTemplate = "g_w_fraggren01";
      if(SWTR_InRange(iRoll,10,29) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_w_StunGren01";
      if(SWTR_InRange(iRoll,30,39) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_w_SonicGren01";
      if(SWTR_InRange(iRoll,40,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "g_w_iongren01";
      if(SWTR_InRange(iRoll,60,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,50,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,60,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt01";
      if(SWTR_InRange(iRoll,70,84) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_MEDEQPMNT04";
      if(SWTR_InRange(iRoll,85,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDREPEQP001";
      if(SWTR_InRange(iRoll,90,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 3:  //mid level military container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,3) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(30)+10);
        bFound = TRUE;
      }
      sTemplate = "g_w_fraggren01";
      if(SWTR_InRange(iRoll,4,17) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_w_StunGren01";
      if(SWTR_InRange(iRoll,18,21) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_w_SonicGren01";
      if(SWTR_InRange(iRoll,22,27) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "g_w_iongren01";
      if(SWTR_InRange(iRoll,28,33) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,20,23) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,24,33) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_MEDEQPMNT02";
      if(SWTR_InRange(iRoll,34,48) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_MEDEQPMNT04";
      if(SWTR_InRange(iRoll,49,53) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDREPEQP002";
      if(SWTR_InRange(iRoll,54,63) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE001";
      if(SWTR_InRange(iRoll,64,75) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE002";
      if(SWTR_InRange(iRoll,76,87) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE003";
      if(SWTR_InRange(iRoll,88,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 4:  //high level military container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,3) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(60)+ 40);
        bFound = TRUE;
      }
      sTemplate = "g_w_fraggren01";
      if(SWTR_InRange(iRoll,4,17) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "G_w_StunGren01";
      if(SWTR_InRange(iRoll,18,21) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "G_w_SonicGren01";
      if(SWTR_InRange(iRoll,22,27) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "g_w_iongren01";
      if(SWTR_InRange(iRoll,28,33) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,20,23) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,24,33) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_MEDEQPMNT03";
      if(SWTR_InRange(iRoll,34,48) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_MEDEQPMNT04";
      if(SWTR_InRange(iRoll,49,53) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDREPEQP003";
      if(SWTR_InRange(iRoll,54,63) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE004";
      if(SWTR_InRange(iRoll,64,75) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE005";
      if(SWTR_InRange(iRoll,76,87) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE006";
      if(SWTR_InRange(iRoll,88,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 5:  //low level corpse container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(20)+ 1);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,70,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,80,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt01";
      if(SWTR_InRange(iRoll,80,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 6:  //mid level corpse container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,49) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(30)+ 10);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,40,49) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,50,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_MEDEQPMNT02";
      if(SWTR_InRange(iRoll,50,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE001";
      if(SWTR_InRange(iRoll,70,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE002";
      if(SWTR_InRange(iRoll,80,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE003";
      if(SWTR_InRange(iRoll,90,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 7:  //high level corpse container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,49) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(60)+ 40);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,40,49) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,50,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_MEDEQPMNT03";
      if(SWTR_InRange(iRoll,50,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE004";
      if(SWTR_InRange(iRoll,70,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE005";
      if(SWTR_InRange(iRoll,80,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE006";
      if(SWTR_InRange(iRoll,90,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 8:  //low level shadowlands container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(20)+ 1);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,60,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt01";
      if(SWTR_InRange(iRoll,70,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 9:  //mid level shadowlands container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(30)+ 10);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,50,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt02";
      if(SWTR_InRange(iRoll,60,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE001";
      if(SWTR_InRange(iRoll,70,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE002";
      if(SWTR_InRange(iRoll,80,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE003";
      if(SWTR_InRange(iRoll,90,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 10:  //high level shadowlands container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(60)+ 40);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,50,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt03";
      if(SWTR_InRange(iRoll,60,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE004";
      if(SWTR_InRange(iRoll,70,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE005";
      if(SWTR_InRange(iRoll,80,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE006";
      if(SWTR_InRange(iRoll,90,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 11:  //low level droid container
      /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_DRDLTPLAT001";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDMTNSEN001";
      if(SWTR_InRange(iRoll,80,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 12:  //mid level droid container
      /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_DRDLTPLAT002";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDMTNSEN002";
      if(SWTR_InRange(iRoll,80,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 13:  //high level droid container
    /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_DRDLTPLAT003";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDMTNSEN003";
      if(SWTR_InRange(iRoll,80,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 14:  //rakatan container
    /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,0,15) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,16,31) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_DRDREPEQP003";
      if(SWTR_InRange(iRoll,0,24) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE004";
      if(SWTR_InRange(iRoll,25,49) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE005";
      if(SWTR_InRange(iRoll,50,74) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE006";
      if(SWTR_InRange(iRoll,75,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 15:  //sandperson container
    /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,0,11) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      */
      sTemplate = "g_w_fraggren01";
      if(SWTR_InRange(iRoll,0,23) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_w_StunGren01";
      if(SWTR_InRange(iRoll,24,35) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_w_SonicGren01";
      if(SWTR_InRange(iRoll,36,47) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "g_w_iongren01";
      if(SWTR_InRange(iRoll,48,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE001";
      if(SWTR_InRange(iRoll,60,71) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE002";
      if(SWTR_InRange(iRoll,72,83) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE003";
      if(SWTR_InRange(iRoll,84,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    }
  } while(!bFound);
  return(sObjDesc);
}
//Fill an object with treasure from the specified table
//This is the only function that should be used outside this include file
void SWTR_PopulateTreasure(object oContainer,int iTable,int iItems = 1,int bUnique = TRUE)
{
  string sFilter = "";  //maintains list of item templates already retrieved
  string sItem,sTemplate;
  int iQuantity;
  int i;
  if(!GetIsObjectValid(oContainer))
  {
    SWTR_Debug_PostString("invalid container");
    return;
  }
  while(iItems > 0)
  {
    sItem = SWTR_GetTreasure(iTable,sFilter);
    if(sItem == "")
    {
      SWTR_Debug_PostString("bad table");
    }
    //parse the item description
    //treasure blobs (strings) consist of the item template followed by the quantity
    if((i = FindSubString(sItem,"[")) >= 0)
    {
      iQuantity = StringToInt(GetSubString(sItem,i+1,4));
      sTemplate = GetSubString(sItem,0,i);
    }
    else
    {
      iQuantity = 1;
      sTemplate = sItem;
    }
    //create item
    if(!GetIsObjectValid(CreateItemOnObject(sTemplate,oContainer,iQuantity)))
    {
      SWTR_Debug_PostString("item create failed (" + sTemplate + ")");
    }
    else
    {
      SWTR_Debug_PostString("container:" + GetTag(oContainer) + " item:" + sTemplate,FALSE);
    }
    //update our filter if we are maintaining uniqueness
    if(bUnique)
    {
      sFilter = sFilter + sTemplate;
    }
    iItems--;
  }
}
""",
    "k_inc_unk": b"""//::///////////////////////////////////////////////
//:: k_inc_unk
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
  include file for unknown world
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Sept. 9, 2002
//:://////////////////////////////////////////////
#include "k_inc_debug"
#include "k_inc_utility"
#include "k_inc_generic"
//mark an object for cleanup by the UNK_CleanupDeadObjects function
void UNK_MarkForCleanup(object obj);
//destroy all objects whose PLOT_10 flag has been set
void UNK_CleanupDeadObjects(object oArea);
//mark object for cleanup and move to nearest exit
void UNK_LeaveArea(object obj = OBJECT_SELF, int bRun = FALSE);
//test if red rakata are hostile
int UNK_GetRedRakataHostile();
//test if black rakata are hostile
int UNK_GetBlackRakataHostile();
//make red rakatans hostile
void UNK_SetRedRakataHostile();
//make black rakatans hostile
void UNK_SetBlackRakataHostile();
//make black rakatans neutral
void UNK_SetBlackRakataNeutral();
//fill container with treasure from table
void UNK_AddTreasureToContainer(object oContainer,int iTable,int iAmount);
// unavoidable damage to all within radius
void UNK_RakDefence(string sObjectTag, float fDistance, int bIndiscriminant = TRUE);
//::///////////////////////////////////////////////
//:: UNK_MarkForCleanup
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//mark an object for cleanup by the TAR_CleanupDeadObjects function
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 26, 2002
//:://////////////////////////////////////////////
void UNK_MarkForCleanup(object obj)
{
  UT_SetPlotBooleanFlag(obj,SW_PLOT_BOOLEAN_10,TRUE);
}
//::///////////////////////////////////////////////
//:: UNK_CleanupDeadObjects
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//destroy all objects whose PLOT_10 flag has been set
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 15, 2002
//:://////////////////////////////////////////////
void UNK_CleanupDeadObjects(object oArea)
{
  object obj;
  obj = GetFirstObjectInArea(oArea);
  //Db_PostString("START CLEANUP...",5,7,5.0);
  while(GetIsObjectValid(obj))
  {
    //Db_PostString("FOUND OBJ",5,6,5.0);
    if ((UT_GetPlotBooleanFlag(obj,SW_PLOT_BOOLEAN_10)) && (IsObjectPartyMember(obj) == FALSE))
    {
      //Db_PostString("CLEANING UP OBJECT",5,5,5.0);
      DestroyObject(obj,0.0,TRUE);
    }
    obj = GetNextObjectInArea(oArea);
  }
}
//::///////////////////////////////////////////////
//:: UNK_LeaveArea
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//mark object for cleanup and move to nearest exit
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 26, 2002
//:://////////////////////////////////////////////
void UNK_LeaveArea(object obj = OBJECT_SELF, int bRun = FALSE)
{
  object oExit = GetNearestObjectByTag("punk_wpnpcext");
  UNK_MarkForCleanup(obj);
  if ((GetIsObjectValid(oExit)) && (IsObjectPartyMember(oExit) == FALSE))
  {
    UT_PlotMoveObject(oExit,bRun);
  }
}
//::///////////////////////////////////////////////
//:: UNK_GetRedRakataHostile
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//test if red rakata are hostile
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Sept. 10, 2002
//:://////////////////////////////////////////////
int UNK_GetRedRakataHostile()
{
  return (GetGlobalNumber("unk_redvill") == 99);
}
//::///////////////////////////////////////////////
//:: UNK_GetBlackRakataHostile
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//test if black rakata are hostile
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Sept. 10, 2002
//:://////////////////////////////////////////////
int UNK_GetBlackRakataHostile()
{
  return ((GetGlobalBoolean("UNK_USEDDARKSIDE") == FALSE) && (GetGlobalBoolean("UNK_BLACKHOSTILE") == FALSE));
}
//::///////////////////////////////////////////////
//:: UNK_SetRedRakatanHostile
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make red rakatans hostile
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Sept. 13, 2002
//:://////////////////////////////////////////////
void UNK_SetRedRakataHostile()
{
  object obj;
  SetGlobalNumber("Unk_redvill",99);
  SetGlobalBoolean("Unk_RedHostile",TRUE);
  obj = GetFirstObjectInArea();
  while (GetIsObjectValid(obj))
  {
    if ((GetTag(obj) != "unk42_breed01") && (GetTag(obj) != "unk42_breed02") && (GetTag(obj) != "unk42_breed03") && (GetTag(obj) != "unk41_gizka") && (IsObjectPartyMember(obj) == FALSE))
    {
      ChangeToStandardFaction(obj,STANDARD_FACTION_HOSTILE_1);
      AssignCommand(obj,ClearAllActions());
      AssignCommand(obj, GN_DetermineCombatRound());
    }
    obj = GetNextObjectInArea();
  }
}
//::///////////////////////////////////////////////
//:: UNK_SetBlackRakatanHostile
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make black rakatans hostile
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Sept. 13, 2002
//:://////////////////////////////////////////////
void UNK_SetBlackRakataHostile()
{
  object obj;
  Db_PostString("SCANNING...",5,5,5.0);
  SetGlobalBoolean("UNK_BLACKHOSTILE",TRUE);
  obj = GetFirstObjectInArea();
  Db_PostString("FOUND OBJ...",5,5,5.0);
  while(GetIsObjectValid(obj))
  {
    if ((GetTag(obj) != "unk41_gizka") && (IsObjectPartyMember(obj) == FALSE) && (GetTag(obj) != "unk43_redpris"))
    {
      Db_PostString("IN LOOP...",5,5,5.0);
      Db_PostString("RAKATA HOSTILE",5,5,5.0);
      ChangeToStandardFaction(obj,STANDARD_FACTION_HOSTILE_1);
      AssignCommand(obj,ClearAllActions());
      AssignCommand(obj, GN_DetermineCombatRound());
    }
    obj = GetNextObjectInArea();
  }
}
//::///////////////////////////////////////////////
//:: UNK_SetBlackRakataNeutral
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make black rakatans neutral
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Sept. 13, 2002
//:://////////////////////////////////////////////
void UNK_SetBlackRakataNeutral()
{
  object obj;
  obj = GetFirstObjectInArea();
  while(GetIsObjectValid(obj))
  {
    if (IsObjectPartyMember(obj) == FALSE)
    {
        ChangeToStandardFaction(obj,STANDARD_FACTION_NEUTRAL);
        AssignCommand(obj,ClearAllActions());
    }
    obj = GetNextObjectInArea();
  }
}
//fill container with treasure from table
void UNK_AddTreasureToContainer(object oContainer,int iTable,int iAmount)
{
  int i;
  if(!GetIsObjectValid(oContainer))
  {
    return;
  }
  for(i = 0;i < iAmount;i++)
  {
    switch(iTable)
    {
    case 0:
      switch(Random(3))
      {
      case 0:
        CreateItemOnObject("G_I_CREDITS001",oContainer,Random(50) + 20);
        break;
      case 1:
        CreateItemOnObject("G_I_MEDEQPMNT04",oContainer);
        break;
      default:
        CreateItemOnObject("G_I_MEDEQPMNT02",oContainer);
      }
      break;
    case 1:
      switch(Random(5))
      {
      case 0:
        CreateItemOnObject("G_I_CREDITS001",oContainer,Random(50) + 20);
        break;
      case 1:
        CreateItemOnObject("G_I_MEDEQPMNT04",oContainer);
        break;
      case 2:
        CreateItemOnObject("G_I_DRDREPEQP002",oContainer);
        break;
      case 3:
        CreateItemOnObject("G_I_PARTS01",oContainer);
        break;
      default:
        CreateItemOnObject("G_I_MEDEQPMNT02",oContainer);
      }
      break;
    }
  }
}
//::///////////////////////////////////////////////
//:: Rakatan Defence Grid
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Overloads a power conduit and does 10d6 damage
    to all within the specified radius
*/
//:://////////////////////////////////////////////
//:: Created By: Peter Thomas
//:: Created On:
//:://////////////////////////////////////////////
void UNK_RakDefence(string sObjectTag, float fDistance, int bIndiscriminant = TRUE)
{
    object oWay = GetObjectByTag(sObjectTag);
    if(GetIsObjectValid(oWay))
    {
        effect eFNF = EffectVisualEffect(VFX_FNF_GRENADE_ION);
        effect eVFXHit = EffectVisualEffect(1021);
        effect eVFXBeam = EffectBeam(VFX_BEAM_LIGHTNING_DARK_L, oWay, BODY_NODE_CHEST);
        effect eDam;
        object oTarget = GetNearestObject(OBJECT_TYPE_CREATURE, oWay, 1);
        int nCount = 1;
        int nDam = 1000;
        float fDelay = 0.3;
        AssignCommand(oWay, ActionPlayAnimation(ANIMATION_PLACEABLE_OPEN));
        DelayCommand(0.3, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eFNF, GetLocation(oWay)));
        while(GetIsObjectValid(oTarget) && GetDistanceBetween(oTarget, oWay) <= fDistance)
        {
            if(bIndiscriminant == TRUE || GetIsEnemy(oTarget, GetFirstPC()))
            {
                eDam = EffectDamage(nDam, DAMAGE_TYPE_UNIVERSAL);
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
                //fDelay = fDelay + 0.17;
                eDam = EffectDeath();
                DelayCommand(fDelay + 0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVFXBeam, oTarget, 1.0));
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFXHit, oTarget, 1.0));
                fDelay = fDelay + 0.17;
}
            nCount++;
            oTarget = GetNearestObject(OBJECT_TYPE_CREATURE, oWay, nCount);
        }
        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_PRO_DROID_KILL), oWay);
    }
}
""",
    "k_inc_utility": b"""//:: k_inc_utility
/*
    common functions used throughout various scripts
    Modified by Peter T. 17/03/03
    - Added UT_MakeNeutral2(), UT_MakeHostile1(), UT_MakeFriendly1() and UT_MakeFriendly2()
*/
//:: Created By: Jason Booth
//:: Copyright (c) 2002 Bioware Corp.
// Plot Flag Constants.
int SW_PLOT_BOOLEAN_01 = 0;
int SW_PLOT_BOOLEAN_02 = 1;
int SW_PLOT_BOOLEAN_03 = 2;
int SW_PLOT_BOOLEAN_04 = 3;
int SW_PLOT_BOOLEAN_05 = 4;
int SW_PLOT_BOOLEAN_06 = 5;
int SW_PLOT_BOOLEAN_07 = 6;
int SW_PLOT_BOOLEAN_08 = 7;
int SW_PLOT_BOOLEAN_09 = 8;
int SW_PLOT_BOOLEAN_10 = 9;
int SW_PLOT_HAS_TALKED_TO = 10;
int SW_PLOT_COMPUTER_OPEN_DOORS = 11;
int SW_PLOT_COMPUTER_USE_GAS = 12;
int SW_PLOT_COMPUTER_DEACTIVATE_TURRETS = 13;
int SW_PLOT_COMPUTER_DEACTIVATE_DROIDS = 14;
int SW_PLOT_COMPUTER_MODIFY_DROID = 15;
int SW_PLOT_REPAIR_WEAPONS = 16;
int SW_PLOT_REPAIR_TARGETING_COMPUTER = 17;
int SW_PLOT_REPAIR_SHIELDS = 18;
int SW_PLOT_REPAIR_ACTIVATE_PATROL_ROUTE = 19;
// UserDefined events
int HOSTILE_RETREAT = 1100;
//Alignment Adjustment Constants
int SW_CONSTANT_DARK_HIT_HIGH = -6;
int SW_CONSTANT_DARK_HIT_MEDIUM = -5;
int SW_CONSTANT_DARK_HIT_LOW = -4;
int SW_CONSTANT_LIGHT_HIT_LOW = -2;
int SW_CONSTANT_LIGHT_HIT_MEDIUM = -1;
int SW_CONSTANT_LIGHT_HIT_HIGH = 0;
// Returns a pass value based on the object's level and DC rating of 0, 1, or 2 (easy, medium, difficult)
// December 20 2001: Changed so that the difficulty is determined by the
// NPC's Hit Dice
int AutoDC(int DC, int nSkill, object oTarget);
//  checks for high charisma
int IsCharismaHigh();
//  checks for low charisma
int IsCharismaLow();
//  checks for normal charisma
int IsCharismaNormal();
//  checks for high intelligence
int IsIntelligenceHigh();
//  checks for low intelligence
int IsIntelligenceLow();
//  checks for normal intelligence
int IsIntelligenceNormal();
//  checks to see if pc is very dark side
int IsDarkHigh();
//  checks to see if pc is just a little dark side
int IsDarkLow();
//  checks to see if pc is dark side
int IsDark();
//  checks to see if pc is very light side
int IsLightHigh();
//  checks to see if pc is slightly light side
int IsLightLow();
//  checks to see if pc is light side
int IsLight();
//  checks to see if pc is neutral
int IsNeutral();
//  pads a string with the given pad character to the specified length
string PadString(string str = "",string pad = " ",int length = 0);
//  causes the given object to initiate conversation with the player
void TalkToPC(object oSpeaker);
//Gets the boolean state of a plot bit field
int UT_GetPlotBooleanFlag(object oTarget, int nIndex);
//Sets the boolean state of plot bit field using the SW_PLOT_BOOLEAN CONSTANTS
void UT_SetPlotBooleanFlag(object oTarget, int nIndex, int nState);
//Determines state of the HAS TALKED TO FLAG on the passed in object.
int UT_GetTalkedToBooleanFlag(object oTarget);
//Sets the Talked To Flag on the specified object.
void UT_SetTalkedToBooleanFlag(object oTarget, int nState = TRUE);
//Get the nearest PC to the specified object
object UT_GetNearestPCToObject(object oTarget = OBJECT_SELF);
//Determine if object is a PC
int UT_IsObjectPC(object oTarget = OBJECT_INVALID);
//does a heavy darkside adjustment on the player
void UT_DarkHigh(object oTarget);
//does a medium darkside adjustment on the player
void UT_DarkMed(object oTarget);
//does a small darkside adjustment on the player
void UT_DarkSml(object oTarget);
//does a heavy lightside adjustment on the player
void UT_LightHigh(object oTarget);
//does a medium lightside adjustment on the player
void UT_LightMed(object oTarget);
//does a small lightside adjustment on the player
void UT_LightSml(object oTarget);
//Resets all of an objects Bit Fields to TRUE or FALSE
void UT_ResetPlotBooleanFlags(object oToChange, int nState);
//make object do an uninterruptible path move
void UT_PlotMovePath(string sWayPointTag,int nFirst, int nLast, int nRun = FALSE);
//make object do an uninterruptible move to an object
void UT_PlotMoveObject(object oTarget,int nRun = FALSE);
//make object do an uninterruptible move to a location
void UT_PlotMoveLocation(location lTarget,int nRun = FALSE);
//perform a skill check
int UT_SkillCheck(int iDC, int iSkill, object oTarget);
//test whether force power is dark side
int UT_IsDarkSidePower(int iSpellID);
//Creates an object at a location without having to pass back an object.  Can be
//used in DelayCommand functions.
void UT_CreateObject(int nObjectType, string sTemplate, location lLocal);
//Command used in the swoop droid triggers to activate the spawning in of messengers.
void UT_SpawnMessenger();
//Makes the NPC flee to an SW_EXIT waypoint and destroy itself
void UT_ExitArea(int nRun = FALSE);
//Determines the number of spikes or parts to take away from the PC.
int UT_DeterminesItemCost(int nDC, int nSkill);
//Remove a number of computer spikes.
void UT_RemoveComputerSpikes(int nNumber);
//Remove a number of parts
void UT_RemoveRepairParts(int nNumber);
//Return items amounts for either the Spikes or the Parts
int UT_ReturnSpikePartAmount(int nSkill);
//Searches the area and changes all turrets with the specified tag to the neutral faction
void UT_MakeNeutral(string sObjectTag);
//Searches the area and changes all droids with the specified tag to the insane faction
void UT_MakeInsane(string sObjectTag);
//Searches through the ara and stuns all droids with the given tag permanently
void UT_StunDroids(string sObjectTag);
//Starts a fight
void UT_StartCombat(object oObject);
//Releases gas into the room and kills all biologicals in the specified radius
//The radius should be between 2 - 5m
void UT_GasRoom(string sWayTag, float fDistance, int bIndiscriminant = TRUE);
//Overloads a power conduit and does 10d6 damage to all within the specified radius
//bIndiscriminant: TRUE-affects all creatures; FALSE-affects only enemies
void UT_OverloadConduit(string sObjectTag, float fDistance, int bIndiscriminant = TRUE);
//Returns a creature to the nearest "wp_" waypoint.
//During this time the creature will be uncommanable
void UT_ReturnToBase(string sTag = "wp_homebase");
//NPC initiates a conversation with the player.
void UT_NPC_InitConversation(string sNPCTag,string sDlg = "",object oEntered = OBJECT_INVALID);
//Sets the Journal entry for the starmap automatically.
void UT_SetStarmapJournal();
//Creates number of creatures with a specific template at a specified waypoint tag.
//Total is the number times the loop will run.
//fTimeDelay is the number seconds between iterations.
//nSpawnIncrement is the number of templates spawned in per iteration.
void UT_RunCombatEncounter(string sTemplate, string sTag, int nTotal = 3, float fTimeDelay = 1.5, int nSpawnIncrement = 1);
//Sets the talik to flag on all objects with the specified tag using the PC as a focal point.
void UT_SetTalkToFlagByTag(string sTag);
//Locks any other doors with the same tag.  Makes them plot.
void UT_LockDoorDuplicates(string sTag);
//Check to see if the Party member specified is in the party and within the distance given.
int UT_CheckCanPartyMemberInterject(int nNPC_Constant, float fDistance);
//Reinitializes the Party Planet Initialization Variables
void UT_ReinitializePartyPlanetVariables();
//Teleport a party member
void UT_TeleportPartyMember(object oPartyMember, location lDest);
//Returns true if oTarget is the object of interest of an attacker
int UT_GetUnderAttack(object oTarget);
//Teleport the whole party and face them the direction that the objects they
//are being jumped to are facing.
void UT_TeleportWholeParty(object oWP0, object oWP1, object oWP2);
//Pause and restart a conversation.
void UT_ActionPauseConversation(float fDelay);
//Spawn NPC without return
void UT_SpawnAvailableNPC(int nNPC, location lWay);
//Goes through the current party and heals them.
void UT_HealParty();
//Heals the object passed in.
void UT_HealNPC(object oNPC);
//Heals all of the Party NPCs in Area
void UT_HealAllPartyNPCs();
//This function removes party members. It stores the npc constants of the removed party members.
void UT_StoreParty();
//This function restore party members. It will only restore party members removed via the UT_StoreParty funcion
void UT_RestoreParty();
//Returns the NPC code for the given object if it is a NPC, otherwise it returns -1
int UT_GetNPCCode(object oNPC);
//restores all party mambers to 1 hp if tempoarily dead
void UT_RestorePartyToOneHealth();
//Alter the stack size of a given item
void UT_AlterItemStack(object oItem,int iNum = 1,int bDecrement = TRUE);
//Goes through the party and removes them. This is best used on Module Load when the object are not actually created yet.
void UT_ClearAllPartyMembers();
//Does a DC check just using an ability score
int UT_AbilityCheck(int iDC, int iAbility, object oTarget);
//Validate a jump back to the last location by comparing module names.
int UT_ValidateJump(string sLastModule);
//Make alignment change based on a constant passed in to the function
void UT_AdjustCharacterAlignment(object oTarget, int nScale);
// Added by Peter T. 17/03/03
// Searches the area and changes all instances with the specified tag to the Neutral faction
void UT_MakeNeutral2(string sObjectTag);
// Added by Peter T. 17/03/03
// Searches the area and changes all instances with the specified tag to the Hostile_1 faction
void UT_MakeHostile1(string sObjectTag);
// Added by Peter T. 17/03/03
// Searches the area and changes all instances with the specified tag to the Friendly_1 faction
void UT_MakeFriendly1(string sObjectTag);
// Added by Peter T. 17/03/03
// Searches the area and changes all instances with the specified tag to the Friendly_2 faction
void UT_MakeFriendly2(string sObjectTag);
//performs a standard torture cage effect
void UT_ActivateTortureCage(object oCage, object oTarget,float fDuration);
//Makes the animal face the PC, do its victory and play a sound passed in.
//Should be used in conjunction with the k_def_interact spawn in
void UT_DoAmbientReaction(string sSound);
//STAR MAP FUNCTION SET
//Advances K_STAR_MAP, sets the journal and sets the talk to flag.
void UT_StarMap1VariableSet();
//Plays the animations necessary for the current state of the starmap variable
void UT_StarMap2PlayAnimation();
//Returns the appropriate animation loop for the Star Map
int UT_StarMap3GetLoopAnim(int nStarMapVar);
//Runs the entire Starmap sequence as a black box with no extra scripting required.
void UT_StarMap4RunStarMap();
///////////////////////////////////////////////////////////////////////////////
/*
    AutoDC
Relation to Max Persuade   Low Persaude chance   Mid Persuade chance   High Persuade chance
Higher than Max                  100                   100                     100
75% to 100%                      100                   100                     75
50% to 75%                       75                    50                      25
25% to 50%                       50                    25                      0
0% to 25%                        25                    0                       0
*/
///////////////////////////////////////////////////////////////////////////////
//  Returns a pass value based on the object's level and the suggested DC
// December 20 2001: Changed so that the difficulty is determined by the
// NPC's Hit Dice
///////////////////////////////////////////////////////////////////////////////
//  Created By: Preston Watamaniuk
///////////////////////////////////////////////////////////////////////////////
int AutoDC(int DC, int nSkill, object oTarget)
{
    int nSkillLvl = GetSkillRank(nSkill, oTarget);
    int nMax;
    int nRoll = d100();
    nMax = GetHitDice(oTarget) + 5;
    float fMax = IntToFloat(nMax);
    float fSkillLvl = IntToFloat(nSkillLvl);
    float fPercent = fSkillLvl/fMax;
    AurPostString("Skill Percentage Chance = " + FloatToString(fPercent,4,2),5,5,3.0);
    AurPostString("Percentage Die Roll     = " + IntToString(nRoll),5,7,3.0);
    if(fPercent <= 0.25)
    {
        if(DC == 0 && nRoll <= 40){return TRUE;}
    }
    else if(fPercent > 0.25 && fPercent <= 0.5)
    {
        if(DC == 0 && nRoll <= 50){return TRUE;}
        if(DC == 1 && nRoll <= 25){return TRUE;}
    }
    else if(fPercent > 0.5 && fPercent <= 0.75)
    {
        if(DC == 0 && nRoll <= 75){return TRUE;}
        if(DC == 1 && nRoll <= 50){return TRUE;}
        if(DC == 2 && nRoll <= 25){return TRUE;}
    }
    else if(fPercent > 0.75 && fPercent <= 1.0)
    {
        if(DC == 0 && nRoll <= 100){return TRUE;}
        if(DC == 1 && nRoll <= 100){return TRUE;}
        if(DC == 2 && nRoll <= 75){return TRUE;}
    }
    else if(fPercent > 1.0)
    {
        return TRUE;
    }
    return FALSE;
    //LEGACY CODE CHANGED ON FEB 18, 2003
    /*
    Easy = Lvl/4 ...rounded up
    Moderate = 3/Lvl + Lvl ...rounded up
    Difficult = Lvl * 1.5 + 6 ...rounded up
    int nLevel = GetHitDice(OBJECT_SELF);
    if(nLevel <= 0 || nLevel > 20)
    {
        nLevel = GetHitDice(GetPCSpeaker());
    }
    int nTest = 0;
    switch (DC)
    {
    case 0: nTest = nLevel / 4 + 1; break;
        // * minor tweak to lower the values a little
    case 1: nTest = (3 / nLevel + nLevel) - abs( (nLevel/2) -2); break;
    case 2: nTest = FloatToInt(nLevel * 1.5 + 6) - abs( ( FloatToInt(nLevel/1.5) -2));   break;
    }
    //SpeakString(IntToString(nTest));
    // * Roll d20 + skill rank vs. DC + 10
    if (GetSkillRank(nSkill, oTarget) + d20() >= nTest + 10)
    {
       return TRUE;
    }
       return FALSE;
    */
}
//::///////////////////////////////////////////////
//:: IsCharismaHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for high charisma
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsCharismaHigh()
{
  if (GetAbilityScore(GetPCSpeaker(),ABILITY_CHARISMA) >= 15)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
//::///////////////////////////////////////////////
//:: IsCharismaLow
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for low charisma
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsCharismaLow()
{
  return !IsCharismaNormal();
}
//::///////////////////////////////////////////////
//:: IsCharismaNormal
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for normal charisma
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsCharismaNormal()
{
  if (GetAbilityScore(GetPCSpeaker(),ABILITY_CHARISMA) >= 10)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
//::///////////////////////////////////////////////
//:: IsIntelligenceHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for high intelligence
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsIntelligenceHigh()
{
  if (GetAbilityScore(GetPCSpeaker(),ABILITY_INTELLIGENCE) >= 15)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
//::///////////////////////////////////////////////
//:: IsIntelligenceLow
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for low intelligence
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsIntelligenceLow()
{
  return !IsIntelligenceNormal();
}
//::///////////////////////////////////////////////
//:: IsIntelligenceNormal
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for normal intelligence
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsIntelligenceNormal()
{
  if (GetAbilityScore(GetPCSpeaker(),ABILITY_INTELLIGENCE) >= 10)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
//::///////////////////////////////////////////////
//:: IsDarkHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is very dark side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsDarkHigh()
{
    int align = GetGoodEvilValue(GetPCSpeaker());
    if(align >= 0 && align < 20)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsDarkLow
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is just a little dark side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsDarkLow()
{
    int align = GetGoodEvilValue(GetPCSpeaker());
    if(align >= 20 && align < 40)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsDark
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is dark side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsDark()
{
    if(IsDarkLow() || IsDarkHigh())
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsLightHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is very light side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsLightHigh()
{
    int align = GetGoodEvilValue(GetPCSpeaker());
    if(align >= 81)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsLightLow
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is slightly light side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsLightLow()
{
    int align = GetGoodEvilValue(GetPCSpeaker());
    if(align >= 61 && align < 81)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsLight
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is light side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsLight()
{
    if(IsLightLow() || IsLightHigh())
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsNeutral
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is neutral
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsNeutral()
{
    if(!IsDark() && !IsLight())
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: PadString
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  pads a string with the given pad character to the specified length
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 20, 2002
//:://////////////////////////////////////////////
string PadString(string str = "",string pad = " ",int length = 0)
{
  while(GetStringLength(str) < length)
  {
    str = pad + str;
  }
  return(str);
}
//::///////////////////////////////////////////////
//:: TalkToPC
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  causes the given object to initiate conversation with the player
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  July 12, 2002
//:://////////////////////////////////////////////
void TalkToPC(object oSpeaker)
{
  AssignCommand(oSpeaker,ClearAllActions());
  AssignCommand(oSpeaker,
  ActionStartConversation(GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC)));
}
//::///////////////////////////////////////////////
//:: Get Boolean Plot Flag
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets the boolean state of a plot bit field
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
int UT_GetPlotBooleanFlag(object oTarget, int nIndex)
{
    int nPlotBoolean;
    if(nIndex >= 0 && nIndex <= 19 && GetIsObjectValid(oTarget))
    {
        nPlotBoolean = GetLocalBoolean(oTarget, nIndex);
        if(nPlotBoolean > 0)
        {
            return TRUE;
        }
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Set Boolean Plot Flag
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the boolean state of a plot bit field
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
void UT_SetPlotBooleanFlag(object oTarget, int nIndex, int nState)
{
    int nLevel = GetHitDice(GetFirstPC());
    if(nState == TRUE)
    {
        if(nIndex == SW_PLOT_COMPUTER_OPEN_DOORS ||
           nIndex == SW_PLOT_REPAIR_WEAPONS ||
           nIndex == SW_PLOT_REPAIR_TARGETING_COMPUTER ||
           nIndex == SW_PLOT_REPAIR_SHIELDS)
        {
            GiveXPToCreature(GetFirstPC(), nLevel * 15);
        }
        else if(nIndex == SW_PLOT_COMPUTER_USE_GAS || nIndex == SW_PLOT_REPAIR_ACTIVATE_PATROL_ROUTE || nIndex == SW_PLOT_COMPUTER_MODIFY_DROID)
        {
            GiveXPToCreature(GetFirstPC(), nLevel * 20);
        }
        else if(nIndex == SW_PLOT_COMPUTER_DEACTIVATE_TURRETS ||
                nIndex == SW_PLOT_COMPUTER_DEACTIVATE_DROIDS)
        {
            GiveXPToCreature(GetFirstPC(), nLevel * 10);
        }
    }
    if(nIndex >= 0 && nIndex <= 19 && GetIsObjectValid(oTarget))
    {
        if(nState == TRUE || nState == FALSE)
        {
            SetLocalBoolean(oTarget, nIndex, nState);
        }
    }
}
//::///////////////////////////////////////////////
//:: Get Talked To Flag
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the state of the Talk to Flag
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
int UT_GetTalkedToBooleanFlag(object oTarget)
{
    int nPlotFlag;
    if(GetIsObjectValid(oTarget))
    {
        nPlotFlag = GetLocalBoolean(oTarget, SW_PLOT_HAS_TALKED_TO);
        if(nPlotFlag > 0)
        {
            return TRUE;
        }
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Set Talked To Flag
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the talked to flag to the given state.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
void UT_SetTalkedToBooleanFlag(object oTarget, int nState = TRUE)
{
    if(GetIsObjectValid(oTarget))
    {
        if(nState == TRUE || nState == FALSE)
        {
            SetLocalBoolean(oTarget, SW_PLOT_HAS_TALKED_TO, nState);
        }
    }
}
//::///////////////////////////////////////////////
//:: UT_GetNearestPCToObject
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//Get the nearest PC to the specified object
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
object UT_GetNearestPCToObject(object oTarget = OBJECT_SELF)
{
  return(GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC,oTarget));
}
//::///////////////////////////////////////////////
//:: UT_IsObjectPC
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//Determine if object is a PC
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
int UT_IsObjectPC(object oTarget = OBJECT_INVALID)
{
  object oPC = GetFirstPC();
  while(oPC != OBJECT_INVALID)
  {
    if(oTarget == oPC)
    {
      return(TRUE);
    }
    oPC = GetNextPC();
  }
  return(FALSE);
}
//::///////////////////////////////////////////////
//:: Adjust Character Alignment
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Make alignment change based on a constant
    passed in to the function
    nDarkSide = 1 then do a darkside hit.
    nScale is the size of the hit. -3 to +3
    //Alignment Adjustment Constants
    int SW_CONSTANT_DARK_HIT_HIGH = -6;
    int SW_CONSTANT_DARK_HIT_MEDIUM = -5;
    int SW_CONSTANT_DARK_HIT_LOW = -4;
    int SW_CONSTANT_LIGHT_HIT_LOW = -2;
    int SW_CONSTANT_LIGHT_HIT_MEDIUM = -1;
    int SW_CONSTANT_LIGHT_HIT_HIGH = 0;
                    1       2       3         4      5
                    VLight  Light   Neutral   Dark   VDark
      High Light    2       4       6         8      10
      Mid Light     1       2       4         6      8
      Low Light     1       1       2         4      6
      Low Dark      -6      -4      -2        -1     -1
      Mid Dark      -8      -6      -4        -2     -1
      High Dark     -10     -8      -6        -4     -2
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 23, 2002
//:://////////////////////////////////////////////
void UT_AdjustCharacterAlignment(object oTarget, int nScale)
{
    //Find out if the target is good or evil
    int nScore = GetGoodEvilValue(oTarget);
    int nAlignType;
    //Set the type of alignment hit to do.
    if(nScale == SW_CONSTANT_DARK_HIT_HIGH ||
       nScale == SW_CONSTANT_DARK_HIT_MEDIUM ||
       nScale == SW_CONSTANT_DARK_HIT_LOW)
    {
        nAlignType = ALIGNMENT_DARK_SIDE;
    }
    else
    {
        nAlignType = ALIGNMENT_LIGHT_SIDE;
    }
    int nHit;
    int nAlignCategory;
    //Set the alignment category which will determine the base from which to calculate the hit.
    if(nScore >= 85)//VERY GOOD
    {
        nAlignCategory = 1;
    }
    else if(nScore < 85 && nScore > 60)//GOOD
    {
        nAlignCategory = 2;
    }
    else if(nScore <= 60 && nScore >= 40)//NEUTRAL
    {
        nAlignCategory = 3;
    }
    else if(nScore < 40 && nScore >= 15)//EVIL
    {
        nAlignCategory = 4;
    }
    else //VERY EVIL
    {
        nAlignCategory = 5;
    }
    //Calculate the hit.
    nHit = (nAlignCategory + nScale) * 2;
    if(nHit < 0)
    {
        nHit = nHit * -1;
    }
    if(nHit == 0)
    {
        nHit = 1;
    }
    //Zero results that do not mathematically fit within the formula.
    if(nAlignCategory == 1 && nScale == SW_CONSTANT_LIGHT_HIT_LOW)
    {
        nHit = 1;
    }
    else if(nAlignCategory == 5 && nScale == SW_CONSTANT_DARK_HIT_LOW)
    {
        nHit = 1;
    }
    AurPostString("Hit = " + IntToString(nHit), 5, 5, 4.0);
    AdjustAlignment(oTarget, nAlignType, nHit);
}
//::///////////////////////////////////////////////
//:: UT_DarkHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a heavy darkside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_DarkHigh(object oTarget)
{
    UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_DARK_HIT_HIGH);
    //AdjustAlignment(oTarget,ALIGNMENT_DARK_SIDE,10);
}
//::///////////////////////////////////////////////
//:: UT_DarkMed
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a medium darkside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_DarkMed(object oTarget)
{
  UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_DARK_HIT_MEDIUM);
  //AdjustAlignment(oTarget,ALIGNMENT_DARK_SIDE,5);
}
//::///////////////////////////////////////////////
//:: UT_DarkSml
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a small darkside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_DarkSml(object oTarget)
{
  UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_DARK_HIT_LOW);
  //AdjustAlignment(oTarget,ALIGNMENT_DARK_SIDE,1);
}
//::///////////////////////////////////////////////
//:: UT_LightHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a heavy lightside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_LightHigh(object oTarget)
{
  UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_LIGHT_HIT_HIGH);
  //AdjustAlignment(oTarget,ALIGNMENT_LIGHT_SIDE,10);
}
//::///////////////////////////////////////////////
//:: UT_LightMed
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a medium lightside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_LightMed(object oTarget)
{
  UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_LIGHT_HIT_MEDIUM);
  //AdjustAlignment(oTarget,ALIGNMENT_LIGHT_SIDE,5);
}
//::///////////////////////////////////////////////
//:: UT_LightSml
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a small lightside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_LightSml(object oTarget)
{
  UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_LIGHT_HIT_LOW);
  //AdjustAlignment(oTarget,ALIGNMENT_LIGHT_SIDE,1);
}
//::///////////////////////////////////////////////
//:: Reset Plot Booleans
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Goes through all of the plot bit fields and sets
    them to nState.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 15, 2002
//:://////////////////////////////////////////////
void UT_ResetPlotBooleanFlags(object oToChange, int nState)
{
    int nCnt;
    for(nCnt; nCnt <= 9; nCnt++)
    {
        if(nState == TRUE || nState == FALSE)
        {
            SetLocalBoolean(oToChange, nCnt, nState);
        }
    }
}
//::///////////////////////////////////////////////
//:: Check Manaan Medical State
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns true if the manaan facilities have
    been destroyed.  Global = 4 returns true.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 19, 2002
//:://////////////////////////////////////////////
int UT_GetIsKoltoDestroyed()
{
    return GetGlobalNumber("MAN_PLANET_PLOT") == 4;
}
//::///////////////////////////////////////////////
//:: UT_PlotMovePath
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make object do an uninterruptible path move
//based on code done by Aidan (actually, pretty much a copy)
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 16, 2002
//:://////////////////////////////////////////////
void UT_PlotMovePath(string sWayPointTag,int nFirst, int nLast, int nRun = FALSE)
{
    int nInc = 1;
    object oWP;
    int nIdx;
    if(nFirst > nLast)
    {
        nInc = -1;
    }
    for(nIdx = nFirst - nInc; abs(nLast - nIdx) > 0 && abs(nLast - nIdx) <= abs((nLast - nFirst) + 1); nIdx = nIdx + nInc)
    {
        oWP = GetObjectByTag(sWayPointTag + IntToString(nIdx + nInc));
        if(GetIsObjectValid(oWP))
        {
            ActionForceMoveToObject(oWP,nRun);
        }
    }
    ActionDoCommand(SetCommandable(TRUE));
    SetCommandable(FALSE);
}
//::///////////////////////////////////////////////
//:: UT_PlotMoveObject
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make object do an uninterruptible move to an object
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 16, 2002
//:://////////////////////////////////////////////
void UT_PlotMoveObject(object oTarget,int nRun = FALSE)
{
  ActionForceMoveToObject(oTarget,nRun);
  ActionDoCommand(SetCommandable(TRUE));
  SetCommandable(FALSE);
}
//::///////////////////////////////////////////////
//:: UT_PlotMoveLocation
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make object do an uninterruptible move to a location
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 16, 2002
//:://////////////////////////////////////////////
void UT_PlotMoveLocation(location lTarget,int nRun = FALSE)
{
  ActionForceMoveToLocation(lTarget,nRun);
  ActionDoCommand(SetCommandable(TRUE));
  SetCommandable(FALSE);
}
//::///////////////////////////////////////////////
//:: UT_SkillCheck
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//perform a skill check using a given DC
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 29, 2002
//:://////////////////////////////////////////////
int UT_SkillCheck(int iDC, int iSkill, object oTarget)
{
  if (GetSkillRank(iSkill, oTarget) + d20() >= iDC)
  {
    return TRUE;
  }
  return FALSE;
}
//::///////////////////////////////////////////////
//:: UT_IsDarkSidePower
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//test whether force power is dark side
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Sept. 11, 2002
//:://////////////////////////////////////////////
int UT_IsDarkSidePower(int iSpellID)
{
  if(iSpellID == FORCE_POWER_AFFECT_MIND) return(FALSE);
  if(iSpellID == FORCE_POWER_AFFLICTION) return(TRUE);
  if(iSpellID == FORCE_POWER_CHOKE) return(TRUE);
  if(iSpellID == FORCE_POWER_CURE) return(FALSE);
  if(iSpellID == FORCE_POWER_DEATH_FIELD) return(TRUE);
  if(iSpellID == FORCE_POWER_DOMINATE) return(TRUE);
  if(iSpellID == FORCE_POWER_DRAIN_LIFE) return(TRUE);
  if(iSpellID == FORCE_POWER_DROID_DESTROY) return(FALSE);
  if(iSpellID == FORCE_POWER_DROID_DISABLE) return(FALSE);
  if(iSpellID == FORCE_POWER_DROID_STUN) return(FALSE);
  if(iSpellID == FORCE_POWER_FEAR) return(TRUE);
  if(iSpellID == FORCE_POWER_FORCE_ARMOR) return(FALSE);
  if(iSpellID == FORCE_POWER_FORCE_AURA) return(FALSE);
  if(iSpellID == FORCE_POWER_FORCE_BREACH) return(FALSE);
  if(iSpellID == FORCE_POWER_FORCE_IMMUNITY) return(FALSE);
  if(iSpellID == FORCE_POWER_FORCE_JUMP) return(FALSE);
  if(iSpellID == FORCE_POWER_FORCE_JUMP_ADVANCED) return(FALSE);
  if(iSpellID == FORCE_POWER_FORCE_MIND) return(TRUE);
  if(iSpellID == FORCE_POWER_FORCE_PUSH) return(FALSE);
  if(iSpellID == FORCE_POWER_FORCE_SHIELD) return(FALSE);
  if(iSpellID == FORCE_POWER_FORCE_STORM) return(TRUE);
  if(iSpellID == FORCE_POWER_FORCE_WAVE) return(FALSE);
  if(iSpellID == FORCE_POWER_FORCE_WHIRLWIND) return(FALSE);
  if(iSpellID == FORCE_POWER_HOLD) return(FALSE);
  if(iSpellID == FORCE_POWER_HORROR) return(TRUE);
  if(iSpellID == FORCE_POWER_INSANITY) return(TRUE);
  if(iSpellID == FORCE_POWER_KILL) return(TRUE);
  if(iSpellID == FORCE_POWER_KNIGHT_SPEED) return(FALSE);
  if(iSpellID == FORCE_POWER_LIGHT_SABER_THROW) return(FALSE);
  if(iSpellID == FORCE_POWER_LIGHT_SABER_THROW_ADVANCED) return(FALSE);
  if(iSpellID == FORCE_POWER_LIGHTNING) return(TRUE);
  if(iSpellID == FORCE_POWER_MASTER_CONTROL) return(FALSE);
  if(iSpellID == FORCE_POWER_MASTER_SENSE) return(FALSE);
  if(iSpellID == FORCE_POWER_MIND_MASTERY) return(FALSE);
  if(iSpellID == FORCE_POWER_PLAGUE) return(FALSE);
  if(iSpellID == FORCE_POWER_REGENERATION) return(FALSE);
  if(iSpellID == FORCE_POWER_REGNERATION_ADVANCED) return(FALSE);
  if(iSpellID == FORCE_POWER_RESIST_COLD_HEAT_ENERGY) return(FALSE);
  if(iSpellID == FORCE_POWER_RESIST_FORCE) return(FALSE);
  if(iSpellID == FORCE_POWER_RESIST_POISON_DISEASE_SONIC) return(FALSE);
  if(iSpellID == FORCE_POWER_SHOCK) return(TRUE);
  if(iSpellID == FORCE_POWER_SLEEP) return(FALSE);
  if(iSpellID == FORCE_POWER_SLOW) return(FALSE);
  if(iSpellID == FORCE_POWER_SPEED_BURST) return(FALSE);
  if(iSpellID == FORCE_POWER_SPEED_MASTERY) return(FALSE);
  if(iSpellID == FORCE_POWER_STUN) return(FALSE);
  if(iSpellID == FORCE_POWER_SUPRESS_FORCE) return(FALSE);
  if(iSpellID == FORCE_POWER_WOUND) return(TRUE);
  return(FALSE);
}
//::///////////////////////////////////////////////
//:: UT_CreateObject
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Create an object without needing a variable
    to pass it into.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Sept. 21, 2002
//:://////////////////////////////////////////////
void UT_CreateObject(int nObjectType, string sTemplate, location lLocal)
{
    object oCreate = CreateObject(nObjectType, sTemplate, lLocal);
}
//::///////////////////////////////////////////////
//:: UT_JumpPartyToObject
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Move the entire party to the object specified.
*/
//:://////////////////////////////////////////////
//:: Created By: John Winski
//:: Created On: Sept. 24, 2002
//:://////////////////////////////////////////////
void UT_JumpPartyToObject(object oTarget)
{
    UT_RestorePartyToOneHealth();
    object oMember1 = GetPartyMemberByIndex(0);
    object oMember2 = GetPartyMemberByIndex(1);
    object oMember3 = GetPartyMemberByIndex(2);
    if (GetIsObjectValid(oMember1) == TRUE)
    {
        AssignCommand(oMember1, ClearAllActions());
        AssignCommand(oMember1, JumpToObject(oTarget));
    }
    if (GetIsObjectValid(oMember2) == TRUE)
    {
        AssignCommand(oMember2, ClearAllActions());
        AssignCommand(oMember2, JumpToObject(oTarget));
    }
    if (GetIsObjectValid(oMember2) == TRUE)
    {
        AssignCommand(oMember3, ClearAllActions());
        AssignCommand(oMember3, JumpToObject(oTarget));
    }
}
//::///////////////////////////////////////////////
//:: UT_JumpPartyToLocation
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Move the entire party to the location specified.
*/
//:://////////////////////////////////////////////
//:: Created By: John Winski
//:: Created On: Sept. 24, 2002
//:://////////////////////////////////////////////
void UT_JumpPartyToLocation(location lTarget)
{
    object oMember1 = GetPartyMemberByIndex(0);
    object oMember2 = GetPartyMemberByIndex(1);
    object oMember3 = GetPartyMemberByIndex(2);
    UT_RestorePartyToOneHealth();
    if (GetIsObjectValid(oMember1) == TRUE)
    {
        AssignCommand(oMember1, ClearAllActions());
        AssignCommand(oMember1, JumpToLocation(lTarget));
    }
    if (GetIsObjectValid(oMember2) == TRUE)
    {
        AssignCommand(oMember2, ClearAllActions());
        AssignCommand(oMember2, JumpToLocation(lTarget));
    }
    if (GetIsObjectValid(oMember2) == TRUE)
    {
        AssignCommand(oMember3, ClearAllActions());
        AssignCommand(oMember3, JumpToLocation(lTarget));
    }
}
//::///////////////////////////////////////////////
//:: Spawn Messenger
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Determines which messenger to spawn in for a specific planet.
    Uses the waypoint K_MESSENGER_SPAWN to determine where to place an incoming messenger
    Carth: KOR_DANEL == 1. Messenger = Jordo.
    Bastila: K_SWG_HELENA == 1. Messenger = Malare.
    Mission: Mis_MissionTalk == 5  Messenger = Lena
    Canderous: G_CAND_STATE == 8, G_CAND_PLOT == 0, K_CURRENT_PLANET != 35.  Messenger = Jagi
    Juhani: G_JUHANIH_STATE == 7, G_JUHANI_PLOT == 0. Messenger = Xor
    Endar Spire     5
    Taris           10
    Dantooine       15
    --Kashyyk       20
    --Manaan        25
    --Korriban      30
    --Tatooine      35
    Leviathan       40
    Unknown World   45
    Star Forge      50
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Sept 26, 2002
//:://////////////////////////////////////////////
void UT_SpawnMessenger()
{
    object oPC = GetFirstPC();
    object oWay = GetWaypointByTag("K_MESSENGER_SPAWN");
    object oNPC;
    int nGlobal_1, nGlobal_2;
    location lLocal;
    int bConditional = FALSE;
    int nXor = GetGlobalNumber("K_XOR_AMBUSH");
    //Do not fire any messenger plots on Kashyyyk if Chuundar is dead
    if(GetGlobalNumber("K_CURRENT_PLANET") == 20)
    {
        bConditional = GetGlobalBoolean("kas_ChuundarDead");
    }
    if(bConditional == FALSE)
    {
        if(nXor == 0 || nXor > 2)
        {
            if(GetIsObjectValid(oWay))
            {
                lLocal = GetLocation(oWay);
                //MODIFIED by Preston Watamaniuk on April 11
                //Added the exchange crony Ziagrom to tell the PC about the special store.
                if(GetGlobalNumber("K_KOTOR_MASTER") >= 20 &&
                   GetGlobalNumber("K_Exchange_Store") == 0 &&
                   GetGlobalBoolean("K_MESS_ZIAGROM") == FALSE)
                {
                    SetGlobalBoolean("K_MESS_ZIAGROM", TRUE);
                    oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_Ziagrom", lLocal);
                    NoClicksFor(2.2);
                    DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                    return;
                }
                if(IsNPCPartyMember(NPC_BASTILA) &&
                   GetGlobalBoolean("K_MESS_BASTILA") == FALSE &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 25 &&
                   GetGlobalNumber("K_SWG_HELENA") == 1)
                {
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_BASTILA", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_malare", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
                if(IsNPCPartyMember(NPC_CARTH) &&
                   //MODIFIED by Preston Watamaniuk on May 13, 2003
                   //Added a check to make sure the Sith Acadamy is not closed before spawning in Jordo.
                   GetGlobalBoolean("KOR_END_HOSTILE") == FALSE &&
                   GetGlobalBoolean("K_MESS_CARTH") == FALSE &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 30 &&
                   GetGlobalNumber("KOR_DANEL") == 1)
                {
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_CARTH", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_jordo", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
                if(IsNPCPartyMember(NPC_JOLEE) &&
                   GetGlobalBoolean("K_MESS_JOLEE") == FALSE &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 25 &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 20 &&
                   GetGlobalNumber("MAN_MURDER_PLOT") == 0)
                {
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_JOLEE", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_davink", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
                if(IsNPCPartyMember(NPC_JUHANI) &&
                   GetGlobalBoolean("K_MESS_JUHANI") == FALSE &&
                   (GetGlobalNumber("G_JUHANIH_STATE") > 5 && GetGlobalNumber("G_JUHANIP_STATE") < 10) &&
                   GetGlobalNumber("G_JUHANI_PLOT") == 0 &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 15)
                {
                        //juhanih_state > 5, and juhanip_state < 10
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_JUHANI", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_xor", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
                if(IsNPCPartyMember(NPC_CANDEROUS) &&
                   GetGlobalBoolean("K_MESS_CANDEROUS") == FALSE &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 35 &&
                   GetGlobalNumber("G_CAND_STATE") >= 6 &&
                   GetGlobalBoolean("G_CAND_THING") == TRUE &&
                   GetGlobalNumber("G_CAND_PLOT") == 0)
                {
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_CANDEROUS", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_jagi", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
                if(IsNPCPartyMember(NPC_MISSION) &&
                   GetGlobalBoolean("K_MESS_MISSION") == FALSE &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 35 &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 25 &&
                   GetGlobalNumber("Mis_MissionTalk") == 5)
                {
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_MISSION", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_lena", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
            }
        }
    }
}
//::///////////////////////////////////////////////
//:: Exit Area
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    The NPC moves to an SW_EXIT waypoint and destroys
    itself.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Sept 27, 2002
//:://////////////////////////////////////////////
void UT_ExitArea(int nRun = FALSE)
{
    object oExit = GetWaypointByTag("SW_EXIT");
    object oExit2 = GetWaypointByTag("K_EXIT");
    if(GetIsObjectValid(oExit) && GetIsObjectValid(oExit2))
    {
        if(GetDistanceBetween(OBJECT_SELF, oExit) > GetDistanceBetween(OBJECT_SELF, oExit2))
        {
            oExit = oExit2;
        }
    }
    else if(GetIsObjectValid(oExit2) && !GetIsObjectValid(oExit))
    {
        oExit = oExit2;
    }
    ActionForceMoveToObject(oExit, nRun);
    ActionDoCommand(SetCommandable(TRUE));
    ActionDoCommand(DestroyObject(OBJECT_SELF));
    SetCommandable(FALSE);
}
//::///////////////////////////////////////////////
//:: UT_GetNumItems
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Counts the number of items with the given tag
    in the party inventory.
*/
//:://////////////////////////////////////////////
//:: Created By: John Winski
//:: Created On: October 15, 2002
//:://////////////////////////////////////////////
int UT_GetNumItems(object oTarget, string sItemTag)
{
    int nCount = 0;
    object oItem = GetFirstItemInInventory(oTarget);
    while (GetIsObjectValid(oItem) == TRUE)
    {
        if (GetTag(oItem) == sItemTag)
        {
            nCount = nCount + 1;
        }
        oItem = GetNextItemInInventory(oTarget);
    }
    return nCount;
}
//::///////////////////////////////////////////////
//:: Determines Item Cost
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a value for how many parts or spikes
    a given dialogue option will cost.  The costs
    are as follows:
    Computer Use
    1.  Open all doors in area (cost: 3 spikes). The player can open all doors on the level.
    2.  Open all containers in area (cost: 3 spikes). The player can open all containers on the level.
    3.  Fill security room with gas (cost: 5 spikes).
    4.  Turn off all gun turrets (cost: 8 spikes).
    5.  Modify droid programming; target everything (cost: 10 spikes).
    6.  Deactivate all droids in area (cost: 8 spikes).
    Repair Use
    1.  Activate droid. Hostile to Sith faction. (cost: 3 repair unit)
    2.  Activate droid. Hostile to Sith faction. Enter patrol route. (cost: 5 repair unit)
    3.  Activate droid. Hostile to Sith faction. Hunter Killer mode. (cost: 7 repair unit)
    4.  Activate droid. Hostile to Sith faction. Follow mode. (cost: 5 repair unit)
*/
//:://////////////////////////////////////////////
//:: Created By: PReston Watamaniuk
//:: Created On: Nov 19, 2002
//:://////////////////////////////////////////////
int UT_DeterminesItemCost(int nDC, int nSkill)
{
        //AurPostString("DC " + IntToString(nDC), 5, 5, 3.0);
    float fModSkill =  IntToFloat(GetSkillRank(nSkill, GetPartyMemberByIndex(0)));
        //AurPostString("Skill Total " + IntToString(GetSkillRank(nSkill, GetPartyMemberByIndex(0))), 5, 6, 3.0);
    int nUse;
    fModSkill = fModSkill/4.0;
    nUse = nDC - FloatToInt(fModSkill);
        //AurPostString("nUse Raw " + IntToString(nUse), 5, 7, 3.0);
    if(nUse < 1)
    {
        //MODIFIED by Preston Watamaniuk, March 19
        //Put in a check so that those PC with a very high skill
        //could have a cost of 0 for doing computer work
        if(nUse <= -3)
        {
            nUse = 0;
        }
        else
        {
            nUse = 1;
        }
    }
        //AurPostString("nUse Final " + IntToString(nUse), 5, 8, 3.0);
    return nUse;
}
//::///////////////////////////////////////////////
//:: Remove X number of Computer Spikes
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Remove a number of computer spikes
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 19, 2002
//:://////////////////////////////////////////////
void UT_RemoveComputerSpikes(int nNumber)
{
    object oItem = GetItemPossessedBy(GetFirstPC(), "K_COMPUTER_SPIKE");
    if(GetIsObjectValid(oItem))
    {
        int nStackSize = GetItemStackSize(oItem);
        if(nNumber < nStackSize)
        {
            nNumber = nStackSize - nNumber;
            SetItemStackSize(oItem, nNumber);
        }
        else if(nNumber > nStackSize || nNumber == nStackSize)
        {
            DestroyObject(oItem);
        }
    }
}
//::///////////////////////////////////////////////
//:: Remove X number of Repair Parts
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Remove a number of repair parts
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 19, 2002
//:://////////////////////////////////////////////
void UT_RemoveRepairParts(int nNumber)
{
    object oItem = GetItemPossessedBy(GetFirstPC(), "K_REPAIR_PART");
    if(GetIsObjectValid(oItem))
    {
        int nStackSize = GetItemStackSize(oItem);
        if(nNumber < nStackSize)
        {
            nNumber = nStackSize - nNumber;
            SetItemStackSize(oItem, nNumber);
        }
        else if(nNumber > nStackSize || nNumber == nStackSize)
        {
            DestroyObject(oItem);
        }
    }
}
//::///////////////////////////////////////////////
//:: Return item amount
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Depending on the skill chosen, returns the
    number items relating to that skill
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 19, 2002
//:://////////////////////////////////////////////
int UT_ReturnSpikePartAmount(int nSkill)
{
    string sItem;
    int nCount = 0;
    if(nSkill == SKILL_COMPUTER_USE)
    {
        sItem = "K_COMPUTER_SPIKE";
    }
    else if(nSkill == SKILL_REPAIR)
    {
        sItem = "K_REPAIR_PART";
    }
    object oItem = GetItemPossessedBy(GetFirstPC(), sItem);
    if(GetIsObjectValid(oItem))
    {
        nCount = GetNumStackedItems(oItem);
    }
    return nCount;
}
//::///////////////////////////////////////////////
//:: Make Neutral
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all object with
    the specified tag to the neutral faction
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 20, 2002
//:://////////////////////////////////////////////
void UT_MakeNeutral(string sObjectTag)
{
    effect eStun = EffectDroidStun();
    int nCount = 1;
    object oDroid = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oDroid))
    {
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStun, oDroid);
        nCount++;
        oDroid = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Make Insane
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the insane faction
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 20, 2002
//:://////////////////////////////////////////////
void UT_MakeInsane(string sObjectTag)
{
    int nCount = 1;
    object oDroid = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oDroid))
    {
        ChangeToStandardFaction(oDroid, STANDARD_FACTION_INSANE);
        UT_StartCombat(oDroid);
        nCount++;
        oDroid = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Stun Droids
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the insane faction
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 20, 2002
//:://////////////////////////////////////////////
void UT_StunDroids(string sObjectTag)
{
    effect eStun = EffectDroidStun();
    int nCount = 1;
    object oDroid = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oDroid))
    {
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStun, oDroid);
        nCount++;
        oDroid = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Start a Fight
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets the nearest enemy that is seen and start combat
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 21, 2002
//:://////////////////////////////////////////////
void UT_StartCombat(object oObject)
{
    AssignCommand(oObject, ActionAttack(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oObject, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN)));
}
//::///////////////////////////////////////////////
//:: Gas a Rooom
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Releases gas into the room and kills all biologicals in the
    specified radius.  The radius should be between 2 - 5m
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 21, 2002
//:://////////////////////////////////////////////
void UT_GasRoom(string sWayTag, float fDistance, int bIndiscriminant = TRUE)
{
    object oWay = GetWaypointByTag(sWayTag);
    object oPC = GetFirstPC();
    if(GetIsObjectValid(oWay))
    {
        effect eVFX = EffectVisualEffect(3006);
        ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVFX, GetLocation(oWay));
        object oTarget = GetNearestCreature(CREATURE_TYPE_RACIAL_TYPE, RACIAL_TYPE_HUMAN, oWay, 1);
        int nCount = 1;
        while(GetIsObjectValid(oTarget) && GetDistanceBetween(oTarget, oWay) <= fDistance)
        {
            float fDelay = 3.0 + (IntToFloat(d10())/10.0);
            float fDelay2 = fDelay + 1.0 + (IntToFloat(d20())/10.0);
            if((GetIsFriend(oTarget, oPC) || GetIsNeutral(oTarget, oPC)) && bIndiscriminant == FALSE)
            {
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectChoke(), oTarget, 3.0));
                DelayCommand(fDelay2, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectPoison(POISON_ABILITY_SCORE_VIRULENT),oTarget));
            }
            else if(GetIsEnemy(oTarget, oPC) || bIndiscriminant == TRUE)
            {
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectChoke(), oTarget, 10.0));
                DelayCommand(fDelay2, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oTarget));
            }
            nCount++;
            oTarget = GetNearestCreature(CREATURE_TYPE_RACIAL_TYPE, RACIAL_TYPE_HUMAN, oWay, nCount);
        }
    }
}
//::///////////////////////////////////////////////
//:: Overload Conduit
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Overloads a power conduit and does 10d6 damage
    to all within the specified radius
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 21, 2002
//:://////////////////////////////////////////////
void UT_OverloadConduit(string sObjectTag, float fDistance, int bIndiscriminant = TRUE)
{
    object oWay = GetObjectByTag(sObjectTag);
    if(GetIsObjectValid(oWay))
    {
        effect eFNF = EffectVisualEffect(VFX_FNF_GRENADE_ION);
        effect eVFXHit = EffectVisualEffect(1021);
        effect eVFXBeam = EffectBeam(VFX_BEAM_LIGHTNING_DARK_L, oWay, BODY_NODE_CHEST);
        effect eDam;
        object oTarget = GetNearestObject(OBJECT_TYPE_CREATURE, oWay, 1);
        int nCount = 1;
        int nDam = 1000;
        float fDelay = 0.3;
        AssignCommand(oWay, ActionPlayAnimation(ANIMATION_PLACEABLE_OPEN));
        DelayCommand(0.3, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eFNF, GetLocation(oWay)));
        while(GetIsObjectValid(oTarget) && GetDistanceBetween(oTarget, oWay) <= fDistance)
        {
            if(bIndiscriminant == TRUE || GetIsEnemy(oTarget, GetFirstPC()))
            {
                eDam = EffectDamage(nDam, DAMAGE_TYPE_ELECTRICAL);
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVFXBeam, oTarget, 1.0));
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFXHit, oTarget, 1.0));
                fDelay = fDelay + 0.17;
            }
            nCount++;
            oTarget = GetNearestObject(OBJECT_TYPE_CREATURE, oWay, nCount);
        }
        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_PRO_DROID_KILL), oWay);
    }
}
///////////////////////////////////////////////////////////////////////////////
/*
    UT_ReturnToBase
    This function is used in the user defined event of a creature crossing a
    trigger used to pen in hostile creatures. When a creature crosses the
    trigger, it's actions are cleared, it is sent to the homebase waypoint and
    it is set non commanble. Once reaching its destination, it becomes
    commandable again. By defaut the standard tag for the waypoint is given, but
    a different one may be specified
    Created by Aidan Scanlan
    On Dec 2, 2002
*/
///////////////////////////////////////////////////////////////////////////////
void UT_ReturnToBase(string sTag = "wp_homebase")
{
    object oSelf = OBJECT_SELF;
    if(GetCommandable(oSelf))
    {
        ClearAllActions();
        CancelCombat(oSelf);
        ActionMoveToObject(GetNearestObjectByTag("wp_homebase"),TRUE,3.0f);
        ActionDoCommand( SetCommandable(TRUE,oSelf));
        SetCommandable(FALSE);
    }
}
//::///////////////////////////////////////////////
//:: UT_NPC_InitConversation
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    The specified NPC will start a conversation
    with the player.
*/
//:://////////////////////////////////////////////
//:: Created By: John Winski
//:: Created On: December 2, 2002
//:://////////////////////////////////////////////
void UT_NPC_InitConversation(string sNPCTag,string sDlg = "",object oEntered = OBJECT_INVALID)
{
    object oNPC = GetObjectByTag(sNPCTag);
    object oPC = GetFirstPC();
    UT_RestorePartyToOneHealth();
    // The NPC must exist.
    if (GetIsObjectValid(oNPC) == TRUE)
    {
        if (oPC == GetPartyMemberByIndex(0))
        {
            AssignCommand(oPC, ClearAllActions());
            AssignCommand(oNPC, ClearAllActions());
            CancelCombat(oPC);
            AssignCommand(oNPC, ActionStartConversation(oPC, sDlg, FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE));
        }
        else
        {
            // Fade to black, switch player control to the main character,
            // move the player to the NPC and start conversation.
            SetGlobalFadeOut();
            SetPartyLeader(NPC_PLAYER);
            object oParty1 = GetPartyMemberByIndex(1);
            object oParty2 = GetPartyMemberByIndex(2);
            //P.W. (June 7) - Put this in to terminate any player input during the fade.
            NoClicksFor(0.7);
            AssignCommand(oPC, ClearAllActions());
            AssignCommand(oNPC, ClearAllActions());
            CancelCombat(oPC);
            if (GetIsObjectValid(oEntered) == TRUE)
            {
                AssignCommand(oPC, DelayCommand(0.2, JumpToObject(oEntered)));
                AssignCommand(oPC, DelayCommand(0.4, SetFacingPoint(GetPosition(oNPC))));
            }
            else
            {
                AssignCommand(oPC, DelayCommand(0.2, JumpToObject(oNPC)));
            }
            AssignCommand(oParty1, DelayCommand(0.5, JumpToObject(oPC)));
            AssignCommand(oParty2, DelayCommand(0.5, JumpToObject(oPC)));
            AssignCommand(oNPC, ActionDoCommand(SetGlobalFadeIn(0.5, 2.0)));
            AssignCommand(oNPC, ActionStartConversation(oPC, sDlg, FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE));
        }
    }
}
//::///////////////////////////////////////////////
//:: Set Starmap Journal
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the Journal entry for the starmap
    automatically.
    Korriban - entry 10
    Tatooine - entry 20
    Kashyyyk - entry 30
    Manaan   - entry 40
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamanmiuk
//:: Created On: Dec 17, 2002
//:://////////////////////////////////////////////
void UT_SetStarmapJournal()
{
    string sModule = GetModuleFileName();
    if(sModule == "manm28ad") //Manaan
    {
        SetGlobalBoolean("K_STAR_MAP_MANAAN", TRUE);
        AddJournalQuestEntry("k_starforge", 40, TRUE);
    }
    else if(sModule == "korr_m39aa") //Korriban
    {
        SetGlobalBoolean("K_STAR_MAP_KORRIBAN", TRUE);
        AddJournalQuestEntry("k_starforge", 10, TRUE);
    }
    else if(sModule == "Kas_m25aa") //Kashyyyk
    {
        SetGlobalBoolean("K_STAR_MAP_KASHYYYK", TRUE);
        AddJournalQuestEntry("k_starforge", 30, TRUE);
    }
    else if(sModule == "Tat_m18ac") //Tatooine
    {
        SetGlobalBoolean("K_STAR_MAP_TATOOINE", TRUE);
        AddJournalQuestEntry("k_starforge", 20, TRUE);
    }
    if(GetGlobalNumber("K_STAR_MAP") == 50)
    {
        AddJournalQuestEntry("k_starforge", 50, TRUE);
    }
}
//::///////////////////////////////////////////////
//:: Spawn Creatures
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Creates number of creatures with a specific template at a specified waypoint tag.
    Total is the number times the loop will run.
    fTimeDelay is the number seconds between iterations.
    nSpawnIncrement is the number of templates spawned in per iteration.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamanmiuk
//:: Created On: Dec 17, 2002
//:://////////////////////////////////////////////
void UT_RunCombatEncounter(string sTemplate, string sTag, int nTotal = 3, float fTimeDelay = 1.5, int nSpawnIncrement = 1)
{
    if(fTimeDelay < 1.5)
    {
       fTimeDelay = 1.5;
    }
    object oWay = GetWaypointByTag(sTag);
    object oCreate;
    if(GetIsObjectValid(oWay))
    {
        int nCount = nSpawnIncrement;
        for(nCount; nCount != 0; nCount--)
        {
            oCreate = CreateObject(OBJECT_TYPE_CREATURE, sTemplate, GetLocation(oWay));
        }
        nTotal--;
        if(nTotal > 0)
        {
            DelayCommand(fTimeDelay, UT_RunCombatEncounter(sTemplate, sTag, nTotal, fTimeDelay, nSpawnIncrement));
        }
        fTimeDelay += fTimeDelay;
    }
}
//::///////////////////////////////////////////////
//:: Set Talk To Flag by Tag
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Loops through all object with a certain tag
    and sets their Talk To Flag to TRUE.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamanmiuk
//:: Created On: Dec 17, 2002
//:://////////////////////////////////////////////
void UT_SetTalkToFlagByTag(string sTag)
{
    int nCnt = 1;
    object oTrigger = GetNearestObjectByTag(sTag, GetFirstPC(), nCnt);
    while(GetIsObjectValid(oTrigger))
    {
        SetLocalBoolean(oTrigger, SW_PLOT_HAS_TALKED_TO, TRUE);
        nCnt++;
        oTrigger = GetNearestObjectByTag(sTag, GetFirstPC(), nCnt);
    }
}
//::///////////////////////////////////////////////
//:: Lock / Plot Twin Doors
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Loops through all doors with a certain tag
    and closes, locks and plots them.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamanmiuk
//:: Created On: Dec 17, 2002
//:://////////////////////////////////////////////
void UT_LockDoorDuplicates(string sTag)
{
    int nCount;
    object oDoor = GetNearestObjectByTag(sTag);
    while(GetIsObjectValid(oDoor) && GetObjectType(oDoor) == OBJECT_TYPE_DOOR)
    {
        if(oDoor != OBJECT_SELF)
        {
            AssignCommand(oDoor, ActionCloseDoor(oDoor));
            AssignCommand(oDoor, ActionLockObject(oDoor));
            AssignCommand(oDoor, SetPlotFlag(oDoor, TRUE));
        }
        nCount++;
        oDoor = GetNearestObjectByTag(sTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Can Party Member Interject
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Check to see if the Party member specified is
    in the party and within the distance given.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 10, 2003
//:://////////////////////////////////////////////
int UT_CheckCanPartyMemberInterject(int nNPC_Constant, float fDistance)
{
    object oParty;
    if(IsNPCPartyMember(nNPC_Constant))
    {
        //MODIFIED by Preston Watamaniuk on April 24, 2003
        //Put this in so that NPCs who you turn down on a planet will not reinitiate on that planet again.
        int nPlanet = GetGlobalNumber("K_CURRENT_PLANET");
        string sConstant = "NPC_INIT_PLANET_";
        sConstant = "NPC_INIT_PLANET_" + IntToString(nNPC_Constant);
        int nConstant = GetGlobalNumber(sConstant);
        if(nNPC_Constant == NPC_BASTILA)
        {
            oParty = GetObjectByTag("Bastila");
        }
        else if(nNPC_Constant == NPC_CANDEROUS)
        {
            oParty = GetObjectByTag("Cand");
        }
        else if(nNPC_Constant == NPC_CARTH)
        {
            oParty = GetObjectByTag("Carth");
        }
        else if(nNPC_Constant == NPC_HK_47)
        {
            oParty = GetObjectByTag("HK47");
        }
        else if(nNPC_Constant == NPC_JOLEE)
        {
            oParty = GetObjectByTag("Jolee");
        }
        else if(nNPC_Constant == NPC_JUHANI)
        {
            oParty = GetObjectByTag("Juhani");
        }
        else if(nNPC_Constant == NPC_MISSION)
        {
            oParty = GetObjectByTag("Mission");
        }
        else if(nNPC_Constant == NPC_T3_M4)
        {
            oParty = GetObjectByTag("T3M4");
        }
        else if(nNPC_Constant == NPC_ZAALBAR)
        {
            oParty = GetObjectByTag("Zaalbar");
        }
        if(GetIsObjectValid(oParty) &&
           GetDistanceBetween(oParty, GetFirstPC()) <= fDistance &&
           nPlanet != nConstant)
        {
            return TRUE;
        }
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Reinitialize NPC Planet Constants
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This resets the variables for each party member
    that controls whether they will init on a
    particular planet.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 24, 2003
//:://////////////////////////////////////////////
void UT_ReinitializePartyPlanetVariables()
{
    string sConstant = "NPC_INIT_PLANET_";
    int nCnt = 0;
    for(nCnt; nCnt <= 8; nCnt++)
    {
        sConstant = "NPC_INIT_PLANET_" + IntToString(nCnt);
        SetGlobalNumber(sConstant, 0);
    }
}
//teleport party member
void UT_TeleportPartyMember(object oPartyMember, location lDest)
{
  if(!GetIsObjectValid(oPartyMember))
  {
    return;
  }
  if(GetCurrentHitPoints(oPartyMember) < 1)
  {
    ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oPartyMember);
    ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectHeal(1),oPartyMember);
  }
  SetCommandable(TRUE,oPartyMember);
  AssignCommand(oPartyMember,ClearAllActions());
  AssignCommand(oPartyMember,ActionJumpToLocation(lDest));
}
//Returns true if oTarget is the object of interest of an attacker
int UT_GetUnderAttack(object oTarget)
{
  if(!GetIsObjectValid(oTarget))
  {
    return(FALSE);
  }
  object oAttacker = GetLastHostileActor(oTarget);
  return(GetIsObjectValid(oAttacker) || !GetIsDead(oAttacker) || GetObjectSeen(oAttacker, oTarget));
}
//:://////////////////////////////////////////////
/*
     This include handles jumping the party to the
     specified locations, good for controlling
     positions at the start of a cutscene.
     They will also be faced in the direction of
     the waypoints or objects they are being
     jumped to.
*/
//:://////////////////////////////////////////////
//:: Created By: Brad Prince
//:: Created On: Jan 23, 2003
//:://////////////////////////////////////////////
void UT_TeleportWholeParty(object oWP0, object oWP1, object oWP2)
{
   // The member the PC is in control of.
   object oMember0 = GetPartyMemberByIndex(0);
   // The second party member.
   object oMember1 = GetPartyMemberByIndex(1);
   // The third member.
   object oMember2 = GetPartyMemberByIndex(2);
   UT_RestorePartyToOneHealth();
   if(GetIsObjectValid(oMember0)) {
      UT_TeleportPartyMember(oMember0, GetLocation(oWP0));
      AssignCommand(oMember0, SetFacing(GetFacing(oWP0)));
   }
   if(GetIsObjectValid(oMember1)) {
      UT_TeleportPartyMember(oMember1, GetLocation(oWP1));
      DelayCommand(0.3, AssignCommand(oMember1, SetFacing(GetFacing(oWP1))));
   }
   if(GetIsObjectValid(oMember2)) {
      UT_TeleportPartyMember(oMember2, GetLocation(oWP2));
      DelayCommand(0.3, AssignCommand(oMember2, SetFacing(GetFacing(oWP2))));
   }
}
//::///////////////////////////////////////////////
//:: Action Pause Converation
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
     This will stop and start a conversation in 1
     step. Just pass the length of the pause.
     Be sure your commands will get carried out
     in the specified time and that the "pauser"
     is not killed.
*/
//:://////////////////////////////////////////////
//:: Created By: Brad Prince
//:: Created On: Jan 23, 2003
//:://////////////////////////////////////////////
void UT_ActionPauseConversation(float fDelay)
{
   ActionPauseConversation();
   DelayCommand(fDelay, ActionResumeConversation());
}
//::///////////////////////////////////////////////
//:: Spawn Available NPC
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Allows the uses to delay command on the creation
    of an NPC.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 5, 2003
//:://////////////////////////////////////////////
void UT_SpawnAvailableNPC(int nNPC, location lWay)
{
    object oNPC = SpawnAvailableNPC(nNPC, lWay);
}
//::///////////////////////////////////////////////
//:: Set Starmap Variables
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Advances K_STAR_MAP, sets the journal and
    sets the talk to flag.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 19, 2003
//:://////////////////////////////////////////////
void UT_StarMap1VariableSet()
{
    int nStar = GetGlobalNumber("K_STAR_MAP");
    int nBast = GetGlobalNumber("K_SWG_BASTILA");
    int nBool = GetLocalBoolean(OBJECT_SELF, SW_PLOT_HAS_TALKED_TO);
    if(nBool == FALSE)
    {
        //REMOVE THIS BEFORE SHIP
        AurPostString("v3.0 - K_STAR_MAP Before = " + IntToString(nStar), 5, 5, 5.0);
        nStar = nStar + 10;
        SetGlobalNumber("K_STAR_MAP",nStar);
        //REMOVE THIS BEFORE SHIP
        AurPostString("K_STAR_MAP After = " + IntToString(nStar), 5, 7, 5.0);
        if(nStar == 30)
        {
            if(nBast < 3)
            {
                SetGlobalNumber("K_SWG_BASTILA", 99);
            }
        }
        else if(nStar == 40)
        {
            //The player should now be captured by the Leviathan
            SetGlobalNumber("K_CAPTURED_LEV", 5);
            if(nBast < 5)
            {
                SetGlobalNumber("K_SWG_BASTILA", 99);
            }
        }
        else if(nStar == 50)
        {
            //The player should now have access to the unknown world.
            SetGlobalNumber("K_KOTOR_MASTER", 30);
        }
        SetLocalBoolean(OBJECT_SELF, SW_PLOT_HAS_TALKED_TO, TRUE);
        UT_SetStarmapJournal();
        AurPostString("Manaan Starmap = " + IntToString(GetGlobalBoolean("K_STAR_MAP_MANAAN")), 5, 9, 4.0);
        AurPostString("Kashyyyk Starmap = " + IntToString(GetGlobalBoolean("K_STAR_MAP_KASHYYYK")), 5, 11, 4.0);
        AurPostString("Korriban Starmap = " + IntToString(GetGlobalBoolean("K_STAR_MAP_KORRIBAN")), 5, 13, 4.0);
        AurPostString("Tatooine Starmap = " + IntToString(GetGlobalBoolean("K_STAR_MAP_TATOOINE")), 5, 15, 4.0);
    }
}
//::///////////////////////////////////////////////
//:: Play Starmap Animations
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Plays the animations necessary for the current
    state of the starmap variable
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 19, 2003
//:://////////////////////////////////////////////
void UT_StarMap2PlayAnimation()
{
    int nStar = GetGlobalNumber("K_STAR_MAP");
    int nBool = GetLocalBoolean(OBJECT_SELF, SW_PLOT_HAS_TALKED_TO);
    float fDelay = 30.0;
    if(nBool == FALSE)
    {
        ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);
        ActionPlayAnimation(UT_StarMap3GetLoopAnim(nStar));
        if(nStar == 40)//This variable is the pre-activation value.  It is going from 40 to 50
        {
            fDelay = 60.0;
        }
        DelayCommand(fDelay, ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
    }
}
//::///////////////////////////////////////////////
//:: Returns the Appropriate Starmap Anim Loop
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the appropriate animation loop for the
    Star Map based on the value used before the
    new variable is set.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 19, 2003
//:://////////////////////////////////////////////
int UT_StarMap3GetLoopAnim(int nStarMapVar)
{
    if(nStarMapVar == 0)
    {
        return ANIMATION_PLACEABLE_ANIMLOOP01;
    }
    else if(nStarMapVar == 10)
    {
        return ANIMATION_PLACEABLE_ANIMLOOP02;
    }
    else if(nStarMapVar == 20)
    {
        return ANIMATION_PLACEABLE_ANIMLOOP03;
    }
    else if(nStarMapVar == 30)
    {
        return ANIMATION_PLACEABLE_ANIMLOOP04;
    }
    else if(nStarMapVar == 40)
    {
        return ANIMATION_PLACEABLE_ANIMLOOP06;
    }
    return -1;
}
//::///////////////////////////////////////////////
//:: Generic Starmap Handler
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Runs the entire Starmap sequence as a black
    box with no extra scripting required.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 19, 2003
//:://////////////////////////////////////////////
void UT_StarMap4RunStarMap()
{
    UT_StarMap2PlayAnimation();
    UT_StarMap1VariableSet();
}
//////////////////////////////////////////////////////////////////////
/*    This function removes party members. It stores the npc constants
    of the removed party members.
    Aidan-Feb 20,03
*/
//////////////////////////////////////////////////////////////////////
void UT_StoreParty()
{
    if(GetPartyMemberByIndex(0) != GetFirstPC())
    {
        SetPartyLeader(NPC_PLAYER);
    }
    object oNPC1 = GetPartyMemberByIndex(1);
    object oNPC2 = GetPartyMemberByIndex(2);
    int nIdx, bFound1, bFound2, bRemove;
    for (nIdx = NPC_BASTILA; nIdx <= NPC_ZAALBAR && !bFound2; nIdx++)
    {
        bRemove = IsNPCPartyMember(nIdx);
        if(bRemove)
        {
            if(bFound1 == FALSE)
            {
                RemovePartyMember(nIdx);
                SetGlobalNumber("K_PARTY_STORE1",nIdx);
                bFound1 = TRUE;
                SetGlobalBoolean("K_PARTY_STORED",TRUE);
            }
            else
            {
                RemovePartyMember(nIdx);
                SetGlobalNumber("K_PARTY_STORE2",nIdx);
                bFound2 = TRUE;
                SetGlobalBoolean("K_PARTY_STORED",TRUE);
            }
        }
        bRemove = FALSE;
    }
    if(GetIsObjectValid(oNPC1))
    {
        DestroyObject(oNPC1);
    }
    if(GetIsObjectValid(oNPC2))
    {
        DestroyObject(oNPC2);
    }
}
//::///////////////////////////////////////////////
//:: Restore NPC
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This function restore party members. It will only
    restore party members removed via the
    UT_StoreParty function
*/
//:://////////////////////////////////////////////
//:: Created By: Aidan Scanlan
//:: Created On: Feb 20, 2003
//:://////////////////////////////////////////////
void UT_RestoreParty()
{
    int nNPC1 = GetGlobalNumber("K_PARTY_STORE1");
    int nNPC2 = GetGlobalNumber("K_PARTY_STORE2");
    object oNPC;
    if(GetGlobalBoolean("K_PARTY_STORED"))
    {
        if(nNPC1 >= NPC_BASTILA && nNPC1 <= NPC_ZAALBAR)
        {
            if(GetIsObjectValid(GetPartyMemberByIndex(1)) == FALSE)
            {
                oNPC = SpawnAvailableNPC(nNPC1,GetLocation(GetFirstPC()));
                if(GetIsObjectValid(oNPC))
                {
                    AddPartyMember(nNPC1,oNPC);
                }
            }
        }
        if(nNPC2 >= NPC_BASTILA && nNPC2 <= NPC_ZAALBAR)
        {
            if(GetIsObjectValid(GetPartyMemberByIndex(2)) == FALSE)
            {
                oNPC = SpawnAvailableNPC(nNPC2,GetLocation(GetFirstPC()));
                if(GetIsObjectValid(oNPC))
                {
                    AddPartyMember(nNPC2,oNPC);
                }
            }
        }
    }
    SetGlobalNumber("K_PARTY_STORE2",-2);
    SetGlobalNumber("K_PARTY_STORE1",-2);
    SetGlobalBoolean("K_PARTY_STORED",FALSE);
}
//::///////////////////////////////////////////////
//:: Return NPC Integer
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the NPC code for the given object if
    it is a NPC, otherwise it returns -1
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Feb 26, 2003
//:://////////////////////////////////////////////
int UT_GetNPCCode(object oNPC)
{
  string sTag = GetTag(oNPC);
  if(!GetIsObjectValid(oNPC))
  {
    return(-1);
  }
  if(sTag == "bastila")
  {
    return(NPC_BASTILA);
  }
  if(sTag == "cand")
  {
    return(NPC_CANDEROUS);
  }
  if(sTag == "carth")
  {
    return(NPC_CARTH);
  }
  if(sTag == "hk47")
  {
    return(NPC_HK_47);
  }
  if(sTag == "jolee")
  {
    return(NPC_JOLEE);
  }
  if(sTag == "juhani")
  {
    return(NPC_JUHANI);
  }
  if(sTag == "mission")
  {
    return(NPC_MISSION);
  }
  if(sTag == "t3m4")
  {
    return(NPC_T3_M4);
  }
  if(sTag == "zaalbar")
  {
    return(NPC_ZAALBAR);
  }
  return(-1);
}
//::///////////////////////////////////////////////
//:: Restore Party Member to 1 Vitality
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Restores all party mambers to 1 hp if
    tempoarily dead
*/
//:://////////////////////////////////////////////
//:: Created By: Aidan Scanlan
//:: Created On: March 1, 2003
//:://////////////////////////////////////////////
void UT_RestorePartyToOneHealth()
{
    int nIdx = 0;
    object oParty = GetPartyMemberByIndex(nIdx);
    while (GetIsObjectValid(oParty))
    {
        if(GetCurrentHitPoints(oParty) < 1)
        {
            ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oParty);
            ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectHeal(1),oParty);
        }
        nIdx++;
        oParty = GetPartyMemberByIndex(nIdx);
    }
}
//::///////////////////////////////////////////////
//:: Heal Party
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Cycles throught the entire party and heals
    them.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 28, 2003
//:://////////////////////////////////////////////
void UT_HealParty()
{
    object oParty;
    int nCnt = 0;
    for(nCnt; nCnt < 3; nCnt++)
    {
        oParty = GetPartyMemberByIndex(nCnt);
        if(GetIsObjectValid(oParty))
        {
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(500), oParty);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHealForcePoints(500), oParty);
        }
    }
}
//::///////////////////////////////////////////////
//:: Heal Party Member
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Heals a single target to full.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 28, 2003
//:://////////////////////////////////////////////
void UT_HealNPC(object oNPC)
{
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(500), oNPC);
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHealForcePoints(500), oNPC);
}
//::///////////////////////////////////////////////
//:: Alter Stack
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Alters the stack of a given object by the
    specified amount. If the stack is only 1 then
    the object is destroyed.
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: March 3, 2003
//:://////////////////////////////////////////////
void UT_AlterItemStack(object oItem,int iNum = 1,int bDecrement = TRUE)
{
    int iStackSize;
    if(!GetIsObjectValid(oItem) || iNum == 0)
    {
        return;
    }
    if(bDecrement)
    {
        iNum = -iNum;
    }
    iStackSize = GetItemStackSize(oItem);
    if(iNum > 0)
    {
        SetItemStackSize(oItem,iStackSize+iNum);
    }
    else
    {
        if(iStackSize+iNum <= 0)
        {
          //MODIFIED by Preston Watamaniuk on May 13, 2003
          //Added the command below to set the stack to 1 before destroying it.
          SetItemStackSize(oItem,1);
          DestroyObject(oItem,0.0,TRUE);
        }
        else
        {
          SetItemStackSize(oItem,iStackSize+iNum);
        }
    }
}
//::///////////////////////////////////////////////
//:: Heal All Party NPCs
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches through the area and heals all of the
    party members who are there. Used on the Ebon
    Hawk and the Taris Apartment.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: March 5, 2003
//:://////////////////////////////////////////////
void UT_HealAllPartyNPCs()
{
    object oNPC1 = GetObjectByTag("bastila");
    object oNPC2 =  GetObjectByTag("carth");
    object oNPC3 = GetObjectByTag("cand");
    object oNPC4 = GetObjectByTag("hk47");
    object oNPC5 = GetObjectByTag("jolee");
    object oNPC6 = GetObjectByTag("juhani");
    object oNPC7 = GetObjectByTag("mission");
    object oNPC8 = GetObjectByTag("t3m4");
    object oNPC9 = GetObjectByTag("zaalbar");
    object oCurrent;
    int nCnt = 1;
    while(nCnt <= 9)
    {
        if(nCnt == 1){oCurrent = oNPC1;}
        if(nCnt == 2){oCurrent = oNPC2;}
        if(nCnt == 3){oCurrent = oNPC3;}
        if(nCnt == 4){oCurrent = oNPC4;}
        if(nCnt == 5){oCurrent = oNPC5;}
        if(nCnt == 6){oCurrent = oNPC6;}
        if(nCnt == 7){oCurrent = oNPC7;}
        if(nCnt == 8){oCurrent = oNPC8;}
        if(nCnt == 9){oCurrent = oNPC9;}
        if(GetIsObjectValid(oCurrent))
        {
            UT_HealNPC(oCurrent);
        }
        nCnt++;
    }
    UT_HealNPC(GetFirstPC());
}
//::///////////////////////////////////////////////
//:: Clear Party Members
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Goes through the party and removes them.
    This is best used on Module Load when the
    object are not actually created yet.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: March 6, 2003
//:://////////////////////////////////////////////
void UT_ClearAllPartyMembers()
{
    int nCnt;
    for(nCnt; nCnt <= 8; nCnt++)
    {
        if(IsNPCPartyMember(nCnt))
        {
            RemovePartyMember(nCnt);
        }
    }
}
//::///////////////////////////////////////////////
//:: DC check using an ability score only
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Does a DC check just using an ability score
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: March 13, 2003
//:://////////////////////////////////////////////
int UT_AbilityCheck(int iDC, int iAbility, object oTarget)
{
    if(!GetIsObjectValid(oTarget))
    {
        return(FALSE);
    }
    if(GetAbilityScore(oTarget,iAbility) + (Random(20)+1) >= iDC)
    {
        return(TRUE);
    }
    else
    {
        return(FALSE);
    }
}
//::///////////////////////////////////////////////
//:: Make Neutral2
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the neutral faction
*/
//:://////////////////////////////////////////////
//:: Created By: Peter T.
//:: Created On: March 17, 2003
//:://////////////////////////////////////////////
void UT_MakeNeutral2(string sObjectTag)
{
    int nCount = 1;
    // get first object
    object oObject = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oObject))
    {
        // set to Neutral
        ChangeToStandardFaction(oObject, STANDARD_FACTION_NEUTRAL);
        // get next object
        nCount++;
        oObject = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Make Hostile1
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the Hostile_1 faction
*/
//:://////////////////////////////////////////////
//:: Created By: Peter T.
//:: Created On: March 17, 2003
//:://////////////////////////////////////////////
void UT_MakeHostile1(string sObjectTag)
{
    int nCount = 1;
    // get first object
    object oObject = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oObject))
    {
        // set to Hostile_1
        ChangeToStandardFaction(oObject, STANDARD_FACTION_HOSTILE_1);
        // get next object
        nCount++;
        oObject = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Make Friendly1
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the Friendly_1 faction
*/
//:://////////////////////////////////////////////
//:: Created By: Peter T.
//:: Created On: March 17, 2003
//:://////////////////////////////////////////////
void UT_MakeFriendly1(string sObjectTag)
{
    int nCount = 1;
    // get first object
    object oObject = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oObject))
    {
        // set to Friendly_1
        ChangeToStandardFaction(oObject, STANDARD_FACTION_FRIENDLY_1);
        // get next object
        nCount++;
        oObject = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Make Friendly2
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the Friendly_2 faction
*/
//:://////////////////////////////////////////////
//:: Created By: Peter T.
//:: Created On: March 17, 2003
//:://////////////////////////////////////////////
void UT_MakeFriendly2(string sObjectTag)
{
    int nCount = 1;
    // get first object
    object oObject = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oObject))
    {
        // set to Friendly_2
        ChangeToStandardFaction(oObject, STANDARD_FACTION_FRIENDLY_2);
        // get next object
        nCount++;
        oObject = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: UT_ActivateTortureCage
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    performs a standard torture cage effect
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: April 1, 2003
//:://////////////////////////////////////////////
void DoTortureAnims(float fDuration)
{
    ActionPlayAnimation(ANIMATION_LOOPING_SPASM,1.0,fDuration/3.0);
    ActionPlayAnimation(ANIMATION_LOOPING_HORROR,1.0,fDuration/3.0);
    ActionPlayAnimation(ANIMATION_LOOPING_SPASM,1.0,fDuration/3.0);
}
void UT_ActivateTortureCage(object oCage, object oTarget,float fDuration)
{
    //AssignCommand(oCage,
    //ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
    //ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectHorrified(),oTarget,fDuration);
    AssignCommand(oTarget,DoTortureAnims(fDuration));
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectBeam(VFX_BEAM_LIGHTNING_DARK_S, oCage, BODY_NODE_HEAD),oTarget,fDuration);
    //DelayCommand(fDuration,AssignCommand(oCage,ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE)));
}
//::///////////////////////////////////////////////
//:: Validate Jump
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    If the first three letters of the last module
    do not match the first three letters of the
    space port then function will return false.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 15, 2003
//:://////////////////////////////////////////////
int UT_ValidateJump(string sLastModule)
{
    int nJump = FALSE;
    string sCurrentModule = GetModuleFileName();
    PrintString("JUMP VALIDATION: CURRENT = " + sCurrentModule + " LAST = " + sLastModule);
    PrintString("JUMP VALIDATION: SUBSTRING: " + GetSubString(sCurrentModule, 0,3) + " = " + GetSubString(sLastModule, 0,3));
    if(GetSubString(sCurrentModule, 0,3) == GetSubString(sLastModule, 0,3))
    {
        nJump = TRUE;
    }
    else if(sCurrentModule != "ebo_m12aa")
    {
        SetGlobalString("K_LAST_MODULE", "NO_MODULE");
    }
    return nJump;
}
//::///////////////////////////////////////////////
//:: Play On Click Reaction
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Makes the animal face the PC, do its victory
    and play a sound passed in. Should be used
    in conjunction with the k_def_interact spawn in
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 31, 2003
//:://////////////////////////////////////////////
void UT_DoAmbientReaction(string sSound)
{
    //ActionDoCommand(SetLocalBoolean(OBJECT_SELF, 72, FALSE));
    PlaySound(sSound);
    SetFacingPoint(GetPosition(GetPCSpeaker()));
    ActionPlayAnimation(ANIMATION_FIREFORGET_VICTORY1);
    //DelayCommand(2.0, ActionDoCommand(SetLocalBoolean(OBJECT_SELF, 72, TRUE)));
}
""",
    "k_inc_walkways": b"""//:: k_inc_walkways
/*
    v1.0
    Walk Way Points Include
    used by k_inc_generic
    NOTE - To get these functions
    use k_inc_generic
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
int WALKWAYS_CURRENT_POSITION = 0;
int WALKWAYS_END_POINT = 1;
int WALKWAYS_SERIES_NUMBER = 2;
int    SW_FLAG_AMBIENT_ANIMATIONS    =    29;
int    SW_FLAG_AMBIENT_ANIMATIONS_MOBILE =    30;
int    SW_FLAG_WAYPOINT_WALK_ONCE    =    34;
int    SW_FLAG_WAYPOINT_WALK_CIRCULAR    =    35;
int    SW_FLAG_WAYPOINT_WALK_PATH    =    36;
int    SW_FLAG_WAYPOINT_WALK_STOP    =    37; //One to three
int    SW_FLAG_WAYPOINT_WALK_RANDOM    =    38;
int SW_FLAG_WAYPOINT_WALK_RUN    =   39;
int SW_FLAG_WAYPOINT_DIRECTION = 41;
int SW_FLAG_WAYPOINT_DEACTIVATE = 42;
int SW_FLAG_WAYPOINT_WALK_STOP_LONG = 46;
int SW_FLAG_WAYPOINT_WALK_STOP_RANDOM = 47;
//Makes OBJECT_SELF walk way points based on the spawn in conditions set out.
void GN_WalkWayPoints();
//Sets the series number from 01 to 99 on a creature so that the series number and not the creature's tag is used for walkway points
void GN_SetWalkWayPointsSeries(int nSeriesNumber);
//Sets Generic Spawn In Conditions
void GN_SetSpawnInCondition(int nFlag, int nState = TRUE);
//Gets the boolean state of a generic spawn in condition.
int GN_GetSpawnInCondition(int nFlag);
//Moves an object to the last waypoint in a series
void GN_MoveToLastWayPoint(object oToMove);
//Moves an object to a random point in the series
void GN_MoveToRandomWayPoint(object oToMove);
//Moves an object to a sepcific point in the series
void GN_MoveToSpecificWayPoint(object oToMove, int nArrayNumber);
//Determines the correct direction to proceed in a walkway points array.
int GN_GetWayPointDirection(int nEndArray, int nCurrentPosition);
//Should only be called from within SetListendingPatterns
void GN_SetUpWayPoints();
//Play an animation between way points.
void GN_PlayWalkWaysAnimation();
//Inserts a print string into the log file for debugging purposes for the walkways include.
void WK_MyPrintString(string sString);
//Are valid walkway points available
int GN_CheckWalkWays(object oTarget);
//::///////////////////////////////////////////////
//:: Walk Way Points
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Makes OBJECT_SELF walk way points based on a
    number of spawn in conditions.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
void GN_WalkWayPoints()
{
    if(!GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE))
    {
        string sPost = "POST_";
        string sWays = "WP_";
        string sWayNumber;
        int nCurrentTarget = GetLocalNumber(OBJECT_SELF, WALKWAYS_CURRENT_POSITION);
        int nEndArray = GetLocalNumber(OBJECT_SELF, WALKWAYS_END_POINT);
        int nSeriesInt = GetLocalNumber(OBJECT_SELF, WALKWAYS_SERIES_NUMBER);
        //Used where you want the creature to use a numbered series instead of their own tag.
        if(nCurrentTarget < 10 &&  nCurrentTarget > 0)
        {
            sWayNumber = "0" + IntToString(nCurrentTarget);
        }
        else if(nCurrentTarget == 0)
        {
            //August 2, 2002 - Jason Booth - changed to randomize start wp
            if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RANDOM))
            {
                nCurrentTarget = Random(nEndArray) + 1;
                if(nCurrentTarget < 10)
                {
                  sWayNumber = "0" + IntToString(nCurrentTarget);
                }
                else
                {
                  sWayNumber = IntToString(nCurrentTarget);
                }
            }
            else
            {
              sWayNumber = "01";
            }
        }
        else if(nCurrentTarget < 10)
        {
            sWayNumber = "0" + IntToString(nCurrentTarget);
        }
        else
        {
            sWayNumber = IntToString(nCurrentTarget);
        }
        string sMoveWay;
        string sTestWay;
        //Test to see if the series waypoints are being used and if so then build sTestWay with the number not tag.
        if(nSeriesInt > 0)
        {
            string sSeriesWay;
            if(nSeriesInt < 10)
            {
                sSeriesWay = "0" + IntToString(nSeriesInt);
            }
            else
            {
                sSeriesWay = IntToString(nSeriesInt);
            }
            sTestWay = sWays + sSeriesWay + "_02";
        }
        //Use object tag if there is no series number
        else
        {
            sTestWay = sWays + GetTag(OBJECT_SELF) + "_02";
        }
        object oTestWay = GetWaypointByTag(sTestWay);
        if(nEndArray == 0 && GetIsObjectValid(oTestWay))
        {
            //GN_PostString("SET LISTENING PATTERNS HAS NOT RUN PLEASE USE IN SPAWN IN SCRIPT");
        }
        if(GetIsObjectValid(oTestWay))
        {
            int nLength = GetStringLength(sTestWay);
            sMoveWay = GetStringLeft(sTestWay, nLength - 2) + sWayNumber;
            //sWays + GetTag(OBJECT_SELF) + "_" + sWayNumber;
        }
        else
        {
            sWays = "UNKNOWN";
            sMoveWay = sPost + GetTag(OBJECT_SELF);
        }
        object oWay = GetWaypointByTag(sMoveWay);
        int nRun = GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RUN);
        //Check if the target waypoint is close enough to warrent moving on to the next waypoint.
        if(GetDistanceToObject2D(oWay) <= 2.5)
        {
            int nDirection;
            if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RANDOM))
            {
                nCurrentTarget = Random(nEndArray) + 1;
            }
            else if(nCurrentTarget < nEndArray && !GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RANDOM))
            {
                nDirection = GN_GetWayPointDirection(nEndArray, nCurrentTarget);
                nCurrentTarget = nCurrentTarget + nDirection;
            }
            else if(nCurrentTarget == nEndArray)
            {
                nDirection = GN_GetWayPointDirection(nEndArray, nCurrentTarget);
                if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_ONCE))
                {
                    GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE);
                }
                else if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_CIRCULAR))
                {
                    nCurrentTarget = 1;
                    GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DIRECTION, FALSE);
                }
                else
                {
                    nCurrentTarget = nCurrentTarget + nDirection;
                }
            }
        }
        if(GetIsObjectValid(GetWaypointByTag(sMoveWay)))
        {
            //MODIFIED by Preston Watamaniuk on March 13
            //Took out the clear all actions. It was mucking up the chain of commands.
            //ActionDoCommand(ClearAllActions());
            int nRand;
            if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_STOP))
            {
                nRand = d3();
            }
            else if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_STOP_LONG))
            {
                nRand = d6()+6;
            }
            else if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_STOP_RANDOM))
            {
                nRand = d12();
            }
            else if(nRand > 0)
            {
                ActionWait(IntToFloat(nRand)); //ACTION
            }
            oWay = GetWaypointByTag(sMoveWay);
            //Calculate the timeout based on the distance that needs to be traveled.
            float fTimeOut = GetDistanceBetween2D(GetWaypointByTag(sMoveWay), OBJECT_SELF)/1.25;
            if(fTimeOut < 30.0)
            {
                fTimeOut = 30.0;
            }
            //WK_MyPrintString("WALKWAYS DEBUG *************** Adding Action: Force Move");
            ActionForceMoveToObject(oWay, GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RUN), 2.5, fTimeOut); //ACTION
            //MODIFIED by Preston Watamaniuk on March 13
            //Added this piece of code to add ambient animations to Walkways.
            if(GN_GetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS))
            {
                //WK_MyPrintString("WALKWAYS DEBUG *************** Adding Action: Animation");
                ActionDoCommand(GN_PlayWalkWaysAnimation()); //ACTION
            }
            SetLocalNumber(OBJECT_SELF, WALKWAYS_CURRENT_POSITION, nCurrentTarget);
            if(sWays != "UNKNOWN")
            {
                //WK_MyPrintString("WALKWAYS DEBUG *************** Adding Action: Walkways Interate");
                ActionDoCommand(GN_WalkWayPoints());   //ACTION
            }
        }
    }
}
void GN_SetWalkWayPointsSeries(int nSeriesNumber)
{
    SetLocalNumber(OBJECT_SELF, WALKWAYS_SERIES_NUMBER, nSeriesNumber);
}
//::///////////////////////////////////////////////
//:: Set Spawn In Condition
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the Generic Spawn In Conditions
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
void GN_SetSpawnInCondition(int nFlag, int nState = TRUE)
{
    //WK_MyPrintString("GENERIC DEBUG *************** Setting Local Number (" + IntToString(nFlag) + ") = " + IntToString(nState));
    SetLocalBoolean(OBJECT_SELF, nFlag, nState);
}
//::///////////////////////////////////////////////
//:: Get Spawn In Condition
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets the Generic Spawn In Conditions
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
int GN_GetSpawnInCondition(int nFlag)
{
    int nLocal = GetLocalBoolean(OBJECT_SELF, nFlag);
    if(nLocal > 0)
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Preston Watamaniuk
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Moves the passed in object to the last waypoint
    in that NPCs series of waypoints.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 12, 2002
//:://////////////////////////////////////////////
void GN_MoveToLastWayPoint(object oToMove)
{
    int nLastWay = GetLocalNumber(oToMove, WALKWAYS_END_POINT);
    int nSeries = GetLocalNumber(oToMove, WALKWAYS_SERIES_NUMBER);
    string sString;
    if(nSeries > 0)
    {
        string sSeriesWay;
        if(nSeries < 10)
        {
            sSeriesWay = "0" + IntToString(nSeries);
        }
        else
        {
            sSeriesWay = IntToString(nSeries);
        }
        sString = "WP_" + sSeriesWay;
    }
    else
    {
        sString = "WP_" + GetTag(oToMove);
    }
    if(nLastWay < 10)
    {
        sString = sString + "_0" + IntToString(nLastWay);
    }
    else
    {
        sString = sString + "_" + IntToString(nLastWay);
    }
    object oWay = GetWaypointByTag(sString);
    if(GetIsObjectValid(oWay))
    {
        AssignCommand(oToMove, ClearAllActions());
        AssignCommand(oToMove, ActionMoveToObject(oWay, FALSE));
    }
}
//::///////////////////////////////////////////////
//:: Preston Watamaniuk
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Moves the passed in object to a random waypoint
    in that NPCs series of waypoints.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 12, 2002
//:://////////////////////////////////////////////
void GN_MoveToRandomWayPoint(object oToMove)
{
    int nLastWay = GetLocalNumber(oToMove, WALKWAYS_END_POINT);
    int nRandom = Random(nLastWay)+1;
    int nSeries = GetLocalNumber(oToMove, WALKWAYS_SERIES_NUMBER);
    string sString;
    if(nSeries > 0)
    {
        string sSeriesWay;
        if(nSeries < 10)
        {
            sSeriesWay = "0" + IntToString(nSeries);
        }
        else
        {
            sSeriesWay = IntToString(nSeries);
        }
        sString = "WP_" + sSeriesWay;
    }
    else
    {
        sString = "WP_" + GetTag(oToMove);
    }
    if(nLastWay < 10)
    {
        sString = sString + "_0" + IntToString(nRandom);
    }
    else
    {
        sString = sString + "_" + IntToString(nRandom);
    }
    object oWay = GetWaypointByTag(sString);
    if(GetIsObjectValid(oWay))
    {
        AssignCommand(oToMove, ClearAllActions());
        AssignCommand(oToMove, ActionMoveToObject(oWay, FALSE));
    }
}
//::///////////////////////////////////////////////
//:: Preston Watamaniuk
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Moves the passed in object to a specified waypoint
    in that NPCs series of waypoints.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 12, 2002
//:://////////////////////////////////////////////
void GN_MoveToSpecificWayPoint(object oToMove, int nArrayNumber)
{
    int nLastWay = GetLocalNumber(oToMove, WALKWAYS_END_POINT);
    int nSeries = GetLocalNumber(oToMove, WALKWAYS_SERIES_NUMBER);
    string sString;
    if(nArrayNumber <= nLastWay)
    {
        if(nSeries > 0)
        {
            string sSeriesWay;
            if(nSeries < 10)
            {
                sSeriesWay = "0" + IntToString(nSeries);
            }
            else
            {
                sSeriesWay = IntToString(nSeries);
            }
            sString = "WP_" + sSeriesWay;
        }
        else
        {
            sString = "WP_" + GetTag(oToMove);
        }
        if(nArrayNumber < 10)
        {
            sString = sString + "_0" + IntToString(nArrayNumber);
        }
        else
        {
            sString = sString + "_" + IntToString(nArrayNumber);
        }
        object oWay = GetWaypointByTag(sString);
        if(GetIsObjectValid(oWay))
        {
            AssignCommand(oToMove, ClearAllActions());
            AssignCommand(oToMove, ActionMoveToObject(oWay, FALSE));
        }
    }
}
//::///////////////////////////////////////////////
//:: Get Waypooint Direction
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Determines the direction that a NPC should be
    walking along their waypoints.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jul 20, 2002
//:://////////////////////////////////////////////
int GN_GetWayPointDirection(int nEndArray, int nCurrentPosition)
{
    int nDirection;
    int nFlag = GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_DIRECTION);
    if(nEndArray == nCurrentPosition && nFlag == FALSE)
    {
        nDirection = -1;
        GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DIRECTION, TRUE);
    }
    else if(nCurrentPosition == 1 && nFlag == TRUE)
    {
        nDirection = 1;
        GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DIRECTION, FALSE);
    }
    else if(nFlag == FALSE)
    {
        nDirection = 1;
    }
    else if(nFlag == TRUE)
    {
        nDirection = -1;
    }
    return nDirection;
}
//::///////////////////////////////////////////////
//:: Set Up Way Points
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Used to initialize the NPCs waypoints
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
void GN_SetUpWayPoints()
{
    string sString;
    int nSeries = GetLocalNumber(OBJECT_SELF, WALKWAYS_SERIES_NUMBER);
    if(nSeries > 0)
    {
        string sSeriesWay;
        if(nSeries < 10)
        {
            sSeriesWay = "0" + IntToString(nSeries);
        }
        else
        {
            sSeriesWay = IntToString(nSeries);
        }
        sString = "WP_" + sSeriesWay;
    }
    else
    {
        sString = "WP_" + GetTag(OBJECT_SELF);
    }
    int nCnt = 1;
    string sTest = sString + "_01";
    object oWay = GetWaypointByTag(sTest);
    while(GetIsObjectValid(oWay))
    {
        nCnt++;
        if(nCnt < 10)
        {
            sTest = sString + "_0" + IntToString(nCnt);
        }
        else
        {
            sTest = sString + "_" + IntToString(nCnt);
        }
        oWay = GetWaypointByTag(sTest);
    }
    nCnt = nCnt - 1;
    if(nCnt > 0)
    {
        SetLocalNumber(OBJECT_SELF, WALKWAYS_END_POINT, nCnt);
    }
}
//::///////////////////////////////////////////////
//:: Play Walk Ways Animations
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Plays an animation between way points
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: March 13, 2003
//:://////////////////////////////////////////////
void GN_PlayWalkWaysAnimation()
{
    int nRoll = d8();
    if(nRoll == 1)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Bored");
        ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_BORED, 1.0);
    }
    else if(nRoll == 2)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Scratch");
        ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0);
    }
    else if(nRoll == 3)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Pause 2");
        ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 3.0);
    }
    else if((nRoll == 4 || nRoll == 5) && GetRacialType(OBJECT_SELF) != RACIAL_TYPE_DROID)
    {
        if(GetGender(OBJECT_SELF) == GENDER_MALE)
        {
            //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Male Pause 3");
            GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
            ActionPlayAnimation(ANIMATION_LOOPING_PAUSE3, 1.0, 20.4);
            ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
        }
        else if(GetGender(OBJECT_SELF) == GENDER_FEMALE)
        {
            //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Female Pause 3");
            GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
            ActionPlayAnimation(ANIMATION_LOOPING_PAUSE3, 1.0, 13.3);
            ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
        }
    }
    else if(nRoll == 6 || nRoll == 4 || nRoll == 5)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Head Turn Left");
        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT);
    }
    else if(nRoll == 7)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Head Turn Right");
        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT);
    }
    else if(nRoll == 8)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Pause 2");
        GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
        ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 5.0);
        ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
    }
}
//::///////////////////////////////////////////////
//:: Are Walk Ways Available
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Are valid walkway points available for walking
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 22, 2003
//:://////////////////////////////////////////////
int GN_CheckWalkWays(object oTarget)
{
    string sTag = "WP_" + GetTag(oTarget) + "_01";
    string sPost = "POST_" + GetTag(oTarget);
    int nSeriesInt = GetLocalNumber(oTarget, WALKWAYS_SERIES_NUMBER);
    string sSeriesWay;
    if(nSeriesInt < 10)
    {
        sSeriesWay = "0" + IntToString(nSeriesInt);
    }
    else
    {
        sSeriesWay = IntToString(nSeriesInt);
    }
    string sTestWay = "WP_" + sSeriesWay + "_01";
    object oWay = GetWaypointByTag(sTag);
    object oWay2 = GetWaypointByTag(sTestWay);
    object oPost = GetWaypointByTag(sPost);
    WK_MyPrintString("Walk Initiate for " + GetTag(oTarget));
    WK_MyPrintString("TAG WAY FOUND = " + IntToString(GetIsObjectValid(oWay)));
    WK_MyPrintString("WAY POINT NAME = " + GetTag(oWay));
    WK_MyPrintString("SERIES INT = " + IntToString(nSeriesInt));
    WK_MyPrintString("SERIES WAY FOUND = " + IntToString(GetIsObjectValid(oWay2)));
    WK_MyPrintString("SERIES Series Tag = " + sTestWay);
    WK_MyPrintString("");
    if(GetIsObjectValid(oWay) || GetIsObjectValid(oWay2) || GetIsObjectValid(oPost))
    {
        return TRUE;
    }
    return FALSE;
}
void WK_MyPrintString(string sString)
{
    if(!ShipBuild())
    {
        PrintString(sString);
    }
}
""",
    "k_inc_zone": b"""//:: k_inc_zones
/*
     Zone including for controlling
     the chaining of creatures
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
#include "k_inc_generic"
//Function run by the trigger to catalog the control nodes followers
void ZN_CatalogFollowers();
//Checks zone conditional on creature to if they belong to the zone
int ZN_CheckIsFollower(object oController, object oTarget);
//Checks the distance and creatures around the PC to see if it should return home.
int ZN_CheckReturnConditions();
//Gets the followers to move back to the controller object
void ZN_MoveToController(object oController, object oFollower);
//Checks to see if a specific individual needs to return to the controller.
int ZN_CheckFollowerReturnConditions(object oTarget);
//::///////////////////////////////////////////////
//:: Catalog Zone Followers
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
     Catalogs all creatures within
     the trigger area and marks
     them with an integer which
     is part of the creature's
     tag.
     Use local number SW_NUMBER_LAST_COMBO
     as a test. A new local number will
     be defined if the system works.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 7, 2003
//:://////////////////////////////////////////////
void ZN_CatalogFollowers()
{
    GN_PostString("FIRING", 10,10, 10.0);
    if(GetLocalBoolean(OBJECT_SELF, 10) == FALSE) //Has talked to boolean
    {
        string sZoneTag = GetTag(OBJECT_SELF);
        int nZoneNumber = StringToInt(GetStringRight(sZoneTag, 2));
        //Set up creature followers
        object oZoneFollower = GetFirstInPersistentObject();
        while(GetIsObjectValid(oZoneFollower))
        {
            SetLocalNumber(oZoneFollower, SW_NUMBER_COMBAT_ZONE, nZoneNumber);
            //GN_MyPrintString("ZONING DEBUG ***************** Setup Follower = " + GN_ReturnDebugName(oZoneFollower));
            //GN_MyPrintString("ZONING DEBUG ***************** Setup Follower Zone # = " + GN_ITS(GetLocalNumber(oZoneFollower, SW_NUMBER_COMBAT_ZONE)));
            oZoneFollower = GetNextInPersistentObject();
        }
        SetLocalBoolean(OBJECT_SELF, 10, TRUE);//Has talked to boolean
    }
}
//::///////////////////////////////////////////////
//:: Check Object for Zoning
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the object to see if they part of the
    zone. This function is run off of the control
    node.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 7, 2003
//:://////////////////////////////////////////////
int ZN_CheckIsFollower(object oController, object oTarget)
{
    int nNumber = GetLocalNumber(oTarget, SW_NUMBER_COMBAT_ZONE);
    string sZoneTag = GetTag(OBJECT_SELF);
    int nZoneNumber = StringToInt(GetStringRight(sZoneTag, 2));
    if(nZoneNumber == nNumber)
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Check Return Conditions
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks to see if the conditions exist to
    possibly check for followers to return to
    the controller.
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
int ZN_CheckReturnConditions()
{
    object oPC = GetPartyMemberByIndex(0);
    /*
        1.  Is the PC more than 21m away from the control node
        2.  Is the follower more than 20m away from the control node
        3.  Are there 9 or more individuals around the any single party member out to a distance of 30m
    */
    object oNinth = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, oPC, 9);
    //GN_MyPrintString("ZONING DEBUG ***************** 9th Creature = " + GN_ReturnDebugName(oNinth));
    //GN_MyPrintString("ZONING DEBUG ***************** 9th Creature Distance = " + FloatToString(GetDistanceBetween(oPC, oNinth), 4,2));
    if(GetIsObjectValid(oNinth) && GetDistanceBetween(oPC, oNinth) < 30.0)
    {
        if(GetDistanceBetween(OBJECT_SELF, oPC) > 21.0)
        {
            return TRUE;
        }
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Check Follower Return Conditions.
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks if the follower object needs to return
    to home base.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 8, 2003
//:://////////////////////////////////////////////
int ZN_CheckFollowerReturnConditions(object oTarget)
{
    float fDistance = GetDistanceBetween(oTarget, OBJECT_SELF);
    //GN_MyPrintString("ZONING DEBUG ***************** " + GN_ReturnDebugName(oTarget) + " control distance " + FloatToString(fDistance, 4, 2));
    if(fDistance >= 10.0 && GetIsEnemy(oTarget, GetFirstPC()))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Move to Controller
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets the follower object to move back to the
    controller object.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 7, 2003
//:://////////////////////////////////////////////
void ZN_MoveToController(object oController, object oFollower)
{
    //GN_MyPrintString("ZONING DEBUG ***************** Controller = " + GN_ReturnDebugName(oController));
    //GN_MyPrintString("ZONING DEBUG ***************** Follower = " + GN_ReturnDebugName(oFollower));
    //GN_MyPrintString("ZONING DEBUG ***************** Follower Zone # = " + GN_ITS(GetLocalNumber(oFollower, SW_NUMBER_LAST_COMBO)));
    if(GetCurrentAction(oFollower) != ACTION_INVALID)
    {
        SetCommandable(TRUE);
    }
    CancelCombat(oFollower);
    AssignCommand(oFollower, ClearAllActions());
    AssignCommand(oFollower, ActionForceMoveToObject(oController, TRUE, 5.0, 5.0));
    AssignCommand(oFollower, ActionDoCommand(SetCommandable(TRUE, oFollower)));
    AssignCommand(oFollower, SetCommandable(FALSE, oFollower));
}
""",
}
TSL_LIBRARY = {
    "a_global_inc": b"""
//:: a_global_inc
/*
    parameter 1 = string identifier for a global number
    parameter 2 = amount to increment GetGlobalNumber(param1)
*/
//:: Created By: Anthony Davis
#include "k_inc_debug"
void main()
{
    string tString = GetScriptStringParameter();
    int tInt = GetScriptParameter( 1 );
    SetGlobalNumber(tString, GetGlobalNumber(tString) + tInt);
}
""",
    "a_influence_inc": b"""// a_influence_inc
/* Parameter Count: 2
Increases an NPC's influence.
Param1 - The NPC value of the player whose influence is increased.
Param2 - magnitude of influence change:
    1 - low
    2 - medium
    3 - high
    all others - medium
NPC numbers, as specified in NPC.2da
0       Atton
1       BaoDur
2       Mand
3       g0t0
4       Handmaiden
5       hk47
6       Kreia
7       Mira
8       T3m4
9       VisasMarr
10      Hanharr
11      Disciple
*/
//
// KDS 06/16/04
void main()
{
int nInfluenceLow = 8;
int nInfluenceMedium = 8;
int nInfluenceHigh = 8;
int nNPC = GetScriptParameter(1);
int nImpact = GetScriptParameter(2);
int nInfluenceChange;
switch (nImpact)
{
    case 1:
        nInfluenceChange = nInfluenceLow;
        break;
    case 2:
        nInfluenceChange = nInfluenceMedium;
        break;
    case 3:
        nInfluenceChange = nInfluenceHigh;
        break;
    default:
        nInfluenceChange = nInfluenceMedium;
        break;
}
ModifyInfluence (nNPC, nInfluenceChange);
}
""",
    "a_localn_inc": b"""// a_localn_inc
// Parameter Count: 2
// Param1 - The local number # to increment (range 12-31)
// Param2 - the amount to increment Param1 by (default = 1)
// Param3 - Optional string parameter to refer to another object's local #
//
// KDS 06/15/04
// Modified TDE 7/31/04
#include "k_inc_debug"
#include "k_inc_utility"
void main()
{
    int nLocalNumber = GetScriptParameter( 1 );
    int nValue = GetScriptParameter ( 2 );
    // Added optional string parameter to refer to another object's local #
    string sTag = GetScriptStringParameter();
    object oObject;
    // If sTag is empty, use the object that called the script
    if ( sTag == "" ) oObject = OBJECT_SELF;
    else oObject = GetObjectByTag(sTag);
    if (nValue == 0) nValue = 1;
    SetLocalNumber(oObject, nLocalNumber,
        GetLocalNumber(oObject, nLocalNumber) + nValue);
}
""",
    "k_inc_cheat": b"""//:: k_inc_cheat
/*
    This will be localized area for all
    Cheat Bot scripting.
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
#include "k_inc_debug"
//Takes a PLANET_ Constant
void CH_SetPlanetaryGlobal(int nPlanetConstant);
//Makes the specified party member available to the PC
void CH_SetPartyMemberAvailable(int nNPC);
//::///////////////////////////////////////////////
//:: Set Planet Local
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    VARIABLE = K_CURRENT_PLANET
        Endar Spire     5
        Taris           10
        Dantooine       15
        --Kashyyk       20
        --Manaan        25
        --Korriban      30
        --Tatooine      35
        Leviathan       40
        Unknown World   45
        Star Forge      50
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2002
//:://////////////////////////////////////////////
void CH_SetPlanetaryGlobal(int nPlanetConstant)
{
/*
    if(nPlanetConstant == PLANET_ENDAR_SPIRE)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 5);
    }
    else if(nPlanetConstant == PLANET_TARIS)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 10);
    }
    else if(nPlanetConstant == PLANET_DANTOOINE)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 15);
    }
    else if(nPlanetConstant == PLANET_KASHYYYK)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 20);
    }
    else if(nPlanetConstant == PLANET_KORRIBAN)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 30);
    }
    else if(nPlanetConstant == PLANET_MANAAN)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 25);
    }
    else if(nPlanetConstant == PLANET_TATOOINE)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 35);
    }
    else if(nPlanetConstant == PLANET_LEVIATHAN)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 40);
    }
    else if(nPlanetConstant == PLANET_UNKNOWN_WORLD)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 45);
    }
    else if(nPlanetConstant == PLANET_STAR_FORGE)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 50);
    }
*/
}
//::///////////////////////////////////////////////
//:: Make NPC Available
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets an NPC as available
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2002
//:://////////////////////////////////////////////
void CH_SetPartyMemberAvailable(int nNPC)
{
/*
    if(nNPC == NPC_BASTILA)
    {
        AddAvailableNPCByTemplate(NPC_BASTILA, "p_bastilla");
    }
    else if(nNPC == NPC_CANDEROUS)
    {
        AddAvailableNPCByTemplate(NPC_CANDEROUS, "p_cand");
    }
    else if(nNPC == NPC_CARTH)
    {
        AddAvailableNPCByTemplate(NPC_CARTH, "p_carth");
    }
    else if(nNPC == NPC_HK_47)
    {
        AddAvailableNPCByTemplate(NPC_HK_47, "p_hk47");
    }
    else if(nNPC == NPC_JOLEE)
    {
        AddAvailableNPCByTemplate(NPC_JOLEE, "p_jolee");
    }
    else if(nNPC == NPC_JUHANI)
    {
        AddAvailableNPCByTemplate(NPC_JUHANI, "p_juhani");
    }
    else if(nNPC == NPC_MISSION)
    {
        AddAvailableNPCByTemplate(NPC_MISSION, "p_mission");
    }
    else if(nNPC == NPC_T3_M4)
    {
        AddAvailableNPCByTemplate(NPC_T3_M4, "p_t3m4");
    }
    else if(nNPC == NPC_ZAALBAR)
    {
        AddAvailableNPCByTemplate(NPC_ZAALBAR, "p_zaalbar");
    }
*/
}
""",
    "k_inc_debug": b"""//::///////////////////////////////////////////////
//:: KOTOR Debug Include
//:: k_inc_debug
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This contains the functions for inserting
    debug information into the scripts.
    This include will use Db as its two letter
    function prefix.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//:://////////////////////////////////////////////
//Inserts a print string into the log file for debugging purposes.
void Db_MyPrintString(string sString);
//Makes the object running the script say a speak string.
void Db_MySpeakString(string sString);
//Makes the nearest PC say a speakstring.
void Db_AssignPCDebugString(string sString);
//Basically, a wrapper for AurPostString
void Db_PostString(string sString = "",int x = 5,int y = 5,float fShow = 1.0);
//::///////////////////////////////////////////////
//:: Debug Print String
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Inserts a print string into the log file for
    debugging purposes.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//:://////////////////////////////////////////////
void Db_MyPrintString(string sString)
{
    if(!ShipBuild())
    {
        PrintString(sString);
    }
}
//::///////////////////////////////////////////////
//:: Debug Speak String
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Makes the object running the script say a
    speak string.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//:://////////////////////////////////////////////
void Db_MySpeakString(string sString)
{
    SpeakString(sString);
}
//::///////////////////////////////////////////////
//:: Assign PC Debug String
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Assigns the nearest PC a speakstring for debug
    purposes.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//:://////////////////////////////////////////////
void Db_AssignPCDebugString(string sString)
{
    object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
    if(GetIsObjectValid(oPC))
    {
        AssignCommand(oPC, SpeakString(sString));
    }
}
//::///////////////////////////////////////////////
//:: Db_PostString
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//Basically, a wrapper for AurPostString
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
void Db_PostString(string sString = "",int x = 5,int y = 5,float fShow = 1.0)
{
    if(!ShipBuild())
    {
        AurPostString(sString,x,y,fShow);
    }
}
""",
    "k_inc_disguise": b"""//:: k_inc_disguise
/*
    This script contains all functions necessary to add and
    remove disguises on all party members.
*/
void DonEnvironmentSuit() {
    object oPC;
    int nMax = GetPartyMemberCount();
    int nIdx;
    effect eChange = EffectDisguise(DISGUISE_TYPE_ENVIRONMENTSUIT);
    for(nIdx = 0;nIdx < nMax; nIdx++)
    {
        ApplyEffectToObject(DURATION_TYPE_PERMANENT,eChange,GetPartyMemberByIndex(nIdx));
    }
}
void DonSpaceSuit() {
    int nMax = GetPartyMemberCount();
    int nIdx;
    effect eChange = EffectDisguise(DISGUISE_TYPE_ENVIRONMENTSUIT_02);
    for(nIdx = 0;nIdx < nMax; nIdx++)
    {
        object oPartyMember = GetPartyMemberByIndex(nIdx);
        ApplyEffectToObject(DURATION_TYPE_PERMANENT,eChange,oPartyMember);
    }
}
void RemoveDisguises() {
    int nDisguise = EFFECT_TYPE_DISGUISE;
    object oPC;
    effect eEffect;
    int nMax = GetPartyMemberCount();
    int nIdx;
    for(nIdx = 0;nIdx < nMax; nIdx++)
    {
        oPC = GetPartyMemberByIndex(nIdx);
        eEffect = GetFirstEffect(oPC);
        while(GetIsEffectValid(eEffect))
        {
            if(GetEffectType(eEffect) == nDisguise)
            {
                RemoveEffect(oPC,eEffect);
            }
            eEffect = GetNextEffect(oPC);
        }
    }
}
""",
    "k_inc_drop": b"""//::///////////////////////////////////////////////
//:: KOTOR Treasure drop Include
//:: k_inc_drop
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
// Contains the functions for handling creatures dropping random treasure
//Only human creatures not of the beast subrace willdrop treasure dependant
//on their hit dice
//:://////////////////////////////////////////////
//:: Created By: Aidan Scanlan On: 02/06/03
//:://////////////////////////////////////////////
int DR_HIGH_LEVEL = 15;
int DR_MEDIUM_LEVEL = 10;
int DR_LOW_LEVEL = 5;
int DR_SUBRACE_BEAST = 2;
//Checks for treasure drop conditions. Returns True if treasure will drop
int DR_SpawnCreatureTreasure(object oTarget = OBJECT_SELF);
//Dependant on the level of a creature drops treasure from a list
void DR_CreateRandomTreasure(object oTarget = OBJECT_SELF);
// creates a low level treasure: med pack/repair, frag grenade, credits
void DR_CreateLowTreasure();
// creates midlevel treasure: adv-med/repair, any gredade, stims, credits
void DR_CreateMidTreasure();
// creates high treasure: adv stims, grenades, ultra med/repair, credits
void DR_CreateHighTreasure();
// Creates 1-4 credits
void DR_CreateFillerCredits();
/////////////////////////////////////////////////////////////////////////
//Checks for treasure drop conditions. Returns True if treasure will drop
int DR_SpawnCreatureTreasure(object oTarget = OBJECT_SELF)
{
    int nRace = GetRacialType(oTarget);
    int nFaction = GetStandardFaction(oTarget);
    int nSubRace = GetSubRace(oTarget);
    if(Random(4) == 0 &&
       nRace != RACIAL_TYPE_DROID &&
       nSubRace != DR_SUBRACE_BEAST)
    {
        //AurPostString("will drop",5,5,5.0);
        DR_CreateRandomTreasure(oTarget);
        return TRUE;
    }
    return FALSE;
}
//Dependant on the level of a creature drops treasure from a list
void DR_CreateRandomTreasure(object oTarget = OBJECT_SELF)
{
    int nLevel = GetHitDice(oTarget);
    if (nLevel > DR_HIGH_LEVEL)
    {
        DR_CreateHighTreasure();
        if(Random(2) == 0)
        {
            DR_CreateHighTreasure();
        }
        if(Random(2) == 0)
        {
            DR_CreateMidTreasure();
        }
    }
    else if (nLevel <= DR_HIGH_LEVEL && nLevel > DR_MEDIUM_LEVEL)
    {
        DR_CreateMidTreasure();
        if(Random(3) == 0)
        {
            DR_CreateHighTreasure();
        }
        if(Random(2) == 0)
        {
            DR_CreateMidTreasure();
        }
    }
    else if (nLevel <= DR_MEDIUM_LEVEL && nLevel > DR_LOW_LEVEL)
    {
        DR_CreateMidTreasure();
        if(Random(2) == 0)
        {
            DR_CreateLowTreasure();
        }
    }
    else
    {
        DR_CreateLowTreasure();
        if(Random(3) == 0)
        {
            DR_CreateLowTreasure();
        }
        if(Random(4) == 0)
        {
            DR_CreateMidTreasure();
        }
    }
}
// creates a low level treasure: med pack/repair, frag grenade, credits
void DR_CreateLowTreasure()
{
   //AurPostString("dropping low",5,6,5.0);
    string sTemplate;
    int nStack = 1;
    int nRandom = Random(6);
    switch(nRandom)
    {
        case 0: sTemplate = "g_i_drdrepeqp001";  //repair kit
        break;
        case 1:
            sTemplate = "g_i_credits001";// 5 stack
            nStack = 5;
            DR_CreateFillerCredits();
        break;
        case 2:
            sTemplate = "g_i_credits002";  //10 stack
            nStack = 10;
            DR_CreateFillerCredits();
        break;
        case 3:
            sTemplate = "g_i_credits003";  // 25 stack
            nStack = 25;
            DR_CreateFillerCredits();
        break;
        case 4: sTemplate = "g_i_medeqpmnt01";// med kit
        break;
        case 5: sTemplate = "g_w_fraggren01"; // frag grenade
        break;
    }
    CreateItemOnObject(sTemplate,OBJECT_SELF,nStack);
}
// creates midlevel treasure: adv-med/repair, any gredade, stims, credits
void DR_CreateMidTreasure()
{
    string sTemplate;
    int nStack = 1;
    int nRandom = Random(15);
    switch (nRandom)
    {
        case 0: sTemplate = "g_i_drdrepeqp002";  //advanced repair kit
        break;
        case 1:
            sTemplate = "g_i_credits004";  // 50 stack
            nStack = 50;
            DR_CreateFillerCredits();
        break;
        case 2: sTemplate = "g_i_medeqpmnt02"; //advanced med pack
        break;
        case 3: sTemplate = "g_i_cmbtshot001"; //battle stimulant
        break;
        case 4: sTemplate = "g_i_adrnaline003";  //adrenal stamina
        break;
        case 5: sTemplate = "g_i_adrnaline002"; // adrenal alacrity
        break;
        case 6: sTemplate = "g_i_adrnaline001"; // adrenal strength
        break;
        case 7:
            sTemplate = "g_w_stungren01";  // stun grenade
            nStack = 2;
        break;
        case 8:
            sTemplate = "g_w_fraggren01";  // fragmentation grenade
            nStack = 2;
        break;
        case 9: sTemplate = "g_w_poisngren01"; // poison gredade
        break;
        case 10: sTemplate = "g_w_sonicgren01"; // sonic grenade
        break;
        case 11: sTemplate = "g_w_adhsvgren001"; // adhesive grenade
        break;
        case 12: sTemplate = "g_w_cryobgren001";// cryo grenade
        break;
        case 13: sTemplate = "g_w_iongren01";// ion grenade
        break;
    }
    CreateItemOnObject(sTemplate,OBJECT_SELF,nStack);
}
// creates high treasure: adv stims, grenades, ultra med/repair, credits
void DR_CreateHighTreasure()
{
    string sTemplate;
    int nStack = 1;
    int nRandom = Random(16);
    switch (nRandom)
    {
        case 0: sTemplate = "g_i_drdrepeqp003";  //super repair kit
        break;
        case 1: sTemplate = "g_w_thermldet01"; //Thermal detinator
        break;
        case 2: sTemplate = "g_i_medeqpmnt03"; //life pack
        break;
        case 3: sTemplate = "g_i_cmbtshot003";//speed stim
        break;
        case 4: sTemplate = "g_i_cmbtshot002"; //hyper battle stim
        break;
        case 5: sTemplate = "g_i_adrnaline006"; //huper adrenal stamina
        break;
        case 6: sTemplate = "g_i_adrnaline005"; //hyper adrenal alacrity
        break;
        case 7: sTemplate = "g_i_adrnaline004";// hyper adrenal strength
        break;
        case 8:
        sTemplate = "g_w_poisngren01"; // poison gredade
        nStack = 2;
        break;
        case 9:
        sTemplate = "g_w_sonicgren01"; // sonic grenade
        nStack = 2;
        break;
        case 10:
        sTemplate = "g_w_adhsvgren001"; // adhesive grenade
        nStack = 2;
        break;
        case 11:
        sTemplate = "g_w_cryobgren001";// cryo grenade
        nStack = 2;
        break;
        case 12:
        sTemplate = "g_w_firegren001";// plasma grenade
        nStack = 2;
        break;
        case 13:
        sTemplate = "g_w_iongren01";// ion grenade
        nStack = 2;
        break;
        case 14:
        sTemplate = "g_i_credits015";
        nStack = Random(50) + 50;
        break;
        case 15: sTemplate = "g_w_firegren001";// plasma grenade
        break;
    }
    CreateItemOnObject(sTemplate,OBJECT_SELF,nStack);
}
// Creates 1-4 credits
void DR_CreateFillerCredits()
{
    CreateItemOnObject("g_i_credits015",OBJECT_SELF,Random(4) + 1);
}
""",
    "k_inc_fab": b"""// k_inc_fab
/*
    Ferret's Wacky Include Script - YAY
    A running compilation of short cuts
    to make life easier
*/
// FAB 3/11
// This spawns in a creature with resref sCreature
// in waypoint location "sp_<sCreature><nInstance>"
object FAB_Spawn( string sCreature, int nInstance = 0 );
// This makes oAct face in the direction of oFace
// if oFace is left blank it defaults to the PC
void FAB_Face( object oAct, object oFace = OBJECT_INVALID );
// This function teleports the PC to oWP then any
// other CNPCs are teleported behind the PC.
// WARNING: Make sure that behind the waypoint there
// are valid points for the CNPCs to teleport to.
void FAB_PCPort( object oWP );
// This function returns a location directly behind the object
// you pass it. The float can be changed to determine how far
// behind the PC.
location FAB_Behind( object oTarg, float fMult = 2.5 );
// This spawns in a creature with resref sCreature
// in waypoint location "sp_<sCreature><nInstance>"
object FAB_Spawn( string sCreature, int nInstance = 0 )
{
    string sWP;
    if ( nInstance == 0 ) sWP = "sp_" + sCreature ;
    else sWP = "sp_" + sCreature + IntToString( nInstance );
    return CreateObject( OBJECT_TYPE_CREATURE, sCreature, GetLocation( GetObjectByTag( sWP ) ));
}
// This makes oAct face in the direction of oFace
// if oFace is left blank it defaults to the PC
void FAB_Face( object oAct, object oFace = OBJECT_INVALID )
{
    if ( oFace == OBJECT_INVALID ) oFace = GetFirstPC();
    AssignCommand( oAct, SetFacingPoint( GetPositionFromLocation(GetLocation(oFace)) ));
}
// This function teleports the PC to oWP then any
// other CNPCs are teleported behind the PC.
// WARNING: Make sure that behind the waypoint there
// are valid points for the CNPCs to teleport to.
void FAB_PCPort( object oWP )
{
    AurPostString("Testing!",5,4,2.0);
    //object oWP = GetObjectByTag( "tp_test" );
    //object oTarg = GetFirstPC();
    object oTarg = GetPartyMemberByIndex(0);
    DelayCommand( 0.1, AssignCommand( oTarg, ClearAllActions() ));
    DelayCommand( 0.2, AssignCommand( oTarg, ActionJumpToObject(oWP) ) );
    float fX = 0.0;
    float fY = 0.0;
    float fFacing = GetFacing( oWP ) + 0.0;
    float fFacing2 = GetFacing( oWP ) + 90.0;
    float fTempFace;
    vector vTest;
    if ( fFacing >  180.0 ) fTempFace = fFacing - 360.0;
    else fTempFace = fFacing;
    fTempFace = fTempFace / 90;
    if ( fTempFace < -1.0 ) fTempFace = -( fTempFace + 2.0 );
    if ( fTempFace > 1.0 ) fTempFace = -( fTempFace - 2.0 );
    fY = fTempFace * -2.5;
    // Come up with X adjust based on Facing2
    if ( fFacing2 > 360.0 ) fFacing2 = fFacing2 - 360.0;
    if ( fFacing2 >  180.0 ) fTempFace = fFacing2 - 360.0;
    else fTempFace = fFacing2;
    fTempFace = fTempFace / 90;
    if ( fTempFace < -1.0 ) fTempFace = -( fTempFace + 2.0 );
    if ( fTempFace > 1.0 ) fTempFace = -( fTempFace - 2.0 );
    fX = fTempFace * -2.5;
    //AurPostString("fFacing: " + FloatToString(fFacing),5,4,2.0);
    //AurPostString("fX: " + FloatToString(fX) + ", fY: " + FloatToString(fY),5,5,2.0);
    //oTarg = GetObjectByTag( "bith",0 );
    oTarg = GetPartyMemberByIndex(1);
    if( GetIsObjectValid(oTarg) && GetCurrentHitPoints(oTarg) > 1 )
    {
        SetCommandable(TRUE,oTarg);
        vTest = GetPositionFromLocation(GetLocation(oWP)) + Vector(fX,fY);
        DelayCommand( 0.1, AssignCommand( oTarg, ClearAllActions() ));
        DelayCommand( 0.2, AssignCommand( oTarg, ActionJumpToLocation( Location(vTest,fFacing) ) ));
        //SetCommandable(FALSE,oTarg);
    }
    //oTarg = GetObjectByTag( "bith",1 );
    oTarg = GetPartyMemberByIndex(2);
    if( GetIsObjectValid(oTarg) && GetCurrentHitPoints(oTarg) > 1 )
    {
        SetCommandable(TRUE,oTarg);
        vTest = GetPositionFromLocation(GetLocation(oWP)) + Vector(fX * 1.9,fY * 1.9);
        DelayCommand( 0.1, AssignCommand( oTarg, ClearAllActions() ));
        DelayCommand( 0.2, AssignCommand( oTarg, ActionJumpToLocation( Location(vTest,fFacing) ) ));
        //SetCommandable(FALSE,oTarg);
    }
}
// This function returns a location directly behind the object
// you pass it. The float can be changed to determine how far
// behind the PC.
location FAB_Behind( object oTarg, float fMult = 2.5 )
{
    float fX = 0.0;
    float fY = 0.0;
    float fFacing = GetFacing( oTarg ) + 0.0;
    float fFacing2 = GetFacing( oTarg ) + 90.0;
    float fTempFace;
    vector vTest;
    if ( fFacing >  180.0 ) fTempFace = fFacing - 360.0;
    else fTempFace = fFacing;
    fTempFace = fTempFace / 90;
    if ( fTempFace < -1.0 ) fTempFace = -( fTempFace + 2.0 );
    if ( fTempFace > 1.0 ) fTempFace = -( fTempFace - 2.0 );
    fY = fTempFace * - fMult;
    // Come up with X adjust based on Facing2
    if ( fFacing2 > 360.0 ) fFacing2 = fFacing2 - 360.0;
    if ( fFacing2 >  180.0 ) fTempFace = fFacing2 - 360.0;
    else fTempFace = fFacing2;
    fTempFace = fTempFace / 90;
    if ( fTempFace < -1.0 ) fTempFace = -( fTempFace + 2.0 );
    if ( fTempFace > 1.0 ) fTempFace = -( fTempFace - 2.0 );
    fX = fTempFace * - fMult;
    vTest = GetPositionFromLocation(GetLocation(oTarg)) + Vector(fX,fY);
    return Location( vTest,fFacing );
}
""",
    "k_inc_fakecombat": b"""//:: k_inc_fakecombat
/*
     routines for doing fake combat
*/
//:: Created By: Jason Booth
//:: Copyright (c) 2002 Bioware Corp.
#include "k_inc_generic"
void FAI_EnableFakeMode(object oTarget,int iFaction);
void FAI_DisableFakeMode(object oTarget,int iFaction);
void FAI_PerformFakeAttack(object oAttacker,object oTarget,int bLethal = FALSE);
void FAI_PerformFakeTalent(object oAttacker,object oTarget,talent t,int bLethal = FALSE);
void FAI_EnableFakeMode(object oTarget,int iFaction)
{
  if(!GetIsObjectValid(oTarget))
  {
    return;
  }
  SetCommandable(TRUE,oTarget);
  AssignCommand(oTarget,ClearAllActions());
  SetLocalBoolean(oTarget,SW_FLAG_AI_OFF,TRUE);
  AurPostString("TURNING AI OFF - " + GetTag(oTarget),5,5,5.0);
  ChangeToStandardFaction(oTarget,iFaction);
  SetMinOneHP(oTarget,TRUE);
}
void FAI_DisableFakeMode(object oTarget,int iFaction)
{
  if(!GetIsObjectValid(oTarget))
  {
    return;
  }
  SetCommandable(TRUE,oTarget);
  SetLocalBoolean(oTarget,SW_FLAG_AI_OFF,FALSE);
  ChangeToStandardFaction(oTarget,iFaction);
  SetMinOneHP(oTarget,FALSE);
}
void DoFakeAttack(object oTarget,int bLethal)
{
  if(bLethal)
  {
    SetMinOneHP(oTarget,FALSE);
    ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDamage(GetCurrentHitPoints(oTarget)-1),
      oTarget);
    //CutsceneAttack(oTarget,ACTION_ATTACKOBJECT,ATTACK_RESULT_HIT_SUCCESSFUL,1000);
  }
  //else
  //{
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectAssuredHit(),OBJECT_SELF,3.0);
    ActionAttack(oTarget);
 //}
}
void FAI_PerformFakeAttack(object oAttacker,object oTarget,int bLethal = FALSE)
{
  if(!GetIsObjectValid(oAttacker) || !GetIsObjectValid(oTarget))
  {
    return;
  }
  AssignCommand(oAttacker,ActionDoCommand(DoFakeAttack(oTarget,bLethal)));
}
void DoFakeTalent(object oTarget,talent t,int bLethal)
{
  if(bLethal)
  {
    SetMinOneHP(oTarget,FALSE);
    ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDamage(GetCurrentHitPoints(oTarget)-1),
      oTarget);
  }
  ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectAssuredHit(),OBJECT_SELF,3.0);
  ActionUseTalentOnObject(t,oTarget);
}
void FAI_PerformFakeTalent(object oAttacker,object oTarget,talent t,int bLethal = FALSE)
{
  if(!GetIsObjectValid(oAttacker) || !GetIsObjectValid(oTarget))
  {
    return;
  }
  AssignCommand(oAttacker,ActionDoCommand(DoFakeTalent(oTarget,t,bLethal)));
}
""",
    "k_inc_force": b"""//:: k_inc_force
/*
    v1.0
    Force Powers Include for KOTOR
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
float fLightningDuration = 1.0;
//These variables are set in the script run area.
int SWFP_PRIVATE_SAVE_TYPE;
int SWFP_PRIVATE_SAVE_VERSUS_TYPE;
int SWFP_DAMAGE;
int SWFP_DAMAGE_TYPE;
int SWFP_DAMAGE_VFX;
int SWFP_HARMFUL;
int SWFP_SHAPE;
//Runs the script section for the particular force power.
void  Sp_RunForcePowers();
//Immunity and Resist Spell check for the force power.
//The eDamage checks whether the target is immune to the damage effect
int Sp_BlockingChecks(object oTarget, effect eEffect, effect eEffect2, effect eDamage);
//Makes the necessary saving throws
int Sp_MySavingThrows(object oTarget, int iSpellDC = 0);
//Remove an effect of a specific type
void Sp_RemoveSpecificEffect(int nEffectTypeID, object oTarget);
//Remove an effect from a specific force power.
void Sp_RemoveSpellEffects(int nSpell_ID, object oCaster, object oTarget);
// Delays the application of a spell effect by an amount determined by distance.
float Sp_GetSpellEffectDelay(location SpellTargetLocation, object oTarget);
//Randomly delays the effect application for a default of 0.0 to 0.75 seconds
float Sp_GetRandomDelay(float fMinimumTime = 0.0, float MaximumTime = 0.75);
//Gets a saving throw appropriate to the jedi using the force power.
int Sp_GetJediDCSave();
///Apply effects in a sphere shape.
void Sp_SphereSaveHalf(object oAnchor, float fSize, int nCounter, effect eLink1, float fDuration1, effect eLink2, float fDuration);
//Apply effects to a single target.
void Sp_SingleTarget(object oAnchor, effect eLink1, float fDuration1, effect eLink2, float fDuration2);
//Apply effect to an area and negate on a save.
void Sp_SphereBlocking(object oAnchor, float fSize, int nCounter, effect eLink1, float fDuration1, effect eLink2, float fDuration);
// /Apply effect to an object and negate on a save.
void Sp_SingleTargetBlocking(object oAnchor, effect eLink1, float fDuration1, effect eLink2, float fDuration2);
//Apply effects for a for power.
void Sp_ApplyForcePowerEffects(float fTime, effect eEffect, object oTarget);
//Apply effects to targets.
void Sp_ApplyEffects(int nBlocking, object oAnchor, float fSize, int nCounter, effect eLink1, float fDuration1, effect eLink2, float fDuration2, int nRacial = RACIAL_TYPE_ALL);
//Removes all effects from the spells , Knights Mind, Mind Mastery and Battle Meditation
void Sp_RemoveBuffSpell();
//Prints a string for the spell stript
void SP_MyPrintString(string sString);
//Posts a string for the spell script
void SP_MyPostString(string sString, int n1 = 5, int n2 = 10, float fTime = 4.0);
//Interates through given a time period and a damage amount and hurts someone.  Checks if the person is in conversation.
void SP_InterativeDamage(effect eDamage, int nSecondsRemaining, object oTarget);
//Checks to see if the target is a Turret
int SP_CheckAppearanceTurret(object oTarget, int nFeedback = FALSE);
//Checks to see if the target is a Mark 1, 2, 4 or Spyder Droid
int SP_CheckAppearanceGeoDroid(object oTarget);
//Checks if the character already has Energy Resistance and Improved Energy Resistance
int SP_CheckEnergyResistance(object oTarget);
//This checks all of the delayed effect applications to make sure the target is still hostile and has not surrendered
void SP_MyApplyEffectToObject(int nDurationType, effect eEffect, object oTarget, float fDuration=0.0);
//Checks droids appearance type and if they have shields up
int SP_CheckAppearanceGeoDroidShields(object oTarget, int nFeedback = FALSE);
//Check push compatibility, if true is passed in for the Whirlwind an addition check for shields is made
int SP_CheckForcePushViability(object oTarget, int Whirlwind);
// DJS-OEI 12/9/2003
void Sp_RemoveRelatedPowers( object oTarget, int nPowerID );
int Sp_BetterRelatedPowerExists( object oTarget, int nPowerID );
void Sp_RemoveRelatedPowersInRadius( int nPowerID, float nRadius );
int Sp_IsJedi( object oTarget );
// DJS-OEI 3/25/2004
// Due to the addition of Lightsaber/Consular Forms and their
// frequent modification of damage, I've implemented this function
// to calculate the damage for a Force Power based on the parameters
// passed in, as well as adding in modifiers based on the target
// or caster's active Form.
int Sp_CalcDamage( object oTarget, int nNumDice, int nSizeDice, int nFlatAmount=0 );
// DJS-OEI 3/28/2004
// Similar to Sp_CalcDamage(), this function calculates the duration
// of a Force Power, taking into account the base duration as well
// as modifiers due to Consular Forms.
float Sp_CalcDuration( float fBaseDuration );
// DJS-OEI 3/29/2004
// Similar to Sp_CalcDamage(), this function calculates the range
// of a Force Power, taking into account the base range as well
// as modifiers due to Consular Forms.
float Sp_CalcRange( float fBaseRange );
//::///////////////////////////////////////////////
//:: Apply Delayed Effect
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This checks all of the delayed effect applications
    to make sure the target is still hostile and has
    not surrendered
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 20, 2003
//:://////////////////////////////////////////////
void SP_MyApplyEffectToObject(int nDurationType, effect eEffect, object oTarget, float fDuration=0.0)
{
    if(GetIsEnemy(oTarget))
    {
        ApplyEffectToObject(nDurationType, eEffect, oTarget, fDuration);
    }
}
//::///////////////////////////////////////////////
//:: Interative Damage
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Interates through given a time period and a
    damage amount and hurts someone.  Checks if
    the person is in conversation.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 5, 2003
//:://////////////////////////////////////////////
void SP_InterativeDamage(effect eDamage, int nSecondsRemaining, object oTarget)
{
    if(GetIsObjectValid(oTarget))
    {
        if(!GetIsConversationActive() && !GetIsDead(oTarget) && GetIsEnemy(oTarget))
        {
             if (nSecondsRemaining % 2 == 0)
             {
                  ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
             }
             --nSecondsRemaining;
             if (nSecondsRemaining > 0)
             {
                DelayCommand(1.0f, SP_InterativeDamage(eDamage, nSecondsRemaining, oTarget));
             }
        }
    }
}
//::///////////////////////////////////////////////
//:: Blocking Checks
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Does the Spell Resistance and Immunity
    Checks
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 15, 2002
//:://////////////////////////////////////////////
int Sp_BlockingChecks(object oTarget, effect eEffect1, effect eEffect2, effect eDamage)
{
    int nReturn = FALSE;
    //MODIFIED by Preston Watamaniuk on April 11th
    //Put the immunity check in place for Force Powers.
    if(GetIsLinkImmune(oTarget, eEffect1) || GetIsLinkImmune(oTarget, eEffect2) || GetIsLinkImmune(oTarget, eDamage))
    {
        DisplayFeedBackText(oTarget, 1);
        nReturn = TRUE;
    }
    // DJS-OEI 7/20/2004
    // Form/Stance re-design.
    /*
    // DJS-OEI 3/29/2004
    // Users of the Power of the Dark Side III Consular Form
    // are immune to any spell with the Form Mask for that Form.
    if( GetSpellFormMask( GetSpellId() ) & FORM_MASK_POWER_OF_THE_DARK_SIDE ) {
        if( IsFormActive( oTarget, FORM_CONSULAR_POWER_OF_THE_DARK_SIDE_III ) ) {
            DisplayFeedBackText(oTarget, 1);
            nReturn = TRUE;
        }
    }
    */
    if(ResistForce(OBJECT_SELF, oTarget))
    {
        DisplayFeedBackText(oTarget, 0);
        nReturn = TRUE;
    }
    if(nReturn == TRUE)
    {
        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
    }
    return nReturn;
}
// DJS-OEI 3/16/2004
int Sp_IsJedi( object oTarget ) {
    if( ( GetLevelByClass( CLASS_TYPE_JEDICONSULAR, oTarget ) > 0 ) ||
        ( GetLevelByClass( CLASS_TYPE_JEDIGUARDIAN, oTarget ) > 0 ) ||
        ( GetLevelByClass( CLASS_TYPE_JEDIMASTER, oTarget ) > 0 ) ||
        ( GetLevelByClass( CLASS_TYPE_JEDISENTINEL, oTarget ) > 0 ) ||
        ( GetLevelByClass( CLASS_TYPE_JEDIWATCHMAN, oTarget ) > 0 ) ||
        ( GetLevelByClass( CLASS_TYPE_JEDIWEAPONMASTER, oTarget ) > 0 ) ||
        ( GetLevelByClass( CLASS_TYPE_SITHASSASSIN, oTarget ) > 0 ) ||
        ( GetLevelByClass( CLASS_TYPE_SITHLORD, oTarget ) > 0 ) ||
        ( GetLevelByClass( CLASS_TYPE_SITHMARAUDER, oTarget ) > 0 ) ) {
        return TRUE;
    }
    return FALSE;
}
// DJS-OEI 3/25/2004
// Due to the addition of Lightsaber/Consular Forms and their
// frequent modification of damage, I've implemented this function
// to calculate the damage for a Force Power based on the parameters
// passed in, as well as adding in modifiers based on the target
// or caster's active Form.
int Sp_CalcDamage( object oTarget, int nNumDice, int nSizeDice, int nFlatAmount ) {
    int nDamage = 0;
    int nMod = 0;
    int nCounter = 0;
    if( nFlatAmount != 0 ) {
        nDamage = nFlatAmount;
    }
    else {
        // DJS-OEI 7/20/2004
        // Form/Stance re-design.
        /*
        // The caller is using using die rolls to determine.
        // damage. The Force Potency Form tree plays havoc
        // with this process since it can change rolls of 1 or 2
        // to higher values.
        if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_POTENCY_I ) ) {
            // Change all ones rolled to twos.
            int nRoll;
            for( nCounter=0; nCounter<nNumDice; nCounter++ ) {
                nRoll = Random( nSizeDice ) + 1;
                if( nRoll < 2 ) {
                    nRoll = 2;
                }
                nDamage += nRoll;
            }
        }
        else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_POTENCY_II ) ||
                 IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_POTENCY_III ) ) {
            // Change all ones and twos rolled to threes.
            int nRoll;
            for( nCounter=0; nCounter<nNumDice; nCounter++ ) {
                nRoll = Random( nSizeDice ) + 1;
                if( nRoll < 3 ) {
                    nRoll = 3;
                }
                nDamage += nRoll;
            }
        }
        */
        switch( nSizeDice ) {
            case 2:
                nDamage = d2( nNumDice );
                break;
            case 3:
                nDamage = d3( nNumDice );
                break;
            case 4:
                nDamage = d4( nNumDice );
                break;
            case 6:
                nDamage = d6( nNumDice );
                break;
            case 8:
                nDamage = d8( nNumDice );
                break;
            case 10:
                nDamage = d10( nNumDice );
                break;
            case 12:
                nDamage = d12( nNumDice );
                break;
            case 20:
                nDamage = d20( nNumDice );
                break;
            case 100:
                nDamage = d100( nNumDice );
                break;
            default:
                SP_MyPrintString("SP_CalcDamage() - Invalid Die Size:" + IntToString(nSizeDice));
                return 0;
                break;
        }
    }
    // DJS-OEI 7/20/2004
    // Form/Stance re-design.
    /////////////////////////////////////////////////
    // Modifiers due to caster's Form
    /////////////////////////////////////////////////
    // The Force Focus Form increases damage
    // for offensive Force Powers.
    if( IsFormActive( OBJECT_SELF, FORM_FORCE_I_FOCUS ) ) {
        // +3 to damage.
        nDamage += 3;
    }
    else if( IsFormActive( OBJECT_SELF, FORM_FORCE_II_POTENCY ) ) {
        // DJS-OEI 8/24/2004
        // Changed to +30%.
        /*
        // +1 damage for each class level. We'll just get the
        // levels attained for the base class and sub-class.
        int nTotalLevel = GetLevelByPosition( 1, OBJECT_SELF ) + GetLevelByPosition( 2, OBJECT_SELF );
        nDamage += nTotalLevel;
        */
        int nExtraDamage = ( nDamage * 30 ) / 100;
        nDamage += nExtraDamage;
    }
    /*
    // The Force Focus Lightsaber Form I-III increases damage
    // for offensive Force Powers.
    if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_FOCUS_I ) ) {
        // +1 to damage.
        nDamage += 1;
    }
    else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_FOCUS_II ) ) {
        // +3 to damage.
        nDamage += 3;
    }
    else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_FOCUS_III ) ) {
        // If the damage is a flat amount, just add 5. Otherwise, the
        // damage was calculated with die rolls. Increase the damage
        // by 1 for each die rolled.
        if( nFlatAmount == 0 ) {
            nDamage += nNumDice;
        }
        else {
            nDamage += 5;
        }
    }
    // The Force Potency Form I-III increases damage for offensive
    // Force Powers.
    if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_POTENCY_I ) ) {
        // If the damage is a flat amount, just add 5. Otherwise, the
        // damage was calculated with die rolls. Increase the damage
        // by 1 for each die rolled.
        if( nFlatAmount == 0 ) {
            nDamage += nNumDice;
        }
        else {
            nDamage += 5;
        }
    }
    else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_POTENCY_II ) ) {
        // If the damage is a flat amount, just add 7. Otherwise, the
        // damage was calculated with die rolls. Increase the damage
        // by 1 for each die rolled.
        if( nFlatAmount == 0 ) {
            nDamage += nNumDice;
        }
        else {
            nDamage += 7;
        }
    }
    else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_POTENCY_III ) ) {
        // If the damage is a flat amount, just add 10. Otherwise, the
        // damage was calculated with die rolls. Increase the damage
        // by 2 for each die rolled.
        if( nFlatAmount == 0 ) {
            nDamage += nNumDice*2;
        }
        else {
            nDamage += 10;
        }
    }
    // The Power of the Dark Side Form I-III increases damage for offensive
    // Force Powers.
    if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_POWER_OF_THE_DARK_SIDE_I ) ||
        IsFormActive( OBJECT_SELF, FORM_CONSULAR_POWER_OF_THE_DARK_SIDE_II ) ) {
        // If the damage is a flat amount, add nothing. Otherwise, the
        // damage was calculated with die rolls. Increase the damage
        // by 1 for each die rolled.
        if( nFlatAmount == 0 ) {
            nDamage += nNumDice;
        }
    }
    else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_POWER_OF_THE_DARK_SIDE_III ) ) {
        // If the damage is a flat amount, add nothing. Otherwise, the
        // damage was calculated with die rolls. Increase the damage
        // by 2 for each die rolled.
        if( nFlatAmount == 0 ) {
            nDamage += nNumDice*2;
        }
    }
    /////////////////////////////////////////////////
    // Modifiers due to target's Form
    /////////////////////////////////////////////////
    // The Ancient III Lightsaber Form and Force Armor III Form
    // both reduce damage by 1/2 of the target's level.
    if( IsFormActive( oTarget, FORM_LIGHTSABER_ANCIENT_III ) ||
        IsFormActive( oTarget, FORM_CONSULAR_FORCE_SHELL_III ) ) {
        nMod = GetHitDice( oTarget )/2;
        if( nDamage > nMod ) {
            nDamage -= nMod;
        }
        else {
            nDamage = 0;
        }
    }
    // The Force Armor II Form reduces damage by 4.
    if( IsFormActive( oTarget, FORM_CONSULAR_FORCE_SHELL_II ) ) {
        if( nDamage > 4 ) {
            nDamage -= 4;
        }
        else {
            nDamage = 0;
        }
    }
    */
    return nDamage;
}
// DJS-OEI 3/28/2004
// Similar to Sp_CalcDamage(), this function calculates the duration
// of a Force Power, taking into account the base duration as well
// as modifiers due to Consular Forms.
float Sp_CalcDuration( float fBaseDuration ) {
    float fFinalDuration = fBaseDuration;
    // DJS-OEI 7/20/2004
    // Form/Stance re-design.
    if( IsFormActive( OBJECT_SELF, FORM_FORCE_IV_MASTERY ) ) {
        // Duration is increased by 50%.
        fFinalDuration = fFinalDuration * 1.50f;
    }
    /*
    // If the Form Mask of the spell we're casting has the
    // Enduring Force mask, its duration can be modified
    // when Enduring Force is the caster's active Form.
    if( GetSpellFormMask( GetSpellId() ) & FORM_MASK_ENDURING_FORCE ) {
        if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_ENDURING_FORCE_I ) ) {
            // Duration is increased by 25%.
            fFinalDuration = fFinalDuration * 1.25f;
        }
        else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_ENDURING_FORCE_II ) ) {
            // Duration is increased by 50%.
            fFinalDuration = fFinalDuration * 1.50f;
        }
        else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_ENDURING_FORCE_III ) ) {
            // Duration is increased by 100%.
            fFinalDuration = fFinalDuration * 2.0f;
        }
    }
    */
    return fFinalDuration;
}
// DJS-OEI 3/29/2004
// Similar to Sp_CalcDamage(), this function calculates the range
// of a Force Power, taking into account the base range as well
// as modifiers due to Consular Forms.
float Sp_CalcRange( float fBaseRange ) {
    float fFinalRange = fBaseRange;
    // DJS-OEI 7/20/2004
    // Form/Stance re-design.
    /*
    // If the Form Mask of the spell we're casting has the
    // Force Amplification mask, its range can be modified
    // when Force Amplification is the caster's active Form.
    if( GetSpellFormMask( GetSpellId() ) & FORM_MASK_FORCE_AMPLIFICATION ) {
        if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_AMPLIFICATION_I ) ) {
            // Duration is increased by 25%.
            fFinalRange = fFinalRange * 1.25f;
        }
        else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_AMPLIFICATION_II ) ) {
            // Duration is increased by 50%.
            fFinalRange = fFinalRange * 1.50f;
        }
        else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_FORCE_AMPLIFICATION_III ) ) {
            // Duration is increased by 100%.
            fFinalRange = fFinalRange * 2.0f;
        }
    }
    */
    return fFinalRange;
}
int Sp_MySavingThrows(object oTarget, int iSpellDC = 0)
{
    int nSave;
    int nMod;
    // FAK - OEI , for allowing spell based DC
    if (iSpellDC > 0)
    {
        nMod = iSpellDC;
    }
    else
    {
        nMod = Sp_GetJediDCSave();
    }
    // DJS-OEI 7/20/2004
    // Form/Stance re-design.
    /////////////////////////////////////////////////
    // Modifiers due to caster's Form
    /////////////////////////////////////////////////
    if( IsFormActive( OBJECT_SELF, FORM_FORCE_IV_MASTERY ) ) {
        // +2 bonus to DC.
        nMod += 2;
    }
    /////////////////////////////////////////////////
    // Modifiers due to target's Form
    /////////////////////////////////////////////////
    // If the target has a bonus to saves, we just decrease
    // the DC by that amount. If it's a penalty, we increase it.
    if( IsFormActive( oTarget, FORM_SABER_II_MAKASHI ) ||
        IsFormActive( oTarget, FORM_FORCE_I_FOCUS ) ) {
        // +2 bonus to save.
        nMod -= 2;
    }
    else if( IsFormActive( oTarget, FORM_SABER_VI_NIMAN ) ) {
        // +1 bonus to save.
        nMod -= 1;
    }
    else if( IsFormActive( oTarget, FORM_SABER_VII_JUYO ) ||
             IsFormActive( oTarget, FORM_FORCE_IV_MASTERY ) ) {
        // -4 penalty to save.
        nMod += 4;
    }
    /*
    /////////////////////////////////////////////////
    // Modifiers due to caster's Form
    /////////////////////////////////////////////////
    // DJS-OEI 3/25/2004
    // The Power of the Dark Side Form provides bonuses to the
    // DC of the save.
    if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_POWER_OF_THE_DARK_SIDE_I ) ) {
        // +1 bonus to DC.
        nMod += 1;
    }
    else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_POWER_OF_THE_DARK_SIDE_II ) ||
             IsFormActive( OBJECT_SELF, FORM_CONSULAR_POWER_OF_THE_DARK_SIDE_III ) ) {
        // +2 bonus to DC.
        nMod += 2;
    }
    /////////////////////////////////////////////////
    // Modifiers due to target's Form
    /////////////////////////////////////////////////
    // DJS-OEI 3/16/2004
    // The Total Defense Stance gives Jedis a +4 to their
    // saving throws versus force powers. We just decrease
    // the DC by that amount.
    if( IsInTotalDefense( oTarget ) && Sp_IsJedi( oTarget ) ) {
        nMod -= 4;
    }
    // DJS-OEI 3/25/2004
    // The Ancient Lightsaber Form provides bonuses to saves,
    // which we handle as decreases to the DC.
    if( IsFormActive( oTarget, FORM_LIGHTSABER_ANCIENT_I ) ||
        IsFormActive( oTarget, FORM_LIGHTSABER_ANCIENT_II ) ) {
        // +1 bonus to save.
        nMod -= 1;
    }
    else if( IsFormActive( oTarget, FORM_LIGHTSABER_ANCIENT_III ) ) {
        // +2 bonus to save.
        nMod -= 2;
    }
    // DJS-OEI 3/25/2004
    // The Force Armor I-III Form provides bonuses to saves,
    // which we handle as decreases to the DC.
    if( IsFormActive( oTarget, FORM_CONSULAR_FORCE_SHELL_I ) ) {
        // +2 bonus to save.
        nMod -= 2;
    }
    else if( IsFormActive( oTarget, FORM_CONSULAR_FORCE_SHELL_II ) ) {
        // +4 bonus to save.
        nMod -= 4;
    }
    else if( IsFormActive( oTarget, FORM_CONSULAR_FORCE_SHELL_III ) ) {
        // +6 bonus to save.
        nMod -= 6;
    }
    */
    if( nMod < 0 ) {
        nMod = 0;
    }
    if(SWFP_PRIVATE_SAVE_TYPE == SAVING_THROW_FORT)
    {
        nSave = FortitudeSave(oTarget,nMod, SWFP_PRIVATE_SAVE_VERSUS_TYPE);
        SP_MyPrintString("Fort Save = " + IntToString(nSave) + " For DC of " + IntToString(nMod));
    }
    else if(SWFP_PRIVATE_SAVE_TYPE == SAVING_THROW_REFLEX)
    {
        nSave = ReflexSave(oTarget, nMod, SWFP_PRIVATE_SAVE_VERSUS_TYPE);
        SP_MyPrintString("Reflex Save = " + IntToString(nSave)+" For DC of " + IntToString(nMod));
    }
    else if(SWFP_PRIVATE_SAVE_TYPE == SAVING_THROW_WILL)
    {
        nSave = WillSave(oTarget, nMod, SWFP_PRIVATE_SAVE_VERSUS_TYPE);
        SP_MyPrintString("Will Save = " + IntToString(nSave)+" For DC of " + IntToString(nMod));
    }
    if(nSave > 0)
    {
        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
        DisplayFeedBackText(oTarget, 2);
    }
    return nSave;
}
void Sp_RemoveSpellEffects(int nSpell_ID, object oCaster, object oTarget)
{
    //Declare major variables
    int bValid = FALSE;
    effect eAOE;
    if(GetHasSpellEffect(nSpell_ID, oTarget))
    {
        //Search through the valid effects on the target.
        eAOE = GetFirstEffect(oTarget);
        while (GetIsEffectValid(eAOE) && bValid == FALSE)
        {
            if (GetEffectCreator(eAOE) == oCaster)
            {
                //If the effect was created by the spell then remove it
                if(GetEffectSpellId(eAOE) == nSpell_ID)
                {
                    RemoveEffect(oTarget, eAOE);
                    bValid = TRUE;
                }
            }
            //Get next effect on the target
            eAOE = GetNextEffect(oTarget);
        }
    }
}
void Sp_RemoveSpecificEffect(int nEffectTypeID, object oTarget)
{
    //Declare major variables
    //Get the object that is exiting the AOE
    int bValid = FALSE;
    effect eAOE;
    //Search through the valid effects on the target.
    eAOE = GetFirstEffect(oTarget);
    while (GetIsEffectValid(eAOE))
    {
        if (GetEffectType(eAOE) == nEffectTypeID)
        {
            //If the effect was created by the spell then remove it
            bValid = TRUE;
            RemoveEffect(oTarget, eAOE);
        }
        //Get next effect on the target
        eAOE = GetNextEffect(oTarget);
    }
}
float Sp_GetSpellEffectDelay(location SpellTargetLocation, object oTarget)
{
    float fDelay;
    return fDelay = GetDistanceBetweenLocations(SpellTargetLocation, GetLocation(oTarget))/20;
}
float Sp_GetRandomDelay(float fMinimumTime = 0.4, float MaximumTime = 1.1)
{
    float fRandom = MaximumTime - fMinimumTime;
    int nRandom;
    if(fRandom < 0.0)
    {
        return 0.0;
    }
    else
    {
        nRandom = FloatToInt(fRandom  * 10.0);
        nRandom = Random(nRandom) + 1;
        fRandom = IntToFloat(nRandom);
        fRandom /= 10.0;
        return fRandom + fMinimumTime;
    }
}
int Sp_GetJediDCSave()
{
    int nDC = GetSpellSaveDC();
    return nDC;
}
void Sp_ApplyForcePowerEffects(float fTime, effect eEffect, object oTarget)
{
    float fDelay;
    int nRoll = d6();
    fDelay = IntToFloat(nRoll)/10.0;
    if(fTime == 1000.0)
    {
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
    }
    else if(fTime == 0.0)
    {
        DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget));
    }
    else
    {
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oTarget, fTime);
    }
}
int SP_CheckEnergyResistance(object oTarget)
{
    // DJS-OEI 12/9/2003
    // Added Master Energy Resistance to the check.
    if( GetHasSpellEffect(FORCE_POWER_RESIST_COLD_HEAT_ENERGY, oTarget) ||
        GetHasSpellEffect(FORCE_POWER_RESIST_POISON_DISEASE_SONIC, oTarget) ||
        GetHasSpellEffect(FORCE_POWER_MASTER_ENERGY_RESISTANCE, oTarget) )
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Runs the specified force power.
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Runs the script for the particular force power.
    SWFP_HARMFUL = ;
    SWFP_PRIVATE_SAVE_TYPE;
    SWFP_PRIVATE_SAVE_VERSUS_TYPE;
    SWFP_DAMAGE;
    SWFP_DAMAGE_TYPE;
    SWFP_DAMAGE_VFX;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 30, 2002
//:://////////////////////////////////////////////
void  Sp_RunForcePowers()
{
    object oTarget = GetSpellTargetObject();
    effect eLink1, eLink2;
    effect eInvalid;
    SWFP_SHAPE = SHAPE_SPHERE;
    //P.W. (June 8) This makes the Taris Calo Nord immune to Force Push, breaks the cutscene if not.
    if(GetTag(oTarget) == "Calo082" && GetSpellId() == FORCE_POWER_FORCE_PUSH)
    {
        DisplayFeedBackText(oTarget, 1);
        return;
    }
    // DJS-OEI 10/18/2004
    // I'm going to jump on the hack bandwagon and make sure General Vaklu can't
    // be affected by Confusion.
    if(GetTag(oTarget) == "vaklu" && GetSpellId() == FORCE_POWER_CONFUSION)
    {
        DisplayFeedBackText(oTarget, 1);
        return;
    }
    // DJS-OEI 10/22/2004
    // Also made Bralor immune.
    else if(GetTag(oTarget) == "npc_bralor" && GetSpellId() == FORCE_POWER_CONFUSION)
    {
        DisplayFeedBackText(oTarget, 1);
        return;
    }
    switch (GetSpellId())
    {
        /*
        AFFLICTION
        */
        case FORCE_POWER_AFFLICTION:
        {
            // If the target is already poisoned in any way, don't
            // apply this effect.
            if(!GetIsPoisoned(oTarget))
            {
                // DJS-OEI 12/9/2003
                // For KotOR2, we have decided to modify the application behavior
                // of Force Power trees. Lower level versions of Force Powers will
                // no longer overwrite higher level versions, although this means
                // the caster still loses their Force Points to no effect. Also,
                // casting a Force Power will remove any Force Powers of equal or
                // lesser level prior to applying themselves.
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( oTarget, FORCE_POWER_AFFLICTION );
                // Do not apply the effects of this power if a more powerful
                // version is already attached to the target.
                if( !Sp_BetterRelatedPowerExists( oTarget, FORCE_POWER_AFFLICTION ) ) {
                    SWFP_HARMFUL = TRUE;
                    eLink1 = EffectPoison(POISON_ABILITY_SCORE_AVERAGE);
                    eLink1 = EffectLinkEffects(eLink1, EffectMovementSpeedDecrease(50));
                    //eLink1 = SetEffectIcon(eLink1, 23);
                    eLink1 = SetEffectIcon(eLink1, 1);//RWT-OEI 07/08/04 - Affliction is a specific effect
                    //Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 1000.0, eInvalid, 0.0);
                    //RWT-OEI 09/27/04 - Apparently this is supposed to last 21 seconds.
                    Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 21.0, eInvalid, 0.0);
                }
            }
            // DJS-OEI 10/22/2004
            else {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
            }
        }
        break;
        /*
        CHOKE
        */
        case FORCE_POWER_CHOKE:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            // DJS-OEI 3/25/2004
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, 0, 0, (GetHitDice(OBJECT_SELF)*2)/3 );
            //SWFP_DAMAGE = (GetHitDice(OBJECT_SELF)*2)/3;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            SWFP_DAMAGE_VFX = VFX_IMP_CHOKE;
            eLink1 = EffectAbilityDecrease(ABILITY_CONSTITUTION, 4);
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityDecrease(ABILITY_STRENGTH, 4));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityDecrease(ABILITY_DEXTERITY, 4));
            eLink1 = SetEffectIcon(eLink1, 3);
            effect eChoke = EffectChoke();
            effect eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
            int nResist = Sp_BlockingChecks(oTarget, eChoke, eDamage, eInvalid);
            int nSaves;
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if(nResist == 0)
            {
                nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_CHOKE), oTarget);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eChoke, oTarget, 6.0);
                    float fDuration = Sp_CalcDuration( 24.0 );
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                    int nIdx = 1;
                    float fDelay;
                    SP_InterativeDamage(eDamage, 7, oTarget);
                }
            }
            if(nResist > 0 || nSaves > 0)
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        /*
        HEAL
        */
        //MODIFIED by Preston Watamaniuk March 28
        // Remove cure poison and reduced the amount by 5
        case FORCE_POWER_CURE:
        {
            SWFP_HARMFUL = FALSE;
            // DJS-OEI 3/29/2004
            // The Regeneration Consular Forms increase the relevance of
            // the Wisdom and Charisma modifiers.
            int nMultiplier = 1;
            // DJS-OEI 7/20/2004
            // Form/Stance re-design.
            /*
            if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_REGENERATION_I ) ) {
                nMultiplier = 2;
            }
            else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_REGENERATION_II ) ||
                     IsFormActive( OBJECT_SELF, FORM_CONSULAR_REGENERATION_III ) ) {
                nMultiplier = 3;
            }
            */
            int nHeal = ( ( GetAbilityModifier(ABILITY_WISDOM) + GetAbilityModifier(ABILITY_CHARISMA) ) * nMultiplier ) + 5 + GetHitDice(OBJECT_SELF);
            effect eVis =  EffectVisualEffect(VFX_IMP_CURE);
            int nCnt = 0;
            object oParty;
            if(IsObjectPartyMember(OBJECT_SELF))
            {
                oParty = GetPartyMemberByIndex(nCnt);
            }
            else
            {
                oParty = OBJECT_SELF;
            }
            while(nCnt < 3)
            {
                if(GetIsObjectValid(oParty) &&
                   GetRacialType(oParty) != RACIAL_TYPE_DROID &&
                   GetDistanceBetween(OBJECT_SELF, oParty) < 15.0)
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), FALSE));
                    //Sp_RemoveSpecificEffect(EFFECT_TYPE_POISON, oParty);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oParty);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHeal), oParty);
                }
                nCnt++;
                if(IsObjectPartyMember(OBJECT_SELF))
                {
                   oParty = GetPartyMemberByIndex(nCnt);
                }
                else
                {
                   oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt);
                }
            }
        }
        break;
        /*
        DEATH FIELD
        */
        case FORCE_POWER_DEATH_FIELD:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_DARK_SIDE;
            int nDamTest = GetHitDice(OBJECT_SELF);
            if(nDamTest > 10)
            {
                nDamTest = 10;
            }
            // DJS-OEI 3/25/2004
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, nDamTest, 4 );
            //SWFP_DAMAGE = d4(nDamTest);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_DARK_SIDE;
            SWFP_DAMAGE_VFX = VFX_PRO_DEATH_FIELD;
            int nHealCount;
            int nDamage = SWFP_DAMAGE/2;
            effect eDamage;
            effect eBeam = EffectBeam(VFX_BEAM_DEATH_FIELD_TENTACLE, OBJECT_SELF, BODY_NODE_HEAD);
            effect eVFX = EffectVisualEffect(VFX_PRO_DEATH_FIELD);
            //object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 12.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 12.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oTarget))
            {
                int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eDamage);
                if((GetRacialType(oTarget) == RACIAL_TYPE_HUMAN &&
                   GetRacialType(oTarget) != RACIAL_TYPE_DROID) || GetObjectType(oTarget) == OBJECT_TYPE_PLACEABLE)
                {
                    if(GetIsEnemy(oTarget))
                    {
                        SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                        if(nResist == 0)
                        {
                            int nSaves = Sp_MySavingThrows(oTarget);
                            if(nSaves == FALSE)
                            {
                                eDamage =  EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                                nHealCount += SWFP_DAMAGE;
                            }
                            else
                            {
                                eDamage =  EffectDamage(nDamage, SWFP_DAMAGE_TYPE);
                                nHealCount += nDamage;
                            }
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, fLightningDuration);
                        }
                        else
                        {
                            //effect eBeam2 = EffectBeam(VFX_BEAM_DEATH_FIELD_TENTACLE, OBJECT_SELF, BODY_NODE_HEAD, TRUE);
                            //ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, fLightningDuration);
                        }
                    }
                }
                //oTarget = GetNextObjectInShape(SHAPE_SPHERE, 12.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
                oTarget = GetNextObjectInShape(SHAPE_SPHERE, 12.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
            if(GetCurrentHitPoints(OBJECT_SELF) < GetMaxHitPoints(OBJECT_SELF) && nHealCount > 0)
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHealCount), OBJECT_SELF);
            }
        }
        break;
        /*
        DRAIN LIFE
        */
        case FORCE_POWER_DRAIN_LIFE:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            int nDam = GetHitDice(OBJECT_SELF);
            int nDamTest = GetHitDice(OBJECT_SELF);
            if(nDamTest > 10)
            {
                nDamTest = 10;
            }
            // DJS-OEI 3/25/2004
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, nDamTest, 4 );
            //SWFP_DAMAGE = d4(nDamTest);
            SWFP_DAMAGE_TYPE= DAMAGE_TYPE_DARK_SIDE;
            SWFP_DAMAGE_VFX = VFX_PRO_DRAIN;
            //Set up the drain effect link for the target
            effect eBeam = EffectBeam(VFX_BEAM_DRAIN_LIFE, OBJECT_SELF, BODY_NODE_HAND);
            effect eVFX = EffectVisualEffect(SWFP_DAMAGE_VFX);
            //Set up the link to Heal the user by the same amount.
            effect eHeal;
            effect eDamage = EffectDamage(SWFP_DAMAGE, DAMAGE_TYPE_DARK_SIDE);
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, fLightningDuration);
            DelayCommand(0.3, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget));
            int nResist = Sp_BlockingChecks(oTarget, eDamage, eInvalid, eInvalid);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if(GetRacialType(oTarget) != RACIAL_TYPE_DROID)
            {
                if(nResist == 0)
                {
                    int nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves > 0)
                    {
                        SWFP_DAMAGE /= 2;
                    }
                    eDamage = EffectDamage(SWFP_DAMAGE,  DAMAGE_TYPE_DARK_SIDE);
                    if(GetCurrentHitPoints(OBJECT_SELF) < GetMaxHitPoints(OBJECT_SELF) && SWFP_DAMAGE > 0)
                    {
                        eHeal = EffectHeal(SWFP_DAMAGE);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, OBJECT_SELF);
                    }
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                }
            }
        }
        break;
        /*
        DESTROY DROID
        */
        case FORCE_POWER_DROID_DESTROY:
        {
            int bIsMine = FALSE;
            //RWT-OEI 08/31/04 - Need to special case the mine stuff
            //everywhere below.
            //We don't have to confirm that the targetted trap is the
            //right level of trap to get blown up because it wouldn't
            //have been targettable otherwise. But all the traps in the loop
            //for the AoE portion will have to be tested.
            if ( GetObjectType(oTarget) == OBJECT_TYPE_TRIGGER )
            {
                //Check for MINOR and AVERAGE and STRONG trap types now
                int nMineType = GetTrapBaseType(oTarget);
                if ( !GetIsTrapped(oTarget) )
                {
                    nMineType = -1;
                }
                if ( nMineType == TRAP_BASE_TYPE_FLASH_STUN_MINOR            ||
                     nMineType == TRAP_BASE_TYPE_FLASH_STUN_AVERAGE          ||
                     nMineType == TRAP_BASE_TYPE_FLASH_STUN_STRONG           ||
                     nMineType == TRAP_BASE_TYPE_FRAGMENTATION_MINE_MINOR     ||
                     nMineType == TRAP_BASE_TYPE_FRAGMENTATION_MINE_AVERAGE  ||
                     nMineType == TRAP_BASE_TYPE_FRAGMENTATION_MINE_STRONG   ||
                     nMineType == TRAP_BASE_TYPE_LASER_SLICING_MINOR         ||
                     nMineType == TRAP_BASE_TYPE_LASER_SLICING_AVERAGE       ||
                     nMineType == TRAP_BASE_TYPE_LASER_SLICING_STRONG        ||
                     nMineType == TRAP_BASE_TYPE_POISON_GAS_MINOR            ||
                     nMineType == TRAP_BASE_TYPE_POISON_GAS_AVERAGE          ||
                     nMineType == TRAP_BASE_TYPE_POISON_GAS_STRONG           ||
                     nMineType == TRAP_BASE_TYPE_SONIC_CHARGE_MINOR          ||
                     nMineType == TRAP_BASE_TYPE_SONIC_CHARGE_AVERAGE        ||
                     nMineType == TRAP_BASE_TYPE_SONIC_CHARGE_STRONG
                     )
                 {
                     bIsMine = TRUE;
                 }
                 else
                 {
                    break;//Somehow a non-mine trigger got targetted. Just bail
                 }
            }
            SWFP_HARMFUL = TRUE;
            //SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;//RWT-OEI 09/27/04
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_ELECTRICAL;
            float fRange = Sp_CalcRange( 6.0 );
            eLink1 = EffectBeam(VFX_BEAM_DROID_DESTROY, oTarget, BODY_NODE_CHEST);
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_PRO_LIGHTNING_L));
            eLink2 = EffectDroidStun();
            eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(1008));
            eLink2 = SetEffectIcon(eLink2, 5);
            effect eLink3 = EffectBeam(VFX_BEAM_DROID_DESTROY, OBJECT_SELF, BODY_NODE_HAND);
            eLink3 = EffectLinkEffects(eLink3, EffectVisualEffect(VFX_PRO_LIGHTNING_L));
            // DJS-OEI 3/25/2004
            int nDamage = Sp_CalcDamage( oTarget, GetHitDice(OBJECT_SELF), 6 );
            //int nDamage = d6(GetHitDice(OBJECT_SELF));
            int nApply;
            // DJS-OEI 11/20/2003
            // If the target has the Evasion feat, the damage on a successful
            // Reflex save is 0. Otherwise, it's half the original damage.
            if( GetHasFeat( FEAT_EVASION, oTarget ) ) {
                nApply = 0;
            }
            else {
                nApply = nDamage/2;
            }
            effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_ELECTRICAL);;
            effect eSaveDamage = EffectDamage(nApply, DAMAGE_TYPE_ELECTRICAL);
            //Apply Effects to the first droid targeted.
            int nResist = 0;
            if ( !bIsMine )
            {
                nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
            }
            int nSaves = 0;
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink3, oTarget, fLightningDuration);
            if(nResist == 0)
            {
                if (!bIsMine)
                {
                    nSaves = Sp_MySavingThrows(oTarget);
                }
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage , oTarget);
                    float fDuration = Sp_CalcDuration( 12.0 );
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, fDuration);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eSaveDamage , oTarget);
                }
            }
            else
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
            //RWT-OEI 08/31/04 - Cache location here since this object goes baibai
            location lTarget = GetLocation(oTarget);
            if ( bIsMine )
            {
                AssignCommand(oTarget,ExecuteScript( "k_trp_generic",oTarget));
                DetonateMine(oTarget);
            }
            //Start going through all hostile droids around the primary target
            //object oSecond = GetFirstObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            object oSecond = GetFirstObjectInShape(SHAPE_SPHERE, fRange, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_TRIGGER);
            while(GetIsObjectValid(oSecond))
            {
                int bIsMine2 = FALSE;
                if (GetObjectType(oSecond) == OBJECT_TYPE_TRIGGER)
                {
                    //Check for MINOR, AVERAGE, and STRONG mine types here
                    int nMineType2 = GetTrapBaseType(oSecond);
                    if ( !GetIsTrapped(oSecond) )
                    {
                        nMineType2 = -1;
                    }
                    if (nMineType2 == TRAP_BASE_TYPE_FLASH_STUN_MINOR            ||
                        nMineType2 == TRAP_BASE_TYPE_FLASH_STUN_AVERAGE          ||
                        nMineType2 == TRAP_BASE_TYPE_FLASH_STUN_STRONG           ||
                        nMineType2 == TRAP_BASE_TYPE_FRAGMENTATION_MINE_MINOR     ||
                        nMineType2 == TRAP_BASE_TYPE_FRAGMENTATION_MINE_AVERAGE  ||
                        nMineType2 == TRAP_BASE_TYPE_FRAGMENTATION_MINE_STRONG   ||
                        nMineType2 == TRAP_BASE_TYPE_LASER_SLICING_MINOR         ||
                        nMineType2 == TRAP_BASE_TYPE_LASER_SLICING_AVERAGE       ||
                        nMineType2 == TRAP_BASE_TYPE_LASER_SLICING_STRONG        ||
                        nMineType2 == TRAP_BASE_TYPE_POISON_GAS_MINOR            ||
                        nMineType2 == TRAP_BASE_TYPE_POISON_GAS_AVERAGE          ||
                        nMineType2 == TRAP_BASE_TYPE_POISON_GAS_STRONG           ||
                        nMineType2 == TRAP_BASE_TYPE_SONIC_CHARGE_MINOR          ||
                        nMineType2 == TRAP_BASE_TYPE_SONIC_CHARGE_AVERAGE        ||
                        nMineType2 == TRAP_BASE_TYPE_SONIC_CHARGE_STRONG
                        )
                    {
                        bIsMine2 = TRUE;
                    }
                    else
                    {
                        continue;//This is a non-mine trigger. Just skip it.
                    }
                }
                if(oSecond != oTarget && GetIsEnemy(oSecond) && (GetRacialType(oSecond) == RACIAL_TYPE_DROID || bIsMine2))
                {
                    if ( !bIsMine2 )
                    {
                        nResist = Sp_BlockingChecks(oSecond, eLink1, eLink2, eInvalid);
                    }
                    else
                    {
                        nResist = 0;
                    }
                    SignalEvent(oSecond, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    if(nResist == 0)
                    {
                        if ( !bIsMine2 )
                        {
                            nSaves = Sp_MySavingThrows(oSecond);
                        }
                        else
                        {
                            nSaves = 0;
                        }
                        //Apply the beam effect and hit regardless because damage is still done.
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oSecond, fLightningDuration);
                        if(nSaves == 0)
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage , oSecond);
                            float fDuration = Sp_CalcDuration( 12.0 );
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oSecond, fDuration);
                        }
                        else
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eSaveDamage , oSecond);
                        }
                        if ( bIsMine2 )
                        {
                            AssignCommand(oSecond,ExecuteScript( "k_trp_generic",oSecond));
                            DetonateMine(oSecond);
                        }
                    }
                }
                //oSecond = GetNextObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
                oSecond = GetNextObjectInShape(SHAPE_SPHERE, fRange, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_TRIGGER);
            }
        }
        break;
        /*
        DISABLE DROID
        */
        case FORCE_POWER_DROID_DISABLE:
        {
            int bIsMine = FALSE;
            //RWT-OEI 08/31/04 - Need to special case the mine stuff
            //everywhere below.
            //We don't have to confirm that the targetted trap is the
            //right level of trap to get blown up because it wouldn't
            //have been targettable otherwise. But all the traps in the loop
            //for the AoE portion will have to be tested.
            if ( GetObjectType(oTarget) == OBJECT_TYPE_TRIGGER )
            {
                //Check for MINOR and AVERAGE trap types now
                int nMineType = GetTrapBaseType(oTarget);
                if ( !GetIsTrapped(oTarget) )
                {
                    nMineType = -1;
                }
                if ( nMineType == TRAP_BASE_TYPE_FLASH_STUN_MINOR            ||
                     nMineType == TRAP_BASE_TYPE_FLASH_STUN_AVERAGE          ||
                     nMineType == TRAP_BASE_TYPE_FRAGMENTATION_MINE_MINOR     ||
                     nMineType == TRAP_BASE_TYPE_FRAGMENTATION_MINE_AVERAGE  ||
                     nMineType == TRAP_BASE_TYPE_LASER_SLICING_MINOR         ||
                     nMineType == TRAP_BASE_TYPE_LASER_SLICING_AVERAGE       ||
                     nMineType == TRAP_BASE_TYPE_POISON_GAS_MINOR            ||
                     nMineType == TRAP_BASE_TYPE_POISON_GAS_AVERAGE          ||
                     nMineType == TRAP_BASE_TYPE_SONIC_CHARGE_MINOR          ||
                     nMineType == TRAP_BASE_TYPE_SONIC_CHARGE_AVERAGE )
                 {
                     bIsMine = TRUE;
                 }
                 else
                 {
                    break;//Somehow a non-mine trigger got targetted. Bail
                 }
            }
            SWFP_HARMFUL = TRUE;
            //SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;//RWT-OEI 09/27/04
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_ELECTRICAL;
            float fRange = Sp_CalcRange( 5.0 );
            eLink1 = EffectBeam(VFX_BEAM_DROID_DESTROY, oTarget, BODY_NODE_CHEST);
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_PRO_LIGHTNING_L));
            eLink2 = EffectDroidStun();
            eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(1008));
            eLink2 = SetEffectIcon(eLink2, 4);
            effect eLink3 = EffectBeam(VFX_BEAM_DROID_DISABLE, OBJECT_SELF, BODY_NODE_HAND);
            eLink3 = EffectLinkEffects(eLink3, EffectVisualEffect(VFX_PRO_LIGHTNING_L));
            // DJS-OEI 3/25/2004
            int nDamage = Sp_CalcDamage( oTarget, 0, 0, GetHitDice(OBJECT_SELF) );
            //int nDamage = GetHitDice(OBJECT_SELF);
            int nApply;
            // DJS-OEI 11/20/2003
            // If the target has the Evasion feat, the damage on a successful
            // Reflex save is 0. Otherwise, it's half the original damage.
            if( GetHasFeat( FEAT_EVASION, oTarget ) ) {
                nApply = 0;
            }
            else {
                nApply = nDamage/2;
            }
            effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_ELECTRICAL);;
            effect eSaveDamage = EffectDamage(nApply, DAMAGE_TYPE_ELECTRICAL);
            //Apply Effects to the first droid targeted.
            int nResist = 0;
            if ( !bIsMine )
            {
                nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
            }
            int nSaves = 0;
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink3, oTarget, fLightningDuration);
            if(nResist == 0)
            {
                if ( !bIsMine )
                {
                    nSaves = Sp_MySavingThrows(oTarget);
                }
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage , oTarget);
                    float fDuration = Sp_CalcDuration( 12.0 );
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, fDuration);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eSaveDamage , oTarget);
                }
            }
            else
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
            location lTarget = GetLocation(oTarget);
            if ( bIsMine )
            {
                AssignCommand(oTarget,ExecuteScript( "k_trp_generic",oTarget));
                DetonateMine(oTarget);
            }
            //Start going through all hostile droids around the primary target
            //object oSecond = GetFirstObjectInShape(SHAPE_SPHERE, fRange, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            object oSecond = GetFirstObjectInShape(SHAPE_SPHERE, fRange, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_TRIGGER);
            while(GetIsObjectValid(oSecond))
            {
                int bIsMine2 = FALSE;
                if (GetObjectType(oSecond) == OBJECT_TYPE_TRIGGER)
                {
                    int nMineType2 = GetTrapBaseType(oSecond);
                    if ( !GetIsTrapped(oSecond))
                    {
                        nMineType2 = -1;
                    }
                    if (nMineType2 == TRAP_BASE_TYPE_FLASH_STUN_MINOR            ||
                        nMineType2 == TRAP_BASE_TYPE_FLASH_STUN_AVERAGE          ||
                        nMineType2 == TRAP_BASE_TYPE_FRAGMENTATION_MINE_MINOR     ||
                        nMineType2 == TRAP_BASE_TYPE_FRAGMENTATION_MINE_AVERAGE  ||
                        nMineType2 == TRAP_BASE_TYPE_LASER_SLICING_MINOR         ||
                        nMineType2 == TRAP_BASE_TYPE_LASER_SLICING_AVERAGE       ||
                        nMineType2 == TRAP_BASE_TYPE_POISON_GAS_MINOR            ||
                        nMineType2 == TRAP_BASE_TYPE_POISON_GAS_AVERAGE          ||
                        nMineType2 == TRAP_BASE_TYPE_SONIC_CHARGE_MINOR          ||
                        nMineType2 == TRAP_BASE_TYPE_SONIC_CHARGE_AVERAGE )
                    {
                        bIsMine2 = TRUE;
                    }
                    else
                    {
                        continue;//This is a non-mine trigger. Just skip it.
                    }
                }
                if(oSecond != oTarget && GetIsEnemy(oSecond) && (GetRacialType(oSecond) == RACIAL_TYPE_DROID || bIsMine2 ))
                {
                    int bIsMine2 = (GetObjectType(oSecond) == OBJECT_TYPE_TRIGGER);
                    if (!bIsMine2)
                    {
                        nResist = Sp_BlockingChecks(oSecond, eLink1, eLink2, eInvalid);
                    }
                    SignalEvent(oSecond, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    if(nResist == 0)
                    {
                        if ( !bIsMine2 )
                        {
                            AurPostString( "Mines found in radius.", 20, 21, 5.0f );
                            nSaves = Sp_MySavingThrows(oSecond);
                        }
                        //Apply the beam effect and hit regardless because damage is still done.
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oSecond, fLightningDuration);
                        if(nSaves == 0)
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage , oSecond);
                            float fDuration = Sp_CalcDuration( 12.0 );
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oSecond, fDuration);
                        }
                        else
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eSaveDamage , oSecond);
                        }
                        if ( bIsMine2 )
                        {
                            AssignCommand(oSecond,ExecuteScript( "k_trp_generic",oSecond));
                            DetonateMine(oSecond);
                        }
                    }
                }
                //oSecond = GetNextObjectInShape(SHAPE_SPHERE, fRange, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
                oSecond = GetNextObjectInShape(SHAPE_SPHERE, fRange, lTarget, FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_TRIGGER);
            }
        }
        break;
        /*
        STUN DROID
        */
        case FORCE_POWER_DROID_STUN:
        {
            //RWT-OEI 08/31/04
            //if the oTarget is a trigger, it's a mine, so handle way differently
            int bIsMine = 0;
            if ( GetObjectType(oTarget) == OBJECT_TYPE_TRIGGER )
            {
                int nMineType = GetTrapBaseType(oTarget);
                if ( !GetIsTrapped(oTarget) )
                {
                    nMineType = -1;
                }
                if ( nMineType == TRAP_BASE_TYPE_FLASH_STUN_MINOR             ||
                     nMineType == TRAP_BASE_TYPE_FRAGMENTATION_MINE_MINOR     ||
                     nMineType == TRAP_BASE_TYPE_LASER_SLICING_MINOR          ||
                     nMineType == TRAP_BASE_TYPE_POISON_GAS_MINOR            ||
                     nMineType == TRAP_BASE_TYPE_SONIC_CHARGE_MINOR )
                {
                    bIsMine = TRUE;
                }
                else
                {
                    break;//Somehow a none-mine trigger got targetted. Just skip
                }
            }
            //if ( GetObjectType(oTarget) == OBJECT_TYPE_TRIGGER )
            if ( bIsMine )
            {
                AurPostString( "Stun Droid on a mine.", 20,20,5.0f);
                eLink1 = EffectBeam(2065, OBJECT_SELF, BODY_NODE_HAND);
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_PRO_LIGHTNING_S));
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fLightningDuration);
                AssignCommand(oTarget, ExecuteScript("k_trp_generic", oTarget));
                DetonateMine(oTarget);
            }
            else
            {//Otherwise target is a droid, so handle the existing way.
                SWFP_HARMFUL = TRUE;
                SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
                SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_ELECTRICAL;
                // DJS-OEI 3/25/2004
                SWFP_DAMAGE = Sp_CalcDamage( oTarget, 0, 0, GetHitDice(OBJECT_SELF) );
                //SWFP_DAMAGE = GetHitDice(OBJECT_SELF);
                SWFP_DAMAGE_TYPE= DAMAGE_TYPE_ELECTRICAL;
                eLink1 = EffectBeam(2065, OBJECT_SELF, BODY_NODE_HAND); //P.W.(May 19, 2003) New Droid Stun Beam Effect added
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_PRO_LIGHTNING_S));
                eLink2 = EffectDroidStun();
                eLink2 = SetEffectIcon(eLink2, 30);
                eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(1007));  //P.W.(May 19, 2003) Linked the smoke to Link 2
                effect eDamage;
                int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fLightningDuration);
                if(nResist == 0)
                {
                    int nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves == 0)
                    {
                        eDamage = EffectDamage(SWFP_DAMAGE, DAMAGE_TYPE_ELECTRICAL);
                        float fDuration = Sp_CalcDuration( 12.0 );
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, fDuration);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                    }
                    else
                    {
                        eDamage = EffectDamage(SWFP_DAMAGE/2, DAMAGE_TYPE_ELECTRICAL);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                    }
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                }
            }
        }
        break;
        /*
        FEAR
        */
        case FORCE_POWER_FEAR:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_FEAR;
            eLink1 = EffectHorrified();
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(1041));
            eLink1 = SetEffectIcon(eLink1, 6);
            float fDuration = Sp_CalcDuration( 6.0 );
            Sp_ApplyEffects(TRUE, oTarget, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
        }
        break;
        /*
        FORCE ARMOR
        */
        case FORCE_POWER_FORCE_ARMOR:
        {
            // DJS-OEI 12/9/2003
            // For KotOR2, we have decided to modify the application behavior
            // of Force Power trees. Lower level versions of Force Powers will
            // no longer overwrite higher level versions, although this means
            // the caster still loses their Force Points to no effect. Also,
            // casting a Force Power will remove any Force Powers of equal or
            // lesser level prior to applying themselves.
            float fDuration = Sp_CalcDuration( 20.0 );
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_FORCE_ARMOR );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_FORCE_ARMOR ) ) {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectACIncrease(6, AC_DODGE_BONUS);
                eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 6));
                eLink1 = SetEffectIcon(eLink1, 7);
                eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
                eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_FORCE_ARMOR)) {
                         Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_FORCE_ARMOR);
                         eLink1 = EffectACIncrease(6, AC_DODGE_BONUS);
                         eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 6));
                         eLink1 = SetEffectIcon(eLink1, 7);
                         eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
                         eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
                         Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                    }
                }
            }
        }
        break;
        /*
        FORCE AURA
        */
        case FORCE_POWER_FORCE_AURA:
        {
            // DJS-OEI 12/9/2003
            // For KotOR2, we have decided to modify the application behavior
            // of Force Power trees. Lower level versions of Force Powers will
            // no longer overwrite higher level versions, although this means
            // the caster still loses their Force Points to no effect. Also,
            // casting a Force Power will remove any Force Powers of equal or
            // lesser level prior to applying themselves.
            float fDuration = Sp_CalcDuration( 20.0 );
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_FORCE_AURA );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_FORCE_AURA ) ) {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectACIncrease(2, AC_DODGE_BONUS);
                eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 2));
                eLink1 = SetEffectIcon(eLink1, 8);
                eLink2 = EffectVisualEffect(VFX_PRO_FORCE_AURA);
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_FORCE_AURA)) {
                         Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_FORCE_AURA);
                         eLink1 = EffectACIncrease(2, AC_DODGE_BONUS);
                         eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 2));
                         eLink1 = SetEffectIcon(eLink1, 8);
                         eLink2 = EffectVisualEffect(VFX_PRO_FORCE_AURA);
                         Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                    }
                }
            }
        }
        break;
        /*
        FORCE BREACH
        */
        case FORCE_POWER_FORCE_BREACH:
        {
            effect eBuff = GetFirstEffect(oTarget);
            int bValid = FALSE;
            while(GetIsEffectValid(eBuff))
            {
                if(GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_AURA ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_SHIELD ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_ARMOR ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_MIND ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_KNIGHT_MIND ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_MIND_MASTERY ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_SPEED_BURST  ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_KNIGHT_SPEED ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_SPEED_MASTERY ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_RESIST_COLD_HEAT_ENERGY ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_RESIST_POISON_DISEASE_SONIC ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_RESIST_FORCE ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_IMMUNITY ||
                   // DJS-OEI 12/9/2003
                   GetEffectSpellId(eBuff) == FORCE_POWER_MASTER_ENERGY_RESISTANCE ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_BARRIER ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_IMPROVED_FORCE_BARRIER ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_MASTER_FORCE_BARRIER ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_ENLIGHTENMENT )
                 {
                    RemoveEffect(oTarget, eBuff);
                 }
                 eBuff = GetNextEffect(oTarget);
            }
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId()));
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FORCE_BREACH), oTarget);
        }
        break;
        /*
        FORCE IMMUNITY
        */
        case FORCE_POWER_FORCE_IMMUNITY:
        {
            // DJS-OEI 12/9/2003
            // For KotOR2, we have decided to modify the application behavior
            // of Force Power trees. Lower level versions of Force Powers will
            // no longer overwrite higher level versions, although this means
            // the caster still loses their Force Points to no effect. Also,
            // casting a Force Power will remove any Force Powers of equal or
            // lesser level prior to applying themselves.
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_FORCE_IMMUNITY );
            float fDuration = Sp_CalcDuration( 60.0 );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_FORCE_IMMUNITY ) ) {
                SWFP_HARMFUL = FALSE;
                int nSR = 15 + GetHitDice(OBJECT_SELF);
                eLink1 = EffectForceResistanceIncrease(nSR);
                eLink1 = SetEffectIcon(eLink1, 9);
                eLink2 = EffectVisualEffect(VFX_PRO_RESIST_FORCE);
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 1.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_FORCE_IMMUNITY)) {
                         Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_FORCE_IMMUNITY);
                         int nSR = 15 + GetHitDice(oCharacter);
                         eLink1 = EffectForceResistanceIncrease(nSR);
                         eLink1 = SetEffectIcon(eLink1, 9);
                         eLink2 = EffectVisualEffect(VFX_PRO_RESIST_FORCE);
                         Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eLink2, 1.0);
                    }
                }
            }
        }
        break;
        /*
        FORCE PUSH
        */
        case FORCE_POWER_FORCE_PUSH:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            // DJS-OEI 3/25/2004
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, 0, 0, GetHitDice(OBJECT_SELF) );
            //SWFP_DAMAGE = GetHitDice(OBJECT_SELF);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            //eLink1 = EffectForcePushed();
            //eLink2 = EffectStunned();
            //eLink2 = SetEffectIcon(eLink2, 11);
            //eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_IMP_FORCE_PUSH));
            effect eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            // DJS-OEI 10/24/2004
            // Droids can now be pushed back, but not stunned.
            if( GetRacialType(oTarget) == RACIAL_TYPE_DROID ) {
                eLink1 = EffectForcePushed();
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_IMP_FORCE_PUSH));
            }
            else {
                eLink1 = EffectForcePushed();
                eLink2 = EffectStunned();
                eLink2 = SetEffectIcon(eLink2, 11);
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_IMP_FORCE_PUSH));
            }
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eDamage);
            if(SP_CheckForcePushViability(oTarget, FALSE))
            {
                if(nResist == FALSE)
                {
                    int nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves == FALSE)
                    {
                        eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                        DelayCommand(0.4, SP_MyApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget));
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 0.1);
                        float fDuration = Sp_CalcDuration( 2.0 );
                        DelayCommand(2.55, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, fDuration));
                    }
                    else
                    {
                        int nApply;
                        // DJS-OEI 11/20/2003
                        // If the target has the Evasion feat, the damage on a successful
                        // Reflex save is 0. Otherwise, it's half the original damage.
                        if( GetHasFeat( FEAT_EVASION, oTarget ) ) {
                            nApply = 0;
                        }
                        else {
                            nApply = SWFP_DAMAGE/2;
                        }
                        eDamage = EffectDamage(nApply, SWFP_DAMAGE_TYPE);
                        // DJS-OEI 10/26/2004
                        // Asked to remove push effect on successful save.
//                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 0.1);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
//                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FORCE_PUSH), oTarget);
                    }
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                }
            }
        }
        break;
        /*
        FORCE VALOR
        */
        case FORCE_POWER_FORCE_MIND:
        {
            // DJS-OEI 12/10/2003
            // Although the Force Valor series of effects still need to handle
            // stacking like all of the other power trees, it can't be handled
            // in the same fashion since it affects a radius. We can't just call
            // Sp_ApplyEffects() as usual since we would have to change the script
            // to query for better related effects in the tree prior to application.
            // As a result, we are just going to find all of the targets ourselves.
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectSavingThrowIncrease(SAVING_THROW_FORT,2);
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_REFLEX, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CHARISMA, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_DEXTERITY, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_INTELLIGENCE, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_WISDOM, 2));
            eLink2 = EffectVisualEffect(VFX_IMP_MIND_FORCE);
            eLink1 = SetEffectIcon(eLink1, 10);
            float fDuration = Sp_CalcDuration( 20.0 );
            // Get each creature within 30.0 units.
            object oCreature = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oCreature))
            {
                // This power targets party members only.
                if( GetIsObjectValid(oCreature) && IsObjectPartyMember(oCreature) )
                {
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oCreature, FORCE_POWER_FORCE_MIND );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oCreature, FORCE_POWER_FORCE_MIND ) ) {
                        SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                        Sp_ApplyForcePowerEffects(fDuration, eLink1, oCreature);
                        Sp_ApplyForcePowerEffects(0.0, eLink2, oCreature);
                    }
                }
                oCreature = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        /*
        FORCE SHIELD
        */
        case FORCE_POWER_FORCE_SHIELD:
        {
            // DJS-OEI 12/9/2003
            // For KotOR2, we have decided to modify the application behavior
            // of Force Power trees. Lower level versions of Force Powers will
            // no longer overwrite higher level versions, although this means
            // the caster still loses their Force Points to no effect. Also,
            // casting a Force Power will remove any Force Powers of equal or
            // lesser level prior to applying themselves.
            float fDuration = Sp_CalcDuration( 20.0 );
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_FORCE_SHIELD );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_FORCE_SHIELD ) ) {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectACIncrease(4, AC_DODGE_BONUS);
                eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 4));
                eLink1 = SetEffectIcon(eLink1, 12);
                eLink2 = EffectVisualEffect(VFX_PRO_FORCE_SHIELD);
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_FORCE_SHIELD)) {
                         Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_FORCE_SHIELD);
                         eLink1 = EffectACIncrease(4, AC_DODGE_BONUS);
                         eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 4));
                         eLink1 = SetEffectIcon(eLink1, 12);
                         eLink2 = EffectVisualEffect(VFX_PRO_FORCE_SHIELD);
                         Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                    }
                }
            }
        }
        break;
        /*
        FORCE STORM
        */
        case FORCE_POWER_FORCE_STORM:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            float fRange = Sp_CalcRange( 12.0 );
            // DJS-OEI 3/25/2004
            int nDice = GetHitDice(OBJECT_SELF);
            // DJS-OEI 10/7/2004
            // Removed cap.
            /*
            if(nDice > 10)
            {
                nDice = 10;
            }
            */
            // DJS-OEI 3/25/2004
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, nDice, 6 );
            //SWFP_DAMAGE = d6(nDamage);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_ELECTRICAL;
            effect eBeam = EffectBeam(2061, OBJECT_SELF, BODY_NODE_HEAD);
            effect eVis = EffectVisualEffect(VFX_PRO_LIGHTNING_L);
            effect eForce;
            effect eDam;
            //object oUse = GetFirstObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            object oUse = GetFirstObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oUse))
            {
                //Make Immunity Checks
                if(GetIsEnemy(oUse))
                {
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    // DJS-OEI 3/25/2004
                    // Modified this power to use the sp_ functions so it could
                    // get the benefits of the Form modifiers.
                    int nResist = Sp_BlockingChecks(oUse, eVis, eBeam, eInvalid);
                    int nSaves;
                    if(nResist == 0)
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oUse);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oUse, fLightningDuration);
                        nSaves = Sp_MySavingThrows(oUse);
                        if(nSaves == 0)
                        {
                            eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                            eForce = EffectDamageForcePoints(SWFP_DAMAGE);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
                        }
                        else
                        {
                            eDam = EffectDamage(SWFP_DAMAGE/2, SWFP_DAMAGE_TYPE);
                            eForce = EffectDamageForcePoints(SWFP_DAMAGE/2);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
                        }
                    }
                    else {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                    }
                    /*
                    if(!ResistForce(OBJECT_SELF, oUse))
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oUse);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oUse, fLightningDuration);
                        // DJS-OEI 3/16/2004
                        // The Total Defense Stance gives Jedis a +4 to their
                        // saving throws versus force powers. We just decrease
                        // the DC by that amount.
                        int nMod = Sp_GetJediDCSave();
                        if( IsInTotalDefense( oTarget ) && Sp_IsJedi( oTarget ) ) {
                            if( nMod > 4 ) {
                                nMod -= 4;
                            }
                            else {
                                nMod = 0;
                            }
                        }
                        if(!WillSave(oUse, nMod))
                        {
                            eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                            eForce = EffectDamageForcePoints(SWFP_DAMAGE);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
                        }
                        else
                        {
                            eDam = EffectDamage(SWFP_DAMAGE/2, SWFP_DAMAGE_TYPE);
                            eForce = EffectDamageForcePoints(SWFP_DAMAGE/2);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
                        }
                    }
                    else
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                    }
                    */
                }
                //oUse = GetNextObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
                oUse = GetNextObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        /*
        FORCE WAVE
        */
        case FORCE_POWER_FORCE_WAVE:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            float fRange = Sp_CalcRange( 15.0 );
            // DJS-OEI 3/25/2004
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, 0, 0, GetHitDice(OBJECT_SELF) + GetHitDice(OBJECT_SELF)/2 );
            //SWFP_DAMAGE = GetHitDice(OBJECT_SELF) + GetHitDice(OBJECT_SELF)/2;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            effect eVis = EffectVisualEffect(VFX_IMP_FORCE_PUSH);
            eLink1 = EffectForcePushed();
            eLink2 = EffectStunned();
            eLink2 = SetEffectIcon(eLink2, 13);
            effect eDam;
            effect eForce;
            //object oUse = GetFirstObjectInShape(SHAPE_SPHERE, fRange, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            object oUse = GetFirstObjectInShape(SHAPE_SPHERE, fRange, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_FORCE_WAVE), GetLocation(OBJECT_SELF));
            while(GetIsObjectValid(oUse))
            {
                //Make Immunity Checks
                if(GetIsEnemy(oUse))
                {
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    // DJS-OEI 3/25/2004
                    // Modified this power to use the sp_ functions so it could
                    // get the benefits of the Form modifiers.
                    int nResist = Sp_BlockingChecks(oUse, eVis, eInvalid, eInvalid);
                    int nSaves;
                    if(nResist == 0)
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oUse);
                        nSaves = Sp_MySavingThrows(oUse);
                        if(nSaves == 0)
                        {
                            eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                            DelayCommand(0.4, SP_MyApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse));
                            if(SP_CheckForcePushViability(oUse, FALSE))
                            {
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oUse, 0.2);
                            }
                            DelayCommand(2.55, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oUse, 6.0));
                        }
                        else
                        {
                            // DJS-OEI 10/26/2004
                            // Asked to remove Push if save succeeded.
//                            if(SP_CheckForcePushViability(oUse, FALSE))
//                            {
//                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oUse, 0.2);
//                            }
                            int nApply;
                            // DJS-OEI 11/20/2003
                            // If the target has the Evasion feat, the damage on a successful
                            // Reflex save is 0. Otherwise, it's half the original damage.
                            if( GetHasFeat( FEAT_EVASION, oTarget ) ) {
                                nApply = 0;
                            }
                            else {
                                nApply = SWFP_DAMAGE/2;
                            }
                            eDam = EffectDamage(nApply, SWFP_DAMAGE_TYPE);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
                        }
                    }
                    /*
                    if(!ResistForce(OBJECT_SELF, oUse))
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oUse);
                        // DJS-OEI 3/16/2004
                        // The Total Defense Stance gives Jedis a +4 to their
                        // saving throws versus force powers. We just decrease
                        // the DC by that amount.
                        int nMod = Sp_GetJediDCSave();
                        if( IsInTotalDefense( oTarget ) && Sp_IsJedi( oTarget ) ) {
                            if( nMod > 4 ) {
                                nMod -= 4;
                            }
                            else {
                                nMod = 0;
                            }
                        }
                        if(!ReflexSave(oUse, nMod))
                        {
                            eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                            DelayCommand(0.4, SP_MyApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse));
                            if(SP_CheckForcePushViability(oUse, FALSE))
                            {
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oUse, 0.2);
                            }
                            DelayCommand(2.55, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oUse, 6.0));
                        }
                        else
                        {
                            if(SP_CheckForcePushViability(oUse, FALSE))
                            {
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oUse, 0.2);
                            }
                            int nApply;
                            // DJS-OEI 11/20/2003
                            // If the target has the Evasion feat, the damage on a successful
                            // Reflex save is 0. Otherwise, it's half the original damage.
                            if( GetHasFeat( FEAT_EVASION, oTarget ) ) {
                                nApply = 0;
                            }
                            else {
                                nApply = SWFP_DAMAGE/2;
                            }
                            eDam = EffectDamage(nApply, SWFP_DAMAGE_TYPE);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
                        }
                    }
                    */
                }
                //oUse = GetNextObjectInShape(SHAPE_SPHERE, fRange, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
                oUse = GetNextObjectInShape(SHAPE_SPHERE, fRange, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        /*
        FORCE WHIRLWIND
        */
        case FORCE_POWER_FORCE_WHIRLWIND:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            float fRange = Sp_CalcRange( 5.0 );
            // DJS-OEI 3/25/2004
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, 0, 0, GetHitDice(OBJECT_SELF)/3 );
            //SWFP_DAMAGE = GetHitDice(OBJECT_SELF)/3;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            effect eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
            //SP_MyPostString(IntToString(SP_CheckAppearanceGeoDroidShields(oTarget)),5,5,3.0);
            if(SP_CheckForcePushViability(oTarget, TRUE))
            {
                eLink1 = EffectWhirlWind();
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_IMP_FORCE_WHIRLWIND));
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_FORCE_WHIRLWIND));
                eLink1 = SetEffectIcon(eLink1, 14);
                int nResist = Sp_BlockingChecks(oTarget, eLink1, eDamage, eInvalid);
                int nSaves;
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                if(nResist == 0)
                {
                    nSaves =Sp_MySavingThrows(oTarget);
                    if(nSaves == 0)
                    {
                        //ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 9.0);
                        //RWT-OEI 09/27/04 - QA says they fall too soon. Upping this to 12 to
                        //see if that fixes it. FMP#6266
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 12.0);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDamage, oTarget);
                        int nIdx = 1;
                        float fDelay;
                        SP_InterativeDamage(eDamage, 13, oTarget);
                    }
                }
                if(nResist > 0 || nSaves > 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                }
            }
            //Force Push all enemies away from the target is they meet the conditions.
            SP_MyPrintString("");
            eLink2 = EffectForcePushTargeted(GetLocation(oTarget));
            object oSecond = GetFirstObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget));
            while(GetIsObjectValid(oSecond))
            {
                if(SP_CheckForcePushViability(oSecond, FALSE) == TRUE && GetIsEnemy(oSecond, OBJECT_SELF) && oSecond != oTarget)
                {
                    //P.W. (June 8) - Put this check in so Calo Nord does not move during the fight on Taris
                    if(GetTag(oTarget) != "Calo082")
                    {
                        SignalEvent(oSecond, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                        int nResist2 = Sp_BlockingChecks(oSecond, eLink2,eInvalid,eInvalid);
                        if(nResist2 == 0)
                        {
                            int nSaves2 = Sp_MySavingThrows(oSecond);
                            if(nSaves2 == 0)
                            {
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oSecond, 0.2);
                            }
                        }
                    }
                }
                oSecond = GetNextObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget));
                SP_MyPrintString("");
            }
        }
        break;
        /*
        IMPROVED HEAL
        */
        //MODIFIED by Preston Watamaniuk March 28
        //Cut the heal in half
        case FORCE_POWER_HEAL:
        {
            SWFP_HARMFUL = FALSE;
            // DJS-OEI 3/29/2004
            // The Regeneration Consular Forms increase the relevance of
            // the Wisdom and Charisma modifiers.
            int nMultiplier = 1;
            // DJS-OEI 7/20/2004
            // Form/Stance re-design.
            /*
            if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_REGENERATION_I ) ) {
                nMultiplier = 2;
            }
            else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_REGENERATION_II ) ||
                     IsFormActive( OBJECT_SELF, FORM_CONSULAR_REGENERATION_III ) ) {
                nMultiplier = 3;
            }
            */
            // DJS-OEI 10/20/2004
            // Balance change
            //int nHeal = ( ( GetAbilityModifier(ABILITY_WISDOM) + GetAbilityModifier(ABILITY_CHARISMA) ) * nMultiplier ) + 10 + GetHitDice(OBJECT_SELF);
            int nHeal = ( ( GetAbilityModifier(ABILITY_WISDOM) + GetAbilityModifier(ABILITY_CHARISMA) ) * nMultiplier ) + 15 + GetHitDice(OBJECT_SELF);
            effect eVis =  EffectVisualEffect(VFX_IMP_HEAL);
            int nCnt = 0;
            object oParty;
            if(IsObjectPartyMember(OBJECT_SELF))
            {
                oParty = GetPartyMemberByIndex(nCnt);
            }
            else
            {
                oParty = OBJECT_SELF;
            }
            while(nCnt < 3)
            {
                if(GetIsObjectValid(oParty) &&
                   GetRacialType(oParty) != RACIAL_TYPE_DROID &&
                   GetDistanceBetween(OBJECT_SELF, oParty) < 15.0)
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    Sp_RemoveSpecificEffect(EFFECT_TYPE_POISON, oParty);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oParty);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHeal), oParty);
                }
                nCnt++;
                if(IsObjectPartyMember(OBJECT_SELF))
                {
                   oParty = GetPartyMemberByIndex(nCnt);
                }
                else
                {
                   oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt, CREATURE_TYPE_RACIAL_TYPE, RACIAL_TYPE_HUMAN);
                }
            }
        }
        break;
        /*
        MASTER HEAL
        */
        // Same as Improved Heal with addition 5 VP and Stun removal.
        case FORCE_POWER_MASTER_HEAL:
        {
            SWFP_HARMFUL = FALSE;
            // DJS-OEI 3/29/2004
            // The Regeneration Consular Forms increase the relevance of
            // the Wisdom and Charisma modifiers.
            int nMultiplier = 1;
            // DJS-OEI 7/20/2004
            // Form/Stance re-design.
            /*
            if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_REGENERATION_I ) ) {
                nMultiplier = 2;
            }
            else if( IsFormActive( OBJECT_SELF, FORM_CONSULAR_REGENERATION_II ) ||
                     IsFormActive( OBJECT_SELF, FORM_CONSULAR_REGENERATION_III ) ) {
                nMultiplier = 3;
            }
            */
            // Balance Change
            //int nHeal = ( ( GetAbilityModifier(ABILITY_WISDOM) + GetAbilityModifier(ABILITY_CHARISMA) ) * nMultiplier ) + 15 + GetHitDice(OBJECT_SELF);
            int nHeal = ( ( GetAbilityModifier(ABILITY_WISDOM) + GetAbilityModifier(ABILITY_CHARISMA) ) * nMultiplier ) + 15 + 2*GetHitDice(OBJECT_SELF);
            effect eVis =  EffectVisualEffect(VFX_IMP_HEAL);
            int nCnt = 0;
            object oParty;
            if(IsObjectPartyMember(OBJECT_SELF))
            {
                oParty = GetPartyMemberByIndex(nCnt);
            }
            else
            {
                oParty = OBJECT_SELF;
            }
            while(nCnt < 3)
            {
                if(GetIsObjectValid(oParty) &&
                   GetRacialType(oParty) != RACIAL_TYPE_DROID &&
                   GetDistanceBetween(OBJECT_SELF, oParty) < 15.0)
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    Sp_RemoveSpecificEffect(EFFECT_TYPE_STUNNED, oParty);
                    Sp_RemoveSpecificEffect(EFFECT_TYPE_POISON, oParty);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oParty);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHeal), oParty);
                }
                nCnt++;
                if(IsObjectPartyMember(OBJECT_SELF))
                {
                   oParty = GetPartyMemberByIndex(nCnt);
                }
                else
                {
                   oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt, CREATURE_TYPE_RACIAL_TYPE, RACIAL_TYPE_HUMAN);
                }
            }
        }
        break;
        /*
        HORROR
        */
        case FORCE_POWER_HORROR:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_FEAR;
            float fRange = Sp_CalcRange( 5.0 );
            eLink1 = EffectHorrified();
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(1042));
            eLink1 = SetEffectIcon(eLink1, 16);
            float fDuration = Sp_CalcDuration( 12.0 );
            Sp_ApplyEffects(TRUE, oTarget, fRange, 1000, eLink1, fDuration, eInvalid, 0.0, RACIAL_TYPE_HUMAN);
        }
        break;
        /*
        INSANITY
        */
        case FORCE_POWER_INSANITY:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_FEAR;
            float fRange = Sp_CalcRange( 10.0 );
            eLink1 = EffectHorrified();
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(1043));
            eLink1 = SetEffectIcon(eLink1, 17);
            // DJS-OEI 10/7/2004
            // Changed to base of 18 seconds.
            //float fDuration = Sp_CalcDuration( 12.0 );
            float fDuration = Sp_CalcDuration( 18.0 );
            Sp_ApplyEffects(TRUE, oTarget, fRange, 1000, eLink1, fDuration, eInvalid, 0.0, RACIAL_TYPE_HUMAN);
            //ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(1043), oTarget);
        }
        break;
        /*
        KILL
        */
        case FORCE_POWER_KILL:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            effect eDeath = EffectDeath();
            effect eDamage;
            effect eChoke = EffectChoke();
            eChoke = SetEffectIcon(eChoke, 18);
            effect eVFX = EffectVisualEffect(VFX_IMP_CHOKE);
            int nResist = Sp_BlockingChecks(oTarget, eDeath, eDamage, eChoke);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if(nResist == 0)
            {
                int nSaves = Sp_MySavingThrows(oTarget);
                // DJS-OEI 3/25/2004
                int nDamage = Sp_CalcDamage( oTarget, 0, 0, GetHitDice(OBJECT_SELF) );
                //int nDamage = GetHitDice(OBJECT_SELF);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget);
                eDamage = EffectDamage(nDamage, DAMAGE_TYPE_BLUDGEONING);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eChoke, oTarget, 6.0);
                    nDamage = (GetMaxHitPoints(oTarget))/2;
                    nDamage = nDamage/3;
                    // DJS-OEI 3/25/2004
                    nDamage = Sp_CalcDamage( oTarget, 0, 0, nDamage );
                    //This will do damage over time to make the effect look more dramatic
                    eDamage = EffectDamage(nDamage, DAMAGE_TYPE_BLUDGEONING);
                    SP_InterativeDamage(eDamage, 7, oTarget);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                }
            }
            else
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        /*
        KNIGHT VALOR
        */
        case FORCE_POWER_KNIGHT_MIND:
        {
            // DJS-OEI 12/10/2003
            // Although the Force Valor series of effects still need to handle
            // stacking like all of the other power trees, it can't be handled
            // in the same fashion since it affects a radius. We can't just call
            // Sp_ApplyEffects() as usual since we would have to change the script
            // to query for better related effects in the tree prior to application.
            // As a result, we are just going to find all of the targets ourselves.
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectSavingThrowIncrease(SAVING_THROW_ALL,3);
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CHARISMA, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_DEXTERITY, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_INTELLIGENCE, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_WISDOM, 3));
            eLink1 = EffectLinkEffects(eLink1, EffectImmunity(IMMUNITY_TYPE_POISON));
            eLink1 = SetEffectIcon(eLink1, 19);
            eLink2 = EffectVisualEffect(1033);
            float fDuration = Sp_CalcDuration( 20.0 );
            // Get each creature within 30.0 units.
            object oCreature = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oCreature))
            {
                // This power targets party members only.
                if( GetIsObjectValid(oCreature) && IsObjectPartyMember(oCreature) )
                {
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oCreature, FORCE_POWER_KNIGHT_MIND );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oCreature, FORCE_POWER_KNIGHT_MIND ) ) {
                        SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                        Sp_ApplyForcePowerEffects(fDuration, eLink1, oCreature);
                        Sp_ApplyForcePowerEffects(0.0, eLink2, oCreature);
                    }
                }
                oCreature = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        /*
        KNIGHT SPEED
        */
        case FORCE_POWER_KNIGHT_SPEED:
        {
            // DJS-OEI 12/9/2003
            // For KotOR2, we have decided to modify the application behavior
            // of Force Power trees. Lower level versions of Force Powers will
            // no longer overwrite higher level versions, although this means
            // the caster still loses their Force Points to no effect. Also,
            // casting a Force Power will remove any Force Powers of equal or
            // lesser level prior to applying themselves.
            float fDuration = Sp_CalcDuration( 36.0 );
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_KNIGHT_SPEED );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_KNIGHT_SPEED ) ) {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectMovementSpeedIncrease(99);
                eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(4));
                eLink1 = EffectLinkEffects(eLink1, EffectModifyAttacks(1));
                eLink1 = SetEffectIcon(eLink1, 20);
                if(OBJECT_SELF == GetPartyMemberByIndex(0))
                {
                    eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_SPEED));
                    //eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_IMP_SPEED_KNIGHT));
                }
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_KNIGHT_SPEED)) {
                            Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_KNIGHT_SPEED );
                            eLink2 = EffectMovementSpeedIncrease(99);
                            eLink2 = EffectLinkEffects(eLink2, EffectACIncrease(4));
                            eLink2 = EffectLinkEffects(eLink2, EffectModifyAttacks(1));
                            eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_DUR_SPEED));
                            eLink2 = SetEffectIcon(eLink2, 20);
                            Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink2, fDuration, eInvalid, 0.0);
                    }
                }
            }
        }
        break;
        /*
        LIGHTSABER THROW
        */
        case FORCE_POWER_LIGHT_SABER_THROW:
        {
            SWFP_HARMFUL = TRUE;
            eLink1 = EffectLightsaberThrow(oTarget);
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, OBJECT_SELF, 3.0);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
        }
        break;
        /*
        ADVANCED LIGHTSABER THROW
        */
        case FORCE_POWER_LIGHT_SABER_THROW_ADVANCED:
        {
            SWFP_HARMFUL = TRUE;
            object oTarget2, oTarget3;
            oTarget2 = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, oTarget, 1);
            if(GetIsObjectValid(oTarget2) && GetDistanceBetween(oTarget, oTarget2) <= 5.0)
            {
                oTarget3 = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, oTarget, 2);
                if(GetIsObjectValid(oTarget3) && GetDistanceBetween(oTarget, oTarget3) <= 5.0)
                {
                    SP_MyPrintString("Target 1 = " + ObjectToString(oTarget) +
                                " Target 2 = " + ObjectToString(oTarget2) +
                                " Target 3 = " + ObjectToString(oTarget3));
                    eLink1 = EffectLightsaberThrow(oTarget, oTarget2, oTarget3);
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    SignalEvent(oTarget2, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    SignalEvent(oTarget3, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                }
                else
                {
                    SP_MyPrintString("Target 1 = " + ObjectToString(oTarget) +
                                " Target 2 = " + ObjectToString(oTarget2));
                    eLink1 = EffectLightsaberThrow(oTarget, oTarget2);
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    SignalEvent(oTarget2, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                }
            }
            else
            {
                SP_MyPrintString("Target 1 = " + ObjectToString(oTarget));
                eLink1 = EffectLightsaberThrow(oTarget);
                oTarget2 = OBJECT_INVALID;
            }
            SP_MyPrintString("Apply Throwsaber Effect");
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, OBJECT_SELF, 3.0);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
        }
        break;
        /*
        LIGHTNING
        */
        case FORCE_POWER_LIGHTNING:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_ELECTRICAL;
            int nDice = GetHitDice(OBJECT_SELF);
            // DJS-OEI 10/7/2004
            // Removed cap.
            /*
            if(nDice > 10)
            {
                nDice = 10;
            }
            */
            float fRange = Sp_CalcRange( 17.0 );
            // DJS-OEI 3/25/2004
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, nDice, 6 );
            //SWFP_DAMAGE = d6(nDamage);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_ELECTRICAL;
            SWFP_DAMAGE_VFX = VFX_PRO_LIGHTNING_L; //1036 - With sound
            SWFP_SHAPE = SHAPE_SPELLCYLINDER;
            effect eLightning = EffectBeam(VFX_BEAM_LIGHTNING_DARK_L, OBJECT_SELF, BODY_NODE_HAND);
            effect eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
            //object oUse = GetFirstObjectInShape(SWFP_SHAPE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            object oUse = GetFirstObjectInShape(SWFP_SHAPE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE );
            effect eBump = EffectVisualEffect(SWFP_DAMAGE_VFX);
            int nCnt = 1;
            // This will need to be changed to a double while get nearest in shape script.
            //ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(1036), OBJECT_SELF);
            while(GetIsObjectValid(oUse))
            {
                if(GetIsEnemy(oUse))
                {
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    // DJS-OEI 3/25/2004
                    // Modified this power to use the sp_ functions so it could
                    // get the benefits of the Form modifiers.
                    int nResist = Sp_BlockingChecks(oUse, eBump, eInvalid, eInvalid);
                    int nSaves;
                    if(nResist == 0)
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eBump, oUse);
                        nSaves = Sp_MySavingThrows(oUse);
                        if(nSaves == 0)
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            //ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
                        }
                        else
                        {
                            SWFP_DAMAGE /= 2;
                            eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                        }
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLightning, oUse, fLightningDuration);
                    }
                    else
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
                    }
                    /*
                    //Make Immunity Checks
                    if(!ResistForce(OBJECT_SELF, oUse))
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eBump, oUse);
                        // DJS-OEI 3/16/2004
                        // The Total Defense Stance gives Jedis a +4 to their
                        // saving throws versus force powers. We just decrease
                        // the DC by that amount.
                        int nMod = Sp_GetJediDCSave();
                        if( IsInTotalDefense( oTarget ) && Sp_IsJedi( oTarget ) ) {
                            if( nMod > 4 ) {
                                nMod -= 4;
                            }
                            else {
                                nMod = 0;
                            }
                        }
                        if(!WillSave(oUse, nMod, SWFP_PRIVATE_SAVE_VERSUS_TYPE))
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                            //ApplyEffectToObject(DURATION_TYPE_INSTANT, eForce, oUse);
                        }
                        else
                        {
                            SWFP_DAMAGE /= 2;
                            eDam = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oUse);
                        }
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLightning, oUse, fLightningDuration);
                    }
                    else
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
                    }
                    */
                }
                nCnt++;
                //oUse = GetNextObjectInShape(SWFP_SHAPE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
                oUse = GetNextObjectInShape(SWFP_SHAPE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        /*
        MASTER VALOR
        */
        case FORCE_POWER_MIND_MASTERY:
        {
            // DJS-OEI 12/10/2003
            // Although the Force Valor series of effects still need to handle
            // stacking like all of the other power trees, it can't be handled
            // in the same fashion since it affects a radius. We can't just call
            // Sp_ApplyEffects() as usual since we would have to change the script
            // to query for better related effects in the tree prior to application.
            // As a result, we are just going to find all of the targets ourselves.
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectSavingThrowIncrease(SAVING_THROW_ALL,5);
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CHARISMA, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_DEXTERITY, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_INTELLIGENCE, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_WISDOM, 5));
            eLink1 = EffectLinkEffects(eLink1, EffectImmunity(IMMUNITY_TYPE_POISON));
            eLink1 = SetEffectIcon(eLink1, 21);
            eLink2 = EffectVisualEffect(VFX_IMP_MIND_MASTERY);
            float fDuration = Sp_CalcDuration( 20.0 );
            // Get each creature within 30.0 units.
            object oCreature = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oCreature))
            {
                // This power targets party members only.
                if( GetIsObjectValid(oCreature) && IsObjectPartyMember(oCreature) )
                {
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oCreature, FORCE_POWER_MIND_MASTERY );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oCreature, FORCE_POWER_MIND_MASTERY ) ) {
                        SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                        Sp_ApplyForcePowerEffects(fDuration, eLink1, oCreature);
                        Sp_ApplyForcePowerEffects(0.0, eLink2, oCreature);
                    }
                }
                oCreature = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        /*
        PLAGUE
        */
        case FORCE_POWER_PLAGUE:
        {
            // If the target is already poisoned in any way, don't
            // apply this effect.
            if(!GetIsPoisoned(oTarget))
            {
                // DJS-OEI 12/9/2003
                // For KotOR2, we have decided to modify the application behavior
                // of Force Power trees. Lower level versions of Force Powers will
                // no longer overwrite higher level versions, although this means
                // the caster still loses their Force Points to no effect. Also,
                // casting a Force Power will remove any Force Powers of equal or
                // lesser level prior to applying themselves.
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( oTarget, FORCE_POWER_PLAGUE );
                // Do not apply the effects of this power if a more powerful
                // version is already attached to the target.
                if( !Sp_BetterRelatedPowerExists( oTarget, FORCE_POWER_PLAGUE ) ) {
                    SWFP_HARMFUL = TRUE;
                    eLink1 = EffectPoison(POISON_ABILITY_SCORE_VIRULENT);
                    eLink1 = EffectLinkEffects(eLink1, EffectMovementSpeedDecrease(50));
                    eLink1 = SetEffectIcon(eLink1, 23);
                    if(!GetIsPoisoned(oTarget))
                    {
                        //Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 1000.0, eInvalid, 0.0);
                        //RWT-OEI 09/27/04 - This is apparently supposed to be 12 seconds instead
                        //of permanent.
                        Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, 12.0, eInvalid, 0.0);
                    }
                }
            }
            // DJS-OEI 10/22/2004
            else {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceResisted(OBJECT_SELF), oTarget);
            }
        }
        break;
        /*
        IMPROVED ENERGY RESISTANCE
        */
        case FORCE_POWER_RESIST_COLD_HEAT_ENERGY:
        {
            // DJS-OEI 12/10/2003
            // Although the Energy Resistance series of effects still need to handle
            // stacking like all of the other power trees, it can't be handled
            // in the same fashion since it affects multiple targets in the party. We can't just call
            // Sp_ApplyEffects() as usual since we would have to change the script
            // to query for better related effects in the tree prior to application.
            // As a result, we are just going to find all of the targets ourselves.
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectDamageResistance(DAMAGE_TYPE_COLD, 12);
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_FIRE, 12));
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SONIC, 12));
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_BLASTER, 12));
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 12));
            eLink1 = SetEffectIcon(eLink1, 24);
            eLink2 = EffectVisualEffect(VFX_PRO_RESIST_ELEMENTS);
            // Keep in mind that enemies can also cast this, although
            // only the caster will receive benfit. If a PC casts it,
            // the entire party is affected regardless of distance.
            if(!IsObjectPartyMember(OBJECT_SELF))
            {
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_RESIST_COLD_HEAT_ENERGY );
                // Do not apply the effects of this power if a more powerful
                // version is already attached to the target.
                if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_RESIST_COLD_HEAT_ENERGY ) ) {
                    float fDuration = Sp_CalcDuration( 120.0 );
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, OBJECT_SELF, fDuration);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, OBJECT_SELF, 1.0);
                }
            }
            else if(IsObjectPartyMember(OBJECT_SELF))
            {
                int nCnt = 0;
                object oParty;
                for(nCnt; nCnt < 3; nCnt++)
                {
                    oParty = GetPartyMemberByIndex(nCnt);
                    if(GetIsObjectValid(oParty))
                    {
                        // Remove any lower level or equal versions of this power.
                        Sp_RemoveRelatedPowers( oParty, FORCE_POWER_RESIST_COLD_HEAT_ENERGY );
                        // Do not apply the effects of this power if a more powerful
                        // version is already attached to the target.
                        if( !Sp_BetterRelatedPowerExists( oParty, FORCE_POWER_RESIST_COLD_HEAT_ENERGY ) ) {
                            // Make sure to send the event signal to anyone other
                            // than the caster that gets the benefit of this power.
                            if( oParty != OBJECT_SELF ) {
                                SignalEvent(oParty, EventSpellCastAt(oParty, GetSpellId(), SWFP_HARMFUL));
                            }
                            float fDuration = Sp_CalcDuration( 120.0 );
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oParty, fDuration);
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oParty, 1.0);
                        }
                    }
                }
            }
        }
        break;
        // DJS-OEI 12/9/2003
        /*
        MASTER ENERGY RESISTANCE
        */
        case FORCE_POWER_MASTER_ENERGY_RESISTANCE:
        {
            // DJS-OEI 12/10/2003
            // Although the Energy Resistance series of effects still need to handle
            // stacking like all of the other power trees, it can't be handled
            // in the same fashion since it affects multiple targets in the party. We can't just call
            // Sp_ApplyEffects() as usual since we would have to change the script
            // to query for better related effects in the tree prior to application.
            // As a result, we are just going to find all of the targets ourselves.
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectDamageResistance(DAMAGE_TYPE_COLD, 20);
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_FIRE, 20));
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SONIC, 20));
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_BLASTER, 20));
            eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 20));
            eLink1 = SetEffectIcon(eLink1, 104);
            eLink2 = EffectVisualEffect(VFX_PRO_RESIST_ELEMENTS);
            // Keep in mind that enemies can also cast this, although
            // only the caster will receive benfit. If a PC casts it,
            // the entire party is affected regardless of distance.
            if(!IsObjectPartyMember(OBJECT_SELF))
            {
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_MASTER_ENERGY_RESISTANCE );
                // Do not apply the effects of this power if a more powerful
                // version is already attached to the target.
                if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_MASTER_ENERGY_RESISTANCE ) ) {
                    float fDuration = Sp_CalcDuration( 120.0 );
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, OBJECT_SELF, fDuration);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, OBJECT_SELF, 1.0);
                }
            }
            else if(IsObjectPartyMember(OBJECT_SELF))
            {
                int nCnt = 0;
                object oParty;
                for(nCnt; nCnt < 3; nCnt++)
                {
                    oParty = GetPartyMemberByIndex(nCnt);
                    if(GetIsObjectValid(oParty))
                    {
                        // Remove any lower level or equal versions of this power.
                        Sp_RemoveRelatedPowers( oParty, FORCE_POWER_MASTER_ENERGY_RESISTANCE );
                        // Do not apply the effects of this power if a more powerful
                        // version is already attached to the target.
                        if( !Sp_BetterRelatedPowerExists( oParty, FORCE_POWER_MASTER_ENERGY_RESISTANCE ) ) {
                            // Make sure to send the event signal to anyone other
                            // than the caster that gets the benefit of this power.
                            if( oParty != OBJECT_SELF ) {
                                SignalEvent(oParty, EventSpellCastAt(oParty, GetSpellId(), SWFP_HARMFUL));
                            }
                            float fDuration = Sp_CalcDuration( 120.0 );
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oParty, fDuration);
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oParty, 1.0);
                        }
                    }
                }
            }
        }
        break;
        /*
        RESIST FORCE 1
        */
        case FORCE_POWER_RESIST_FORCE:
        {
            // DJS-OEI 12/9/2003
            // For KotOR2, we have decided to modify the application behavior
            // of Force Power trees. Lower level versions of Force Powers will
            // no longer overwrite higher level versions, although this means
            // the caster still loses their Force Points to no effect. Also,
            // casting a Force Power will remove any Force Powers of equal or
            // lesser level prior to applying themselves.
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_RESIST_FORCE );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_RESIST_FORCE ) ) {
                SWFP_HARMFUL = FALSE;
                int nSR = 10 + GetHitDice(OBJECT_SELF);
                eLink1 = EffectForceResistanceIncrease(nSR);
                eLink1 = SetEffectIcon(eLink1, 25);
                eLink2 = EffectVisualEffect(VFX_PRO_RESIST_FORCE);
                float fDuration = Sp_CalcDuration( 60.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 1.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_RESIST_FORCE)) {
                         Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_RESIST_FORCE );
                         int nSR = 10 + GetHitDice(oCharacter);
                         eLink1 = EffectForceResistanceIncrease(nSR);
                         eLink1 = SetEffectIcon(eLink1, 25);
                         eLink2 = EffectVisualEffect(VFX_PRO_RESIST_FORCE);
                         float fDuration = Sp_CalcDuration( 60.0 );
                         Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eLink2, 1.0);
                    }
                }
            }
        }
        break;
        /*
        RESIST ENERGY
        */
        case FORCE_POWER_RESIST_POISON_DISEASE_SONIC:
        {
            // DJS-OEI 12/9/2003
            // For KotOR2, we have decided to modify the application behavior
            // of Force Power trees. Lower level versions of Force Powers will
            // no longer overwrite higher level versions, although this means
            // the caster still loses their Force Points to no effect. Also,
            // casting a Force Power will remove any Force Powers of equal or
            // lesser level prior to applying themselves.
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_RESIST_POISON_DISEASE_SONIC );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_RESIST_POISON_DISEASE_SONIC ) ) {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectDamageResistance(DAMAGE_TYPE_COLD, 6);
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_FIRE, 6));
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SONIC, 6));
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 6));
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_BLASTER, 6));
                eLink1 = SetEffectIcon(eLink1, 26);
                eLink2 = EffectVisualEffect(VFX_PRO_RESIST_ELEMENTS);
                float fDuration = Sp_CalcDuration( 120.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 1.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_RESIST_POISON_DISEASE_SONIC)) {
                         Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_RESIST_POISON_DISEASE_SONIC );
                         eLink1 = EffectDamageResistance(DAMAGE_TYPE_COLD, 6);
                         eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_FIRE, 6));
                         eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SONIC, 6));
                         eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 6));
                         eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_BLASTER, 6));
                         eLink1 = SetEffectIcon(eLink1, 26);
                         eLink2 = EffectVisualEffect( VFX_PRO_RESIST_ELEMENTS);
                         float fDuration = Sp_CalcDuration( 120.0 );
                         Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eLink2, 1.0);
                    }
                }
            }
        }
        break;
        /*
        SHOCK
        */
        case FORCE_POWER_SHOCK:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_ELECTRICAL;
            int nDice = GetHitDice(OBJECT_SELF);
            // DJS-OEI 10/7/2004
            // Removed cap.
            /*
            if(nDice > 10)
            {
                nDice = 10;
            }
            */
            // DJS-OEI 3/25/2004
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, nDice, 6 );
            //SWFP_DAMAGE = d6(nDamage);
            SP_MyPostString(IntToString(SWFP_DAMAGE),5,5,4.0);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_ELECTRICAL;
            SWFP_DAMAGE_VFX = VFX_PRO_LIGHTNING_S;
            effect eDamage = EffectDamage(SWFP_DAMAGE, DAMAGE_TYPE_ELECTRICAL);
            effect eDamage2 = EffectDamage(SWFP_DAMAGE/2, DAMAGE_TYPE_ELECTRICAL);
            int nSaves = Sp_MySavingThrows(oTarget);
            int nResist = Sp_BlockingChecks(oTarget, eDamage, eInvalid, eInvalid);
            eLink1 = EffectBeam(2066, OBJECT_SELF, BODY_NODE_HAND); //P.W.(May 19, 2003) Changed to Shock beam effect.
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if(nResist == 0)
            {
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fLightningDuration);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_PRO_LIGHTNING_S), oTarget);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage2, oTarget);
                }
            }
            //Sp_ApplyEffects(FALSE, oTarget, 0.0, 1, eLink1, fLightningDuration, eInvalid, 0.0);
        }
        break;
        /*
        STASIS
        */
        case FORCE_POWER_HOLD:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            eLink1 = EffectParalyze();
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_HOLD));
            eLink1 = SetEffectIcon(eLink1, 15);
            eLink2 = EffectMovementSpeedDecrease(50);
            eLink2 = EffectLinkEffects(eLink2, EffectACDecrease(4));
            eLink2 = SetEffectIcon(eLink2, 15);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            //Make Immunity Checks
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
            if(nResist == 0)
            {
                // Remove any lower level or equal versions of this power.
                // DJS-OEI 9/30/2004
                // Since this spell has differing effects based on whether the
                // saving throw succeeds or fails, we can't remove the related
                // powers or a failed save on the second cast will override a
                // succeeded save on the first cast.
                //Sp_RemoveRelatedPowers( oTarget, FORCE_POWER_HOLD );
                // Do not apply the effects of this power if a more powerful
                // version is already attached to the target.
                if( !Sp_BetterRelatedPowerExists( oTarget, FORCE_POWER_HOLD ) ) {
                    float fDuration = Sp_CalcDuration( 12.0 );
                    int nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves == 0)
                    {
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget,fDuration);
                    }
                    else
                    {
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, fDuration);
                    }
                }
            }
            else
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        /*
        STASIS FIELD
        */
        case FORCE_POWER_SLEEP:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            float fRange = Sp_CalcRange( 10.0 );
            eLink1 = EffectParalyze();
            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_HOLD));
            eLink1 = SetEffectIcon(eLink1, 27);
            eLink2 = EffectMovementSpeedDecrease(50);
            eLink2 = EffectLinkEffects(eLink2, EffectACDecrease(4));
            eLink2 = SetEffectIcon(eLink2, 27);
            //oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
            oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oTarget))
            {
                if(GetIsEnemy(oTarget) && GetRacialType(oTarget) != RACIAL_TYPE_DROID)
                {
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    //Make Immunity Checks
                    int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
                    if(nResist == 0)
                    {
                        // Remove any lower level or equal versions of this power.
                        // DJS-OEI 9/30/2004
                        // Since this spell has differing effects based on whether the
                        // saving throw succeeds or fails, we can't remove the related
                        // powers or a failed save on the second cast will override a
                        // succeeded save on the first cast.
                        //Sp_RemoveRelatedPowers( oTarget, FORCE_POWER_SLEEP );
                        // Do not apply the effects of this power if a more powerful
                        // version is already attached to the target.
                        if( !Sp_BetterRelatedPowerExists( oTarget, FORCE_POWER_SLEEP ) ) {
                            float fDuration = Sp_CalcDuration( 12.0 );
                            int nSaves = Sp_MySavingThrows(oTarget);
                            if(nSaves == 0)
                            {
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                            }
                            else
                            {
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, fDuration);
                            }
                        }
                    }
                }
                //oTarget = GetNextObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
                oTarget = GetNextObjectInShape(SHAPE_SPHERE, fRange, GetLocation(oTarget), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        /*
        SLOW
        */
        case FORCE_POWER_SLOW:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            eLink1 = EffectMovementSpeedDecrease(50);
            eLink1 = EffectLinkEffects(eLink1, EffectACDecrease(2));
            eLink1 = EffectLinkEffects(eLink1, EffectAttackDecrease(2));
            //eLink1 = EffectLinkEffects(eLink1, EffectDamageDecrease(2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowDecrease(SAVING_THROW_REFLEX,2));
            eLink2 = EffectVisualEffect(VFX_PRO_AFFLICT);
            eLink1 = SetEffectIcon(eLink1, 28);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            //Make Immunity Checks
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
            if(nResist == 0)
            {
                int nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oTarget, FORCE_POWER_SLOW );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oTarget, FORCE_POWER_SLOW ) ) {
                        float fDuration = Sp_CalcDuration( 30.0 );
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, 1.0);
                    }
                }
            }
        }
        break;
        /*
        BURST OF SPEED
        */
        case FORCE_POWER_SPEED_BURST:
        {
            // DJS-OEI 12/9/2003
            // For KotOR2, we have decided to modify the application behavior
            // of Force Power trees. Lower level versions of Force Powers will
            // no longer overwrite higher level versions, although this means
            // the caster still loses their Force Points to no effect. Also,
            // casting a Force Power will remove any Force Powers of equal or
            // lesser level prior to applying themselves.
            float fDuration = Sp_CalcDuration( 36.0 );
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_SPEED_BURST );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_SPEED_BURST ) ) {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectMovementSpeedIncrease(99);
                eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(2));
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_KNIGHTS_SPEED));
                eLink1 = SetEffectIcon(eLink1, 2);
                if(OBJECT_SELF == GetPartyMemberByIndex(0))
                {
                    eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_SPEED));
                }
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_SPEED_BURST)) {
                            Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_SPEED_BURST );
                            eLink2 = EffectMovementSpeedIncrease(99);
                            eLink2 = EffectLinkEffects(eLink2, EffectACIncrease(2));
                            eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_DUR_SPEED));
                            eLink2 = SetEffectIcon(eLink2, 2);
                            Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink2, fDuration, eInvalid, 0.0);
                    }
                }
            }
        }
        break;
        /*
        MASTER SPEED
        */
        case FORCE_POWER_SPEED_MASTERY:
        {
            // DJS-OEI 12/9/2003
            // For KotOR2, we have decided to modify the application behavior
            // of Force Power trees. Lower level versions of Force Powers will
            // no longer overwrite higher level versions, although this means
            // the caster still loses their Force Points to no effect. Also,
            // casting a Force Power will remove any Force Powers of equal or
            // lesser level prior to applying themselves.
            float fDuration = Sp_CalcDuration( 36.0 );
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_SPEED_MASTERY );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_SPEED_MASTERY ) ) {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectMovementSpeedIncrease(99);
                eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(4));
                eLink1 = EffectLinkEffects(eLink1, EffectModifyAttacks(2));
                eLink1 = SetEffectIcon(eLink1, 22);
                if(OBJECT_SELF == GetPartyMemberByIndex(0))
                {
                    eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_SPEED));
                    //eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_IMP_SPEED_MASTERY));
                }
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_SPEED_MASTERY)) {
                            Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_SPEED_MASTERY );
                            eLink2 = EffectMovementSpeedIncrease(99);
                            eLink2 = EffectLinkEffects(eLink2, EffectACIncrease(4));
                            eLink2 = EffectLinkEffects(eLink2, EffectModifyAttacks(2));
                            eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_DUR_SPEED));
                            eLink2 = SetEffectIcon(eLink2, 22);
                            Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink2, fDuration, eInvalid, 0.0);
                    }
                }
            }
        }
        break;
        /*
        STUN
        */
        case FORCE_POWER_STUN:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_MIND_AFFECTING;
            eLink1 = EffectStunned();
            //eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_HOLD));
            eLink1 = SetEffectIcon(eLink1, 29);
            eLink2 = EffectMovementSpeedDecrease(50);
            eLink2 = EffectLinkEffects(eLink2, EffectACDecrease(4));
            eLink1 = SetEffectIcon(eLink1, 29);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            //Make Immunity Checks
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
            int nSaves;
            if(nResist == 0)
            {
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( oTarget, FORCE_POWER_STUN );
                // Do not apply the effects of this power if a more powerful
                // version is already attached to the target.
                if( !Sp_BetterRelatedPowerExists( oTarget, FORCE_POWER_STUN ) ) {
                    float fDuration = Sp_CalcDuration( 9.0 );
                    nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves == 0)
                    {
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                    }
                    else
                    {
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, fDuration);
                    }
                }
            }
            if(nResist > 0 || nSaves > 0)
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        /*
        SUPRESS FORCE
        */
        case FORCE_POWER_SUPRESS_FORCE:
        {
            effect eBuff = GetFirstEffect(oTarget);
            int bValid = FALSE;
            while(GetIsEffectValid(eBuff))
            {
                if(GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_AURA ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_SHIELD ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_MIND ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_KNIGHT_MIND ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_SPEED_BURST ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_KNIGHT_SPEED ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_RESIST_FORCE ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_RESIST_POISON_DISEASE_SONIC ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_FORCE_BARRIER ||
                   GetEffectSpellId(eBuff) == FORCE_POWER_IMPROVED_FORCE_BARRIER )
                 {
                    RemoveEffect(oTarget, eBuff);
                 }
                 eBuff = GetNextEffect(oTarget);
            }
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId()));
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FORCE_BREACH), oTarget);
        }
        break;
        /*
        WOUND
        */
        case FORCE_POWER_WOUND:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            // DJS-OEI 3/25/2004
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, 0, 0, (GetHitDice(OBJECT_SELF)*2)/3 );
            //SWFP_DAMAGE = (GetHitDice(OBJECT_SELF)*2)/3;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            effect eChoke = EffectChoke();
            eChoke = SetEffectIcon(eChoke, 31);
            effect eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
            int nResist = Sp_BlockingChecks(oTarget, eChoke, eDamage, eInvalid);
            int nSaves;
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if(nResist == 0)
            {
                nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_CHOKE), oTarget);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eChoke, oTarget, 6.0);
                    int nIdx = 1;
                    float fDelay;
                    SP_InterativeDamage(eDamage, 7, oTarget);
                }
            }
            if(nResist > 0 || nSaves > 0)
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        //
        // Force Sight
        //
        case FORCE_POWER_FORCE_SIGHT:
        {
            float fDuration = Sp_CalcDuration( 20.0 );
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_FORCE_SIGHT );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_FORCE_SIGHT ) ) {
                SWFP_HARMFUL = FALSE;
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, EffectForceSight(), fDuration, eInvalid, 0.0);
            }
        }
        break;
        case SPECIAL_ABILITY_BODY_FUEL:
        {
            effect eBody = EffectBodyFuel();
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBody, OBJECT_SELF, 30.0);
        }
        break;
        case SPECIAL_ABILITY_ENHANCED_SENSES:
        {
            effect eAC = EffectACDecrease(6);
            effect eAware = EffectSkillIncrease(SKILL_AWARENESS, 10);
            effect eSee = EffectTrueSeeing();
            eLink1 = EffectLinkEffects(eAC, eAware);
            eLink1 = EffectLinkEffects(eLink1, eAware);
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, OBJECT_SELF, RoundsToSeconds(10));
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_MIND_FORCE), OBJECT_SELF);
        }
        break;
        case SPECIAL_ABILITY_PSYCHIC_STANCE:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_MIND_AFFECTING;
            eLink1 = EffectPsychicStatic();
            Sp_ApplyEffects(TRUE, oTarget, 10.0, 1000, eLink1, 20.0, eInvalid, 0.0);
        }
        break;
        /*
        Rage
        This ability allows Zaalbar to fly into a rage.
        When Zaalbar flies into a rage he gains +4 to his Strength and Constitution.  He also gains a +2 bonus on
        Fortitude and Will saves.  While raging Zaalbar cannot use any skills.  He also has a -4 penalty to his Defense rating.
        Interface: Mystical.  It takes one round to initiate the rage.
        Prerequisites: Nothing.  This is a unique NPC power.
        */
        case SPECIAL_ABILITY_RAGE:
        {
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_FORT, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 4));
            eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 4));
            eLink1 = EffectLinkEffects(eLink1, EffectACDecrease(4));
            Sp_ApplyEffects(TRUE, OBJECT_SELF, 0.0, 1, eLink1, 30.0, eInvalid, 0.0);
        }
        break;
        case 83: //Monster Slam Attack
        {
            SP_MyPrintString("I am attempting to use monster slam");
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_REFLEX;
            SWFP_DAMAGE = GetHitDice(OBJECT_SELF);
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_BLUDGEONING;
            eLink1 = EffectForcePushed();
            eLink2 = EffectStunned();
            effect eDamage = EffectDamage(GetHitDice(OBJECT_SELF), SWFP_DAMAGE_TYPE);
            if(!ReflexSave(oTarget, 15))
            {
                eDamage = EffectDamage(GetHitDice(OBJECT_SELF), SWFP_DAMAGE_TYPE);
                DelayCommand(0.5, SP_MyApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget));
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 0.25);
                DelayCommand(2.55, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, 3.0));
            }
            else
            {
                int nApply;
                // DJS-OEI 11/20/2003
                // If the target has the Evasion feat, the damage on a successful
                // Reflex save is 0. Otherwise, it's half the original damage.
                if( GetHasFeat( FEAT_EVASION, oTarget ) ) {
                    nApply = 0;
                }
                else {
                    nApply = GetHitDice(OBJECT_SELF)/2;
                }
                eDamage = EffectDamage(nApply, SWFP_DAMAGE_TYPE);
                DelayCommand(0.5, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, 0.25));
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_FORCE_PUSH), oTarget);
            }
        }
        break;
        case 130: //Fire Breath Weapon
        {
            oTarget = GetSpellTargetObject();
            int nDC = 15;
            int nDamage = 40;
            effect eBeam = EffectBeam(2053, OBJECT_SELF, BODY_NODE_HEAD);
            effect eVFX = EffectVisualEffect(1039);
            effect eBump = EffectVisualEffect(2062);
            effect eHorror = EffectHorrified();
            eHorror = SetEffectIcon(eHorror, 57);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget);
            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, 1.0);
            if(GetHitDice(oTarget) < 7 || FortitudeSave(oTarget, 15) == FALSE)
            {
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eHorror, oTarget, 3.0);
            }
            DelayCommand(0.33, SP_MyApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBump, oTarget, 1.5));
            if(ReflexSave(oTarget, nDC, SAVING_THROW_TYPE_FIRE))
            {
                // DJS-OEI 11/20/2003
                // If the target has the Evasion feat, the damage on a successful
                // Reflex save is 0. Otherwise, it's half the original damage.
                if( GetHasFeat( FEAT_EVASION, oTarget ) ) {
                    nDamage = 0;
                }
                else {
                    nDamage /= 2;
                }
            }
            effect eDam = EffectDamage(nDamage, DAMAGE_TYPE_FIRE);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
        }
        break;
        case 131:   // Sonic Howl
        {
            // DJS-OEI 9/27/2004
            // This is basically just Master Force Scream.
            /*
            int nVFX = 3002;
            int nDC = 15;
            effect eDex = EffectAbilityDecrease(ABILITY_DEXTERITY, 3);
            eDex = SetEffectIcon(eDex, 106);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(nVFX), OBJECT_SELF);
            oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 10.0, GetSpellTargetLocation());
            while(GetIsObjectValid(oTarget))
            {
                if(GetIsEnemy(oTarget))
                {
                    if(!FortitudeSave(oTarget, nDC, SAVING_THROW_TYPE_SONIC))
                    {
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDex, oTarget, 30.0);
                    }
                }
                oTarget = GetNextObjectInShape(SHAPE_SPHERE, 4.0, GetSpellTargetLocation());
            }
            */
            // Force Scream and Improved Force Scream both affect
            // targets in a cone extending from the caster's location.
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_SONIC;
            // Each version of the spell causes differing amounts of damage.
            int nDamageRolls;
            int nAttributeDamage;
            int nIconID;
            int nShape;
            float fShapeSize;
            int nVFXID;
                nDamageRolls = 7;
                nAttributeDamage = 6;
                nIconID = 113;
                nShape = SHAPE_SPHERE;
                // DJS-OEI 1/14/2004
                // Increase the range slightly. Since the range for this spell
                // is 10m, the pathing system fudging will in some cases not
                // cuase any valid targets to be within 10m to get damaged.
                //fShapeSize = Sp_CalcRange( 10.0 );
                fShapeSize = Sp_CalcRange( 12.0 );
                nVFXID = 9007;
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect( nVFXID ), OBJECT_SELF);
            object oTarget = GetFirstObjectInShape(nShape, fShapeSize, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oTarget))
            {
                int nTotalDamage = Sp_CalcDamage( oTarget, nDamageRolls, 6 );
                // Create the damage effects.
                eLink1 = EffectDamage( nTotalDamage, DAMAGE_TYPE_SONIC );
                eLink2 = EffectAbilityDecrease(ABILITY_STRENGTH, nAttributeDamage);
                eLink2 = EffectLinkEffects(eLink2, EffectAbilityDecrease(ABILITY_DEXTERITY, nAttributeDamage));
                eLink2 = EffectLinkEffects(eLink2, EffectAbilityDecrease(ABILITY_INTELLIGENCE, nAttributeDamage));
                eLink2 = EffectLinkEffects(eLink2, EffectAbilityDecrease(ABILITY_WISDOM, nAttributeDamage));
                eLink2 = EffectLinkEffects(eLink2, EffectAbilityDecrease(ABILITY_CHARISMA, nAttributeDamage));
                eLink2 = EffectLinkEffects(eLink2, EffectAbilityDecrease(ABILITY_CONSTITUTION, nAttributeDamage));
                eLink2 = SetEffectIcon(eLink2, nIconID);
                // Check resistances.
                int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                if( ( GetRacialType(oTarget) != RACIAL_TYPE_DROID ) &&
                    GetIsEnemy(oTarget) )
                {
                    if(nResist == 0)
                    {
                        int nSaves = Sp_MySavingThrows(oTarget, 20);
                        if(nSaves <= 0)
                        {
                            // Apply physical damage effect to the target.
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink1, oTarget);
                            // Remove any lower level or equal versions of this power.
                            Sp_RemoveRelatedPowers( oTarget, GetSpellId() );
                            // Do not apply the effects of this power if a more powerful
                            // version is already attached to the target.
                            if( !Sp_BetterRelatedPowerExists( oTarget, GetSpellId() ) ) {
                                // Apply the attribute damage effect.
                                float fDuration = Sp_CalcDuration( 30.0 );
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, fDuration);
                            }
                        }
                        else {
                            int nApply;
                            // DJS-OEI 11/20/2003
                            // If the target has the Evasion feat, the damage on a successful
                            // save is 0. Otherwise, it's half the original damage.
                            if( GetHasFeat( FEAT_EVASION, oTarget ) ) {
                                nApply = 0;
                            }
                            else {
                                nApply = nTotalDamage/2;
                            }
                            if( nApply > 0 ) {
                                // The target saved, so the attribute damage is ignored.
                                // Rebuild the damage effect with the new damage.
                                eLink1 = EffectDamage( nApply, DAMAGE_TYPE_SONIC );
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink1, oTarget);
                            }
                        }
                    }
                    else
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                    }
                }
                oTarget = GetNextObjectInShape(nShape, fShapeSize, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        // DJS-OEI 12/11/2003
        case FORCE_POWER_FORCE_BARRIER:
        {
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_FORCE_BARRIER );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_FORCE_BARRIER ) ) {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectDamageResistance(DAMAGE_TYPE_BLUDGEONING, 4);
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_PIERCING, 4));
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SLASHING, 4));
                eLink1 = SetEffectIcon(eLink1, 64);
                eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
                eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
                float fDuration = Sp_CalcDuration( 30.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_FORCE_BARRIER)) {
                         Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_FORCE_BARRIER );
                         eLink1 = EffectDamageResistance(DAMAGE_TYPE_BLUDGEONING, 4);
                         eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_PIERCING, 4));
                         eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SLASHING, 4));
                         eLink1 = SetEffectIcon(eLink1, 64);
                         eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
                         eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
                         float fDuration = Sp_CalcDuration( 30.0 );
                         Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                    }
                }
            }
        }
        break;
        // DJS-OEI 12/11/2003
        case FORCE_POWER_IMPROVED_FORCE_BARRIER:
        {
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_IMPROVED_FORCE_BARRIER );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_IMPROVED_FORCE_BARRIER ) ) {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectDamageResistance(DAMAGE_TYPE_BLUDGEONING, 8);
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_PIERCING, 8));
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SLASHING, 8));
                eLink1 = SetEffectIcon(eLink1, 65);
                eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
                eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
                float fDuration = Sp_CalcDuration( 45.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_IMPROVED_FORCE_BARRIER)) {
                         Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_IMPROVED_FORCE_BARRIER );
                         eLink1 = EffectDamageResistance(DAMAGE_TYPE_BLUDGEONING, 8);
                         eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_PIERCING, 8));
                         eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SLASHING, 8));
                         eLink1 = SetEffectIcon(eLink1, 65);
                         eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
                         eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
                         float fDuration = Sp_CalcDuration( 45.0 );
                         Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                    }
                }
            }
        }
        break;
        // DJS-OEI 12/11/2003
        case FORCE_POWER_MASTER_FORCE_BARRIER:
        {
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_MASTER_FORCE_BARRIER );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, FORCE_POWER_MASTER_FORCE_BARRIER ) ) {
                SWFP_HARMFUL = FALSE;
                eLink1 = EffectDamageResistance(DAMAGE_TYPE_BLUDGEONING, 15);
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_PIERCING, 15));
                eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SLASHING, 15));
                eLink1 = SetEffectIcon(eLink1, 66);
                eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
                eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
                float fDuration = Sp_CalcDuration( 60.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
            }
            //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
            //  Will add this bonus to anyone else w/Force Chain for free.
            if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                int index = 0;
                for ( ; index < 3; ++index ) {
                    object oCharacter = GetPartyMemberByIndex(index);
                    if ( oCharacter != OBJECT_SELF
                         && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                         && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_MASTER_FORCE_BARRIER)) {
                         Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_MASTER_FORCE_BARRIER );
                         eLink1 = EffectDamageResistance(DAMAGE_TYPE_BLUDGEONING, 15);
                         eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_PIERCING, 15));
                         eLink1 = EffectLinkEffects(eLink1, EffectDamageResistance(DAMAGE_TYPE_SLASHING, 15));
                         eLink1 = SetEffectIcon(eLink1, 66);
                         eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
                         eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
                         float fDuration = Sp_CalcDuration( 60.0 );
                         Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                    }
                }
            }
        }
        break;
        // DJS-OEI 12/12/2003
        // Only PCs, NPCs, and Friendly Allies should cast these
        // versions of Battle Meditation. That way, only allies will
        // get bonuses with this spell ID and only targets will get
        // penalties with this spell ID.
        case FORCE_POWER_BATTLE_MEDITATION_PC:
        {
            SWFP_HARMFUL = FALSE;
            // Bonuses
            eLink1 = EffectDamageIncrease(2, DAMAGE_TYPE_UNIVERSAL);
            eLink1 = EffectLinkEffects(eLink1, EffectAttackIncrease(2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectVPRegenModifier( 50 ) );
            eLink1 = SetEffectIcon(eLink1, 67);
            int nCnt = 0;
            float fDuration = Sp_CalcDuration( 20.0 );
            object oParty;
            if(IsObjectPartyMember(OBJECT_SELF))
            {
                // The caster is a party member. Apply the benefits
                // to the each member of the party.
                oParty = GetPartyMemberByIndex(nCnt);
            }
            else
            {
                // The caster is not a party member. Apply the benefits
                // to the closest three allies.
                oParty = OBJECT_SELF;
            }
            while(nCnt < 3)
            {
                if( GetIsObjectValid(oParty) &&
                    GetRacialType(oParty) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oParty, FORCE_POWER_BATTLE_MEDITATION_PC );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oParty, FORCE_POWER_BATTLE_MEDITATION_PC ) ) {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9000), oParty);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oParty, fDuration);
                    }
                }
                nCnt++;
                if(IsObjectPartyMember(OBJECT_SELF))
                {
                   oParty = GetPartyMemberByIndex(nCnt);
                }
                else
                {
                   oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt);
                }
            }
        }
        break;
        case FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC:
        {
            SWFP_HARMFUL = FALSE;
            // Bonuses
            eLink1 = EffectDamageIncrease(2);
            eLink1 = EffectLinkEffects(eLink1, EffectAttackIncrease(2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2));
            eLink1 = EffectLinkEffects(eLink1, EffectVPRegenModifier( 50 ) );
            eLink1 = SetEffectIcon(eLink1, 68);
            int nCnt = 0;
            float fDuration = Sp_CalcDuration( 20.0 );
            object oParty;
            if(IsObjectPartyMember(OBJECT_SELF))
            {
                // The caster is a party member. Apply the benefits
                // to the each member of the party.
                oParty = GetPartyMemberByIndex(nCnt);
            }
            else
            {
                // The caster is not a party member. Apply the benefits
                // to the closest three allies.
                oParty = OBJECT_SELF;
            }
            //tIterae over all targets of the beneficial effects and
            // apply them.
            while(nCnt < 3)
            {
                if( GetIsObjectValid(oParty) &&
                    GetRacialType(oParty) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oParty, FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oParty, FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC ) ) {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9001), oParty);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oParty, fDuration);
                    }
                }
                nCnt++;
                if(IsObjectPartyMember(OBJECT_SELF))
                {
                   oParty = GetPartyMemberByIndex(nCnt);
                }
                else
                {
                   oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt);
                }
            }
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_SHAPE = SHAPE_SPHERE;
            // Penalties
            eLink1 = EffectDamageDecrease(2);
            eLink1 = EffectLinkEffects(eLink1, EffectAttackDecrease(2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowDecrease(SAVING_THROW_WILL, 2));
            eLink1 = SetEffectIcon(eLink1, 68);
            // Iterate over all targets of the detrimental effects and
            // apply them.
            // Get each creature within 10.0 units.
            object oCreature = GetFirstObjectInShape(SWFP_SHAPE, 10.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oCreature))
            {
                // This power targets hostile creatures only.
                if( GetIsObjectValid(oCreature) &&
                    GetIsEnemy(oCreature) &&
                    GetRacialType(oCreature) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    //Make Immunity Checks
                    int nResist = Sp_BlockingChecks(oCreature, eLink1, eInvalid, eInvalid);
                    if(nResist == 0)
                    {
                        int nSaves = Sp_MySavingThrows(oCreature);
                        if(nSaves == 0)
                        {
                            // Remove any lower level or equal versions of this power.
                            Sp_RemoveRelatedPowers( oCreature, FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC );
                            // Do not apply the effects of this power if a more powerful
                            // version is already attached to the target.
                            if( !Sp_BetterRelatedPowerExists( oCreature, FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC ) ) {
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9003), oCreature);
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oCreature, fDuration);
                            }
                        }
                    }
                }
                oCreature = GetNextObjectInShape(SWFP_SHAPE, 10.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        case FORCE_POWER_MASTER_BATTLE_MEDITATION_PC:
        {
            SWFP_HARMFUL = FALSE;
            // Bonuses
            eLink1 = EffectDamageIncrease(4);
            eLink1 = EffectLinkEffects(eLink1, EffectAttackIncrease(4));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 4));
            eLink1 = EffectLinkEffects(eLink1, EffectVPRegenModifier( 50 ) );
            eLink1 = SetEffectIcon(eLink1, 69);
            int nCnt = 0;
            float fDuration = Sp_CalcDuration( 20.0 );
            object oParty;
            if(IsObjectPartyMember(OBJECT_SELF))
            {
                // The caster is a party member. Apply the benefits
                // to the each member of the party.
                oParty = GetPartyMemberByIndex(nCnt);
            }
            else
            {
                // The caster is not a party member. Apply the benefits
                // to the closest three allies.
                oParty = OBJECT_SELF;
            }
            // Iterate over all targets of the beneficial effects and
            // apply them.
            while(nCnt < 3)
            {
                if( GetIsObjectValid(oParty) &&
                    GetRacialType(oParty) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oParty, FORCE_POWER_MASTER_BATTLE_MEDITATION_PC );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oParty, FORCE_POWER_MASTER_BATTLE_MEDITATION_PC ) ) {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9002), oParty);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oParty, fDuration);
                    }
                }
                nCnt++;
                if(IsObjectPartyMember(OBJECT_SELF))
                {
                   oParty = GetPartyMemberByIndex(nCnt);
                }
                else
                {
                   oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt);
                }
            }
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_SHAPE = SHAPE_SPHERE;
            // Penalties
            eLink1 = EffectDamageDecrease(4);
            eLink1 = EffectLinkEffects(eLink1, EffectAttackDecrease(4));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowDecrease(SAVING_THROW_WILL, 4));
            eLink1 = SetEffectIcon(eLink1, 69);
            // Iterate over all targets of the detrimental effects and
            // apply them.
            // Get each creature within 15.0 units.
            object oCreature = GetFirstObjectInShape(SWFP_SHAPE, 15.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oCreature))
            {
                // This power targets hostile creatures only.
                if( GetIsObjectValid(oCreature) &&
                    GetIsEnemy(oCreature) &&
                    GetRacialType(oCreature) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    //Make Immunity Checks
                    int nResist = Sp_BlockingChecks(oCreature, eLink1, eInvalid, eInvalid);
                    if(nResist == 0)
                    {
                        int nSaves = Sp_MySavingThrows(oCreature);
                        if(nSaves == 0)
                        {
                            // Remove any lower level or equal versions of this power.
                            Sp_RemoveRelatedPowers( oCreature, FORCE_POWER_MASTER_BATTLE_MEDITATION_PC );
                            // Do not apply the effects of this power if a more powerful
                            // version is already attached to the target.
                            if( !Sp_BetterRelatedPowerExists( oCreature, FORCE_POWER_MASTER_BATTLE_MEDITATION_PC ) ) {
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9004), oCreature);
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oCreature, fDuration);
                            }
                        }
                    }
                }
                oCreature = GetNextObjectInShape(SWFP_SHAPE, 15.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        // DJS-OEI 12/12/2003
        // Only enemies of the PC party should cast these
        // versions of Battle Meditation. That way, only enemies will
        // get bonuses with this spell ID and only "allied" targets will get
        // penalties with this spell ID.
        case FORCE_POWER_BAT_MED_ENEMY:
        {
            SWFP_HARMFUL = FALSE;
            // Bonuses
            eLink1 = EffectDamageIncrease(2, DAMAGE_TYPE_UNIVERSAL);
            eLink1 = EffectLinkEffects(eLink1, EffectAttackIncrease(2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2));
            eLink1 = SetEffectIcon(eLink1, 107);
            int nCnt = 0;
            float fDuration = Sp_CalcDuration( 20.0 );
            //Apply the benefits to the closest three allies.
            object oParty = OBJECT_SELF;
            while(nCnt < 3)
            {
                if( GetIsObjectValid(oParty) &&
                    GetRacialType(oParty) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oParty, FORCE_POWER_BAT_MED_ENEMY );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oParty, FORCE_POWER_BAT_MED_ENEMY ) ) {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9000), oParty);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oParty, fDuration);
                    }
                }
                nCnt++;
                oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt);
            }
        }
        break;
        case FORCE_POWER_IMP_BAT_MED_ENEMY:
        {
            SWFP_HARMFUL = FALSE;
            // Bonuses
            eLink1 = EffectDamageIncrease(2);
            eLink1 = EffectLinkEffects(eLink1, EffectAttackIncrease(2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2));
            eLink1 = SetEffectIcon(eLink1, 108);
            int nCnt = 0;
            float fDuration = Sp_CalcDuration( 20.0 );
            object oParty = OBJECT_SELF;
            // Iterate over all targets of the beneficial effects and
            // apply them.
            while(nCnt < 3)
            {
                if( GetIsObjectValid(oParty) &&
                    GetRacialType(oParty) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oParty, FORCE_POWER_IMP_BAT_MED_ENEMY );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oParty, FORCE_POWER_IMP_BAT_MED_ENEMY ) ) {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9001), oParty);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oParty, fDuration);
                    }
                }
                nCnt++;
                oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt);
            }
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_SHAPE = SHAPE_SPHERE;
            // Penalties
            eLink1 = EffectDamageDecrease(2);
            eLink1 = EffectLinkEffects(eLink1, EffectAttackDecrease(2));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowDecrease(SAVING_THROW_WILL, 2));
            eLink1 = SetEffectIcon(eLink1, 108);
            // Iterate over all targets of the detrimental effects and
            // apply them.
            // Get each creature within 10.0 units.
            object oCreature = GetFirstObjectInShape(SWFP_SHAPE, 10.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oCreature))
            {
                // This power targets hostile creatures only.
                if( GetIsObjectValid(oCreature) &&
                    GetIsEnemy(oCreature) &&
                    GetRacialType(oCreature) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    //Make Immunity Checks
                    int nResist = Sp_BlockingChecks(oCreature, eLink1, eInvalid, eInvalid);
                    if(nResist == 0)
                    {
                        int nSaves = Sp_MySavingThrows(oCreature);
                        if(nSaves == 0)
                        {
                            // Remove any lower level or equal versions of this power.
                            Sp_RemoveRelatedPowers( oCreature, FORCE_POWER_IMP_BAT_MED_ENEMY );
                            // Do not apply the effects of this power if a more powerful
                            // version is already attached to the target.
                            if( !Sp_BetterRelatedPowerExists( oCreature, FORCE_POWER_IMP_BAT_MED_ENEMY ) ) {
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9001), oCreature);
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oCreature, fDuration);
                            }
                        }
                    }
                }
                oCreature = GetNextObjectInShape(SWFP_SHAPE, 10.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        case FORCE_POWER_MAS_BAT_MED_ENEMY:
        {
            SWFP_HARMFUL = FALSE;
            // Bonuses
            eLink1 = EffectDamageIncrease(4);
            eLink1 = EffectLinkEffects(eLink1, EffectAttackIncrease(4));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 4));
            eLink1 = SetEffectIcon(eLink1, 109);
            int nCnt = 0;
            float fDuration = Sp_CalcDuration( 20.0 );
            object oParty = OBJECT_SELF;
            // Iterate over all targets of the beneficial effects and
            // apply them.
            while(nCnt < 3)
            {
                if( GetIsObjectValid(oParty) &&
                    GetRacialType(oParty) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oParty, FORCE_POWER_MAS_BAT_MED_ENEMY );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oParty, FORCE_POWER_MAS_BAT_MED_ENEMY ) ) {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9002), oParty);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oParty, fDuration);
                    }
                }
                nCnt++;
                oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt);
            }
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_SHAPE = SHAPE_SPHERE;
            // Penalties
            eLink1 = EffectDamageDecrease(4);
            eLink1 = EffectLinkEffects(eLink1, EffectAttackDecrease(4));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowDecrease(SAVING_THROW_WILL, 4));
            eLink1 = SetEffectIcon(eLink1, 109);
            // Iterate over all targets of the detrimental effects and
            // apply them.
            // Get each creature within 15.0 units.
            object oCreature = GetFirstObjectInShape(SWFP_SHAPE, 15.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oCreature))
            {
                // This power targets hostile creatures only.
                if( GetIsObjectValid(oCreature) &&
                    GetIsEnemy(oCreature) &&
                    GetRacialType(oCreature) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    //Make Immunity Checks
                    int nResist = Sp_BlockingChecks(oCreature, eLink1, eInvalid, eInvalid);
                    if(nResist == 0)
                    {
                        int nSaves = Sp_MySavingThrows(oCreature);
                        if(nSaves == 0)
                        {
                            // Remove any lower level or equal versions of this power.
                            Sp_RemoveRelatedPowers( oCreature, FORCE_POWER_MAS_BAT_MED_ENEMY );
                            // Do not apply the effects of this power if a more powerful
                            // version is already attached to the target.
                            if( !Sp_BetterRelatedPowerExists( oCreature, FORCE_POWER_MAS_BAT_MED_ENEMY ) ) {
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9002), oCreature);
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oCreature, fDuration);
                            }
                        }
                    }
                }
                oCreature = GetNextObjectInShape(SWFP_SHAPE, 15.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        // DJS-OEI 12/15/2003
        case FORCE_POWER_CRUSH_OPPOSITION_I:
        case FORCE_POWER_CRUSH_OPPOSITION_II:
        case FORCE_POWER_CRUSH_OPPOSITION_III:
        case FORCE_POWER_CRUSH_OPPOSITION_IV:
        case FORCE_POWER_CRUSH_OPPOSITION_V:
        case FORCE_POWER_CRUSH_OPPOSITION_VI:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_SHAPE = SHAPE_SPHERE;
            float fRange = Sp_CalcRange( 15.0 );
            // Calculate the severity of the penalty based on the power used.
            // It goes from 1 to 6.
            int nPenalty = GetSpellId() - FORCE_POWER_CRUSH_OPPOSITION_I + 1;
            // Penalties
            eLink1 = EffectAttackDecrease(nPenalty);
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowDecrease(SAVING_THROW_WILL, nPenalty));
            eLink1 = SetEffectIcon(eLink1, 70 + nPenalty - 1);
            // Iterate over all targets of the detrimental effects and
            // apply them.
            // Get each creature within 15.0 units.
            object oCreature = GetFirstObjectInShape(SWFP_SHAPE, fRange, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oCreature))
            {
                // This power targets hostile creatures only.
                if( GetIsObjectValid(oCreature) &&
                    GetIsEnemy(oCreature) &&
                    GetRacialType(oCreature) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    //Make Immunity Checks
                    int nResist = Sp_BlockingChecks(oCreature, eLink1, eInvalid, eInvalid);
                    if(nResist == 0)
                    {
                        int nSaves = Sp_MySavingThrows(oCreature);
                        if(nSaves == 0)
                        {
                            // Remove any lower level or equal versions of this power.
                            Sp_RemoveRelatedPowers( oCreature, GetSpellId() );
                            // Do not apply the effects of this power if a more powerful
                            // version is already attached to the target.
                            if( !Sp_BetterRelatedPowerExists( oCreature, GetSpellId() ) ) {
                                float fDuration = Sp_CalcDuration( 45.0 );
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oCreature, fDuration);
                            }
                        }
                    }
                }
                oCreature = GetNextObjectInShape(SWFP_SHAPE, fRange, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        // DJS-OEI 12/15/2003
        // Applies the Force Body effect to the target. This effect has
        // the value 0, 1, or 2 embedded in it depending on the level of
        // this power cast. This will determine the percentages of FP/VP
        // used to cast subsquent spells.
        case FORCE_POWER_FORCE_BODY:
        case FORCE_POWER_IMPROVED_FORCE_BODY:
        case FORCE_POWER_MASTER_FORCE_BODY:
        {
            int nFX = 0;
            if( GetSpellId() == FORCE_POWER_FORCE_BODY ) {
                nFX = 9011;
            }
            else if( GetSpellId() == FORCE_POWER_IMPROVED_FORCE_BODY ) {
                nFX = 9012;
            }
            else if( GetSpellId() == FORCE_POWER_MASTER_FORCE_BODY ) {
                nFX = 9013;
            }
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, GetSpellId() );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, GetSpellId() ) ) {
                SWFP_HARMFUL = FALSE;
                int nValue = GetSpellId() - FORCE_POWER_FORCE_BODY;
                eLink1 = EffectForceBody( nValue );
                eLink1 = SetEffectIcon(eLink1, 76 + nValue );
                float fDuration = Sp_CalcDuration( 30.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
                ApplyEffectToObject( DURATION_TYPE_INSTANT, EffectVisualEffect( nFX ), OBJECT_SELF );
            }
        }
        break;
        // DJS-OEI 12/30/2003
        case FORCE_POWER_DRAIN_FORCE:
        {
            // Drain Force affects a single target and drains a maximum
            // of 10 FP plus the casting cost.
            // As per Ferret, the caster will always receive at least the casting
            // cost of the power in FP even if none of the targets have
            // that much FP to leech. Since the caster has lost the FP by the time
            // we get here, just apply a Force Heal effect immediately.
            int nCost = GetSpellForcePointCost();
            //eLink1 = EffectHealForcePoints( nCost );
            //ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink1, OBJECT_SELF);
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            // The number of FP to steal is assumed to be 10 to start with.
            int nFPAmount = 20;
            // Determine the number of Force Points the target has. If it is
            // less than the steal amount, decrease the steal amount.
            /*
            int nTargetFP = GetCurrentForcePoints( oTarget );
            if( nTargetFP < nFPAmount ) {
                nFPAmount = nTargetFP;
            }
            */
            if ( GetMaxForcePoints( oTarget ) < 1 )
            {
                nFPAmount = nCost;
            }
            else
            {
                nFPAmount = 20;
            }
            // Always give the player back the casting cost.
            //nFPAmount += nCost;
            // Create a temporary Force Point Damage effect in order to
            // see if the target is immune for some reason.
            eLink1 = EffectDamageForcePoints( nFPAmount );
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eInvalid, eInvalid);
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if( GetRacialType(oTarget) != RACIAL_TYPE_DROID )
            {
                if(nResist == 0)
                {
                    int nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves > 0)
                    {
                        nFPAmount /= 2;
                    }
                    if ( nFPAmount < nCost )
                    {
                        nFPAmount = nCost;
                    }
                    // Apply a Force Point Damage effect to the target.
                    eLink1 = EffectDamageForcePoints( nFPAmount );
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink1, oTarget);
                    // Apply a Force Point Heal effect to the caster.
                    eLink2 = EffectHealForcePoints( nFPAmount );
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink2, OBJECT_SELF);
                }
                else
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                }
            }
        }
        break;
        // DJS-OEI 12/30/2003
        case FORCE_POWER_IMPROVED_DRAIN_FORCE:
        case FORCE_POWER_MASTER_DRAIN_FORCE:
        {
            // Improved Drain Force and Master Drain Force both
            // affect multiple targets.
            // As per Ferret, the caster will always receive at least the casting
            // cost of the power in FP even if none of the targets have
            // that much FP to leech. Since the caster has lost the FP by the time
            // we get here, just apply a Force Heal effect immediately.
            int nCost = GetSpellForcePointCost();
            //eLink1 = EffectHealForcePoints( nCost );
            //ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink1, OBJECT_SELF);
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            int nFullRegainAmount = nCost;
            object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 10.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oTarget))
            {
                int nFPAmount;
                if( GetSpellId() == FORCE_POWER_IMPROVED_DRAIN_FORCE ) {
                    nFPAmount = 20;
                }
                else if( GetSpellId() == FORCE_POWER_MASTER_DRAIN_FORCE ) {
                    nFPAmount = 30;
                }
                // Determine the number of Force Points the target has. If it is
                // less than the steal amount, decrease the steal amount.
                int nTargetFP = GetCurrentForcePoints( oTarget );
                if( nTargetFP < nFPAmount ) {
                    nFPAmount = nTargetFP;
                }
                // Create a temporary Force Point Damage effect in order to
                // see if the target is immune for some reason.
                eLink1 = EffectDamageForcePoints( nFPAmount );
                int nResist = Sp_BlockingChecks(oTarget, eLink1, eInvalid, eInvalid);
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                if( ( GetRacialType(oTarget) != RACIAL_TYPE_DROID ) &&
                    GetIsEnemy(oTarget) )
                {
                    if(nResist == 0)
                    {
                        int nSaves = Sp_MySavingThrows(oTarget);
                        if(nSaves > 0)
                        {
                            nFPAmount /= 2;
                        }
                        // Apply a Force Point Damage effect to the target.
                        eLink1 = EffectDamageForcePoints( nFPAmount );
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink1, oTarget);
                        nFullRegainAmount += nFPAmount;
                    }
                    else
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                    }
                }
                oTarget = GetNextObjectInShape(SHAPE_SPHERE, 10.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
            }
            // Finally, give the player the FP they've drained plus the
            // casting cost (assigned above).
            eLink2 = EffectHealForcePoints( nFullRegainAmount );
            ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink2, OBJECT_SELF);
        }
        break;
        // DJS-OEI 12/30/2003
        case FORCE_POWER_FORCE_SCREAM:
        case FORCE_POWER_IMPROVED_FORCE_SCREAM:
        case FORCE_POWER_MASTER_FORCE_SCREAM:
        {
            // Force Scream and Improved Force Scream both affect
            // targets in a cone extending from the caster's location.
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            SWFP_PRIVATE_SAVE_VERSUS_TYPE = SAVING_THROW_TYPE_SONIC;
            // Each version of the spell causes differing amounts of damage.
            int nDamageRolls;
            int nAttributeDamage;
            int nIconID;
            int nShape;
            float fShapeSize;
            int nVFXID;
            location lTargetLoc;
            if( GetSpellId() == FORCE_POWER_FORCE_SCREAM ) {
                nDamageRolls = 3;
                nAttributeDamage = 2;
                nIconID = 79;
                nShape = SHAPE_SPELLCONE;
                fShapeSize = Sp_CalcRange( 20.0 );
                nVFXID = 9005;
                lTargetLoc = GetLocation( GetSpellTarget() );
            }
            else if( GetSpellId() == FORCE_POWER_IMPROVED_FORCE_SCREAM ) {
                nDamageRolls = 5;
                nAttributeDamage = 4;
                nIconID = 80;
                nShape = SHAPE_SPELLCONE;
                fShapeSize = Sp_CalcRange( 20.0 );
                nVFXID = 9006;
                lTargetLoc = GetLocation( GetSpellTarget() );
            }
            else if( GetSpellId() == FORCE_POWER_MASTER_FORCE_SCREAM ) {
                nDamageRolls = 7;
                nAttributeDamage = 6;
                nIconID = 81;
                nShape = SHAPE_SPHERE;
                // DJS-OEI 1/14/2004
                // Increase the range slightly. Since the range for this spell
                // is 10m, the pathing system fudging will in some cases not
                // cuase any valid targets to be within 10m to get damaged.
                //fShapeSize = Sp_CalcRange( 10.0 );
                fShapeSize = Sp_CalcRange( 12.0 );
                nVFXID = 9007;
                lTargetLoc = GetLocation( OBJECT_SELF );
            }
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect( nVFXID ), OBJECT_SELF);
//            object oTarget = GetFirstObjectInShape(nShape, fShapeSize, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE );
            object oTarget = GetFirstObjectInShape(nShape, fShapeSize, lTargetLoc, TRUE, OBJECT_TYPE_CREATURE );
            while(GetIsObjectValid(oTarget))
            {
                int nTotalDamage = Sp_CalcDamage( oTarget, nDamageRolls, 6 );
                // Create the damage effects.
                eLink1 = EffectDamage( nTotalDamage, DAMAGE_TYPE_SONIC );
                eLink2 = EffectAbilityDecrease(ABILITY_STRENGTH, nAttributeDamage);
                eLink2 = EffectLinkEffects(eLink2, EffectAbilityDecrease(ABILITY_DEXTERITY, nAttributeDamage));
                eLink2 = EffectLinkEffects(eLink2, EffectAbilityDecrease(ABILITY_INTELLIGENCE, nAttributeDamage));
                eLink2 = EffectLinkEffects(eLink2, EffectAbilityDecrease(ABILITY_WISDOM, nAttributeDamage));
                eLink2 = EffectLinkEffects(eLink2, EffectAbilityDecrease(ABILITY_CHARISMA, nAttributeDamage));
                eLink2 = EffectLinkEffects(eLink2, EffectAbilityDecrease(ABILITY_CONSTITUTION, nAttributeDamage));
                eLink2 = SetEffectIcon(eLink2, nIconID);
                // Check resistances.
                int nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eInvalid);
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                if( ( GetRacialType(oTarget) != RACIAL_TYPE_DROID ) &&
                    GetIsEnemy(oTarget) )
                {
                    if(nResist == 0)
                    {
                        int nSaves = Sp_MySavingThrows(oTarget);
                        if(nSaves <= 0)
                        {
                            // Apply physical damage effect to the target.
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink1, oTarget);
                            // Remove any lower level or equal versions of this power.
                            Sp_RemoveRelatedPowers( oTarget, GetSpellId() );
                            // Do not apply the effects of this power if a more powerful
                            // version is already attached to the target.
                            if( !Sp_BetterRelatedPowerExists( oTarget, GetSpellId() ) ) {
                                // Apply the attribute damage effect.
                                float fDuration = Sp_CalcDuration( 30.0 );
                                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oTarget, fDuration);
                            }
                        }
                        else {
                            int nApply;
                            // DJS-OEI 11/20/2003
                            // If the target has the Evasion feat, the damage on a successful
                            // save is 0. Otherwise, it's half the original damage.
                            if( GetHasFeat( FEAT_EVASION, oTarget ) ) {
                                nApply = 0;
                            }
                            else {
                                nApply = nTotalDamage/2;
                            }
                            if( nApply > 0 ) {
                                // The target saved, so the attribute damage is ignored.
                                // Rebuild the damage effect with the new damage.
                                eLink1 = EffectDamage( nApply, DAMAGE_TYPE_SONIC );
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink1, oTarget);
                            }
                        }
                    }
                    else
                    {
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                    }
                }
//                oTarget = GetNextObjectInShape(nShape, fShapeSize, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE );
                oTarget = GetNextObjectInShape(nShape, fShapeSize, lTargetLoc, TRUE, OBJECT_TYPE_CREATURE );
            }
        }
        break;
        case FORCE_POWER_FURY:
        case FORCE_POWER_IMPROVED_FURY:
        case FORCE_POWER_MASTER_FURY:
        case FORCE_POWER_WOOKIEE_RAGE_I:
        case FORCE_POWER_WOOKIEE_RAGE_II:
        case FORCE_POWER_WOOKIEE_RAGE_III:
        {
            SWFP_HARMFUL = FALSE;
            int nVPPerLevel;
            int nSaveModifier;
            int nStrModifier;
            int nDefenseModifier;
            // DJS-OEI 2/15/2005
            // I have no idea why I commented this out, but it happened
            // in January 2004. Apparently the description still indicates
            // the target gets extra attacks. Reinstated since Speed tree
            // uses extra attacks.
            //int nExtraAttacks;
            int nExtraAttacks;
            float nDuration;
            int nIcon;
            if( ( GetSpellId() == FORCE_POWER_FURY ) ||
                ( GetSpellId() == FORCE_POWER_WOOKIEE_RAGE_I ) ) {
                nVPPerLevel = 1;
                nSaveModifier = 1;
                nStrModifier = 2;
                nDefenseModifier = 2;
                // DJS-OEI 2/15/2005
                // I have no idea why I commented this out, but it happened
                // in January 2004. Apparently the description still indicates
                // the target gets extra attacks. Reinstated since Speed tree
                // uses extra attacks.
                //nExtraAttacks = 0;
                nExtraAttacks = 0;
                nDuration = 30.0;
                nIcon = 82;
            }
            else if( ( GetSpellId() == FORCE_POWER_IMPROVED_FURY ) ||
                     ( GetSpellId() == FORCE_POWER_WOOKIEE_RAGE_II ) ) {
                nVPPerLevel = 2;
                nSaveModifier = 2;
                nStrModifier = 4;
                nDefenseModifier = 4; //RWT-OEI 09/27/04 - Changed from 4 to 2 per FMP#400
                // DJS-OEI 2/15/2005
                // I have no idea why I commented this out, but it happened
                // in January 2004. Apparently the description still indicates
                // the target gets extra attacks. Reinstated since Speed tree
                // uses extra attacks.
                //nExtraAttacks = 1;
                nExtraAttacks = 1;
                nDuration = 45.0;
                nIcon = 83;
            }
            else if( ( GetSpellId() == FORCE_POWER_MASTER_FURY ) ||
                     ( GetSpellId() == FORCE_POWER_WOOKIEE_RAGE_III ) ) {
                nVPPerLevel = 3;
                nSaveModifier = 3;
                nStrModifier = 6;
                nDefenseModifier = 6;
                // DJS-OEI 2/15/2005
                // I have no idea why I commented this out, but it happened
                // in January 2004. Apparently the description still indicates
                // the target gets extra attacks. Reinstated since Speed tree
                // uses extra attacks.
                //nExtraAttacks = 2;
                nExtraAttacks = 2;
                nDuration = 60.0;
                nIcon = 84;
            }
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, GetSpellId() );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( OBJECT_SELF, GetSpellId() ) ) {
                int nFinalVP = GetHitDice( OBJECT_SELF ) * nVPPerLevel;
                eLink1 = EffectFury();
                eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease( SAVING_THROW_FORT, nSaveModifier ) );
                eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease( SAVING_THROW_WILL, nSaveModifier ) );
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease( ABILITY_STRENGTH, nStrModifier ) );
                eLink1 = EffectLinkEffects(eLink1, EffectACDecrease( nDefenseModifier ) );
                // DJS-OEI 2/15/2005
                // I have no idea why I commented this out, but it happened
                // in January 2004. Apparently the description still indicates
                // the target gets extra attacks. Reinstated since Speed tree
                // uses extra attacks.
                /*
                if( nExtraAttacks > 0 ) {
                    eLink1 = EffectLinkEffects(eLink1, EffectModifyAttacks( nExtraAttacks ) );
                }
                */
                if( nExtraAttacks > 0 ) {
                    eLink1 = EffectLinkEffects(eLink1, EffectModifyAttacks( nExtraAttacks ) );
                }
                eLink1 = EffectLinkEffects(eLink1, EffectImmunity( IMMUNITY_TYPE_PARALYSIS ) );
                eLink1 = EffectLinkEffects(eLink1, EffectImmunity( IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE ) );
                eLink1 = SetEffectIcon(eLink1, nIcon);
                // DJS-OEI 10/16/2004
                // I unlinked this effect from the rest since when the points
                // were used up the effect was destroyed, along with the Fury effect.
                eLink2 = EffectTemporaryHitpoints( nFinalVP );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, nDuration, eInvalid, 0.0);
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink2, nDuration, eInvalid, 0.0);
            }
        }
        break;
        // DJS-OEI 1/2/2004
        case FORCE_POWER_INSPIRE_FOLLOWERS_I:
        case FORCE_POWER_INSPIRE_FOLLOWERS_II:
        case FORCE_POWER_INSPIRE_FOLLOWERS_III:
        case FORCE_POWER_INSPIRE_FOLLOWERS_IV:
        case FORCE_POWER_INSPIRE_FOLLOWERS_V:
        case FORCE_POWER_INSPIRE_FOLLOWERS_VI:
        {
            SWFP_HARMFUL = FALSE;
            float fDuration = Sp_CalcDuration( 45.0 );
            // Calculate the size of the bonus based on the power used.
            // It goes from 1 to 6.
            int nBonus = GetSpellId() - FORCE_POWER_INSPIRE_FOLLOWERS_I + 1;
            // Bonuses
            eLink1 = EffectAttackIncrease(nBonus);
            eLink1 = EffectLinkEffects(eLink1, EffectDamageIncrease(nBonus));
            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, nBonus));
            eLink1 = SetEffectIcon(eLink1, 85 + nBonus - 1);
            int nCnt = 0;
            object oParty;
            if(IsObjectPartyMember(OBJECT_SELF))
            {
                // The caster is a party member. Apply the benefits
                // to the each member of the party.
                oParty = GetPartyMemberByIndex(nCnt);
            }
            else
            {
                // The caster is not a party member. Apply the benefits
                // to the closest three allies.
                oParty = OBJECT_SELF;
            }
            // Iterate over all targets of the beneficial effects and
            // apply them.
            while(nCnt < 3)
            {
                if( GetIsObjectValid(oParty) &&
                    GetRacialType(oParty) != RACIAL_TYPE_DROID )
                {
                    SignalEvent(oParty, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oParty, GetSpellId() );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oParty, GetSpellId() ) ) {
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oParty, fDuration);
                    }
                }
                nCnt++;
                if(IsObjectPartyMember(OBJECT_SELF))
                {
                   oParty = GetPartyMemberByIndex(nCnt);
                }
                else
                {
                   oParty = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt);
                }
            }
        }
        break;
        // DJS-OEI 1/2/2004
        // The first level of the Revitalize tree is separate from the
        // other two levels since it only applies to the first unconcious
        // character closest to the the caster.
        case FORCE_POWER_REVITALIZE:
        {
            SWFP_HARMFUL = FALSE;
            // Make sure the caster is in the party. If they're not we can't
            // really do anything with this power since enemies don't get
            // knocked unconscious, they die.
            if( IsObjectPartyMember(OBJECT_SELF) ) {
                // Find which party members are unconscious. This
                // function makes the assumption there can only be
                // up to 3 party members at a time, so only 2 can
                // be unconscious at maximum or the game would be over.
                object oPossibility1 = OBJECT_INVALID;
                object oPossibility2 = OBJECT_INVALID;
                int nCnt = 0;
                for( nCnt = 0; nCnt < 3; nCnt++ ) {
                    object oPartyMember = GetPartyMemberByIndex(nCnt);
                    // Don't count the caster since they couldn't be
                    // casting the spell if they were unconscious.
                    if( oPartyMember != OBJECT_SELF ) {
                        if( GetIsObjectValid(oPartyMember) &&
                            GetRacialType(oPartyMember) != RACIAL_TYPE_DROID &&
                            GetCurrentHitPoints( oPartyMember ) < 1 ) {
                            if( oPossibility1 == OBJECT_INVALID ) {
                                oPossibility1 = oPartyMember;
                            }
                            else {
                                oPossibility2 = oPartyMember;
                            }
                        }
                    }
                }
                // Determine the final target.
                oTarget = OBJECT_INVALID;
                if( ( oPossibility1 != OBJECT_INVALID ) && ( oPossibility2 == OBJECT_INVALID ) ) {
                    oTarget = oPossibility1;
                }
                else if( ( oPossibility1 == OBJECT_INVALID ) && ( oPossibility2 != OBJECT_INVALID ) ) {
                    // Should never happen, but deal with it anyways.
                    oTarget = oPossibility2;
                }
                else if( ( oPossibility1 != OBJECT_INVALID ) && ( oPossibility2 != OBJECT_INVALID ) ) {
                    // Find the closest unconscious party member.
                    float fDist1;
                    float fDist2;
                    fDist1 = GetDistanceBetween( OBJECT_SELF, oPossibility1 );
                    fDist2 = GetDistanceBetween( OBJECT_SELF, oPossibility2 );
                    if( fDist1 <= fDist2 ) {
                        oTarget = oPossibility1;
                    }
                    else {
                        oTarget = oPossibility2;
                    }
                }
                // If there is a valid target, resurrect it and give it 5% of its max HP back.
                if( oTarget != OBJECT_INVALID ) {
                    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                    //int nHeal = ( GetMaxHitPoints( oTarget ) * 5 ) / 100;
                    //if( nHeal < 1 ) {
                    //    nHeal = 1;
                    //}
                    //RWT-OEI 09/27/04 FMP#4893 - They want it to do fixed HP amounts
                    int nHeal = 10;
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), oTarget);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHeal), oTarget);
                    ApplyEffectToObject( DURATION_TYPE_INSTANT, EffectVisualEffect( 9008 ), oTarget );
                }
            }
        }
        break;
        // DJS-OEI 1/2/2004
        case FORCE_POWER_IMPROVED_REVITALIZE:
        case FORCE_POWER_MASTER_REVITALIZE:
        {
            SWFP_HARMFUL = FALSE;
            int nHPPercent = 0;
            if( GetSpellId() == FORCE_POWER_IMPROVED_REVITALIZE ) {
                nHPPercent = 5;
            }
            else {
                nHPPercent = 10;
            }
            // Make sure the caster is in the party. If they're not we can't
            // really do anything with this power since enemies don't get
            // knocked unconscious, they die.
            if( IsObjectPartyMember(OBJECT_SELF) ) {
                // Resurrect all unconscious non-droid party members and
                // give them some of their HP back.
                int nCnt = 0;
                for( nCnt = 0; nCnt < 3; nCnt++ ) {
                    object oPartyMember = GetPartyMemberByIndex(nCnt);
                    // Don't count the caster since they couldn't be
                    // casting the spell if they were unconscious.
                    if( oPartyMember != OBJECT_SELF ) {
                        if( GetIsObjectValid(oPartyMember) &&
                            GetRacialType(oPartyMember) != RACIAL_TYPE_DROID &&
                            GetCurrentHitPoints( oPartyMember ) < 1 ) {
                            SignalEvent(oPartyMember, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                            //int nHeal = ( GetMaxHitPoints( oPartyMember ) * nHPPercent ) / 100;
                            //if( nHeal < 1 ) {
                            //    nHeal = 1;
                            //}
                            //RWT-OEI 09/27/04 - FMP #4893 - They want it to do fixed
                            //heal amounts instead of percentage
                            int nHeal = 0;
                            if ( GetSpellId() == FORCE_POWER_IMPROVED_REVITALIZE )
                            {
                                nHeal = 25;
                            }
                            else
                            {
                                nHeal = 50;
                            }
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), oPartyMember);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHeal), oPartyMember);
                            ApplyEffectToObject( DURATION_TYPE_INSTANT, EffectVisualEffect( 9008 ), oPartyMember );
                        }
                    }
                }
            }
        }
        break;
        // DJS-OEI 1/2/2004
        case FORCE_POWER_FORCE_CRUSH:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_FORT;
            int nDice = GetHitDice(OBJECT_SELF);
            // DJS-OEI 10/7/2004
            // Removed damage level cap and changed to d10.
            /*
            if(nDice > 10)
            {
                nDice = 10;
            }
            */
            //SWFP_DAMAGE = Sp_CalcDamage( oTarget, nDice, 6 );
            SWFP_DAMAGE = Sp_CalcDamage( oTarget, nDice, 10 );
            //SWFP_DAMAGE = d6(nDamage);
            // DJS-OEI 8/16/2004
            // Damage type is now Unstoppable, although its define is still Acid.
            //SWFP_DAMAGE_TYPE = DAMAGE_TYPE_UNIVERSAL;
            SWFP_DAMAGE_TYPE = DAMAGE_TYPE_ACID;
            effect eCrush = EffectCrush();
            effect eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
            int nResist = Sp_BlockingChecks(oTarget, eCrush, eDamage, eInvalid);
            int nSaves;
            SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
            if(nResist == 0)
            {
                nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    // Apply the Crush effect for the length of the damage animation.
                    // Also, time the application of damage to the point at which the
                    // crush animation climaxes.
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eCrush, oTarget, 2.0);
                    DelayCommand( 1.64, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget) );
                    // DJS-OEI 8/16/2004
                    // Finally, delay application of a Force Push effect with no
                    // fly-back duration to cause the target to fall to the ground
                    // and get back up.
                    effect eDrop = EffectForcePushed();
                    DelayCommand( 2.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDrop, oTarget) );
                }
                else {
                    // Half damage.
                    eDamage = EffectDamage(SWFP_DAMAGE/2, SWFP_DAMAGE_TYPE);
                    // Apply the Crush effect for the length of the damage animation.
                    // Also, time the application of damage to the point at which the
                    // crush animation climaxes.
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eCrush, oTarget, 2.0);
                    DelayCommand( 1.64, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget) );
                    // DJS-OEI 8/16/2004
                    // Finally, delay application of a Force Push effect with no
                    // fly-back duration to cause the target to fall to the ground
                    // and get back up.
                    effect eDrop = EffectForcePushed();
                    DelayCommand( 2.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDrop, oTarget) );
                }
            }
            if(nResist > 0)
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
            }
        }
        break;
        // DJS-OEI 1/2/2004
        case FORCE_POWER_FORCE_ENLIGHTENMENT:
        {
            SWFP_HARMFUL = FALSE;
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_FORCE_ENLIGHTENMENT );
            // Apply the highest level versions of the Speed, Armor, and Valor
            // tree known by the caster.
            // Speed
            if( GetSpellAcquired( FORCE_POWER_SPEED_MASTERY ) ) {
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_SPEED_MASTERY );
                eLink1 = EffectMovementSpeedIncrease(99);
                eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(4));
                eLink1 = EffectLinkEffects(eLink1, EffectModifyAttacks(2));
                eLink1 = SetEffectIcon(eLink1, 22);
                if(OBJECT_SELF == GetPartyMemberByIndex(0))
                {
                    eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_SPEED));
                }
                float fDuration = Sp_CalcDuration( 36.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
                //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
                //  Will add this bonus to anyone else w/Force Chain for free.
                if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                    int index = 0;
                    for ( ; index < 3; ++index ) {
                        object oCharacter = GetPartyMemberByIndex(index);
                        if ( oCharacter != OBJECT_SELF
                             && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                             && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_SPEED_MASTERY)) {
                             Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_SPEED_MASTERY);
                            eLink1 = EffectMovementSpeedIncrease(99);
                            eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(4));
                            eLink1 = EffectLinkEffects(eLink1, EffectModifyAttacks(2));
                            eLink1 = SetEffectIcon(eLink1, 22);
                            Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
                        }
                    }
                }
            }
            else if( GetSpellAcquired( FORCE_POWER_KNIGHT_SPEED ) ) {
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_KNIGHT_SPEED );
                eLink1 = EffectMovementSpeedIncrease(99);
                eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(4));
                eLink1 = EffectLinkEffects(eLink1, EffectModifyAttacks(1));
                eLink1 = SetEffectIcon(eLink1, 20);
                if(OBJECT_SELF == GetPartyMemberByIndex(0))
                {
                    eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_SPEED));
                }
                float fDuration = Sp_CalcDuration( 36.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
                //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
                //  Will add this bonus to anyone else w/Force Chain for free.
                if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                    int index = 0;
                    for ( ; index < 3; ++index ) {
                        object oCharacter = GetPartyMemberByIndex(index);
                        if ( oCharacter != OBJECT_SELF
                             && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                             && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_KNIGHT_SPEED)) {
                             Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_KNIGHT_SPEED);
                            eLink1 = EffectMovementSpeedIncrease(99);
                            eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(4));
                            eLink1 = EffectLinkEffects(eLink1, EffectModifyAttacks(1));
                            eLink1 = SetEffectIcon(eLink1, 20);
                            Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
                        }
                    }
                }
            }
            else if( GetSpellAcquired( FORCE_POWER_SPEED_BURST ) ) {
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_SPEED_BURST );
                eLink1 = EffectMovementSpeedIncrease(99);
                eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(2));
                eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_KNIGHTS_SPEED));
                eLink1 = SetEffectIcon(eLink1, 2);
                if(OBJECT_SELF == GetPartyMemberByIndex(0))
                {
                    eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_SPEED));
                }
                float fDuration = Sp_CalcDuration( 36.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
                //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
                //  Will add this bonus to anyone else w/Force Chain for free.
                if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                    int index = 0;
                    for ( ; index < 3; ++index ) {
                        object oCharacter = GetPartyMemberByIndex(index);
                        if ( oCharacter != OBJECT_SELF
                             && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                             && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_SPEED_BURST)) {
                             Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_SPEED_BURST);
                            eLink1 = EffectMovementSpeedIncrease(99);
                            eLink1 = EffectLinkEffects(eLink1, EffectACIncrease(2));
                            eLink1 = EffectLinkEffects(eLink1, EffectVisualEffect(VFX_DUR_KNIGHTS_SPEED));
                            eLink1 = SetEffectIcon(eLink1, 2);
                            Sp_ApplyEffects(FALSE, oCharacter, 0.0, 1, eLink1, fDuration, eInvalid, 0.0);
                        }
                    }
                }
            }
            // Armor
            if( GetSpellAcquired( FORCE_POWER_FORCE_ARMOR ) ) {
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_FORCE_ARMOR );
                eLink1 = EffectACIncrease(6, AC_DODGE_BONUS);
                eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 6));
                eLink1 = SetEffectIcon(eLink1, 7);
                eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
                eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
                float fDuration = Sp_CalcDuration( 20.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
                //  Will add this bonus to anyone else w/Force Chain for free.
                if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                    int index = 0;
                    for ( ; index < 3; ++index ) {
                        object oCharacter = GetPartyMemberByIndex(index);
                        if ( oCharacter != OBJECT_SELF
                             && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                             && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_FORCE_ARMOR)) {
                             Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_FORCE_ARMOR);
                            eLink1 = EffectACIncrease(6, AC_DODGE_BONUS);
                            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 6));
                            eLink1 = SetEffectIcon(eLink1, 7);
                            eLink2 = EffectVisualEffect(VFX_PRO_FORCE_ARMOR);
                            eLink2 = EffectLinkEffects(eLink2, EffectVisualEffect(VFX_PRO_FORCE_SHIELD));
                            Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                        }
                    }
                }
            }
            else if( GetSpellAcquired( FORCE_POWER_FORCE_SHIELD ) ) {
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_FORCE_SHIELD );
                eLink1 = EffectACIncrease(4, AC_DODGE_BONUS);
                eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 4));
                eLink1 = SetEffectIcon(eLink1, 12);
                eLink2 = EffectVisualEffect(VFX_PRO_FORCE_SHIELD);
                float fDuration = Sp_CalcDuration( 20.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
                //  Will add this bonus to anyone else w/Force Chain for free.
                if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                    int index = 0;
                    for ( ; index < 3; ++index ) {
                        object oCharacter = GetPartyMemberByIndex(index);
                        if ( oCharacter != OBJECT_SELF
                             && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                             && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_FORCE_SHIELD)) {
                             Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_FORCE_SHIELD);
                            eLink1 = EffectACIncrease(4, AC_DODGE_BONUS);
                            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 4));
                            eLink1 = SetEffectIcon(eLink1, 12);
                            eLink2 = EffectVisualEffect(VFX_PRO_FORCE_SHIELD);
                            Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                        }
                    }
                }
            }
            else if( GetSpellAcquired( FORCE_POWER_FORCE_AURA ) ) {
                // Remove any lower level or equal versions of this power.
                Sp_RemoveRelatedPowers( OBJECT_SELF, FORCE_POWER_FORCE_AURA );
                eLink1 = EffectACIncrease(2, AC_DODGE_BONUS);
                eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 2));
                eLink1 = SetEffectIcon(eLink1, 8);
                eLink2 = EffectVisualEffect(VFX_PRO_FORCE_AURA);
                float fDuration = Sp_CalcDuration( 20.0 );
                Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                //RWT-OEI 12//29/03 - Added support for the ForceChain FEAT
                //  Will add this bonus to anyone else w/Force Chain for free.
                if ( GetHasFeat(FEAT_FORCE_CHAIN, OBJECT_SELF) ) {
                    int index = 0;
                    for ( ; index < 3; ++index ) {
                        object oCharacter = GetPartyMemberByIndex(index);
                        if ( oCharacter != OBJECT_SELF
                             && GetHasFeat(FEAT_FORCE_CHAIN, oCharacter)
                             && !Sp_BetterRelatedPowerExists( oCharacter, FORCE_POWER_FORCE_AURA)) {
                             Sp_RemoveRelatedPowers( oCharacter, FORCE_POWER_FORCE_AURA);
                            eLink1 = EffectACIncrease(2, AC_DODGE_BONUS);
                            eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_ALL, 2));
                            eLink1 = SetEffectIcon(eLink1, 8);
                            eLink2 = EffectVisualEffect(VFX_PRO_FORCE_AURA);
                            Sp_ApplyEffects(FALSE, OBJECT_SELF, 0.0, 1, eLink1, fDuration, eLink2, 3.0);
                        }
                    }
                }
            }
            // Valor
            if( GetSpellAcquired( FORCE_POWER_MIND_MASTERY ) ) {
                eLink1 = EffectSavingThrowIncrease(SAVING_THROW_ALL,5);
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CHARISMA, 5));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 5));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_DEXTERITY, 5));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_INTELLIGENCE, 5));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 5));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_WISDOM, 5));
                eLink1 = EffectLinkEffects(eLink1, EffectImmunity(IMMUNITY_TYPE_POISON));
                eLink1 = SetEffectIcon(eLink1, 21);
                eLink2 = EffectVisualEffect(VFX_IMP_MIND_MASTERY);
                // Get each creature within 30.0 units.
                object oCreature = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
                while(GetIsObjectValid(oCreature))
                {
                    // This power targets party members only.
                    if( GetIsObjectValid(oCreature) && IsObjectPartyMember(oCreature) )
                    {
                        // Remove any lower level or equal versions of this power.
                        Sp_RemoveRelatedPowers( oCreature, FORCE_POWER_MIND_MASTERY );
                        // Do not apply the effects of this power if a more powerful
                        // version is already attached to the target.
                        if( !Sp_BetterRelatedPowerExists( oCreature, FORCE_POWER_MIND_MASTERY ) ) {
                            SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                            float fDuration = Sp_CalcDuration( 20.0 );
                            Sp_ApplyForcePowerEffects(fDuration, eLink1, oCreature);
                            Sp_ApplyForcePowerEffects(0.0, eLink2, oCreature);
                        }
                    }
                    oCreature = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
                }
            }
            else if( GetSpellAcquired( FORCE_POWER_KNIGHT_MIND ) ) {
                eLink1 = EffectSavingThrowIncrease(SAVING_THROW_ALL,3);
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CHARISMA, 3));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 3));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_DEXTERITY, 3));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_INTELLIGENCE, 3));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 3));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_WISDOM, 3));
                eLink1 = EffectLinkEffects(eLink1, EffectImmunity(IMMUNITY_TYPE_POISON));
                eLink1 = SetEffectIcon(eLink1, 19);
                eLink2 = EffectVisualEffect(1033);
                // Get each creature within 30.0 units.
                object oCreature = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
                while(GetIsObjectValid(oCreature))
                {
                    // This power targets party members only.
                    if( GetIsObjectValid(oCreature) && IsObjectPartyMember(oCreature) )
                    {
                        // Remove any lower level or equal versions of this power.
                        Sp_RemoveRelatedPowers( oCreature, FORCE_POWER_KNIGHT_MIND );
                        // Do not apply the effects of this power if a more powerful
                        // version is already attached to the target.
                        if( !Sp_BetterRelatedPowerExists( oCreature, FORCE_POWER_KNIGHT_MIND ) ) {
                            SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                            float fDuration = Sp_CalcDuration( 20.0 );
                            Sp_ApplyForcePowerEffects(fDuration, eLink1, oCreature);
                            Sp_ApplyForcePowerEffects(0.0, eLink2, oCreature);
                        }
                    }
                    oCreature = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
                }
            }
            else if( GetSpellAcquired( FORCE_POWER_FORCE_MIND ) ) {
                eLink1 = EffectSavingThrowIncrease(SAVING_THROW_FORT,2);
                eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_REFLEX, 2));
                eLink1 = EffectLinkEffects(eLink1, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CHARISMA, 2));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_CONSTITUTION, 2));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_DEXTERITY, 2));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_INTELLIGENCE, 2));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_STRENGTH, 2));
                eLink1 = EffectLinkEffects(eLink1, EffectAbilityIncrease(ABILITY_WISDOM, 2));
                eLink2 = EffectVisualEffect(VFX_IMP_MIND_FORCE);
                eLink1 = SetEffectIcon(eLink1, 10);
                // Get each creature within 30.0 units.
                object oCreature = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
                while(GetIsObjectValid(oCreature))
                {
                    // This power targets party members only.
                    if( GetIsObjectValid(oCreature) && IsObjectPartyMember(oCreature) )
                    {
                        // Remove any lower level or equal versions of this power.
                        Sp_RemoveRelatedPowers( oCreature, FORCE_POWER_FORCE_MIND );
                        // Do not apply the effects of this power if a more powerful
                        // version is already attached to the target.
                        if( !Sp_BetterRelatedPowerExists( oCreature, FORCE_POWER_FORCE_MIND ) ) {
                            SignalEvent(oCreature, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                            float fDuration = Sp_CalcDuration( 20.0 );
                            Sp_ApplyForcePowerEffects(fDuration, eLink1, oCreature);
                            Sp_ApplyForcePowerEffects(0.0, eLink2, oCreature);
                        }
                    }
                    oCreature = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
                }
            }
        }
        break;
        // DJS-OEI 7/29/2004
        case FORCE_POWER_CONFUSION:
        {
            float fDuration = 0.0f;
            int nResist = 0;
            int nSaves = 0;
            // If an active instance of this spell is already
            // in progress, drop through to Mind Trick. The spell
            // will still cost the full amount, though. This should
            // only happen if the player cued a bunch of Confusion
            // castings instead of waiting for Mind Trick to replace
            // it in the interface.
            if( GetGlobalNumber( "000_Human_Conf_Active" ) == 0 ) {
                SWFP_HARMFUL = TRUE;
                SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
                if( GetPlotFlag( oTarget ) ) {
                    return;
                }
                // FAK - OEI 2/3/04 -- racial checks, DC checks
                if (GetRacialType(oTarget) == RACIAL_TYPE_DROID)
                {
                    return;
                }
                if (GetSubRace(oTarget) == 2)
                {
                    return;
                }
                eLink1 = EffectFactionModifier( STANDARD_FACTION_FRIENDLY_1 );
                nResist = Sp_BlockingChecks(oTarget, eLink1, eInvalid, eInvalid);
                if(nResist == 0)
                {
                    nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves == 0)
                    {
                        // Remove any lower level or equal versions of this power.
                        Sp_RemoveRelatedPowers( oTarget, GetSpellId() );
                        // Do not apply the effects of this power if a more powerful
                        // version is already attached to the target.
                        if( !Sp_BetterRelatedPowerExists( oTarget, GetSpellId() ) ) {
                            // Flag this spell as having been cast once already.
                            SetGlobalNumber( "000_Human_Conf_Active", 1 );
                            // If more than one casting is attempted, it will just
                            // drop through to Mind Trick.
                            fDuration = Sp_CalcDuration( 30.0 );
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                            break;
                        }
                    }
                }
                break;
            }
            else {
                // NO BREAK!!!
                // Drop through to Mind Trick.
            }
        }
        ///////////////////////////////////////////////////////////
        //
        // THERE IS NO BREAK HERE ON PURPOSE. FORCE CONFUSION CAN
        // DROP THROUGH TO MIND TRICK IF IT IS CAST AGAIN DURING
        // THE DURATION OF A PREVIOUS CASTING.
        //
        ///////////////////////////////////////////////////////////
        // DJS-OEI 7/28/2004
        case FORCE_POWER_MIND_TRICK:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            if( GetPlotFlag( oTarget ) ) {
                return;
            }
            // FAK - OEI 2/3/04 -- racial checks, DC checks
            if (GetRacialType(oTarget) == RACIAL_TYPE_DROID)
            {
                return;
            }
            if (GetSubRace(oTarget) == 2)
            {
                return;
            }
            eLink1 = EffectMindTrick();
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eInvalid, eInvalid);
            int nSaves;
            if(nResist == 0)
            {
                nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oTarget, GetSpellId() );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oTarget, GetSpellId() ) ) {
                        // In addition to the effect, turn the target away
                        // from the caster.
                        FaceObjectAwayFromObject( oTarget, OBJECT_SELF );
                        float fDuration = Sp_CalcDuration( 30.0 );
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9009), oTarget);
                    }
                }
            }
        }
        break;
        // DJS-OEI 7/30/2004
        case FORCE_POWER_BEAST_CONFUSION:
        {
            float fDuration = 0.0f;
            int nResist = 0;
            int nSaves = 0;
            // If an active instance of this spell is already
            // in progress, drop through to Beast Trick. The spell
            // will still cost the full amount, though. This should
            // only happen if the player cued a bunch of Confusion
            // castings instead of waiting for Beast Trick to replace
            // it in the interface.
            if( GetGlobalNumber( "000_Beast_Conf_Active" ) == 0 ) {
                SWFP_HARMFUL = TRUE;
                SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
                if( GetPlotFlag( oTarget ) ) {
                    return;
                }
                if (GetRacialType(oTarget) == RACIAL_TYPE_DROID)
                {
                    return;
                }
                // Only works on beasts.
                if (GetSubRace(oTarget) != 2)
                {
                    return;
                }
                eLink1 = EffectFactionModifier( STANDARD_FACTION_FRIENDLY_1 );
                nResist = Sp_BlockingChecks(oTarget, eLink1, eInvalid, eInvalid);
                if(nResist == 0)
                {
                    nSaves = Sp_MySavingThrows(oTarget);
                    if(nSaves == 0)
                    {
                        // Remove any lower level or equal versions of this power.
                        Sp_RemoveRelatedPowers( oTarget, GetSpellId() );
                        // Do not apply the effects of this power if a more powerful
                        // version is already attached to the target.
                        if( !Sp_BetterRelatedPowerExists( oTarget, GetSpellId() ) ) {
                            // Flag this spell as having been cast once already.
                            SetGlobalNumber( "000_Beast_Conf_Active", 1 );
                            // If more than one casting is attempted, it will just
                            // drop through to Mind Trick.
                            fDuration = Sp_CalcDuration( 30.0 );
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                            break;
                        }
                    }
                }
                break;
            }
            else {
                // NO BREAK!!!
                // Drop through to Beast Trick.
            }
        }
        ///////////////////////////////////////////////////////////
        //
        // THERE IS NO BREAK HERE ON PURPOSE. CONFUSION CAN
        // DROP THROUGH TO TRICK IF IT IS CAST AGAIN DURING
        // THE DURATION OF A PREVIOUS CASTING.
        //
        ///////////////////////////////////////////////////////////
        // DJS-OEI 7/30/2004
        case FORCE_POWER_BEAST_TRICK:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            if( GetPlotFlag( oTarget ) ) {
                return;
            }
            if (GetRacialType(oTarget) == RACIAL_TYPE_DROID)
            {
                return;
            }
            // Only works on beasts.
            if (GetSubRace(oTarget) != 2)
            {
                return;
            }
            eLink1 = EffectMindTrick();
            int nResist = Sp_BlockingChecks(oTarget, eLink1, eInvalid, eInvalid);
            int nSaves;
            if(nResist == 0)
            {
                nSaves = Sp_MySavingThrows(oTarget);
                if(nSaves == 0)
                {
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oTarget, GetSpellId() );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oTarget, GetSpellId() ) ) {
                        // In addition to the effect, turn the target away
                        // from the caster.
                        FaceObjectAwayFromObject( oTarget, OBJECT_SELF );
                        float fDuration = Sp_CalcDuration( 30.0 );
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9009), oTarget);
                    }
                }
            }
        }
        break;
        // DJS-OEI 7/30/2004
        case FORCE_POWER_DROID_CONFUSION:
        {
            float fDuration = 0.0f;
            int nResist = 0;
            int nSaves = 0;
            // If an active instance of this spell is already
            // in progress, drop through to Droid Trick. The spell
            // will still cost the full amount, though. This should
            // only happen if the player cued a bunch of Confusion
            // castings instead of waiting for Droid Trick to replace
            // it in the interface.
            if( GetGlobalNumber( "000_Droid_Conf_Active" ) == 0 ) {
                SWFP_HARMFUL = TRUE;
                SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
                if( GetPlotFlag( oTarget ) ) {
                    return;
                }
                if (GetRacialType(oTarget) != RACIAL_TYPE_DROID)
                {
                    return;
                }
                eLink1 = EffectFactionModifier( STANDARD_FACTION_FRIENDLY_1 );
                ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_FORCE_WAVE), GetLocation(OBJECT_SELF));
//                effect eBeam = EffectBeam(2049, OBJECT_SELF, BODY_NODE_HAND);
//                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, 1.0);
                //int nResist = Sp_BlockingChecks(oTarget, eLink1, eInvalid, eInvalid);
                if(nResist == 0)
                {
                    int nDC = 5 + GetHitDice(OBJECT_SELF) + GetAbilityModifier( ABILITY_INTELLIGENCE );
                    nSaves = Sp_MySavingThrows(oTarget, nDC);
                    if(nSaves == 0)
                    {
                        // Remove any lower level or equal versions of this power.
                        Sp_RemoveRelatedPowers( oTarget, GetSpellId() );
                        // Do not apply the effects of this power if a more powerful
                        // version is already attached to the target.
                        if( !Sp_BetterRelatedPowerExists( oTarget, GetSpellId() ) ) {
                            // Flag this spell as having been cast once already.
                            SetGlobalNumber( "000_Droid_Conf_Active", 1 );
                            // If more than one casting is attempted, it will just
                            // drop through to Mind Trick.
                            fDuration = Sp_CalcDuration( 30.0 );
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                            break;
                        }
                    }
                }
                break;
            }
            else {
                // NO BREAK!!!
                // Drop through to Droid Trick.
            }
        }
        ///////////////////////////////////////////////////////////
        //
        // THERE IS NO BREAK HERE ON PURPOSE. CONFUSION CAN
        // DROP THROUGH TO TRICK IF IT IS CAST AGAIN DURING
        // THE DURATION OF A PREVIOUS CASTING.
        //
        ///////////////////////////////////////////////////////////
        // DJS-OEI 7/30/2004
        case FORCE_POWER_DROID_TRICK:
        {
            SWFP_HARMFUL = TRUE;
            SWFP_PRIVATE_SAVE_TYPE = SAVING_THROW_WILL;
            if( GetPlotFlag( oTarget ) ) {
                return;
            }
            if (GetRacialType(oTarget) != RACIAL_TYPE_DROID)
            {
                return;
            }
            eLink1 = EffectDroidScramble();
            ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_FORCE_WAVE), GetLocation(OBJECT_SELF));
//            effect eBeam = EffectBeam(2049, OBJECT_SELF, BODY_NODE_HAND);
//            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBeam, oTarget, 1.0);
            //int nResist = Sp_BlockingChecks(oTarget, eLink1, eInvalid, eInvalid);
            int nResist = 0;
            int nSaves;
            if(nResist == 0)
            {
                int nDC = 5 + GetHitDice(OBJECT_SELF) + GetAbilityModifier( ABILITY_INTELLIGENCE );
                nSaves = Sp_MySavingThrows(oTarget, nDC);
                if(nSaves == 0)
                {
                    // Remove any lower level or equal versions of this power.
                    Sp_RemoveRelatedPowers( oTarget, GetSpellId() );
                    // Do not apply the effects of this power if a more powerful
                    // version is already attached to the target.
                    if( !Sp_BetterRelatedPowerExists( oTarget, GetSpellId() ) ) {
                        // In addition to the effect, turn the target away
                        // from the caster.
                        FaceObjectAwayFromObject( oTarget, OBJECT_SELF );
                        float fDuration = Sp_CalcDuration( 30.0 );
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(9009), oTarget);
                    }
                }
            }
        }
        break;
        // DJS-OEI 8/15/2004
        case FORCE_POWER_BREATH_CONTROL:
        {
            SWFP_HARMFUL = FALSE;
            eLink1 = EffectImmunity(IMMUNITY_TYPE_POISON);
            eLink1 = SetEffectIcon(eLink1, 111);
            // Remove any lower level or equal versions of this power.
            Sp_RemoveRelatedPowers( oTarget, GetSpellId() );
            // Do not apply the effects of this power if a more powerful
            // version is already attached to the target.
            if( !Sp_BetterRelatedPowerExists( oTarget, GetSpellId() ) ) {
        // DJS-OEI 10/24/2004
        // Increased duration at QA's behest.
                //float fDuration = Sp_CalcDuration( 30.0 );
                float fDuration = Sp_CalcDuration( 240.0 );
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink1, oTarget, fDuration);
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(1015), oTarget, 3.0);
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(2064), oTarget, fDuration);
            }
        }
        break;
    }
    // DJS-OEI 7/20/2004
    // Form/Stance re-design.
    /*
    // DJS-OEI 3/29/2004
    // If the designated target was using the Regeneration III
    // Consular Form, they get 20% of the base cost of the power
    // in FP.
    if( GetSpellFormMask( GetSpellId() ) & FORM_MASK_REGENERATION ) {
        object oSpellTarget = GetSpellTargetObject();
        if( GetIsObjectValid( oSpellTarget ) ) {
            if( IsFormActive( oSpellTarget, FORM_CONSULAR_REGENERATION_III ) ) {
                int nCost = ( GetSpellBaseForcePointCost( GetSpellId() ) * 20 ) / 100;
                eLink1 = EffectHealForcePoints( nCost );
                ApplyEffectToObject( DURATION_TYPE_INSTANT, eLink1, oSpellTarget );
            }
        }
    }
    */
}
//::///////////////////////////////////////////////
//:: While Loop Effect Delivery
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Uses these values to deliver the effects in the
    loop.
    SWFP_PRIVATE_SAVE_TYPE;
    SWFP_PRIVATE_SAVE_VERSUS_TYPE;
    SWFP_DAMAGE;
    SWFP_DAMAGE_TYPE;
    SWFP_DAMAGE_VFX;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 2, 2002
//:://////////////////////////////////////////////
void Sp_ApplyEffects(int nBlocking, object oAnchor, float fSize, int nCounter, effect eLink1, float fDuration1, effect eLink2, float fDuration2, int nRacial = RACIAL_TYPE_ALL)
{
    int nCnt = 0;
    object oTarget;
    //By setting the counter to 1 you specify a single target.
    //By setting the counter to 1000, you specify all targets in a shape.
    //By setting the counter to another number you specify that many targets maximum.
    if(nCounter > 1)
    {
        oTarget = GetFirstObjectInShape(SWFP_SHAPE, fSize, GetLocation(oAnchor));
    }
    else if(nCounter == 1)
    {
        oTarget = oAnchor;
    }
    while(GetIsObjectValid(oTarget) && nCnt < nCounter)
    {
        if(nRacial == GetRacialType(oTarget) || nRacial == RACIAL_TYPE_ALL)
        {
            int nIdx = 0; // Index for the for loop link application.
            effect eUse;  // Current effect to use
            float fUse;   // Current duration to use
            int nDamage;  // The damage as set from SWFP_DAMAGE
            int bFizzle;  // Tracks whether the Fizzle has played on the caster yet or not.
            effect eDamage; // The damage effect which will be linked after the saves are done and checked with blocking.
            if((GetIsEnemy(oTarget) && SWFP_HARMFUL == TRUE) || (GetIsFriend(oTarget) && SWFP_HARMFUL == FALSE))
            {
                SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), SWFP_HARMFUL));
                //eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                int nResist = FALSE;
                int nSaves = -1;
                if(SWFP_HARMFUL == TRUE)
                {
                    nResist = Sp_BlockingChecks(oTarget, eLink1, eLink2, eDamage);
                }
                //By adding another index the number of links added to this function can increase.
                for(nIdx; nIdx <= 1; nIdx++)
                {
                    if(nIdx == 0)
                    {
                        eUse = eLink1;
                        fUse = fDuration1;
                    }
                    else
                    {
                        eUse = eLink2;
                        fUse = fDuration2;
                    }
                    if(nResist == FALSE)
                    {
                        //MODIFIED by Preston Watamaniuk March 23
                         //Moved the save call down to here from up above with the resist inorder to help
                         //feedback system not make useless save calls.
                        //MODIFIED by Preston Watamaniuk March 24
                         //Made the default value of nSave -1 so that I only do it once.
                        //MODIFIED by Preston Watamaniuk April 5
                         //Made sure to set nSaves to FALSE so that it would fall through the function.
                        if(SWFP_HARMFUL == TRUE && nSaves == -1)
                        {
                            nSaves = Sp_MySavingThrows(oTarget);
                        }
                        else
                        {
                            nSaves = FALSE;
                        }
                        if(nSaves == FALSE)
                        {
                            if(nIdx == 1 && SWFP_DAMAGE > 0)
                            //Damage effects are always linked to the eDamage effect which is kept seperate from
                            //all other eLink types coming in.
                            {
                                eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                                eDamage = EffectLinkEffects(eDamage, EffectVisualEffect(SWFP_DAMAGE_VFX));
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                            }
                            if(GetIsEffectValid(eUse))
                            {
                                Sp_ApplyForcePowerEffects(fUse, eUse, oTarget);
                            }
                        }
                        //If the blocking flag is true then do not apply any effects on a save.
                        else if(nSaves > 0 && nBlocking == FALSE)
                        {
                            if(nIdx == 1 && SWFP_DAMAGE > 0)
                            {
                                SWFP_DAMAGE /= 2;
                                eDamage = EffectDamage(SWFP_DAMAGE, SWFP_DAMAGE_TYPE);
                                eDamage = EffectLinkEffects(eDamage, EffectVisualEffect(SWFP_DAMAGE_VFX));
                                ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
                            }
                            if(GetIsEffectValid(eUse))
                            {
                                Sp_ApplyForcePowerEffects(fUse, eUse, oTarget);
                            }
                        }
                    }
                    if(nResist > 0 || (nSaves > 0 && nBlocking > 0))
                    {
                        if(bFizzle == FALSE)
                        {
                            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectForceFizzle(), OBJECT_SELF);
                            bFizzle = TRUE;
                        }
                    }
                }
                nCnt++;
            }
        }
        oTarget = GetNextObjectInShape(SWFP_SHAPE, fSize, GetLocation(oAnchor), FALSE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE);
    }
}
//::///////////////////////////////////////////////
//:: Remove Buff Bonuses
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Goes through and removes all of the bonuses
    from people in a 30m radius from Force Mind,
    Knight Mind, Mind Mastery and Battle Meditation
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 7, 2002
//:://////////////////////////////////////////////
void Sp_RemoveBuffSpell()
{
    object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF));
    while(GetIsObjectValid(oTarget))
    {
        if(GetFactionEqual(oTarget))
        {
            //Declare major variables
            int bValid = FALSE;
            effect eAOE;
            if(GetHasSpellEffect(FORCE_POWER_FORCE_MIND, oTarget) ||
               GetHasSpellEffect(FORCE_POWER_MIND_MASTERY, oTarget) ||
               GetHasSpellEffect(FORCE_POWER_KNIGHT_MIND, oTarget) ||
               GetHasSpellEffect(SPECIAL_ABILITY_BATTLE_MEDITATION, oTarget))
            {
                //Search through the valid effects on the target.
                eAOE = GetFirstEffect(oTarget);
                while (GetIsEffectValid(eAOE) && bValid == FALSE)
                {
                    //If the effect was created by the spell then remove it
                    if(GetEffectSpellId(eAOE) == FORCE_POWER_FORCE_MIND ||
                       GetEffectSpellId(eAOE) == FORCE_POWER_MIND_MASTERY ||
                       GetEffectSpellId(eAOE) == FORCE_POWER_KNIGHT_MIND ||
                       GetEffectSpellId(eAOE) == SPECIAL_ABILITY_BATTLE_MEDITATION)
                    {
                        RemoveEffect(oTarget, eAOE);
                    }
                    //Get next effect on the target
                    eAOE = GetNextEffect(oTarget);
                }
            }
        }
        oTarget = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF));
    }
}
//::///////////////////////////////////////////////
//:: Check for Appearance Type Turret
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks to see if the target is a Turret
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 10, 2003
//:://////////////////////////////////////////////
int SP_CheckAppearanceTurret(object oTarget, int nFeedback = FALSE)
{
    int nCheck = FALSE;
    SP_MyPostString("Appearance = " + IntToString(GetAppearanceType(oTarget)));
    // DJS-OEI 10/24/2004
    // Added some new Turret types.
    if(GetAppearanceType(oTarget) == 182 ||
       GetAppearanceType(oTarget) == 183 ||
       GetAppearanceType(oTarget) == 640 ||
       GetAppearanceType(oTarget) == 657 )
    {
        if(nFeedback == TRUE)
        {
            DisplayFeedBackText(oTarget, 1);
        }
        nCheck = TRUE;
    }
    return nCheck;
}
//::///////////////////////////////////////////////
//:: Check Droid Appearance Type
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks to see if the target is a Mark 1, 2, 4
    or Spyder Droid
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 10, 2003
//:://////////////////////////////////////////////
int SP_CheckAppearanceGeoDroid(object oTarget)
{
    int nCheck = FALSE;
    if(GetAppearanceType(oTarget) == 59 ||
       GetAppearanceType(oTarget) == 60 ||
       GetAppearanceType(oTarget) == 61 ||
       GetAppearanceType(oTarget) == 65)
    {
        nCheck = TRUE;
    }
    return nCheck;
}
//::///////////////////////////////////////////////
//:: Check Droid Appearance Type and and Shields
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks to see if the target is a Mark 1, 2, 4
    or Spyder Droid and has a shield activated
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 10, 2003
//:://////////////////////////////////////////////
int SP_CheckAppearanceGeoDroidShields(object oTarget, int nFeedback = FALSE)
{
    int nCheck = FALSE;
    if(GetAppearanceType(oTarget) == 59 ||
       GetAppearanceType(oTarget) == 60 ||
       GetAppearanceType(oTarget) == 61 ||
       GetAppearanceType(oTarget) == 65)
    {
        if(GetHasSpellEffect(110, oTarget) ||
           GetHasSpellEffect(111, oTarget) ||
           GetHasSpellEffect(112, oTarget) ||
           GetHasSpellEffect(113, oTarget) ||
           GetHasSpellEffect(114, oTarget) ||
           GetHasSpellEffect(115, oTarget))
         {
            if(nFeedback == TRUE)
            {
                DisplayFeedBackText(oTarget, 1);
            }
            nCheck = TRUE;
         }
    }
    return nCheck;
}
//::///////////////////////////////////////////////
//:: Force Push Viability
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns TRUE if the target can be force pushed
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2003
//:://////////////////////////////////////////////
int SP_CheckForcePushViability(object oTarget, int Whirlwind)
{
    int bValid = FALSE;
    SP_MyPrintString("Push Check Start");
    if(GetCreatureSize(oTarget) != CREATURE_SIZE_LARGE &&
       GetCreatureSize(oTarget) != CREATURE_SIZE_HUGE)
    {
        SP_MyPrintString("Size is OK");
        if(SP_CheckAppearanceTurret(oTarget) == FALSE)
        {
            SP_MyPrintString("I am not a turret");
            if((Whirlwind == TRUE && SP_CheckAppearanceGeoDroidShields(oTarget) == FALSE) ||
                Whirlwind == FALSE)
            {
                SP_MyPrintString("I am whirlwind without droid shiled or not whirlwind");
                if(GetCreatureMovmentType(oTarget) != MOVEMENT_SPEED_IMMOBILE)
                {
                    SP_MyPrintString("Returning Push True");
                    bValid = TRUE;
                }
            }
        }
    }
    if(bValid == FALSE)
    {
        DisplayFeedBackText(oTarget, 1);
    }
    return bValid;
}
void SP_MyPrintString(string sString)
{
    if(!ShipBuild())
    {
        sString = "SPELL GENERIC DEBUG STRING: " + sString;
        PrintString(sString);
    }
}
void SP_MyPostString(string sString, int n1 = 5, int n2 = 10, float fTime = 4.0)
{
    sString = "DEBUG: " + sString;
    AurPostString(sString,10,10,3.0);
}
void Sp_RemoveRelatedPowersInRadius( int nPowerID, float nRadius ) {
    // DJS-OEI 12/10/2003
    // This function makes use of the Sp_RemoveRelatedPowers()
    // function to allow removal of lesser related powers on multiple
    // targets in a radius. These targets must be of the same
    // faction as the caster (OBJECT_SELF). This may need to be
    // changed if/when new force powers are created that require
    // ranged removal versus enemies.
    object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, nRadius, GetLocation(OBJECT_SELF));
    while(GetIsObjectValid(oTarget))
    {
        if(GetFactionEqual(oTarget))
        {
            Sp_RemoveRelatedPowers( oTarget, nPowerID );
        }
        oTarget = GetNextObjectInShape(SHAPE_SPHERE, nRadius, GetLocation(OBJECT_SELF));
    }
}
void Sp_RemoveRelatedPowers( object oTarget, int nPowerID )
{
    // DJS-OEI 12/9/2003
    // Given a Force Power ID, remove all equal and
    // lesser Force Powers that are part of the same
    // Force Power tree from the target object.
    int nRelatedPowerID1 = -1;
    int nRelatedPowerID2 = -1;
    int nRelatedPowerID3 = -1;
    int nRelatedPowerID4 = -1;
    int nRelatedPowerID5 = -1;
    int nRelatedPowerID6 = -1;
    switch ( nPowerID )
    {
        // Slow/Affliction/Plague tree
        case FORCE_POWER_SLOW:
            // Remove all other Slow Force Power instances.
            nRelatedPowerID1 = FORCE_POWER_SLOW;
            break;
        case FORCE_POWER_AFFLICTION:
            // Remove all Slow Force Power and Affliction
            // Force Power instances.
            nRelatedPowerID1 = FORCE_POWER_SLOW;
            nRelatedPowerID2 = FORCE_POWER_AFFLICTION;
            break;
        case FORCE_POWER_PLAGUE:
            // Remove all Slow Force Power, Affliction
            // Force Power, and Plague Force Power instances.
            nRelatedPowerID1 = FORCE_POWER_SLOW;
            nRelatedPowerID2 = FORCE_POWER_AFFLICTION;
            nRelatedPowerID3 = FORCE_POWER_PLAGUE;
            break;
        // Force Aura/Force Shield/Force Armor tree
        case FORCE_POWER_FORCE_AURA:
            // Remove all other Force Aura instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_AURA;
            break;
        case FORCE_POWER_FORCE_SHIELD:
            // Remove all Force Aura and Force Shield instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_AURA;
            nRelatedPowerID2 = FORCE_POWER_FORCE_SHIELD;
            break;
        case FORCE_POWER_FORCE_ARMOR:
            // Remove all Force Aura, Force Shield,
            // and Force Armor instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_AURA;
            nRelatedPowerID2 = FORCE_POWER_FORCE_SHIELD;
            nRelatedPowerID3 = FORCE_POWER_FORCE_ARMOR;
            break;
        // Resist Force/Force Immunity tree
        case FORCE_POWER_RESIST_FORCE:
            // Remove all Resist Force instances.
            nRelatedPowerID1 = FORCE_POWER_RESIST_FORCE;
            break;
        case FORCE_POWER_FORCE_IMMUNITY:
            // Remove all Resist Force and Force Immunity instances.
            nRelatedPowerID1 = FORCE_POWER_RESIST_FORCE;
            nRelatedPowerID2 = FORCE_POWER_FORCE_IMMUNITY;
            break;
        // Force Valor/Knight Valor/Master Valor tree
        case FORCE_POWER_FORCE_MIND:
            // Remove all other Force Valor instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_MIND;
            break;
        case FORCE_POWER_KNIGHT_MIND:
            // Remove all Force Valor and Knight Valor instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_MIND;
            nRelatedPowerID2 = FORCE_POWER_KNIGHT_MIND;
            break;
        case FORCE_POWER_MIND_MASTERY:
            // Remove all Force Valor, Knight Valor,
            // and Master Valor instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_MIND;
            nRelatedPowerID2 = FORCE_POWER_KNIGHT_MIND;
            nRelatedPowerID3 = FORCE_POWER_MIND_MASTERY;
            break;
        // Energy Resistance/Improved Energy Resistance/Master Energy Resistance tree
        case FORCE_POWER_RESIST_POISON_DISEASE_SONIC:
            // Remove all other Energy Resistance instances.
            nRelatedPowerID1 = FORCE_POWER_RESIST_POISON_DISEASE_SONIC;
            break;
        case FORCE_POWER_RESIST_COLD_HEAT_ENERGY:
            // Remove all Energy Resistance and Improved
            // Energy Resistance instances.
            nRelatedPowerID1 = FORCE_POWER_RESIST_POISON_DISEASE_SONIC;
            nRelatedPowerID2 = FORCE_POWER_RESIST_COLD_HEAT_ENERGY;
            break;
        case FORCE_POWER_MASTER_ENERGY_RESISTANCE:
            // Remove all Energy Resistance, Improved Energy Resistance,
            // and Master Energy Resistance instances.
            nRelatedPowerID1 = FORCE_POWER_RESIST_POISON_DISEASE_SONIC;
            nRelatedPowerID2 = FORCE_POWER_RESIST_COLD_HEAT_ENERGY;
            nRelatedPowerID3 = FORCE_POWER_MASTER_ENERGY_RESISTANCE;
            break;
        // Stun/Stasis/Stasis Field tree
        case FORCE_POWER_STUN:
            // Remove all other Stun instances.
            nRelatedPowerID1 = FORCE_POWER_STUN;
            break;
        case FORCE_POWER_HOLD:
            // Remove all Stun and Stasis instances.
            nRelatedPowerID1 = FORCE_POWER_STUN;
            nRelatedPowerID2 = FORCE_POWER_HOLD;
            break;
        case FORCE_POWER_SLEEP:
            // Remove all Stun, Stasis, and Stasis Field instances.
            nRelatedPowerID1 = FORCE_POWER_STUN;
            nRelatedPowerID2 = FORCE_POWER_HOLD;
            nRelatedPowerID3 = FORCE_POWER_SLEEP;
            break;
        // Burst of Speed/Knight Speed/Master Speed tree
        case FORCE_POWER_SPEED_BURST:
            // Remove all other Burst of Speed instances.
            nRelatedPowerID1 = FORCE_POWER_SPEED_BURST;
            break;
        case FORCE_POWER_KNIGHT_SPEED:
            // Remove all Burst of Speed and Knight Speed instances.
            nRelatedPowerID1 = FORCE_POWER_SPEED_BURST;
            nRelatedPowerID2 = FORCE_POWER_KNIGHT_SPEED;
            break;
        case FORCE_POWER_SPEED_MASTERY:
            // Remove all Burst of Speed, Knight Speed, and
            // Master Speed instances.
            nRelatedPowerID1 = FORCE_POWER_SPEED_BURST;
            nRelatedPowerID2 = FORCE_POWER_KNIGHT_SPEED;
            nRelatedPowerID3 = FORCE_POWER_SPEED_MASTERY;
            break;
        // Force Barrier/Improved Barrier/Master Barrier tree
        case FORCE_POWER_FORCE_BARRIER:
            // Remove all other Force Barrier instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_BARRIER;
            break;
        case FORCE_POWER_IMPROVED_FORCE_BARRIER:
            // Remove all Force Barrier and Improved
            // Force Barrier instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_BARRIER;
            nRelatedPowerID2 = FORCE_POWER_IMPROVED_FORCE_BARRIER;
            break;
        case FORCE_POWER_MASTER_FORCE_BARRIER:
            // Remove all Force Barrier, Improved Force
            // Barrier, and Master Barrier instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_BARRIER;
            nRelatedPowerID2 = FORCE_POWER_IMPROVED_FORCE_BARRIER;
            nRelatedPowerID3 = FORCE_POWER_MASTER_FORCE_BARRIER;
            break;
        // Battle Meditation PC/Improved Battle Meditation PC/Master Battle Meditation PC tree
        case FORCE_POWER_BATTLE_MEDITATION_PC:
            // Remove all other Battle Meditation PC instances.
            nRelatedPowerID1 = FORCE_POWER_BATTLE_MEDITATION_PC;
            break;
        case FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC:
            // Remove all Battle Meditation PC and Improved
            // Battle Meditation PC instances.
            nRelatedPowerID1 = FORCE_POWER_BATTLE_MEDITATION_PC;
            nRelatedPowerID2 = FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC;
            break;
        case FORCE_POWER_MASTER_BATTLE_MEDITATION_PC:
            // Remove all Battle Meditation PC, Improved Battle
            // Meditation PC, and Master Battle Meditation PC instances.
            nRelatedPowerID1 = FORCE_POWER_BATTLE_MEDITATION_PC;
            nRelatedPowerID2 = FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC;
            nRelatedPowerID3 = FORCE_POWER_MASTER_BATTLE_MEDITATION_PC;
            break;
        // Battle Meditation Enemy/Improved Battle Meditation Enemy/Master Battle Meditation Enemy tree
        case FORCE_POWER_BAT_MED_ENEMY:
            // Remove all other Battle Meditation Enemy instances.
            nRelatedPowerID1 = FORCE_POWER_BAT_MED_ENEMY;
            break;
        case FORCE_POWER_IMP_BAT_MED_ENEMY:
            // Remove all Battle Meditation Enemy and Improved
            // Battle Meditation Enemy instances.
            nRelatedPowerID1 = FORCE_POWER_BAT_MED_ENEMY;
            nRelatedPowerID2 = FORCE_POWER_IMP_BAT_MED_ENEMY;
            break;
        case FORCE_POWER_MAS_BAT_MED_ENEMY:
            // Remove all Battle Meditation Enemy, Improved Battle
            // Meditation Enemy, and Master Battle Meditation Enemy instances.
            nRelatedPowerID1 = FORCE_POWER_BAT_MED_ENEMY;
            nRelatedPowerID2 = FORCE_POWER_IMP_BAT_MED_ENEMY;
            nRelatedPowerID3 = FORCE_POWER_MAS_BAT_MED_ENEMY;
            break;
        // Crush Opposition Tree
        case FORCE_POWER_CRUSH_OPPOSITION_I:
            // Remove all other Crush Opposition I instances.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_I;
            break;
        case FORCE_POWER_CRUSH_OPPOSITION_II:
            // Remove all other Crush Opposition I/II instances.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_I;
            nRelatedPowerID2 = FORCE_POWER_CRUSH_OPPOSITION_II;
            break;
        case FORCE_POWER_CRUSH_OPPOSITION_III:
            // Remove all other Crush Opposition I/II/III instances.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_I;
            nRelatedPowerID2 = FORCE_POWER_CRUSH_OPPOSITION_II;
            nRelatedPowerID3 = FORCE_POWER_CRUSH_OPPOSITION_III;
            break;
        case FORCE_POWER_CRUSH_OPPOSITION_IV:
            // Remove all other Crush Opposition I/II/III/IV instances.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_I;
            nRelatedPowerID2 = FORCE_POWER_CRUSH_OPPOSITION_II;
            nRelatedPowerID3 = FORCE_POWER_CRUSH_OPPOSITION_III;
            nRelatedPowerID4 = FORCE_POWER_CRUSH_OPPOSITION_IV;
            break;
        case FORCE_POWER_CRUSH_OPPOSITION_V:
            // Remove all other Crush Opposition I/II/III/IV/V instances.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_I;
            nRelatedPowerID2 = FORCE_POWER_CRUSH_OPPOSITION_II;
            nRelatedPowerID3 = FORCE_POWER_CRUSH_OPPOSITION_III;
            nRelatedPowerID4 = FORCE_POWER_CRUSH_OPPOSITION_IV;
            nRelatedPowerID5 = FORCE_POWER_CRUSH_OPPOSITION_V;
            break;
        case FORCE_POWER_CRUSH_OPPOSITION_VI:
            // Remove all other Crush Opposition I/II/III/IV/V/VI instances.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_I;
            nRelatedPowerID2 = FORCE_POWER_CRUSH_OPPOSITION_II;
            nRelatedPowerID3 = FORCE_POWER_CRUSH_OPPOSITION_III;
            nRelatedPowerID4 = FORCE_POWER_CRUSH_OPPOSITION_IV;
            nRelatedPowerID5 = FORCE_POWER_CRUSH_OPPOSITION_V;
            nRelatedPowerID6 = FORCE_POWER_CRUSH_OPPOSITION_VI;
            break;
        // DJS-OEI 12/15/2003
        // Force Body Tree
        case FORCE_POWER_FORCE_BODY:
            // Remove all other Force Body instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_BODY;
            break;
        case FORCE_POWER_IMPROVED_FORCE_BODY:
            // Remove all other Force Body and Improved Force
            // Body instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_BODY;
            nRelatedPowerID2 = FORCE_POWER_IMPROVED_FORCE_BODY;
            break;
        case FORCE_POWER_MASTER_FORCE_BODY:
            // Remove all other Force Body, Improved Force Body
            // and Master Force Body instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_BODY;
            nRelatedPowerID2 = FORCE_POWER_IMPROVED_FORCE_BODY;
            nRelatedPowerID3 = FORCE_POWER_MASTER_FORCE_BODY;
            break;
        // DJS-OEI 12/31/2003
        // Force Scream Tree
        case FORCE_POWER_FORCE_SCREAM:
            // Remove all other Force Scream instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_SCREAM;
            break;
        case FORCE_POWER_IMPROVED_FORCE_SCREAM:
            // Remove all other Force Scream and Improved Force
            // Scream instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_SCREAM;
            nRelatedPowerID2 = FORCE_POWER_IMPROVED_FORCE_SCREAM;
            break;
        case FORCE_POWER_MASTER_FORCE_SCREAM:
            // Remove all other Force Scream, Improved Force Scream
            // and Master Force Scream instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_SCREAM;
            nRelatedPowerID2 = FORCE_POWER_IMPROVED_FORCE_SCREAM;
            nRelatedPowerID3 = FORCE_POWER_MASTER_FORCE_SCREAM;
            break;
        // DJS-OEI 1/2/2004
        // Fury Tree
        case FORCE_POWER_FURY:
            // Remove all other Fury instances.
            nRelatedPowerID1 = FORCE_POWER_FURY;
            break;
        case FORCE_POWER_IMPROVED_FURY:
            // Remove all other Fury and Improved Fury
            // instances.
            nRelatedPowerID1 = FORCE_POWER_FURY;
            nRelatedPowerID2 = FORCE_POWER_IMPROVED_FURY;
            break;
        case FORCE_POWER_MASTER_FURY:
            // Remove all other Fury, Improved Fury
            // and Master Fury instances.
            nRelatedPowerID1 = FORCE_POWER_FURY;
            nRelatedPowerID2 = FORCE_POWER_IMPROVED_FURY;
            nRelatedPowerID3 = FORCE_POWER_MASTER_FURY;
            break;
        // DJS-OEI 8/20/2004
        case FORCE_POWER_WOOKIEE_RAGE_I:
            // Remove all other Rage instances.
            nRelatedPowerID1 = FORCE_POWER_WOOKIEE_RAGE_I;
            break;
        case FORCE_POWER_WOOKIEE_RAGE_II:
            // Remove all other Rage and Rage II
            // instances.
            nRelatedPowerID1 = FORCE_POWER_WOOKIEE_RAGE_I;
            nRelatedPowerID2 = FORCE_POWER_WOOKIEE_RAGE_II;
            break;
        case FORCE_POWER_WOOKIEE_RAGE_III:
            // Remove all other Rage, Rage II, and Rage III.
            nRelatedPowerID1 = FORCE_POWER_WOOKIEE_RAGE_I;
            nRelatedPowerID2 = FORCE_POWER_WOOKIEE_RAGE_II;
            nRelatedPowerID3 = FORCE_POWER_WOOKIEE_RAGE_III;
            break;
        // Inspire Followers Tree
        case FORCE_POWER_INSPIRE_FOLLOWERS_I:
            // Remove all other Inspire Followers I instances.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_I;
            break;
        case FORCE_POWER_INSPIRE_FOLLOWERS_II:
            // Remove all other Inspire Followers I/II instances.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_I;
            nRelatedPowerID2 = FORCE_POWER_INSPIRE_FOLLOWERS_II;
            break;
        case FORCE_POWER_INSPIRE_FOLLOWERS_III:
            // Remove all other Inspire Followers I/II/III instances.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_I;
            nRelatedPowerID2 = FORCE_POWER_INSPIRE_FOLLOWERS_II;
            nRelatedPowerID3 = FORCE_POWER_INSPIRE_FOLLOWERS_III;
            break;
        case FORCE_POWER_INSPIRE_FOLLOWERS_IV:
            // Remove all other Inspire Followers I/II/III/IV instances.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_I;
            nRelatedPowerID2 = FORCE_POWER_INSPIRE_FOLLOWERS_II;
            nRelatedPowerID3 = FORCE_POWER_INSPIRE_FOLLOWERS_III;
            nRelatedPowerID4 = FORCE_POWER_INSPIRE_FOLLOWERS_IV;
            break;
        case FORCE_POWER_INSPIRE_FOLLOWERS_V:
            // Remove all other Inspire Followers I/II/III/IV/V instances.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_I;
            nRelatedPowerID2 = FORCE_POWER_INSPIRE_FOLLOWERS_II;
            nRelatedPowerID3 = FORCE_POWER_INSPIRE_FOLLOWERS_III;
            nRelatedPowerID4 = FORCE_POWER_INSPIRE_FOLLOWERS_IV;
            nRelatedPowerID5 = FORCE_POWER_INSPIRE_FOLLOWERS_V;
            break;
        case FORCE_POWER_INSPIRE_FOLLOWERS_VI:
            // Remove all other Inspire Followers I/II/III/IV/V/VI instances.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_I;
            nRelatedPowerID2 = FORCE_POWER_INSPIRE_FOLLOWERS_II;
            nRelatedPowerID3 = FORCE_POWER_INSPIRE_FOLLOWERS_III;
            nRelatedPowerID4 = FORCE_POWER_INSPIRE_FOLLOWERS_IV;
            nRelatedPowerID5 = FORCE_POWER_INSPIRE_FOLLOWERS_V;
            nRelatedPowerID6 = FORCE_POWER_INSPIRE_FOLLOWERS_VI;
            break;
        case FORCE_POWER_MIND_TRICK:
            // Remove all other Mind Trick instances.
            nRelatedPowerID1 = FORCE_POWER_MIND_TRICK;
            break;
        case FORCE_POWER_CONFUSION:
            // Remove all other Mind Trick and Force Confusion
            // instance.
            nRelatedPowerID1 = FORCE_POWER_MIND_TRICK;
            nRelatedPowerID2 = FORCE_POWER_CONFUSION;
            break;
        case FORCE_POWER_BEAST_TRICK:
            // Remove all other Beast Trick instances.
            nRelatedPowerID1 = FORCE_POWER_BEAST_TRICK;
            break;
        case FORCE_POWER_BEAST_CONFUSION:
            // Remove all other Beast Trick and Beast Confusion
            // instance.
            nRelatedPowerID1 = FORCE_POWER_BEAST_TRICK;
            nRelatedPowerID2 = FORCE_POWER_BEAST_CONFUSION;
            break;
        case FORCE_POWER_DROID_TRICK:
            // Remove all other Droid Trick instances.
            nRelatedPowerID1 = FORCE_POWER_DROID_TRICK;
            break;
        case FORCE_POWER_DROID_CONFUSION:
            // Remove all other Droid Trick and Droid Confusion
            // instance.
            nRelatedPowerID1 = FORCE_POWER_DROID_TRICK;
            nRelatedPowerID2 = FORCE_POWER_DROID_CONFUSION;
            break;
        case FORCE_POWER_FORCE_ENLIGHTENMENT:
            // Remove all other Force Enlightenment instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_ENLIGHTENMENT;
            break;
        case FORCE_POWER_FORCE_SIGHT:
            // Remove all other Force Sight instances.
            nRelatedPowerID1 = FORCE_POWER_FORCE_SIGHT;
            break;
        case FORCE_POWER_BREATH_CONTROL:
            // Remove all other Breath Control instances.
            nRelatedPowerID1 = FORCE_POWER_BREATH_CONTROL;
            break;
        case 131:
            // Remove all other Sonic Howl instances.
            nRelatedPowerID1 = 131;
        default:
            return;
    }
    // Check to see if the target has any of the Force Power
    // effects we want to delete.
    effect eRelatedEffect;
    if( GetHasSpellEffect(nRelatedPowerID1, oTarget) ||
        GetHasSpellEffect(nRelatedPowerID2, oTarget) ||
        GetHasSpellEffect(nRelatedPowerID3, oTarget) ||
        GetHasSpellEffect(nRelatedPowerID4, oTarget) ||
        GetHasSpellEffect(nRelatedPowerID5, oTarget) ||
        GetHasSpellEffect(nRelatedPowerID6, oTarget) )
    {
        // Search through the valid effects on the target
        // for those that match the requested related powers.
        eRelatedEffect = GetFirstEffect(oTarget);
        while (GetIsEffectValid(eRelatedEffect))
        {
            // If the effect was created by one of the related Force Powers
            // we want to delete, remove the effect.
            if( GetEffectSpellId(eRelatedEffect) == nRelatedPowerID1 ||
                GetEffectSpellId(eRelatedEffect) == nRelatedPowerID2 ||
                GetEffectSpellId(eRelatedEffect) == nRelatedPowerID3 ||
                GetEffectSpellId(eRelatedEffect) == nRelatedPowerID4 ||
                GetEffectSpellId(eRelatedEffect) == nRelatedPowerID5 ||
                GetEffectSpellId(eRelatedEffect) == nRelatedPowerID6 )
            {
                RemoveEffect(oTarget, eRelatedEffect);
            }
            //Get next effect on the target
            eRelatedEffect = GetNextEffect(oTarget);
        }
    }
}
int Sp_BetterRelatedPowerExists( object oTarget, int nPowerID )
{
    // DJS-OEI 12/9/2003
    // Given a Force Power ID, this function will return
    // whether or not a more powerful version of the power
    // from the same Force Power tree is already applied to
    // the target object.
    int bBetterExists = 0;
    int nRelatedPowerID1 = -1;
    int nRelatedPowerID2 = -1;
    int nRelatedPowerID3 = -1;
    int nRelatedPowerID4 = -1;
    int nRelatedPowerID5 = -1;
    int nRelatedPowerID6 = -1;
    switch ( nPowerID )
    {
        // Slow/Affliction/Plague tree
        case FORCE_POWER_SLOW:
            // Affliction and Plague are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_AFFLICTION;
            nRelatedPowerID2 = FORCE_POWER_PLAGUE;
            break;
        case FORCE_POWER_AFFLICTION:
            // Plague is more powerful and part of the
            // same tree.
            nRelatedPowerID1 = FORCE_POWER_PLAGUE;
            break;
        // Force Aura/Force Shield/Force Armor tree
        case FORCE_POWER_FORCE_AURA:
            // Force Shield and Force Armor are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_FORCE_SHIELD;
            nRelatedPowerID2 = FORCE_POWER_FORCE_ARMOR;
            break;
        case FORCE_POWER_FORCE_SHIELD:
            // Force Armor is more powerful and part of the
            // same tree.
            nRelatedPowerID1 = FORCE_POWER_FORCE_ARMOR;
            break;
        // Resist Force/Force Immunity tree
        case FORCE_POWER_RESIST_FORCE:
            // Force Immunity is more powerful and part of the
            // same tree.
            nRelatedPowerID1 = FORCE_POWER_FORCE_IMMUNITY;
            break;
        // Force Valor/Knight Valor/Master Valor tree
        case FORCE_POWER_FORCE_MIND:
            // Knight Valor and Master Valor are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_KNIGHT_MIND;
            nRelatedPowerID2 = FORCE_POWER_MIND_MASTERY;
            break;
        case FORCE_POWER_KNIGHT_MIND:
            // Master Valor is more powerful and part of the
            // same tree.
            nRelatedPowerID1 = FORCE_POWER_MIND_MASTERY;
            break;
        // Energy Resistance/Improved Energy Resistance/Master Energy Resistance tree
        case FORCE_POWER_RESIST_POISON_DISEASE_SONIC:
            // Improved Energy Resistance and Master Energy Resistance are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_RESIST_COLD_HEAT_ENERGY;
            nRelatedPowerID2 = FORCE_POWER_MASTER_ENERGY_RESISTANCE;
            break;
        case FORCE_POWER_RESIST_COLD_HEAT_ENERGY:
            // Master Energy Resistance is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_MASTER_ENERGY_RESISTANCE;
            break;
        // Stun/Stasis/Stasis Field tree
        case FORCE_POWER_STUN:
            // Stasis and Stasis are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_HOLD;
            nRelatedPowerID2 = FORCE_POWER_SLEEP;
            break;
        case FORCE_POWER_HOLD:
            // Stasis Field is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_SLEEP;
            break;
        // Burst of Speed/Knight Speed/Master Speed tree
        case FORCE_POWER_SPEED_BURST:
            // Knight Speed and Master Speed are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_KNIGHT_SPEED;
            nRelatedPowerID2 = FORCE_POWER_SPEED_MASTERY;
            break;
        case FORCE_POWER_KNIGHT_SPEED:
            // Master Speed is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_SPEED_MASTERY;
            break;
        // Force Barrier/Improved Barrier/Master Barrier tree
        case FORCE_POWER_FORCE_BARRIER:
            // Improved Barrier and Master Barrier are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_IMPROVED_FORCE_BARRIER;
            nRelatedPowerID2 = FORCE_POWER_MASTER_FORCE_BARRIER;
            break;
        case FORCE_POWER_IMPROVED_FORCE_BARRIER:
            // Master Barrier is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_MASTER_FORCE_BARRIER;
            break;
        // Battle Meditation PC/Improved Battle Meditation PC/Master Battle Meditation PC tree
        case FORCE_POWER_BATTLE_MEDITATION_PC:
            // Improved Battle Meditation PC and Master Battle Meditation PC are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC;
            nRelatedPowerID2 = FORCE_POWER_MASTER_BATTLE_MEDITATION_PC;
            break;
        case FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC:
            // Master Battle Meditation PC is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_MASTER_BATTLE_MEDITATION_PC;
            break;
        // Battle Meditation Enemy/Improved Battle Meditation EnemyMaster Battle Meditation Enemy tree
        case FORCE_POWER_BAT_MED_ENEMY:
            // Improved Battle Meditation Enemy and Master Battle Meditation Enemy are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_IMP_BAT_MED_ENEMY;
            nRelatedPowerID2 = FORCE_POWER_MAS_BAT_MED_ENEMY;
            break;
        case FORCE_POWER_IMP_BAT_MED_ENEMY:
            // Master Battle Meditation Enemy is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_MAS_BAT_MED_ENEMY;
            break;
        // Crush Opposition Tree
        case FORCE_POWER_CRUSH_OPPOSITION_I:
            // Crush Opposition II/III/IV/V/VI are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_II;
            nRelatedPowerID2 = FORCE_POWER_CRUSH_OPPOSITION_III;
            nRelatedPowerID3 = FORCE_POWER_CRUSH_OPPOSITION_IV;
            nRelatedPowerID4 = FORCE_POWER_CRUSH_OPPOSITION_V;
            nRelatedPowerID5 = FORCE_POWER_CRUSH_OPPOSITION_VI;
            break;
        case FORCE_POWER_CRUSH_OPPOSITION_II:
            // Crush Opposition III/IV/V/VI are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_III;
            nRelatedPowerID2 = FORCE_POWER_CRUSH_OPPOSITION_IV;
            nRelatedPowerID3 = FORCE_POWER_CRUSH_OPPOSITION_V;
            nRelatedPowerID4 = FORCE_POWER_CRUSH_OPPOSITION_VI;
            break;
        case FORCE_POWER_CRUSH_OPPOSITION_III:
            // Crush Opposition IV/V/VI are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_IV;
            nRelatedPowerID2 = FORCE_POWER_CRUSH_OPPOSITION_V;
            nRelatedPowerID3 = FORCE_POWER_CRUSH_OPPOSITION_VI;
            break;
        case FORCE_POWER_CRUSH_OPPOSITION_IV:
            // Crush Opposition V/VI are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_V;
            nRelatedPowerID2 = FORCE_POWER_CRUSH_OPPOSITION_VI;
            break;
        case FORCE_POWER_CRUSH_OPPOSITION_V:
            // Crush Opposition VI is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_CRUSH_OPPOSITION_VI;
            break;
        // Force Body/Improved Body/Master Body tree
        case FORCE_POWER_FORCE_BODY:
            // Improved Body and Master Body are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_IMPROVED_FORCE_BODY;
            nRelatedPowerID2 = FORCE_POWER_MASTER_FORCE_BODY;
            break;
        case FORCE_POWER_IMPROVED_FORCE_BODY:
            // Master Body is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_MASTER_FORCE_BODY;
            break;
        // DJS-OEI 12/31/2003
        // Force Scream/Improved Force Scream/Master Force Scream
        case FORCE_POWER_FORCE_SCREAM:
            // Improved Scream and Master Scream are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_IMPROVED_FORCE_SCREAM;
            nRelatedPowerID2 = FORCE_POWER_MASTER_FORCE_SCREAM;
            break;
        case FORCE_POWER_IMPROVED_FORCE_SCREAM:
            // Master Scream is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_MASTER_FORCE_SCREAM;
            break;
        // DJS-OEI 1/2/2004
        // Fury Tree
        case FORCE_POWER_FURY:
            // Improved Fury and Scream Body are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_IMPROVED_FURY;
            nRelatedPowerID2 = FORCE_POWER_MASTER_FURY;
            break;
        case FORCE_POWER_IMPROVED_FURY:
            // Master Fury is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_MASTER_FURY;
            break;
        // DJS-OEI 8/20/2004
        // Rage Tree
        case FORCE_POWER_WOOKIEE_RAGE_I:
            // Rage II and Rage III are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_WOOKIEE_RAGE_II;
            nRelatedPowerID2 = FORCE_POWER_WOOKIEE_RAGE_III;
            break;
        case FORCE_POWER_WOOKIEE_RAGE_II:
            // Rage III is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_WOOKIEE_RAGE_III;
            break;
        // Inspire Followers Tree
        case FORCE_POWER_INSPIRE_FOLLOWERS_I:
            // Inspire Followers II/III/IV/V/VI are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_II;
            nRelatedPowerID2 = FORCE_POWER_INSPIRE_FOLLOWERS_III;
            nRelatedPowerID3 = FORCE_POWER_INSPIRE_FOLLOWERS_IV;
            nRelatedPowerID4 = FORCE_POWER_INSPIRE_FOLLOWERS_V;
            nRelatedPowerID5 = FORCE_POWER_INSPIRE_FOLLOWERS_VI;
            break;
        case FORCE_POWER_INSPIRE_FOLLOWERS_II:
            // Inspire Followers III/IV/V/VI are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_III;
            nRelatedPowerID2 = FORCE_POWER_INSPIRE_FOLLOWERS_IV;
            nRelatedPowerID3 = FORCE_POWER_INSPIRE_FOLLOWERS_V;
            nRelatedPowerID4 = FORCE_POWER_INSPIRE_FOLLOWERS_VI;
            break;
        case FORCE_POWER_INSPIRE_FOLLOWERS_III:
            // Inspire Followers IV/V/VI are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_IV;
            nRelatedPowerID2 = FORCE_POWER_INSPIRE_FOLLOWERS_V;
            nRelatedPowerID3 = FORCE_POWER_INSPIRE_FOLLOWERS_VI;
            break;
        case FORCE_POWER_INSPIRE_FOLLOWERS_IV:
            // Inspire Followers V/VI are more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_V;
            nRelatedPowerID2 = FORCE_POWER_INSPIRE_FOLLOWERS_VI;
            break;
        case FORCE_POWER_INSPIRE_FOLLOWERS_V:
            // Inspire Followers VI is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_INSPIRE_FOLLOWERS_VI;
            break;
        case FORCE_POWER_MIND_TRICK:
            // Force Confusion is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_CONFUSION;
            break;
        case FORCE_POWER_BEAST_TRICK:
            // Beast Confusion is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_BEAST_CONFUSION;
            break;
        case FORCE_POWER_DROID_TRICK:
            // Droid Confusion is more powerful and
            // part of the same tree.
            nRelatedPowerID1 = FORCE_POWER_DROID_CONFUSION;
            break;
        case FORCE_POWER_PLAGUE:
        case FORCE_POWER_FORCE_ARMOR:
        case FORCE_POWER_FORCE_IMMUNITY:
        case FORCE_POWER_MIND_MASTERY:
        case FORCE_POWER_MASTER_ENERGY_RESISTANCE:
        case FORCE_POWER_SLEEP:
        case FORCE_POWER_SPEED_MASTERY:
        case FORCE_POWER_MASTER_FORCE_BARRIER:
        case FORCE_POWER_MASTER_BATTLE_MEDITATION_PC:
        case FORCE_POWER_MAS_BAT_MED_ENEMY:
        case FORCE_POWER_CRUSH_OPPOSITION_VI:
        case FORCE_POWER_MASTER_FORCE_BODY:
        case FORCE_POWER_MASTER_FORCE_SCREAM:
        case FORCE_POWER_MASTER_FURY:
        case FORCE_POWER_WOOKIEE_RAGE_III:
        case FORCE_POWER_INSPIRE_FOLLOWERS_VI:
        case FORCE_POWER_DOMINATE:
        case FORCE_POWER_FORCE_ENLIGHTENMENT:
        case FORCE_POWER_FORCE_SIGHT:
        case FORCE_POWER_CONFUSION:
        case FORCE_POWER_BEAST_CONFUSION:
        case FORCE_POWER_DROID_CONFUSION:
        case FORCE_POWER_BREATH_CONTROL:
        case 131: // DJS-OEI 10/23/2004 Sonic Howl
        default:
            // There is either no Force Power within the same
            // tree that is better than the given one, or
            // the power ID passed in is not part of a tree
            // that requires this check.
            return 0;
            break;
    }
    // Check to see if the target has any of the Force Power
    // effects we are looking for.
    effect eRelatedEffect;
    if( GetHasSpellEffect(nRelatedPowerID1, oTarget) ||
        GetHasSpellEffect(nRelatedPowerID2, oTarget) ||
        GetHasSpellEffect(nRelatedPowerID3, oTarget) ||
        GetHasSpellEffect(nRelatedPowerID4, oTarget) ||
        GetHasSpellEffect(nRelatedPowerID5, oTarget) ||
        GetHasSpellEffect(nRelatedPowerID6, oTarget) )
    {
        bBetterExists = 1;
    }
    return bBetterExists;
}
""",
    "k_inc_generic": b"""//:: k_inc_generic
/*
    v1.5
    Generic Include for KOTOR
    Post Clean Up as of March 3, 2003
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
#include "k_inc_gensupport"
#include "k_inc_walkways"
#include "k_inc_drop"
struct tLastRound
{
    int nLastAction;
    int nLastActionID;
    int nLastTalentCode;
    object oLastTarget;
    int nTalentSuccessCode;
    int nIsLastTargetDebil;
    int nLastCombo;
    int nLastComboIndex;
    int nCurrentCombo;
    int nBossSwitchCurrent;
};
struct tLastRound tPR;
//LOCAL BOOLEANS RANGE FROM 0 to 96
int AMBIENT_PRESENCE_DAY_ONLY = 1;        //POSSIBLE CUT
int AMBIENT_PRESENCE_NIGHT_ONLY = 2;      //POSSIBLE CUT
int AMBIENT_PRESENCE_ALWAYS_PRESENT = 3;
int SW_FLAG_EVENT_ON_PERCEPTION =   20;
int SW_FLAG_EVENT_ON_ATTACKED   =   21;
int SW_FLAG_EVENT_ON_DAMAGED    =   22;
int SW_FLAG_EVENT_ON_FORCE_AFFECTED = 23;
int SW_FLAG_EVENT_ON_DISTURBED = 24;
int SW_FLAG_EVENT_ON_COMBAT_ROUND_END = 25;
int SW_FLAG_EVENT_ON_DIALOGUE    = 26;
int SW_FLAG_EVENT_ON_DEATH       = 27;
int SW_FLAG_EVENT_ON_HEARTBEAT   = 28;
//int SW_FLAG_AMBIENT_ANIMATIONS = 29;          located in k_inc_walkways
// DJS-OEI 3/31/2004
// Since I misinformed the designers early on about the
// number of local boolean the game was using internally,
// they started using flags 30 thru 64 for plot-related
// stuff. This started causing problems since it was signalling
// the AI to perform incorrect behaviors. I've set aside the
// 30-64 range for designer use and increased the values of
// the remaining flags (as well as the engine's total storage
// capacity) so their current scripts will still work. We need
// to recompile all global and MOD embedded scripts so they use
// the new values.
// 30-64 reserved for designer usage.
/*
//int SW_FLAG_AMBIENT_ANIMATIONS_MOBILE = 30;   located in k_inc_walkways
int SW_FLAG_FAST_BUFF            = 31;   //POSSIBLE CUT
int SW_FLAG_ASC_IS_BUSY          = 32;   //POSSIBLE CUT
int SW_FLAG_ASC_AGGRESSIVE_MODE  = 33;   //POSSIBLE CUT
int SW_FLAG_AMBIENT_DAY_ONLY     = 40;   //POSSIBLE CUT
int SW_FLAG_AMBIENT_NIGHT_ONLY   = 43;   //POSSIBLE CUT
int SW_FLAG_EVENT_ON_SPELL_CAST_AT = 44;
int SW_FLAG_EVENT_ON_BLOCKED     = 45;
int SW_FLAG_ON_DIALOGUE_COMPUTER = 48;
int SW_FLAG_FORMATION_POSITION_0 = 49;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_1 = 50;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_2 = 51;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_3 = 52;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_4 = 53;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_5 = 54;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_6 = 55;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_7 = 56;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_8 = 57;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_9 = 58;   //POSSIBLE CUT
//int SW_FLAG_TARGET_FRIEND      = 59;        Located in k_inc_gensupport
int SW_FLAG_COMMONER_BEHAVIOR    = 60;
int SW_FLAG_SPECTATOR_STATE      = 61;
int SW_FLAG_AI_OFF               = 62;
int SW_CANDEROUS_COMBAT_REGEN    = 63;
int SW_FLAG_BOSS_AI              = 64;
int SW_FLAG_SHIELD_USED          = 65;
int SW_FLAG_EVENT_ON_DIALOGUE_END = 66;
int SW_FLAG_RESISTANCES_APPLIED  = 67;
int SW_FLAG_EVENT_DIALOGUE_END   = 68;   //User defined event
//This flag is set when the creature percieves a hostile for the first time.
//Used to eliminate the delay a creature puts on his perception event when first seeing a hostile.
int SW_FLAG_STATE_AGITATED       = 69;
int SW_FLAG_MALAK_AI_ON          = 70;
int SW_FLAG_DYNAMIC_COMBAT_ZONE  = 71;
int SW_FLAG_EVENT_ON_DIALOGUE_INTERRUPT  = 72;
//int SW_FLAG_WAYPOINT_START_AT_NEAREST = 73;//Located in k_inc_walkways
*/
//int SW_FLAG_AMBIENT_ANIMATIONS_MOBILE = 65;   located in k_inc_walkways
int SW_FLAG_FAST_BUFF            = 66;   //POSSIBLE CUT
int SW_FLAG_ASC_IS_BUSY          = 67;   //POSSIBLE CUT
int SW_FLAG_ASC_AGGRESSIVE_MODE  = 68;   //POSSIBLE CUT
int SW_FLAG_AMBIENT_DAY_ONLY     = 69;   //POSSIBLE CUT
int SW_FLAG_AMBIENT_NIGHT_ONLY   = 70;   //POSSIBLE CUT
int SW_FLAG_EVENT_ON_SPELL_CAST_AT = 71;
int SW_FLAG_EVENT_ON_BLOCKED     = 72;
int SW_FLAG_ON_DIALOGUE_COMPUTER = 73;
int SW_FLAG_FORMATION_POSITION_0 = 74;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_1 = 75;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_2 = 76;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_3 = 77;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_4 = 78;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_5 = 79;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_6 = 80;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_7 = 81;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_8 = 82;   //POSSIBLE CUT
int SW_FLAG_FORMATION_POSITION_9 = 83;   //POSSIBLE CUT
//int SW_FLAG_TARGET_FRIEND      = 84;        Located in k_inc_gensupport
int SW_FLAG_COMMONER_BEHAVIOR    = 85;
int SW_FLAG_SPECTATOR_STATE      = 86;
int SW_FLAG_AI_OFF               = 87;
int SW_CANDEROUS_COMBAT_REGEN    = 88;
int SW_FLAG_BOSS_AI              = 89;
int SW_FLAG_SHIELD_USED          = 90;
int SW_FLAG_EVENT_ON_DIALOGUE_END = 91;
int SW_FLAG_RESISTANCES_APPLIED  = 92;
//JAB-OEI 5/21/04
//Commented out the Following line because of conflicts with SW_FLAG_EVENT_ON_DIALOGUE_END
//int SW_FLAG_EVENT_DIALOGUE_END   = 93;   //User defined event
//This flag is set when the creature percieves a hostile for the first time.
//Used to eliminate the delay a creature puts on his perception event when first seeing a hostile.
int SW_FLAG_STATE_AGITATED       = 94;
int SW_FLAG_MALAK_AI_ON          = 95;
int SW_FLAG_DYNAMIC_COMBAT_ZONE  = 96;
int SW_FLAG_EVENT_ON_DIALOGUE_INTERRUPT  = 97;
//int SW_FLAG_WAYPOINT_START_AT_NEAREST = 98;//Located in k_inc_walkways
//TALENT ROUTINES
int GEN_TALENT_SUPRESS_FORCE = 1;
int GEN_TALENT_REMOVE_POISON = 2;
int GEN_TALENT_HEALING       = 3;
int GEN_TALENT_BUFF          = 4;
int GEN_TALENT_REVITALIZE    = 5;//RWT-OEI 09/03/04
//Sets the NPC listening patterns for the purposes of shouts
void GN_SetListeningPatterns();
//Determines what combat actions the character is going to take.
void GN_DetermineCombatRound(object oIntruder = OBJECT_INVALID);
// Function used by the On Dialogue script to determine what to do when a NPC gets shout
void GN_RespondToShout(object oShouter, int nShoutIndex, object oIntruder = OBJECT_INVALID);
//Sets the day night patterns for the creature.  Uses the AMBIENCE_ constants.
void GN_SetDayNightPresence(int nPresenceSetting);
//Sets the attack target depending on whether oTarget or oIntruder is Valid
object GN_DetermineAttackTarget(object oIntruder = OBJECT_INVALID);
//Makes the character flee the center of an explosion
void GN_DodgeGrenade(object oIntruder);
//Resets the formation booleans on a character.
void GN_ResetFormationBooleans();
//Checks which position on a character is free.
void GN_MoveToFormation(object oAnchor, int nFormationType);
//Runs the default AI routine
int GN_RunDefaultAIRoutine(object oIntruder = OBJECT_INVALID);
//Runs the Aid AI routine
int GN_RunAidAIRoutine(object oIntruder = OBJECT_INVALID);
//Runs the Grenade Thrower AI
int GN_RunGrenadeAIRoutine(object oIntruder = OBJECT_INVALID);
//Runs the Jedi Support AI routine
int GN_RunJediSupportAIRoutine(object oIntruder = OBJECT_INVALID);
//RWT-OEI 03/18/04 - This AI only heals, never attacks.
int GN_RunHealerAIRoutine( object oIntruder = OBJECT_INVALID );
//RWT-OEI 03/22/04 - This AI moves between shooting.
//  If called outside of combat, they just move around randomly.
int GN_RunSkirmishAIRoutine( object oIntruder = OBJECT_INVALID );
//RWT-OEI 08/28/04 - This function keeps the party NPCs within
//a certain number of meters from the party leader. Returns FALSE
//if they are already within that range, returns TRUE if it is
//currently moving them into range.
int GN_CheckRangeFromLeader(float fDistanceLimit = 10.0f);
//RWT-OEI 09/08/04 - This function keeps party puppets within
//a certain number of meters from their owner. Returns FALSE
//if they are already within that range, returns TRUE if it is
//currently moving them into range.
int GN_CheckRangeFromOwner(float fDistanceLimit = 5.0f );
//RWT-OEI 08/28/04 - This AI tries to use ranged as much as possible,
//switches to melee if being attacked with melee.
int GN_RunRangedSupportAIRoutine( object oIntruder = OBJECT_INVALID );
//RWT-OEI 08/28/04 - Calling this tries to switch us to a ranged
//weapon config if we can and we are not being attacked by
//melee at the moment or in the last X rounds.
int GN_CheckRangedPreferred();
//RWT-OEI 08/28/04 - This AI stands in one place and uses ranged or
//melee when being attacked by melee.
int GN_RunStationaryAIRoutine( object oIntruder = OBJECT_INVALID );
//RWT-OEI 08/28/04 - This returns TRUE if the object has a Jedi class
int GN_IsJedi(object oObject = OBJECT_SELF);
//RWT-OEI 09/08/04 - Runs the default puppet AI.
int GN_RunDefaultPuppetAIRoutine(object oIntruder = OBJECT_INVALID );
//Runs the Boss AI Routine
int GN_RunBossAIRoutine(object oIntruder = OBJECT_INVALID);
//Run Boss Grenade AI Routine
int GN_RunBossGrenadeAI();
//Run Boss AOE Force Power Routine
int GN_RunBossAOEPowerRoutine();
//Runs special AI just for Darth Malak on the Star Forge
int GN_RunMalakAIRoutine();
//Run Boss Targeted Routine
int GN_RunBossTargetedRoutine();
// JAB-OEI 7/3/04 - Runs special AI for boss Drexl on Onderon
int GN_RunTurtleAIRoutine(object oIntruder = OBJECT_INVALID);
// DJS-OEI 9/27/2004 - Runs AI for monsters that use Special Abilities
int GN_RunMonsterPowersAIRoutine(object oIntruder = OBJECT_INVALID);
//Sets up struct tLastRound to allow for a single point of determination.
void GN_SetLastRoundData();
//Makes the person or droid activate a shield
int GN_ActivateForceField();
//Makes the person activate Resist Elements and Resist Force.
int GN_ActivateResistances();
//Resets a Droid to his deactivated animation
void GN_ResetDroidDeactivationState(object oDroid = OBJECT_SELF);
//Checks the target and the droid utility use to make sure they are compatible
talent GN_CheckDroidUtilityUsage(object oTarget, talent tUse);
//Checks the target and the force power to make sure that a lightsaber is not thrown from close range.
talent GN_CheckThrowLightSaberUsage(object oTarget, talent tUse);
//Checks the target and the force power to make sure that a non-droid force power is used against a droid
talent GN_CheckNonDroidForcePower(object oTarget, talent tUse);
//Performs a series of checks in case the combat portion of DetermineCombatRound falls through.
int GN_DoPostDCRChecks();
//A void version of do post DCR checks for use with action do command.
void GN_ActionDoPostDCRChecks();
//Determine Combat Round Targeting Funtions
//This function returns an object if OBJECT_SELF is poisoned, or if any party member is poisoned.
object GN_CheckIfPoisoned();
//This function returns an object if OBJECT_SELF is below 50% health, or if any party member is injured.
object GN_CheckIfInjured();
//RWT-OEI 09/03/04 - This returns TRUE if any party member is KO'd.
int GN_CheckIfKnockedOut();
//This checks the last hostile target and determines the best attack action based on the last round.
int GN_GetAttackTalentCode(object oTarget);
//Pass in a talent type and a target to have object_self use the talent
int GN_TalentMasterRoutine(int nTalentConstant, object oTarget);
//Determines where in the current combo the character is and what to do next based on AI style, and combat info.
talent GN_GetComboMove(int nBoss = FALSE);
//Plays an Ambient Animation depending on the spawn in condition selected.
void GN_PlayAmbientAnimation();
// This causes peasants to flee when people
int GN_CommonAI();
//Should Commoners run away.  This returns a yes or no based on a set of conditions
int GN_CheckShouldFlee();
//RWT-OEI 04/07/04 - Sets the heal percentage for the calling object.
void GN_SetHealPercentage( int nHeal );
//RWT-OEI 04/13/04 - Sets the threshold at which the Healer AI will heal
void GN_SetHealThreshold( int nPercentage );
//RWT-OEI 07/16/04 - Set the amount of damage the exploding, floating
//mine will do.
void GN_SetFloatingMineDamage( int nDamage );
//RWT-OEI 07/16/04 - Set the Range that the mine will start seeking
void GN_SetFloatingMineSeekRange( int nRange );
void GN_DetermineCombatRound(object oIntruder = OBJECT_INVALID)
{
    GN_MyPrintString("");
    GN_MyPrintString("GENERIC DEBUG *************** START DETERMINE COMBAT ROUND " + GN_ReturnDebugName(OBJECT_SELF));
    //RWT-OEI 10/19/04 - If this is a party member, and this party member already has
    //combat actions queued up, don't do anything to override those.
    //RWT-OEI 10/30/04 - I had to take this out. It was causing your party members to not
    //engage if they were in Ranged Support but had a melee weapon equipped. They'd often just
    //stand there and do nothing.
    //if ( IsObjectPartyMember(OBJECT_SELF) && GetCombatActionsPending(OBJECT_SELF))
    //{
    //    return;
    //}
    GN_SetLastRoundData();
    int nPartyAI = GetPartyAIStyle(); //Determines how the party should react to intruders
    int nNPC_AI = GetNPCAIStyle(OBJECT_SELF); //Determines how the individual should react in combat
    GN_MyPrintString("GENERIC DEBUG *************** AI STYLE = " + GN_ReturnAIStyle());
    if(!GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR)
    && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE)
    && !GN_GetSpawnInCondition(SW_FLAG_AI_OFF)
    //MODIFIED by Preston Watamaniuk on March 27
    //Put this back in to cancel Determine Combat when user actions are present.
    && !GetUserActionsPending())
    {
        if(GetPartyMemberByIndex(0) != OBJECT_SELF && !GetPlayerRestrictMode())
        {
            if((IsObjectPartyMember(OBJECT_SELF) && !GetPlayerRestrictMode()) || !IsObjectPartyMember(OBJECT_SELF))
            {
                if(nNPC_AI == NPC_AISTYLE_MELEE_ATTACK)
                {
                    if(GetIsObjectValid(oIntruder))
                    {
                        ClearAllActions();
                        ActionAttack(oIntruder);
                        return;
                    }
                    else
                    {
                        object oDefault = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
                        if(GetIsObjectValid(oDefault))
                        {
                            ClearAllActions();
                            ActionAttack(oDefault);
                            return;
                        }
                    }
                    return;
                }
                //Always try and run a force field at the beginning of combat.
                if(GN_ActivateForceField() == TRUE)
                {
                    GN_MyPrintString("GENERIC DEBUG *************** Terminating AI from Shields");
                    return;
                }
                //Always try to use Force Resistance at the beginning of combat.
                if(GN_ActivateResistances() == TRUE){return;}
                //P.W. (June 9) - Malak AI put into the generics
                if(GN_GetSpawnInCondition(SW_FLAG_MALAK_AI_ON) == TRUE)
                {
                    if(GN_RunMalakAIRoutine() == TRUE){return;}
                }
                //If the boss flag is set then the creature will run the boss AI first.
                if(GN_GetSpawnInCondition(SW_FLAG_BOSS_AI) == TRUE)
                {
                    if(GN_RunBossAIRoutine(oIntruder) == TRUE){return;}
                }
                //RWT-OEI 03/18/04 - This AI just runs around healing others
                if ( nNPC_AI == NPC_AISTYLE_HEALER )
                {
                    GN_RunHealerAIRoutine(oIntruder);
                    //If this AI is active, they get no other options, so
                    //just return after it executes.
                    return;
                }
                //RWT-OEI 03/22/04 - This AI moves randomly between shooting
                if ( nNPC_AI == NPC_AISTYLE_SKIRMISH )
                {
                    //If this AI returns 1, then no other AIs should be
                    //executed. If it returns 0, then other attacks are fine.
                    if ( GN_RunSkirmishAIRoutine(oIntruder) )
                        return;
                }
                //RWT-OEI 03/23/04 - If we get here, we may be in skirmish
                //  mode, but not moving. Therefore just attack like normal.
                if(nNPC_AI == NPC_AISTYLE_DEFAULT_ATTACK ||
                   nNPC_AI == NPC_AISTYLE_SKIRMISH )
                {
                     //ACTIVE
                     if(GN_RunDefaultAIRoutine(oIntruder) == TRUE)
                     {
                        return;
                     }
                }
                else if(nNPC_AI == NPC_AISTYLE_GRENADE_THROWER)
                {
                     //ACTIVE
                     if(GN_RunGrenadeAIRoutine(oIntruder) == TRUE){return;}
                }
                else if(nNPC_AI == NPC_AISTYLE_JEDI_SUPPORT)
                {
                     //ACTIVE
                     if ( GN_CheckRangeFromLeader(10.0f) == TRUE )
                     {
                        return;
                     }
                     if(GN_RunJediSupportAIRoutine(oIntruder) == TRUE){return;}
                }
                //JAB-OEI 7/3/04
                else if(nNPC_AI == NPC_AISTYLE_TURTLE)
                {
                    if(GN_RunTurtleAIRoutine(oIntruder) == TRUE){return;}
                }
                else if(nNPC_AI == NPC_AISTYLE_PARTY_AGGRO)
                {
                    //RWT-OEI 08/28/04 Aggressive just acts like it
                    //did in KotOR1.
                    //AurPostString("Aggro AI", 10, 30, 5.0f);
                    if (GN_RunDefaultAIRoutine(oIntruder) == TRUE)
                    {
                        return;
                    }
                }
                else if(nNPC_AI == NPC_AISTYLE_PARTY_DEFENSE)
                {
                    //RWT-OEI 08/28/04 - Defensive acts just like
                    //default in KotOR1, except never more than
                    //10 meters away from the party leader at any
                    //time.
                    //AurPostString("Defense AI", 10, 30, 5.0f);
                    if(GN_CheckRangeFromLeader(5.0f) == TRUE)
                    {
                        return;
                    }
                    GN_RunDefaultAIRoutine(oIntruder);
                    return;
                }
                else if(nNPC_AI == NPC_AISTYLE_PARTY_RANGED)
                {
                    //RWT-OEI 08/28/04 - Ranged Support will
                    //stand back and use ranged weapons. If
                    //they are attacked by someone with melee
                    //they will switch to their alternate
                    //weapon config if that config has
                    //melee weapons in it. Must stay within
                    //10 meters of party leader at any time.
                    if (GN_CheckRangeFromLeader(10.0f) == TRUE)
                    {
                        return;
                    }
                    //AurPostString("Ranged AI", 20, 20, 5.0f);
                    GN_RunRangedSupportAIRoutine(oIntruder);
                    return;
                }
                else if (nNPC_AI == NPC_AISTYLE_PARTY_STATIONARY)
                {
                    //RWT-OEI 08/28/04 - Just stand in one place and
                    //shoot. Don't move under any circumstances whenever
                    //in combat mode. This mode should probably override
                    //movement outside of combat as well. That would
                    //be handled elsewhere.
                    //AurPostString("Stationary AI", 10, 30, 5.0f);
                    //GN_RunStationaryAIRoutine(oIntruder);
                    GN_RunRangedSupportAIRoutine(oIntruder);
                    return;
                }
                else if (nNPC_AI == NPC_AISTYLE_PARTY_SUPPORT)
                {
                    //RWT-OEI 08/28/04 - If is Jedi, then will run
                    //default Jedi routine from KotOR1. If not,
                    //will run Grenadier routine from KotOR1.
                    if (GN_IsJedi(OBJECT_SELF))
                    {
                        //AurPostString("JediSupport AI", 10, 30, 5.0f);
                        GN_RunJediSupportAIRoutine(oIntruder);
                    }
                    else
                    {
                        //AurPostString("Grenadier AI", 10, 30, 5.0f);
                        GN_RunGrenadeAIRoutine(oIntruder);
                    }
                    return;
                }
                else if ( nNPC_AI == NPC_AISTYLE_PARTY_REMOTE )
                {
                    //RWT-OEI 09/08/04 - First priority is to stay in range
                    //of owner.
                    //If we need to move as a result, don't do anything else.
                    if (GN_CheckRangeFromOwner(2.0f) == TRUE)
                    {
                        return;
                    }
                    //Otherwise, call the default puppet AI
                    GN_RunDefaultPuppetAIRoutine(oIntruder);
                    return;
                }
                else if( nNPC_AI == NPC_AISTYLE_MONSTER_POWERS ) {
                    // DJS-OEI 9/27/2004
                    if( GN_RunMonsterPowersAIRoutine(oIntruder) == TRUE ) {
                        return;
                    }
                    else {
                        GN_RunDefaultAIRoutine(oIntruder);
                    }
                }
                else
                {
                    //Run a default AI no matter what. RWT-OEI 08/20/04
                    if (GN_RunDefaultAIRoutine(oIntruder) == TRUE)
                    {
                        return;
                    }
                }
            }
        }
    }
    if(GN_DoPostDCRChecks())
    {
        GN_MyPrintString("GENERIC DEBUG *************** DETERMINE COMBAT ROUND END");
    }
    GN_MyPrintString("GENERIC DEBUG *************** WARNING DETERMINE COMBAT ROUND FAILURE");
}
//::///////////////////////////////////////////////
//:: Do Post Determine Combat Round Checks
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Performs a series of checks in case the combat
    portion of DetermineCombatRound falls through.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 25, 2003
//:://////////////////////////////////////////////
int GN_DoPostDCRChecks()
{
    GN_MyPrintString("GENERIC DEBUG *************** Post DCR Checks for " + GN_ReturnDebugName(OBJECT_SELF));
    if(GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR) && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE))
    {
        //MODIFIED by Preston Watamaniuk on May 29, 2003
        //Changed the commoner subroutine to make sure it walks ways at the end of battles.
        if(GN_CommonAI())
        {
            return TRUE;
        }
    }
    else if(GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Clear 1000");
        ClearAllActions();
        return TRUE;
    }
    //If all combat actions fail, then return to Walkways
    //P.W.(May 22, 2003) - Added check to make sure a waypoint path is set out for the creature. If then do not clear all actions.
    //if(!IsObjectPartyMember(OBJECT_SELF) && GN_CheckWalkWays(OBJECT_SELF) == TRUE)
    if(!IsObjectPartyMember(OBJECT_SELF) && GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE) == TRUE)//AWD-OEI 10/27/2004 we need to actually check if walk waypoints is ON
    {
        GN_MyPrintString("GENERIC DEBUG *************** Clear 1100");
        ClearAllActions();
        //MODIFIED by Preston Watamaniuk on May15, 2003
        //Put this delay command in so that bark bubble do not disapear so quickly off conversations.
        DelayCommand(1.0, GN_WalkWayPoints());
        return TRUE;
    }
    else if(GetPartyMemberByIndex(0) != OBJECT_SELF &&
            !GetIsObjectValid(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF,1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN)) &&
            IsObjectPartyMember(OBJECT_SELF))
    {
        object oLeader = GetPartyMemberByIndex(0);
        object oLeaderTarget = GetAttackTarget(oLeader);
        if(!GetSoloMode())
        {
            //RWT-OEI 09/18/04 - Now your party members will stick it out with
            //helping you bash stuff, if they're not otherwise already occupied.
            if ( GetObjectType( oLeaderTarget ) == OBJECT_TYPE_DOOR &&
                 !GetIsOpen( oLeaderTarget ) && !GetSoloMode())
            {
                //Forget it. Party members won't help with bashing anymore.
                //The targets are too small so it looks lame
                ClearAllActions();
                ActionFollowLeader();
            }
            else if ( GetObjectType( oLeaderTarget ) == OBJECT_TYPE_PLACEABLE &&
                      GetCurrentHitPoints(oLeaderTarget) > 0 && !GetSoloMode())
            {
                //AurPostString( GetTag(OBJECT_SELF) + ": Leader picking on something.", 20, 30, 5.0f );
                //RWT-OEI 10/05/04 - No matter what I do this is going to look lame, taking
                //out party bashing help
                ClearAllActions();
                //ActionAttack(oLeaderTarget);
                ActionFollowLeader();
            }
            else
            {
                //AurPostString( GetTag(OBJECT_SELF) + ": Leader not up to anything.", 20, 31, 5.0f );
                GN_PostString("NO TARGET: FOLLOW LEADER");
                CancelCombat(OBJECT_SELF);
                GN_MyPrintString("GENERIC DEBUG *************** Clear 1200");
                ClearAllActions();
                ActionFollowLeader();
            }
        }
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: GN_ActionDoPostDCRChecks
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    A form of the DCR checks that can be run as
    an actions.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 29, 2003
//:://////////////////////////////////////////////
void GN_ActionDoPostDCRChecks()
{
    int nx = GN_DoPostDCRChecks();
}
//:://////////////////////////////////////////////
//:: Run Default AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Runs the default AI for an NPC. Returns FALSE
    if they cannot do anything.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
int GN_RunDefaultAIRoutine(object oIntruder)
{
    object oTarget, oClose;
    oClose = OBJECT_INVALID;
    int nTalentCode;
    talent tUse;
    int nMoving = 0;
    oTarget = GN_CheckIfPoisoned();
    if(GetIsObjectValid(oTarget))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_REMOVE_POISON, oTarget)) {return TRUE;}
    }
    oTarget = GN_CheckIfInjured();
    if(GetIsObjectValid(oTarget))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_HEALING, oTarget)) {return TRUE;}
    }
    tUse = GN_GetComboMove();
    int nFriend = GetLocalBoolean(OBJECT_SELF, SW_FLAG_TARGET_FRIEND);
    if(nFriend == TRUE)
    {
        if(GetNPCAIStyle(OBJECT_SELF) == NPC_AISTYLE_JEDI_SUPPORT)
        {
            oTarget = GetPartyMemberByIndex(0);
        }
        else
        {
            oTarget = OBJECT_SELF;
        }
    }
    else
    {
        oTarget = tPR.oLastTarget;
        if ( GetNPCAIStyle(OBJECT_SELF) == NPC_AISTYLE_PARTY_DEFENSE )
        {
            //RWT-OEI 10/04/04 - In Defensive AI mode, we chose our targets
            //differently than other modes
            //First we need to know if we have range or melee equipped.
            object oLeader = GetPartyLeader();
            int nWeaponType = 0;
            object oWeap = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON );
            if ( GetIsObjectValid(oWeap) )
            {
                nWeaponType = GN_GetWeaponTypeFromBaseItem(GetBaseItemType(oWeap));
            }
            //If we have RANGED (2), then we only target whoever the player is
            //attacking currently
            if ( nWeaponType == 2 )
            {   if ( GetIsInCombat(oLeader, TRUE) )
                {
                    oClose = GetAttackTarget(oLeader);
                }
                else
                {
                    //If the leader isn't fighting, then either do we
                    oClose = OBJECT_INVALID;
                }
            }
            else
            {
                //If we have melee equipped, we only attack creatures that are within 5.0 meters of the player character
                oClose = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oLeader,1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
                //So just get the nearest creature and check that they're within 5 meters of the
                //current leader
                //AurPostString( "Distance is: " + FloatToString( GetDistanceToObject(oClose)), 20, 21, 5.0f );
                if ( GetIsObjectValid(oClose) && GetDistanceToObject(oClose) > 5.0f )
                {
                    //Clear oClose as a non-target then
                    oClose = OBJECT_INVALID;
                    oIntruder = OBJECT_INVALID;//Clear this as well
                }
            }
        }
        else
        {
            //RWT-OEI 11/01/04 - Trying to make the bosses more aggressive
            if ( GetNPCAIStyle(OBJECT_SELF) != SW_FLAG_BOSS_AI )
            {
                oClose = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF,1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
            }
            else
            {
                oClose = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF,1);
                oTarget = oClose;
            }
        }
        GN_MyPrintString("GENERIC DEBUG *************** Default AI Debug Start *************************");
        GN_MyPrintString("GENERIC DEBUG *************** Intruder    = " + GN_ReturnDebugName(oIntruder));
        GN_MyPrintString("GENERIC DEBUG *************** Last Target = " + GN_ReturnDebugName(oTarget));
        GN_MyPrintString("GENERIC DEBUG *************** Closest     = " + GN_ReturnDebugName(oClose));
        //GN_MyPrintString("GENERIC DEBUG *************** " + GN_ReturnDebugName(OBJECT_SELF) + "I see an enemy = " + IntToString(GetIsObjectValid(oClose)));
        //MODIFIED by Preston Watamaniuk on June 3, 2003
        //I put this check in to make sure the party members only attack what you want until that things dies or leaves.
        if(IsObjectPartyMember(OBJECT_SELF) && GetIsObjectValid(oTarget) && !GetIsDead(oTarget) && GetObjectSeen(oTarget))
        {
            oTarget = oTarget; //Just put this here to show that the target is being used.
        }
        //MODIFIED by Preston Watamaniuk on May 15, 2003
        //Made it so the intruder object is always used if they can be seen and are valid.
        else if(GetIsObjectValid(oIntruder) && GetObjectSeen(oIntruder) )
        {
            GN_MyPrintString("GENERIC DEBUG *************** Intruder becomes Target");
            oTarget = oIntruder;
        }
        else if(GetIsObjectValid(oClose) && GetObjectSeen(oClose))
        {
            if((!GetIsObjectValid(oTarget) ||
               !GetIsEnemy(oTarget) ||
               GetIsDead(oTarget) ||
               GetCurrentHitPoints(oTarget) < GetCurrentHitPoints(oClose)))
               {
                  GN_MyPrintString("GENERIC DEBUG *************** Closest becomes Target");
                  oTarget = oClose;
               }
        } else  if ( GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID &&
                     !IsObjectPartyMember(OBJECT_SELF)) {
            //RWT-OEI 04/07/04 - I added this support to make it so that
            //  ranged-only users will try to chase down the characters.
            //  But the problem is that the HasLineOfSight function is
            //  returning vectors that don't actually give line of
            //  sight -sometimes-. It works about 60%, but the percentage
            //  goes down the further the player is from the attacker.
            //  I would like to fix this up in the future if I have time
            //  to get back to it.
            /*
            if ( !GetIsObjectValid(oIntruder) )
                AurPostString( "Intruder is invalid", 10, 10, 2.0f );
            if ( GetIsObjectValid(oIntruder) && !GetObjectSeen(oIntruder ) )
                AurPostString( "Intruder not seen, but valid.", 10, 15, 2.0f );
            if ( !GetIsObjectValid( oClose ) )
                AurPostString( "oClose is invalid.", 10, 20, 2.0f );
            if ( GetIsObjectValid( oClose ) && !GetObjectSeen( oClose ) )
                AurPostString( "oClose is valid but not seen.", 10, 25, 2.0f );
            */
            //First we need to determine a valid target to go after.
            if ( !GetIsObjectValid( oClose ) ) {
                //oClose is not valid. Probably out of sight. Now find
                //an oClose without the line of sight check.
                oClose = GetNearestCreature(CREATURE_TYPE_REPUTATION,
                                            REPUTATION_TYPE_ENEMY,
                                            OBJECT_SELF, 1);
            }
            if ( GetIsObjectValid( oClose ) )
            {
                //See if that nearest target is stealthed, if so,
                //don't keep looking for them
                if ( IsStealthed(oClose))
                {
                    oClose = OBJECT_INVALID;
                }
            }
            //Do we have a valid target now?
            if ( GetIsObjectValid( oClose ) ) {
                float fDistance = GetDistanceToObject2D( oClose );
                string sDistance = FloatToString( fDistance );
                //AurPostString( sDistance, 20, 20, 2.0f );
                vector vTargetPos = GetPosition( oClose );
                int nLocal = GetLocalNumber( OBJECT_SELF, 9 );
                string sLocal = IntToString( nLocal );
                //AurPostString( sLocal, 40, 10, 2.0f );
                if ( GetLocalNumber( OBJECT_SELF, 9 ) > 2 ) {
                    int nActionID = GetCurrentAction( OBJECT_SELF ) ;
                    //AurPostString( "Going straight there now.", 20, 20, 2.0f);
                    location newLoc = Location( vTargetPos,
                                                GetFacing(OBJECT_SELF));
                    ActionMoveToLocation( newLoc, TRUE );
                    oClose = OBJECT_INVALID;
                    oTarget = OBJECT_INVALID;
                } else {
                    vector vNewPos = GetRandomDestination( OBJECT_SELF, 10 );
                    int nCount = 0;
                    //float fDistanceToTarget = GetDistanceToObject2D(oClose);
                    while ( nCount < 20 ) {
                        if ( HasLineOfSight( vNewPos, vTargetPos ) ) {
                            //New position has line of sight.
                            break;
                        }
                        //If we didn't have line of sight at that last point,
                        //try another one
                        vNewPos = GetRandomDestination( OBJECT_SELF, 20 );
                        ++nCount;
                    }
                    //If nCount is < 20, we found a good place to move to.
                    //So move.
                    if ( nCount < 20 ) {
                        //if ( HasLineOfSight( vNewPos, vTargetPos ) )
                            //AurPostString( "New loc found.", 20, 25, 2.0f );
                        string sCount = IntToString( nCount );
                        //AurPostString( sCount, 20, 30, 2.0f );
                        int nActionID = GetCurrentAction(OBJECT_SELF);
                        if ( nActionID != ACTION_MOVETOPOINT ) {
                            location newLoc = Location( vNewPos,
                                                       GetFacing(OBJECT_SELF));
                            ActionMoveToLocation( newLoc, TRUE );
                            SetLocalNumber(OBJECT_SELF, 9,
                                           GetLocalNumber(OBJECT_SELF, 9) + 1);
                       }
                    }
                    //Clear objects since we have nothing to attack
                    oClose = OBJECT_INVALID;
                    oTarget = OBJECT_INVALID;
                }
            }
        }
    }
    //RWT-OEI 10/31/04 - If our target is more than 30 meters away,
    //drop out of combat all together
    float fDistance = GetDistanceToObject(oTarget);
    if ( fDistance > 30.0f && GetNPCAIStyle(OBJECT_SELF) != SW_FLAG_BOSS_AI )
    {
        //Okay, target is too far. Just drop out of combat all
        //together.
        oTarget = OBJECT_INVALID;
        CancelCombat(OBJECT_SELF);
    }
    //If we have a valid target, reset the number of times we've looked for
    //a better firing position.
    if ( GetIsObjectValid( oTarget ) ) {
        SetLocalNumber( OBJECT_SELF, 9, 0 );
    }
    //MODIFIED by Preston Watamaniuk on April 22, 2003
    //Put this check in to allow Droids to use their special abilities in a more logical manner. Passes in the talent and the target
    //and double checks that the usage is logical.
    if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID)
    {
        tUse = GN_CheckDroidUtilityUsage(oTarget, tUse);
    }
    tUse = GN_CheckThrowLightSaberUsage(oTarget, tUse);
    tUse = GN_CheckNonDroidForcePower(oTarget, tUse);
    GN_MyPrintString("GENERIC DEBUG *************** Default AI Debug End ***************************");
    GN_MyPrintString("GENERIC DEBUG *************** Target = " + GN_ReturnDebugName(oTarget) + " is Enemy: " + IntToString(GetIsEnemy(oTarget)));
    if(GetIsObjectValid(oTarget))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Clear 1300");
        ClearAllActions();
        if(GN_EquipAppropriateWeapon())
        {
           GN_MyPrintString("GENERIC DEBUG *************** Switching Weapons");
        }
        if(GetIsTalentValid(tUse) && GetIsEnemy(oTarget))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Using Talent on Target");
            ActionUseTalentOnObject(tUse, oTarget);
            return TRUE;
        }
        else if(GetIsEnemy(oTarget))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Action Attack by Default");
            ActionAttack(oTarget);
            return TRUE;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Default AI has failed to do an action");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Jedi Aid AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    AI that concentrates on keeping the party healed,
    poison free.  If the party is doing ok then the Jedi
    will attempt to use Force Powers. If they are unable
    to use force powers they will run default AI.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 20, 2003
//:://////////////////////////////////////////////
int GN_RunAidAIRoutine(object oIntruder = OBJECT_INVALID)
{
    object oPoisoned = GN_CheckIfPoisoned();
    if(GetIsObjectValid(oPoisoned))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_REMOVE_POISON, oPoisoned)) {return TRUE;}
    }
    object oInjured = GN_CheckIfInjured();
    if(GetIsObjectValid(oInjured))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_HEALING, oInjured)) {return TRUE;}
    }
    return GN_RunDefaultAIRoutine(oIntruder);
}
//::///////////////////////////////////////////////
//:: Grenade AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Trys to use a grenades on targets not surrounded
    by enemies
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17, 2003
//:://////////////////////////////////////////////
int GN_RunGrenadeAIRoutine(object oIntruder = OBJECT_INVALID)
{
    if(IsObjectPartyMember(OBJECT_SELF) || d100() > 50)
    {
        int nDroid = FALSE;
        talent tUse;
        object oTarget = GN_FindGrenadeTarget();
        if(GetRacialType(oTarget) == RACIAL_TYPE_DROID)
        {
            nDroid = TRUE;
        }
        tUse = GN_GetGrenadeTalent(nDroid);
        if(GetIsObjectValid(oTarget) && GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Clear 1400");
            ClearAllActions();
            ActionUseTalentOnObject(tUse, oTarget);
            return TRUE;
        }
        GN_MyPrintString("GENERIC DEBUG *************** Grenade AI Failure");
        return GN_RunDefaultAIRoutine(oIntruder);
    }
    GN_MyPrintString("GENERIC DEBUG *************** Grenade AI Fall Through");
    return GN_RunDefaultAIRoutine(oIntruder);
}
//::///////////////////////////////////////////////
//:: Jedi Support
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This will make the Jedi use Force Powers before
    everything else.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17, 2003
//:://////////////////////////////////////////////
int GN_RunJediSupportAIRoutine(object oIntruder = OBJECT_INVALID)
{
    //RWT-OEI 10/19/04 - Don't do ANYTHING if we're in a cutscene...
    if ( GetIsConversationActive() )
    {
        return TRUE;
    }
    object oPoisoned = GN_CheckIfPoisoned();
    talent tUse;
    object oTarget;
    //P.W (May 27, 2003) - Made a change so that Droids can use Jedi Support. Its just defaul AI with an AI check however.
    if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID)
    {
        return GN_RunDefaultAIRoutine();
    }
    //RWT-OEI 10/11/04 - If the player character is just attacking doors
    //or placeables, then don't bother buffing them...
    object oLeader = GetPartyMemberByIndex(0);
    object oLeaderTarget = GetAttackTarget(oLeader);
    if ( !GetSoloMode() )
    {
        if ( GetObjectType( oLeaderTarget ) == OBJECT_TYPE_DOOR ||
             GetObjectType( oLeaderTarget ) == OBJECT_TYPE_PLACEABLE )
        {
            return FALSE;
        }
    }
    if (GN_CheckSeriesRevitalize() != -1)
    {
        int nDown = GN_CheckIfKnockedOut();
        if ( nDown )
        {
            AurPostString( "Someone is knocked out.", 20, 25, 5.0f );
            if ( GN_TalentMasterRoutine(GEN_TALENT_REVITALIZE, GetFirstPC()) )
            {
                return TRUE;
            }
        }
    }
    if(GetIsObjectValid(oPoisoned))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_REMOVE_POISON, oPoisoned)) {return TRUE;}
    }
    object oInjured = GN_CheckIfInjured();
    if(GetIsObjectValid(oInjured))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_HEALING, oInjured)) {return TRUE;}
    }
    if(GN_TalentMasterRoutine(GEN_TALENT_BUFF, OBJECT_SELF))
    {
        return TRUE;
    }
    oTarget = GN_FindAOETarget();
    GN_MyPrintString("GENERIC DEBUG *************** Jedi Support AI: AOE Target = " + GN_ITS(GetIsObjectValid(oTarget)));
    if(GetIsObjectValid(oTarget))
    {
        if(GetRacialType(oTarget) == RACIAL_TYPE_DROID)
        {
            tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_FORCE_POWER, TRUE);
        }
        else
        {
            tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_FORCE_POWER);
        }
    }
    else
    {
        GN_MyPrintString("GENERIC DEBUG *************** Jedi Support AI: Inside the Party AI Section");
        oTarget = GN_DetermineAttackTarget();
        GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Initial oFind Search = " + GN_ReturnDebugName(oTarget));
        if(GetIsObjectValid(oTarget))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Jedi Support AI: Valid oTarget Set As = " + GN_ReturnDebugName(oTarget));
            if(GetRacialType(oTarget) == RACIAL_TYPE_DROID)
            {
                tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_NPC, TRUE);
            }
            else
            {
                tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_NPC);
            }
        }
    }
    tUse = GN_CheckThrowLightSaberUsage(oTarget, tUse);
    tUse = GN_CheckNonDroidForcePower(oTarget, tUse);
    if(GetIsObjectValid(oTarget) && GetIsTalentValid(tUse))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Clear 1450");
        ClearAllActions();
        ActionUseTalentOnObject(tUse, oTarget);
        return TRUE;
    }
    GN_MyPrintString("GENERIC DEBUG *************** Jedi Support AI: Fall Through");
    return GN_RunDefaultAIRoutine();
}
//::///////////////////////////////////////////////
//:: Boss AI: Grenade
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Run Boss Grenade AI Routine
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 2, 2003
//:://////////////////////////////////////////////
int GN_RunBossGrenadeAI()
{
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Grenade Function Starting");
    talent tUse;
    object oCheck = GN_FindGrenadeTarget();
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Grenade Target = " + GN_ITS(GetIsObjectValid(oCheck)));
    int nDroid;
    if(GetIsObjectValid(oCheck))
    {
         if(GetRacialType(oCheck) == RACIAL_TYPE_DROID)
         {
            nDroid == TRUE;
         }
         tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_GRENADE, nDroid);
         if(GetIsTalentValid(tUse))
         {
            GN_MyPrintString("GENERIC DEBUG *************** Clear 1460");
            ClearAllActions();
            ActionUseTalentOnObject(tUse, oCheck);
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Success");
            return TRUE;
         }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Failure");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Boss AI: AOE Power
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Run Boss AOE Force Power Routine
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 2, 2003
//:://////////////////////////////////////////////
int GN_RunBossAOEPowerRoutine()
{
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Function Starting");
    talent tUse;
    object oCheck = GN_FindAOETarget();
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Target = " + GN_ITS(GetIsObjectValid(oCheck)));
    int nDroid;
    if(GetIsObjectValid(oCheck))
    {
         if(GetRacialType(oCheck) == RACIAL_TYPE_DROID)
         {
            nDroid == TRUE;
         }
         tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_FORCE_POWER, nDroid);
         if(GetIsTalentValid(tUse))
         {
            ClearAllActions();
            ActionUseTalentOnObject(tUse, oCheck);
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Success");
            return TRUE;
         }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Failure");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Boss AI: Targeting
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This will make boss monsters use targeted
    super powers.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 2, 2003
//:://////////////////////////////////////////////
int GN_RunBossTargetedRoutine()
{
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Start Targeted Action Routine");
    talent tUse;
    object oTarget;
    int nDroid;
    int nRand = d6();
    int nCnt = 1;
    if(nRand < 4){nRand = 1;}
    if(nRand == 4){nRand = 2;}
    if(nRand == 5){nRand = 3;}
    if(nRand == 6){nRand = 4;}
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Get the #" + GN_ITS(nRand) + " target");
    object oFind = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Initial oFind Search = " + GN_ReturnDebugName(oFind));
    while(GetIsObjectValid(oFind) && nCnt <= nRand)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Valid oFind = " + GN_ReturnDebugName(oFind) + " nCnt = " + GN_ITS(nCnt));
        if(GetIsObjectValid(oFind))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Valid oTarget Set As = " + GN_ReturnDebugName(oFind));
            oTarget = oFind;
        }
        nCnt++;
        oFind = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
    }
    //DEBUG STATEMENTS
    int nX = TRUE;
    if(nX == TRUE)
    {
        if(GetIsTalentValid(tUse))
        {
            if(GetTypeFromTalent(tUse) == TALENT_TYPE_FEAT)
            {
                GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Talent Feat = " + GN_ITS(GetIdFromTalent(tUse)));
            }
            else if(GetTypeFromTalent(tUse) == TALENT_TYPE_FORCE)
            {
                GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Talent Power = " + GN_ITS(GetIdFromTalent(tUse)));
            }
        }
    }
    if(GetIsObjectValid(oTarget))
    {
        if(GetRacialType(oTarget) == RACIAL_TYPE_DROID)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Get Boss Combat Move AI Droid");
            nDroid = TRUE;
        }
        tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_TYPE_NPC, nDroid);
        tUse = GN_CheckThrowLightSaberUsage(oTarget, tUse);
        tUse = GN_CheckNonDroidForcePower(oTarget, tUse);
        //MODIFIED by Preston Watamaniuk on April 2, 2003
        //Added this check to make the Droid setting was used for non-specific attacks.
        GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Target = " + GN_ITS(GetIsObjectValid(oTarget)));
        GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Talent = " + GN_ITS(GetIsTalentValid(tUse)));
        if(GetIsTalentValid(tUse) && GetIsObjectValid(oTarget))
        {
            ClearAllActions();
            ActionUseTalentOnObject(tUse, oTarget);
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Targeted Power Success");
            return TRUE;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Targeted Failure");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Boss AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This will make boss monsters buff themselves
    and use more force powers or utility devices
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 31, 2003
//:://////////////////////////////////////////////
int GN_RunBossAIRoutine(object oIntruder = OBJECT_INVALID)
{
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI Start");
    object oTarget = GN_CheckIfInjured();
    if(GetIsObjectValid(oTarget))
    {
        if(GN_TalentMasterRoutine(GEN_TALENT_HEALING, oTarget)) {return TRUE;}
    }
    if(GN_EquipAppropriateWeapon())
    {
       GN_MyPrintString("GENERIC DEBUG *************** Switching Weapons");
    }
    if(GN_RunBossGrenadeAI() == TRUE) {return TRUE;}
    else if(GN_RunBossAOEPowerRoutine() == TRUE) {return TRUE;}
    else if(GN_RunBossTargetedRoutine() ==  TRUE) {return TRUE;}
    GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Fall Through");
    return GN_RunDefaultAIRoutine();
}
//::///////////////////////////////////////////////
//:: Malak AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This AI is just for Darth Malak on the Star
    Forge. It assumes there is only the PC and
    no one else.
    Malak's Force Powers
        Master Speed
        Force Push
        Throw Lightsaber (15)
        Affliction
        Force Resistance
        Imp. Energy Resist
        Lightning (15)
        Force Breach
    This routine is an add-on for boss ai.  It
    tests certain conditions that could be
    occurring in the Malak fight and reacts to them
    in a more agressive manner.
    1. K_END_JEDI_LEFT - Will track the total number
       of entombed Jedi left in the fight.
    2. K_END_MALAK_JEDI_USED - Will track the number
    of Jedi's Malak has personally used in the fight.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 29, 2003
//:://////////////////////////////////////////////
int GN_RunMalakAIRoutine()
{
    GN_MyPrintString("GENERIC DEBUG *************** Malak AI Start");
    //int nJediLeft = GetGlobalNumber("K_END_JEDI_LEFT");
    //int nMalakUsed = GetGlobalNumber("K_END_MALAK_JEDI_USED");
    object oPC = GetFirstPC();
    int bJedi, bDist, bAttack;
    float fDist = GetDistanceBetween(OBJECT_SELF, oPC);
    //Check to see if Malak need to become more aggressive
    //Test the number of Jedi to see if the player has used any
    //if(((8 - nJediLeft) < nMalakUsed))
    //{
    //    bJedi = TRUE;
    //}
    //Check to see if the player is running away
    GN_MyPrintString("GENERIC DEBUG *************** Malak Distance to PC = " + FloatToString(GetDistanceBetween(OBJECT_SELF, oPC),4,4));
    if(fDist > 10.0)
    {
        bDist = TRUE;
    }
    if(bDist == TRUE)
    {
        /*
            AI REACTION 2 - Player is keeping his distance.
            1. Force Breach if the player is using speed
            OR
            2. Use Action Attack to Force Jump
        */
        GN_MyPrintString("GENERIC DEBUG *************** Clear 1480");
        ClearAllActions();
        if(GetHasSpellEffect(FORCE_POWER_SPEED_BURST, oPC) ||
           GetHasSpellEffect(FORCE_POWER_KNIGHT_SPEED, oPC) ||
           GetHasSpellEffect(FORCE_POWER_SPEED_MASTERY, oPC))
        {
            talent tBreach = TalentSpell(FORCE_POWER_FORCE_BREACH);
            if(GetIsTalentValid(tBreach))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Using Breach");
                ActionUseTalentOnObject(tBreach, oPC);
            }
            bAttack = TRUE;
        }
        else
        {
            if(fDist > 10.0)
            {
                int nRoll = d3();
                int nPower = -1;
                if(nRoll == 1)
                {
                    nPower = FORCE_POWER_LIGHTNING;
                }
                else if(nRoll == 2)
                {
                    nPower = FORCE_POWER_LIGHT_SABER_THROW;
                }
                else if(nRoll > 2)
                {
                    bAttack = TRUE;
                }
                if(nPower != -1)
                {
                    talent tPower = TalentSpell(nPower);
                    if(GetIsTalentValid(tPower))
                    {
                        GN_MyPrintString("GENERIC DEBUG *************** Malak Using Force Power");
                        ActionUseTalentOnObject(tPower, oPC);
                        return TRUE;
                    }
                }
            }
            bAttack = TRUE;
        }
    }
    if(bAttack == TRUE)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Malak Attacking");
        ActionAttack(oPC);
        return TRUE;
    }
    GN_MyPrintString("GENERIC DEBUG *************** Malak AI Drop Out");
    return FALSE;
}
//RWT-OEI 04/07/04
// GN_SetHealPercentage
// Determines what percentage the HealerAI does per heal.
// Specific to the calling object
void GN_SetHealPercentage( int nHeal )
{
    SetLocalNumber(OBJECT_SELF, SW_NUMBER_HEALERAI_PERCENTAGE, nHeal );
}
//RWT-OEI 04/13/04
// GN_SetHealThreshold
// Sets the threshold at which the HealerAI will try to heal
// Specific to the calling object
void GN_SetHealThreshold( int nPercentage )
{
    SetLocalNumber( OBJECT_SELF, SW_NUMBER_HEALERAI_THRESHOLD, nPercentage );
}
//::///////////////////////////////////////////////
//:: Healer AI Routine: Do Heal
//:: Copyright (c) 2004 Obsidian Entertainment
//:://////////////////////////////////////////////
/*
    This subfunction is only intended to be called
    from within the GN_RunHealerAIRoutine.
    It is what handles the actual healing after
    all the logic, patient selection, and movement
    has been taken care of.
*/
//:://////////////////////////////////////////////
//:: Created By: R.Taylor
//:: Created On: 03/22/04
//:://////////////////////////////////////////////
void HealerAIDoHeal( object oPatient )
{
    //AurPostString( "Now in healeraidoheal", 10, 10, 10.0f );
    //Make sure we're facing the right way
    SetFacingPoint(GetPosition(oPatient));
    int nMaxHP = GetMaxHitPoints( oPatient );
    int nCurHP = GetCurrentHitPoints( oPatient );
    //Determine the percentage to heal.
    int nHealPercentage = GetLocalNumber(OBJECT_SELF, SW_NUMBER_HEALERAI_PERCENTAGE);
    if ( !nHealPercentage ) //It wasn't set, so default to 25%
        nHealPercentage = 25;
    int nHealAmount = ( nMaxHP * nHealPercentage ) / 100;
    //int nHealAmount = nMaxHP / 4;
    //Make sure we can't heal them over 100%
    if ( (nMaxHP - nCurHP ) < nHealAmount )
        nHealAmount = nMaxHP - nCurHP;
    //Create and apply the heal effect
    effect eHeal = EffectHeal( nHealAmount );
    ApplyEffectToObject( DURATION_TYPE_INSTANT, eHeal, oPatient );
    //effect eBeam = EffectVisualEffect( VFX_BEAM_STUN_RAY );
    //ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eBeam, OBJECT_SELF, 1.0 );
    effect eBeam = EffectBeam( VFX_BEAM_STUN_RAY, OBJECT_SELF, BODY_NODE_HAND );
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eBeam, oPatient, 1.0f );
    effect eHealField;
    if ( GetRacialType( oPatient ) == RACIAL_TYPE_DROID ) {
        eHealField = EffectVisualEffect( 1048 );
    } else {
        eHealField = EffectVisualEffect( VFX_IMP_HEAL );
    }
    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eHealField, oPatient, 3.0f );
}
//::///////////////////////////////////////////////
//:: Healer AI Routine
//:: Copyright (c) 2004 Obsidian Entertainment
//:://////////////////////////////////////////////
/*
    Creatures using this AI do NOT FIGHT no matter
    what. Instead, they run around looking for
    anyone that is 'friendly' to their faction and
    healing them as long as combat is going on.
    Outside of combat, they'll keep healing until
    no allies are nearby that need healing.
    They do not heal themselves.
    Currently, they restore 25% of their patient's
        HP.
*/
//:://////////////////////////////////////////////
//:: Created By: R.Taylor
//:: Created On: 03/18/04
//:://////////////////////////////////////////////
int GN_RunHealerAIRoutine( object oIntruder )
{
    //First we need to see if we're already actively
    //trying to find someone to heal.
    object oOldTarget = GetHealTarget( OBJECT_SELF );
    if ( GetIsObjectValid( oOldTarget ) && !(GetIsDead( oOldTarget) ) ) {
        //The old target is still valid, let's see if
        //we're close enough to heal them.
        //AurPostString( "We have a heal target", 10, 10, 10.0f );
        float distance = GetDistanceToObject( oOldTarget );
        if ( distance < 3.5 ) { //We're now close enough to heal
            HealerAIDoHeal( oOldTarget );
            //Clear our old target so we don't heal them again
            SetHealTarget( OBJECT_SELF, OBJECT_INVALID );
            if ( GetIsInCombat() )
                DelayCommand( 3.0, GN_DetermineCombatRound( oIntruder ) );
        } else {
            //See if we're still moving
            //AurPostString( "Check if we are still moving", 10, 10, 10.0f );
            int nActionID = GetCurrentAction(OBJECT_SELF);
            if ( nActionID != ACTION_MOVETOPOINT ) {
                //Requeue a move action to get us moving again
                //AurPostString( "Requeue Moving to New Target", 10, 10, 10.0f );
                ActionMoveToObject( oOldTarget, TRUE, 3.0f );
                if ( GetIsInCombat() )
                    DelayCommand( 3.0, GN_DetermineCombatRound( oIntruder ) );
            }
        }
        return 0;
    } else {
        //AurPostString( "Target is dead or invalid, so clear.", 10, 10, 10.0f);
        SetHealTarget( OBJECT_SELF, OBJECT_INVALID );
    }
    //If we get this far, then we do not have a current heal target to
    //focus on.
    //Search through every creature within a 20m radius
    //If they are friendly to this creature, and
    //have HP less than 50%, move over to them and heal
    //them.
    //AurPostString( "We don't have a target yet", 10, 10, 10.0f );
    object oCurTarget = GetFirstObjectInShape(SHAPE_SPHERE, 20.0f,
        GetLocation(OBJECT_SELF), FALSE, OBJECT_TYPE_CREATURE );
    while ( GetIsObjectValid(oCurTarget) )
    {
        int bHealCurTarget = TRUE;
        //Make sure we're not healing self
        if ( oCurTarget == OBJECT_SELF ) {
            //AurPostString( "Don't heal self.", 10, 10, 10.0f );
            bHealCurTarget = FALSE;
        }
        //Can't heal the dead ones.
        if ( bHealCurTarget && GetIsDead( oCurTarget ) ) {
            //AurPostString( "Cur Target is already dead.", 10, 10, 10.0f );
            bHealCurTarget = FALSE;
        }
        //Heal those we're friendly to
        if ( bHealCurTarget && !(GetIsFriend( oCurTarget ))  ) {
            //AurPostString( "Not friend or neutral to target.", 10, 10, 10.0f );
            bHealCurTarget = FALSE;
        }
        //RWT-OEI 10/05/04
        //If we're NOT Friendly1, only heal droids.
        if ( GetStandardFaction(OBJECT_SELF) != STANDARD_FACTION_FRIENDLY_1 &&
             GetStandardFaction(OBJECT_SELF) != STANDARD_FACTION_FRIENDLY_2 )
        {
            if ( GetRacialType(oCurTarget) != RACIAL_TYPE_DROID )
            {
                bHealCurTarget = FALSE;
            }
        }
        //RWT-OEI 10/05/04
        //If we're neutral, don't heal anyone
        if ( GetStandardFaction(OBJECT_SELF) == STANDARD_FACTION_NEUTRAL )
        {
            bHealCurTarget = FALSE;
        }
        //We have a target that we might heal now if bHealCurTarget = true
        if ( bHealCurTarget ) {
            //AurPostString( "Target eligible for possible healing.", 10, 10, 5.0f);
            //Determine if cur target has less than 50% HP
            int nCurHP = GetCurrentHitPoints( oCurTarget );
            int nMaxHP = GetMaxHitPoints( oCurTarget );
            int nPercentage = ( nCurHP * 100 ) / nMaxHP;
            int nThreshold = GetLocalNumber(OBJECT_SELF, SW_NUMBER_HEALERAI_THRESHOLD );
            if ( nThreshold < 1 )
                nThreshold = 50;//RWT-OEI 04/13/04 - Default to 50%
            if ( nPercentage < nThreshold ) {
                //AurPostString( "Need to heal this target.", 10, 10, 5.0f );
                //Need to heal this target
                ClearAllActions();
                //Get within 3.5 meters for visual reasons
                float distance = GetDistanceToObject2D( oCurTarget );
                if ( distance > 3.5 ) {
                    //We need to move closer to the object before healing
                    //AurPostString( "Need move closer new target.", 10, 10, 5.0f);
                    //Make sure to store the ID of our current heal target
                    //so we know not to seek out a new target
                    SetHealTarget( OBJECT_SELF, oCurTarget );
                    ActionMoveToObject( oCurTarget, TRUE, 3.0f );
                    if (GetIsInCombat() )
                        DelayCommand( 3.0, GN_DetermineCombatRound( oIntruder ) );
                    return 0;
                } else {
                    //Close enough to heal new target
                    HealerAIDoHeal( oCurTarget );
                    SetHealTarget( OBJECT_SELF, OBJECT_INVALID );
                    if ( GetIsInCombat() )
                        DelayCommand( 3.0, GN_DetermineCombatRound( oIntruder ));
                    return 0;
                }
            } //if percentage < 50
        } //if bHealCurTarget
        oCurTarget = GetNextObjectInShape(SHAPE_SPHERE, 20.0f,
                       GetLocation(OBJECT_SELF), FALSE,
                       OBJECT_TYPE_CREATURE );
    }// while GetObjectIsValid()
    return 0;
}
//::///////////////////////////////////////////////
//:: Skirmish AI Routine
//:: Copyright (c) 2004 Obsidian Entertainment
//:://////////////////////////////////////////////
/*
    This function handles the Skirmish AI.
    Basically, between shooting, the creature will
    move around randomly. This is designed to give
    the illusion of skirmishing and movement during
    combat, when in effect, all it really does is make
    the creature waste a lot combat rounds by moving
    instead of attacking. As a result, creatures using
    this AI will be easier than the same creature
    using the default AI.
    If it returns 0, that means to continue on
    with alternative AI routines. If it returns 1,
    that means it has handled the creature's action
    for now and no other AI routines should be run.
*/
//:://////////////////////////////////////////////
//:: Created By: R.Taylor
//:: Created On: 03/22/04
//:://////////////////////////////////////////////
int GN_RunSkirmishAIRoutine( object oIntruder )
{
    //Creatures on the Skirmish AI will NOT be allowed
    //to use Waypoints, so we'll just borrow the local
    //Number fields that deal with Waypoints: 0, 1, 2
    //0 = # of times this has been called but done \
    //    nothing.
    //If we're already moving, do nothing.
    if ( GetCurrentAction() == ACTION_MOVETOPOINT ) {
        return 1;
    }
    int nTimes = GetLocalNumber( OBJECT_SELF, 0 );
    int nOdds = (nTimes * 100) / 5;
    int nRand = Random( 100 );
    if ( nRand < nOdds ) {//Okay, move and reset Local:0
        vector vNewPos = GetRandomDestination( OBJECT_SELF, 6 );
        float fFacing  = GetFacing( OBJECT_SELF );
        SetLocalNumber( OBJECT_SELF, 0, 0 );
        location lNewLoc = Location( vNewPos, fFacing );
        ActionMoveToLocation( lNewLoc, TRUE );
        return 1;//We handled the action here
    } else {
        // We're not going to move this time, increment Local:0
        nTimes += 1;
        SetLocalNumber( OBJECT_SELF, 0, nTimes );
        return 0;//We didn't control the action at this time
    }
}
//::///////////////////////////////////////////////
//:: Turtle AI Routine
//:: Copyright (c) 2004 Obsidian Entertainment
//:://////////////////////////////////////////////
/*
    This function handles the Turtle AI.
    We needed a special AI for the Drexl Boss
    on Onderon. Basically what happens is the Drexl
    goes into a defensive turtle mode, where he does
    not attack the PC and the party. He absorbs a
    certain amount of damage, then deals it
    off to the player, and or surrounding NPCs
    The damage is stored in local number 15
    We need to keep a tab on how much damage
    is given in this number
*/
//:://////////////////////////////////////////////
//:: Created By: Adam Brennecke
//:: Created On: 07/03/04
//:://////////////////////////////////////////////
int GN_RunTurtleAIRoutine( object oIntruder )
{
    // check how much damage has been done
    int iDmg = GetLocalNumber(OBJECT_SELF,15);
    // check if we are about to die, if so, then don't do the special attack
    if(GetCurrentHitPoints() < 5)
        return TRUE;
    if(iDmg > 30)
    {
        AurPostString("Turtle Special Attack",5,7,5.0);
        iDmg = iDmg / 3;
        // we need to remove the effects on the object so it can roar
        effect e = GetFirstEffect(OBJECT_SELF);
        while(GetIsEffectValid(e))
        {
            if(GetEffectType(e) == EFFECT_TYPE_SLEEP)
            {
                DelayCommand(0.1,RemoveEffect(OBJECT_SELF,e));
            }
            else if(GetEffectType(e) == EFFECT_TYPE_PARALYZE)
            {
                DelayCommand(0.1,RemoveEffect(OBJECT_SELF,e));
            }
            else if(GetEffectType(e) == EFFECT_TYPE_VISUAL)
            {
                DelayCommand(0.1,RemoveEffect(OBJECT_SELF,e));
            }
           e = GetNextEffect(OBJECT_SELF);
        }
        // make it look like we are attacking
        ClearAllActions();
        DelayCommand(0.3,ActionPlayAnimation(ANIMATION_FIREFORGET_TAUNT,1.0,1.0));
        // apply damage to the three PCs if they are close enough
        int i;
        for(i = 0; i < 3; i++)
        {
            object oTarg = GetPartyMemberByIndex(i);
            if(GetDistanceBetween(OBJECT_SELF,oTarg) < 10.0)
            {
                // saving throws?
                DelayCommand(1.0,ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDamage(iDmg),oTarg));
                // play special effect
                //effect eVis = EffectBeam(VFX_BEAM_FLAME_SPRAY,OBJECT_SELF,BODY_NODE_HEAD);
                //DelayCommand(0.5,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eVis,oTarg,2.0));
            }
        }
        // reset damage counter
        DelayCommand(1.0,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectVisualEffect(VFX_IMP_SCREEN_SHAKE),GetFirstPC(),2.0));
        SetLocalNumber(OBJECT_SELF,15,0);
    }
    else
    {
        AurPostString("Turtle Paralyzed Code.",5,6,4.0);
        ClearAllActions();
        //ActionPlayAnimation(ANIMATION_LOOPING_SLEEP,1.0,-1.0);
        // We should look like we are about to die, and on the defensive
        // check to see if we already have the effects applied, if so, don't do it twice
        // this was causing me to have alot of headaches
        int nApplyEffects = 1;
        effect e = GetFirstEffect(OBJECT_SELF);
        while(GetIsEffectValid(e))
        {
            if(GetEffectType(e) == EFFECT_TYPE_SLEEP)
                nApplyEffects = 0;
           e = GetNextEffect(OBJECT_SELF);
        }
        if(nApplyEffects)
        {
            //DelayCommand(3.0,ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectVisualEffect(VFX_IMP_FLAME),OBJECT_SELF,100.0)));
            DelayCommand(3.0,ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectSleep(),OBJECT_SELF,100.0)));
            DelayCommand(3.0,ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectParalyze(),OBJECT_SELF,100.0)));
        }
    }
    return TRUE;
}
// DJS-OEI 9/27/2004
// AI for creatures that need to occassionally use Special Abilities.
int GN_RunMonsterPowersAIRoutine(object oIntruder) {
    AurPostString( "Monster Powers AI Routine", 5, 4, 3.0 );
    // This just looks for Monster Powers (which all seem to have 0x1304 as
    // their category.
    talent tPower = GetCreatureTalentRandom( 0x1304, OBJECT_SELF, TALENT_TYPE_SPELL );
    // Fire a power 20% of the time.
    if( d100() < 20 ) {
        // Perform it.
        if(GetIsTalentValid(tPower) && GetCreatureHasTalent(tPower)) {
            if(GetIsObjectValid(oIntruder) && GetIsEnemy(oIntruder)) {
                GN_MyPrintString("GENERIC DEBUG *************** Using Talent on Intruder Target");
                ActionUseTalentOnObject(tPower, oIntruder);
                return TRUE;
            }
            else {
                // Get the nearest enemy and use the ability on it.
                object oDefault = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
                if(GetIsObjectValid(oDefault))
                {
                    GN_MyPrintString("GENERIC DEBUG *************** Using Talent on Determined Target");
                    ActionUseTalentOnObject(tPower, oDefault);
                    return TRUE;
                }
            }
        }
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Shield Activation
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Organic Shields are 99 to 107
    Droid shields are 110 to 115
    Scans through all of the shield talents to
    see if the target has a shield to use. If the
    shield is used then the person will never use
    another one. Party members will never use this
    function.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 31, 2003
//:://////////////////////////////////////////////
int GN_ActivateForceField()
{
    GN_MyPrintString("GENERIC DEBUG *************** Starting Forcefield Search");
    GN_MyPrintString("GENERIC DEBUG *************** Shield Boolean (" + GN_ITS(SW_FLAG_SHIELD_USED) + ") = " + GN_ITS(GN_GetSpawnInCondition(SW_FLAG_SHIELD_USED)));
    if(GN_GetSpawnInCondition(SW_FLAG_SHIELD_USED) == FALSE && !IsObjectPartyMember(OBJECT_SELF))
    {
        int nCnt, nStop;
        int bValid = FALSE;
        talent tShield;
        if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID)
        {
            nCnt = 110;
            nStop = 115;
        }
        else
        {
            nCnt = 99;
            nStop = 107;
        }
        while(bValid == FALSE && nCnt <= nStop)
        {
            tShield = TalentSpell(nCnt);
            if(GetCreatureHasTalent(tShield))
            {
                bValid = TRUE;
            }
            else
            {
                nCnt++;
            }
        }
        //RWT-OEI 04/22/04 - Since shield powers aren't necessarially
        //incremental in order anymore, we need to catch some special
        //cases here:
        if ( !bValid ) {//One hasn't been found yet, try special cases
            tShield = TalentSpell( 132 ); //This is the Heat Shield
            if ( GetCreatureHasTalent( tShield ) ) {
                bValid = TRUE;
            }
            // JAB-OEI 7/2/04 added another special case
            if(!bValid)
            {
                tShield = TalentSpell( 257 ); // drexl shield
                if ( GetCreatureHasTalent( tShield ) ) {
                    bValid = TRUE;
                }
            }
        }
        if(bValid)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Clear 1700");
            ClearAllActions();
            ActionUseTalentOnObject(tShield, OBJECT_SELF);
            GN_SetSpawnInCondition(SW_FLAG_SHIELD_USED);
            return TRUE;
        }
        else
        {
            GN_MyPrintString("GENERIC DEBUG *************** Forcefield Search Fallthrough");
            GN_SetSpawnInCondition(SW_FLAG_SHIELD_USED);
            return FALSE;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Forcefield Search Fallthrough");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Resistance Activation
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    20 Resist Force
    41 Force Immunity
    Checks to see if the character has resist force
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 31, 2003
//:://////////////////////////////////////////////
//Makes the person activate Resist Elements and Resist Force.
int GN_ActivateResistances()
{
    int bValid = FALSE;
    if(GN_GetSpawnInCondition(SW_FLAG_RESISTANCES_APPLIED) == FALSE && !IsObjectPartyMember(OBJECT_SELF))
    {
        if(GetHitDice(GetFirstPC()) >= 15 || GN_GetSpawnInCondition(SW_FLAG_BOSS_AI))
        {
            talent tResist = TalentSpell(FORCE_POWER_RESIST_FORCE);
            talent tImmune = TalentSpell(FORCE_POWER_FORCE_IMMUNITY);
            talent tUse;
            if(GetCreatureHasTalent(tImmune))
            {
                tUse = tImmune;
                bValid = TRUE;
            }
            else if(GetCreatureHasTalent(tResist))
            {
                tUse = tResist;
                bValid = TRUE;
            }
            if(bValid == TRUE)
            {
                GN_MyPrintString("GENERIC DEBUG *************** Clear 1710");
                ClearAllActions();
                ActionUseTalentOnObject(tUse, OBJECT_SELF);
            }
            GN_SetSpawnInCondition(SW_FLAG_RESISTANCES_APPLIED);
        }
    }
    return bValid;
}
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Respond to Shout                                           ========  =       =   =======   =       =  =========   ========
//:: Copyright (c) 2001 Bioware Corp.                          =          =       =  =       =  =       =      =      =
//:://////////////////////////////////////////////             =          =       =  =       =  =       =      =      =
/*//                                                           =          =       =  =       =  =       =      =      =
    Catches the shouts and determines the best                 =========  =========  =       =  =       =      =      =========
    course of action for them                                          =  =       =  =       =  =       =      =              =
                                                                       =  =       =  =       =  =       =      =              =
    SetListenPattern(OBJECT_SELF, "GEN_I_WAS_ATTACKED", 1);            =  =       =  =       =  =       =      =              =
    SetListenPattern(OBJECT_SELF, "GEN_I_SEE_AN_ENEMY", 15);   ========   =       =   =======     ======       =      ========
*///
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 16, 2002
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void GN_RespondToShout(object oShouter, int nShoutIndex, object oIntruder = OBJECT_INVALID)
{
    GN_MyPrintShoutString("");
    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Respond to Shout Started for " + GN_ReturnDebugName(OBJECT_SELF));
    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Intruder Object = " + GN_ReturnDebugName(oIntruder));
    //RWT-OEI 10/08/04 - If we're neutral, we just don't want to respond to these
    //shouts. Ever. Seriously.
    if ( GetStandardFaction(OBJECT_SELF) == STANDARD_FACTION_NEUTRAL )
    {
        return;
    }
    int nFLAG; //This determines whether the object walksway points instead of attacking.
    int nPartyAI = GetPartyAIStyle(); //Determines how the party should react to intruders
    int nNPC_AI = GetNPCAIStyle(OBJECT_SELF); //Determines how the individual should react in combat
    //MODIFIED by Preston Watamaniuk May 9
    //Put this check into disable shouts being heard by people from different combat zones.
    if(GetLocalNumber(oShouter, SW_NUMBER_COMBAT_ZONE) == GetLocalNumber(OBJECT_SELF, SW_NUMBER_LAST_COMBO) ||
       GetLocalNumber(oShouter, SW_NUMBER_COMBAT_ZONE) == 0 ||
       GetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBAT_ZONE) == 0 ||
       IsObjectPartyMember(OBJECT_SELF))
    {
        if(!GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR)
           && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE)
           && !GN_GetSpawnInCondition(SW_FLAG_AI_OFF)
           && !GetUserActionsPending())
        {
            GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Check 1 Pass");
            if(nShoutIndex == 1 && GetIsFriend(oShouter) && oShouter != OBJECT_SELF)
            {
                if((IsObjectPartyMember(OBJECT_SELF) && IsObjectPartyMember(oShouter) && GetSoloMode() == FALSE) ||
                    !IsObjectPartyMember(OBJECT_SELF))
                {
                    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Check 2 Pass");
                    if(!GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()) && !GetIsObjectValid(GetAttackTarget()))
                    {
                        GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Check 3 Pass");
                        if(GetPartyMemberByIndex(0) != OBJECT_SELF && nPartyAI != PARTY_AISTYLE_PASSIVE && !GetPlayerRestrictMode())
                        {
                            GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Check 3 Pass");
                            if((IsObjectPartyMember(OBJECT_SELF) && !GetPlayerRestrictMode()) || !IsObjectPartyMember(OBJECT_SELF))
                            {
                                GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Check 5 Pass");
                                GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Intruder = " + GN_ReturnDebugName(oIntruder));
                                if(GetObjectSeen(oIntruder))
                                {
                                    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Shout: Determine Combat Round");
                                    GN_MyPrintString("GENERIC SHOUT DEBUG *************** Shout Clear 1800");
                                    ClearAllActions();
                                    GN_DetermineCombatRound(oIntruder);
                                }
                                else if(GetIsObjectValid(oIntruder))
                                {
                                    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Shout: Move To Intruder");
                                    GN_MyPrintString("GENERIC SHOUT DEBUG ***************= Shout Clear 1900");
                                    ClearAllActions();
                                    float fDistance = 5.0;
                                    /*
                                    if(!GetObjectSeen(oIntruder))
                                    {
                                        fDistance = 3.0;
                                    }
                                    */
                                    //P.W. (June 8) - Put this check in to try and reduce the instances of NPCs running right up
                                    //to their enemies with blasters.
                                    if(GetDistanceBetween(OBJECT_SELF, oIntruder) < 20.0 && !GetObjectSeen(oIntruder))
                                    {
                                        ActionMoveToObject(oIntruder, TRUE, 2.0);
                                    }
                                    else
                                    {
                                        if(GN_GetWeaponType(OBJECT_SELF) == 1)
                                        {
                                            ActionMoveToObject(oIntruder, TRUE, 4.0);
                                        }
                                        else
                                        {
                                            ActionMoveToObject(oIntruder, TRUE, 15.0);
                                        }
                                    }
                                }
                                //MODIFIED by Preston Watamaniuk on May 16th
                                //Added this check to make Party Members attack after the PC engages in combat.
                                else if(IsObjectPartyMember(OBJECT_SELF))
                                {
                                    oIntruder = GetAttackTarget(oShouter);
                                    GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Attack Intruder = " + GN_ReturnDebugName(oIntruder));
                                    if(GetIsObjectValid(oIntruder))
                                    {
                                        GN_DetermineCombatRound(oIntruder);
                                    }
                                    else
                                    {
                                        oIntruder = GetSpellTarget(oShouter);
                                        GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Spell Intruder = " + GN_ReturnDebugName(oIntruder));
                                        if(GetIsObjectValid(oIntruder))
                                        {
                                            GN_DetermineCombatRound(oIntruder);
                                        }
                                    }
                                }
                            }
                            //I AM IN COMBAT
                            else if(nShoutIndex == 15 && GetIsFriend(oShouter) && oShouter != OBJECT_SELF)
                            {
                                if(GetCurrentAction(OBJECT_SELF) == ACTION_INVALID)
                                {
                                    if(GetObjectSeen(oIntruder))
                                    {
                                        GN_MyPrintString("GENERIC SHOUT DEBUG *************** Clear 2000");
                                        ClearAllActions();
                                        GN_MyPrintShoutString("GENERIC SHOUT DEBUG *************** Attack Intruder = " + GN_ReturnDebugName(oIntruder));
                                        GN_DetermineCombatRound(oIntruder);
                                        //GN_SetSpawnInCondition(SW_FLAG_SHOUTED_AT);
                                    }
                                    else if(GetIsObjectValid(oIntruder))
                                    {
                                        GN_MyPrintString("GENERIC SHOUT DEBUG *************** Clear 2100");
                                        ClearAllActions();
                                        ActionMoveToObject(oIntruder, TRUE, 5.0);
                                        //GN_SetSpawnInCondition(SW_FLAG_SHOUTED_AT);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        else if(GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE))
        {
            GN_MyPrintString("GENERIC SHOUT DEBUG *************** Clear 2200");
            ClearAllActions();
            return;
        }
    }
    /*
    if(!GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR)
       && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE)
       && !GN_GetSpawnInCondition(SW_FLAG_AI_OFF))
    {
        if(GetPartyMemberByIndex(0) != OBJECT_SELF && nPartyAI != PARTY_AISTYLE_PASSIVE && !GetPlayerRestrictMode())
        {
            //P.W.(June 5) It looks stupid, but do not take this out.
            if(GetCurrentAction(OBJECT_SELF) == ACTION_QUEUEEMPTY && !GetUserActionsPending() && !IsObjectPartyMember(OBJECT_SELF))
            {
                if((IsObjectPartyMember(OBJECT_SELF) && IsObjectPartyMember(oShouter) && GetSoloMode() == FALSE) ||
                    !IsObjectPartyMember(OBJECT_SELF))
                {
                    GN_MyPrintString("GENERIC SHOUT DEBUG *************** Hail Mary activated by " + GN_ReturnDebugName(OBJECT_SELF));
                    GN_MyPrintString("GENERIC SHOUT DEBUG *************** Hail Mary Shout Clear 2110");
                    GN_DetermineCombatRound();
                }
            }
        }
    }
    */
    GN_MyPrintShoutString("");
}
//::///////////////////////////////////////////////
//:: SetListeningPatterns
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the correct listen checks on the NPC by
    determining what talents they possess or what
    class they use.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 24, 2001
//:://////////////////////////////////////////////
void GN_SetListeningPatterns()
{
    SetListening(OBJECT_SELF, TRUE);
    SetListenPattern(OBJECT_SELF, "GEN_I_WAS_ATTACKED", 1);
    SetListenPattern(OBJECT_SELF, "GEN_I_AM_DEAD", 3);
    SetListenPattern(OBJECT_SELF, "GEN_CALL_TO_ARMS", 6);
    if(GetHasSpell(FORCE_POWER_SUPRESS_FORCE) || GetHasSpell(FORCE_POWER_FORCE_BREACH))
    {
        SetListenPattern(OBJECT_SELF, "GEN_SUPRESS_FORCE", 9);
    }
    SetListenPattern(OBJECT_SELF, "GEN_GRENADE_TOSSED", 12);
    SetListenPattern(OBJECT_SELF, "GEN_I_SEE_AN_ENEMY", 14);
    SetListenPattern(OBJECT_SELF, "GEN_COMBAT_ACTIVE", 15);
    GN_SetUpWayPoints();
    // JAB-OEI 7/21/04
    // removed because we have a new treasure model in K2
    /*string sTag = GetTag(OBJECT_SELF);
    if(sTag != "Carth" &&
       sTag != "Bastila" &&
       sTag != "Cand" &&
       sTag != "HK47" &&
       sTag != "Jolee" &&
       sTag != "Juhani" &&
       sTag != "Mission" &&
       sTag != "T3M4" &&
       sTag != "Zaalbar" &&
       !GetIsPC(OBJECT_SELF))
    {
        DR_SpawnCreatureTreasure(OBJECT_SELF);
    }*/
    // end removal
    //MODIFIED by Preston Watamaniuk on May 8, 2003
    //Added functionality for dynamic or encounter creatures
    //to latch onto a Zone Controller.
    //GN_MyPrintString("ZONE DEBUG *****************" + IntToString(GetIsEncounterCreature()) + " " + GN_ReturnDebugName(OBJECT_SELF));
    if(GN_GetSpawnInCondition(SW_FLAG_DYNAMIC_COMBAT_ZONE) || GetIsEncounterCreature())
    {
        string sController;
        int nCount = 1;
        object oController, oTest;
        float fNear;
        float fClosest = 100.0;
        for(nCount; nCount < 40; nCount++)
        {
            if(nCount < 10)
            {
                sController = "ZoneController" + "0" + IntToString(nCount);
            }
            else
            {
                sController = "ZoneController" + IntToString(nCount);
            }
            oTest = GetObjectByTag(sController);
            if(GetIsObjectValid(oTest))
            {
                fNear = GetDistanceBetween(OBJECT_SELF, oTest);
                //GN_MyPrintString("ZONING DEBUG ***************** Controller Distance = " + GN_ReturnDebugName(oController) + " " + FloatToString(fNear, 4, 2));
                if(fNear < fClosest)
                {
                    fClosest = fNear;
                    oController = oTest;
                }
            }
        }
        if(GetIsObjectValid(oController) && fClosest < 30.0)
        {
            //GN_MyPrintString("ZONING DEBUG ***************** Setup Controller = " + GN_ReturnDebugName(oController));
            int nZone = StringToInt(GetStringRight(GetTag(oController), 2));
            SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBAT_ZONE, nZone);
        }
    }
}
//::///////////////////////////////////////////////
//:: Check for Poison
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks if someone in the party is poisoned.
    If the person is a non-party NPC then they
    check if they are poisoned.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
object GN_CheckIfPoisoned()
{
    GN_MyPrintString("GENERIC DEBUG *************** Starting Poison Check");
    effect ePoison;
    if(IsObjectPartyMember(OBJECT_SELF))
    {
        int nCnt = 0;
        for(nCnt; nCnt > 2; nCnt++)
        {
            ePoison = GetFirstEffect(GetPartyMemberByIndex(nCnt));
            while(GetIsEffectValid(ePoison))
            {
                if(GetEffectType(ePoison) == EFFECT_TYPE_POISON)
                {
                    return GetPartyMemberByIndex(nCnt);
                }
                ePoison = GetNextEffect(GetPartyMemberByIndex(nCnt));
            }
        }
    }
    else
    {
        ePoison = GetFirstEffect(OBJECT_SELF);
        while(GetIsEffectValid(ePoison))
        {
            if(GetEffectType(ePoison) == EFFECT_TYPE_POISON)
            {
                return OBJECT_SELF;
            }
            ePoison = GetNextEffect(OBJECT_SELF);
        }
    }
    GN_MyPrintString("GENERIC DEBUG ***************  Returning Invalid Poison Object");
    return OBJECT_INVALID;
}
//::///////////////////////////////////////////////
//:: Check for Injuries
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns member index +1 or false depending on
    whether the object belongs in the PCs party.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
object GN_CheckIfInjured()
{
    GN_MyPrintString("GENERIC DEBUG ***************  Starting Injury Check Function");
//RWT-OEI 03/03/04 - Took out this check that used the TYPE_DROID racial query. It didn't make
//  a bit of sense. Having it in there made it so that NPC droids are checking Party Characters
//  to determine if they are injured, instead of just looking at their own condition.
//  Removing this check made it so that droids will use Repair Kits on themselves now.
//    if(IsObjectPartyMember(OBJECT_SELF) || GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID)
    if(IsObjectPartyMember(OBJECT_SELF))
    {
        object oP0=GetPartyMemberByIndex(0);
        object oP1=GetPartyMemberByIndex(1);
        object oP2=GetPartyMemberByIndex(2);
        float fDown00 = 10.0;
        float fDown01 = 10.0;
        float fDown02 = 10.0;
        if(GetIsObjectValid(oP0) && GetRacialType(oP0) != RACIAL_TYPE_DROID)
        {
            fDown00 = IntToFloat(GetCurrentHitPoints(oP0)) / IntToFloat(GetMaxHitPoints(oP0));
        }
        if(GetIsObjectValid(oP1)&& GetRacialType(oP0) != RACIAL_TYPE_DROID)
        {
            fDown01 = IntToFloat(GetCurrentHitPoints(oP1)) / IntToFloat(GetMaxHitPoints(oP1));
        }
        if(GetIsObjectValid(oP2) && GetRacialType(oP0) != RACIAL_TYPE_DROID)
        {
            fDown02 = IntToFloat(GetCurrentHitPoints(oP2)) / IntToFloat(GetMaxHitPoints(oP2));
        }
        if(GetIsObjectValid(oP0) && !GetIsDead(oP0) && (fDown00 < 0.5 && fDown00 > 0.0))
        {
            GN_MyPrintString("GENERIC DEBUG ***************  Return oP0");
            return oP0;
        }
        else if(GetIsObjectValid(oP1) && !GetIsDead(oP1) && (fDown00 < 0.5 && fDown00 > 0.0))
        {
            GN_MyPrintString("GENERIC DEBUG ***************  Return oP1");
            return oP1;
        }
        else if(GetIsObjectValid(oP2) && !GetIsDead(oP2) && (fDown00 < 0.5 && fDown00 > 0.0))
        {
            GN_MyPrintString("GENERIC DEBUG ***************  Return oP2");
            return oP2;
        }
    }
    else
    {
        float fNPC = IntToFloat(GetCurrentHitPoints(OBJECT_SELF)) / IntToFloat(GetMaxHitPoints(OBJECT_SELF));
        if(fNPC < 0.5)
        {
            return OBJECT_SELF;
        }
    }
    return OBJECT_INVALID;
}
//RWT-OEI 09/03/04
//Returns TRUE if any of the party members are knocked out.
//Only works if OBJECT_SELF is in the party.
int GN_CheckIfKnockedOut()
{
    object oCurPlayer;
    int i = 0;
    for (i = 0; i < 3; ++i )
    {
        oCurPlayer = GetPartyMemberByIndex(i);
        if ( GetIsObjectValid(oCurPlayer) )
        {
            if ( GetCurrentHitPoints(oCurPlayer) < 1 )
            {
                return TRUE;//Someone is knocked out
            }
        }
    }
    return FALSE;//No one is knocked out
}
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Generic Talent Routines
//:: Copyright (c) 2001 Bioware Corp.
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int GN_TalentMasterRoutine(int nTalentConstant, object oTarget)
{
    if(GetIsObjectValid(oTarget))
    {
        talent tSpe11_01, tSpe11_02, tSpe11_03, tSpe11_04, tSpe11_05, tSpe11_06, tSpe11_07, tUse;
        int nTalent;
        int bValid = FALSE;
        int bHostile = FALSE;
        if(nTalentConstant == GEN_TALENT_SUPRESS_FORCE)
        {
            nTalent = 0xf021; //Any Area, No Harmful, Dispel, Ranged
        }
        else if(nTalentConstant == GEN_TALENT_REMOVE_POISON)
        {
            bValid = FALSE;
            tSpe11_01 = TalentSpell(FORCE_POWER_HEAL);
            tSpe11_02 = TalentSpell(FORCE_POWER_CURE);
            tSpe11_03 = TalentSpell(67); //Remove Poison Item
            // DJS-OEI 12/11/2003
            tSpe11_04 = TalentSpell(FORCE_POWER_MASTER_HEAL);
            if(GetCreatureHasTalent(tSpe11_01) || GetCreatureHasTalent(tSpe11_02) || GetCreatureHasTalent(tSpe11_04) )
            {
                bValid = TRUE;
                if(GetCreatureHasTalent(tSpe11_01))
                {
                    tUse = tSpe11_01;
                }
                else if(GetCreatureHasTalent(tSpe11_02))
                {
                    tUse = tSpe11_02;
                }
                else if(GetCreatureHasTalent(tSpe11_04))
                {
                    tUse = tSpe11_04;
                }
            }
            else if(GetCreatureHasTalent(tSpe11_03) && oTarget == OBJECT_SELF)
            {
                bValid = TRUE;
                tUse = tSpe11_03;
            }
            //nTalent = 0xff4f;
        }
        else if(nTalentConstant == GEN_TALENT_HEALING)
        {
            bValid = FALSE;
            GN_MyPrintString("GENERIC DEBUG *************** Starting Heal Talent Checks " + GN_ReturnDebugName(OBJECT_SELF));
            tSpe11_01 = TalentSpell(FORCE_POWER_HEAL);
            tSpe11_02 = TalentSpell(FORCE_POWER_CURE);
            // DJS-OEI 12/11/2003
            tSpe11_03 = TalentSpell(FORCE_POWER_MASTER_HEAL);
            if(GetRacialType(OBJECT_SELF) != RACIAL_TYPE_DROID)
            {
                tSpe11_05 = GetCreatureTalentBest(0x1408, 20);
            }
            else
            {
                tSpe11_05 = TalentSpell(128);
                if(!GetCreatureHasTalent(tSpe11_05))
                {
                    tSpe11_05 = TalentSpell(127);
                    if(!GetCreatureHasTalent(tSpe11_05))
                    {
                        tSpe11_05 = TalentSpell(84);
                    }
                }
            }
            tSpe11_06 = TalentSpell(FORCE_POWER_DRAIN_LIFE);
            tSpe11_07 = TalentSpell(FORCE_POWER_DEATH_FIELD);
            tUse;
            bValid = FALSE;
            if(GetCreatureHasTalent(tSpe11_01) || GetCreatureHasTalent(tSpe11_02) || GetCreatureHasTalent(tSpe11_03) )
            {
                GN_MyPrintString("GENERIC DEBUG *************** I have Heal, Improved Heal, or Master Heal");
                bValid = TRUE;
                if(GetCreatureHasTalent(tSpe11_03))
                {
                    tUse = tSpe11_03;
                }
                else if(GetCreatureHasTalent(tSpe11_01))
                {
                    tUse = tSpe11_01;
                }
                else if(GetCreatureHasTalent(tSpe11_02))
                {
                    tUse = tSpe11_02;
                }
            }
            //else if(GetIsTalentValid(tSpe11_05) ||
            else if(GetCreatureHasTalent(tSpe11_05) ||
                    GetCreatureHasTalent(tSpe11_06) ||
                    GetCreatureHasTalent(tSpe11_07))
            {
                if(oTarget == OBJECT_SELF)
                {
                    if(GetCreatureHasTalent(tSpe11_07) && !IsObjectPartyMember(OBJECT_SELF))
                    {
                        GN_MyPrintString("GENERIC DEBUG *************** I have Death Field");
                        bValid = TRUE;
                        bHostile = TRUE;
                        tUse = tSpe11_07;
                    }
                    else if(GetCreatureHasTalent(tSpe11_06) && !IsObjectPartyMember(OBJECT_SELF))
                    {
                        GN_MyPrintString("GENERIC DEBUG *************** I have Drain Life");
                        bValid = TRUE;
                        bHostile = TRUE;
                        tUse = tSpe11_06;
                    }
                    else
                    {
                        GN_MyPrintString("GENERIC DEBUG *************** I have a Med Pack");
                        bValid = TRUE;
                        tUse = tSpe11_05;
                    }
                }
            }
        }
        else if (nTalentConstant == GEN_TALENT_REVITALIZE)
        {
            int nID = GN_GetSeriesRevitalize();
            tUse = TalentSpell(nID);
            bValid = TRUE;
            bHostile = FALSE;
            AurPostString( "Setting up to revitalize.", 20, 26, 5.0f );
        }
        else if(nTalentConstant == GEN_TALENT_BUFF)
        {
            bValid = FALSE;
            //RWT-OEI 10/11/04 - Rewriting this lame function all together.
            //Basically we need to try the different buffs, see if the creature
            //has them, then see if they're already applied. In theory.
            //We need to come up with random spells out of all possible
            //ones. First we'll grab a spell category.
            int nSpellTree = 0;
            talent tBuff_01;
            talent tBuff_02;
            talent tBuff_03;
            talent tBuff_04;
            talent tBuff_05;
            talent tBuff_06;
            if ( GetFirstPC() == OBJECT_SELF )
            {
                //If we're the player character, there's 3 spell trees
                //only we can get, so we want a higher random number.
                nSpellTree = Random(10000) % 9;
            }
            else
            {
                nSpellTree = Random(10000) % 6;
            }
            //First get the 3 possible spells.
            //*ALWAYS* set all 3 spells, even if you need to just
            //duplicate one multiple times, we don't want any of the 3
            //being left over from anything else
            //AurPostString( "Going for tree #" + IntToString(nSpellTree), 20, 30, 2.0f );
            if ( nSpellTree == 0 ) //Speed
            {
                tBuff_01 = TalentSpell(8);// Speed Burst
                tBuff_02 = TalentSpell(34);//Knight Speed
                tBuff_03 = TalentSpell(37);//Master Speed
            }
            else if ( nSpellTree == 1 ) //Armor
            {
                tBuff_01 = TalentSpell(18);//Aura
                tBuff_02 = TalentSpell(24);//Shield
                tBuff_03 = TalentSpell(17);//Armor
            }
            else if ( nSpellTree == 2 ) //Valor
            {
                tBuff_01 = TalentSpell(22);//Valor
                tBuff_02 = TalentSpell(33);//Knight Valor
                tBuff_03 = TalentSpell(36);//Master Valor
            }
            else if ( nSpellTree == 3 ) //Energy Resist
            {
                tBuff_01 = TalentSpell(42);//Energy Resist 1
                tBuff_02 = TalentSpell(40);//Energy Resist 2
                tBuff_03 = TalentSpell(133);//Master energy resist
            }
            else if ( nSpellTree == 4 ) //Barrier
            {
                tBuff_01 = TalentSpell(135);//Force Barrier
                tBuff_02 = TalentSpell(136);//Improved Barrier
                tBuff_03 = TalentSpell(137);//Master Force Barrier
            }
            else if ( nSpellTree == 5 ) //Battle Meditation
            {
                tBuff_01 = TalentSpell(138);//Battle Meditation
                tBuff_02 = TalentSpell(139);//Improved Meditation
                tBuff_03 = TalentSpell(140);//Master Meditation
            }
            else if ( nSpellTree == 6 ) // Crush Opposition
            {
                tBuff_01 = TalentSpell(144);//Crush Opposition I
                tBuff_02 = TalentSpell(145);//Crush Opposition II
                tBuff_03 = TalentSpell(146);//Crush Opposition III
                tBuff_04 = TalentSpell(147);//Crush Opposition IV
                tBuff_05 = TalentSpell(148);//Crush Opposition V
                tBuff_06 = TalentSpell(149);//Crush Opposition VI
            }
            else if ( nSpellTree == 7 ) //Inspire Followers
            {
                tBuff_01 = TalentSpell(167);//Inspire I
                tBuff_02 = TalentSpell(168);//Inspire II
                tBuff_03 = TalentSpell(169);//Inspire III
                tBuff_04 = TalentSpell(170);//Inspire IV
                tBuff_05 = TalentSpell(171);//Inspire V
                tBuff_06 = TalentSpell(172);//Inspire VI
            }
            else if ( nSpellTree == 8 ) // Fury
            {
                tBuff_01 = TalentSpell(164);//Fury
                tBuff_02 = TalentSpell(165);//Improved Fury
                tBuff_03 = TalentSpell(166);//Master Fury
            }
            //Now we have set all the tBuff_## to point to the possible
            //spells for this random roll.
            //Next determine if we even have any of them and if so to
            //set the level of the one we're using in tTemp
            talent tTemp;
            if ( GetIsTalentValid(tBuff_06) &&
                 GetCreatureHasTalent(tBuff_06) )
            {
                tTemp = tBuff_06;
            }
            else if ( GetIsTalentValid(tBuff_05) &&
                      GetCreatureHasTalent(tBuff_06) )
            {
                tTemp = tBuff_05;
            }
            else if ( GetIsTalentValid(tBuff_04) &&
                      GetCreatureHasTalent(tBuff_04) )
            {
                tTemp = tBuff_04;
            }
            else if ( GetIsTalentValid(tBuff_03) &&
                      GetCreatureHasTalent(tBuff_03) )
            {
                tTemp = tBuff_03;
            }
            else if ( GetIsTalentValid(tBuff_02) &&
                      GetCreatureHasTalent(tBuff_02) )
            {
                tTemp = tBuff_02;
            }
            else if ( GetIsTalentValid( tBuff_01 ) &&
                      GetCreatureHasTalent(tBuff_01) )
            {
                tTemp = tBuff_01;
            }
            //Once we get to this point, if tTemp is VALID, then we
            //have picked out a potential buff to cast. Now see if its
            //effects are already active on the creature or not.
            //In order to do that we need to loop through the active effects
            //and see if they came from this specific talent.
            if ( GetIsTalentValid( tTemp ))
            {
                int nSpellID = GetIdFromTalent(tTemp);
                effect eCurEffect = GetFirstEffect(OBJECT_SELF);
                int nCounter = 0;
                while ( GetIsEffectValid(eCurEffect) )
                {
                    nCounter++;
                    if ( GetEffectSpellId(eCurEffect) == nSpellID )
                    {
                        //AurPostString( "I already have talent #" + IntToString( nSpellID ), 20, 31,2.0f );
                        tTemp = TalentSpell(-1);//Set tTemp invalid
                        break;
                    }
                    eCurEffect = GetNextEffect(OBJECT_SELF);
                }
            }
            //If we get down to here, and tTemp is STILL valid, then it is
            //the spell we should cast
            if ( GetIsTalentValid( tTemp ) )
            {
                int nCost = GetSpellBaseForcePointCost(GetIdFromTalent(tTemp));
                if ( nCost <= GetCurrentForcePoints())
                {
                    bValid = TRUE;
                    tUse = tTemp;
                }
            }
/*
            tSpe11_01 = TalentSpell(36); //Master Valor
            tSpe11_02 = TalentSpell(33); //Knight Valor
            tSpe11_03 = TalentSpell(22); //Valor
            int bBuff = FALSE;
            if(GetCreatureHasTalent(tSpe11_01))
            {
                bBuff = TRUE;
                tUse = tSpe11_01;
            }
            else if(GetCreatureHasTalent(tSpe11_02))
            {
                bBuff = TRUE;
                tUse = tSpe11_02;
            }
            else if(GetCreatureHasTalent(tSpe11_03))
            {
                bBuff = TRUE;
                tUse = tSpe11_03;
            }
            GN_MyPrintString("GENERIC DEBUG *************** Spell Effect 22" + GN_ITS(GetHasSpellEffect(22)));
            GN_MyPrintString("GENERIC DEBUG *************** Spell Effect 33" + GN_ITS(GetHasSpellEffect(33)));
            GN_MyPrintString("GENERIC DEBUG *************** Spell Effect 36" + GN_ITS(GetHasSpellEffect(36)));
            if(!GetHasSpellEffect(22) &&
               !GetHasSpellEffect(33) &&
               !GetHasSpellEffect(36) &&
               bBuff == TRUE)
            {
                GN_MyPrintString("GENERIC DEBUG *************** I do have VALOR");
                bValid = TRUE;
            }
            else
            {
                GN_MyPrintString("GENERIC DEBUG *************** I do not have VALOR");
                bValid = FALSE;
            }
*/
        }
        if(bValid == TRUE && bHostile == FALSE)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Clear 2300");
            int nSpell = GetIdFromTalent(tUse);
            GN_MyPrintString("GENERIC DEBUG *************** Spells.2DA ID = " + GN_ITS(nSpell));
            ClearAllActions();
            ActionUseTalentOnObject(tUse, OBJECT_SELF);
            return TRUE;
        }
        else if(bValid == TRUE && bHostile == TRUE)
        {
            oTarget = GN_GetActivePartyMember(TRUE);
            if(GetIsObjectValid(oTarget))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Hostile Heal Targeted On: " + GN_ReturnDebugName(oTarget));
                GN_MyPrintString("GENERIC DEBUG *************** Clear 2400");
                ClearAllActions();
                ActionUseTalentOnObject(tUse, oTarget);
                return TRUE;
            }
        }
        talent tUse2 = GetCreatureTalentBest(nTalent, 20);
        if(GetIsTalentValid(tUse) && !GetHasSpellEffect(GetIdFromTalent(tUse)))
        {
            if(GetIsObjectValid(oTarget))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Clear 2500");
                ClearAllActions();
                GN_MyPrintString("GENERIC DEBUG *************** Target = " + GetName(oTarget) + " Talent Code = " + IntToString(nTalent));
                ActionUseTalentOnObject(tUse, OBJECT_SELF);
                return TRUE;
            }
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** " + GN_ReturnDebugName(OBJECT_SELF) + " VP = " + GN_ITS(GetCurrentHitPoints())+ "/" + GN_ITS(GetMaxHitPoints()) );
    GN_MyPrintString("GENERIC DEBUG *************** Healing Not Used");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Last Round Setup
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the following struct up so that Last Rounds
    information is easier to access.
    int nLastAction;
    int nLastActionID;
    int nLastTalentCode;
    object oLastTarget;
    int nTalentSuccessCode;
    int nIsLastTargetDebil;
    int nLastCombo;
    int nLastComboIndex;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 26, 2002
//:://////////////////////////////////////////////
void GN_SetLastRoundData()
{
     talent tTalent;
     tPR.oLastTarget = GetLastHostileTarget();
     tPR.nIsLastTargetDebil = GetIsDebilitated(tPR.oLastTarget);
     tPR.nLastAction = GetLastAttackAction();
     if(tPR.nLastAction == ACTION_CASTSPELL)
     {
        tPR.nLastActionID = GetLastForcePowerUsed();
        tPR.nTalentSuccessCode = GetWasForcePowerSuccessful();
        tTalent = TalentSpell(tPR.nLastActionID);
        tPR.nLastTalentCode = GetCategoryFromTalent(tTalent);
     }
     else if(tPR.nLastAction == ACTION_ATTACKOBJECT)
     {
        tPR.nLastActionID = GetLastCombatFeatUsed();
        tPR.nTalentSuccessCode = GetLastAttackResult();
        tTalent = TalentFeat(tPR.nLastActionID);
        tPR.nLastTalentCode = GetCategoryFromTalent(tTalent);
     }
     //tPR.nLastCombo = GetLocalNumber(OBJECT_SELF, SW_NUMBER_LAST_COMBO);
     tPR.nLastComboIndex = GetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX);
     tPR.nCurrentCombo = GetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE);
}
//::///////////////////////////////////////////////
//:: Combo Sub Routine
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This function determines what move to do
    based on the last part of the combo performed.
    int nLastAction;
    int nLastActionID;
    int nLastTalentCode;
    object oLastTarget;
    int nTalentSuccessCode;
    int nIsLastTargetDebil;
    int nLastCombo;
    int nLastComboIndex;
    int nCurrentCombo;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 27, 2002
//:://////////////////////////////////////////////
talent GN_GetComboMove(int nBoss = FALSE)
{
    int nRand;
    int nCombo;
    talent tUse;
    int nNPC_AI = GetNPCAIStyle(OBJECT_SELF); //Determines how the individual should react in combat
    GN_MyPrintString("GENERIC DEBUG *************** Starting GetComboMove");
    // FAK - OEI 3/4/04
    // enemy droids with utitlies and no blasters, always use them
    object oItem =   GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON);
    if ( (GetLevelByClass(CLASS_TYPE_COMBATDROID) > 0 ||
                    GetLevelByClass(CLASS_TYPE_EXPERTDROID) > 0)
          && !GN_CheckNPCIsInParty(OBJECT_SELF)
          && !GetIsObjectValid(oItem)
        )
    {
        object oItem1 = GetItemInSlot(INVENTORY_SLOT_LEFTARM);
        object oItem2 = GetItemInSlot(INVENTORY_SLOT_RIGHTARM);
        int    bValid = 1;
        int iCooldown = GetLocalNumber(OBJECT_SELF, SW_NUMBER_COOLDOWN);
        int iCooldownThresh = GetLocalNumber(OBJECT_SELF, SW_NUMBER_COOLDOWN_FIRE);
        if (iCooldownThresh <= 0 || iCooldownThresh >= 10)
        {
            iCooldownThresh = 6;
        }
        if (GetIsObjectValid(oItem1))
        {
            nCombo = SW_COMBO_DROID_UTILITIES;
        }
        else if (GetIsObjectValid(oItem2))
        {
            nCombo = SW_COMBO_DROID_UTILITIES_2;
        }
        else
        {
            bValid = 0;
        }
        iCooldown = iCooldown + 1;
        SetLocalNumber(OBJECT_SELF, SW_NUMBER_COOLDOWN, iCooldown);
        if (bValid && iCooldown >= iCooldownThresh)
        {
            SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, 3);
            SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE, nCombo);
            SetLocalNumber(OBJECT_SELF, SW_NUMBER_COOLDOWN, 0);
            return GN_GetNextTalentInCombo(nCombo);
        }
        else
        {
            SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, 0);
            SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE, SW_COMBO_INVALID);
        }
    }
    //Is the last combo done?
    if(tPR.nLastComboIndex == 4 || tPR.nLastComboIndex == 0)
    {
        //If so then set the local numbers controlling the combo to 0;
        SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, 0);
        SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE, 0);
        nRand = d6();
        if(nRand > 0)//This nRand check is place here in case we need to limit combo use later
        {
            //If a Jedi use the jedi routines.
            if(GetLevelByClass(CLASS_TYPE_JEDICONSULAR) > 0 ||
               GetLevelByClass(CLASS_TYPE_JEDIGUARDIAN) > 0 ||
               GetLevelByClass(CLASS_TYPE_JEDISENTINEL) > 0 ||
               GetLevelByClass(CLASS_TYPE_JEDIWEAPONMASTER) > 0 ||  // DJS-OEI 8/19/2004
               GetLevelByClass(CLASS_TYPE_JEDIMASTER) > 0 ||
               GetLevelByClass(CLASS_TYPE_JEDIWATCHMAN) > 0 ||
               GetLevelByClass(CLASS_TYPE_SITHMARAUDER) > 0 ||
               GetLevelByClass(CLASS_TYPE_SITHLORD) > 0 ||
               GetLevelByClass(CLASS_TYPE_SITHASSASSIN) > 0 )
            {
                nCombo = GN_GetStandardJediCombo(nBoss);
                GN_MyPrintString("GENERIC DEBUG *************** Starting Jedi Combo " + GN_FetchComboString(nCombo));
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, 1);
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE, nCombo);
                return GN_GetNextTalentInCombo(nCombo);
            }
            //If a Droid use these routines
            else if(GetLevelByClass(CLASS_TYPE_COMBATDROID) > 0 ||
                    GetLevelByClass(CLASS_TYPE_EXPERTDROID) > 0)
            {
                nCombo = GN_GetStandardDroidCombo(nBoss);
                GN_MyPrintString("GENERIC DEBUG *************** Starting Droid Combo " + GN_FetchComboString(nCombo));
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, 1);
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE, nCombo);
                return GN_GetNextTalentInCombo(nCombo);
            }
            //All others.
            else
            {
                nCombo = GN_GetStandardNPCCombo(nBoss);
                GN_MyPrintString("GENERIC DEBUG *************** Starting NPC Combo " + GN_FetchComboString(nCombo));
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, 1);
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_ROUTINE, nCombo);
                return GN_GetNextTalentInCombo(nCombo);
            }
        }
        else//returning an invalid Talent here will mean action attack.
        {
            return tUse;
        }
    }
    else//if(tPR.nTalentSuccessCode > 0)
    {
        //If the PC is already in a combo then continue that combo
        GN_MyPrintString("GENERIC DEBUG *************** Continuing Combo " + GN_FetchComboString(tPR.nCurrentCombo));
        return GN_GetNextTalentInCombo(tPR.nCurrentCombo);
    }
    return tUse;
}
//::///////////////////////////////////////////////
//:: Check Droid Utility Usage
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the target and the droid utility use
    to make sure they are compatible
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 22, 2003
//:://////////////////////////////////////////////
talent GN_CheckDroidUtilityUsage(object oTarget, talent tUse)
{
    int bSwitch;
    GN_MyPrintString("GENERIC DEBUG *************** Starting Droid Talent Double Check");
    if(GetTypeFromTalent(tUse) == TALENT_TYPE_FORCE)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Droid Talent is a Spell");
        if(GetIdFromTalent(tUse) == 116 || GetIdFromTalent(tUse) == 117) //STUN RAY
        {
            if(GetRacialType(oTarget) == RACIAL_TYPE_HUMAN)
            {
                return tUse;
            }
            else
            {
                bSwitch = TRUE;
            }
        }
        if(GetIdFromTalent(tUse) == 118 || GetIdFromTalent(tUse) == 119) //SHIELD DISRUPTOR
        {
            if(GetHasSpellEffect(99, oTarget) || GetHasSpellEffect(100, oTarget) || GetHasSpellEffect(101, oTarget) ||
               GetHasSpellEffect(102, oTarget) || GetHasSpellEffect(103, oTarget) || GetHasSpellEffect(104, oTarget) ||
               GetHasSpellEffect(105, oTarget) || GetHasSpellEffect(106, oTarget) || GetHasSpellEffect(107, oTarget) ||
               GetHasSpellEffect(110, oTarget) || GetHasSpellEffect(111, oTarget) || GetHasSpellEffect(112, oTarget) ||
               GetHasSpellEffect(113, oTarget) || GetHasSpellEffect(114, oTarget) || GetHasSpellEffect(115, oTarget))
            {
                return tUse;
            }
            else
            {
                bSwitch = TRUE;
            }
        }
    }
    if(bSwitch == TRUE)
    {
        // DJS-OEI 4/26/2004
        // All of the Ranged combat Feats are 0x1111, not
        // 0x1181. This was causing droids, for instance,
        // to never use their Ranged Feats.
        //talent tFeat = GetCreatureTalentBest(0x1181, 20);
        talent tFeat = GetCreatureTalentBest(0x1111, 20);
        if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
        {
            return tFeat;
        }
        else
        {
            talent Invalid;
            return Invalid;
        }
    }
    return tUse;
}
//::///////////////////////////////////////////////
//:: Throw Lightsaber Check
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the target and the force power to make
    sure that a lightsaber is not thrown from close
    range.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 24, 2003
//:://////////////////////////////////////////////
talent GN_CheckThrowLightSaberUsage(object oTarget, talent tUse)
{
    int bSwitch = FALSE;
    if(GetTypeFromTalent(tUse) == TALENT_TYPE_FORCE)
    {
        if(GetIdFromTalent(tUse) == FORCE_POWER_LIGHT_SABER_THROW || GetIdFromTalent(tUse) == FORCE_POWER_LIGHT_SABER_THROW_ADVANCED)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Lightsaber Throw Check = " + FloatToString(GetDistanceBetween(OBJECT_SELF, oTarget),4,2));
            if(GetDistanceBetween(OBJECT_SELF, oTarget) < 10.0)
            {
                bSwitch = TRUE;
            }
        }
    }
    if(bSwitch == TRUE)
    {
        talent tFeat = GetCreatureTalentBest(0x1104, 20);
        if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
        {
            return tFeat;
        }
        else
        {
            talent Invalid;
            return Invalid;
        }
    }
    return tUse;
}
//::///////////////////////////////////////////////
//:: Check Droid Force Power Usage
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the force power and makes sure it can
    be used on a droid.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On:May 12, 2003
//:://////////////////////////////////////////////
talent GN_CheckNonDroidForcePower(object oTarget, talent tUse)
{
    int bSwitch = FALSE;
    if(GetTypeFromTalent(tUse) == TALENT_TYPE_FORCE)
    {
        if(GetIdFromTalent(tUse) == FORCE_POWER_HOLD ||
           GetIdFromTalent(tUse) == FORCE_POWER_HORROR ||
           GetIdFromTalent(tUse) == FORCE_POWER_INSANITY ||
           GetIdFromTalent(tUse) == FORCE_POWER_KILL ||
           GetIdFromTalent(tUse) == FORCE_POWER_PLAGUE ||
           GetIdFromTalent(tUse) == FORCE_POWER_SLEEP ||
           GetIdFromTalent(tUse) == FORCE_POWER_SLOW ||
           GetIdFromTalent(tUse) == FORCE_POWER_STUN ||
           GetIdFromTalent(tUse) == FORCE_POWER_WOUND ||
           GetIdFromTalent(tUse) == FORCE_POWER_AFFLICTION ||
           GetIdFromTalent(tUse) == FORCE_POWER_CHOKE ||
           GetIdFromTalent(tUse) == FORCE_POWER_DEATH_FIELD ||
           GetIdFromTalent(tUse) == FORCE_POWER_DRAIN_LIFE ||
           GetIdFromTalent(tUse) == FORCE_POWER_FEAR ||
           GetIdFromTalent(tUse) == FORCE_POWER_FORCE_SCREAM || // DJS-OEI 8/19/2004
           GetIdFromTalent(tUse) == FORCE_POWER_IMPROVED_FORCE_SCREAM || // DJS-OEI 8/19/2004
           GetIdFromTalent(tUse) == FORCE_POWER_MASTER_FORCE_SCREAM // DJS-OEI 8/19/2004
           )
        {
            if(GetRacialType(oTarget) == RACIAL_TYPE_DROID)
            {
                bSwitch = TRUE;
            }
        }
    }
    if(bSwitch == TRUE)
    {
        talent tFeat = GetCreatureTalentBest(0x1104, 20);
        if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
        {
            return tFeat;
        }
        else
        {
            talent Invalid;
            return Invalid;
        }
    }
    return tUse;
}
//::///////////////////////////////////////////////
//:: Play Ambient Animations
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Play the correct animations based on the
    spawn in condition selected.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 4, 2002
//:://////////////////////////////////////////////
void GN_PlayAmbientAnimation()
{
    if(!GetIsInConversation(OBJECT_SELF))
    {
        location lLocal;
        vector vFrnd;
        int nRoll = d2();
        object oFriend = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nRoll, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
        if(!GetIsObjectValid(oFriend))
        {
            oFriend = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, OBJECT_SELF, nRoll, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
        }
        object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
        int nHDMe = GetHitDice(OBJECT_SELF);
        int nHDOther = GetHitDice(oFriend);
        if(!GN_CheckShouldFlee() || !GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR))
        {
            if(GN_GetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS))
            {
                vFrnd = GetPosition(oFriend);
                nRoll = d6();
                if(GetIsObjectValid(oFriend) && GetDistanceBetween(oFriend, OBJECT_SELF) < 5.0 && !IsObjectPartyMember(oFriend))
                {
                    SetFacingPoint(vFrnd);
                    GN_MyPrintString("GENERIC DEBUG *************** Clear 2600");
                    ClearAllActions();
                    if(nRoll == 1 || nRoll == 2)
                    {
                        ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 3.0);
                    }
                    else if(nRoll == 3)
                    {
                        ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING, 1.0, 3.0);
                    }
                    else if(nRoll == 4)
                    {
                        ActionPlayAnimation(ANIMATION_LOOPING_TALK_FORCEFUL, 1.0, 3.0);
                    }
                    else if(nRoll == 5)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT);
                    }
                    else if(nRoll == 6)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT);
                    }
                }
                else
                {
                    nRoll = d8();
                    if(nRoll == 1)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_BORED, 1.0);
                    }
                    else if(nRoll == 2)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0);
                    }
                    else if(nRoll == 3)
                    {
                        ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 3.0);
                    }
                    else if(nRoll == 4 || nRoll == 5)
                    {
                        if(GetGender(OBJECT_SELF) == GENDER_MALE)
                        {
                            GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
                            ActionPlayAnimation(ANIMATION_LOOPING_PAUSE3, 1.0, 20.4);
                            ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
                        }
                        else if(GetGender(OBJECT_SELF) == GENDER_FEMALE)
                        {
                            GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
                            ActionPlayAnimation(ANIMATION_LOOPING_PAUSE3, 1.0, 13.3);
                            ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
                        }
                    }
                    else if(nRoll == 6)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT);
                    }
                    else if(nRoll == 7)
                    {
                        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT);
                    }
                    else if(nRoll == 8)
                    {
                        GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
                        ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 5.0);
                        ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
                    }
                }
            }
            else if(GN_GetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS_MOBILE))
            {
                nRoll = d8();
                GN_MyPrintString("GENERIC DEBUG *************** Clear 2700");
                ClearAllActions();
                if(nRoll == 1)
                {
                    ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 2.0);
                }
                else if(nRoll == 2)
                {
                    ActionPlayAnimation(ANIMATION_FIREFORGET_TAUNT, 1.0);
                }
                else if(nRoll == 3)
                {
                    //ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT, 0.75);
                    //ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT, 0.75);
                }
                else if(nRoll == 4)
                {
                    ActionPlayAnimation(ANIMATION_FIREFORGET_VICTORY1, 1.0);
                }
                else if(nRoll >= 5)
                {
                    ActionRandomWalk();
                }
            }
        }
        else if(GN_CheckShouldFlee() && GN_GetSpawnInCondition(SW_FLAG_COMMONER_BEHAVIOR))
        {
            GN_CommonAI();
        }
    }
}
//::///////////////////////////////////////////////
//:: Commoner AI
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    If ever engaged in combat they will flee.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 18, 2002
//:://////////////////////////////////////////////
int GN_CommonAI()
{
    GN_MyPrintString("GENERIC DEBUG *************** Start Commoner AI");
    object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
    object oFlee;
    int bValid = TRUE;
    int nIdx = 1;
    object oNeutral = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL);
    while(GetIsObjectValid(oNeutral) && bValid == TRUE)
    {
        if(GetStandardFaction(oNeutral) == STANDARD_FACTION_HOSTILE_1 ||
            GetStandardFaction(oNeutral) == STANDARD_FACTION_HOSTILE_2 ||
            GetStandardFaction(oNeutral) == STANDARD_FACTION_INSANE)
        {
            if(GetDistanceBetween(OBJECT_SELF, oNeutral) <= 20.0)
            {
                oFlee = oNeutral;
                bValid = FALSE;
            }
            nIdx++;
            oNeutral = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, OBJECT_SELF, nIdx);
        }
        else
        {
            nIdx++;
            oNeutral = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, OBJECT_SELF, nIdx);
        }
    }
    if(GetIsObjectValid(oEnemy))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Clear 2710");
        ClearAllActions();
        ActionMoveAwayFromObject(oEnemy, TRUE, 20.0);
        DelayCommand(0.2, ActionDoCommand(GN_ActionDoPostDCRChecks()));
        return TRUE;
    }
    else if(GetIsObjectValid(oFlee))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Object Flee = " + GN_ReturnDebugName(oFlee));
        GN_MyPrintString("GENERIC DEBUG *************** Clear 2720");
        ClearAllActions();
        ActionMoveAwayFromObject(oFlee, TRUE, 20.0);
        DelayCommand(0.2, ActionDoCommand(GN_ActionDoPostDCRChecks()));
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Should Commoner Flee
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks a number of conditions for a commoner
    to flee.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 20, 2002
//:://////////////////////////////////////////////
int GN_CheckShouldFlee()
{
    int nIdx = 1;
    object oNeutral = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
    object oHostile = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
    while(GetIsObjectValid(oNeutral) || GetIsObjectValid(oHostile))
    {
        if(GetIsObjectValid(oHostile))
        {
            return TRUE;
        }
        if(GetIsObjectValid(oNeutral))
        {
            if(GetStandardFaction(oNeutral) == STANDARD_FACTION_HOSTILE_1 ||
                GetStandardFaction(oNeutral) == STANDARD_FACTION_HOSTILE_2 ||
                GetStandardFaction(oNeutral) == STANDARD_FACTION_INSANE)
            {
                return TRUE;
            }
        }
        nIdx++;
        oNeutral = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_NEUTRAL, OBJECT_SELF, nIdx, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Reset Deactivated Droid
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Resets a Droid to his deactivated animation
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 25, 2003
//:://////////////////////////////////////////////
void GN_ResetDroidDeactivationState(object oDroid = OBJECT_SELF)
{
    /*
    GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT, FALSE);
    ClearAllActions();
    ActionPlayAnimation(ANIMATION_LOOPING_DEACTIVATE, 1.0, 900.0);
    ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT, TRUE));
    */
    ClearAllActions();
    ActionPlayAnimation(ANIMATION_LOOPING_DEACTIVATE, 1.0, -1.0);
    GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT, FALSE);
}
//::///////////////////////////////////////////////
//:: Determine Attack Target
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the nearest seen target and oIntruder
    for a valid attack target.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 7, 2002
//:://////////////////////////////////////////////
object GN_DetermineAttackTarget(object oIntruder = OBJECT_INVALID)
{
    GN_MyPrintString("GENERIC DEBUG *************** Starting: Determine Attack Target");
    int nPartyAI = GetPartyAIStyle();
    int nNPC_AI = GetNPCAIStyle(OBJECT_SELF);
    object oTarget;
    object oLastTarget = GetLastHostileTarget();
    GN_MyPrintString("GENERIC DEBUG *************** Intruder = " + IntToString(GetIsObjectValid(oIntruder)) + " Last Target = " + IntToString(GetIsObjectValid(oLastTarget)));
    if(GetIsObjectValid(oIntruder) && !GetIsDead(oIntruder) && !GetIsDebilitated(oIntruder))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Intruder Target Returned = " + ObjectToString(oIntruder));
        return oIntruder;
    }
    else if(GetIsObjectValid(oLastTarget) && !GetIsDead(oLastTarget) && !GetIsDebilitated(oLastTarget))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Last Target Returned = " + ObjectToString(oIntruder));
        return oLastTarget;
    }
    else
    {
        if(nPartyAI == PARTY_AISTYLE_AGGRESSIVE)
        {
            int nCnt = 1;
            GN_MyPrintString("GENERIC DEBUG *************** Getting nearest target - 249");
            object oATarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
            oTarget = oATarget;
            while(!GetIsDebilitated(oTarget) && GetIsObjectValid(oTarget))
            {
                nCnt++;
                oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
            }
            if(!GetIsObjectValid(oTarget) && GetIsObjectValid(oATarget))
            {
                oTarget = oATarget;
            }
        }
        else if(nPartyAI == PARTY_AISTYLE_DEFENSIVE)
        {
            int nCnt = 0;
            object oHostile;
            while(!GetIsObjectValid(oHostile) && nCnt < 3)
            {
                oHostile = GetLastHostileActor(GetPartyMemberByIndex(nCnt));
                nCnt++;
            }
            if(GetIsObjectValid(oHostile))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Getting nearest target - 262");
                oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
            }
            else
            {
                oHostile = GetLastHostileTarget(GetPartyMemberByIndex(0));
                if(GetIsObjectValid(oHostile))
                {
                    GN_MyPrintString("GENERIC DEBUG *************** Getting nearest target - 269");
                    oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
                }
            }
        }
        else if(nPartyAI != PARTY_AISTYLE_PASSIVE)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Getting nearest target - 275");
            oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
        }
        else
        {
            GN_MyPrintString("GENERIC DEBUG *************** Getting nearest target - 279");
            oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
        }
    }
    if(GetIsObjectValid(oTarget))
    {
        GN_MyPrintString("GENERIC DEBUG *************** Attack Target From Determine Attack Target = " + GN_ReturnDebugName(oTarget));
        return oTarget;
    }
    GN_MyPrintString("GENERIC DEBUG *************** No Attack Targets Found");
    return OBJECT_INVALID;
}
//::///////////////////////////////////////////////
//:: Return Talent Code
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This function determines the state of the selected
    attack target and what should be done to them.
    If the target is last rounds target then they
    will try not to use failed attack types.
    NOTE: The functionality for area attacks and
    specialized talent use will be coded here.
    For the time being, I will just try to get
    the appropriate cascade of talents being used.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetAttackTalentCode(object oTarget)
{
    GN_MyPrintString("GENERIC DEBUG *************** Starting: Getting Talent Attack Code");
    int nPreviousTalentCode;
    //GN_MyPrintString("GENERIC DEBUG *************** Cooked Return Code  0x0100");
    GN_MyPrintString("GENERIC DEBUG *************** Debilitated = " + IntToString(GetIsDebilitated(oTarget)));
    if(!GetIsDead(oTarget) && GetIsObjectValid(oTarget) && !GetIsDebilitated(oTarget) && GetLastHostileTarget() == oTarget)
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Talent Code: Before GetPreviousTalent");
        nPreviousTalentCode = GN_GetPreviousTalentCode();
        //GN_MyPrintString("GENERIC DEBUG *************** Talent Code: Before If Compare");
        if(GN_CompareTalents(nPreviousTalentCode, 0xf2ff))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Talent Code: 0xff1f");
            if(GN_GetHasViableTalent(0xff1f))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Return Code 0xff1f");
                return 0xff1f;
            }
            if(GN_GetHasViableTalent(0x0100))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf1ff");
                return 0xf1ff;
            }
        }
        else if(GN_CompareTalents(nPreviousTalentCode, 0xff1f))
        {
            if(GN_GetHasViableTalent(0xf1f0))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf1ff");
                return 0xf1ff;
            }
        }
    }
    else if(!GetIsDead(oTarget) && GetIsObjectValid(oTarget) && !GetIsDebilitated(oTarget) && GetLastHostileTarget() != oTarget)
    {
        if(GN_GetHasViableTalent(0xf3ff))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf3ff");
            return 0xf3ff;
        }
        if(GN_GetHasViableTalent(0xf2ff))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf2ff");
            return 0xf2ff;
        }
        if(GN_GetHasViableTalent(0xff1f))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xff1f");
            return 0xff1f;
        }
        if(GN_GetHasViableTalent(0xf1ff))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf1ff");
            return 0xf1ff;
        }
    }
    else if(!GetIsDead(oTarget) && GetIsObjectValid(oTarget) && GetIsDebilitated(oTarget))
    {
        if(GN_GetHasViableTalent(0xf1ff))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xf1ff");
            return 0xf1ff;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Return Code  0xffff");
    return 0xffff;
}
//this function was cut from the generics but is needed
//here to keep scripts from breaking.
void GN_SetDayNightPresence(int nPresenceSetting)
{
}
//RWT-OEI 07/16/04 - Set the amount of damage the exploding, floating
//mine will do.
void GN_SetFloatingMineDamage( int nDamage )
{
    SetLocalNumber( OBJECT_SELF, SW_NUMBER_HEALERAI_THRESHOLD, nDamage );
}
//RWT-OEI 07/16/04 - Set the Range that the mine will start seeking
void GN_SetFloatingMineSeekRange( int nRange )
{
    SetLocalNumber( OBJECT_SELF, SW_NUMBER_HEALERAI_PERCENTAGE, nRange );
}
//RWT-OEI 08/28/04 - GN_CheckRangeFromLeader()
//Keeps the party members within a certain number of meters
//from the party leader when they are in combat.
int GN_CheckRangeFromLeader(float fDistanceLimit)
{
    //This only works on party NPCs.
    if (!IsObjectPartyMember(OBJECT_SELF))
    {
        return 0;
    }
    object oLeader = GetPartyLeader();
    //Make sure we're not the party leader, though
    //this should never happen anyway
    if (OBJECT_SELF == oLeader)
    {
        return 0;
    }
    //Make sure we're not dead.
    if ( GetCurrentHitPoints(OBJECT_SELF) < 1 )
    {
        return 0;
    }
    //Compare distance
    float fCurDistance = GetDistanceToObject2D(oLeader);
    if ( fCurDistance <= fDistanceLimit )
    {
        //AurPostString( "Close enough.", 10,31,5.0f );
        return 0;//We're close enough.
    }
    //If we get here, we're too far from the party leader.
    //See if we are actively moving. If so, leave alone.
    //If not, make us move to leader.
    int nActionID = GetCurrentAction(OBJECT_SELF);
    if ( nActionID == ACTION_MOVETOPOINT )
    {
        //AurPostString( "Actively trying to move to leader.", 10, 34, 2.0f );
        //Leave alone
        return 1;
    }
    //If we get here, we're too far away and are not
    //actively moving, so need a new moveto action
    //AurPostString( "Moving to leader.", 10, 32, 2.0f );
    ClearAllActions();
    ActionMoveToObject(oLeader, TRUE, fDistanceLimit / 2.0f);
    return 1;
}
//RWT_OEI 09/08/04 - GN_CheckRangeFromOwner()
//Keeps party puppets within a certain number of meters from their
//owner when they are in combat.
int GN_CheckRangeFromOwner(float fDistanceLimit)
{
    //Only works on party puppets
    if ( !GetIsPuppet(OBJECT_SELF) )
    {
        return 0;
    }
    object oOwner = GetPUPOwner(OBJECT_SELF);
    if ( !GetIsObjectValid(oOwner) )
    {
        AurPostString( "PUPAI - Unable to find owner. Major error",20, 30, 5.0f );
        return 0;
    }
    //Puppets can never die, so we don't need to bother checking if we're dead.
    //So now move on to comparing distances.
    float fCurDistance = GetDistanceToObject2D(oOwner);
    if ( fCurDistance <= fDistanceLimit )
    {
        //Close enough.
        return FALSE;
    }
    //If we get here, we're too far from the owner.
    //See if we are actively moving. If so, leave alone.
    //If not, make us follow the owner.
    int nActionID = GetCurrentAction(OBJECT_SELF);
    if ( nActionID == ACTION_MOVETOPOINT ||
         nActionID == ACTION_FOLLOWOWNER )
    {
        return TRUE;
    }
    //If we get here, we're too far away and are not
    //actively moving, so need a new followowner action.
    ClearAllActions();
    ActionFollowOwner(2.0f);
    return TRUE;
}
//RWT-OEI 08/28/04 - GN_RangedSupport
//Tries to use ranged weapons, but will switch to melee
//weapons if the 2nd config has melee and they are being
//attacked by someone using melee.
int GN_RunRangedSupportAIRoutine(object oIntruder)
{
    //This only works on party NPCs.
    if (!IsObjectPartyMember(OBJECT_SELF))
    {
        return 0;
    }
    object oLeader = GetPartyLeader();
    //Make sure we're not the party leader, though
    //this should never happen anyway
    if (OBJECT_SELF == oLeader)
    {
        return 0;
    }
    //Make sure we're not dead.
    if ( GetCurrentHitPoints(OBJECT_SELF) < 1 )
    {
        return 0;
    }
    //If this returns TRUE, then it is handling a weapon
    //swapping action this round and we shouldn't do
    //anything else.
    //RWT-OEI 11/01/04 - Only check this if we're in Ranged
    //Suport Mode
    int nCurAI = GetNPCAIStyle(OBJECT_SELF);
    if ( nCurAI == NPC_AISTYLE_PARTY_RANGED )
    {
        if ( GN_CheckRangedPreferred() )
        {
            return 0;
        }
    }
    //If we get here, we need to just go ahead with our normal
    //attack behaviors.
    GN_RunDefaultAIRoutine(oIntruder);
    return 0;
}
//RWT-OEI 08/28/04
//For Party NPCs, will determine if they should switch
//to a Melee configuration or ranged configuration if
//the options are available to them.
//Return 1 if we weren't using the right weapon but were
//able to queue an action to correct it.
//Return 0 if we are using the right weapon or were unable
//to find a better configuration.
int GN_CheckRangedPreferred()
{
    //The main point of this AI function is to
    //try and use ranged as much as possible.
    //So... if we haven't been attacked by
    //melee for X rounds, switch to ranged if we have it
    //If we have been attacked by melee in the last
    //X rounds, switch to melee if we have it.
    //I'm using the LocalNumbers I added for HealerAI
    //since we're not on healer AI if we're here, obviously.
    //int SW_NUMBER_HEALERAI_THRESHOLD = 8;
    //int SW_NUMBER_HEALERAI_PERCENTAGE = 9;
    //1 = Melee
    //2 = Ranged
    int nHitByMelee = GetLocalNumber(OBJECT_SELF, SW_NUMBER_HEALERAI_THRESHOLD);
    if ( nHitByMelee > 0 )
    {
        //AurPostString( "We have been hit by melee.", 20,21,2.0f);
        nHitByMelee--;
        SetLocalNumber(OBJECT_SELF, SW_NUMBER_HEALERAI_THRESHOLD, nHitByMelee);
        //Make sure we are using melee weapons right now
        object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON);
        int nType = 0;
        if ( GetIsObjectValid(oWeapon))
        {
            nType = GN_GetWeaponTypeFromBaseItem(GetBaseItemType(oWeapon));
        }
        //AurPostString( IntToString(nType),20,22,2.0f);
        if ( nType == 2 )
        {
            //We are using ranged but getting hit by melee. See if we
            //should switch to the second config
            object oWeapon2 = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON2);
            int nType2 = 0;
            if ( GetIsObjectValid(oWeapon2) )
            {
                nType2 = GN_GetWeaponTypeFromBaseItem(GetBaseItemType(oWeapon2));
            }
            //AurPostString( IntToString(nType2),20,23,2.0f);
            if ( nType2 != 2 )
            {
                //Our second config is NOT ranged, switch to it
                //AurPostString( "Ranged ----> Melee",20,24,2.0f);
                ClearAllActions();
                ActionSwitchWeapons();
                return 1;
            }
            //Otherwise the other slot is no better, can't do anything.
        }//Otherwise we're not using ranged right now, so stick with what
         //we're using.
     }
     else
     {  //If we haven't been hit by Melee in the last X number of rounds
        //(see KOTOR_HENCH_EVENT_ON_ATTACKED in k_ai_master for the exact
        //number of rounds) then make sure we're using a ranged configuration
        //if we have one
        //AurPostString( "We have not been hit by melee recently", 20, 25, 2.0f);
        object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON);
        int nType = 0;
        if ( GetIsObjectValid(oWeapon))
        {
            nType = GN_GetWeaponTypeFromBaseItem(GetBaseItemType(oWeapon));
        }
        //AurPostString(IntToString(nType),20,26,2.0f);
        if ( nType != 2 )
        {
            //We're not using a ranged weapon right now, so see if we have
            //ranged in our other config
            object oWeapon2 = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON2);
            int nType2 = 0;
            if ( GetIsObjectValid(oWeapon2) )
            {
                nType2 = GN_GetWeaponTypeFromBaseItem(GetBaseItemType(oWeapon2));
            }
            //AurPostString(IntToString(nType2),20,27,2.0f);
            if ( nType2 == 2 )
            {
                //2nd slot has ranged, so switch to it.
                //AurPostString( "Melee ----> Ranged",20,28,2.0f);
                ClearAllActions();
                ActionSwitchWeapons();
                return 1;
            }
        }//Otherwise our other slot doesn't have ranged either
    }//Otherwise we're already using ranged
    //AurPostString( "Couldn't improve any",20,29,2.0f);
    //If we get here, there was nothing we could do here or
    //everything was already ideal, so just return 0.
    return 0;
}
//RWT-OEI 08/28/04 - GN_IsJedi
//Returns true if the object passed in has one
//of the many Jedi classes.
int GN_IsJedi(object oObject )
{
    if ( GetLevelByClass(CLASS_TYPE_JEDICONSULAR) > 0 )
        return 1;
    if ( GetLevelByClass(CLASS_TYPE_JEDIGUARDIAN) > 0 )
        return 1;
    if ( GetLevelByClass(CLASS_TYPE_JEDISENTINEL) > 0)
        return 1;
    if ( GetLevelByClass(CLASS_TYPE_JEDIWEAPONMASTER) > 0 )
        return 1;
    if ( GetLevelByClass(CLASS_TYPE_JEDIMASTER) > 0 )
        return 1;
    if ( GetLevelByClass(CLASS_TYPE_JEDIWATCHMAN) > 0 )
        return 1;
    if ( GetLevelByClass(CLASS_TYPE_SITHMARAUDER) > 0 )
        return 1;
    if ( GetLevelByClass(CLASS_TYPE_SITHLORD) > 0 )
        return 1;
    if ( GetLevelByClass(CLASS_TYPE_SITHASSASSIN) > 0 )
        return 1;
    return 0;//Not a Jedi.
}
//RWT-OEI 09/08/04
//GN_RuNDefaultPuppetAIRoutine()
//This function decides and executes all
//functions that are not related to staying close
//to the owner.
//In otherwords, the AI should never get to this
//function unless they are already safely within
//range of their owner
int GN_RunDefaultPuppetAIRoutine(object oIntruder)
{
    //AurPostString( "Default Puppet AI", 20, 20, 2.0f );
    //If we're not a party puppet, just run default AI routines
    if ( !GetIsPuppet(OBJECT_SELF) )
    {
        GN_RunDefaultAIRoutine(oIntruder);
        return 0;
    }
    //If the owner is disabled, don't do anything
    object oOwner = GetPUPOwner(OBJECT_SELF);
    if ( !GetIsObjectValid(oOwner) )
    {
        return 0;//This is a major error
    }
    if ( GetCurrentHitPoints(oOwner) < 1 )
    {
        //Owner is disabled, so shut down
        //AurPostString( "Owner is down.", 20, 22, 2.0f );
        ClearAllActions();
        return 0;
    }
    else
    {
        //AurPostString( "Owner has HP: " + IntToString(GetCurrentHitPoints(oOwner)), 20, 21, 2.0f);
    }
    //First priority is to heal any droids in the party that are in need
    //of healing.
    //This var is used to determine which droid
    //in the party to heal, if any.
    object oHealDroid = OBJECT_INVALID;
    int nThreshold = GetLocalNumber(OBJECT_SELF, SW_NUMBER_HEALERAI_THRESHOLD);
    int nRand = Random(200) % 2;
    if ( nThreshold > 0  && nRand == 1)
    {
        //Check to see if any of the party member droids are damaged.
        //AurPostString( "Checking need to heal.", 20, 20, 4.0f );
        int i = 0;
        for (i = 0; i < 3; ++i )
        {
            object oMember = GetPartyMemberByIndex(i);
            if ( GetIsObjectValid(oMember) )
            {
                if ( GetRacialType(oMember) == RACIAL_TYPE_DROID )
                {
                    int nCurrentHP = GetCurrentHitPoints(oMember);
                    int nMaxHP = GetMaxHitPoints(oMember);
                    int nPercentage = (nCurrentHP * 100) / nMaxHP;
                    if ( nPercentage < nThreshold && nCurrentHP > 0 )
                    {
                        AurPostString( "Found wounded droid in party:" + IntToString(nPercentage) + "/" + IntToString( nThreshold ), 20, 21, 4.0f );
                        //Make sure they're within 10 meters.
                        //TODO: Enable this check once we're confident in the rest.
                        if ( GetDistanceToObject2D(oMember) <= 10.0f )
                        {
                           // AurPostString( "Setting ohealdroid to:" + GetTag(oMember),20,24,4.0f );
                            oHealDroid = oMember;
                            //break;
                        }
                    }
                }
            }
        }
        //AurPostString( "Damaged droid is: " + GetTag(oHealDroid), 20, 25, 4.0f );
        if ( GetIsObjectValid(oHealDroid) )
        {
            ClearAllActions();
            //AurPostString( "Attempting to heal.", 20, 22, 4.0f );
            //If we get here, then we have a valid droid in the party that
            //is in need of healing. Go ahead and take care of it.
            int nHealAmount = GetLocalNumber(OBJECT_SELF, SW_NUMBER_HEALERAI_PERCENTAGE);
            if ( nHealAmount < 1 )
            {
                nHealAmount = 10;
            }
            //Face the right direction
            SetFacingPoint(GetPosition(oHealDroid));
            int nCurrentHP = GetCurrentHitPoints(oHealDroid);
            int nMaxHP = GetMaxHitPoints(oHealDroid);
            //Don't heal over 100% health.
            if ( (nMaxHP - nCurrentHP ) < nHealAmount )
            {
                nHealAmount = nMaxHP - nCurrentHP;
            }
            effect eHeal = EffectHeal( nHealAmount );
            ApplyEffectToObject( DURATION_TYPE_INSTANT, eHeal, oHealDroid);
            effect eBeam = EffectBeam( VFX_BEAM_STUN_RAY, OBJECT_SELF, BODY_NODE_HAND);
            ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eBeam, oHealDroid, 1.0f );
            effect eHealField = EffectVisualEffect( 1048 );
            ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eHealField, oHealDroid, 3.0f );
            //Jump out now as this was our action for this round.
            return 0;
        }
    }
    //If owner is in combat, attack his target by default
    if ( !GetIsInCombat(oOwner) )
    {
        return 0;//Don't do any attacks if the owner isn't in combat.
    }
    object oTarget = GetLastHostileTarget(oOwner);
    if ( GetIsObjectValid( oTarget ) && GetObjectSeen(oTarget,OBJECT_SELF))
    {
        //AurPostString( "Ordering an attack.", 20, 23, 2.0f );
        //We have a valid target. Go ahead and attack it too.
        ActionAttack(oTarget);
    }
    return 0;
}
""",
    "k_inc_gensupport": b"""//:: k_inc_gensupport
/*
    v1.0
    Support Include for k_inc_generic
    NOTE - To get these functions
    use k_inc_generic
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
//BOSS ATTACK TYPES
int SW_BOSS_ATTACK_TYPE_GRENADE = 1;
int SW_BOSS_ATTACK_TYPE_FORCE_POWER = 2;
int SW_BOSS_ATTACK_TYPE_NPC = 3;
int SW_BOSS_ATTACK_TYPE_PC = 4;
int SW_BOSS_ATTACK_ANY = 5;
int SW_BOSS_ATTACK_DROID = 6;
//LOCAL NUMBERS
int SW_NUMBER_COMBO_ROUTINE = 3;
int SW_NUMBER_COMBO_INDEX = 4;
int SW_NUMBER_LAST_COMBO = 5;
int SW_NUMBER_ROUND_COUNTER = 6;
int SW_NUMBER_COMBAT_ZONE = 7;
int SW_NUMBER_HEALERAI_THRESHOLD = 8;
int SW_NUMBER_HEALERAI_PERCENTAGE = 9;
int SW_NUMBER_COOLDOWN = 10; // fak - oei, rounds before firing again
int SW_NUMBER_COOLDOWN_FIRE = 11; // fak - oei, threshold at which turret fires
//COMBO CONSTANTS
int SW_COMBO_RANGED_FEROCIOUS = 1;
int SW_COMBO_RANGED_AGGRESSIVE = 2;
int SW_COMBO_RANGED_DISCIPLINED = 3;
int SW_COMBO_RANGED_CAUTIOUS = 4;
int SW_COMBO_MELEE_FEROCIOUS = 5;
int SW_COMBO_MELEE_AGGRESSIVE = 6;
int SW_COMBO_MELEE_DISCIPLINED = 7;
int SW_COMBO_MELEE_CAUTIOUS = 8;
int SW_COMBO_BUFF_PARTY = 9;
int SW_COMBO_BUFF_DEBILITATE = 10;
int SW_COMBO_BUFF_DAMAGE = 11;
int SW_COMBO_BUFF_DEBILITATE_DESTROY = 12;
int SW_COMBO_SUPRESS_DEBILITATE_DESTROY = 13;
int SW_COMBO_SITH_ATTACK = 14;
int SW_COMBO_BUFF_ATTACK = 15;
int SW_COMBO_SITH_CONFOUND = 16;
int SW_COMBO_JEDI_SMITE = 17;
int SW_COMBO_SITH_TAUNT = 18;
int SW_COMBO_SITH_BLADE = 19;
int SW_COMBO_SITH_CRUSH = 20;
int SW_COMBO_JEDI_CRUSH = 21;
int SW_COMBO_SITH_BRUTALIZE = 22;
int SW_COMBO_SITH_DRAIN = 23;
int SW_COMBO_SITH_ESCAPE = 24;
int SW_COMBO_JEDI_BLITZ = 25;
int SW_COMBO_SITH_SPIKE = 26;
int SW_COMBO_SITH_SCYTHE = 27;
int SW_COMBO_SITH_FURY = 28;
int SW_COMBO_JEDI_FOCUS = 29;
int SW_COMBO_DROID_UTILITIES = 30;
int SW_COMBO_DROID_UTILITIES_2 = 31;
int SW_COMBO_INVALID = 32;
// DJS-OEI 3/31/2004
// Modified to make room for designer-reserved values.
//int SW_FLAG_TARGET_FRIEND = 59;
int SW_FLAG_TARGET_FRIEND = 84;
//****SUPPORT FUNCTIONS FOR THE GENERICS**************************************************************************
//Returns the number targets attacking the passed in object
int GN_GetAttackers(object oTarget);
//Returns the index of the party member passed in or false if the object is not a party member.
int GN_CheckNPCIsInParty(object oNPC);
//Checks whether the attempted spell or attack targets are true
int GN_CheckAttemptedSpellAttackTarget();
//Determines if the object has a valid attempted spell or attack target or a valid attack target.
int GN_GetIsFighting(object oFighting);
//Compares to talent codes to see if specific bits are true.
int GN_CompareTalents(int nTalent1, int nTalent2);
// Returns the talent code for the previous round.
int GN_GetPreviousTalentCode();
//Takes a spell constant and passes back the code
int GN_GetSpellTalentCode(int nSpell);
//Takes a feat constant and passes back the code
int GN_GetFeatTalentCode(int nFeat);
//Searchs for viable talents that can be used by the user and passes back yes or no according to whether one is found.
int GN_GetHasViableTalent(int nTalentCode);
//Returns the exclusion code for the talent based on the racial type of the creature passed in.
int GN_GetExclusionCode(object oTarget);
//This takes a combo constant and returns a talent.
talent GN_GetNextTalentInCombo(int nCombo);
//Determines if a combo is valid for the object in question
int GN_GetIsComboValid(int nComboType);
//Does the Jedi have a damaging Force Power
int GN_GetHasDamagingForcePower();
//Gets a random combo for a default AI Jedi
int GN_GetStandardJediCombo(int nBoss = FALSE);
//Gets a random combo for a default AI Droid
int GN_GetStandardDroidCombo(int nBoss = FALSE);
//Gets a random combo for a default AI NPC
int GN_GetStandardNPCCombo(int nBoss = FALSE);
// Returns 2 for Ranged and 1 for Melee weapons, checking the basetype
int GN_GetWeaponType(object oTarget = OBJECT_SELF);
//RWT-OEI 08/28/04
//Returns 1 if base item is ranged, returns 2 if base item
//is melee, returns 0 if item is not a weapon
int GN_GetWeaponTypeFromBaseItem(int nBaseType);
//Gets the NPC to eqyuip a melee = 1 or ranged = 2 weapon.
int GN_EquipAppropriateWeapon();
//Returns a talent for the boss to perform in combat.
talent GN_GetBossCombatMove(int nBossAttackType, int nDroid = FALSE);
//Get Boss AOE Force Powers
talent GN_GetAOEForcePower(int nDroid = FALSE);
//Get Boss Single Target Force Powers
talent GN_GetTargetedForcePower(int nDroid = FALSE);
//Returns the number of party members who are active
int GN_GetActivePartyMemberCount();
//Returns the active party member who is not Member(0)
object GN_GetActivePartyMember(int nDrainTarget = FALSE);
//This function returns an active party member. They must not be dead.  The debilitated parameter will
//ignore those party members already debilitated.
object GN_ReturnActivePartyMember(int nDebil = FALSE);
//****VERIFICATION FOR COMMANDS FOR COMBOS**************************************************************************
//Check Push Series
int GN_CheckSeriesForcePush();
//Check Armor Series
int GN_CheckSeriesArmor();
//Check Fear Series
int GN_CheckSeriesFear();
//Check Hold Series
int GN_CheckSeriesHold();
//Check Poison Series
int GN_CheckSeriesAfflict();
//Check Saber Throw Series
int GN_CheckSeriesSaberThrow();
//Check Lightning Series
int GN_CheckSeriesLightning();
//Check Jump Series
int GN_CheckSeriesJump();
//Check Choke Series
int GN_CheckSeriesChoke();
//Check Drain Life Series
int GN_CheckSeriesDrainLife();
//Check Speed Series
int GN_CheckSeriesSpeed();
//Checks if the droid has utility items
int GN_CheckSeriesDroidUtilities();
//Checks Mind Series
int GN_CheckSeriesMind();
//Checks Resist Series
int GN_CheckSeriesResist();
//Checks Force Immunity Series();
int GN_CheckSeriesForceImmunity();
//Checks the Breach Series
int GN_CheckSeriesBreach();
// DJS-OEI 8/19/2004
//Checks the Heal Series
int GN_CheckSeriesHeal();
//Checks the Barrier Series
int GN_CheckSeriesBarrier();
//Checks the Battle Meditation Series
int GN_CheckSeriesBattleMeditation();
//Checks the Drain Force Series
int GN_CheckSeriesDrainForce();
//Checks the Scream Series
int GN_CheckSeriesScream();
//Checks the Fury series
int GN_CheckSeriesFury();
//Checks the revitalize series
int GN_CheckSeriesRevitalize();
//****GET COMMANDS FOR COMBOS**************************************************************************
//Fetch Series Force Push Power
int GN_GetSeriesForcePush();
//Fetch Series Force Armor Power
int GN_GetSeriesForceArmor();
//Fetch Series Fear Power
int GN_GetSeriesFear();
//Fetch Series Hold Power
int GN_GetSeriesHold();
//Fetch Series Afflict Power
int GN_GetSeriesAfflict();
//Fetch Series Saber Throw Power
int GN_GetSeriesSaberThrow();
//Fetch Series Lightning Power
int GN_GetSeriesLightning();
//Fetch Series Jump Power
int GN_GetSeriesJump();
//Fetch Series Choke Power
int GN_GetSeriesChoke();
//Fetch Series Drain Life Power
int GN_GetSeriesDrainLife();
//Fetch Series Speed Power
int GN_GetSeriesSpeed();
//Fetch Melee Feat
int GN_GetSeriesMeleeFeat();
//Fetch Ranged Feat
int GN_GetSeriesRangedFeat();
//Fetch Mind Series
int GN_GetSeriesMind();
//Fetch Resist Series
int GN_GetSeriesResist();
//Fetch Force Immunity Series();
int GN_GetSeriesForceImmunity();
//Fetch the Breach Series
int GN_GetSeriesBreach();
//Fetch the Fury series
int GN_GetSeriesFury();
//Fetch the Revitalize series
int GN_GetSeriesRevitalize();
// DJS-OEI 8/19/2004
//Fetch the Heal Series
int GN_GetSeriesHeal();
//Fetch the Barrier Series
int GN_GetSeriesBarrier();
//Fetch the Battle Meditation Series
int GN_GetSeriesBattleMeditation();
//Fetch the Drain Force Series
int GN_GetSeriesDrainForce();
//Fetch the Scream Series
int GN_GetSeriesScream();
//****DEBUG COMMANDS FOR THE GENERICS**************************************************************************
//Basically, a wrapper for AurPostString
void GN_PostString(string sString = "",int x = 10,int y = 10,float fShow = 4.0);
//Makes the object running the script say a speak string.
void GN_MySpeakString(string sString);
//Makes the nearest PC say a speakstring.
void GN_AssignPCDebugString(string sString);
//Inserts a print string into the log file for debugging purposes.
void GN_MyPrintString(string sString);
//Prints to the log file the shout received by a target.
void GN_PrintShoutType(object oShouter, int nShout);
//Returns the object ID and name appended to each other.
string GN_ReturnDebugName(object oTarget);
//Returns a string of the combo being used.
string GN_FetchComboString(int nCombo);
//Checks the friendly fire on the target out to 3.5m by default.
int GN_CheckFriendlyFireOnTarget(object oTarget, float fDistance = 4.0);
//Checks the enemies around a target object.
int GN_CheckEnemyGroupingOnTarget(object oTarget, float fDistance = 4.0);
//Searches the area and marks a group as a viable target for a grenade
object GN_FindGrenadeTarget();
//Searches the area and marks a group as a viable target for a AOE force power
object GN_FindAOETarget();
//Returns a grenade appropriate to the target
talent GN_GetGrenadeTalent(int nDroid = FALSE);
//Returns the AI style in a string
string GN_ReturnAIStyle(object oTarget = OBJECT_SELF);
//Prints a string from a int
string GN_ITS(int sFutureString);
//These debug commands are used for debugging shouts only
void GN_PostShoutString(string sString = "",int x = 10,int y = 10,float fShow = 4.0);
//These debug commands are used for debugging shouts o
void GN_MyPrintShoutString(string sString);
//::///////////////////////////////////////////////
//:: Get Attackers
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the number objects attacking the object;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
int GN_GetAttackers(object oTarget)
{
    int nCnt = 0;
    object oAttacker = GetFirstAttacker(oTarget);
    while(GetIsObjectValid(oAttacker))
    {
        nCnt++;
        oAttacker = GetNextAttacker(oTarget);
    }
    return nCnt;
}
//::///////////////////////////////////////////////
//:: Am I a party member
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns member index +1 or false depending on
    whether the object belongs in the PCs party.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
int GN_CheckNPCIsInParty(object oNPC)
{
    if(GetPartyMemberByIndex(0) == oNPC)
    {
        return 1;
    }
    else if(GetPartyMemberByIndex(1) == oNPC)
    {
        return 2;
    }
    else if(GetPartyMemberByIndex(2) == oNPC)
    {
        return 3;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: GetAttempted Spell or Attack Target State
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns true if the spell or attack target is
    true
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 8, 2002
//:://////////////////////////////////////////////
int GN_CheckAttemptedSpellAttackTarget()
{
    object oAttack = GetAttemptedAttackTarget();
    object oSpell = GetAttemptedSpellTarget();
    if(GetIsObjectValid(oAttack) || GetIsObjectValid(oSpell))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: GetIsFighting
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks if the passed object has an Attempted
    Attack or Spell Target
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
int GN_GetIsFighting(object oFighting)
{
    object oAttack = GetAttemptedAttackTarget();
    object oSpellTarget = GetAttemptedSpellTarget();
    object oAttacking = GetAttackTarget();
    object oMove = GetAttemptedMovementTarget();
    if(GetTag(OBJECT_SELF) == "DEBUG")
    {
        GN_ReturnDebugName(OBJECT_SELF);
        GN_PostString("Attempted Attack Target = " + IntToString(GetIsObjectValid(oAttack)), 10,20, 4.0);
        GN_PostString("Attempted Spell Target = " + IntToString(GetIsObjectValid(oSpellTarget)), 10,22, 4.0);
        GN_PostString("Attack Target = " + IntToString(GetIsObjectValid(oAttacking)), 10,24, 4.0);
        GN_PostString("Move Target = " + IntToString(GetIsObjectValid(oMove)), 10,26, 4.0);
    }
    if(GetIsObjectValid(oAttack) || GetIsObjectValid(oSpellTarget) || GetIsObjectValid(oAttacking) ||
     (GetIsObjectValid(oMove) && GetIsEnemy(oMove)))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Compare Talents
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the bits of Talent 1 against the bits
    of Talent 2 to see if 1 is true.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 12, 2002
//:://////////////////////////////////////////////
int GN_CompareTalents(int nTalent1, int nTalent2)
{
    if(nTalent1 & nTalent2)
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Comparison of " + IntToString(nTalent1) + " / " + IntToString(nTalent2));
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Get Last Talent Code
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Determines the last talent that was used
    by OBJECT_SELF
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetPreviousTalentCode()
{
    int nAction = GetLastAttackAction();
    int nFeatSpell;
    if(nAction == ACTION_CASTSPELL)
    {
        nFeatSpell = GetLastForcePowerUsed();
        nFeatSpell = GN_GetSpellTalentCode(nFeatSpell);
    }
    else if(nAction == ACTION_ATTACKOBJECT)
    {
        nFeatSpell = GetLastCombatFeatUsed();
        nFeatSpell = GN_GetFeatTalentCode(nFeatSpell);
    }
    return nFeatSpell;
}
//::///////////////////////////////////////////////
//:: Get Spell Talent Code
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the talent code for a particular spell
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetSpellTalentCode(int nSpell)
{
    talent tSpell = TalentSpell(nSpell);
    return GetCategoryFromTalent(tSpell);
}
//::///////////////////////////////////////////////
//:: Get Feat Talent Code
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the talent code for a particular feat
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetFeatTalentCode(int nFeat)
{
    talent tFeat = TalentSpell(nFeat);
    return GetCategoryFromTalent(tFeat);
}
//::///////////////////////////////////////////////
//:: Get Has Viable Talent
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Takes a talent code and searches for a viable
    talent from the bunch
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetHasViableTalent(int nTalentCode)
{
    talent tTest = GetCreatureTalentBest(nTalentCode, 20);
    if(GetIsTalentValid(tTest))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Get Exclusion Code
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns an exclusion code based on the Racial
    Type of the target
    0x00 = None
    0x01 = Organic
    0x02 = Droid
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 14, 2002
//:://////////////////////////////////////////////
int GN_GetExclusionCode(object oTarget)
{
    int nRacial = GetRacialType(oTarget);
    if(nRacial == RACIAL_TYPE_DROID)
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Exclusion Used: 0x01");
        return 0x01;
    }
    else if(nRacial == RACIAL_TYPE_HUMAN)
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Exclusion Used: 0x02");
        return 0x02;
    }
    //GN_MyPrintString("GENERIC DEBUG *************** Exclusion Used: 0x03");
    return 0x03;
}
//::///////////////////////////////////////////////
//:: Get Jedi Combo
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a proper Jedi Combo for Standard AI
int SW_COMBO_RANGED_FEROCIOUS = 1;
int SW_COMBO_RANGED_AGGRESSIVE = 2;
int SW_COMBO_RANGED_DISCIPLINED = 3;
int SW_COMBO_RANGED_CAUTIOUS = 4;
int SW_COMBO_MELEE_FEROCIOUS = 5;
int SW_COMBO_MELEE_AGGRESSIVE = 6;
int SW_COMBO_MELEE_DISCIPLINED = 7;
int SW_COMBO_MELEE_CAUTIOUS = 8;
int SW_COMBO_BUFF_PARTY = 9;
int SW_COMBO_BUFF_DEBILITATE = 10;
int SW_COMBO_BUFF_DAMAGE = 11;
int SW_COMBO_BUFF_DEBILITATE_DESTROY = 12;
int SW_COMBO_SUPRESS_DEBILITATE_DESTROY = 13;
int SW_COMBO_SITH_ATTACK = 14;
int SW_COMBO_BUFF_ATTACK = 15;
int SW_COMBO_SITH_CONFOUND = 16;
int SW_COMBO_JEDI_SMITE = 17;
int SW_COMBO_SITH_TAUNT = 18;
int SW_COMBO_SITH_BLADE = 19;
int SW_COMBO_SITH_CRUSH = 20;
int SW_COMBO_JEDI_CRUSH = 21;
int SW_COMBO_SITH_BRUTALIZE = 22;
int SW_COMBO_SITH_DRAIN = 23;
int SW_COMBO_SITH_ESCAPE = 24;
int SW_COMBO_JEDI_BLITZ = 25;
int SW_COMBO_SITH_SPIKE = 26;
int SW_COMBO_SITH_SCYTHE = 27;
int SW_COMBO_SITH_FURY = 28;
int SW_COMBO_JEDI_FOCUS = 29;
int SW_COMBO_DROID_UTILITIES = 30;
int SW_COMBO_DROID_UTILITIES_2 = 31;
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 28, 2002
//:://////////////////////////////////////////////
int GN_GetStandardJediCombo(int nBoss = FALSE)
{
    int nBool;
    int nRand;
    while(nBool == FALSE)
    {
        if(nBoss == FALSE)
        {
            nRand = Random(25)+1; //RWT-OEI 09/03/04 - Changed from 23->25
            if(nRand == 1 || nRand == 2) {return SW_COMBO_MELEE_FEROCIOUS;}
            else if(nRand == 3 || nRand == 4) {return SW_COMBO_MELEE_AGGRESSIVE;}
            else if(nRand == 5 || nRand == 6) {return SW_COMBO_MELEE_DISCIPLINED;}
            else if(nRand == 7 || nRand == 8 || nRand == 9) {return SW_COMBO_MELEE_CAUTIOUS;}
            else if(nRand >= 10 || nRand <= 26)
            {
                nRand = nRand+3;
            }
        }
        else
        {
            nRand = Random(15);
            nRand = nRand + 14;//RWT-OEI 09/03/04 - Changed from 13->14
        }
        nBool = GN_GetIsComboValid(nRand);
        //GN_MyPrintString("GENERIC DEBUG *************** Jedi Combo " + GN_FetchComboString(nRand) + " is " + IntToString(nBool));
    }
    return nRand;
}
//::///////////////////////////////////////////////
//:: Get Droid Combo
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a proper Droid Combo for Standard AI
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 28, 2002
//:://////////////////////////////////////////////
int GN_GetStandardDroidCombo(int nBoss = FALSE)
{
    //GN_MyPrintString("GENERIC DEBUG *************** Droid Combo Selection Started");
    int nBool = FALSE;
    int nRand = d6();
    while(nBool == FALSE)
    {
        if(nRand == 1){nRand = SW_COMBO_RANGED_AGGRESSIVE;}
        else if(nRand == 2){nRand = SW_COMBO_RANGED_CAUTIOUS;}
        else if(nRand == 3){nRand = SW_COMBO_RANGED_DISCIPLINED;}
        else if(nRand == 4){nRand = SW_COMBO_RANGED_FEROCIOUS;}
        else if(nRand == 5 || nRand == 6)
        {
            if((IsObjectPartyMember(OBJECT_SELF) && GetNPCAIStyle(OBJECT_SELF) == NPC_AISTYLE_JEDI_SUPPORT) ||
                !IsObjectPartyMember(OBJECT_SELF))
            {
                if(nRand == 5)
                {
                    nRand = SW_COMBO_DROID_UTILITIES;
                }
                else if(nRand == 6)
                {
                    nRand = SW_COMBO_DROID_UTILITIES_2;
                }
            }
            else
            {
                nRand = SW_COMBO_INVALID;
            }
        }
        nBool = GN_GetIsComboValid(nRand);
        //GN_MyPrintString("GENERIC DEBUG *************** Droid Combo Picked " + GN_FetchComboString(nRand) + " is " + IntToString(nBool));
        if(nBool == FALSE)
        {
            nRand = d6();
        }
    }
    //GN_MyPrintString("GENERIC DEBUG *************** Returning Combo Returned = " + GN_FetchComboString(nRand));
    return nRand;
}
//::///////////////////////////////////////////////
//:: Get NPC Combo
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a proper NPC Combo for Standard AI
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 28, 2002
//:://////////////////////////////////////////////
int GN_GetStandardNPCCombo(int nBoss = FALSE)
{
    int nBool;
    int nRand = d4();
    if(GN_GetWeaponType() != 0)
    {
        while(nBool == FALSE)
        {
            if(GN_GetWeaponType() == 1)
            {
                if(nRand == 1){nRand = SW_COMBO_MELEE_AGGRESSIVE;}
                else if(nRand == 2){nRand = SW_COMBO_MELEE_CAUTIOUS;}
                else if(nRand == 3){nRand = SW_COMBO_MELEE_DISCIPLINED;}
                else if(nRand == 4){nRand = SW_COMBO_MELEE_FEROCIOUS;}
            }
            else if(GN_GetWeaponType() == 2)
            {
                if(nRand == 1){nRand = SW_COMBO_RANGED_AGGRESSIVE;}
                else if(nRand == 2){nRand = SW_COMBO_RANGED_CAUTIOUS;}
                else if(nRand == 3){nRand = SW_COMBO_RANGED_DISCIPLINED;}
                else if(nRand == 4){nRand = SW_COMBO_RANGED_FEROCIOUS;}
            }
            nBool = GN_GetIsComboValid(nRand);
            if(nBool == FALSE)
            {
                //nRand = d6();
                nRand = d4();//RWT-OEI 09/03/04 - Pretty sure this is supposed to be d4()
            }
        }
    }
    else
    {
        // DJS-OEI 9/28/2004
        // For some reason, if the caller is unarmed, it would resort
        // to SW_COMBO_RANGED_AGGRESSIVE, which seems very odd. Since CNPCs
        // will never auto-equip weapons (since GN_EquipAppropriateWeapon())
        // always drops out for party members, we were getting a crash with
        // the new Sniper Shot feat when someone tried to use it unarmed.
        // I have fixed that crash, but we will try to choose melee feats
        // in this case instead of ranged.
        //nRand = 2;
        if(nRand == 1) {nRand = SW_COMBO_MELEE_AGGRESSIVE;}
        else if(nRand == 2) {nRand = SW_COMBO_MELEE_CAUTIOUS;}
        else if(nRand == 3) {nRand = SW_COMBO_MELEE_DISCIPLINED;}
        else if(nRand == 4) {nRand = SW_COMBO_MELEE_FEROCIOUS;}
    }
    //GN_MyPrintString("GENERIC DEBUG *************** NPC Combo " + GN_FetchComboString(nRand) + " is " + IntToString(nBool));
    return nRand;
}
//::///////////////////////////////////////////////
//:: Get Next Talent In Combo
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Looks at the combo id and returns an ability
    usable by the NPC which matches the next
    feat in the combo.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 27, 2002
//:://////////////////////////////////////////////
talent GN_GetNextTalentInCombo(int nCombo)
{
    SetLocalBoolean(OBJECT_SELF, SW_FLAG_TARGET_FRIEND, FALSE);
    int nLocal = GetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX);
    //GN_MyPrintString("GENERIC DEBUG *************** Combo Index " + IntToString(nLocal));
    talent tUse, tInvalid;
    int nID = -1;
    int nFeat = FALSE;
    int nBuff = FALSE;
    //Sith Attack(PUSH, CHOKE, JUMP)
    if(nCombo == SW_COMBO_SITH_ATTACK)
    {
        if(nLocal == 1)
        {
            //nID = GN_GetSeriesChoke();
            GN_GetSeriesScream();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesForcePush();
        }
        else
        {
            //nID = GN_GetSeriesJump();
            nID = GN_GetSeriesJump();
        }
    }
    //Buff Attack(ARMOR, SPEED, FEAT)
    else if(nCombo == SW_COMBO_BUFF_ATTACK)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesForceArmor();
            nBuff = TRUE;
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesSpeed();
            nBuff = TRUE;
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Sith Confound (FEAR, FEAT, FEAT)
    else if(nCombo == SW_COMBO_SITH_CONFOUND)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesLightning();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Jedi Smite (HOLD, FEAT, FEAT)
    else if(nCombo == SW_COMBO_JEDI_SMITE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesHold();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Sith Taunt (CHOKE, POISON, FEAT)
    else if(nCombo == SW_COMBO_SITH_TAUNT)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesChoke();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesAfflict();
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Sith Blade (SLOW, PUSH, THROW)
    else if(nCombo == SW_COMBO_SITH_BLADE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesAfflict();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesForcePush();
        }
        else
        {
            nID = GN_GetSeriesSaberThrow();
        }
    }
    //Sith Crush (PUSH, SHOCK, JUMP)
    else if(nCombo == SW_COMBO_SITH_CRUSH)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesLightning();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesForcePush();
        }
        else
        {
            nID = GN_GetSeriesJump();
        }
    }
    //Jedi Crush (HOLD, THROW, JUMP)
    else if(nCombo == SW_COMBO_JEDI_CRUSH)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesHold();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesForcePush();
        }
        else
        {
            nID = GN_GetSeriesJump();
        }
    }
    //Sith Brutalize (CHOKE, DRAIN, PUSH)
    else if(nCombo == SW_COMBO_SITH_BRUTALIZE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesChoke();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesDrainLife();
        }
        else
        {
            nID = GN_GetSeriesForcePush();
        }
    }
    //Sith Drain (FEAT, DRAIN, FEAT)
    else if(nCombo == SW_COMBO_SITH_DRAIN)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesDrainLife();
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Sith Escape (DRAIN, PUSH, THROW)
    else if(nCombo == SW_COMBO_SITH_ESCAPE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesDrainLife();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesForcePush();
        }
        else
        {
            nID = GN_GetSeriesSaberThrow();
        }
    }
    //Jedi Blitz (FEAT, FEAT, PUSH)
    else if(nCombo == SW_COMBO_JEDI_BLITZ)
    {
        if(nLocal == 1)
        {
            //nID = GN_GetSeriesMeleeFeat();
            //RWT-OEI 09/02/04 - Since this one has no series, just give
            //the ID directly.
            nID = FORCE_POWER_FORCE_CRUSH;
            nFeat = TRUE;
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            nID = GN_GetSeriesForcePush();
        }
    }
    //Sith Spike (PUSH, SLOW, FEAT)
    else if(nCombo == SW_COMBO_SITH_SPIKE)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesAfflict();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            nID = GN_GetSeriesForcePush();
        }
    }
    //Sith Scythe (DRAIN, FEAR, FEAT)
    else if(nCombo == SW_COMBO_SITH_SCYTHE)
    {
        if(nLocal == 1)
        {
            //nID = GN_GetSeriesDrainLife();
            nID = GN_GetSeriesDrainForce();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesBreach();
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    else if ( nCombo == SW_COMBO_SITH_FURY)
    {
        if ( nLocal == 1 )
        {
            nID = GN_GetSeriesFury();
        }
        else if (nLocal == 2)
        {
            nID = GN_GetSeriesScream();
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    else if ( nCombo == SW_COMBO_JEDI_FOCUS )
    {
        if ( nLocal == 1 )
        {
            nID = GN_GetSeriesBattleMeditation();
        }
        else if ( nLocal == 2 )
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
    }
    //Melee Ferocious (USE 3 FEATS)
    else if(nCombo == SW_COMBO_MELEE_FEROCIOUS)
    {
        nID = GN_GetSeriesMeleeFeat();
        nFeat = TRUE;
    }
    //Melee Aggressive (USE 2 FEATS)
    else if(nCombo == SW_COMBO_MELEE_AGGRESSIVE)
    {
        if(nLocal == 1 || nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee/Ranged Breather");
        }
    }
    //Melee Discipline (USE 1 FEAT)
    else if(nCombo == SW_COMBO_MELEE_DISCIPLINED)
    {
        if(nLocal == 1 || nLocal == 2)
        {
            nID = GN_GetSeriesMeleeFeat();
            nFeat = TRUE;
        }
        else
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee/Ranged Breather");
        }
    }
    else if(nCombo == SW_COMBO_MELEE_CAUTIOUS || nCombo == SW_COMBO_RANGED_CAUTIOUS)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Melee/Ranged Breather");
    }
    //Melee Cautious (USE NO FEATS) //This does not require a check. It will return an invalid talent
    //Ranged Cautious (USE NO FEATS) //This does not require a check. It will return an invalid talent
    //Ranged Ferocious (USE 3 FEATS)
    else if(nCombo == SW_COMBO_RANGED_FEROCIOUS)
    {
        nID = GN_GetSeriesRangedFeat();
        nFeat = TRUE;
    }
    //Ranged Aggressive (USE 2 FEATS)
    else if(nCombo == SW_COMBO_RANGED_AGGRESSIVE)
    {
        if(nLocal == 1 || nLocal == 2)
        {
            nID = GN_GetSeriesRangedFeat();
            nFeat = TRUE;
        }
        else
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee/Ranged Breather");
        }
    }
    //Ranged Discipline (USE 1 FEAT)
    else if(nCombo == SW_COMBO_RANGED_DISCIPLINED)
    {
        if(nLocal == 1 || nLocal == 2)
        {
            nID = GN_GetSeriesRangedFeat();
            nFeat = TRUE;
        }
        else
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee/Ranged Breather");
        }
    }
    //Buff Party
    else if(nCombo == SW_COMBO_BUFF_PARTY)
    {
        tUse = GetCreatureTalentRandom(0xf8ff);
    }
    //Buff & Debilitate (BUFF & 2 DEBILITATE ENEMY)
    else if(nCombo == SW_COMBO_BUFF_DEBILITATE)
    {
        if(nLocal == 1)
        {
            tUse = GetCreatureTalentRandom(0xf8ff);
        }
        else
        {
            tUse = GetCreatureTalentRandom(0xf2ff);
        }
    }
    //Buff & Damage (BUFF  & 2 DAMAGE ENEMY)
    else if(nCombo == SW_COMBO_BUFF_DAMAGE)
    {
        if(nLocal == 1)
        {
            tUse = GetCreatureTalentRandom(0xf8ff);
        }
        else
        {
            tUse = GetCreatureTalentRandom(0xf1ff);
        }
    }
    //Buff, Debilitate & Destroy (1 BUFF, 1 DEBILITATE, 1 DESTROY)
    else if(nCombo == SW_COMBO_BUFF_DEBILITATE_DESTROY)
    {
        if(nLocal == 1)
        {
            tUse = GetCreatureTalentRandom(0xf8ff);
        }
        if(nLocal == 2)
        {
            tUse = GetCreatureTalentRandom(0xf2ff);
        }
        if(nLocal == 3)
        {
            tUse = GetCreatureTalentRandom(0x1101);
        }
    }
    //Supress, Debilitate & Destroy (1 Supress, 1 DEBILITATE, 1 DESTROY)
    else if(nCombo == SW_COMBO_SUPRESS_DEBILITATE_DESTROY)
    {
        if(nLocal == 1)
        {
            tUse = GetCreatureTalentRandom(0xf1ff);
        }
        if(nLocal == 2)
        {
            tUse = GetCreatureTalentRandom(0xf2ff);
        }
        if(nLocal == 3)
        {
            tUse = GetCreatureTalentRandom(0x1101);
        }
    }
    else if(nCombo == SW_COMBO_DROID_UTILITIES)
    {
        if(nLocal == 1)
        {
            nID = GN_GetSeriesRangedFeat();
            nFeat = TRUE;
        }
        if(nLocal == 2)
        {
            nID = GN_GetSeriesRangedFeat();
            nFeat = TRUE;
        }
        if(nLocal == 3)
        {
            tUse = GetCreatureTalentRandom(0x8000);
        }
    }
    else if(nCombo == SW_COMBO_DROID_UTILITIES_2)
    {
        if(nLocal == 1)
        {
            tUse = GetCreatureTalentRandom(0x8000);
        }
        if(nLocal == 2)
        {
            nID = GN_GetSeriesRangedFeat();
            nFeat = TRUE;
        }
        if(nLocal == 3)
        {
            tUse = GetCreatureTalentRandom(0x8000);
        }
    }
    //Increments the Local number so that the progression through the Combo continues even if the talent fails
    nLocal++;
    SetLocalNumber(OBJECT_SELF, SW_NUMBER_COMBO_INDEX, nLocal);
    if(!GetIsTalentValid(tUse) || !GetCreatureHasTalent(tUse))
    {
        //GN_MyPrintString("GENERIC DEBUG *************** ID = " + IntToString(nID));
        if(nID != -1 && nFeat == FALSE)
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Spell ID = " + IntToString(nID));
            tUse = TalentSpell(nID);
        }
        else if(nID != -1 && nFeat == TRUE)
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Feat ID = " + IntToString(nID));
            tUse = TalentFeat(nID);
        }
    }
    else
    {
        nID = GetIdFromTalent(tUse);
        //GN_MyPrintString("GENERIC DEBUG *************** Preselected ID = " + IntToString(nID));
    }
    //Use GetCreatureHasTalent here to make the talent is currently usable - ie enough force points.
    //Currently it terminates the script, so do not use it.
    if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Returning Valid Talent");
        return tUse;
    }
    //GN_MyPrintString("GENERIC DEBUG *************** Returning Invalid Talent");
    return tInvalid;
}
//::///////////////////////////////////////////////
//:: Force Power Get Functions
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns an ability based.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 27, 2002
//:://////////////////////////////////////////////
int GN_GetSeriesForcePush()
{
    if(GetHasSpell(FORCE_POWER_FORCE_WAVE))
    {
        return FORCE_POWER_FORCE_WAVE;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_WHIRLWIND))
    {
        return FORCE_POWER_FORCE_WHIRLWIND;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_PUSH))
    {
        return FORCE_POWER_FORCE_PUSH;
    }
    return -1;
}
int GN_GetSeriesForceArmor()
{
    if(GetHasSpell(FORCE_POWER_FORCE_ARMOR))
    {
        return FORCE_POWER_FORCE_ARMOR;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_SHIELD))
    {
        return FORCE_POWER_FORCE_SHIELD;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_AURA))
    {
        return FORCE_POWER_FORCE_AURA;
    }
    return -1;
}
int GN_GetSeriesFear()
{
    if(GetHasSpell(FORCE_POWER_INSANITY))
    {
        return FORCE_POWER_INSANITY;
    }
    else if(GetHasSpell(FORCE_POWER_HORROR))
    {
        return FORCE_POWER_HORROR;
    }
    else if(GetHasSpell(FORCE_POWER_FEAR))
    {
        return FORCE_POWER_FEAR;
    }
    return -1;
}
int GN_GetSeriesHold()
{
    if(GetHasSpell(FORCE_POWER_SLEEP))
    {
        return FORCE_POWER_SLEEP;
    }
    else if(GetHasSpell(FORCE_POWER_HOLD))
    {
        return FORCE_POWER_HOLD;
    }
    else if(GetHasSpell(FORCE_POWER_STUN))
    {
        return FORCE_POWER_STUN;
    }
    return -1;
}
int GN_GetSeriesAfflict()
{
    if(GetHasSpell(FORCE_POWER_PLAGUE))
    {
        return FORCE_POWER_PLAGUE;
    }
    else if(GetHasSpell(FORCE_POWER_AFFLICTION))
    {
        return FORCE_POWER_AFFLICTION;
    }
    else if(GetHasSpell(FORCE_POWER_SLOW))
    {
        return FORCE_POWER_SLOW;
    }
    return -1;
}
int GN_GetSeriesSaberThrow()
{
    if(GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW_ADVANCED))
    {
        return FORCE_POWER_LIGHT_SABER_THROW_ADVANCED;
    }
    else if(GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW))
    {
        return FORCE_POWER_LIGHT_SABER_THROW;
    }
    return -1;
}
int GN_GetSeriesLightning()
{
    if(GetHasSpell(FORCE_POWER_FORCE_STORM))
    {
        return FORCE_POWER_FORCE_STORM;
    }
    else if(GetHasSpell(FORCE_POWER_LIGHTNING))
    {
        return FORCE_POWER_LIGHTNING;
    }
    else if(GetHasSpell(FORCE_POWER_SHOCK))
    {
        return FORCE_POWER_SHOCK;
    }
    return -1;
}
int GN_GetSeriesJump()
{
    if(GetHasSpell(FORCE_POWER_FORCE_JUMP_ADVANCED))
    {
        return FORCE_POWER_FORCE_JUMP_ADVANCED;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_JUMP))
    {
        return FORCE_POWER_FORCE_JUMP;
    }
    return -1;
}
int GN_GetSeriesChoke()
{
    if(GetHasSpell(FORCE_POWER_KILL))
    {
        return FORCE_POWER_KILL;
    }
    else if(GetHasSpell(FORCE_POWER_CHOKE))
    {
        return FORCE_POWER_CHOKE;
    }
    else if(GetHasSpell(FORCE_POWER_WOUND))
    {
        return FORCE_POWER_WOUND;
    }
    return -1;
}
int GN_GetSeriesDrainLife()
{
    if(GetHasSpell(FORCE_POWER_DEATH_FIELD))
    {
        return FORCE_POWER_DEATH_FIELD;
    }
    else if(GetHasSpell(FORCE_POWER_DRAIN_LIFE))
    {
        return FORCE_POWER_DRAIN_LIFE;
    }
    return -1;
}
int GN_GetSeriesSpeed()
{
    if(GetHasSpell(FORCE_POWER_SPEED_MASTERY))
    {
        return FORCE_POWER_SPEED_MASTERY;
    }
    else if(GetHasSpell(FORCE_POWER_KNIGHT_SPEED))
    {
        return FORCE_POWER_KNIGHT_SPEED;
    }
    else if(GetHasSpell(FORCE_POWER_SPEED_BURST))
    {
        return FORCE_POWER_SPEED_BURST;
    }
    return -1;
}
int GN_GetSeriesMeleeFeat()
{
    //RWT-OEI 10/12/04 - If the character has a ranged weapon
    //equipped give them a ranged feat no matter what.
    if ( GN_GetWeaponType() == 2 )
    {
        talent tUse = GetCreatureTalentBest(0x1111,20);
        if ( GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse) )
        {
            int nID = GetIdFromTalent(tUse);
            return nID;
        }
    }
    else
    {
        talent tUse = GetCreatureTalentBest(0x1104, 20);
        if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
        {
            int nID = GetIdFromTalent(tUse);
            return nID;
        }
    }
    return -1;
}
int GN_GetSeriesRangedFeat()
{
    // DJS-OEI 4/26/2004
    // All of the Ranged combat Feats are 0x1111, not
    // 0x1181. This was causing droids, for instance,
    // to never use their Ranged Feats.
    //talent tUse = GetCreatureTalentBest(0x1181, 20);
    //RWT-OEI 10/12/04 - If the character doesn't have a ranged weapon
    //equipped, give them a melee feat no matter what
    if ( GN_GetWeaponType() != 2 )
    {
        talent tUse = GetCreatureTalentBest(0x1104, 20);
        if ( GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse) )
        {
            int nID = GetIdFromTalent(tUse);
            return nID;
        }
    }
    else
    {
        talent tUse = GetCreatureTalentBest(0x1111, 20);
        if(GetIsTalentValid(tUse) && GetCreatureHasTalent(tUse))
        {
            int nID = GetIdFromTalent(tUse);
            return nID;
        }
    }
    return -1;
}
int GN_GetSeriesMind()
{
    if(GetHasSpell(FORCE_POWER_MIND_MASTERY))
    {
        return FORCE_POWER_MIND_MASTERY;
    }
    else if(GetHasSpell(FORCE_POWER_KNIGHT_MIND))
    {
        return FORCE_POWER_KNIGHT_MIND;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_MIND))
    {
        return FORCE_POWER_FORCE_MIND;
    }
    return -1;
}
int GN_GetSeriesResist()
{
    // DJS-OEI 12/9/2003
    if(GetHasSpell(FORCE_POWER_MASTER_ENERGY_RESISTANCE))
    {
        return FORCE_POWER_MASTER_ENERGY_RESISTANCE;
    }
    else if(GetHasSpell(FORCE_POWER_RESIST_COLD_HEAT_ENERGY))
    {
        return FORCE_POWER_RESIST_COLD_HEAT_ENERGY;
    }
    else if(GetHasSpell(FORCE_POWER_RESIST_POISON_DISEASE_SONIC))
    {
        return FORCE_POWER_RESIST_POISON_DISEASE_SONIC;
    }
    return -1;
}
int GN_GetSeriesForceImmunity()
{
    if(GetHasSpell(FORCE_POWER_FORCE_IMMUNITY))
    {
        return FORCE_POWER_FORCE_IMMUNITY;
    }
    else if(GetHasSpell(FORCE_POWER_RESIST_FORCE))
    {
        return FORCE_POWER_RESIST_FORCE;
    }
    return -1;
}
int GN_GetSeriesBreach()
{
    if(GetHasSpell(FORCE_POWER_FORCE_BREACH))
    {
        return FORCE_POWER_FORCE_BREACH;
    }
    else if(GetHasSpell(FORCE_POWER_SUPRESS_FORCE))
    {
        return FORCE_POWER_SUPRESS_FORCE;
    }
    return -1;
}
// DJS-OEI 8/19/2004
int GN_GetSeriesHeal() {
    if(GetHasSpell(FORCE_POWER_MASTER_HEAL))
    {
        return FORCE_POWER_MASTER_HEAL;
    }
    else if(GetHasSpell(FORCE_POWER_HEAL))
    {
        return FORCE_POWER_HEAL;
    }
    else if(GetHasSpell(FORCE_POWER_CURE))
    {
        return FORCE_POWER_CURE;
    }
    return -1;
}
// DJS-OEI 8/19/2004
int GN_GetSeriesBarrier() {
    if(GetHasSpell(FORCE_POWER_MASTER_FORCE_BARRIER))
    {
        return FORCE_POWER_MASTER_FORCE_BARRIER;
    }
    else if(GetHasSpell(FORCE_POWER_IMPROVED_FORCE_BARRIER))
    {
        return FORCE_POWER_IMPROVED_FORCE_BARRIER;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_BARRIER))
    {
        return FORCE_POWER_FORCE_BARRIER;
    }
    return -1;
}
// DJS-OEI 8/19/2004
int GN_GetSeriesBattleMeditation() {
    if(GetHasSpell(FORCE_POWER_MASTER_BATTLE_MEDITATION_PC))
    {
        return FORCE_POWER_MASTER_BATTLE_MEDITATION_PC;
    }
    else if(GetHasSpell(FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC))
    {
        return FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC;
    }
    else if(GetHasSpell(FORCE_POWER_BATTLE_MEDITATION_PC))
    {
        return FORCE_POWER_BATTLE_MEDITATION_PC;
    }
    if(GetHasSpell(FORCE_POWER_MAS_BAT_MED_ENEMY))
    {
        return FORCE_POWER_MAS_BAT_MED_ENEMY;
    }
    else if(GetHasSpell(FORCE_POWER_IMP_BAT_MED_ENEMY))
    {
        return FORCE_POWER_IMP_BAT_MED_ENEMY;
    }
    else if(GetHasSpell(FORCE_POWER_BAT_MED_ENEMY))
    {
        return FORCE_POWER_BAT_MED_ENEMY;
    }
    return -1;
}
//RWT-OEI 09/03/04
int GN_GetSeriesFury()
{
    if ( GetHasSpell(FORCE_POWER_MASTER_FURY) )
    {
        return FORCE_POWER_MASTER_FURY;
    }
    else if ( GetHasSpell(FORCE_POWER_IMPROVED_FURY) )
    {
        return FORCE_POWER_IMPROVED_FURY;
    }
    else if ( GetHasSpell(FORCE_POWER_FURY))
    {
        return FORCE_POWER_FURY;
    }
    return -1;
}
//RWT-OEI 09/03/04
int GN_GetSeriesRevitalize()
{
    if ( GetHasSpell(FORCE_POWER_MASTER_REVITALIZE) )
    {
        return FORCE_POWER_MASTER_REVITALIZE;
    }
    else if ( GetHasSpell(FORCE_POWER_IMPROVED_REVITALIZE) )
    {
        return FORCE_POWER_IMPROVED_REVITALIZE;
    }
    else if ( GetHasSpell(FORCE_POWER_REVITALIZE) )
    {
        return FORCE_POWER_REVITALIZE;
    }
    return -1;
}
// DJS-OEI 8/19/2004
int GN_GetSeriesDrainForce() {
    if(GetHasSpell(FORCE_POWER_MASTER_DRAIN_FORCE))
    {
        return FORCE_POWER_MASTER_DRAIN_FORCE;
    }
    else if(GetHasSpell(FORCE_POWER_IMPROVED_DRAIN_FORCE))
    {
        return FORCE_POWER_IMPROVED_DRAIN_FORCE;
    }
    else if(GetHasSpell(FORCE_POWER_DRAIN_FORCE))
    {
        return FORCE_POWER_DRAIN_FORCE;
    }
    return -1;
}
// DJS-OEI 8/19/2004
int GN_GetSeriesScream() {
    if(GetHasSpell(FORCE_POWER_MASTER_FORCE_SCREAM))
    {
        return FORCE_POWER_MASTER_FORCE_SCREAM;
    }
    else if(GetHasSpell(FORCE_POWER_IMPROVED_FORCE_SCREAM))
    {
        return FORCE_POWER_IMPROVED_FORCE_SCREAM;
    }
    else if(GetHasSpell(FORCE_POWER_FORCE_SCREAM))
    {
        return FORCE_POWER_FORCE_SCREAM;
    }
    return -1;
}
//::///////////////////////////////////////////////
//:: Force Power Series Checks
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks if a Jedi has 1 in a force power series
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 27, 2002
//:://////////////////////////////////////////////
int GN_CheckSeriesForcePush()
{
    if(GetHasSpell(FORCE_POWER_FORCE_PUSH) || GetHasSpell(FORCE_POWER_FORCE_WHIRLWIND) || GetHasSpell(FORCE_POWER_FORCE_WAVE))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesArmor()
{
    if(GetHasSpell(FORCE_POWER_FORCE_ARMOR) || GetHasSpell(FORCE_POWER_FORCE_SHIELD) || GetHasSpell(FORCE_POWER_FORCE_AURA))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesFear()
{
    if(GetHasSpell(FORCE_POWER_FEAR) || GetHasSpell(FORCE_POWER_HORROR) || GetHasSpell(FORCE_POWER_INSANITY))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesHold()
{
    if(GetHasSpell(FORCE_POWER_STUN) || GetHasSpell(FORCE_POWER_HOLD) || GetHasSpell(FORCE_POWER_SLEEP))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesAfflict()
{
    if(GetHasSpell(FORCE_POWER_SLOW) || GetHasSpell(FORCE_POWER_AFFLICTION) || GetHasSpell(FORCE_POWER_PLAGUE))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesSaberThrow()
{
    if(GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW) || GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW_ADVANCED))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesLightning()
{
    if(GetHasSpell(FORCE_POWER_SHOCK) || GetHasSpell(FORCE_POWER_LIGHTNING) || GetHasSpell(FORCE_POWER_FORCE_STORM))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesJump()
{
    if(GetHasSpell(FORCE_POWER_FORCE_JUMP) || GetHasSpell(FORCE_POWER_FORCE_JUMP_ADVANCED))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesChoke()
{
    if(GetHasSpell(FORCE_POWER_CHOKE) || GetHasSpell(FORCE_POWER_WOUND) || GetHasSpell(FORCE_POWER_KILL))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesDrainLife()
{
    if(GetHasSpell(FORCE_POWER_DRAIN_LIFE) || GetHasSpell(FORCE_POWER_DEATH_FIELD))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesSpeed()
{
    if(GetHasSpell(FORCE_POWER_SPEED_BURST) || GetHasSpell(FORCE_POWER_SPEED_MASTERY) || GetHasSpell(FORCE_POWER_KNIGHT_SPEED))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesMind()
{
    if(GetHasSpell(FORCE_POWER_MIND_MASTERY) || GetHasSpell(FORCE_POWER_KNIGHT_MIND) || GetHasSpell(FORCE_POWER_FORCE_MIND))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesResist()
{
    // DJS-OEI 12/9/2003
    // Added Master Energy Resistance
    if( GetHasSpell(FORCE_POWER_RESIST_COLD_HEAT_ENERGY) ||
        GetHasSpell(FORCE_POWER_RESIST_POISON_DISEASE_SONIC) ||
        GetHasSpell(FORCE_POWER_MASTER_ENERGY_RESISTANCE) )
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesForceImmunity()
{
    if(GetHasSpell(FORCE_POWER_RESIST_FORCE) || GetHasSpell(FORCE_POWER_FORCE_IMMUNITY))
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesBreach()
{
    if(GetHasSpell(FORCE_POWER_SUPRESS_FORCE) || GetHasSpell(FORCE_POWER_FORCE_BREACH))
    {
        return TRUE;
    }
    return FALSE;
}
// DJS-OEI 8/19/2004
int GN_CheckSeriesHeal()
{
    if(GetHasSpell(FORCE_POWER_CURE) || GetHasSpell(FORCE_POWER_HEAL) || GetHasSpell(FORCE_POWER_MASTER_HEAL))
    {
        return TRUE;
    }
    return FALSE;
}
// DJS-OEI 8/19/2004
int GN_CheckSeriesBarrier() {
    if(GetHasSpell(FORCE_POWER_FORCE_BARRIER) ||
       GetHasSpell(FORCE_POWER_IMPROVED_FORCE_BARRIER) ||
       GetHasSpell(FORCE_POWER_MASTER_FORCE_BARRIER))
    {
        return TRUE;
    }
    return FALSE;
}
// DJS-OEI 8/19/2004
int GN_CheckSeriesBattleMeditation() {
    if(GetHasSpell(FORCE_POWER_BATTLE_MEDITATION_PC) ||
       GetHasSpell(FORCE_POWER_IMPROVED_BATTLE_MEDITATION_PC) ||
       GetHasSpell(FORCE_POWER_MASTER_BATTLE_MEDITATION_PC) ||
       GetHasSpell(FORCE_POWER_BAT_MED_ENEMY) ||
       GetHasSpell(FORCE_POWER_IMP_BAT_MED_ENEMY) ||
       GetHasSpell(FORCE_POWER_MAS_BAT_MED_ENEMY))
    {
        return TRUE;
    }
    return FALSE;
}
// DJS-OEI 8/19/2004
int GN_CheckSeriesDrainForce() {
    if(GetHasSpell(FORCE_POWER_DRAIN_FORCE) ||
       GetHasSpell(FORCE_POWER_IMPROVED_DRAIN_FORCE) ||
       GetHasSpell(FORCE_POWER_MASTER_DRAIN_FORCE))
    {
        return TRUE;
    }
    return FALSE;
}
// DJS-OEI 8/19/2004
int GN_CheckSeriesScream() {
    if(GetHasSpell(FORCE_POWER_FORCE_SCREAM) ||
       GetHasSpell(FORCE_POWER_IMPROVED_FORCE_SCREAM) ||
       GetHasSpell(FORCE_POWER_MASTER_FORCE_SCREAM))
    {
        return TRUE;
    }
    return FALSE;
}
//RWT-OEI 09/03/04
int GN_CheckSeriesFury()
{
    if (GetHasSpell(FORCE_POWER_FURY) ||
        GetHasSpell(FORCE_POWER_IMPROVED_FURY) ||
        GetHasSpell(FORCE_POWER_MASTER_FURY) )
    {
        return TRUE;
    }
    return FALSE;
}
//RWT-OEI 09/03/04
int GN_CheckSeriesRevitalize()
{
    if ( GetHasSpell(FORCE_POWER_REVITALIZE) ||
         GetHasSpell(FORCE_POWER_IMPROVED_REVITALIZE) ||
         GetHasSpell(FORCE_POWER_MASTER_REVITALIZE) )
    {
        return TRUE;
    }
    return FALSE;
}
int GN_CheckSeriesDroidUtilities()
{
    talent tUse = GetCreatureTalentRandom(0x8000);
    /*
    if(GetHasSpell(116) || GetHasSpell(117) || GetHasSpell(118) ||
       GetHasSpell(119) || GetHasSpell(120) || GetHasSpell(121) ||
       GetHasSpell(121) || GetHasSpell(122) || GetHasSpell(123) ||
       GetHasSpell(124) || GetHasSpell(125))
    */
    if(GetIsTalentValid(tUse))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Is Combo Valid
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets a combo constant and determines if the
    NPC can perform the stated combo
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 27, 2002
//:://////////////////////////////////////////////
int GN_GetIsComboValid(int nComboType)
{
    //P.W (May 27, 2003) - Made allowances for an invalid effect to be passed in.
    if(nComboType == SW_COMBO_INVALID)
    {
        return FALSE;
    }
    talent tTest, tTest2;
    if(nComboType == SW_COMBO_MELEE_FEROCIOUS ||
            nComboType == SW_COMBO_MELEE_AGGRESSIVE ||
            nComboType == SW_COMBO_MELEE_DISCIPLINED)
    {
        tTest = GetCreatureTalentRandom(0x1104); //Only Melee feats use this code
        if(GetIsTalentValid(tTest) && GetCreatureHasTalent(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_RANGED_CAUTIOUS)
    {
        return TRUE;
    }
    else if(nComboType == SW_COMBO_RANGED_FEROCIOUS ||
       nComboType == SW_COMBO_RANGED_AGGRESSIVE ||
       nComboType == SW_COMBO_RANGED_DISCIPLINED)
    {
        //These are the only ranged feats in the game and therefore it is better to use a feat constant not a talent code
        //given that 0x1101 is also used by some force powers.
        if(GetHasFeat(FEAT_SNIPER_SHOT) || GetHasFeat(FEAT_IMPROVED_SNIPER_SHOT) || GetHasFeat(FEAT_MASTER_SNIPER_SHOT) ||
           GetHasFeat(FEAT_POWER_BLAST) || GetHasFeat(FEAT_IMPROVED_POWER_BLAST) || GetHasFeat(82) || //Master Power Blast
           GetHasFeat(FEAT_RAPID_SHOT) || GetHasFeat(FEAT_MULTI_SHOT) || GetHasFeat(92))//92 = IMRPOVED_RAPID_SHOT
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_MELEE_CAUTIOUS)
    {
        return TRUE;
    }
    else if(nComboType == SW_COMBO_BUFF_PARTY)
    {
        tTest = GetCreatureTalentRandom(0xf8ff);
        if(GetIsTalentValid(tTest) && GetCreatureHasTalent(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_BUFF_DEBILITATE)
    {
        tTest = GetCreatureTalentRandom(0xf8ff);
        tTest2 = GetCreatureTalentRandom(0xf2ff);
        if(GetIsTalentValid(tTest) && GetIsTalentValid(tTest2)
           && GetCreatureHasTalent(tTest)
           && GetCreatureHasTalent(tTest2))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_BUFF_DAMAGE)
    {
        tTest = GetCreatureTalentRandom(0xf8ff);
        if(GetIsTalentValid(tTest) && GN_GetHasDamagingForcePower())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_BUFF_DEBILITATE_DESTROY)
    {
        tTest = GetCreatureTalentRandom(0xf8ff);
        tTest2 = GetCreatureTalentRandom(0xf2ff);
        if(GetIsTalentValid(tTest) && GetIsTalentValid(tTest2) && GN_GetHasDamagingForcePower())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SUPRESS_DEBILITATE_DESTROY)
    {
        tTest = GetCreatureTalentRandom(0xff2f);
        tTest2 = GetCreatureTalentRandom(0xf2ff);
        if(GetIsTalentValid(tTest) && GetIsTalentValid(tTest2) && GN_GetHasDamagingForcePower())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_ATTACK)
    {
        if(GN_CheckSeriesForcePush() && GN_CheckSeriesChoke() && GN_CheckSeriesJump())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_BUFF_ATTACK)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesArmor() && GN_CheckSeriesSpeed() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_CONFOUND)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesLightning() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_JEDI_SMITE)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesHold() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_TAUNT)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesChoke() && GN_CheckSeriesAfflict() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_BLADE)
    {
        if(GN_CheckSeriesAfflict() && GN_CheckSeriesForcePush() && GN_CheckSeriesSaberThrow())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_CRUSH)
    {
        if(GN_CheckSeriesLightning() && GN_CheckSeriesForcePush() && GN_CheckSeriesJump())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_JEDI_CRUSH)
    {
        if(GN_CheckSeriesHold() && GN_CheckSeriesForcePush() && GN_CheckSeriesJump())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_JEDI_CRUSH)
    {
        if(GN_CheckSeriesChoke() && GN_CheckSeriesDrainLife() && GN_CheckSeriesForcePush())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_DRAIN)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesDrainLife() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_ESCAPE)
    {
        if(GN_CheckSeriesDrainLife() && GN_CheckSeriesForcePush() && GN_CheckSeriesSaberThrow())
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_JEDI_BLITZ)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        //if(GN_CheckSeriesForcePush() && GetIsTalentValid(tTest))
        if ( GN_CheckSeriesForcePush() && GetIsTalentValid(tTest) && GetHasSpell(FORCE_POWER_FORCE_CRUSH) )
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_SPIKE)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if(GN_CheckSeriesForcePush() && GN_CheckSeriesAfflict() && GetIsTalentValid(tTest))
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_SCYTHE)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        //if(GN_CheckSeriesDrainLife() && GN_CheckSeriesBreach() && GetIsTalentValid(tTest))
        if ( GN_CheckSeriesDrainForce() && GN_CheckSeriesBreach() && GetIsTalentValid(tTest) )
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_SITH_FURY)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if ( GN_CheckSeriesFury() && GN_CheckSeriesScream() && GetIsTalentValid(tTest) )
        {
            return TRUE;
        }
    }
    else if ( nComboType == SW_COMBO_JEDI_FOCUS)
    {
        tTest = GetCreatureTalentRandom(0x1104);
        if ( GN_CheckSeriesBattleMeditation() && GetIsTalentValid(tTest) )
        {
            return TRUE;
        }
    }
    else if(nComboType == SW_COMBO_DROID_UTILITIES || nComboType == SW_COMBO_DROID_UTILITIES_2)
    {
        object oItem1 = GetItemInSlot(INVENTORY_SLOT_LEFTARM);
        object oItem2 = GetItemInSlot(INVENTORY_SLOT_RIGHTARM);
        GN_MyPrintString("GENERIC DEBUG *************** Droid Items = " + GN_ReturnDebugName(oItem1) + " / " + GN_ReturnDebugName(oItem2));
        if(GN_CheckSeriesDroidUtilities())
        {
            GN_MyPrintString("GENERIC DEBUG *************** Droid Utility Check is TRUE");
            return TRUE;
        }
        GN_MyPrintString("GENERIC DEBUG *************** Droid Utility Check is FALSE");
    }
    return FALSE;
}
int GN_GetHasDamagingForcePower()
{
    if(GetHasSpell(FORCE_POWER_CHOKE) ||
       GetHasSpell(FORCE_POWER_DEATH_FIELD) ||
       GetHasSpell(FORCE_POWER_DRAIN_LIFE) ||
       GetHasSpell(FORCE_POWER_DROID_DESTROY) ||
       GetHasSpell(FORCE_POWER_DROID_DISABLE) ||
       GetHasSpell(FORCE_POWER_FORCE_PUSH) ||
       GetHasSpell(FORCE_POWER_FORCE_STORM) ||
       GetHasSpell(FORCE_POWER_FORCE_WAVE) ||
       GetHasSpell(FORCE_POWER_FORCE_WHIRLWIND) ||
       GetHasSpell(FORCE_POWER_KILL) ||
       GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW) ||
       GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW_ADVANCED) ||
       GetHasSpell(FORCE_POWER_LIGHTNING) ||
       GetHasSpell(FORCE_POWER_SHOCK) ||
       GetHasSpell(FORCE_POWER_WOUND) ||
       GetHasSpell(FORCE_POWER_DRAIN_FORCE) || // DJS-OEI 8/19/2004
       GetHasSpell(FORCE_POWER_IMPROVED_DRAIN_FORCE) || // DJS-OEI 8/19/2004
       GetHasSpell(FORCE_POWER_MASTER_DRAIN_FORCE) ||   // DJS-OEI 8/19/2004
       GetHasSpell(FORCE_POWER_FORCE_SCREAM) ||         // DJS-OEI 8/19/2004
       GetHasSpell(FORCE_POWER_IMPROVED_FORCE_SCREAM) ||    // DJS-OEI 8/19/2004
       GetHasSpell(FORCE_POWER_MASTER_FORCE_SCREAM) ||  // DJS-OEI 8/19/2004
       GetHasSpell(FORCE_POWER_FORCE_CRUSH) )   // DJS-OEI 8/19/2004
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Get Weapon Type
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Return 1 if the object is a Melee Weapon and
    2 if the weapon is a Ranged Weapon
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Dec 2, 2002
//:://////////////////////////////////////////////
int GN_GetWeaponType(object oTarget = OBJECT_SELF)
{
    object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTWEAPON,oTarget);
    //GN_MyPrintString("GENERIC DEBUG *************** Valid Weapon = " + GN_ITS(GetIsObjectValid(oItem)));
    //RWT-OEI 08/28/04 - Took out all those calls to GetBaseItemType() and
    //cached the value here instead.
    int nBaseType = GetBaseItemType(oItem);
    if(GetIsObjectValid(oItem))
    {
        if( nBaseType == BASE_ITEM_BLASTER_CARBINE ||
           nBaseType == BASE_ITEM_BLASTER_PISTOL ||
           nBaseType == BASE_ITEM_BLASTER_RIFLE ||
           nBaseType == BASE_ITEM_BOWCASTER ||
           nBaseType == BASE_ITEM_DISRUPTER_PISTOL ||
           nBaseType == BASE_ITEM_DISRUPTER_RIFLE ||
           nBaseType == BASE_ITEM_HEAVY_BLASTER ||
           nBaseType == BASE_ITEM_HEAVY_REPEATING_BLASTER ||
           nBaseType == BASE_ITEM_HOLD_OUT_BLASTER ||
           nBaseType == BASE_ITEM_ION_BLASTER ||
           nBaseType == BASE_ITEM_ION_RIFLE ||
           nBaseType == BASE_ITEM_REPEATING_BLASTER ||
           nBaseType == BASE_ITEM_SONIC_PISTOL ||
           nBaseType == BASE_ITEM_SONIC_RIFLE )
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Ranged Weapon Equipped");
            return 2;
        }
        else if( nBaseType == BASE_ITEM_DOUBLE_BLADED_LIGHTSABER ||
           nBaseType == BASE_ITEM_DOUBLE_BLADED_SWORD ||
           nBaseType == BASE_ITEM_GAMMOREAN_BATTLEAXE ||
           nBaseType == BASE_ITEM_GHAFFI_STICK ||
           nBaseType == BASE_ITEM_LIGHTSABER ||
           nBaseType == BASE_ITEM_LONG_SWORD ||
           nBaseType == BASE_ITEM_QUARTER_STAFF ||
           nBaseType == BASE_ITEM_SHORT_LIGHTSABER ||
           nBaseType == BASE_ITEM_SHORT_SWORD ||
           nBaseType == BASE_ITEM_STUN_BATON ||
           nBaseType == BASE_ITEM_VIBRO_BLADE ||
           nBaseType == BASE_ITEM_VIBRO_DOUBLE_BLADE ||
           nBaseType == BASE_ITEM_VIBRO_SWORD ||
           nBaseType == BASE_ITEM_WOOKIE_WARBLADE ||
           nBaseType == BASE_ITEM_FORCE_PIKE ) // DJS-OEi 8/19/2004
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee Weapon Equipped");
            return 1;
        }
    }
    /*
    if(GetIsObjectValid(oItem))
    {
        if( GetBaseItemType(oItem) == BASE_ITEM_BLASTER_CARBINE ||
           GetBaseItemType(oItem) == BASE_ITEM_BLASTER_PISTOL ||
           GetBaseItemType(oItem) == BASE_ITEM_BLASTER_RIFLE ||
           GetBaseItemType(oItem) == BASE_ITEM_BOWCASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_DISRUPTER_PISTOL ||
           GetBaseItemType(oItem) == BASE_ITEM_DISRUPTER_RIFLE ||
           GetBaseItemType(oItem) == BASE_ITEM_HEAVY_BLASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_HEAVY_REPEATING_BLASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_HOLD_OUT_BLASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_ION_BLASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_ION_RIFLE ||
           GetBaseItemType(oItem) == BASE_ITEM_REPEATING_BLASTER ||
           GetBaseItemType(oItem) == BASE_ITEM_SONIC_PISTOL ||
           GetBaseItemType(oItem) == BASE_ITEM_SONIC_RIFLE )
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Ranged Weapon Equipped");
            return 2;
        }
        else if( GetBaseItemType(oItem) == BASE_ITEM_DOUBLE_BLADED_LIGHTSABER ||
           GetBaseItemType(oItem) == BASE_ITEM_DOUBLE_BLADED_SWORD ||
           GetBaseItemType(oItem) == BASE_ITEM_GAMMOREAN_BATTLEAXE ||
           GetBaseItemType(oItem) == BASE_ITEM_GHAFFI_STICK ||
           GetBaseItemType(oItem) == BASE_ITEM_LIGHTSABER ||
           GetBaseItemType(oItem) == BASE_ITEM_LONG_SWORD ||
           GetBaseItemType(oItem) == BASE_ITEM_QUARTER_STAFF ||
           GetBaseItemType(oItem) == BASE_ITEM_SHORT_LIGHTSABER ||
           GetBaseItemType(oItem) == BASE_ITEM_SHORT_SWORD ||
           GetBaseItemType(oItem) == BASE_ITEM_STUN_BATON ||
           GetBaseItemType(oItem) == BASE_ITEM_VIBRO_BLADE ||
           GetBaseItemType(oItem) == BASE_ITEM_VIBRO_DOUBLE_BLADE ||
           GetBaseItemType(oItem) == BASE_ITEM_VIBRO_SWORD ||
           GetBaseItemType(oItem) == BASE_ITEM_WOOKIE_WARBLADE ||
           GetBaseItemType(oItem) == BASE_ITEM_FORCE_PIKE ) // DJS-OEi 8/19/2004
        {
            //GN_MyPrintString("GENERIC DEBUG *************** Melee Weapon Equipped");
            return 1;
        }
    }
    */
    GN_MyPrintString("GENERIC DEBUG *************** Return No Weapon Type");
    return 0;
}
//RWT-OEI 08/28/04
//Just pass in the base item number and determine if it is
//ranged or melee weapon.
int GN_GetWeaponTypeFromBaseItem(int nBaseType)
{
    if( nBaseType == BASE_ITEM_BLASTER_CARBINE ||
       nBaseType == BASE_ITEM_BLASTER_PISTOL ||
       nBaseType == BASE_ITEM_BLASTER_RIFLE ||
       nBaseType == BASE_ITEM_BOWCASTER ||
       nBaseType == BASE_ITEM_DISRUPTER_PISTOL ||
       nBaseType == BASE_ITEM_DISRUPTER_RIFLE ||
       nBaseType == BASE_ITEM_HEAVY_BLASTER ||
       nBaseType == BASE_ITEM_HEAVY_REPEATING_BLASTER ||
       nBaseType == BASE_ITEM_HOLD_OUT_BLASTER ||
       nBaseType == BASE_ITEM_ION_BLASTER ||
       nBaseType == BASE_ITEM_ION_RIFLE ||
       nBaseType == BASE_ITEM_REPEATING_BLASTER ||
       nBaseType == BASE_ITEM_SONIC_PISTOL ||
       nBaseType == BASE_ITEM_SONIC_RIFLE )
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Ranged Weapon Equipped");
        return 2;
    }
    else if( nBaseType == BASE_ITEM_DOUBLE_BLADED_LIGHTSABER ||
       nBaseType == BASE_ITEM_DOUBLE_BLADED_SWORD ||
       nBaseType == BASE_ITEM_GAMMOREAN_BATTLEAXE ||
       nBaseType == BASE_ITEM_GHAFFI_STICK ||
       nBaseType == BASE_ITEM_LIGHTSABER ||
       nBaseType == BASE_ITEM_LONG_SWORD ||
       nBaseType == BASE_ITEM_QUARTER_STAFF ||
       nBaseType == BASE_ITEM_SHORT_LIGHTSABER ||
       nBaseType == BASE_ITEM_SHORT_SWORD ||
       nBaseType == BASE_ITEM_STUN_BATON ||
       nBaseType == BASE_ITEM_VIBRO_BLADE ||
       nBaseType == BASE_ITEM_VIBRO_DOUBLE_BLADE ||
       nBaseType == BASE_ITEM_VIBRO_SWORD ||
       nBaseType == BASE_ITEM_WOOKIE_WARBLADE ||
       nBaseType == BASE_ITEM_FORCE_PIKE ) // DJS-OEi 8/19/2004
    {
        //GN_MyPrintString("GENERIC DEBUG *************** Melee Weapon Equipped");
        return 1;
    }
    else
    {
        return 0;//Return 0 by default.
    }
}
//
//::///////////////////////////////////////////////
//:: Equip Appropriate Weapon
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets the NPC to eqyuip a melee = 1 or
    ranged = 2 weapon.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 13, 2003
//:://////////////////////////////////////////////
int GN_EquipAppropriateWeapon()
{
    object oItem;
    if(GetIsObjectValid(GetAttackTarget()) &&
       GetDistanceBetween(GetAttackTarget(), OBJECT_SELF) <= 3.0 &&
       GN_GetWeaponType() != 1 &&
       GetRacialType(OBJECT_SELF) == RACIAL_TYPE_HUMAN &&
       !IsObjectPartyMember(OBJECT_SELF))
    {
        oItem = GetFirstItemInInventory();
        while(GetIsObjectValid(oItem))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Checking Melee Weapon");
            if( GetBaseItemType(oItem) == BASE_ITEM_DOUBLE_BLADED_LIGHTSABER ||
               GetBaseItemType(oItem) == BASE_ITEM_DOUBLE_BLADED_SWORD ||
               GetBaseItemType(oItem) == BASE_ITEM_GAMMOREAN_BATTLEAXE ||
               GetBaseItemType(oItem) == BASE_ITEM_GHAFFI_STICK ||
               GetBaseItemType(oItem) == BASE_ITEM_LIGHTSABER ||
               GetBaseItemType(oItem) == BASE_ITEM_LONG_SWORD ||
               GetBaseItemType(oItem) == BASE_ITEM_QUARTER_STAFF ||
               GetBaseItemType(oItem) == BASE_ITEM_SHORT_LIGHTSABER ||
               GetBaseItemType(oItem) == BASE_ITEM_SHORT_SWORD ||
               GetBaseItemType(oItem) == BASE_ITEM_STUN_BATON ||
               GetBaseItemType(oItem) == BASE_ITEM_VIBRO_BLADE ||
               GetBaseItemType(oItem) == BASE_ITEM_VIBRO_DOUBLE_BLADE ||
               GetBaseItemType(oItem) == BASE_ITEM_VIBRO_SWORD ||
               GetBaseItemType(oItem) == BASE_ITEM_WOOKIE_WARBLADE ||
               GetBaseItemType(oItem) == BASE_ITEM_FORCE_PIKE ) // DJS-OEI 8/19/2004
            {
                GN_MyPrintString("GENERIC DEBUG *************** Equipping Melee Weapon");
                //ActionEquipItem(oItem, INVENTORY_SLOT_RIGHTWEAPON, TRUE);
                ActionEquipMostDamagingMelee();
                return TRUE;
            }
            else
            {
              oItem = GetNextItemInInventory();
            }
        }
    }
    else if(GN_GetWeaponType() != 2 &&
            GetLevelByClass(CLASS_TYPE_JEDICONSULAR) == 0 &&
            GetLevelByClass(CLASS_TYPE_JEDIGUARDIAN) == 0 &&
            GetLevelByClass(CLASS_TYPE_JEDISENTINEL) == 0 &&
            GetLevelByClass(CLASS_TYPE_JEDIWEAPONMASTER) == 0 &&    // DJS-OEI 8/19/2004
            GetLevelByClass(CLASS_TYPE_JEDIMASTER) == 0 &&          // DJS-OEI 8/19/2004
            GetLevelByClass(CLASS_TYPE_JEDIWATCHMAN) == 0 &&        // DJS-OEI 8/19/2004
            GetLevelByClass(CLASS_TYPE_SITHMARAUDER) == 0 &&        // DJS-OEI 8/19/2004
            GetLevelByClass(CLASS_TYPE_SITHLORD) == 0 &&            // DJS-OEI 8/19/2004
            GetLevelByClass(CLASS_TYPE_SITHASSASSIN) == 0 &&        // DJS-OEI 8/19/2004
            //GetIsObjectValid(GetAttackTarget()) &&
            GetDistanceBetween(GetAttemptedAttackTarget(), OBJECT_SELF) > 3.0 &&
            !IsObjectPartyMember(OBJECT_SELF))
    {
        oItem = GetFirstItemInInventory();
        while(GetIsObjectValid(oItem))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Checking Ranged Weapon");
            if( GetBaseItemType(oItem) == BASE_ITEM_BLASTER_CARBINE ||
               GetBaseItemType(oItem) == BASE_ITEM_BLASTER_PISTOL ||
               GetBaseItemType(oItem) == BASE_ITEM_BLASTER_RIFLE ||
               GetBaseItemType(oItem) == BASE_ITEM_BOWCASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_DISRUPTER_PISTOL ||
               GetBaseItemType(oItem) == BASE_ITEM_DISRUPTER_RIFLE ||
               GetBaseItemType(oItem) == BASE_ITEM_HEAVY_BLASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_HEAVY_REPEATING_BLASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_HOLD_OUT_BLASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_ION_BLASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_ION_RIFLE ||
               GetBaseItemType(oItem) == BASE_ITEM_REPEATING_BLASTER ||
               GetBaseItemType(oItem) == BASE_ITEM_SONIC_PISTOL ||
               GetBaseItemType(oItem) == BASE_ITEM_SONIC_RIFLE )
              {
                GN_MyPrintString("GENERIC DEBUG *************** Equipping Ranged Weapon");
                //ActionEquipItem(oItem, INVENTORY_SLOT_RIGHTWEAPON, TRUE);
                ActionEquipMostDamagingRanged();
                return TRUE;
              }
              else
              {
                oItem = GetNextItemInInventory();
              }
         }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Should not currently change weapons");
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Check Friendly Fire on Target
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Takes a target object and a radius and
    returns how many friendly targets
    are in that zone.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17, 2003
//:://////////////////////////////////////////////
int GN_CheckFriendlyFireOnTarget(object oTarget, float fDistance = 4.0)
{
    int nCnt, nHD, nMyHD;
    nMyHD = GetHitDice(OBJECT_SELF);
    object oCheck = GetFirstObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
    while(GetIsObjectValid(oCheck))
    {
        //P.W.(May 20, 2003) - Put a dead check here for whether the person being checked is dead.
        if(GetIsFriend(oCheck) && !GetIsDead(oCheck))
        {
            nCnt++;
        }
        oCheck = GetNextObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
    }
    return nCnt;
}
//::///////////////////////////////////////////////
//:: Check For Enemies Around Target
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Takes a target object and a radius and
    returns how many targets of the enemy faction
    are in that zone.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2001
//:://////////////////////////////////////////////
int GN_CheckEnemyGroupingOnTarget(object oTarget, float fDistance = 4.0)
{
    int nCnt;
    object oCheck = GetFirstObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
    while(GetIsObjectValid(oCheck))
    {
        //P.W.(May 20, 2003) - Put a dead check here for whether the person being checked is dead.
        if(GetIsEnemy(oCheck) && !GetIsDead(oCheck))
        {
            nCnt++;
        }
        oCheck = GetNextObjectInShape(SHAPE_SPHERE, fDistance, GetLocation(oTarget));
    }
    return nCnt;
}
//::///////////////////////////////////////////////
//:: Find Grenade Target
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and marks a group as a viable
    target for a grenade
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17m 2003
//:://////////////////////////////////////////////
object GN_FindGrenadeTarget()
{
    int nMinimum = 0;
    if(IsObjectPartyMember(OBJECT_SELF))
    {
        nMinimum = 1;
    }
    int nFriend = 0;
    int nEnemy = 0;
    int nEnemyCnt = 0;
    object oFinal;
    object oCheck = GetFirstObjectInShape(SHAPE_SPHERE, 40.0, GetLocation(OBJECT_SELF));
    while(GetIsObjectValid(oCheck))
    {
        if(GetObjectSeen(oCheck) && !GetIsDead(oCheck))
        {
            nFriend = GN_CheckFriendlyFireOnTarget(oCheck);
            nEnemy = GN_CheckEnemyGroupingOnTarget(oCheck);
            //GN_MyPrintString("GENERIC DEBUG *************** Friends " + GN_ITS(nFriend) + "Enemies" + GN_ITS(nEnemy));
            if(nEnemy > nMinimum && nFriend == 0 && nEnemyCnt < nEnemy)
            {
                oFinal = oCheck;
                nEnemyCnt = nEnemy;
            }
        }
        oCheck = GetNextObjectInShape(SHAPE_SPHERE, 40.0, GetLocation(OBJECT_SELF));
    }
    return oFinal;
}
//::///////////////////////////////////////////////
//:: Find Grenade Target
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and marks a group as a
    viable target for a AOE force power
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17m 2003
//:://////////////////////////////////////////////
object GN_FindAOETarget()
{
    int nEnemy = 0;
    int nEnemyCnt = 0;
    object oFinal;
    object oCheck = GetFirstObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF));
    while(GetIsObjectValid(oCheck))
    {
        nEnemy = GN_CheckEnemyGroupingOnTarget(oCheck,4.0);
        if(nEnemy > 2 && nEnemyCnt < nEnemy)
        {
            oFinal = oCheck;
            nEnemyCnt = nEnemy;
        }
        oCheck = GetNextObjectInShape(SHAPE_SPHERE, 30.0, GetLocation(OBJECT_SELF));
    }
    return oFinal;
}
//::///////////////////////////////////////////////
//:: Get Grenade Talent
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a talent based on the target.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 17, 2003
//:://////////////////////////////////////////////
talent GN_GetGrenadeTalent(int nDroid = FALSE)
{
    // DJS-OEI 8/19/2004
    // Had to rewrite this function a bit
    // since we added new grenades as well as
    // wrist-fired rockets/darts.
    // Determine if this creature has a Wrist Launcher
    // equipped. If so, they will be able to use rockets.
    int bHasWristLauncher = 0;
    object oItem = GetItemInSlot( INVENTORY_SLOT_LEFTARM );
    if( GetIsObjectValid( oItem ) &&
        GetBaseItemType( oItem ) == BASE_ITEM_WRIST_LAUNCHER ) {
        bHasWristLauncher = 1;
    }
    else {
        oItem = GetItemInSlot( INVENTORY_SLOT_RIGHTARM );
        if( GetIsObjectValid( oItem ) &&
            GetBaseItemType( oItem ) == BASE_ITEM_WRIST_LAUNCHER ) {
            bHasWristLauncher = 1;
        }
    }
    talent tUse;
    talent tNull;
    // Grenades
    int n87, n88, n89, n90, n91, n92, n93, n94, n95, n186, n187;
    // Rockets and Darts
    int n185, n190, n191, n192, n193, n194, n195, n196, n197, n198, n199;
    int nRand = 0;
    // Now, set the flags for the grenades we have on us that
    // would be effective against our target.
    // Perform a loop of 87 - 95.
    int nCnt = 87;
    for(nCnt; nCnt < 96; nCnt++)
    {
        tUse = TalentSpell(nCnt);
        if(GetCreatureHasTalent(tUse))
        {
            switch(nCnt)
            {
                case 87:    // Frag Grenade
                {
                    n87 = TRUE;
                    nRand++;
                }
                break;
                case 88:    // Stun Grenade
                {
                    if(nDroid == FALSE)
                    {
                        n88 = TRUE;
                        nRand++;
                    }
                }
                break;
                case 89:    // Thermal Detonator
                {
                    n89 = TRUE;
                    nRand++;
                }
                break;
                case 90:    // Poison Grenade
                {
                    if(nDroid == FALSE)
                    {
                        n90 = TRUE;
                        nRand++;
                    }
                }
                break;
                case 91:    // Sonic Grenade
                {
                    if(nDroid == FALSE)
                    {
                        n91 = TRUE;
                        nRand++;
                    }
                }
                break;
                case 92:    // Adhesive Grenade
                {
                    if(nDroid == FALSE)
                    {
                        n92 = TRUE;
                        nRand++;
                    }
                }
                break;
                case 93:    // Cryoban Grenade
                {
                    if(nDroid == FALSE)
                    {
                        n93 = TRUE;
                        nRand++;
                    }
                }
                break;
                case 94:    // Fire Grenade
                {
                    n94 = TRUE;
                    nRand++;
                }
                break;
                case 95:    // Ion Grenade
                {
                    if(nDroid == TRUE)
                    {
                        n95 = TRUE;
                        nRand++;
                    }
                }
                break;
            }
        }
    }
    // Manually handle 186 and 187.
    tUse = TalentSpell(186);    // Sonic Grenade 2
    if(GetCreatureHasTalent(tUse)) {
        if(nDroid == FALSE)
        {
            n186 = TRUE;
            nRand++;
        }
    }
    tUse = TalentSpell(187);    // Sonic Grenade 3
    if(GetCreatureHasTalent(tUse)) {
        if(nDroid == FALSE)
        {
            n187 = TRUE;
            nRand++;
        }
    }
    // Next, set the flags for the rockets/darts we have on us that
    // would be effective against our target. These only work if
    // we have a wrist launcher equipped.
    if( bHasWristLauncher ) {
        // Manually handle 185.
        tUse = TalentSpell(185);    // Explosive Rocket
        if(GetCreatureHasTalent(tUse)) {
            n185 = TRUE;
            nRand++;
        }
        // Perform a loop of 190 - 199.
        int nCnt = 190;
        for(nCnt; nCnt < 200; nCnt++)
        {
            tUse = TalentSpell(nCnt);
            if(GetCreatureHasTalent(tUse))
            {
                switch(nCnt)
                {
                    case 190:    // Piercing (Buster) Rocket
                    {
                        n190 = TRUE;
                        nRand++;
                    }
                    break;
                    case 191:    // Poison Rocket
                    {
                        if(nDroid == FALSE)
                        {
                            n191 = TRUE;
                            nRand++;
                        }
                    }
                    break;
                    case 192:    // Ion Rocket
                    {
                        if(nDroid == TRUE)
                        {
                            n192 = TRUE;
                            nRand++;
                        }
                    }
                    break;
                    case 193:    // Plasma Rocket
                    {
                        n193 = TRUE;
                        nRand++;
                    }
                    break;
                    case 194:    // Concussion Rocket
                    {
                        n194 = TRUE;
                        nRand++;
                    }
                    break;
                    case 195:    // Poison Dart
                    {
                        if(nDroid == FALSE)
                        {
                            n195 = TRUE;
                            nRand++;
                        }
                    }
                    break;
                    case 196:    // Kyber Dart
                    {
                        if(nDroid == FALSE)
                        {
                            n196 = TRUE;
                            nRand++;
                        }
                    }
                    break;
                    case 197:    // Paralysis Rocket
                    {
                        if(nDroid == FALSE)
                        {
                            n197 = TRUE;
                            nRand++;
                        }
                    }
                    break;
                    case 198:    // Tranquilizer Dart
                    {
                        if(nDroid == FALSE)
                        {
                            n198 = TRUE;
                            nRand++;
                        }
                    }
                    break;
                    case 199:    // Lawn Dart
                    {
                        n199 = TRUE;
                        nRand++;
                    }
                    break;
                }
            }
        }
    }
    // We now have a number (nRand) representing the number
    // of various grenades/rockets/darts we can use. Randomly
    // choose one of these to use starting with the rockets
    // since they are cooler than grenades.
    int nRoll;
    if(nRand > 0)
    {
        nRoll = Random(nRand) + 1;
    }
    else
    {
        nRoll = 0;
    }
    //GN_MyPrintString("GENERIC DEBUG *************** Roll = " + GN_ITS(nRoll));
    if(nRand > 0)
    {
        //EXPLOSIVE ROCKET
        if(nRoll == 1 && n185 == TRUE)
        {
            return tUse = TalentSpell(185);
        }
        if(nRoll > 1 && n185 == TRUE)
        {
            nRoll--;
        }
        //PIERCING (BUSTER) ROCKET
        if(nRoll == 1 && n190 == TRUE)
        {
            return tUse = TalentSpell(190);
        }
        if(nRoll > 1 && n190 == TRUE)
        {
            nRoll--;
        }
        //POISON ROCKET
        if(nRoll == 1 && n191 == TRUE)
        {
            return tUse = TalentSpell(191);
        }
        if(nRoll > 1 && n191 == TRUE)
        {
            nRoll--;
        }
        //ION ROCKET
        if(nRoll == 1 && n192 == TRUE)
        {
            return tUse = TalentSpell(192);
        }
        if(nRoll > 1 && n192 == TRUE)
        {
            nRoll--;
        }
        //PLASMA ROCKET
        if(nRoll == 1 && n193 == TRUE)
        {
            return tUse = TalentSpell(193);
        }
        if(nRoll > 1 && n193 == TRUE)
        {
            nRoll--;
        }
        //CONCUSSION ROCKET
        if(nRoll == 1 && n194 == TRUE)
        {
            return tUse = TalentSpell(194);
        }
        if(nRoll > 1 && n194 == TRUE)
        {
            nRoll--;
        }
        //POISON DART
        if(nRoll == 1 && n195 == TRUE)
        {
            return tUse = TalentSpell(195);
        }
        if(nRoll > 1 && n195 == TRUE)
        {
            nRoll--;
        }
        //KYBER DART
        if(nRoll == 1 && n196 == TRUE)
        {
            return tUse = TalentSpell(196);
        }
        if(nRoll > 1 && n196 == TRUE)
        {
            nRoll--;
        }
        //PARALYSIS DART
        if(nRoll == 1 && n197 == TRUE)
        {
            return tUse = TalentSpell(197);
        }
        if(nRoll > 1 && n197 == TRUE)
        {
            nRoll--;
        }
        //TRANQUILIZER DART
        if(nRoll == 1 && n198 == TRUE)
        {
            return tUse = TalentSpell(198);
        }
        if(nRoll > 1 && n198 == TRUE)
        {
            nRoll--;
        }
        //LAWN DART
        if(nRoll == 1 && n199 == TRUE)
        {
            return tUse = TalentSpell(199);
        }
        if(nRoll > 1 && n199 == TRUE)
        {
            nRoll--;
        }
        //FRAG GRENADE
        if(nRoll == 1 && n87 == TRUE)
        {
            return tUse = TalentSpell(87);
        }
        if(nRoll > 1 && n87 == TRUE)
        {
            nRoll--;
        }
        //STUN GRENADE
        if(nRoll == 1 && n88 == TRUE)
        {
            return tUse = TalentSpell(88);
        }
        if(nRoll > 1 && n88 == TRUE)
        {
            nRoll--;
        }
        //THERMAL DETONATOR
        if(nRoll == 1 && n89 == TRUE)
        {
            return tUse = TalentSpell(89);
        }
        if(nRoll > 1 && n89 == TRUE)
        {
            nRoll--;
        }
        //POISON
        if(nRoll == 1 && n90 == TRUE)
        {
            return tUse = TalentSpell(90);
        }
        if(nRoll > 1 && n90 == TRUE)
        {
            nRoll--;
        }
        //SONIC
        if(nRoll == 1 && n91 == TRUE)
        {
            return tUse = TalentSpell(91);
        }
        if(nRoll > 1 && n91 == TRUE)
        {
            nRoll--;
        }
        //ADHESIVE
        if(nRoll == 1 && n92 == TRUE)
        {
            return tUse = TalentSpell(92);
        }
        if(nRoll > 1 && n92 == TRUE)
        {
            nRoll--;
        }
        //CRYOBAN
        if(nRoll == 1 && n93 == TRUE)
        {
            return tUse = TalentSpell(93);
        }
        if(nRoll > 1 && n93 == TRUE)
        {
            nRoll--;
        }
        //PLASMA
        if(nRoll == 1 && n94 == TRUE)
        {
            return tUse = TalentSpell(94);
        }
        if(nRoll > 1 && n94 == TRUE)
        {
            nRoll--;
        }
        // DJS-OEI 2/26/2004
        //SONIC 2
        if(nRoll == 1 && n186 == TRUE)
        {
            return tUse = TalentSpell(186);
        }
        if(nRoll > 1 && n186 == TRUE)
        {
            nRoll--;
        }
        //SONIC 3
        if(nRoll == 1 && n187 == TRUE)
        {
            return tUse = TalentSpell(187);
        }
        if(nRoll > 1 && n187 == TRUE)
        {
            nRoll--;
        }
    }
    GN_MyPrintString("GENERIC DEBUG *************** Grenade Selection Failure");
    return tNull;
}
//::///////////////////////////////////////////////
//:: Get Boss Combat Move
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a talent for the boss to perform
    in combat.  This function will try and pick a
    talent which will inflict maximum damage
    on the party via area of effect spells, grenades
    and debilitating effects.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 2, 2003
//:://////////////////////////////////////////////
talent GN_GetBossCombatMove(int nBossAttackType, int nDroid = FALSE)
{
    talent tInvalid;
    talent tUse;
    int bValid = FALSE;
    if(nBossAttackType == SW_BOSS_ATTACK_TYPE_GRENADE || nBossAttackType == SW_BOSS_ATTACK_ANY)
    {
        tUse = GN_GetGrenadeTalent(nDroid);
        if(GetIsTalentValid(tUse))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Grenade Talent Chosen");
            return tUse;
        }
    }
    if(nBossAttackType == SW_BOSS_ATTACK_TYPE_FORCE_POWER || nBossAttackType == SW_BOSS_ATTACK_ANY)
    {
        tUse = GN_GetAOEForcePower(nDroid);
        if(GetIsTalentValid(tUse))
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Force Power Talent Chosen");
            return tUse;
        }
    }
    if(nBossAttackType == SW_BOSS_ATTACK_TYPE_NPC || nBossAttackType == SW_BOSS_ATTACK_ANY)
    {
        if(d100() > 50)
        {
            tUse = GN_GetTargetedForcePower(nDroid);
            if(GetIsTalentValid(tUse))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Targeted Force Power Talent Chosen");
                return tUse;
            }
            tUse = GN_GetAOEForcePower(nDroid);
            if(GetIsTalentValid(tUse))
            {
                GN_MyPrintString("GENERIC DEBUG *************** Boss AI: AOE Force Power Talent Chosen");
                return tUse;
            }
        }
        if(GN_GetWeaponType() == 1)
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Melee Feat Talent Chosen");
            tUse = GetCreatureTalentRandom(0x1104); //Only melee feats use this code
        }
        else
        {
            GN_MyPrintString("GENERIC DEBUG *************** Boss AI: Range Feat Talent Chosen");
            tUse = GetCreatureTalentRandom(0x1111); //Only ranged feats use this code
        }
        if(GetIsTalentValid(tUse))
        {
            return tUse;
        }
    }
    else if(nBossAttackType == SW_BOSS_ATTACK_TYPE_PC || nBossAttackType == SW_BOSS_ATTACK_ANY)
    {
        if(d100() > 70)
        {
            tUse = GN_GetTargetedForcePower(nDroid);
            if(GetIsTalentValid(tUse))
            {
                return tUse;
            }
            tUse = GN_GetAOEForcePower(nDroid);
            if(GetIsTalentValid(tUse))
            {
                return tUse;
            }
        }
        tUse = GetCreatureTalentRandom(0x1104); //Only melee feats use this code
        if(GetIsTalentValid(tUse))
        {
            return tUse;
        }
        GN_MyPrintString("GENERIC DEBUG *************** Boss AI: No Feats Available");
    }
    //Comment this out so that the boss AI handles the failure not this function.
    /*
    if(!GetIsTalentValid(tUse) && nBossAttackType != SW_BOSS_ATTACK_ANY)
    {
        tUse = GN_GetBossCombatMove(SW_BOSS_ATTACK_ANY);
    }
    */
    return tUse;
}
//::///////////////////////////////////////////////
//:: Get AOE Force Power
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks and returns a random force power that
    can effect more than 1 target.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 2, 2003
//:://////////////////////////////////////////////
talent GN_GetAOEForcePower(int nDroid = FALSE)
{
    talent tUse;
    int nHorror, nInsanity, nStorm, nWave, nSaber, nLightning, nSleep, nStunDroid, nKillDroid, nHowl, nCnt;
    // DJS-OEI 8/19/2004
    // New spells.
    int nScream1, nScream2, nScream3;
    //MODIFIED by Preston Watamaniuk on April 27, 2003
    //Removed Death Field so that it would be used exlusively for Healing.
    //MODIFIED by Preston Watamaniuk on May 14, 2003
    //Put a check into make sure that the same AOE power is not used over and over.
    int nLastForcePower = GetLastForcePowerUsed(OBJECT_SELF);
    GN_MyPrintString("GENERIC DEBUG *************** Last Force Power Used = " + GN_ITS(nLastForcePower));
    //THIS SECTION DETERMINES WHICH POWERS ARE APPLICABLE
    if(GetHasSpell(FORCE_POWER_HORROR) && nDroid == FALSE && nLastForcePower != FORCE_POWER_HORROR)
    {
        nHorror = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_INSANITY) && nDroid == FALSE && nLastForcePower != FORCE_POWER_INSANITY)
    {
        nInsanity = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_FORCE_STORM) && nLastForcePower != FORCE_POWER_FORCE_STORM)
    {
        nStorm = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_FORCE_WAVE) && nLastForcePower != FORCE_POWER_FORCE_WAVE)
    {
        nWave = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_LIGHT_SABER_THROW_ADVANCED) && nLastForcePower != FORCE_POWER_LIGHT_SABER_THROW_ADVANCED)
    {
        nSaber = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_LIGHTNING) && nLastForcePower != FORCE_POWER_LIGHTNING)
    {
        nLightning = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_SLEEP) && nDroid == FALSE && nLastForcePower != FORCE_POWER_SLEEP)//Now Mass Stasis
    {
        nSleep = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_DROID_STUN) && nDroid == TRUE && nLastForcePower != FORCE_POWER_DROID_STUN)
    {
        nStunDroid = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_DROID_DESTROY) && nDroid == TRUE && nLastForcePower != FORCE_POWER_DROID_DESTROY)
    {
        nKillDroid = 1;
        nCnt++;
    }
    talent tHowl  = TalentSpell(131);
    if(GetCreatureHasTalent(tHowl)) //Sonic Howl
    {
        nHowl = 1;
        nCnt++;
    }
    // DJS-OEI 8/19/2004
    if(GetHasSpell(FORCE_POWER_FORCE_SCREAM) && nDroid == FALSE && nLastForcePower != FORCE_POWER_FORCE_SCREAM)
    {
        nScream1 = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_IMPROVED_FORCE_SCREAM) && nDroid == FALSE && nLastForcePower != FORCE_POWER_IMPROVED_FORCE_SCREAM)
    {
        nScream2 = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_MASTER_FORCE_SCREAM) && nDroid == FALSE && nLastForcePower != FORCE_POWER_MASTER_FORCE_SCREAM)
    {
        nScream3 = 1;
        nCnt++;
    }
    //THIS SECTION DETERMINES WHICH POWER TO USE
    int nRoll;
    if(nCnt > 0)
    {
        nRoll = Random(nCnt) + 1;
    }
    else
    {
        nRoll = 0;
    }
    //Horror
    if(nHorror == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_HORROR);
        nRoll--;
    }
    if(nHorror == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Insanity
    if(nInsanity == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_INSANITY);
        nRoll--;
    }
    if(nHorror == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Force Storm
    if(nStorm == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_FORCE_STORM);
        nRoll--;
    }
    if(nStorm == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Force Wave
    if(nWave == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_FORCE_WAVE);
        nRoll--;
    }
    if(nWave == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Advanced Saber Throw
    if(nSaber == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_LIGHT_SABER_THROW_ADVANCED);
        nRoll--;
    }
    if(nSaber == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Lightning
    if(nLightning == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_LIGHTNING);
        nRoll--;
    }
    if(nLightning == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Mass Stasis
    if(nSleep == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_SLEEP);
        nRoll--;
    }
    if(nSleep == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Stun Droid
    if(nStunDroid == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_DROID_STUN);
        nRoll--;
    }
    if(nStunDroid == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Destroy Droid
    if(nKillDroid == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_DROID_DESTROY);
        nRoll--;
    }
    if(nKillDroid == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Sonic Howl
    if(nKillDroid == 1 && nRoll == 1)
    {
        tUse = TalentSpell(131);
        nRoll--;
    }
    if(nHowl == 1 && nRoll > 1)
    {
        nRoll--;
    }
    // DJS-OEI 8/19/2004
    //Scream 1
    if(nScream1 == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_FORCE_SCREAM);
        nRoll--;
    }
    if(nScream1 == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Scream 2
    if(nScream2 == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_IMPROVED_FORCE_SCREAM);
        nRoll--;
    }
    if(nScream2 == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Scream 3
    if(nScream3 == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_MASTER_FORCE_SCREAM);
        nRoll--;
    }
    if(nScream3 == 1 && nRoll > 1)
    {
        nRoll--;
    }
    GN_MyPrintString("GENERIC DEBUG *************** Force Power Returned = " + GN_ITS(GetIdFromTalent(tUse)));
    return tUse;
}
//::///////////////////////////////////////////////
//:: Get Targeted Force Power
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks and returns a random force power that
    can effect 1 target.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 2, 2003
//:://////////////////////////////////////////////
talent GN_GetTargetedForcePower(int nDroid = FALSE)
{
    talent tUse;
    int nChoke, nAfflict, nPlague, nPush, nWind, nLightning, nKill, nHorror, nWound, nStasis, nDroid, nKnock, nHowl, nCnt;
    // DJS-OEI 8/19/2004
    int nScream1, nScream2, nScream3;
    if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_DROID)
    {
        tUse = GetCreatureTalentRandom(0x8000);
        if(GetIsTalentValid(tUse))
        {
            return tUse;
        }
    }
    //MODIFIED by Preston Watamaniuk on April 27, 2003
    //Removed Drain Life so that it would be used exlusively for Healing.
    if(GetHasSpell(FORCE_POWER_CHOKE) && nDroid == FALSE)
    {
        nChoke = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_AFFLICTION) && nDroid == FALSE)
    {
        nAfflict = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_PLAGUE) && nDroid == FALSE)
    {
        nPlague = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_FORCE_PUSH))
    {
        nPush = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_FORCE_WHIRLWIND))
    {
        nWind = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_LIGHTNING))
    {
        nLightning = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_KILL) && nDroid == FALSE)
    {
        nKill = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_HORROR) && nDroid == FALSE)
    {
        nHorror = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_WOUND) && nDroid == FALSE)
    {
        nWound = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_HOLD))
    {
        nStasis = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_DROID_DISABLE) && nDroid == TRUE)
    {
        nDroid = 1;
        nCnt++;
    }
    talent tSlam  = TalentSpell(83);
    if(GetCreatureHasTalent(tSlam)) //Monster Slam
    {
        nKnock = 1;
        nCnt++;
    }
    // DJS-OEI 8/19/2004
    if(GetHasSpell(FORCE_POWER_FORCE_SCREAM) && nDroid == FALSE)
    {
        nScream1 = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_IMPROVED_FORCE_SCREAM) && nDroid == FALSE)
    {
        nScream2 = 1;
        nCnt++;
    }
    if(GetHasSpell(FORCE_POWER_MASTER_FORCE_SCREAM) && nDroid == FALSE)
    {
        nScream3 = 1;
        nCnt++;
    }
    //THIS SECTION DETERMINES WHICH POWER TO USE
    int nRoll;
    if(nCnt > 0)
    {
        nRoll = Random(nCnt) + 1;
    }
    else
    {
        nRoll = 0;
    }
    //Choke
    if(nChoke == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_CHOKE);
        nRoll--;
    }
    if(nChoke == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Affliction
    if(nAfflict == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_AFFLICTION);
        nRoll--;
    }
    if(nAfflict == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Plague
    if(nPlague == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_PLAGUE);
        nRoll--;
    }
    if(nPlague == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Force Push
    if(nPush == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_FORCE_PUSH);
        nRoll--;
    }
    if(nPush == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Force Whirlwind
    if(nWind == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_FORCE_WHIRLWIND);
        nRoll--;
    }
    if(nWind == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Lightning
    if(nLightning == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_LIGHTNING);
        nRoll--;
    }
    if(nLightning == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Kill
    if(nKill == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_KILL);
        nRoll--;
    }
    if(nKill == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Horror
    if(nHorror == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_HORROR);
        nRoll--;
    }
    if(nHorror == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Wound
    if(nWound== 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_WOUND);
        nRoll--;
    }
    if(nWound == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Stasis
    if(nStasis== 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_HOLD);
        nRoll--;
    }
    if(nStasis == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Disable Droid
    if(nDroid== 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_DROID_DISABLE);
        nRoll--;
    }
    if(nDroid == 1 && nRoll > 1)
    {
        nRoll--;
    }
    //Monster Slam
    if(nKnock == 1 && nRoll == 1)
    {
        tUse = TalentSpell(83);
        nRoll--;
    }
    if(nKnock == 1 && nRoll > 1)
    {
        nRoll--;
    }
    // DJS-OEI 8/19/2004
    // Scream 1
    if(nScream1 == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_FORCE_SCREAM);
        nRoll--;
    }
    if(nScream1 == 1 && nRoll > 1)
    {
        nRoll--;
    }
    // Scream 2
    if(nScream2 == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_IMPROVED_FORCE_SCREAM);
        nRoll--;
    }
    if(nScream2 == 1 && nRoll > 1)
    {
        nRoll--;
    }
    // Scream 3
    if(nScream3 == 1 && nRoll == 1)
    {
        tUse = TalentSpell(FORCE_POWER_MASTER_FORCE_SCREAM);
        nRoll--;
    }
    if(nScream3 == 1 && nRoll > 1)
    {
        nRoll--;
    }
    return tUse;
}
//::///////////////////////////////////////////////
//:: Get Active Party Member Count
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the number of party members who
    are active
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 2, 2003
//:://////////////////////////////////////////////
int GN_GetActivePartyMemberCount()
{
    object oNPC1 = GetPartyMemberByIndex(0);
    object oNPC2 = GetPartyMemberByIndex(1);
    object oNPC3 = GetPartyMemberByIndex(2);
    int nCnt = 0;
    if(GetIsObjectValid(oNPC1) && GetCurrentHitPoints(oNPC1) > 0 && GetObjectSeen(oNPC1))
    {
        nCnt++;
    }
    if(GetIsObjectValid(oNPC2) && GetCurrentHitPoints(oNPC2) > 0 && GetObjectSeen(oNPC2))
    {
        nCnt++;
    }
    if(GetIsObjectValid(oNPC3) && GetCurrentHitPoints(oNPC3) > 0 && GetObjectSeen(oNPC3))
    {
        nCnt++;
    }
    return nCnt;
}
//::///////////////////////////////////////////////
//:: Get Active Party Member
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a party member who is active a not
    currently controlled by the PC.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 2, 2003
//:://////////////////////////////////////////////
/*
    MODIFIED by Preston Watamaniuk on March 8, 2003
    Added some functionality so that the Drain Life
    will be targeted on the 0 Index as well as the
    other party members. Also if Drain = TRUE then
    no droids will be returned.
    This function will return the nearest non-droid
    enemy if the party is freindly.
*/
//:://////////////////////////////////////////////
object GN_GetActivePartyMember(int nDrainTarget = FALSE)
{
    object oNPC1 = GetPartyMemberByIndex(0);
    object oNPC2 = GetPartyMemberByIndex(1);
    object oNPC3 = GetPartyMemberByIndex(2);
    object oTarget;
    int nCnt = 0;
    int nRoll;
    int nNPC1 = FALSE;
    int nNPC2 = FALSE;
    int nNPC3 = FALSE;
    if(GetIsObjectValid(oNPC2) && GetCurrentHitPoints(oNPC2) > 0 && GetObjectSeen(oNPC2))
    {
        if(GetRacialType(oNPC2) != RACIAL_TYPE_DROID || nDrainTarget == FALSE)
        {
            nCnt++;
            nNPC2 = TRUE;
        }
    }
    if(GetIsObjectValid(oNPC3) && GetCurrentHitPoints(oNPC3) > 0 && GetObjectSeen(oNPC3))
    {
        if(GetRacialType(oNPC3) != RACIAL_TYPE_DROID || nDrainTarget == FALSE)
        {
            nCnt++;
            nNPC3 = TRUE;
        }
    }
    if(nDrainTarget == TRUE)
    {
        if(GetIsObjectValid(oNPC1) && GetCurrentHitPoints(oNPC1) > 0 && GetObjectSeen(oNPC1))
        {
            if(GetRacialType(oNPC1) != RACIAL_TYPE_DROID)
            {
                nCnt++;
                nNPC1 = TRUE;
            }
        }
    }
    if(nCnt == 0)
    {
        oTarget = OBJECT_INVALID;
    }
    else if(nCnt == 1)
    {
        if(nNPC2 == TRUE){oTarget = oNPC2;}
        else if(nNPC3 == TRUE){oTarget = oNPC3;}
        else if(nNPC1 == TRUE){oTarget = oNPC1;}
    }
    else if(nCnt == 2)
    {
        nRoll = d100();
        if(nNPC1 == TRUE && nNPC2 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC1;}
            else{oTarget = oNPC2;}
        }
        else if(nNPC1 == TRUE && nNPC3 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC1;}
            else{oTarget = oNPC3;}
        }
        else if(nNPC2 == TRUE && nNPC3 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC2;}
            else{oTarget = oNPC3;}
        }
    }
    else if(nCnt == 3)
    {
        nRoll = d100();
        if(nRoll <= 33){oTarget = oNPC1;}
        else if(nRoll > 33 && nRoll <= 66) {oTarget = oNPC2;}
        else if(nRoll > 66 && nRoll <= 100) {oTarget = oNPC3;}
    }
    //MODIFIED by Preston Watamaniuk on May 18, 2003
    //Changed the racial type to Human from Droid.
    if(!GetIsEnemy(oTarget, OBJECT_SELF) && nDrainTarget == TRUE)
    {
        GN_MyPrintString("GENERIC DEBUG *************** Searching for Alternate Target");
        oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_RACIAL_TYPE, RACIAL_TYPE_HUMAN);
        GN_MyPrintString("GENERIC DEBUG *************** Alternate Target = " + GN_ReturnDebugName(oTarget));
    }
    GN_MyPrintString("GENERIC DEBUG *************** Heal Drain Target = " + GN_ITS(nDrainTarget));
    GN_MyPrintString("GENERIC DEBUG *************** Get Active Party Member: " + GN_ReturnDebugName(oTarget));
    return oTarget;
}
//::///////////////////////////////////////////////
//:: Return Active Party Member
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This function returns an active party member.
    They must not be dead.  The debilitated
    parameter will ignore those party members
    already debilitated.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2003
//:://////////////////////////////////////////////
object GN_ReturnActivePartyMember(int nDebil = FALSE)
{
    object oNPC1 = GetPartyMemberByIndex(0);
    object oNPC2 = GetPartyMemberByIndex(1);
    object oNPC3 = GetPartyMemberByIndex(2);
    object oTarget;
    int nCnt = 0;
    int nRoll;
    int nNPC1 = FALSE;
    int nNPC2 = FALSE;
    int nNPC3 = FALSE;
    if(GetIsObjectValid(oNPC2) && GetCurrentHitPoints(oNPC2) > 0 && GetObjectSeen(oNPC2))
    {
        if(nDebil == FALSE || !GetIsDebilitated(oNPC2))
        {
            nCnt++;
            nNPC2 = TRUE;
        }
    }
    if(GetIsObjectValid(oNPC3) && GetCurrentHitPoints(oNPC3) > 0 && GetObjectSeen(oNPC3))
    {
        if(nDebil == FALSE || !GetIsDebilitated(oNPC2))
        {
            nCnt++;
            nNPC3 = TRUE;
        }
    }
    if(GetIsObjectValid(oNPC1) && GetCurrentHitPoints(oNPC1) > 0 && GetObjectSeen(oNPC1))
    {
        if(nDebil == FALSE || !GetIsDebilitated(oNPC2))
        {
            nCnt++;
            nNPC1 = TRUE;
        }
    }
    if(nCnt == 0)
    {
        oTarget = OBJECT_INVALID;
    }
    else if(nCnt == 1)
    {
        if(nNPC2 == TRUE){oTarget = oNPC2;}
        else if(nNPC3 == TRUE){oTarget = oNPC3;}
        else if(nNPC1 == TRUE){oTarget = oNPC1;}
    }
    else if(nCnt == 2)
    {
        nRoll = d100();
        if(nNPC1 == TRUE && nNPC2 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC1;}
            else{oTarget = oNPC2;}
        }
        else if(nNPC1 == TRUE && nNPC3 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC1;}
            else{oTarget = oNPC3;}
        }
        else if(nNPC2 == TRUE && nNPC3 == TRUE)
        {
            if(nRoll > 50){oTarget = oNPC2;}
            else{oTarget = oNPC3;}
        }
    }
    else if(nCnt == 3)
    {
        nRoll = d100();
        if(nRoll <= 33){oTarget = oNPC1;}
        else if(nRoll > 33 && nRoll <= 66) {oTarget = oNPC2;}
        else if(nRoll > 66 && nRoll <= 100) {oTarget = oNPC3;}
    }
    return oTarget;
}
//:://///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Generic Include Debug Commands
//:: Copyright (c) 2001 Bioware Corp.
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: June 12, 2002
//::////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void GN_MySpeakString(string sString)
{
    //SpeakString(sString);
}
void GN_AssignPCDebugString(string sString)
{
    object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
    if(GetIsObjectValid(oPC))
    {
        AssignCommand(oPC, SpeakString(sString));
    }
}
void GN_PostString(string sString = "",int x = 10,int y = 10,float fShow = 4.0)
{
    //AurPostString(sString,x,y,fShow);
}
void GN_MyPrintString(string sString)
{
    if(!ShipBuild())
    {
        PrintString(sString);
    }
}
void GN_PostShoutString(string sString = "",int x = 10,int y = 10,float fShow = 4.0)
{
    //AurPostString(sString,x,y,fShow);
}
void GN_MyPrintShoutString(string sString)
{
    if(!ShipBuild())
    {
        //PrintString(sString);
    }
}
void GN_PrintShoutType(object oShouter, int nShout)
{
    /*
    //I WAS ATTACKED
    if(nShout == 1)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " ATTACKED");
    }
    //I WAS KILLED
    else if(nShout == 3)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " KILLED");
    }
    //CALL TO ARMS
    else if(nShout == 6)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " CALL TO ARMS");
    }
    //SUPRESS FORCE
    else if(nShout == 9)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " WANTS FORCE SUPPRESSED");
    }
    //FLEE FROM GRENADES
    else if(nShout == 12)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " GRENADE THROWN");
    }
    //I SEE AN ENEMY
    else if(nShout == 15)
    {
        GN_MyPrintString("GENERIC DEBUG *************** " + GetName(oShouter) + "/" + ObjectToString(oShouter) + " SEES AN ENEMY");
    }
    */
}
string GN_ReturnDebugName(object oTarget)
{
    string sName = GetName(oTarget) + "_" + ObjectToString(oTarget);
    return sName;
}
string GN_FetchComboString(int nCombo)
{
    if(nCombo == SW_COMBO_RANGED_FEROCIOUS){return "SW_COMBO_RANGED_FEROCIOUS";}
    else if(nCombo == SW_COMBO_RANGED_AGGRESSIVE){return "SW_COMBO_RANGED_AGGRESSIVE";}
    else if(nCombo == SW_COMBO_RANGED_DISCIPLINED){return "SW_COMBO_RANGED_DISCIPLINED";}
    else if(nCombo == SW_COMBO_RANGED_CAUTIOUS){return "SW_COMBO_RANGED_CAUTIOUS";}
    else if(nCombo == SW_COMBO_MELEE_FEROCIOUS){return "SW_COMBO_MELEE_FEROCIOUS";}
    else if(nCombo == SW_COMBO_MELEE_AGGRESSIVE){return "SW_COMBO_MELEE_AGGRESSIVE";}
    else if(nCombo == SW_COMBO_MELEE_DISCIPLINED){return "SW_COMBO_MELEE_DISCIPLINED";}
    else if(nCombo == SW_COMBO_MELEE_CAUTIOUS){return "SW_COMBO_MELEE_CAUTIOUS";}
    else if(nCombo == SW_COMBO_BUFF_PARTY){return "SW_COMBO_BUFF_PARTY";}
    else if(nCombo == SW_COMBO_BUFF_DEBILITATE){return "SW_COMBO_BUFF_DEBILITATE";}
    else if(nCombo == SW_COMBO_BUFF_DAMAGE){return "SW_COMBO_BUFF_DAMAGE";}
    else if(nCombo == SW_COMBO_BUFF_DEBILITATE_DESTROY){return "SW_COMBO_BUFF_DEBILITATE_DESTROY";}
    else if(nCombo == SW_COMBO_SUPRESS_DEBILITATE_DESTROY){return "SW_COMBO_SUPRESS_DEBILITATE_DESTROY";}
    else if(nCombo == SW_COMBO_SITH_ATTACK){return "SW_COMBO_SITH_ATTACK";}
    else if(nCombo == SW_COMBO_BUFF_ATTACK){return "SW_COMBO_BUFF_ATTACK";}
    else if(nCombo == SW_COMBO_SITH_CONFOUND){return "SW_COMBO_SITH_CONFOUND";}
    else if(nCombo == SW_COMBO_JEDI_SMITE){return "SW_COMBO_JEDI_SMITE";}
    else if(nCombo == SW_COMBO_SITH_TAUNT){return "SW_COMBO_SITH_TAUNT";}
    else if(nCombo == SW_COMBO_SITH_BLADE){return "SW_COMBO_SITH_BLADE";}
    else if(nCombo == SW_COMBO_SITH_CRUSH){return "SW_COMBO_SITH_CRUSH";}
    else if(nCombo == SW_COMBO_JEDI_CRUSH){return "SW_COMBO_JEDI_CRUSH";}
    else if(nCombo == SW_COMBO_SITH_BRUTALIZE){return "SW_COMBO_SITH_BRUTALIZE";}
    else if(nCombo == SW_COMBO_SITH_DRAIN){return "SW_COMBO_SITH_DRAIN";}
    else if(nCombo == SW_COMBO_SITH_ESCAPE){return "SW_COMBO_SITH_ESCAPE";}
    else if(nCombo == SW_COMBO_JEDI_BLITZ){return "SW_COMBO_JEDI_BLITZ";}
    else if(nCombo == SW_COMBO_SITH_SPIKE){return "SW_COMBO_SITH_SPIKE";}
    else if(nCombo == SW_COMBO_SITH_SCYTHE){return "SW_COMBO_SITH_SCYTHE";}
    else if(nCombo == SW_COMBO_DROID_UTILITIES){return "SW_COMBO_DROID_UTILITIES";}
    return "NO COMBO SELECTED";
}
//::///////////////////////////////////////////////
//:: Return AI Style
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the AI style in a string
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 28, 2003
//:://////////////////////////////////////////////
string GN_ReturnAIStyle(object oTarget = OBJECT_SELF)
{
    if(GetNPCAIStyle(oTarget) == NPC_AISTYLE_AID)
    {
        return "NPC_AISTYLE_AID";
    }
    else if(GetNPCAIStyle(oTarget) == NPC_AISTYLE_GRENADE_THROWER)
    {
        return "NPC_AISTYLE_GRENADE_THROWER";
    }
    else if(GetNPCAIStyle(oTarget) == NPC_AISTYLE_JEDI_SUPPORT)
    {
        return "NPC_AISTYLE_JEDI_SUPPORT";
    }
    else if(GetNPCAIStyle(oTarget) == NPC_AISTYLE_DEFAULT_ATTACK)
    {
        return "NPC_AISTYLE_DEFAULT_ATTACK";
    }
    int nAI = GetNPCAIStyle(oTarget);
    string sAI = IntToString(nAI);
    sAI = "No Valid AI Set, state = " + sAI;
    return sAI;
}
string GN_ITS(int sFutureString)
{
    return IntToString(sFutureString);
}
""",
    "k_inc_glob_party": b"""
//:: k_inc_glob_party
/*
These global scripts are to be used to spawn actual party member objects with thier correct equipment, stats, levels, etc.
Use this to place party members for required scripts and cutscenes.
*/
#include "k_inc_debug"
// FUNCTION DECLARATIONS
string  GetNPCTag( int nNPC );
int     GetNPCConstant( string sTag );
void    ClearPlayerParty();
void    SetPlayerParty(int aNPC_CONSTANT_1, int aNPC_CONSTANT_2);
object  SpawnIndividualPartyMember(int aNPC_CONSTANT, string sWP = "WP_gspawn_");
void    SpawnAllAvailablePartyMembers();
object  SpawnIndividualPuppet(int aNPC_CONSTANT, string sWP = "WP_gspawn_");
string  GetPuppetTag( int nNPC );
int     GetPuppetConstant( string sTag );
// FUNCTION DEFINITIONS:
// Sets the Player created character to be the party leader
// and returns all other party members to the 'party base'.
void ClearPlayerParty()
{
    SetPartyLeader(NPC_PLAYER);
    int i;
    for(i = 0; i < 12; i++)
    {
        if(IsNPCPartyMember( i ))
            RemoveNPCFromPartyToBase( i );
    }
}
// sets the Player created character to be the party leader and then fills the party
// with the passed in constants PROVIDED that they have been previously add to the
// 'party base'
void SetPlayerParty(int aNPC_CONSTANT_1, int aNPC_CONSTANT_2)
{
    ClearPlayerParty();
    object oPartyMember1 = SpawnIndividualPartyMember(aNPC_CONSTANT_1);
    object oPartyMember2 = SpawnIndividualPartyMember(aNPC_CONSTANT_2);
    if(GetIsObjectValid(oPartyMember1) )
    {
        AddPartyMember(aNPC_CONSTANT_1, oPartyMember1);
    }
    if(GetIsObjectValid(oPartyMember2) )
    {
        AddPartyMember(aNPC_CONSTANT_2, oPartyMember2);
    }
}
// Will return the tag of the party member constant passed in.
// Will return 'ERROR' if an invalid constant is passed in.
string GetNPCTag( int nNPC )
{
    switch( nNPC )
    {
        case  NPC_ATTON:
        {
            return "atton";
        }break;
        case  NPC_BAO_DUR:
        {
            return "baodur";
        }break;
        case  NPC_CANDEROUS:
        {
            return "mand";
        }break;
        case  NPC_DISCIPLE:
        {
            return "disciple";
        }break;
        case  NPC_G0T0:
        {
            return "g0t0";
        }break;
        case  NPC_HANDMAIDEN:
        {
            return "handmaiden";
        }break;
        case  NPC_HANHARR:
        {
            return "hanharr";
        }break;
        case  NPC_HK_47:
        {
            return "hk47";
        }break;
        case  NPC_KREIA:
        {
            return "kreia";
        }break;
        case  NPC_MIRA:
        {
            return "mira";
        }break;
        case  NPC_T3_M4:
        {
            return "t3m4";
        }break;
        case  NPC_VISAS:
        {
            return "visasmarr";
        }break;
    }
    return "ERROR";
}
string GetPuppetTag( int nNPC )
{
    switch( nNPC )
    {
        case  PUP_SENSORBALL:
        {
            return "remote";
        }break;
    }
    return "ERROR";
}
int GetNPCConstant( string sTag )
{
    if(sTag == "atton")
    {
        return NPC_ATTON;
    }
    else if(sTag == "baodur")
    {
        return  NPC_BAO_DUR;
    }
    else if(sTag == "mand")
    {
        return  NPC_CANDEROUS;
    }
    else if(sTag == "disciple")
    {
        return  NPC_DISCIPLE;
    }
    else if(sTag == "g0t0")
    {
        return  NPC_G0T0;
    }
    else if(sTag == "handmaiden")
    {
        return  NPC_HANDMAIDEN;
    }
    else if(sTag == "hanharr")
    {
        return  NPC_HANHARR;
    }
    else if(sTag == "hk47")
    {
        return  NPC_HK_47;
    }
    else if(sTag == "kreia")
    {
        return  NPC_KREIA;
    }
    else if(sTag == "mira")
    {
        return  NPC_MIRA;
    }
    else if(sTag == "t3m4")
    {
        return  NPC_T3_M4;
    }
    else if(sTag == "visasmarr")
    {
        return  NPC_VISAS;
    }
    return -1;
}
int GetPuppetConstant( string sTag )
{
    if(sTag == "remote")
    {
        return PUP_SENSORBALL;
    }
    return -1;
}
// Will spawn party member represented by aNPC_CONSTANT at thier personal waypoint IF they exist in the
// 'party base'.  This function does NOT add the spawned party member to the actual party.
object SpawnIndividualPartyMember(int aNPC_CONSTANT, string aWP)
{
    string sWP;
    if(aWP == "WP_gspawn_")
    {
        string sTag = GetNPCTag( aNPC_CONSTANT );
        if(sTag == "ERROR")
            return OBJECT_INVALID;
        sWP = aWP + sTag;
    }
    else
    {
        sWP = aWP;
    }
    object oWP = GetObjectByTag(sWP);
    object oPartyMember;
    if(GetIsObjectValid(oWP))
    {
        oPartyMember = SpawnAvailableNPC( aNPC_CONSTANT, GetLocation(oWP));
        if( GetIsObjectValid(oPartyMember))
        {
            //new AWD-OEI 10/23/2004
            SetCreatureAILevel(oPartyMember, AI_LEVEL_HIGH);
            return oPartyMember;
        }
    }
    return OBJECT_INVALID;
}
// Will spawn puppet represented by aNPC_CONSTANT at thier personal waypoint IF they exist in the
// 'party base'.  This function does NOT add the spawned puppet member to the actual party.
object SpawnIndividualPuppet(int aNPC_CONSTANT, string aWP)
{
    string sWP;
    if(aWP == "WP_gspawn_")
    {
        string sTag = GetPuppetTag( aNPC_CONSTANT );
        if(sTag == "ERROR")
            return OBJECT_INVALID;
        sWP = aWP + sTag;
    }
    else
    {
        sWP = aWP;
    }
    object oWP = GetObjectByTag(sWP);
    object oPartyMember;
    if(GetIsObjectValid(oWP))
    {
        oPartyMember = SpawnAvailablePUP( aNPC_CONSTANT, GetLocation(oWP));
        if( GetIsObjectValid(oPartyMember))
            return oPartyMember;
    }
    return OBJECT_INVALID;
}
// Will spawn all available party members at thier personal waypoints.  This function does not add anyone
// to the actual party.
void SpawnAllAvailablePartyMembers()
{
    int i;
    for(i = 0; i < 12; i++)
    {
        if(GetNPCSelectability( i ) != -1)
        {
            if( !GetIsObjectValid(SpawnIndividualPartyMember( i )) )
            {
                AurPostString("NPC could not spawn, invalid NPC or invalid location!",5,15,10.0);
            }
            else
            {
                if(i == NPC_BAO_DUR)//spawn bao's pet
                {
                    SpawnIndividualPuppet(PUP_SENSORBALL);
                }
            }
        }
    }
}
""",
    "k_inc_hawk": b"""
//:: Script Name
/*
    Desc
*/
//:: Created By:
//:: Copyright (c) 2002 Bioware Corp.
#include "k_inc_glob_party"
#include "k_oei_hench_inc"
void StopCombat()
{
    object oPC = GetFirstPC();
    CancelCombat(oPC);
    int i;
    object oEnemy;
    for(i = 0;i < 20;i++)
    {
        oEnemy = GetObjectByTag("REThug4", i);
        if(GetIsObjectValid(oEnemy))
        {
            ChangeToStandardFaction( oEnemy,STANDARD_FACTION_NEUTRAL );
            CancelCombat(oEnemy);
        }
        oEnemy = GetObjectByTag("REThug5", i);
        if(GetIsObjectValid(oEnemy))
        {
            ChangeToStandardFaction( oEnemy,STANDARD_FACTION_NEUTRAL );
            CancelCombat(oEnemy);
        }
    }
    //take care of the captain
    oEnemy = GetObjectByTag("RECapt");
    if(GetIsObjectValid(oEnemy))
    {
        ChangeToStandardFaction( oEnemy,STANDARD_FACTION_NEUTRAL );
        CancelCombat(oEnemy);
    }
}
void ClearEnemies()
{
    int i;
    object oEnemy;
    for(i = 0;i < 20;i++)
    {
        oEnemy = GetObjectByTag("REThug4", i);
        if(GetIsObjectValid(oEnemy))
            DestroyObject(oEnemy);
        oEnemy = GetObjectByTag("REThug5", i);
        if(GetIsObjectValid(oEnemy))
            DestroyObject(oEnemy);
    }
    //take care of the captain
    oEnemy = GetObjectByTag("RECapt");
    if(GetIsObjectValid(oEnemy))
            DestroyObject(oEnemy);
}
void DestroyVisas()
{
    object oVisasTemp2 = GetObjectByTag("VisasBed");
    if(GetIsObjectValid(oVisasTemp2))
    {
        DestroyObject(oVisasTemp2, 0.0, TRUE);
    }
    object oVisasTemp = GetObjectByTag("VisasCut");
    if (GetIsObjectValid(oVisasTemp))
    {
        DestroyObject(oVisasTemp, 0.0, TRUE);
    }
}
void DoSpecialReset(object oNPC, string sModuleName)
{
    if(GetNPCConstant(GetTag(oNPC)) == NPC_ATTON)
    {
        AurPostString("Resetting Atton 1",15,19,10.0);
        DoAttonSpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_BAO_DUR)
    {
        DoBaoDurSpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_CANDEROUS)
    {
        DoMandSpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_DISCIPLE)
    {
        DoDiscipleSpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_G0T0)
    {
        DoG0T0SpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_HANDMAIDEN)
    {
        DoHandmaidenSpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_HANHARR)
    {
        DoHanharrSpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_HK_47)
    {
        DoHK47SpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_KREIA)
    {
        DoKreiaSpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_MIRA)
    {
        DoMiraSpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_T3_M4)
    {
        DoT3M4SpawnIn(oNPC, sModuleName);
    }
    else if(GetNPCConstant(GetTag(oNPC)) == NPC_VISAS)
    {
        DoVisasMarrSpawnIn(oNPC, sModuleName);
    }
    else
    {
        AurPostString("ERROR: Invalid PartyMember",15,15,10.0);
    }
}
void DoSpecialPuppetReset(object oNPC, string sModuleName)
{
    if(GetPuppetConstant(GetTag(oNPC)) == PUP_SENSORBALL)
    {
        DoRemoteSpawnIn(oNPC, sModuleName);
    }
}
void ResetEbonHawk()
{
    AurPostString("k_inc_hawk: Resetting Ebon Hawk", 15, 18, 10.0);
    int i;
    string sTag;
    object oNPC;
    for(i = 0; i < 12; i++)
    {
        sTag = GetNPCTag( i );
        oNPC = GetObjectByTag(sTag);
        if(GetIsObjectValid(oNPC))
        {
            object oWP = GetObjectByTag("WP_gspawn_" + sTag);
            if(GetIsObjectValid(oWP))
            {
                AssignCommand(oNPC, ClearAllActions());
                AssignCommand(oNPC, ActionJumpToLocation(GetLocation(oWP)));
                DelayCommand(0.2, DoSpecialReset(oNPC, "003EBO"));
            }
            else
            {
                AurPostString("RESET EBONHAWK: invalid waypoint!", 15,15,10.0);
            }
        }
    }
    object oRemote = GetObjectByTag("remote");
    if(GetIsObjectValid(oRemote))
    {
        object oWP = GetObjectByTag("WP_gspawn_" + sTag);
        if(GetIsObjectValid(oWP))
        {
            AssignCommand(oNPC, ClearAllActions());
            AssignCommand(oNPC, ActionJumpToLocation(GetLocation(oWP)));
            DelayCommand(0.2, DoSpecialPuppetReset(oNPC, "003EBO"));
        }
        else
        {
            AurPostString("RESET EBONHAWK: invalid waypoint!", 15,15,10.0);
        }
    }
    //AWD-OEI 10/29/2004
    DestroyVisas();
}
void TurnOffCutsceneMode(object oNPC)
{
    AssignCommand(oNPC, ClearAllActions());
    //waypoints on
    //AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, FALSE));
    //AssignCommand(oPartyMember, GN_WalkWayPoints());
    //waypoints off
    AssignCommand(oNPC, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, TRUE));
    AssignCommand(oNPC, ActionPlayAnimation(ANIMATION_LOOPING_PAUSE, 1.0, -1.0));//clear animations
}
void ClearEbonHawk()
{
    AurPostString("k_inc_hawk: ClearEbonHawk", 15, 21, 10.0);
    int i;
    int bOnXbox = GetIsXBox();
    string sTag;
    object oNPC;
    for(i = 0; i < 12; i++)
    {
        sTag = GetNPCTag( i );
        oNPC = GetObjectByTag(sTag);
        if(GetIsObjectValid(oNPC))
        {
            //SaveNPCByObject(i , oNPC);
            DestroyObject(oNPC, 0.0, bOnXbox);
        }
    }
    object oRemote = GetObjectByTag("remote");
    if(GetIsObjectValid(oRemote))
    {
        //SavePUPByObject(PUP_SENSORBALL, oRemote);
        DestroyObject(oRemote, 0.0, bOnXbox);
    }
}
void SetBackground()
{
    //string sRoom = GetScriptStringParameter();
    string sRoom = "003EBOq";
    int nRoomAnimation = GetGlobalNumber("003EBO_BACKGROUND");
    switch(nRoomAnimation)
    {
        case 0://106PER
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP01;
        }break;
        case 1://201TEL
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP02;
        }break;
        case 2://262TEL
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP03;
        }break;
        case 3://301NAR
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP04;
        }break;
        case 4://401DXN
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP05;
        }break;
        case 5://601DAN
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP06;
        }break;
        case 6://701KOR
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP07;
        }break;
        case 7://801DRO
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP08;
        }break;
        case 8://space
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP09;
        }break;
        case 9://901MAL
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP10;
        }break;
        case 10://Hyperspace
        {
            nRoomAnimation = ANIMATION_ROOM_SCRIPTLOOP11;
        }break;
        default://error
        {
            AurPostString("EBO ERROR: No background sepcified!",15,15,10.0);
        }
    }
    PlayRoomAnimation(sRoom, nRoomAnimation);
}
void SetHologramWorld()
{
    string sResRef;
    int nCurrentWorld = GetGlobalNumber("003EBO_BACKGROUND");
    switch(nCurrentWorld)
    {
        case 0://106PER
        {
            sResRef = "holo_per";
        }break;
        case 1://201TEL
        {
            sResRef = "holo_tel";
        }break;
        case 2://262TEL
        {
            sResRef = "holo_tel";
        }break;
        case 3://301NAR
        {
            sResRef = "holo_nar";
        }break;
        case 4://401DXN
        {
            sResRef = "holo_dxn";
        }break;
        case 5://601DAN
        {
            sResRef = "holo_dan";
        }break;
        case 6://701KOR
        {
            sResRef = "holo_kor";
        }break;
        case 7://801DRO
        {
            sResRef = "";
        }break;
        case 8://space
        {
            sResRef = "";
        }break;
        case 9://901MAL
        {
            sResRef = "holo_mal";
        }break;
        case 10://Hyperspace
        {
            sResRef = "";
        }break;
        default://error
        {
            AurPostString("EBO ERROR: No background sepcified!",15,15,10.0);
        }
    }
    object oHoloWorld = GetObjectByTag("hologram");
    if(GetIsObjectValid(oHoloWorld))
        DestroyObject(oHoloWorld);
    if(sResRef != "")
    {
        object oNewHoloWorld = CreateObject(OBJECT_TYPE_PLACEABLE, sResRef, GetLocation(GetObjectByTag("WP_hologram")));
        if(GetIsObjectValid(oNewHoloWorld))
        {
            //AssignCommand ( oNewHoloWorld, ActionPlayAnimation(ANIMATION_PLACEABLE_ANIMLOOP01, 1.0, -1.0));
            DelayCommand( 1.0, AssignCommand ( oNewHoloWorld, ActionPlayAnimation(ANIMATION_PLACEABLE_ANIMLOOP01) ) );
        }
    }
}
// GetCurrentPlanet
// returns a planet constant based on background
// will return -1 if not on a planet
int GetCurrentPlanet()
{
    int nRoomAnimation = GetGlobalNumber("003EBO_BACKGROUND");
    switch(nRoomAnimation)
    {
        case 0://106PER
        {
            //return PLANET_PERAGUS;
            return PLANET_EBON_HAWK;
        }break;
        case 1://201TEL
        {
            return 10; // citadel station
        }break;
        case 2://262TEL
        {
            return PLANET_TELOS;
        }break;
        case 3://301NAR
        {
            return PLANET_NAR_SHADDAA;
        }break;
        case 4://401DXN
        {
            return PLANET_DXUN;
        }break;
        case 5://601DAN
        {
            return PLANET_DANTOOINE;
        }break;
        case 6://701KOR
        {
            return PLANET_KORRIBAN;
        }break;
        case 7://801DRO
        {
            return PLANET_M4_78;
        }break;
        case 8://space
        {
            return PLANET_EBON_HAWK;
        }break;
        case 9://901MAL
        {
            return PLANET_MALACHOR_V;
        }break;
        case 10://Hyperspace
        {
            return PLANET_EBON_HAWK;
        }break;
        default://error
        {
            return PLANET_EBON_HAWK;
        }
    }
    return PLANET_EBON_HAWK;
}
""",
    "k_inc_item_gen": b"""
//:: k_inc_item_gen.nss
/*
    Global script used to generate items on the PC based on the
    NPC being spoken to.
*/
//:: Created By:
//:: Copyright (c) 2002 Bioware Corp.
#include "k_inc_debug"
//Checks the Player's inventory and determines based on OBJECT_SELF
//whether the Player needs equipment.
//Returns TRUE if the Player needs equipment.
//Returns FALSE if the Player does NOT equipment.
int  GetIsEquipmentNeeded();
//Creates equipment on the PC based on the NPC they are talking to.
void CreateEquipmentOnPC();
//Counts and totals up to four different items within the Player's inventory.
int  CheckInventoryNumbers(string sTag1, string sTag2 = "", string sTag3 = "", string sTag4 = "");
//Checks the Player's inventory and determines based on OBJECT_SELF
//whether the Player needs equipment.
//Returns TRUE if the Player needs equipment.
//Returns FALSE if the Player does NOT equipment.
//Global and modified version of EBO_GetIsEquipmentNeeded() from Kotor1
int GetIsEquipmentNeeded()
{
    int nNumber, nGlobal;
    string sTag = GetTag(OBJECT_SELF);
    int nJediFound = (GetGlobalNumber("000_Jedi_Found")*2) + 10;
    if(sTag == "mira")//Mira
    {
        int bMakeLethalGrenades = GetLocalBoolean( OBJECT_SELF, 31 );
        if(bMakeLethalGrenades)
        {//lethals only
            nNumber = CheckInventoryNumbers("g_w_fraggren01","G_W_FIREGREN001");
            nGlobal = GetGlobalNumber("K_MIRA_ITEMS");
            if((nNumber <= 10 && nGlobal < nJediFound) || nGlobal == 0)
            {
                return TRUE;
            }
            return FALSE;
        }
        else
        {//non lethal grenades only, stuns and adhesives
            nNumber = CheckInventoryNumbers("G_w_StunGren01","g_w_adhsvgren001","G_W_CRYOBGREN001","g_w_iongren01");
            nGlobal = GetGlobalNumber("K_MIRA_ITEMS");
            if((nNumber <= 10 && nGlobal < nJediFound) || nGlobal == 0)
            {
                return TRUE;
            }
            return FALSE;
        }
    }
    else if(sTag == "disciple")//Disciple
    {
        nNumber = CheckInventoryNumbers("g_I_medeqpmnt01","G_I_MEDEQPMNT02","g_I_medeqpmnt03");
        nGlobal = GetGlobalNumber("K_DISCIPLE_ITEMS");
        if((nNumber <= 10 && nGlobal < nJediFound) || nGlobal == 0)
        {
            return TRUE;
        }
        return FALSE;
    }
    else if(sTag == "atton")//Atton
    {
        nNumber = CheckInventoryNumbers("g_i_secspike01","G_I_SECSPIKE02");
        nGlobal = GetGlobalNumber("K_ATTON_ITEMS");
        if((nNumber <= 10 && nGlobal <= nJediFound) || nGlobal == 0)
        {
            return TRUE;
        }
        return FALSE;
    }
    else if(sTag == "mand")//Canderous
    {
        nNumber = CheckInventoryNumbers("g_i_adrnaline001","G_I_ADRNALINE002","g_i_adrnaline003", "g_i_cmbtshot001");
        nGlobal = GetGlobalNumber("K_MAND_ITEMS");
        PrintString("Number = " + IntToString(nNumber));
        PrintString("Global = " + IntToString(nGlobal));
        PrintString("Jedi Found = " + IntToString(nJediFound));
        if((nNumber <= 10 && nGlobal <= nJediFound) || nGlobal == 0)
        {
            return TRUE;
        }
        return FALSE;
    }
    else if(sTag == "t3m4")//T3M4
    {
        nNumber = CheckInventoryNumbers("K_COMPUTER_SPIKE");
        nGlobal = GetGlobalNumber("K_T3M4_ITEMS");
        if((nNumber <= 10 && nGlobal <= nJediFound) || nGlobal == 0)
        {
            return TRUE;
        }
        return FALSE;
    }
    else if(sTag == "baodur")//Bao-Dur
    {
        nGlobal = GetGlobalNumber("K_BAODUR_ITEMS");
        return FALSE;
    }
    else if(sTag == "hanharr")//Hanharr
    {
        nGlobal = GetGlobalNumber("K_HANHARR_ITEMS");
        return FALSE;
    }
    return FALSE;
}
//Creates equipment on the PC based on the NPC they are talking to.
//Global and modified version of EBO_CreateEquipmentOnPC() from Kotor1
void CreateEquipmentOnPC()
{
    int nCount;
    string sTag = GetTag(OBJECT_SELF);
    object oProxy;
    if(sTag == "mira")//Mira
    {
        int nRand;
        int bMakeLethalGrenades = GetLocalBoolean( OBJECT_SELF, 31 );
        if(bMakeLethalGrenades)
        {//make only lethal grenades
            nRand = d2();
            if(nRand == 1)
            {
                oProxy = CreateItemOnObject("g_w_fraggren01", GetFirstPC());
            }
            else if(nRand == 2)
            {
                oProxy = CreateItemOnObject("G_W_FIREGREN001", GetFirstPC());
            }
        }
        else
        {//non-lethal grenades only
            nRand = d4();
            if(nRand == 1)
            {
                oProxy = CreateItemOnObject("G_W_CRYOBGREN001", GetFirstPC());
            }
            else if(nRand == 2)
            {
                oProxy = CreateItemOnObject("g_w_stungren01", GetFirstPC());
            }
            else if(nRand == 3)
            {
                oProxy = CreateItemOnObject("g_w_iongren01", GetFirstPC());
            }
            else if(nRand == 4)
            {
                oProxy = CreateItemOnObject("g_w_adhsvgren001", GetFirstPC());
            }
        }
        nCount = GetGlobalNumber("K_MIRA_ITEMS");
        nCount++;
        SetGlobalNumber("K_MIRA_ITEMS", nCount);
    }
    else if(sTag == "disciple")//Disciple
    {
        int nLevel = GetHitDice(GetFirstPC());
        if(nLevel <= 4)
        {
            oProxy = CreateItemOnObject("G_I_MEDEQPMNT01", GetFirstPC());
        }
        else if(nLevel > 4 && nLevel <= 10)
        {
            oProxy = CreateItemOnObject("G_I_MEDEQPMNT02", GetFirstPC());
        }
        else if(nLevel > 10)
        {
            oProxy = CreateItemOnObject("G_I_MEDEQPMNT03", GetFirstPC());
        }
        nCount = GetGlobalNumber("K_DISCIPLE_ITEMS");
        nCount++;
        SetGlobalNumber("K_DISCIPLE_ITEMS", nCount);
    }
    else if(sTag == "atton")//Atton
    {
        int nLevel = GetHitDice(GetFirstPC());
        if(nLevel <= 7)
        {
            oProxy = CreateItemOnObject("g_i_secspike01", GetFirstPC());
        }
        else if(nLevel > 7)
        {
            oProxy = CreateItemOnObject("g_i_secspike02", GetFirstPC());
        }
        nCount = GetGlobalNumber("K_ATTON_ITEMS");
        nCount++;
        SetGlobalNumber("K_ATTON_ITEMS", nCount);
    }
    else if(sTag == "mand")//Canderous
    {
        int nRand = d4();
        if(nRand == 1)
        {
            oProxy = CreateItemOnObject("G_I_ADRNALINE001", GetFirstPC());
        }
        else if(nRand == 2)
        {
            oProxy = CreateItemOnObject("G_I_ADRNALINE002", GetFirstPC());
        }
        else if(nRand == 3)
        {
            oProxy = CreateItemOnObject("G_I_ADRNALINE003", GetFirstPC());
        }
        else if(nRand == 4)
        {
            oProxy = CreateItemOnObject("G_I_CMBTSHOT001", GetFirstPC());
        }
        nCount = GetGlobalNumber("K_MAND_ITEMS");
        nCount++;
        SetGlobalNumber("K_MAND_ITEMS", nCount);
    }
    else if(sTag == "t3m4")//T3M4
    {
        oProxy = CreateItemOnObject("G_I_PROGSPIKE01", GetFirstPC());
        nCount = GetGlobalNumber("K_T3M4_ITEMS");
        nCount++;
        SetGlobalNumber("K_T3M4_ITEMS", nCount);
    }
    else if(sTag == "baodur")//Bao-Dur
    {
        nCount = GetGlobalNumber("K_BAODUR_ITEMS");
        nCount++;
        SetGlobalNumber("K_BAODUR_ITEMS", nCount);
    }
    else if(sTag == "hanharr")//Hanharr
    {
        nCount = GetGlobalNumber("K_HANHARR_ITEMS");
        nCount++;
        SetGlobalNumber("K_HANHARR_ITEMS", nCount);
    }
}
//Counts and totals up to four different items within the Player's inventory.
//Global and modified version of EBO_CheckInventoryNumbers() from Kotor1
int CheckInventoryNumbers(string sTag1, string sTag2 = "", string sTag3 = "", string sTag4 = "")
{
    int nNumber = 0;
    object oGrenade;
    if(sTag1 != "")
    {
        oGrenade = GetItemPossessedBy(GetFirstPC(), sTag1);
        if(GetIsObjectValid(oGrenade))
        {
            nNumber += GetNumStackedItems(oGrenade);
        }
    }
    if(sTag2 != "")
    {
        oGrenade = GetItemPossessedBy(GetFirstPC(), sTag2);
        if(GetIsObjectValid(oGrenade))
        {
            nNumber += GetNumStackedItems(oGrenade);
        }
    }
    if(sTag3 != "")
    {
        oGrenade = GetItemPossessedBy(GetFirstPC(), sTag3);
        if(GetIsObjectValid(oGrenade))
        {
            nNumber += GetNumStackedItems(oGrenade);
        }
    }
    if(sTag4 != "")
    {
        oGrenade = GetItemPossessedBy(GetFirstPC(), sTag4);
        if(GetIsObjectValid(oGrenade))
        {
            nNumber += GetNumStackedItems(oGrenade);
        }
    }
    return nNumber;
}
""",
    "k_inc_npckill": b"""//Richard Taylor
//OEI 08/08/04
//Various functions to help with killing creatures in
//violent and damaging explosions.
//When this function is called on something it will
//destroy the oCreature after nDelay seconds and do nDamage to
//everyone within 4 meters radius.
void DamagingExplosion(object oCreature, int nDelay, int nDamage );
//When this function is called on something it will
//destroy the oCreature after nDelay seconds but not
//damage anyone in the explosion
void NonDamagingExplosion(object oCreature, int nDelay);
//When this function is called on something it will do
//an EffectDeath on oCreature after nSeconds
void KillCreature(object oCreature, int nDelay);
int GR_GetGrenadeDC(object oTarget);
void DamagingExplosion( object oCreature, int nDelay, int nDamage )
{
    //IF there is a delay just call ourselves after ndelay seconds and
    //not have a delay next time
    if ( nDelay > 0 )
    {
        //AurPostString( "Delaying Damaging", 10, 25, 5.0f );
        DelayCommand( IntToFloat(nDelay), DamagingExplosion(oCreature, 0, nDamage ));
        return;
    }
    //AurPostString( "Executing Damaging", 10, 26, 5.0f );
    int nDC = 15;
    int nDCCheck = 0;
    location oLoc = GetLocation(oCreature);
    float oOri = GetFacing(oCreature);
    vector vPos = GetPositionFromLocation( oLoc );
    vPos.z = vPos.z + 1.0f ;
    location oExplosionLoc = Location( vPos, oOri );
    object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 4.0, oLoc, FALSE, 65);
    while (GetIsObjectValid(oTarget) && nDamage > 0 )
    {
        int nFaction = GetStandardFaction( oTarget );
        if ( oTarget != OBJECT_SELF && nFaction != STANDARD_FACTION_NEUTRAL )
        {
            nDCCheck = nDC;
            nDCCheck -= GR_GetGrenadeDC(oTarget);
            if ( !ReflexSave(oTarget, nDCCheck, SAVING_THROW_TYPE_NONE))
            {
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage, DAMAGE_TYPE_PIERCING), oTarget);
            }
            else
            {//Do a evasion check
                int nApply = 0;
                if ( GetHasFeat( FEAT_EVASION, oTarget ) )
                {
                    nApply = 0;
                }
                else
                {
                    nApply = nDamage / 2;
                }
                ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nApply, DAMAGE_TYPE_PIERCING), oTarget);
            }
        }
        oTarget = GetNextObjectInShape(SHAPE_SPHERE, 4.0, oLoc, FALSE, 65 );
    }
    ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(3003), oExplosionLoc);
    AssignCommand(oCreature, ClearAllActions());
    DestroyObject(oCreature, 0.0f, TRUE);
}
void NonDamagingExplosion(object oCreature, int nDelay)
{
    DamagingExplosion(oCreature, nDelay, 0);
}
void KillCreature(object oCreature, int nDelay )
{
    if ( nDelay > 0 )
    {
        DelayCommand(IntToFloat(nDelay), KillCreature( oCreature, 0 ));
        return;
    }
    effect eDeath = EffectDeath(FALSE, FALSE, TRUE);
    ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oCreature );
}
void main()
{
    int nKillMode = GetScriptParameter(1);
    int nDelay = GetScriptParameter(2);
    int nDamage = GetScriptParameter(3);
    if ( nKillMode == 0 )
    {
      //  AurPostString( "Calling damaging. Delay of: ", 10, 20, 5.0f );
      //  AurPostString( IntToString( nDelay ), 10, 21, 5.0f );
        DamagingExplosion(OBJECT_SELF, nDelay, nDamage);
        return;
    }
    if ( nKillMode == 1 )
    {
        NonDamagingExplosion(OBJECT_SELF, nDelay);
        return;
    }
    if ( nKillMode == 2 )
    {
        KillCreature(OBJECT_SELF, nDelay);
        return;
    }
}
//Get the DC for the grenade based on the targets feats.
int GR_GetGrenadeDC(object oTarget)
{
    int nUnc1 = GetHasFeat(FEAT_UNCANNY_DODGE_1, oTarget);
    int nUnc2 = GetHasFeat(FEAT_UNCANNY_DODGE_2, oTarget);
    int nDC = 0;
    if(nUnc1 == TRUE)
    {
        nDC += 2;
        if(nUnc2 == TRUE)
        {
            nDC += 2;
        }
    }
    return nDC;
}
""",
    "k_inc_quest_hk": b"""// Gives the player the next component needed for the HK quest.
// kds, 09/06/04
#include "k_inc_treas_k2"
void GiveHKPart(string sString)
{
    int k = 1;
    string sHKpart = "hkpart0";
    string sItem;
    object oItem = OBJECT_SELF;
    object oRecipient;
    if(sString != "") oRecipient = GetObjectByTag(sString);
        else oRecipient = OBJECT_SELF;
if(GetJournalEntry("RebuildHK47") < 80)
{
    for(k; GetIsObjectValid(oItem); k++)
    {
    sItem = sHKpart + IntToString(k);
    oItem = GetItemPossessedBy (GetPartyLeader(),sItem);
    }
    //AddJournalQuestEntry("LightsaberQuest",10*i);
}
CreateItemOnObject( sItem, oRecipient, 1 );
}
""",
    "k_inc_q_crystal": b"""//:: a_q_cryst_change
/*
Takes the quest crystal the player has, if any.
Gives the player the appropriate quest crystal for their alignment/level
*/
//:: Created By: Kevin Saunders, 06/26/04
//:: Copyright 2004 Obsidian Entertainment
#include "k_inc_utility"
int GetPCLevel()
{
    int n = GetGlobalNumber("G_PC_LEVEL");
    return(n);
}
string GetPCAlignType()
{
    string s;
    if(IsDark()) s = "1";
    if(IsNeutral()) s = "2";
    if(IsLight()) s = "3";
    if(IsDarkComplete()) s = "0";
    if(IsLightComplete()) s = "4";
    return(s);
}
int GetCrystalLevel()
{
    int n = 1 + (GetPCLevel() - 9)/3;
    if(n < 1) n = 1;
    if(n > 9) n = 9;
    return(n);
}
""",
    "k_inc_switch": b"""//:: k_inc_switch
/*
     A simple include defining all of the
     events in the game as constants.
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
//DEFAULT AI EVENTS
int KOTOR_DEFAULT_EVENT_ON_HEARTBEAT           = 1001;
int KOTOR_DEFAULT_EVENT_ON_PERCEPTION          = 1002;
int KOTOR_DEFAULT_EVENT_ON_COMBAT_ROUND_END    = 1003;
int KOTOR_DEFAULT_EVENT_ON_DIALOGUE            = 1004;
int KOTOR_DEFAULT_EVENT_ON_ATTACKED            = 1005;
int KOTOR_DEFAULT_EVENT_ON_DAMAGE              = 1006;
int KOTOR_DEFAULT_EVENT_ON_DEATH               = 1007;
int KOTOR_DEFAULT_EVENT_ON_DISTURBED           = 1008;
int KOTOR_DEFAULT_EVENT_ON_BLOCKED             = 1009;
int KOTOR_DEFAULT_EVENT_ON_FORCE_AFFECTED      = 1010;
int KOTOR_DEFAULT_EVENT_ON_GLOBAL_DIALOGUE_END = 1011;
int KOTOR_DEFAULT_EVENT_ON_PATH_BLOCKED        = 1012;
//HENCHMEN AI EVENTS
int KOTOR_HENCH_EVENT_ON_HEARTBEAT           = 2001;
int KOTOR_HENCH_EVENT_ON_PERCEPTION          = 2002;
int KOTOR_HENCH_EVENT_ON_COMBAT_ROUND_END    = 2003;
int KOTOR_HENCH_EVENT_ON_DIALOGUE            = 2004;
int KOTOR_HENCH_EVENT_ON_ATTACKED            = 2005;
int KOTOR_HENCH_EVENT_ON_DAMAGE              = 2006;
int KOTOR_HENCH_EVENT_ON_DEATH               = 2007;
int KOTOR_HENCH_EVENT_ON_DISTURBED           = 2008;
int KOTOR_HENCH_EVENT_ON_BLOCKED             = 2009;
int KOTOR_HENCH_EVENT_ON_FORCE_AFFECTED      = 2010;
int KOTOR_HENCH_EVENT_ON_GLOBAL_DIALOGUE_END = 2011;
int KOTOR_HENCH_EVENT_ON_PATH_BLOCKED        = 2012;
int KOTOR_HENCH_EVENT_ON_ENTER_5m            = 2013;
int KOTOR_HENCH_EVENT_ON_EXIT_5m             = 2014;
//MISC AI EVENTS
int KOTOR_MISC_DETERMINE_COMBAT_ROUND                = 3001;
int KOTOR_MISC_DETERMINE_COMBAT_ROUND_ON_PC          = 3002;
int KOTOR_MISC_DETERMINE_COMBAT_ROUND_ON_INDEX_ZERO  = 3003;
// DJS-OEI 6/12/2004
// Miscellaneous KotOR2 events
// This user-defined event is sent to the Area when the player's
// created character has performed an action that is currently
// considered forbidden for combats in the area.
int KOTOR2_MISC_PC_COMBAT_FORFEIT                    = 4001;
""",
    "k_inc_treasure": b"""//:: k_inc_treasure
/*
     contains code for filling containers using treasure tables
*/
//:: Created By:  Jason Booth
//:: Copyright (c) 2002 Bioware Corp.
//
//  March 15, 2003  J.B.
//      removed parts and spikes from tables
//
//constants for container types
int SWTR_DEBUG = TRUE;  //set to false to disable console/file logging
int SWTR_TABLE_CIVILIAN_CONTAINER = 1;
int SWTR_TABLE_MILITARY_CONTAINER_LOW = 2;
int SWTR_TABLE_MILITARY_CONTAINER_MID = 3;
int SWTR_TABLE_MILITARY_CONTAINER_HIGH = 4;
int SWTR_TABLE_CORPSE_CONTAINER_LOW = 5;
int SWTR_TABLE_CORPSE_CONTAINER_MID = 6;
int SWTR_TABLE_CORPSE_CONTAINER_HIGH = 7;
int SWTR_TABLE_SHADOWLANDS_CONTAINER_LOW = 8;
int SWTR_TABLE_SHADOWLANDS_CONTAINER_MID = 9;
int SWTR_TABLE_SHADOWLANDS_CONTAINER_HIGH = 10;
int SWTR_TABLE_DROID_CONTAINER_LOW = 11;
int SWTR_TABLE_DROID_CONTAINER_MID = 12;
int SWTR_TABLE_DROID_CONTAINER_HIGH = 13;
int SWTR_TABLE_RAKATAN_CONTAINER = 14;
int SWTR_TABLE_SANDPERSON_CONTAINER = 15;
//Fill an object with treasure from the specified table
//This is the only function that should be used outside this include file
void SWTR_PopulateTreasure(object oContainer,int iTable,int iItems = 1,int bUnique = TRUE);
//for internal debugging use only, output string to the log file and console if desired
void SWTR_Debug_PostString(string sStr,int bConsole = TRUE,int x = 5,int y = 5,float fTime = 5.0)
{
  if(SWTR_DEBUG)
  {
    if(bConsole)
    {
      AurPostString("SWTR_DEBUG - " + sStr,x,y,fTime);
    }
    PrintString("SWTR_DEBUG - " + sStr);
  }
}
//return whether i>=iLow and i<=iHigh
int SWTR_InRange(int i,int iLow,int iHigh)
{
  if(i >= iLow && i <= iHigh)
  {
    return(TRUE);
  }
  else
  {
    return(FALSE);
  }
}
//returns whether sTemplate is not in sFilter
int SWTR_IsUnique(string sTemplate,string sFilter)
{
  if(sFilter == "")
  {
    return(TRUE);
  }
  if(FindSubString(sFilter,sTemplate) >= 0)
  {
    return(FALSE);
  }
  else
  {
    return(TRUE);
  }
}
//turn a given quantity into appropriate format for a treasure blob (string)
string SWTR_GetQuantity(int iCount)
{
  string str = IntToString(iCount);
  string pad = "0";
  int length = 4;
  while(GetStringLength(str) < length)
  {
    str = pad + str;
  }
  return("[" + str + "]");
}
//get a single treasure blob (string) from specified table
//use sFilter to maintain uniqueness
string SWTR_GetTreasure(int iTable,string sFilter = "")
{
  int iRoll;
  string sTemplate;
  int bFound = FALSE;
  string sObjDesc = "";
  string sQuantity;
  //first, generate a random number (0-99) and then, using the specified table
  //lookup the treasure
  do {
    iRoll = Random(100);
    switch(iTable)
    {
    case 1:  //civilian container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,84) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(20)+1);
        bFound = TRUE;
      }
      /*
      sTemplate = "G_A_CLOTHES01";
      if(SWTR_InRange(iRoll,25,34) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_A_CLOTHES02";
      if(SWTR_InRange(iRoll,35,44) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_A_CLOTHES03";
      if(SWTR_InRange(iRoll,45,54) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_A_CLOTHES04";
      if(SWTR_InRange(iRoll,55,64) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_A_CLOTHES05";
      if(SWTR_InRange(iRoll,65,74) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_A_CLOTHES06";
      if(SWTR_InRange(iRoll,75,84) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,85,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,90,94) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt01";
      if(SWTR_InRange(iRoll,85,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 2:  //low level military container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,9) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(20)+1);
        bFound = TRUE;
      }
      sTemplate = "g_w_fraggren01";
      if(SWTR_InRange(iRoll,10,29) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_w_StunGren01";
      if(SWTR_InRange(iRoll,30,39) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_w_SonicGren01";
      if(SWTR_InRange(iRoll,40,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "g_w_iongren01";
      if(SWTR_InRange(iRoll,60,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,50,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,60,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt01";
      if(SWTR_InRange(iRoll,70,84) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_MEDEQPMNT04";
      if(SWTR_InRange(iRoll,85,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDREPEQP001";
      if(SWTR_InRange(iRoll,90,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 3:  //mid level military container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,3) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(30)+10);
        bFound = TRUE;
      }
      sTemplate = "g_w_fraggren01";
      if(SWTR_InRange(iRoll,4,17) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_w_StunGren01";
      if(SWTR_InRange(iRoll,18,21) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_w_SonicGren01";
      if(SWTR_InRange(iRoll,22,27) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "g_w_iongren01";
      if(SWTR_InRange(iRoll,28,33) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,20,23) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,24,33) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_MEDEQPMNT02";
      if(SWTR_InRange(iRoll,34,48) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_MEDEQPMNT04";
      if(SWTR_InRange(iRoll,49,53) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDREPEQP002";
      if(SWTR_InRange(iRoll,54,63) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE001";
      if(SWTR_InRange(iRoll,64,75) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE002";
      if(SWTR_InRange(iRoll,76,87) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE003";
      if(SWTR_InRange(iRoll,88,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 4:  //high level military container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,3) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(60)+ 40);
        bFound = TRUE;
      }
      sTemplate = "g_w_fraggren01";
      if(SWTR_InRange(iRoll,4,17) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "G_w_StunGren01";
      if(SWTR_InRange(iRoll,18,21) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "G_w_SonicGren01";
      if(SWTR_InRange(iRoll,22,27) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "g_w_iongren01";
      if(SWTR_InRange(iRoll,28,33) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,20,23) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,24,33) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_MEDEQPMNT03";
      if(SWTR_InRange(iRoll,34,48) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_MEDEQPMNT04";
      if(SWTR_InRange(iRoll,49,53) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDREPEQP003";
      if(SWTR_InRange(iRoll,54,63) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE004";
      if(SWTR_InRange(iRoll,64,75) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE005";
      if(SWTR_InRange(iRoll,76,87) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE006";
      if(SWTR_InRange(iRoll,88,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 5:  //low level corpse container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(20)+ 1);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,70,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,80,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt01";
      if(SWTR_InRange(iRoll,80,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 6:  //mid level corpse container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,49) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(30)+ 10);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,40,49) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,50,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_MEDEQPMNT02";
      if(SWTR_InRange(iRoll,50,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE001";
      if(SWTR_InRange(iRoll,70,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE002";
      if(SWTR_InRange(iRoll,80,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE003";
      if(SWTR_InRange(iRoll,90,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 7:  //high level corpse container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,49) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(60)+ 40);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,40,49) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,50,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_MEDEQPMNT03";
      if(SWTR_InRange(iRoll,50,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE004";
      if(SWTR_InRange(iRoll,70,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE005";
      if(SWTR_InRange(iRoll,80,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE006";
      if(SWTR_InRange(iRoll,90,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 8:  //low level shadowlands container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(20)+ 1);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,60,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt01";
      if(SWTR_InRange(iRoll,70,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 9:  //mid level shadowlands container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(30)+ 10);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,50,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt02";
      if(SWTR_InRange(iRoll,60,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE001";
      if(SWTR_InRange(iRoll,70,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE002";
      if(SWTR_InRange(iRoll,80,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE003";
      if(SWTR_InRange(iRoll,90,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 10:  //high level shadowlands container
      sTemplate = "G_I_CREDITS001";
      if(SWTR_InRange(iRoll,0,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(60)+ 40);
        bFound = TRUE;
      }
      /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,50,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      */
      sTemplate = "g_i_medeqpmnt03";
      if(SWTR_InRange(iRoll,60,69) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE004";
      if(SWTR_InRange(iRoll,70,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE005";
      if(SWTR_InRange(iRoll,80,89) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE006";
      if(SWTR_InRange(iRoll,90,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 11:  //low level droid container
      /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_DRDLTPLAT001";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDMTNSEN001";
      if(SWTR_InRange(iRoll,80,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 12:  //mid level droid container
      /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_DRDLTPLAT002";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDMTNSEN002";
      if(SWTR_InRange(iRoll,80,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 13:  //high level droid container
    /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_DRDLTPLAT003";
      if(SWTR_InRange(iRoll,0,79) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_DRDMTNSEN003";
      if(SWTR_InRange(iRoll,80,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 14:  //rakatan container
    /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,0,15) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      sTemplate = "g_i_progspike01";
      if(SWTR_InRange(iRoll,16,31) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(4)+ 3);
        bFound = TRUE;
      }
      */
      sTemplate = "G_I_DRDREPEQP003";
      if(SWTR_InRange(iRoll,0,24) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE004";
      if(SWTR_InRange(iRoll,25,49) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE005";
      if(SWTR_InRange(iRoll,50,74) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE006";
      if(SWTR_InRange(iRoll,75,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    case 15:  //sandperson container
    /*
      sTemplate = "g_i_parts01";
      if(SWTR_InRange(iRoll,0,11) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      */
      sTemplate = "g_w_fraggren01";
      if(SWTR_InRange(iRoll,0,23) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_w_StunGren01";
      if(SWTR_InRange(iRoll,24,35) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_w_SonicGren01";
      if(SWTR_InRange(iRoll,36,47) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "g_w_iongren01";
      if(SWTR_InRange(iRoll,48,59) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate + SWTR_GetQuantity(Random(3)+ 2);
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE001";
      if(SWTR_InRange(iRoll,60,71) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE002";
      if(SWTR_InRange(iRoll,72,83) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      sTemplate = "G_I_ADRNALINE003";
      if(SWTR_InRange(iRoll,84,99) && SWTR_IsUnique(sTemplate,sFilter))
      {
        sObjDesc = sTemplate;
        bFound = TRUE;
      }
      break;
    }
  } while(!bFound);
  return(sObjDesc);
}
//Fill an object with treasure from the specified table
//This is the only function that should be used outside this include file
void SWTR_PopulateTreasure(object oContainer,int iTable,int iItems = 1,int bUnique = TRUE)
{
  string sFilter = "";  //maintains list of item templates already retrieved
  string sItem,sTemplate;
  int iQuantity;
  int i;
  if(!GetIsObjectValid(oContainer))
  {
    SWTR_Debug_PostString("invalid container");
    return;
  }
  while(iItems > 0)
  {
    sItem = SWTR_GetTreasure(iTable,sFilter);
    if(sItem == "")
    {
      SWTR_Debug_PostString("bad table");
    }
    //parse the item description
    //treasure blobs (strings) consist of the item template followed by the quantity
    if((i = FindSubString(sItem,"[")) >= 0)
    {
      iQuantity = StringToInt(GetSubString(sItem,i+1,4));
      sTemplate = GetSubString(sItem,0,i);
    }
    else
    {
      iQuantity = 1;
      sTemplate = sItem;
    }
    //create item
    if(!GetIsObjectValid(CreateItemOnObject(sTemplate,oContainer,iQuantity)))
    {
      SWTR_Debug_PostString("item create failed (" + sTemplate + ")");
    }
    else
    {
      SWTR_Debug_PostString("container:" + GetTag(oContainer) + " item:" + sTemplate,FALSE);
    }
    //update our filter if we are maintaining uniqueness
    if(bUnique)
    {
      sFilter = sFilter + sTemplate;
    }
    iItems--;
  }
}
""",
    "k_inc_treas_k2": b"""#include "k_inc_q_crystal"
#include "k_inc_treasure"
/*
This include files contains the functions used to randomly generate item treasure
based upon the players' level.
Item classifications
hundreds digit = item class
tens digit = item sub-class
ones digit = specifies specific item resref
(* = these items have been created through at least level 10)
Weapons 100
*  111 - Blaster
*  121 - Blaster Rifle
*  131 - Melee
*  141 - Lightsaber (regular)
*  142 - Lightsaber (short)
*  143 - Lightsaber (Double)
Upgrades 200
Upgrade - Ranged 210
*  211 - Targeting scope
*  212 - Firing Chamber
*  213 - Power Pack
Upgrade - Melee 220
*  221 - Grip
*  222 - Edge
*  223 - Energy Cell
Upgrade - Armor 230
*  231 - Overlay
*  232 - Underlay
Upgrades - Lightsaber 240
  241 - Emitter
*  242 - Lens
  243 - Energy Cell
  244 - Crystals
  245 - Color Crystals
Equipment - 300
*  311 - Belts
*  321 - Gloves
*  331 - Head Gear
   Implants - 340
*   341 - Level 1
*   342 - Level 2
*   343 - Level 3
*   344 - Level 4
Armor - 400
*  411 - Light armor
*  421 - Medium armor
*  431 - Heavy armor
*  441 - Jedi Robes
Droid Items - 500
511 - Interface
521 - Utility
531 - Armor
541 - Shielding
551 - Special weapons
Disposables - 900
*  911 - credits
*  921 - components
*  922 - chemicals
*  930 - shields
*  941 - medpac
*  942 - repair kit
*  951 - stim - str
*  952 - stim - dex
*  953 - stim - con
*  954 - medpac
*  961 - credits
*  970 - grenades
*  981 - parts
*  982 - program spikes
*  983 - security spike
   990 - rockets for mira
*/
// generates the base item tag; allows item tags to be descriptive instead of just numbers
string GetItemPrefix (int nItemType)
{
switch (nItemType)
{
        case 111: return("w_blaste_");
        case 121: return("w_brifle_");
        case 131: return("w_melee_");
        // lightsabers are left out of random treasure
        case 141: return("g_w_lghtsbr");
        case 142: return("g_w_shortsbr");
        case 143: return("g_w_dblsbr0");
        case 211: return("u_r_targ_");
        case 212: return("u_r_firi_");
        case 213: return("u_r_powe_");
        case 221: return("u_m_grip_");
        case 222: return("u_m_edge_");
        case 223: return("u_m_cell_");
        case 231: return("u_a_over_");
        case 232: return("u_a_unde_");
        case 241: return("u_l_emit_");
        case 242: return("u_l_lens_");
        case 243: return("u_l_cell_");
        case 244: return("u_l_crys_");
        case 245: return("u_l_colo_");
        case 311: return("a_belt_");
        case 321: return("a_gloves_");
        case 331: return("a_helmet_");
        case 341: return("e_imp1_");
        case 342: return("e_imp2_");
        case 343: return("e_imp3_");
        case 344: return("e_imp4_");
        case 411: return("a_heavy_");
        case 421: return("a_medium_");
        case 431: return("a_light_");
        case 441: return("a_robe_");
        case 511: return("d_utility_");
        case 521: return("d_interface_");
        case 531: return("d_armor_");
        case 541: return("d_shield_");
        case 551: return("d_device_");
}
return("");
}
// returns the tag of the item found.  the first part of the string is the base
// item, the second is the item's power level.
string GetTreasureSpecific (int nItemLevel, int nItemType = 0)
{
    int nItemRandom = 0;
    int nRoll;
    int nPCLevel = GetGlobalNumber("G_PC_LEVEL");
    string sItemLevel = IntToString(nItemLevel);
    string sTemplate = "";
    if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
    if(nItemType == 0)
        //no item class was specified, so we generate item class randomly
        {
    //prevent player from finding armor on Peragus (supposed to be undressed at beginning).
        if(nPCLevel < 4) nRoll = Random(3)+1;
        else
               nRoll = Random(4)+1;
        // equipment is more common than upgrades.
        if(nRoll == 2 && Random(100) < 50) nRoll = 3;
        sTemplate = GetTreasureSpecific(nItemLevel, nRoll*100);
        }
        else
            {
            if((nItemType % 100) == 0)
            // item class is known, but sub-class isn't, so we generate it randomly
            {
                switch (nItemType / 100)
                {
                    // lightsabers left out
                    case 1: {nItemRandom = 3; break;}
                    // lightsaber upgrades left out if item level < 6 or player level < 10
                    case 2: {if(nItemLevel < 6 ||
                                nPCLevel < 10)
                                nItemRandom = 3;
                                else nItemRandom = 4;
                                break;}
                    case 3: {nItemRandom = 4; break;}
                    case 4: {nItemRandom = 4; break;}
                    case 5: {nItemRandom = 5; break;}
                }
                nRoll = Random(nItemRandom) + 1;
                sTemplate = GetTreasureSpecific(nItemLevel, nItemType + 10*nRoll);
            }
            else
                if((nItemType % 10) == 0)
                // item class and sub-class known; generate the base item tag
                    {
                        switch (nItemType / 10)
                        {
                // lightsabers use a different curve
                            case 14: {nItemRandom = 3;
                                      break;}
                            case 21: {nItemRandom = 3;
                                      break;}
                            case 22: {nItemRandom = 3;
                                      break;}
                            case 23: {nItemRandom = 2;
                                      break;}
                            case 24: {nItemRandom = 5;
                                      break;}
                            case 34: {nItemRandom =
                                            GetAbilityModifier(ABILITY_CONSTITUTION, GetFirstPC())+Random(2);
                                      if(nItemRandom > 4) nItemRandom = 4;
                                      break;}
                        }
                        nRoll = (Random(nItemRandom) + 1);
                        sTemplate = GetTreasureSpecific(nItemLevel, nItemType + nRoll);
                     }
                        else
                        {
                            switch (nItemType)
                            {
                                case 141:
                                      nItemLevel = (nItemLevel - 3)/3;
                      // no number 6
                      if(nItemLevel == 6) nItemLevel = 5;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 142:
                                      nItemLevel = (nItemLevel - 3)/3;
                      // no number 6
                      if(nItemLevel == 6) nItemLevel = 5;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 143:
                                      nItemLevel = (nItemLevel - 3)/3;
                      // no number 6
                      if(nItemLevel == 6) nItemLevel = 5;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 211:
                                      nItemLevel = nItemLevel / 2;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 212:
                                      nItemLevel = nItemLevel / 2;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 213:
                                      nItemLevel = nItemLevel / 2;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 221:
                                      nItemLevel = nItemLevel / 2;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 222:
                                      nItemLevel = nItemLevel / 2;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 223:
                                      nItemLevel = nItemLevel / 2;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                // lightsaber lenses, emitters, and energy cells use a different curve
                                case 241:
                                      nItemLevel = (nItemLevel-6) / 2;
                                      if(nItemLevel<1) nItemLevel = 1;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 242:
                                      nItemLevel = (nItemLevel-6) / 2;
                                      if(nItemLevel<1) nItemLevel = 1;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 243:
                                      nItemLevel = (nItemLevel-6) / 2;
                                      if(nItemLevel<1) nItemLevel = 1;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 244:
                                      nItemLevel = nItemLevel - 5;
                                      if(nItemLevel<1) nItemLevel = 1;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 245:
                                      nItemLevel = (nItemLevel - 5)/3 + 2;
                                      if(nItemLevel<4) nItemLevel = 4;
                      //no cyan
                      if(nItemLevel == 6) nItemLevel = 5;
                                      if(nItemLevel>9) nItemLevel = 9;
                                      nItemLevel = Random(nItemLevel) + 1;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 341:
                                      nItemLevel = nItemLevel / 3;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 342:
                                      nItemLevel = nItemLevel / 3;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 343:
                                      nItemLevel = nItemLevel / 3;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                case 344:
                                      nItemLevel = nItemLevel / 3;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                // except for robes, armor uses a different level curve
                                // since there are fewer items per class
                                case 411:
                                {
                                    nItemLevel = nItemLevel / 2;
                                    if(nItemLevel < 1) nItemLevel = 1;
                                    sItemLevel = IntToString(nItemLevel);
                                    if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                    break;
                                }
                                case 421:
                                {
                                    nItemLevel = nItemLevel / 2;
                                    if(nItemLevel < 1) nItemLevel = 1;
                                    sItemLevel = IntToString(nItemLevel);
                                    if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                    break;
                                }
                                case 431:
                                {
                                    nItemLevel = nItemLevel / 2;
                                    if(nItemLevel < 1) nItemLevel = 1;
                                    sItemLevel = IntToString(nItemLevel);
                                    if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                    break;
                                }
                                case 441:
                                {
                                    nItemLevel = nItemLevel / 2;
                                    if(nItemLevel < 1) nItemLevel = 1;
                                    sItemLevel = IntToString(nItemLevel);
                                    if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                    break;
                                }
                                case 511:
                                {
                                      nItemLevel = nItemLevel / 2;
                                      if(nItemLevel<1) nItemLevel = 1;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                }
                                case 521:
                                {
                                      nItemLevel = nItemLevel / 2;
                                      if(nItemLevel<1) nItemLevel = 1;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                }
                                case 531:
                                {
                                      nItemLevel = nItemLevel / 2;
                                      if(nItemLevel<1) nItemLevel = 1;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                }
                                case 541:
                                {
                                      nItemLevel = nItemLevel / 3;
                                      if(nItemLevel<1) nItemLevel = 1;
                      // only six types of shields; adding some variety if item level is high
                      if(nItemLevel>6) nItemLevel = nItemLevel - 4;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                }
                                case 551:
                                {
                                      nItemLevel = nItemLevel / 2;
                                      if(nItemLevel<1) nItemLevel = 1;
                                      sItemLevel = IntToString(nItemLevel);
                                      if(nItemLevel < 10) sItemLevel = "0" + sItemLevel;
                                      break;
                                }
                            }
                            sTemplate = GetItemPrefix(nItemType) + sItemLevel;
                        }
             }
        return sTemplate;
}
// determines the exact bundle (disposable) item that is found
string GetBundlePrefix (int nItemLevel, int nItemType)
{
    // as a default, 1 of the selected item is used
    int nItemQuantity = 1;
    string sTemplate;
    string sModule = GetModuleName();
    //in late game, med pacs and grenades only.
    if(sModule == "851NIH" ||
        sModule == "852NIH" ||
        sModule == "901MAL" ||
        sModule == "902MAL" ||
        sModule == "903MAL" ||
        sModule == "904MAL" ||
        sModule == "905MAL" ||
        sModule == "906MAL")
        {
            if(Random(3) == 0) nItemType = 941;
            else if(Random(3) == 0) nItemType = 971+Random(9);
                else if (Random(3) == 0) nItemType = 931;
                    else if (Random(3) == 0) nItemType = 921;
                        else nItemType = 922;
        }
    switch (nItemType)
    {
        // credits
        case 911:
        {
            nItemQuantity = Random(10*nItemLevel) + Random(50) + 20;
            sTemplate = "g_i_credits015";
            break;
        }
        // chemicals and components
        case 921:
        {
            nItemQuantity = Random(nItemLevel) + Random(nItemLevel) +1;
            sTemplate = "compont_00001";
            break;
        }
        case 922:
        {
            nItemQuantity = Random(nItemLevel) + Random(nItemLevel) + 1;
            sTemplate = "chem_00001";
            break;
        }
        case 931:
        {
            nItemLevel = nItemLevel / 4+1;
            if(nItemLevel > 7) nItemLevel = 7;
            sTemplate = "a_shield_" + "0" + IntToString(nItemLevel);
            break;
        }
        // medpacs and repair kits
        case 941:
        {
            if(nItemLevel < 9)
                sTemplate = "g_i_medeqpmnt01";
                else if(nItemLevel < 16)
                    sTemplate = "g_i_medeqpmnt02";
                    else sTemplate = "g_i_medeqpmnt03";
            break;
        }
        case 942:
        {
            if(nItemLevel < 9)
                sTemplate = "g_i_drdrepeqp001";
                else if(nItemLevel < 16)
                    sTemplate = "g_i_drdrepeqp002";
                    else sTemplate = "g_i_drdrepeqp003";
            break;
        }
        // combat stims
        case 951:
        {
            nItemQuantity = 1;
            if(nItemLevel < 12)
                sTemplate = "g_i_adrnaline001";
                else sTemplate = "g_i_adrnaline004";
            break;
        }
        case 952:
        {
            nItemQuantity = 1;
            if(nItemLevel < 12)
                sTemplate = "g_i_adrnaline002";
                else sTemplate = "g_i_adrnaline005";
            break;
        }
        case 953:
        {
            nItemQuantity = 1;
            if(nItemLevel < 12)
                sTemplate = "g_i_adrnaline003";
                else sTemplate = "g_i_adrnaline006";
            break;
        }
        //medpacs are needed often, so they are a possibility here, too
        case 954:
        {
            if(nItemLevel < 9)
                sTemplate = "g_i_medeqpmnt01";
                else if(nItemLevel < 16)
                    sTemplate = "g_i_medeqpmnt02";
                    else sTemplate = "g_i_medeqpmnt03";
            break;
        }
        // credits should be common, so they appear twice
        case 961:
        {
            nItemQuantity = Random(2*nItemLevel) + Random(50) + 10;
            sTemplate = "g_i_credits014";
            break;
        }
        // grenades are a special case. if the player's level is too low for the
        // type of grenade rolled, then a lesser grenade is substituted instead
        case 971:
        {
            nItemQuantity = Random(2)+1;
            sTemplate = "g_w_adhsvgren001";
            break;
        }
        case 972:
        {
            if(nItemLevel < 4)
                sTemplate = "g_w_fraggren01";
                else
                {
                    sTemplate = "g_w_stungren01";
                }
            break;
        }
        case 973:
        {
            if(nItemLevel < 11)
                sTemplate = "g_w_fraggren01";
                else
                {
                    nItemQuantity = Random(2)+1;
                    sTemplate = "g_w_cryobgren001";
                }
            break;
        }
        case 974:
        {
            if(nItemLevel < 15)
                {
                    sTemplate = "g_w_firegren001";
                    nItemQuantity = Random(2)+1;
                }
                else
                {
                    nItemQuantity = 1;
                    sTemplate = "g_w_thermldet01";
                }
            break;
        }
        case 975:
        {
            if(nItemLevel < 9)
                sTemplate = "g_w_fraggren01";
                else
                {
                    nItemQuantity = Random(2)+1;
                    sTemplate = "g_w_firegren001";
                }
            break;
        }
        case 976:
        {
            sTemplate = "g_w_iongren01";
            break;
        }
        case 977:
        {
            if(nItemLevel < 7)
                sTemplate = "g_w_fraggren01";
                else
                {
                    nItemQuantity = Random(2)+1;
                    sTemplate = "g_w_poisngren01";
                }
            break;
        }
        case 978:
        {
            if(nItemLevel < 6)
                sTemplate = "g_w_sonicgren01";
                else
                {
                    nItemQuantity = Random(2)+1;
                    sTemplate = "g_w_sonicgren01";
                }
            break;
        }
        case 979:
        {
            nItemQuantity = Random(4)+1;
            sTemplate = "g_w_fraggren01";
            break;
        }
        // shields use a different level curve since there are only 7.
        // security spikes, computer spikes, and repair parts
        case 981:
        {
            sTemplate = "g_i_parts01";
            break;
        }
        case 982:
        {
            sTemplate = "g_i_progspike01";
            break;
        }
        case 983:
        {
            sTemplate = "g_i_secspike01";
            break;
        }
        case 991:
        {
            sTemplate = "w_rocket_01";
            break;
        }
        case 992:
        {
            sTemplate = "w_rocket_02";
            break;
        }
        case 993:
        {
            sTemplate = "w_rocket_03";
            break;
        }
        case 994:
        {
            sTemplate = "w_rocket_04";
            break;
        }
        case 995:
        {
            sTemplate = "w_rocket_05";
            break;
        }
    }
    //AurPostString(sTemplate+SWTR_GetQuantity(nItemQuantity),10,15,2.5);
    return(sTemplate + SWTR_GetQuantity(nItemQuantity));
}
// disposable items are handled different from normal/rare items
string GetTreasureBundle (int nItemLevel, int nItemType = 0)
{
    int nItemRandom = 0;
    int nRoll;
    int nPCLevel = GetGlobalNumber("G_PC_LEVEL");
    string sTemplate = "";
    // make sure player doesn't get rockets if no Mira
    if(nItemType == 990 && !IsAvailableCreature(NPC_MIRA)) nItemType = 980;
    // if the item class isn't specified, set the item class to be disposable items
    // (an item type hundreds digit of 9)
    if(nItemType == 0)
        {
            nRoll = Random(0)+9;
            sTemplate = GetTreasureBundle(nItemLevel, nRoll*100);
        }
        else
            {
            // if item sub-class isn't specified, determine the item sub-class (tens digit)
            if((nItemType % 100) == 0)
            {
                switch (nItemType / 100)
                {
                    case 9: {// only allow rockets to be found if mira has joined party
                    if(IsAvailableCreature(NPC_MIRA)) nItemRandom = 9;
                    // on Peragus (Level <6) security/computer spikes/parts/grenades must be prevented.
                    else if(nPCLevel < 6) nItemRandom = 6;
                        else nItemRandom = 8;
            break;}
                }
                nRoll = Random(nItemRandom) + 1;
                sTemplate = GetTreasureBundle(nItemLevel, nItemType + 10*nRoll);
            }
            else
                // item class and sub-class known; generate the base item tag
                if((nItemType % 10) == 0)
                    {
                        switch (nItemType / 10)
                        {
                            case 92: {nItemRandom = 2; break;}
                            case 94: {nItemRandom = 2; break;}
                            case 95: {nItemRandom = 4; break;}
                            case 97: {nItemRandom = 9; break;}
                            case 98: {nItemRandom = 3; break;}
                            // increase access to rockets as level increases
                            case 99: {nItemRandom = nItemLevel / 3;
                                      if(nItemRandom > 5) nItemRandom = 5;
                                      if(nItemRandom = 0) nItemRandom = 1;
                                      break;
                                      }
                        }
                        nRoll = (Random(nItemRandom) + 1);
                        sTemplate = GetBundlePrefix(nItemLevel, nItemType + nRoll);
                     }
                        else
                            sTemplate = GetBundlePrefix(nItemLevel, nItemType);
             }
        return sTemplate;
}
string GetTreasureNormal (int nItemLevel, int nItemType = 0)
{
    string sTemplate = GetTreasureSpecific(nItemLevel, nItemType);
    //AurPostString("Uncommon: "+sTemplate,2,2,2.0);
    return(sTemplate);
}
string GetTreasureRare (int nItemLevel, int nItemType = 0)
{
    string sTemplate = GetTreasureSpecific(nItemLevel + 5, nItemType);
    //AurPostString("Rare: "+sTemplate,2,3,2.0);
    return(sTemplate);
}
void PlaceTreasureDisposable(object oContainer = OBJECT_SELF, int numberOfItems = 1, int nItemType = 900)
{
    if(!GetLocalBoolean(oContainer,57))
    {
        SetLocalBoolean(oContainer,57,TRUE);
        int i;
        int nPCLevel = GetGlobalNumber("G_PC_LEVEL");
        if(nItemType < 900) nItemType = 0;
        int nItemLevel = nPCLevel + Random(6) - 4;
        if(nItemLevel < 1) nItemLevel = 1;
        if(nItemLevel >30) nItemLevel = 30;
        for (i = 1; i <= numberOfItems; i++)
        {
            string sItem;
            string sItemName;
            int nItemQuantity = 1;
            int j;
            sItem = GetTreasureBundle(nItemLevel, nItemType);
            //parse the item description
            //treasure blobs (strings) consist of the item template followed by the quantity
            if((j = FindSubString(sItem,"[")) >= 0)
            {
                nItemQuantity = StringToInt(GetSubString(sItem,j+1,4));
                sItemName = GetSubString(sItem,0,j);
            }
            else sItemName = sItem;
            //place the found item in the container
            CreateItemOnObject(sItemName,oContainer,nItemQuantity);
         }
    }
}
void PlaceTreasure(object oContainer = OBJECT_SELF, int numberOfItems = 1, int nItemType = 0)
{
    if(!GetLocalBoolean(oContainer, 57))
    {
        SetLocalBoolean(oContainer,57,TRUE);
        int i;
        int nRoll;
        int nPCLevel = GetGlobalNumber("G_PC_LEVEL");
        // increases variety of normal items found for level 1 PC
        if(nPCLevel == 1) nPCLevel = 2;
        for (i = 1; i <= numberOfItems; i++)
        {
            int nItemLevel = nPCLevel + Random(8) - 5;
            if(nItemLevel < 1) nItemLevel = 1;
            if(nItemLevel >30) nItemLevel = 30 - Random(7);
            // the chance of finding a rare item increases with each attempt
            // until one is found.
            nRoll = Random(95) + GetGlobalNumber("000_RareItemChance");
            if(nItemType > 0 && nItemType < 900 && nRoll < 91) nRoll = 95;
            string sItem;
            string sItemName;
            int nItemQuantity = 1;
            int j;
            AurPostString("nRoll: " + IntToString(nRoll),9,9,2.0);
            if(nRoll > 100)
            {
                sItem = GetTreasureRare(nItemLevel, nItemType);
                // if a rare item is found, reset the chance of finding the next one
                SetGlobalNumber("000_RareItemChance",0);
            }
            else
            {
            // if no rare item was found, increase the chance of finding one next time
            IncrementGlobalNumber("000_RareItemChance", 3);
            if(SWTR_InRange(nRoll,0,85)) sItem = GetTreasureBundle(nItemLevel, nItemType);
                else if(SWTR_InRange(nRoll,86,100)) sItem = GetTreasureNormal(nItemLevel, nItemType);
            }
            //parse the item description
            //treasure blobs (strings) consist of the item template followed by the quantity
            if((j = FindSubString(sItem,"[")) >= 0)
            {
                nItemQuantity = StringToInt(GetSubString(sItem,j+1,4));
                sItemName = GetSubString(sItem,0,j);
            }
            else sItemName = sItem;
            AurPostString("Item: " + sItemName,10,10+i,2.0);
            //place the found item in the container
            CreateItemOnObject(sItemName,oContainer,nItemQuantity);
         }
    }
}
void PlaceCritterTreasure(object oContainer = OBJECT_SELF, int numberOfItems = 1, int nItemType = 0)
{
    object oContainer = OBJECT_SELF;
    int i;
    int nRoll;
    int nPCLevel = GetGlobalNumber("G_PC_LEVEL");
    // increases variety of normal items found for level 1 PC
    if(nPCLevel == 1) nPCLevel = 2;
    int nItemLevel = nPCLevel + Random(8) - 5;
    if(nItemLevel < 1) nItemLevel = 1;
    if(nItemLevel >30) nItemLevel = 30 - Random(7);
    //AurPostString("nItemLevel: "+IntToString(nItemLevel),1,1,2.0);
    for (i = 1; i <= numberOfItems; i++)
    {
        // the chance of finding a rare item increases with each attempt
        // until one is found.
        nRoll = Random(95) + GetGlobalNumber("000_RareItemChance");
        string sItem;
        string sItemName;
        int nItemQuantity = 1;
        int j;
        //AurPostString("nRoll: "+IntToString(nRoll),2,2,2.0);
        if(nItemType > 0 && nItemType < 900 && nRoll < 91) nRoll = 95;
        if(nRoll > 100)
        {
            sItem = GetTreasureRare(nItemLevel, nItemType);
            // if a rare item is found, reset the chance of finding the next one
            SetGlobalNumber("000_RareItemChance",0);
        }
        else
        {
        // if no rare item was found, increase the chance of finding one next time
        IncrementGlobalNumber("000_RareItemChance", 3);
        if(SWTR_InRange(nRoll,0,85)) sItem = GetTreasureBundle(nItemLevel, nItemType);
            else if(SWTR_InRange(nRoll,86,100)) sItem = GetTreasureNormal(nItemLevel, nItemType);
        }
        //parse the item description
        //treasure blobs (strings) consist of the item template followed by the quantity
        if((j = FindSubString(sItem,"[")) >= 0)
        {
            nItemQuantity = StringToInt(GetSubString(sItem,j+1,4));
            sItemName = GetSubString(sItem,0,j);
        }
        else sItemName = sItem;
        //place the found item in the container
        //AurPostString("Item: "+sItemName,3,3,2.0);
        CreateItemOnObject(sItemName,oContainer,nItemQuantity);
    }
}
void PlaceTreasureJedi(object oContainer = OBJECT_SELF, int numberOfItems = 1)
{
int nRoll;
int i;
int nItemType;
for (i = 1; i <= numberOfItems; i++)
    {
        IncrementGlobalNumber("000_RareItemChance", 3);
        nRoll = Random(10)+1;
        if(nRoll == 1) nItemType = 240;
        else if(nRoll == 2) nItemType = 300;
        else if(nRoll == 3) nItemType = 440;
        else if(nRoll == 4) nItemType = 410;
        else nItemType = 900;
        PlaceCritterTreasure(oContainer, 1, nItemType);
    }
}
void PlaceTreasureDroid(object oContainer = OBJECT_SELF, int numberOfItems = 1, int nItemType = 0)
{
PlaceTreasure(oContainer, numberOfItems, 500);
}
void PlaceTreasurePeragus(object oContainer = OBJECT_SELF, int numberOfItems = 1, int nItemType = 0)
{
int nRoll = Random(100) + GetGlobalNumber("000_RareItemChance");
if(nRoll > 90)
{
// Upgrades
PlaceTreasure(oContainer, numberOfItems, 200);
}
else if(nRoll > 80)
{
// equipment
PlaceTreasure(oContainer, numberOfItems, 300);
}
else
{
IncrementGlobalNumber("000_RareItemChance",3);
PlaceTreasureDisposable(oContainer, numberOfItems);
}
}
""",
    "k_inc_utility": b"""//:: k_inc_utility
/*
    common functions used throughout various scripts
    Modified by Peter T. 17/03/03
    - Added UT_MakeNeutral2(), UT_MakeHostile1(), UT_MakeFriendly1() and UT_MakeFriendly2()
*/
//:: Created By: Jason Booth
//:: Copyright (c) 2002 Bioware Corp.
// Plot Flag Constants.
int SW_PLOT_BOOLEAN_01 = 0;
int SW_PLOT_BOOLEAN_02 = 1;
int SW_PLOT_BOOLEAN_03 = 2;
int SW_PLOT_BOOLEAN_04 = 3;
int SW_PLOT_BOOLEAN_05 = 4;
int SW_PLOT_BOOLEAN_06 = 5;
int SW_PLOT_BOOLEAN_07 = 6;
int SW_PLOT_BOOLEAN_08 = 7;
int SW_PLOT_BOOLEAN_09 = 8;
int SW_PLOT_BOOLEAN_10 = 9;
int SW_PLOT_HAS_TALKED_TO = 10;
int SW_PLOT_COMPUTER_OPEN_DOORS = 11;
int SW_PLOT_COMPUTER_USE_GAS = 12;
int SW_PLOT_COMPUTER_DEACTIVATE_TURRETS = 13;
int SW_PLOT_COMPUTER_DEACTIVATE_DROIDS = 14;
int SW_PLOT_COMPUTER_MODIFY_DROID = 15;
int SW_PLOT_REPAIR_WEAPONS = 16;
int SW_PLOT_REPAIR_TARGETING_COMPUTER = 17;
int SW_PLOT_REPAIR_SHIELDS = 18;
int SW_PLOT_REPAIR_ACTIVATE_PATROL_ROUTE = 19;
// UserDefined events
int HOSTILE_RETREAT = 1100;
//Alignment Adjustment Constants
int SW_CONSTANT_DARK_HIT_HIGH = -6;
int SW_CONSTANT_DARK_HIT_MEDIUM = -5;
int SW_CONSTANT_DARK_HIT_LOW = -4;
int SW_CONSTANT_LIGHT_HIT_LOW = -2;
int SW_CONSTANT_LIGHT_HIT_MEDIUM = -1;
int SW_CONSTANT_LIGHT_HIT_HIGH = 0;
// Returns a pass value based on the object's level and DC rating of 0, 1, or 2 (easy, medium, difficult)
// December 20 2001: Changed so that the difficulty is determined by the
// NPC's Hit Dice
int AutoDC(int DC, int nSkill, object oTarget);
//  checks for high charisma
int IsCharismaHigh();
//  checks for low charisma
int IsCharismaLow();
//  checks for normal charisma
int IsCharismaNormal();
//  checks for high intelligence
int IsIntelligenceHigh();
//  checks for low intelligence
int IsIntelligenceLow();
//  checks for normal intelligence
int IsIntelligenceNormal();
// checks to see if pc is completely dark side
int IsDarkComplete();
//  checks to see if pc is very dark side
int IsDarkHigh();
//  checks to see if pc is just a little dark side
int IsDarkLow();
//  checks to see if pc is dark side
int IsDark();
// checks to see if pc is completely light side
int IsLightComplete();
//  checks to see if pc is very light side
int IsLightHigh();
//  checks to see if pc is slightly light side
int IsLightLow();
//  checks to see if pc is light side
int IsLight();
//  checks to see if pc is neutral
int IsNeutral();
//  pads a string with the given pad character to the specified length
string PadString(string str = "",string pad = " ",int length = 0);
//  causes the given object to initiate conversation with the player
void TalkToPC(object oSpeaker);
//Gets the boolean state of a plot bit field
int UT_GetPlotBooleanFlag(object oTarget, int nIndex);
//Sets the boolean state of plot bit field using the SW_PLOT_BOOLEAN CONSTANTS
void UT_SetPlotBooleanFlag(object oTarget, int nIndex, int nState);
//Determines state of the HAS TALKED TO FLAG on the passed in object.
int UT_GetTalkedToBooleanFlag(object oTarget);
//Sets the Talked To Flag on the specified object.
void UT_SetTalkedToBooleanFlag(object oTarget, int nState = TRUE);
//Get the nearest PC to the specified object
object UT_GetNearestPCToObject(object oTarget = OBJECT_SELF);
//Determine if object is a PC
int UT_IsObjectPC(object oTarget = OBJECT_INVALID);
//does a heavy darkside adjustment on the player
void UT_DarkHigh(object oTarget);
//does a medium darkside adjustment on the player
void UT_DarkMed(object oTarget);
//does a small darkside adjustment on the player
void UT_DarkSml(object oTarget);
//does a heavy lightside adjustment on the player
void UT_LightHigh(object oTarget);
//does a medium lightside adjustment on the player
void UT_LightMed(object oTarget);
//does a small lightside adjustment on the player
void UT_LightSml(object oTarget);
//Resets all of an objects Bit Fields to TRUE or FALSE
void UT_ResetPlotBooleanFlags(object oToChange, int nState);
//make object do an uninterruptible path move
void UT_PlotMovePath(string sWayPointTag,int nFirst, int nLast, int nRun = FALSE);
//make object do an uninterruptible move to an object
void UT_PlotMoveObject(object oTarget,int nRun = FALSE);
//make object do an uninterruptible move to a location
void UT_PlotMoveLocation(location lTarget,int nRun = FALSE);
//perform a skill check
int UT_SkillCheck(int iDC, int iSkill, object oTarget);
//test whether force power is dark side
int UT_IsDarkSidePower(int iSpellID);
//Creates an object at a location without having to pass back an object.  Can be
//used in DelayCommand functions.
void UT_CreateObject(int nObjectType, string sTemplate, location lLocal);
//Command used in the swoop droid triggers to activate the spawning in of messengers.
void UT_SpawnMessenger();
//Makes the NPC flee to an SW_EXIT waypoint and destroy itself
void UT_ExitArea(int nRun = FALSE, int nParam = 0, object oObj = OBJECT_SELF);
//Determines the number of spikes or parts to take away from the PC.
int UT_DeterminesItemCost(int nDC, int nSkill);
//Remove a number of computer spikes.
void UT_RemoveComputerSpikes(int nNumber);
//Remove a number of parts
void UT_RemoveRepairParts(int nNumber);
//Return items amounts for either the Spikes or the Parts
int UT_ReturnSpikePartAmount(int nSkill);
//Searches the area and changes all turrets with the specified tag to the neutral faction
void UT_MakeNeutral(string sObjectTag);
//Searches the area and changes all droids with the specified tag to the insane faction
void UT_MakeInsane(string sObjectTag);
//Searches through the ara and stuns all droids with the given tag permanently
void UT_StunDroids(string sObjectTag);
//Starts a fight
void UT_StartCombat(object oObject);
//Releases gas into the room and kills all biologicals in the specified radius
//The radius should be between 2 - 5m
void UT_GasRoom(string sWayTag, float fDistance, int bIndiscriminant = TRUE);
//Overloads a power conduit and does 10d6 damage to all within the specified radius
//bIndiscriminant: TRUE-affects all creatures; FALSE-affects only enemies
void UT_OverloadConduit(string sObjectTag, float fDistance, int bIndiscriminant = TRUE);
//Returns a creature to the nearest "wp_" waypoint.
//During this time the creature will be uncommanable
void UT_ReturnToBase(string sTag = "wp_homebase");
//NPC initiates a conversation with the player.
void UT_NPC_InitConversation(string sNPCTag,string sDlg = "",object oEntered = OBJECT_INVALID);
//Sets the Journal entry for the starmap automatically.
void UT_SetStarmapJournal();
//Creates number of creatures with a specific template at a specified waypoint tag.
//Total is the number times the loop will run.
//fTimeDelay is the number seconds between iterations.
//nSpawnIncrement is the number of templates spawned in per iteration.
void UT_RunCombatEncounter(string sTemplate, string sTag, int nTotal = 3, float fTimeDelay = 1.5, int nSpawnIncrement = 1);
//Sets the talik to flag on all objects with the specified tag using the PC as a focal point.
void UT_SetTalkToFlagByTag(string sTag);
//Locks any other doors with the same tag.  Makes them plot.
void UT_LockDoorDuplicates(string sTag);
//Check to see if the Party member specified is in the party and within the distance given.
int UT_CheckCanPartyMemberInterject(int nNPC_Constant, float fDistance);
//Reinitializes the Party Planet Initialization Variables
void UT_ReinitializePartyPlanetVariables();
//Teleport a party member
void UT_TeleportPartyMember(object oPartyMember, location lDest);
//Returns true if oTarget is the object of interest of an attacker
int UT_GetUnderAttack(object oTarget);
//Teleport the whole party and face them the direction that the objects they
//are being jumped to are facing.
void UT_TeleportWholeParty(object oWP0, object oWP1, object oWP2);
//Pause and restart a conversation.
void UT_ActionPauseConversation(float fDelay);
//Spawn NPC without return
void UT_SpawnAvailableNPC(int nNPC, location lWay);
//Goes through the current party and heals them.
void UT_HealParty();
//Heals the object passed in.
void UT_HealNPC(object oNPC);
//Heals all of the Party NPCs in Area
void UT_HealAllPartyNPCs();
//This function removes party members. It stores the npc constants of the removed party members.
void UT_StoreParty();
//This function restore party members. It will only restore party members removed via the UT_StoreParty funcion
void UT_RestoreParty();
//Returns the NPC code for the given object if it is a NPC, otherwise it returns -1
int UT_GetNPCCode(object oNPC);
//restores all party mambers to 1 hp if tempoarily dead
void UT_RestorePartyToOneHealth();
//Alter the stack size of a given item
void UT_AlterItemStack(object oItem,int iNum = 1,int bDecrement = TRUE);
//Goes through the party and removes them. This is best used on Module Load when the object are not actually created yet.
void UT_ClearAllPartyMembers();
//Does a DC check just using an ability score
int UT_AbilityCheck(int iDC, int iAbility, object oTarget);
//Validate a jump back to the last location by comparing module names.
int UT_ValidateJump(string sLastModule);
//Make alignment change based on a constant passed in to the function
void UT_AdjustCharacterAlignment(object oTarget, int nScale);
// Added by Peter T. 17/03/03
// Searches the area and changes all instances with the specified tag to the Neutral faction
void UT_MakeNeutral2(string sObjectTag);
// Added by Peter T. 17/03/03
// Searches the area and changes all instances with the specified tag to the Hostile_1 faction
void UT_MakeHostile1(string sObjectTag);
// Added by Peter T. 17/03/03
// Searches the area and changes all instances with the specified tag to the Friendly_1 faction
void UT_MakeFriendly1(string sObjectTag);
// Added by Peter T. 17/03/03
// Searches the area and changes all instances with the specified tag to the Friendly_2 faction
void UT_MakeFriendly2(string sObjectTag);
//performs a standard torture cage effect
void UT_ActivateTortureCage(object oCage, object oTarget,float fDuration);
//Makes the animal face the PC, do its victory and play a sound passed in.
//Should be used in conjunction with the k_def_interact spawn in
void UT_DoAmbientReaction(string sSound);
//STAR MAP FUNCTION SET
//Advances K_STAR_MAP, sets the journal and sets the talk to flag.
void UT_StarMap1VariableSet();
//Plays the animations necessary for the current state of the starmap variable
void UT_StarMap2PlayAnimation();
//Returns the appropriate animation loop for the Star Map
int UT_StarMap3GetLoopAnim(int nStarMapVar);
//Runs the entire Starmap sequence as a black box with no extra scripting required.
void UT_StarMap4RunStarMap();
// JAB-OEI 8/5/04
// Stores the facing of the party leader to be preserved during conversation
// Can restore with UT_RestoreLeaderFacing
void UT_StoreLeaderFacing(object oLeader);
// JAB-OEI 8/5/04
// Restores leader facing direction after conversation (call this on the last red node of a conversation)
// should be called in conjunction with UT_StoreLeaderFacing();
void UT_RestoreLeaderFacing(object oLeader);
// Tony Evans 9/14/04
// Counts the number of creatures of the OBJECT_TYPE of a given tag, or objects that contain a given tag
// Returns the number of objects
int UT_ObjectCount(string sTag = "", int iName = 0);
///////////////////////////////////////////////////////////////////////////////
/*
    AutoDC
Relation to Max Persuade   Low Persaude chance   Mid Persuade chance   High Persuade chance
Higher than Max                  100                   100                     100
75% to 100%                      100                   100                     75
50% to 75%                       75                    50                      25
25% to 50%                       50                    25                      0
0% to 25%                        25                    0                       0
*/
///////////////////////////////////////////////////////////////////////////////
//  Returns a pass value based on the object's level and the suggested DC
// December 20 2001: Changed so that the difficulty is determined by the
// NPC's Hit Dice
///////////////////////////////////////////////////////////////////////////////
//  Created By: Preston Watamaniuk
///////////////////////////////////////////////////////////////////////////////
int AutoDC(int DC, int nSkill, object oTarget)
{
    int nSkillLvl = GetSkillRank(nSkill, oTarget);
    int nMax;
    int nRoll = d100();
    nMax = GetHitDice(oTarget) + 5;
    float fMax = IntToFloat(nMax);
    float fSkillLvl = IntToFloat(nSkillLvl);
    float fPercent = fSkillLvl/fMax;
    AurPostString("Skill Percentage Chance = " + FloatToString(fPercent,4,2),5,5,3.0);
    AurPostString("Percentage Die Roll     = " + IntToString(nRoll),5,7,3.0);
    if(fPercent <= 0.25)
    {
        if(DC == 0 && nRoll <= 40){return TRUE;}
    }
    else if(fPercent > 0.25 && fPercent <= 0.5)
    {
        if(DC == 0 && nRoll <= 50){return TRUE;}
        if(DC == 1 && nRoll <= 25){return TRUE;}
    }
    else if(fPercent > 0.5 && fPercent <= 0.75)
    {
        if(DC == 0 && nRoll <= 75){return TRUE;}
        if(DC == 1 && nRoll <= 50){return TRUE;}
        if(DC == 2 && nRoll <= 25){return TRUE;}
    }
    else if(fPercent > 0.75 && fPercent <= 1.0)
    {
        if(DC == 0 && nRoll <= 100){return TRUE;}
        if(DC == 1 && nRoll <= 100){return TRUE;}
        if(DC == 2 && nRoll <= 75){return TRUE;}
    }
    else if(fPercent > 1.0)
    {
        return TRUE;
    }
    return FALSE;
    //LEGACY CODE CHANGED ON FEB 18, 2003
    /*
    Easy = Lvl/4 ...rounded up
    Moderate = 3/Lvl + Lvl ...rounded up
    Difficult = Lvl * 1.5 + 6 ...rounded up
    int nLevel = GetHitDice(OBJECT_SELF);
    if(nLevel <= 0 || nLevel > 20)
    {
        nLevel = GetHitDice(GetPCSpeaker());
    }
    int nTest = 0;
    switch (DC)
    {
    case 0: nTest = nLevel / 4 + 1; break;
        // * minor tweak to lower the values a little
    case 1: nTest = (3 / nLevel + nLevel) - abs( (nLevel/2) -2); break;
    case 2: nTest = FloatToInt(nLevel * 1.5 + 6) - abs( ( FloatToInt(nLevel/1.5) -2));   break;
    }
    //SpeakString(IntToString(nTest));
    // * Roll d20 + skill rank vs. DC + 10
    if (GetSkillRank(nSkill, oTarget) + d20() >= nTest + 10)
    {
       return TRUE;
    }
       return FALSE;
    */
}
//::///////////////////////////////////////////////
//:: IsCharismaHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for high charisma
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsCharismaHigh()
{
  if (GetAbilityScore(GetPCSpeaker(),ABILITY_CHARISMA) >= 15)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
//::///////////////////////////////////////////////
//:: IsCharismaLow
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for low charisma
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsCharismaLow()
{
  return !IsCharismaNormal();
}
//::///////////////////////////////////////////////
//:: IsCharismaNormal
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for normal charisma
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsCharismaNormal()
{
  if (GetAbilityScore(GetPCSpeaker(),ABILITY_CHARISMA) >= 10)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
//::///////////////////////////////////////////////
//:: IsIntelligenceHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for high intelligence
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsIntelligenceHigh()
{
  if (GetAbilityScore(GetPCSpeaker(),ABILITY_INTELLIGENCE) >= 15)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
//::///////////////////////////////////////////////
//:: IsIntelligenceLow
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for low intelligence
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsIntelligenceLow()
{
  return !IsIntelligenceNormal();
}
//::///////////////////////////////////////////////
//:: IsIntelligenceNormal
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks for normal intelligence
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsIntelligenceNormal()
{
  if (GetAbilityScore(GetPCSpeaker(),ABILITY_INTELLIGENCE) >= 10)
  {
    return TRUE;
  }
  else
  {
    return FALSE;
  }
}
//::///////////////////////////////////////////////
//:: IsDarkComplete
//:: Copyright (c) 2004 Obsidian Entertainment
//:://////////////////////////////////////////////
/*
//  checks to see if pc is completely dark side
*/
//:://////////////////////////////////////////////
//:: Created By:  Kevin Saunders
//:: Created On:  June 26, 2004
//:://////////////////////////////////////////////
int IsDarkComplete()
{
    int align = GetGoodEvilValue(GetPCSpeaker());
    if(align == 0)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsDarkHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is very dark side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsDarkHigh()
{
    int align = GetGoodEvilValue(GetPCSpeaker());
    if(align >= 0 && align < 20)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsDarkLow
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is just a little dark side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsDarkLow()
{
    int align = GetGoodEvilValue(GetPCSpeaker());
    if(align >= 20 && align < 40)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsDark
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is dark side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsDark()
{
    if(IsDarkLow() || IsDarkHigh())
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsLightComplete
//:: Copyright (c) 2004 Obsidian Entertainment
//:://////////////////////////////////////////////
/*
//  checks to see if pc is completely light side
*/
//:://////////////////////////////////////////////
//:: Created By:  Kevin Saunders
//:: Created On:  June 26, 2004
//:://////////////////////////////////////////////
int IsLightComplete()
{
    int align = GetGoodEvilValue(GetPCSpeaker());
    if(align == 100)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsLightHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is very light side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsLightHigh()
{
    int align = GetGoodEvilValue(GetPCSpeaker());
    if(align >= 81)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsLightLow
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is slightly light side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsLightLow()
{
    int align = GetGoodEvilValue(GetPCSpeaker());
    if(align >= 61 && align < 81)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsLight
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is light side
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsLight()
{
    if(IsLightLow() || IsLightHigh())
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: IsNeutral
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  checks to see if pc is neutral
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 19, 2002
//:://////////////////////////////////////////////
int IsNeutral()
{
    if(!IsDark() && !IsLight())
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
//::///////////////////////////////////////////////
//:: PadString
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  pads a string with the given pad character to the specified length
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  June 20, 2002
//:://////////////////////////////////////////////
string PadString(string str = "",string pad = " ",int length = 0)
{
  while(GetStringLength(str) < length)
  {
    str = pad + str;
  }
  return(str);
}
//::///////////////////////////////////////////////
//:: TalkToPC
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//  causes the given object to initiate conversation with the player
*/
//:://////////////////////////////////////////////
//:: Created By:  Jason Booth
//:: Created On:  July 12, 2002
//:://////////////////////////////////////////////
void TalkToPC(object oSpeaker)
{
  AssignCommand(oSpeaker,ClearAllActions());
  AssignCommand(oSpeaker,
  ActionStartConversation(GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC)));
}
//::///////////////////////////////////////////////
//:: Get Boolean Plot Flag
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets the boolean state of a plot bit field
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
int UT_GetPlotBooleanFlag(object oTarget, int nIndex)
{
    int nPlotBoolean;
    if(nIndex >= 0 && nIndex <= 19 && GetIsObjectValid(oTarget))
    {
        nPlotBoolean = GetLocalBoolean(oTarget, nIndex);
        if(nPlotBoolean > 0)
        {
            return TRUE;
        }
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Set Boolean Plot Flag
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the boolean state of a plot bit field
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
void UT_SetPlotBooleanFlag(object oTarget, int nIndex, int nState)
{
    int nLevel = GetHitDice(GetFirstPC());
    if(nState == TRUE)
    {
        if(nIndex == SW_PLOT_COMPUTER_OPEN_DOORS ||
           nIndex == SW_PLOT_REPAIR_WEAPONS ||
           nIndex == SW_PLOT_REPAIR_TARGETING_COMPUTER ||
           nIndex == SW_PLOT_REPAIR_SHIELDS)
        {
            GiveXPToCreature(GetFirstPC(), nLevel * 15);
        }
        else if(nIndex == SW_PLOT_COMPUTER_USE_GAS || nIndex == SW_PLOT_REPAIR_ACTIVATE_PATROL_ROUTE || nIndex == SW_PLOT_COMPUTER_MODIFY_DROID)
        {
            GiveXPToCreature(GetFirstPC(), nLevel * 20);
        }
        else if(nIndex == SW_PLOT_COMPUTER_DEACTIVATE_TURRETS ||
                nIndex == SW_PLOT_COMPUTER_DEACTIVATE_DROIDS)
        {
            GiveXPToCreature(GetFirstPC(), nLevel * 10);
        }
    }
    if(nIndex >= 0 && nIndex <= 19 && GetIsObjectValid(oTarget))
    {
        if(nState == TRUE || nState == FALSE)
        {
            SetLocalBoolean(oTarget, nIndex, nState);
        }
    }
}
//::///////////////////////////////////////////////
//:: Get Talked To Flag
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the state of the Talk to Flag
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
int UT_GetTalkedToBooleanFlag(object oTarget)
{
    int nPlotFlag;
    if(GetIsObjectValid(oTarget))
    {
        nPlotFlag = GetLocalBoolean(oTarget, SW_PLOT_HAS_TALKED_TO);
        if(nPlotFlag > 0)
        {
            return TRUE;
        }
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Set Talked To Flag
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the talked to flag to the given state.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
void UT_SetTalkedToBooleanFlag(object oTarget, int nState = TRUE)
{
    if(GetIsObjectValid(oTarget))
    {
        if(nState == TRUE || nState == FALSE)
        {
            SetLocalBoolean(oTarget, SW_PLOT_HAS_TALKED_TO, nState);
        }
    }
}
//::///////////////////////////////////////////////
//:: UT_GetNearestPCToObject
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//Get the nearest PC to the specified object
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
object UT_GetNearestPCToObject(object oTarget = OBJECT_SELF)
{
  return(GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC,oTarget));
}
//::///////////////////////////////////////////////
//:: UT_IsObjectPC
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//Determine if object is a PC
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
int UT_IsObjectPC(object oTarget = OBJECT_INVALID)
{
  object oPC = GetFirstPC();
  while(oPC != OBJECT_INVALID)
  {
    if(oTarget == oPC)
    {
      return(TRUE);
    }
    oPC = GetNextPC();
  }
  return(FALSE);
}
//::///////////////////////////////////////////////
//:: Adjust Character Alignment
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Make alignment change based on a constant
    passed in to the function
    nDarkSide = 1 then do a darkside hit.
    nScale is the size of the hit. -3 to +3
    //Alignment Adjustment Constants
    int SW_CONSTANT_DARK_HIT_HIGH = -6;
    int SW_CONSTANT_DARK_HIT_MEDIUM = -5;
    int SW_CONSTANT_DARK_HIT_LOW = -4;
    int SW_CONSTANT_LIGHT_HIT_LOW = -2;
    int SW_CONSTANT_LIGHT_HIT_MEDIUM = -1;
    int SW_CONSTANT_LIGHT_HIT_HIGH = 0;
                    1       2       3         4      5
                    VLight  Light   Neutral   Dark   VDark
      High Light    2       4       6         8      10
      Mid Light     1       2       4         6      8
      Low Light     1       1       2         4      6
      Low Dark      -6      -4      -2        -1     -1
      Mid Dark      -8      -6      -4        -2     -1
      High Dark     -10     -8      -6        -4     -2
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 23, 2002
//:://////////////////////////////////////////////
void UT_AdjustCharacterAlignment(object oTarget, int nScale)
{
    //Find out if the target is good or evil
    int nScore = GetGoodEvilValue(oTarget);
    int nAlignType;
    //Set the type of alignment hit to do.
    if(nScale == SW_CONSTANT_DARK_HIT_HIGH ||
       nScale == SW_CONSTANT_DARK_HIT_MEDIUM ||
       nScale == SW_CONSTANT_DARK_HIT_LOW)
    {
        nAlignType = ALIGNMENT_DARK_SIDE;
    }
    else
    {
        nAlignType = ALIGNMENT_LIGHT_SIDE;
    }
    int nHit;
    int nAlignCategory;
    //Set the alignment category which will determine the base from which to calculate the hit.
    if(nScore >= 85)//VERY GOOD
    {
        nAlignCategory = 1;
    }
    else if(nScore < 85 && nScore > 60)//GOOD
    {
        nAlignCategory = 2;
    }
    else if(nScore <= 60 && nScore >= 40)//NEUTRAL
    {
        nAlignCategory = 3;
    }
    else if(nScore < 40 && nScore >= 15)//EVIL
    {
        nAlignCategory = 4;
    }
    else //VERY EVIL
    {
        nAlignCategory = 5;
    }
    //Calculate the hit.
    nHit = (nAlignCategory + nScale) * 2;
    if(nHit < 0)
    {
        nHit = nHit * -1;
    }
    if(nHit == 0)
    {
        nHit = 1;
    }
    //Zero results that do not mathematically fit within the formula.
    if(nAlignCategory == 1 && nScale == SW_CONSTANT_LIGHT_HIT_LOW)
    {
        nHit = 1;
    }
    else if(nAlignCategory == 5 && nScale == SW_CONSTANT_DARK_HIT_LOW)
    {
        nHit = 1;
    }
    AurPostString("Hit = " + IntToString(nHit), 5, 5, 4.0);
    AdjustAlignment(oTarget, nAlignType, nHit);
}
//::///////////////////////////////////////////////
//:: UT_DarkHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a heavy darkside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_DarkHigh(object oTarget)
{
    UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_DARK_HIT_HIGH);
    //AdjustAlignment(oTarget,ALIGNMENT_DARK_SIDE,10);
}
//::///////////////////////////////////////////////
//:: UT_DarkMed
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a medium darkside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_DarkMed(object oTarget)
{
  UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_DARK_HIT_MEDIUM);
  //AdjustAlignment(oTarget,ALIGNMENT_DARK_SIDE,5);
}
//::///////////////////////////////////////////////
//:: UT_DarkSml
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a small darkside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_DarkSml(object oTarget)
{
  UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_DARK_HIT_LOW);
  //AdjustAlignment(oTarget,ALIGNMENT_DARK_SIDE,1);
}
//::///////////////////////////////////////////////
//:: UT_LightHigh
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a heavy lightside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_LightHigh(object oTarget)
{
  UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_LIGHT_HIT_HIGH);
  //AdjustAlignment(oTarget,ALIGNMENT_LIGHT_SIDE,10);
}
//::///////////////////////////////////////////////
//:: UT_LightMed
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a medium lightside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_LightMed(object oTarget)
{
  UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_LIGHT_HIT_MEDIUM);
  //AdjustAlignment(oTarget,ALIGNMENT_LIGHT_SIDE,5);
}
//::///////////////////////////////////////////////
//:: UT_LightSml
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//does a small lightside adjustment on the target
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: July 16, 2002
//:://////////////////////////////////////////////
void UT_LightSml(object oTarget)
{
  UT_AdjustCharacterAlignment(oTarget, SW_CONSTANT_LIGHT_HIT_LOW);
  //AdjustAlignment(oTarget,ALIGNMENT_LIGHT_SIDE,1);
}
//::///////////////////////////////////////////////
//:: Reset Plot Booleans
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Goes through all of the plot bit fields and sets
    them to nState.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 15, 2002
//:://////////////////////////////////////////////
void UT_ResetPlotBooleanFlags(object oToChange, int nState)
{
    int nCnt;
    for(nCnt; nCnt <= 9; nCnt++)
    {
        if(nState == TRUE || nState == FALSE)
        {
            SetLocalBoolean(oToChange, nCnt, nState);
        }
    }
}
//::///////////////////////////////////////////////
//:: Check Manaan Medical State
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns true if the manaan facilities have
    been destroyed.  Global = 4 returns true.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 19, 2002
//:://////////////////////////////////////////////
int UT_GetIsKoltoDestroyed()
{
    return GetGlobalNumber("MAN_PLANET_PLOT") == 4;
}
//::///////////////////////////////////////////////
//:: UT_PlotMovePath
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make object do an uninterruptible path move
//based on code done by Aidan (actually, pretty much a copy)
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 16, 2002
//:://////////////////////////////////////////////
void UT_PlotMovePath(string sWayPointTag,int nFirst, int nLast, int nRun = FALSE)
{
    int nInc = 1;
    object oWP;
    int nIdx;
    if(nFirst > nLast)
    {
        nInc = -1;
    }
    for(nIdx = nFirst - nInc; abs(nLast - nIdx) > 0 && abs(nLast - nIdx) <= abs((nLast - nFirst) + 1); nIdx = nIdx + nInc)
    {
        oWP = GetObjectByTag(sWayPointTag + IntToString(nIdx + nInc));
        if(GetIsObjectValid(oWP))
        {
            ActionForceMoveToObject(oWP,nRun);
        }
    }
    ActionDoCommand(SetCommandable(TRUE));
    SetCommandable(FALSE);
}
//::///////////////////////////////////////////////
//:: UT_PlotMoveObject
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make object do an uninterruptible move to an object
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 16, 2002
//:://////////////////////////////////////////////
void UT_PlotMoveObject(object oTarget,int nRun = FALSE)
{
  ActionForceMoveToObject(oTarget,nRun);
  ActionDoCommand(SetCommandable(TRUE));
  SetCommandable(FALSE);
}
//::///////////////////////////////////////////////
//:: UT_PlotMoveLocation
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//make object do an uninterruptible move to a location
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 16, 2002
//:://////////////////////////////////////////////
void UT_PlotMoveLocation(location lTarget,int nRun = FALSE)
{
  ActionForceMoveToLocation(lTarget,nRun);
  ActionDoCommand(SetCommandable(TRUE));
  SetCommandable(FALSE);
}
//::///////////////////////////////////////////////
//:: UT_SkillCheck
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//perform a skill check using a given DC
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: August 29, 2002
//:://////////////////////////////////////////////
int UT_SkillCheck(int iDC, int iSkill, object oTarget)
{
  if (GetSkillRank(iSkill, oTarget) + d20() >= iDC)
  {
    return TRUE;
  }
  return FALSE;
}
//::///////////////////////////////////////////////
//:: UT_IsDarkSidePower
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
//test whether force power is dark side
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Sept. 11, 2002
//:://////////////////////////////////////////////
int UT_IsDarkSidePower(int iSpellID)
{
  if(iSpellID == FORCE_POWER_AFFLICTION) return(TRUE);
  if(iSpellID == FORCE_POWER_CHOKE) return(TRUE);
  if(iSpellID == FORCE_POWER_DEATH_FIELD) return(TRUE);
  if(iSpellID == FORCE_POWER_DRAIN_LIFE) return(TRUE);
  if(iSpellID == FORCE_POWER_FEAR) return(TRUE);
  if(iSpellID == FORCE_POWER_FORCE_STORM) return(TRUE);
  if(iSpellID == FORCE_POWER_HORROR) return(TRUE);
  if(iSpellID == FORCE_POWER_INSANITY) return(TRUE);
  if(iSpellID == FORCE_POWER_KILL) return(TRUE);
  if(iSpellID == FORCE_POWER_LIGHTNING) return(TRUE);
  if(iSpellID == FORCE_POWER_PLAGUE) return(TRUE);
  if(iSpellID == FORCE_POWER_SHOCK) return(TRUE);
  if(iSpellID == FORCE_POWER_SLOW) return(TRUE);
  if(iSpellID == FORCE_POWER_WOUND) return(TRUE);
  if(iSpellID == FORCE_POWER_CRUSH_OPPOSITION_I) return(TRUE);
  if(iSpellID == FORCE_POWER_CRUSH_OPPOSITION_II) return(TRUE);
  if(iSpellID == FORCE_POWER_CRUSH_OPPOSITION_III) return(TRUE);
  if(iSpellID == FORCE_POWER_CRUSH_OPPOSITION_IV) return(TRUE);
  if(iSpellID == FORCE_POWER_CRUSH_OPPOSITION_V) return(TRUE);
  if(iSpellID == FORCE_POWER_CRUSH_OPPOSITION_VI) return(TRUE);
  if(iSpellID == FORCE_POWER_DRAIN_FORCE) return(TRUE);
  if(iSpellID == FORCE_POWER_IMPROVED_DRAIN_FORCE) return(TRUE);
  if(iSpellID == FORCE_POWER_MASTER_DRAIN_FORCE) return(TRUE);
  if(iSpellID == FORCE_POWER_FORCE_SCREAM) return(TRUE);
  if(iSpellID == FORCE_POWER_IMPROVED_FORCE_SCREAM) return(TRUE);
  if(iSpellID == FORCE_POWER_MASTER_FORCE_SCREAM) return(TRUE);
  if(iSpellID == FORCE_POWER_FURY) return(TRUE);
  if(iSpellID == FORCE_POWER_IMPROVED_FURY) return(TRUE);
  if(iSpellID == FORCE_POWER_MASTER_FURY) return(TRUE);
  if(iSpellID == FORCE_POWER_FORCE_CRUSH) return(TRUE);
  return(FALSE);
}
//::///////////////////////////////////////////////
//:: UT_CreateObject
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Create an object without needing a variable
    to pass it into.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Sept. 21, 2002
//:://////////////////////////////////////////////
void UT_CreateObject(int nObjectType, string sTemplate, location lLocal)
{
    object oCreate = CreateObject(nObjectType, sTemplate, lLocal);
}
//::///////////////////////////////////////////////
//:: UT_JumpPartyToObject
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Move the entire party to the object specified.
*/
//:://////////////////////////////////////////////
//:: Created By: John Winski
//:: Created On: Sept. 24, 2002
//:://////////////////////////////////////////////
void UT_JumpPartyToObject(object oTarget)
{
    UT_RestorePartyToOneHealth();
    object oMember1 = GetPartyMemberByIndex(0);
    object oMember2 = GetPartyMemberByIndex(1);
    object oMember3 = GetPartyMemberByIndex(2);
    if (GetIsObjectValid(oMember1) == TRUE)
    {
        AssignCommand(oMember1, ClearAllActions());
        AssignCommand(oMember1, JumpToObject(oTarget));
    }
    if (GetIsObjectValid(oMember2) == TRUE)
    {
        AssignCommand(oMember2, ClearAllActions());
        AssignCommand(oMember2, JumpToObject(oTarget));
    }
    if (GetIsObjectValid(oMember2) == TRUE)
    {
        AssignCommand(oMember3, ClearAllActions());
        AssignCommand(oMember3, JumpToObject(oTarget));
    }
}
//::///////////////////////////////////////////////
//:: UT_JumpPartyToLocation
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Move the entire party to the location specified.
*/
//:://////////////////////////////////////////////
//:: Created By: John Winski
//:: Created On: Sept. 24, 2002
//:://////////////////////////////////////////////
void UT_JumpPartyToLocation(location lTarget)
{
    object oMember1 = GetPartyMemberByIndex(0);
    object oMember2 = GetPartyMemberByIndex(1);
    object oMember3 = GetPartyMemberByIndex(2);
    UT_RestorePartyToOneHealth();
    if (GetIsObjectValid(oMember1) == TRUE)
    {
        AssignCommand(oMember1, ClearAllActions());
        AssignCommand(oMember1, JumpToLocation(lTarget));
    }
    if (GetIsObjectValid(oMember2) == TRUE)
    {
        AssignCommand(oMember2, ClearAllActions());
        AssignCommand(oMember2, JumpToLocation(lTarget));
    }
    if (GetIsObjectValid(oMember2) == TRUE)
    {
        AssignCommand(oMember3, ClearAllActions());
        AssignCommand(oMember3, JumpToLocation(lTarget));
    }
}
//::///////////////////////////////////////////////
//:: Spawn Messenger
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Determines which messenger to spawn in for a specific planet.
    Uses the waypoint K_MESSENGER_SPAWN to determine where to place an incoming messenger
    Carth: KOR_DANEL == 1. Messenger = Jordo.
    Bastila: K_SWG_HELENA == 1. Messenger = Malare.
    Mission: Mis_MissionTalk == 5  Messenger = Lena
    Canderous: G_CAND_STATE == 8, G_CAND_PLOT == 0, K_CURRENT_PLANET != 35.  Messenger = Jagi
    Juhani: G_JUHANIH_STATE == 7, G_JUHANI_PLOT == 0. Messenger = Xor
    Endar Spire     5
    Taris           10
    Dantooine       15
    --Kashyyk       20
    --Manaan        25
    --Korriban      30
    --Tatooine      35
    Leviathan       40
    Unknown World   45
    Star Forge      50
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Sept 26, 2002
//:://////////////////////////////////////////////
void UT_SpawnMessenger()
{
/*
    object oPC = GetFirstPC();
    object oWay = GetWaypointByTag("K_MESSENGER_SPAWN");
    object oNPC;
    int nGlobal_1, nGlobal_2;
    location lLocal;
    int bConditional = FALSE;
    int nXor = GetGlobalNumber("K_XOR_AMBUSH");
    //Do not fire any messenger plots on Kashyyyk if Chuundar is dead
    if(GetGlobalNumber("K_CURRENT_PLANET") == 20)
    {
        bConditional = GetGlobalBoolean("kas_ChuundarDead");
    }
    if(bConditional == FALSE)
    {
        if(nXor == 0 || nXor > 2)
        {
            if(GetIsObjectValid(oWay))
            {
                lLocal = GetLocation(oWay);
                //MODIFIED by Preston Watamaniuk on April 11
                //Added the exchange crony Ziagrom to tell the PC about the special store.
                if(GetGlobalNumber("K_KOTOR_MASTER") >= 20 &&
                   GetGlobalNumber("K_Exchange_Store") == 0 &&
                   GetGlobalBoolean("K_MESS_ZIAGROM") == FALSE)
                {
                    SetGlobalBoolean("K_MESS_ZIAGROM", TRUE);
                    oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_Ziagrom", lLocal);
                    NoClicksFor(2.2);
                    DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                    return;
                }
                if(IsNPCPartyMember(NPC_BASTILA) &&
                   GetGlobalBoolean("K_MESS_BASTILA") == FALSE &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 25 &&
                   GetGlobalNumber("K_SWG_HELENA") == 1)
                {
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_BASTILA", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_malare", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
                if(IsNPCPartyMember(NPC_CARTH) &&
                   //MODIFIED by Preston Watamaniuk on May 13, 2003
                   //Added a check to make sure the Sith Acadamy is not closed before spawning in Jordo.
                   GetGlobalBoolean("KOR_END_HOSTILE") == FALSE &&
                   GetGlobalBoolean("K_MESS_CARTH") == FALSE &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 30 &&
                   GetGlobalNumber("KOR_DANEL") == 1)
                {
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_CARTH", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_jordo", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
                if(IsNPCPartyMember(NPC_JOLEE) &&
                   GetGlobalBoolean("K_MESS_JOLEE") == FALSE &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 25 &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 20 &&
                   GetGlobalNumber("MAN_MURDER_PLOT") == 0)
                {
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_JOLEE", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_davink", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
                if(IsNPCPartyMember(NPC_JUHANI) &&
                   GetGlobalBoolean("K_MESS_JUHANI") == FALSE &&
                   (GetGlobalNumber("G_JUHANIH_STATE") > 5 && GetGlobalNumber("G_JUHANIP_STATE") < 10) &&
                   GetGlobalNumber("G_JUHANI_PLOT") == 0 &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 15)
                {
                        //juhanih_state > 5, and juhanip_state < 10
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_JUHANI", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_xor", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
                if(IsNPCPartyMember(NPC_CANDEROUS) &&
                   GetGlobalBoolean("K_MESS_CANDEROUS") == FALSE &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 35 &&
                   GetGlobalNumber("G_CAND_STATE") >= 6 &&
                   GetGlobalBoolean("G_CAND_THING") == TRUE &&
                   GetGlobalNumber("G_CAND_PLOT") == 0)
                {
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_CANDEROUS", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_jagi", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
                if(IsNPCPartyMember(NPC_MISSION) &&
                   GetGlobalBoolean("K_MESS_MISSION") == FALSE &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 35 &&
                   GetGlobalNumber("K_CURRENT_PLANET") != 25 &&
                   GetGlobalNumber("Mis_MissionTalk") == 5)
                {
                        SetGlobalBoolean("K_MESSENGER_AVAILABLE", FALSE);
                        SetGlobalBoolean("K_MESS_MISSION", TRUE);
                        oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_lena", lLocal);
                        NoClicksFor(2.2);
                        DelayCommand(2.0,  AssignCommand(oNPC, ActionStartConversation(oPC,"",FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE)));
                        //DelayCommand(2.0, UT_NPC_InitConversation(GetTag(oNPC)));
                        return;
                }
            }
        }
    }
*/
}
//::///////////////////////////////////////////////
//:: Exit Area
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    The NPC moves to an SW_EXIT waypoint and destroys
    itself.
*/
//:://////////////////////////////////////////////
//:: Created By:  Preston Watamaniuk
//:: Created On:  Sept 27, 2002
//:: Modified By: Ferret Baudoin, Adam Brennecke
//:: Modified On: 3/11/04, 6/28/04
//:://////////////////////////////////////////////
void UT_ExitArea(int nRun = FALSE, int nParam = 0, object oObj = OBJECT_SELF)
{
    object oExit;
    // if P1 = 0, then just go to SW_EXIT
    if ( nParam == 0 )
    {
        oExit = GetWaypointByTag("SW_EXIT");
    }
    else oExit = GetWaypointByTag("SW_EXIT" + IntToString(nParam));
    if ( oObj != OBJECT_SELF )
    {
        AssignCommand( oObj, ActionForceMoveToObject(oExit, nRun));
        AssignCommand( oObj, ActionDoCommand(SetCommandable(TRUE)));
        AssignCommand( oObj, ActionDoCommand(DestroyObject(oObj))); // JAB-OEI 6/28/04
        AssignCommand( oObj, SetCommandable(FALSE) );
    }
    else
    {
        ActionForceMoveToObject(oExit, nRun);
        ActionDoCommand(SetCommandable(TRUE));
        ActionDoCommand(DestroyObject(OBJECT_SELF));
        SetCommandable(FALSE);
    }
}
//::///////////////////////////////////////////////
//:: UT_GetNumItems
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Counts the number of items with the given tag
    in the party inventory.
*/
//:://////////////////////////////////////////////
//:: Created By: John Winski
//:: Created On: October 15, 2002
//:://////////////////////////////////////////////
int UT_GetNumItems(object oTarget, string sItemTag)
{
    int nCount = 0;
    object oItem = GetFirstItemInInventory(oTarget);
    while (GetIsObjectValid(oItem) == TRUE)
    {
        if (GetTag(oItem) == sItemTag)
        {
            nCount = nCount + 1;
        }
        oItem = GetNextItemInInventory(oTarget);
    }
    return nCount;
}
//::///////////////////////////////////////////////
//:: Determines Item Cost
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns a value for how many parts or spikes
    a given dialogue option will cost.  The costs
    are as follows:
    Computer Use
    1.  Open all doors in area (cost: 3 spikes). The player can open all doors on the level.
    2.  Open all containers in area (cost: 3 spikes). The player can open all containers on the level.
    3.  Fill security room with gas (cost: 5 spikes).
    4.  Turn off all gun turrets (cost: 8 spikes).
    5.  Modify droid programming; target everything (cost: 10 spikes).
    6.  Deactivate all droids in area (cost: 8 spikes).
    Repair Use
    1.  Activate droid. Hostile to Sith faction. (cost: 3 repair unit)
    2.  Activate droid. Hostile to Sith faction. Enter patrol route. (cost: 5 repair unit)
    3.  Activate droid. Hostile to Sith faction. Hunter Killer mode. (cost: 7 repair unit)
    4.  Activate droid. Hostile to Sith faction. Follow mode. (cost: 5 repair unit)
*/
//:://////////////////////////////////////////////
//:: Created By: PReston Watamaniuk
//:: Created On: Nov 19, 2002
//:://////////////////////////////////////////////
int UT_DeterminesItemCost(int nDC, int nSkill)
{
        //AurPostString("DC " + IntToString(nDC), 5, 5, 3.0);
    float fModSkill =  IntToFloat(GetSkillRank(nSkill, GetPartyMemberByIndex(0)));
        //AurPostString("Skill Total " + IntToString(GetSkillRank(nSkill, GetPartyMemberByIndex(0))), 5, 6, 3.0);
    int nUse;
    fModSkill = fModSkill/4.0;
    nUse = nDC - FloatToInt(fModSkill);
        //AurPostString("nUse Raw " + IntToString(nUse), 5, 7, 3.0);
    if(nUse < 1)
    {
        //MODIFIED by Preston Watamaniuk, March 19
        //Put in a check so that those PC with a very high skill
        //could have a cost of 0 for doing computer work
        if(nUse <= -3)
        {
            nUse = 0;
        }
        else
        {
            nUse = 1;
        }
    }
        //AurPostString("nUse Final " + IntToString(nUse), 5, 8, 3.0);
    return nUse;
}
//::///////////////////////////////////////////////
//:: Remove X number of Computer Spikes
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Remove a number of computer spikes
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 19, 2002
//:://////////////////////////////////////////////
void UT_RemoveComputerSpikes(int nNumber)
{
    object oItem = GetItemPossessedBy(GetFirstPC(), "K_COMPUTER_SPIKE");
    if(GetIsObjectValid(oItem))
    {
        int nStackSize = GetItemStackSize(oItem);
        if(nNumber < nStackSize)
        {
            nNumber = nStackSize - nNumber;
            SetItemStackSize(oItem, nNumber);
        }
        else if(nNumber > nStackSize || nNumber == nStackSize)
        {
            DestroyObject(oItem);
        }
    }
}
//::///////////////////////////////////////////////
//:: Remove X number of Repair Parts
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Remove a number of repair parts
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 19, 2002
//:://////////////////////////////////////////////
void UT_RemoveRepairParts(int nNumber)
{
    object oItem = GetItemPossessedBy(GetFirstPC(), "K_REPAIR_PART");
    if(GetIsObjectValid(oItem))
    {
        int nStackSize = GetItemStackSize(oItem);
        if(nNumber < nStackSize)
        {
            nNumber = nStackSize - nNumber;
            SetItemStackSize(oItem, nNumber);
        }
        else if(nNumber > nStackSize || nNumber == nStackSize)
        {
            DestroyObject(oItem);
        }
    }
}
//::///////////////////////////////////////////////
//:: Return item amount
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Depending on the skill chosen, returns the
    number items relating to that skill
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 19, 2002
//:://////////////////////////////////////////////
int UT_ReturnSpikePartAmount(int nSkill)
{
    string sItem;
    int nCount = 0;
    if(nSkill == SKILL_COMPUTER_USE)
    {
        sItem = "K_COMPUTER_SPIKE";
    }
    else if(nSkill == SKILL_REPAIR)
    {
        sItem = "K_REPAIR_PART";
    }
    object oItem = GetItemPossessedBy(GetFirstPC(), sItem);
    if(GetIsObjectValid(oItem))
    {
        nCount = GetNumStackedItems(oItem);
    }
    return nCount;
}
//::///////////////////////////////////////////////
//:: Make Neutral
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all object with
    the specified tag to the neutral faction
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 20, 2002
//:://////////////////////////////////////////////
void UT_MakeNeutral(string sTag)
{
    // BMA-OEI 8/25/2004 - Old code tried to stun all sObjectTag?
    // Duplicate of UT_MakeNeutral2()?
    int nInstance = 1;
    object oObject = GetObjectByTag(sTag, nInstance);
    while (GetIsObjectValid(oObject))
    {
        ChangeToStandardFaction(oObject, STANDARD_FACTION_NEUTRAL);
        nInstance++;
        oObject = GetObjectByTag(sTag, nInstance);
    }
}
//::///////////////////////////////////////////////
//:: Make Insane
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the insane faction
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 20, 2002
//:://////////////////////////////////////////////
void UT_MakeInsane(string sObjectTag)
{
    int nCount = 1;
    object oDroid = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oDroid))
    {
        ChangeToStandardFaction(oDroid, STANDARD_FACTION_INSANE);
        UT_StartCombat(oDroid);
        nCount++;
        oDroid = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Stun Droids
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the insane faction
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 20, 2002
//:://////////////////////////////////////////////
void UT_StunDroids(string sObjectTag)
{
    effect eStun = EffectDroidStun();
    int nCount = 1;
    object oDroid = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oDroid))
    {
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStun, oDroid);
        nCount++;
        oDroid = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Start a Fight
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets the nearest enemy that is seen and start combat
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 21, 2002
//:://////////////////////////////////////////////
void UT_StartCombat(object oObject)
{
    AssignCommand(oObject, ActionAttack(GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oObject, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN)));
}
//::///////////////////////////////////////////////
//:: Gas a Rooom
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Releases gas into the room and kills all biologicals in the
    specified radius.  The radius should be between 2 - 5m
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 21, 2002
//:://////////////////////////////////////////////
void UT_GasRoom(string sWayTag, float fDistance, int bIndiscriminant = TRUE)
{
    object oWay = GetWaypointByTag(sWayTag);
    object oPC = GetFirstPC();
    if(GetIsObjectValid(oWay))
    {
        effect eVFX = EffectVisualEffect(3006);
        ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVFX, GetLocation(oWay));
        object oTarget = GetNearestCreature(CREATURE_TYPE_RACIAL_TYPE, RACIAL_TYPE_HUMAN, oWay, 1);
        int nCount = 1;
        while(GetIsObjectValid(oTarget) && GetDistanceBetween(oTarget, oWay) <= fDistance)
        {
            float fDelay = 3.0 + (IntToFloat(d10())/10.0);
            float fDelay2 = fDelay + 1.0 + (IntToFloat(d20())/10.0);
            if((GetIsFriend(oTarget, oPC) || GetIsNeutral(oTarget, oPC)) && bIndiscriminant == FALSE)
            {
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectChoke(), oTarget, 3.0));
                DelayCommand(fDelay2, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectPoison(POISON_ABILITY_SCORE_VIRULENT),oTarget));
            }
            else if(GetIsEnemy(oTarget, oPC) || bIndiscriminant == TRUE)
            {
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectChoke(), oTarget, 10.0));
                DelayCommand(fDelay2, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oTarget));
            }
            nCount++;
            oTarget = GetNearestCreature(CREATURE_TYPE_RACIAL_TYPE, RACIAL_TYPE_HUMAN, oWay, nCount);
        }
    }
}
//::///////////////////////////////////////////////
//:: Overload Conduit
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Overloads a power conduit and does 10d6 damage
    to all within the specified radius
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 21, 2002
//:://////////////////////////////////////////////
void UT_OverloadConduit(string sObjectTag, float fDistance, int bIndiscriminant = TRUE)
{
    object oWay = GetObjectByTag(sObjectTag);
    if(GetIsObjectValid(oWay))
    {
        effect eFNF = EffectVisualEffect(VFX_FNF_GRENADE_ION);
        effect eVFXHit = EffectVisualEffect(1021);
        effect eVFXBeam = EffectBeam(VFX_BEAM_LIGHTNING_DARK_L, oWay, BODY_NODE_CHEST);
        effect eDam;
        object oTarget = GetNearestObject(OBJECT_TYPE_CREATURE, oWay, 1);
        int nCount = 1;
        int nDam = 1000;
        float fDelay = 0.3;
        AssignCommand(oWay, ActionPlayAnimation(ANIMATION_PLACEABLE_OPEN));
        DelayCommand(0.3, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eFNF, GetLocation(oWay)));
        while(GetIsObjectValid(oTarget) && GetDistanceBetween(oTarget, oWay) <= fDistance)
        {
            if(bIndiscriminant == TRUE || GetIsEnemy(oTarget, GetFirstPC()))
            {
                eDam = EffectDamage(nDam, DAMAGE_TYPE_ELECTRICAL);
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVFXBeam, oTarget, 1.0));
                DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFXHit, oTarget, 1.0));
                fDelay = fDelay + 0.17;
            }
            nCount++;
            oTarget = GetNearestObject(OBJECT_TYPE_CREATURE, oWay, nCount);
        }
        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_PRO_DROID_KILL), oWay);
    }
}
///////////////////////////////////////////////////////////////////////////////
/*
    UT_ReturnToBase
    This function is used in the user defined event of a creature crossing a
    trigger used to pen in hostile creatures. When a creature crosses the
    trigger, it's actions are cleared, it is sent to the homebase waypoint and
    it is set non commanble. Once reaching its destination, it becomes
    commandable again. By defaut the standard tag for the waypoint is given, but
    a different one may be specified
    Created by Aidan Scanlan
    On Dec 2, 2002
*/
///////////////////////////////////////////////////////////////////////////////
void UT_ReturnToBase(string sTag = "wp_homebase")
{
    object oSelf = OBJECT_SELF;
    if(GetCommandable(oSelf))
    {
        ClearAllActions();
        CancelCombat(oSelf);
        ActionMoveToObject(GetNearestObjectByTag("wp_homebase"),TRUE,3.0f);
        ActionDoCommand( SetCommandable(TRUE,oSelf));
        SetCommandable(FALSE);
    }
}
//::///////////////////////////////////////////////
//:: UT_NPC_InitConversation
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
    The specified NPC will start a conversation
    with the player.
*/
//:://////////////////////////////////////////////
//:: Created By: John Winski
//:: Created On: December 2, 2002
//:://////////////////////////////////////////////
void UT_NPC_InitConversation(string sNPCTag,string sDlg = "",object oEntered = OBJECT_INVALID)
{
    object oNPC = GetObjectByTag(sNPCTag);
    object oPC = GetFirstPC();
    UT_RestorePartyToOneHealth();
    // The NPC must exist.
    if (GetIsObjectValid(oNPC) == TRUE)
    {
        if (oPC == GetPartyMemberByIndex(0))
        {
            AssignCommand(oPC, ClearAllActions());
            AssignCommand(oNPC, ClearAllActions());
            CancelCombat(oPC);
            AssignCommand(oNPC, ActionStartConversation(oPC, sDlg, FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE));
        }
        else
        {
            // Fade to black, switch player control to the main character,
            // move the player to the NPC and start conversation.
            SetGlobalFadeOut();
            SetPartyLeader(NPC_PLAYER);
            object oParty1 = GetPartyMemberByIndex(1);
            object oParty2 = GetPartyMemberByIndex(2);
            //P.W. (June 7) - Put this in to terminate any player input during the fade.
            NoClicksFor(0.7);
            AssignCommand(oPC, ClearAllActions());
            AssignCommand(oNPC, ClearAllActions());
            CancelCombat(oPC);
            if (GetIsObjectValid(oEntered) == TRUE)
            {
                AssignCommand(oPC, DelayCommand(0.2, JumpToObject(oEntered)));
                AssignCommand(oPC, DelayCommand(0.4, SetFacingPoint(GetPosition(oNPC))));
            }
            else
            {
                AssignCommand(oPC, DelayCommand(0.2, JumpToObject(oNPC)));
            }
            AssignCommand(oParty1, DelayCommand(0.5, JumpToObject(oPC)));
            AssignCommand(oParty2, DelayCommand(0.5, JumpToObject(oPC)));
            AssignCommand(oNPC, ActionDoCommand(SetGlobalFadeIn(0.5, 2.0)));
            AssignCommand(oNPC, ActionStartConversation(oPC, sDlg, FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE));
        }
    }
}
//::///////////////////////////////////////////////
//:: Set Starmap Journal
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the Journal entry for the starmap
    automatically.
    Korriban - entry 10
    Tatooine - entry 20
    Kashyyyk - entry 30
    Manaan   - entry 40
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamanmiuk
//:: Created On: Dec 17, 2002
//:://////////////////////////////////////////////
void UT_SetStarmapJournal()
{
    string sModule = GetModuleFileName();
    if(sModule == "manm28ad") //Manaan
    {
        SetGlobalBoolean("K_STAR_MAP_MANAAN", TRUE);
        AddJournalQuestEntry("k_starforge", 40, TRUE);
    }
    else if(sModule == "korr_m39aa") //Korriban
    {
        SetGlobalBoolean("K_STAR_MAP_KORRIBAN", TRUE);
        AddJournalQuestEntry("k_starforge", 10, TRUE);
    }
    else if(sModule == "Kas_m25aa") //Kashyyyk
    {
        SetGlobalBoolean("K_STAR_MAP_KASHYYYK", TRUE);
        AddJournalQuestEntry("k_starforge", 30, TRUE);
    }
    else if(sModule == "Tat_m18ac") //Tatooine
    {
        SetGlobalBoolean("K_STAR_MAP_TATOOINE", TRUE);
        AddJournalQuestEntry("k_starforge", 20, TRUE);
    }
    if(GetGlobalNumber("K_STAR_MAP") == 50)
    {
        AddJournalQuestEntry("k_starforge", 50, TRUE);
    }
}
//::///////////////////////////////////////////////
//:: Spawn Creatures
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Creates number of creatures with a specific template at a specified waypoint tag.
    Total is the number times the loop will run.
    fTimeDelay is the number seconds between iterations.
    nSpawnIncrement is the number of templates spawned in per iteration.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamanmiuk
//:: Created On: Dec 17, 2002
//:://////////////////////////////////////////////
void UT_RunCombatEncounter(string sTemplate, string sTag, int nTotal = 3, float fTimeDelay = 1.5, int nSpawnIncrement = 1)
{
    if(fTimeDelay < 1.5)
    {
       fTimeDelay = 1.5;
    }
    object oWay = GetWaypointByTag(sTag);
    object oCreate;
    if(GetIsObjectValid(oWay))
    {
        int nCount = nSpawnIncrement;
        for(nCount; nCount != 0; nCount--)
        {
            oCreate = CreateObject(OBJECT_TYPE_CREATURE, sTemplate, GetLocation(oWay));
        }
        nTotal--;
        if(nTotal > 0)
        {
            DelayCommand(fTimeDelay, UT_RunCombatEncounter(sTemplate, sTag, nTotal, fTimeDelay, nSpawnIncrement));
        }
        fTimeDelay += fTimeDelay;
    }
}
//::///////////////////////////////////////////////
//:: Set Talk To Flag by Tag
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Loops through all object with a certain tag
    and sets their Talk To Flag to TRUE.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamanmiuk
//:: Created On: Dec 17, 2002
//:://////////////////////////////////////////////
void UT_SetTalkToFlagByTag(string sTag)
{
    int nCnt = 1;
    object oTrigger = GetNearestObjectByTag(sTag, GetFirstPC(), nCnt);
    while(GetIsObjectValid(oTrigger))
    {
        SetLocalBoolean(oTrigger, SW_PLOT_HAS_TALKED_TO, TRUE);
        nCnt++;
        oTrigger = GetNearestObjectByTag(sTag, GetFirstPC(), nCnt);
    }
}
//::///////////////////////////////////////////////
//:: Lock / Plot Twin Doors
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Loops through all doors with a certain tag
    and closes, locks and plots them.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamanmiuk
//:: Created On: Dec 17, 2002
//:://////////////////////////////////////////////
void UT_LockDoorDuplicates(string sTag)
{
    int nCount;
    object oDoor = GetNearestObjectByTag(sTag);
    while(GetIsObjectValid(oDoor) && GetObjectType(oDoor) == OBJECT_TYPE_DOOR)
    {
        if(oDoor != OBJECT_SELF)
        {
            AssignCommand(oDoor, ActionCloseDoor(oDoor));
            AssignCommand(oDoor, ActionLockObject(oDoor));
            AssignCommand(oDoor, SetPlotFlag(oDoor, TRUE));
        }
        nCount++;
        oDoor = GetNearestObjectByTag(sTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Can Party Member Interject
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Check to see if the Party member specified is
    in the party and within the distance given.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 10, 2003
//:://////////////////////////////////////////////
int UT_CheckCanPartyMemberInterject(int nNPC_Constant, float fDistance)
{
/*
    object oParty;
    if(IsNPCPartyMember(nNPC_Constant))
    {
        //MODIFIED by Preston Watamaniuk on April 24, 2003
        //Put this in so that NPCs who you turn down on a planet will not reinitiate on that planet again.
        int nPlanet = GetGlobalNumber("K_CURRENT_PLANET");
        string sConstant = "NPC_INIT_PLANET_";
        sConstant = "NPC_INIT_PLANET_" + IntToString(nNPC_Constant);
        int nConstant = GetGlobalNumber(sConstant);
        if(nNPC_Constant == NPC_BASTILA)
        {
            oParty = GetObjectByTag("Bastila");
        }
        else if(nNPC_Constant == NPC_CANDEROUS)
        {
            oParty = GetObjectByTag("Cand");
        }
        else if(nNPC_Constant == NPC_CARTH)
        {
            oParty = GetObjectByTag("Carth");
        }
        else if(nNPC_Constant == NPC_HK_47)
        {
            oParty = GetObjectByTag("HK47");
        }
        else if(nNPC_Constant == NPC_JOLEE)
        {
            oParty = GetObjectByTag("Jolee");
        }
        else if(nNPC_Constant == NPC_JUHANI)
        {
            oParty = GetObjectByTag("Juhani");
        }
        else if(nNPC_Constant == NPC_MISSION)
        {
            oParty = GetObjectByTag("Mission");
        }
        else if(nNPC_Constant == NPC_T3_M4)
        {
            oParty = GetObjectByTag("T3M4");
        }
        else if(nNPC_Constant == NPC_ZAALBAR)
        {
            oParty = GetObjectByTag("Zaalbar");
        }
        if(GetIsObjectValid(oParty) &&
           GetDistanceBetween(oParty, GetFirstPC()) <= fDistance &&
           nPlanet != nConstant)
        {
            return TRUE;
        }
    }
*/
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Reinitialize NPC Planet Constants
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This resets the variables for each party member
    that controls whether they will init on a
    particular planet.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 24, 2003
//:://////////////////////////////////////////////
void UT_ReinitializePartyPlanetVariables()
{
    string sConstant = "NPC_INIT_PLANET_";
    int nCnt = 0;
    for(nCnt; nCnt <= 8; nCnt++)
    {
        sConstant = "NPC_INIT_PLANET_" + IntToString(nCnt);
        SetGlobalNumber(sConstant, 0);
    }
}
//teleport party member
void UT_TeleportPartyMember(object oPartyMember, location lDest)
{
  if(!GetIsObjectValid(oPartyMember))
  {
    return;
  }
  if(GetCurrentHitPoints(oPartyMember) < 1)
  {
    ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oPartyMember);
    ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectHeal(1),oPartyMember);
  }
  SetCommandable(TRUE,oPartyMember);
  AssignCommand(oPartyMember,ClearAllActions());
  AssignCommand(oPartyMember,ActionJumpToLocation(lDest));
}
//Returns true if oTarget is the object of interest of an attacker
int UT_GetUnderAttack(object oTarget)
{
  if(!GetIsObjectValid(oTarget))
  {
    return(FALSE);
  }
  object oAttacker = GetLastHostileActor(oTarget);
  return(GetIsObjectValid(oAttacker) || !GetIsDead(oAttacker) || GetObjectSeen(oAttacker, oTarget));
}
//:://////////////////////////////////////////////
/*
     This include handles jumping the party to the
     specified locations, good for controlling
     positions at the start of a cutscene.
     They will also be faced in the direction of
     the waypoints or objects they are being
     jumped to.
*/
//:://////////////////////////////////////////////
//:: Created By: Brad Prince
//:: Created On: Jan 23, 2003
//:://////////////////////////////////////////////
void UT_TeleportWholeParty(object oWP0, object oWP1, object oWP2)
{
   // The member the PC is in control of.
   object oMember0 = GetPartyMemberByIndex(0);
   // The second party member.
   object oMember1 = GetPartyMemberByIndex(1);
   // The third member.
   object oMember2 = GetPartyMemberByIndex(2);
   UT_RestorePartyToOneHealth();
   if(GetIsObjectValid(oMember0)) {
      UT_TeleportPartyMember(oMember0, GetLocation(oWP0));
      AssignCommand(oMember0, SetFacing(GetFacing(oWP0)));
   }
   if(GetIsObjectValid(oMember1)) {
      UT_TeleportPartyMember(oMember1, GetLocation(oWP1));
      DelayCommand(0.3, AssignCommand(oMember1, SetFacing(GetFacing(oWP1))));
   }
   if(GetIsObjectValid(oMember2)) {
      UT_TeleportPartyMember(oMember2, GetLocation(oWP2));
      DelayCommand(0.3, AssignCommand(oMember2, SetFacing(GetFacing(oWP2))));
   }
}
//::///////////////////////////////////////////////
//:: Action Pause Converation
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
     This will stop and start a conversation in 1
     step. Just pass the length of the pause.
     Be sure your commands will get carried out
     in the specified time and that the "pauser"
     is not killed.
*/
//:://////////////////////////////////////////////
//:: Created By: Brad Prince
//:: Created On: Jan 23, 2003
//:://////////////////////////////////////////////
void UT_ActionPauseConversation(float fDelay)
{
   ActionPauseConversation();
   DelayCommand(fDelay, ActionResumeConversation());
}
//::///////////////////////////////////////////////
//:: Spawn Available NPC
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Allows the uses to delay command on the creation
    of an NPC.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 5, 2003
//:://////////////////////////////////////////////
void UT_SpawnAvailableNPC(int nNPC, location lWay)
{
    object oNPC = SpawnAvailableNPC(nNPC, lWay);
}
//::///////////////////////////////////////////////
//:: Set Starmap Variables
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Advances K_STAR_MAP, sets the journal and
    sets the talk to flag.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 19, 2003
//:://////////////////////////////////////////////
void UT_StarMap1VariableSet()
{
    int nStar = GetGlobalNumber("K_STAR_MAP");
    int nBast = GetGlobalNumber("K_SWG_BASTILA");
    int nBool = GetLocalBoolean(OBJECT_SELF, SW_PLOT_HAS_TALKED_TO);
    if(nBool == FALSE)
    {
        //REMOVE THIS BEFORE SHIP
        AurPostString("v3.0 - K_STAR_MAP Before = " + IntToString(nStar), 5, 5, 5.0);
        nStar = nStar + 10;
        SetGlobalNumber("K_STAR_MAP",nStar);
        //REMOVE THIS BEFORE SHIP
        AurPostString("K_STAR_MAP After = " + IntToString(nStar), 5, 7, 5.0);
        if(nStar == 30)
        {
            if(nBast < 3)
            {
                SetGlobalNumber("K_SWG_BASTILA", 99);
            }
        }
        else if(nStar == 40)
        {
            //The player should now be captured by the Leviathan
            SetGlobalNumber("K_CAPTURED_LEV", 5);
            if(nBast < 5)
            {
                SetGlobalNumber("K_SWG_BASTILA", 99);
            }
        }
        else if(nStar == 50)
        {
            //The player should now have access to the unknown world.
            SetGlobalNumber("K_KOTOR_MASTER", 30);
        }
        SetLocalBoolean(OBJECT_SELF, SW_PLOT_HAS_TALKED_TO, TRUE);
        UT_SetStarmapJournal();
        AurPostString("Manaan Starmap = " + IntToString(GetGlobalBoolean("K_STAR_MAP_MANAAN")), 5, 9, 4.0);
        AurPostString("Kashyyyk Starmap = " + IntToString(GetGlobalBoolean("K_STAR_MAP_KASHYYYK")), 5, 11, 4.0);
        AurPostString("Korriban Starmap = " + IntToString(GetGlobalBoolean("K_STAR_MAP_KORRIBAN")), 5, 13, 4.0);
        AurPostString("Tatooine Starmap = " + IntToString(GetGlobalBoolean("K_STAR_MAP_TATOOINE")), 5, 15, 4.0);
    }
}
//::///////////////////////////////////////////////
//:: Play Starmap Animations
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Plays the animations necessary for the current
    state of the starmap variable
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 19, 2003
//:://////////////////////////////////////////////
void UT_StarMap2PlayAnimation()
{
    int nStar = GetGlobalNumber("K_STAR_MAP");
    int nBool = GetLocalBoolean(OBJECT_SELF, SW_PLOT_HAS_TALKED_TO);
    float fDelay = 30.0;
    if(nBool == FALSE)
    {
        ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE);
        ActionPlayAnimation(UT_StarMap3GetLoopAnim(nStar));
        if(nStar == 40)//This variable is the pre-activation value.  It is going from 40 to 50
        {
            fDelay = 60.0;
        }
        DelayCommand(fDelay, ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
    }
}
//::///////////////////////////////////////////////
//:: Returns the Appropriate Starmap Anim Loop
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the appropriate animation loop for the
    Star Map based on the value used before the
    new variable is set.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 19, 2003
//:://////////////////////////////////////////////
int UT_StarMap3GetLoopAnim(int nStarMapVar)
{
    if(nStarMapVar == 0)
    {
        return ANIMATION_PLACEABLE_ANIMLOOP01;
    }
    else if(nStarMapVar == 10)
    {
        return ANIMATION_PLACEABLE_ANIMLOOP02;
    }
    else if(nStarMapVar == 20)
    {
        return ANIMATION_PLACEABLE_ANIMLOOP03;
    }
    else if(nStarMapVar == 30)
    {
        return ANIMATION_PLACEABLE_ANIMLOOP04;
    }
    else if(nStarMapVar == 40)
    {
        return ANIMATION_PLACEABLE_ANIMLOOP06;
    }
    return -1;
}
//::///////////////////////////////////////////////
//:: Generic Starmap Handler
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Runs the entire Starmap sequence as a black
    box with no extra scripting required.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 19, 2003
//:://////////////////////////////////////////////
void UT_StarMap4RunStarMap()
{
    UT_StarMap2PlayAnimation();
    UT_StarMap1VariableSet();
}
//////////////////////////////////////////////////////////////////////
/*    This function removes party members. It stores the npc constants
    of the removed party members.
    Aidan-Feb 20,03
*/
//////////////////////////////////////////////////////////////////////
void UT_StoreParty()
{
    if(GetPartyMemberByIndex(0) != GetFirstPC())
    {
        SetPartyLeader(NPC_PLAYER);
    }
    object oNPC1 = GetPartyMemberByIndex(1);
    object oNPC2 = GetPartyMemberByIndex(2);
    int nIdx, bFound1, bFound2, bRemove;
    for (nIdx = NPC_ATTON; nIdx <= NPC_VISAS && !bFound2; nIdx++)
    {
        bRemove = IsNPCPartyMember(nIdx);
        if(bRemove)
        {
            if(bFound1 == FALSE)
            {
                RemovePartyMember(nIdx);
                SetGlobalNumber("K_PARTY_STORE1",nIdx);
                bFound1 = TRUE;
                SetGlobalBoolean("K_PARTY_STORED",TRUE);
            }
            else
            {
                RemovePartyMember(nIdx);
                SetGlobalNumber("K_PARTY_STORE2",nIdx);
                bFound2 = TRUE;
                SetGlobalBoolean("K_PARTY_STORED",TRUE);
            }
        }
        bRemove = FALSE;
    }
    if(GetIsObjectValid(oNPC1))
    {
        DestroyObject(oNPC1);
    }
    if(GetIsObjectValid(oNPC2))
    {
        DestroyObject(oNPC2);
    }
}
//::///////////////////////////////////////////////
//:: Restore NPC
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This function restore party members. It will only
    restore party members removed via the
    UT_StoreParty function
*/
//:://////////////////////////////////////////////
//:: Created By: Aidan Scanlan
//:: Created On: Feb 20, 2003
//:://////////////////////////////////////////////
void UT_RestoreParty()
{
    int nNPC1 = GetGlobalNumber("K_PARTY_STORE1");
    int nNPC2 = GetGlobalNumber("K_PARTY_STORE2");
    object oNPC;
    if(GetGlobalBoolean("K_PARTY_STORED"))
    {
        if(nNPC1 >= NPC_ATTON && nNPC1 <= NPC_VISAS)
        {
            if(GetIsObjectValid(GetPartyMemberByIndex(1)) == FALSE)
            {
                oNPC = SpawnAvailableNPC(nNPC1,GetLocation(GetFirstPC()));
                if(GetIsObjectValid(oNPC))
                {
                    AddPartyMember(nNPC1,oNPC);
                }
            }
        }
        if(nNPC2 >= NPC_ATTON && nNPC2 <= NPC_VISAS)
        {
            if(GetIsObjectValid(GetPartyMemberByIndex(2)) == FALSE)
            {
                oNPC = SpawnAvailableNPC(nNPC2,GetLocation(GetFirstPC()));
                if(GetIsObjectValid(oNPC))
                {
                    AddPartyMember(nNPC2,oNPC);
                }
            }
        }
    }
    SetGlobalNumber("K_PARTY_STORE2",-2);
    SetGlobalNumber("K_PARTY_STORE1",-2);
    SetGlobalBoolean("K_PARTY_STORED",FALSE);
}
//::///////////////////////////////////////////////
//:: Return NPC Integer
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns the NPC code for the given object if
    it is a NPC, otherwise it returns -1
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: Feb 26, 2003
//:://////////////////////////////////////////////
int UT_GetNPCCode(object oNPC)
{
  string sTag = GetTag(oNPC);
  if(!GetIsObjectValid(oNPC))
  {
    return(-1);
  }
  if(sTag == "atton")
  {
    return(NPC_ATTON);
  }
  if(sTag == "bao")
  {
    return(NPC_BAO_DUR);
  }
  if(sTag == "cand")
  {
    return(NPC_CANDEROUS);
  }
  if(sTag == "g0t0")
  {
    return(NPC_G0T0);
  }
  if(sTag == "handmaiden")
  {
    return(NPC_HANDMAIDEN);
  }
  if(sTag == "hk47")
  {
    return(NPC_HK_47);
  }
  if(sTag == "kreia")
  {
    return(NPC_KREIA);
  }
  if(sTag == "t3m4")
  {
    return(NPC_T3_M4);
  }
  if(sTag == "visas")
  {
    return(NPC_VISAS);
  }
  if(sTag == "mira")
  {
    return(NPC_MIRA);
  }
  return(-1);
}
//::///////////////////////////////////////////////
//:: Restore Party Member to 1 Vitality
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Restores all party mambers to 1 hp if
    tempoarily dead
*/
//:://////////////////////////////////////////////
//:: Created By: Aidan Scanlan
//:: Created On: March 1, 2003
//:://////////////////////////////////////////////
void UT_RestorePartyToOneHealth()
{
    int nIdx = 0;
    object oParty = GetPartyMemberByIndex(nIdx);
    while (GetIsObjectValid(oParty))
    {
        if(GetCurrentHitPoints(oParty) < 1)
        {
            ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectResurrection(),oParty);
            ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectHeal(1),oParty);
        }
        nIdx++;
        oParty = GetPartyMemberByIndex(nIdx);
    }
}
//::///////////////////////////////////////////////
//:: Heal Party
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Cycles throught the entire party and heals
    them.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 28, 2003
//:://////////////////////////////////////////////
void UT_HealParty()
{
    object oParty;
    int nCnt = 0;
    for(nCnt; nCnt < 3; nCnt++)
    {
        oParty = GetPartyMemberByIndex(nCnt);
        if(GetIsObjectValid(oParty))
        {
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(500), oParty);
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHealForcePoints(500), oParty);
        }
    }
}
//::///////////////////////////////////////////////
//:: Heal Party Member
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Heals a single target to full.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 28, 2003
//:://////////////////////////////////////////////
void UT_HealNPC(object oNPC)
{
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(500), oNPC);
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHealForcePoints(500), oNPC);
}
//::///////////////////////////////////////////////
//:: Alter Stack
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Alters the stack of a given object by the
    specified amount. If the stack is only 1 then
    the object is destroyed.
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: March 3, 2003
//:://////////////////////////////////////////////
void UT_AlterItemStack(object oItem,int iNum = 1,int bDecrement = TRUE)
{
    int iStackSize;
    if(!GetIsObjectValid(oItem) || iNum == 0)
    {
        return;
    }
    if(bDecrement)
    {
        iNum = -iNum;
    }
    iStackSize = GetItemStackSize(oItem);
    if(iNum > 0)
    {
        SetItemStackSize(oItem,iStackSize+iNum);
    }
    else
    {
        if(iStackSize+iNum <= 0)
        {
          //MODIFIED by Preston Watamaniuk on May 13, 2003
          //Added the command below to set the stack to 1 before destroying it.
          SetItemStackSize(oItem,1);
          DestroyObject(oItem,0.0,TRUE);
        }
        else
        {
          SetItemStackSize(oItem,iStackSize+iNum);
        }
    }
}
//::///////////////////////////////////////////////
//:: Heal All Party NPCs
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches through the area and heals all of the
    party members who are there. Used on the Ebon
    Hawk and the Taris Apartment.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: March 5, 2003
//:://////////////////////////////////////////////
void UT_HealAllPartyNPCs()
{
    object oNPC1 = GetObjectByTag("atton");
    object oNPC2 =  GetObjectByTag("baodur");
    object oNPC3 = GetObjectByTag("mand");
    object oNPC4 = GetObjectByTag("g0t0");
    object oNPC5 = GetObjectByTag("handmaiden");
    object oNPC6 = GetObjectByTag("hk47");
    object oNPC7 = GetObjectByTag("kreia");
    object oNPC8 = GetObjectByTag( "mira" );
    object oNPC9 = GetObjectByTag("t3m4");
    object oNPC10 = GetObjectByTag("visasmarr");
    object oNPC11 = GetObjectByTag("disciple");
    object oCurrent;
    int nCnt = 1;
    while(nCnt <= 11)
    {
        if(nCnt == 1){oCurrent = oNPC1;}
        if(nCnt == 2){oCurrent = oNPC2;}
        if(nCnt == 3){oCurrent = oNPC3;}
        if(nCnt == 4){oCurrent = oNPC4;}
        if(nCnt == 5){oCurrent = oNPC5;}
        if(nCnt == 6){oCurrent = oNPC6;}
        if(nCnt == 7){oCurrent = oNPC7;}
        if(nCnt == 8){oCurrent = oNPC8;}
        if(nCnt == 9){oCurrent = oNPC9;}
        if(nCnt == 10){oCurrent = oNPC10;}
        if(nCnt == 11){oCurrent = oNPC11;}
        if(GetIsObjectValid(oCurrent))
        {
            UT_HealNPC(oCurrent);
        }
        nCnt++;
    }
    UT_HealNPC(GetFirstPC());
}
//::///////////////////////////////////////////////
//:: Clear Party Members
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Goes through the party and removes them.
    This is best used on Module Load when the
    object are not actually created yet.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: March 6, 2003
//:://////////////////////////////////////////////
void UT_ClearAllPartyMembers()
{
    int nCnt;
    for(nCnt; nCnt <= 8; nCnt++)
    {
        if(IsNPCPartyMember(nCnt))
        {
            RemovePartyMember(nCnt);
        }
    }
}
//::///////////////////////////////////////////////
//:: DC check using an ability score only
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Does a DC check just using an ability score
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: March 13, 2003
//:://////////////////////////////////////////////
int UT_AbilityCheck(int iDC, int iAbility, object oTarget)
{
    if(!GetIsObjectValid(oTarget))
    {
        return(FALSE);
    }
    if(GetAbilityScore(oTarget,iAbility) + (Random(20)+1) >= iDC)
    {
        return(TRUE);
    }
    else
    {
        return(FALSE);
    }
}
//::///////////////////////////////////////////////
//:: Make Neutral2
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the neutral faction
*/
//:://////////////////////////////////////////////
//:: Created By: Peter T.
//:: Created On: March 17, 2003
//:://////////////////////////////////////////////
void UT_MakeNeutral2(string sObjectTag)
{
    int nCount = 1;
    // get first object
    object oObject = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oObject))
    {
        // set to Neutral
        ChangeToStandardFaction(oObject, STANDARD_FACTION_NEUTRAL);
        // get next object
        nCount++;
        oObject = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Make Hostile1
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the Hostile_1 faction
*/
//:://////////////////////////////////////////////
//:: Created By: Peter T.
//:: Created On: March 17, 2003
//:://////////////////////////////////////////////
void UT_MakeHostile1(string sObjectTag)
{
    int nCount = 1;
    // get first object
    object oObject = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oObject))
    {
        // set to Hostile_1
        ChangeToStandardFaction(oObject, STANDARD_FACTION_HOSTILE_1);
        // get next object
        nCount++;
        oObject = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Make Friendly1
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the Friendly_1 faction
*/
//:://////////////////////////////////////////////
//:: Created By: Peter T.
//:: Created On: March 17, 2003
//:://////////////////////////////////////////////
void UT_MakeFriendly1(string sObjectTag)
{
    int nCount = 1;
    // get first object
    object oObject = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oObject))
    {
        // set to Friendly_1
        ChangeToStandardFaction(oObject, STANDARD_FACTION_FRIENDLY_1);
        // get next object
        nCount++;
        oObject = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: Make Friendly2
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Searches the area and changes all objects with
    the specified tag to the Friendly_2 faction
*/
//:://////////////////////////////////////////////
//:: Created By: Peter T.
//:: Created On: March 17, 2003
//:://////////////////////////////////////////////
void UT_MakeFriendly2(string sObjectTag)
{
    int nCount = 1;
    // get first object
    object oObject = GetNearestObjectByTag(sObjectTag);
    while(GetIsObjectValid(oObject))
    {
        // set to Friendly_2
        ChangeToStandardFaction(oObject, STANDARD_FACTION_FRIENDLY_2);
        // get next object
        nCount++;
        oObject = GetNearestObjectByTag(sObjectTag, OBJECT_SELF, nCount);
    }
}
//::///////////////////////////////////////////////
//:: UT_ActivateTortureCage
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    performs a standard torture cage effect
*/
//:://////////////////////////////////////////////
//:: Created By: Jason Booth
//:: Created On: April 1, 2003
//:://////////////////////////////////////////////
void DoTortureAnims(float fDuration)
{
    ActionPlayAnimation(ANIMATION_LOOPING_SPASM,1.0,fDuration/3.0);
    ActionPlayAnimation(ANIMATION_LOOPING_HORROR,1.0,fDuration/3.0);
    ActionPlayAnimation(ANIMATION_LOOPING_SPASM,1.0,fDuration/3.0);
}
void UT_ActivateTortureCage(object oCage, object oTarget,float fDuration)
{
    //AssignCommand(oCage,
    //ActionPlayAnimation(ANIMATION_PLACEABLE_ACTIVATE));
    //ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectHorrified(),oTarget,fDuration);
    AssignCommand(oTarget,DoTortureAnims(fDuration));
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectBeam(VFX_BEAM_LIGHTNING_DARK_S, oCage, BODY_NODE_HEAD),oTarget,fDuration);
    //DelayCommand(fDuration,AssignCommand(oCage,ActionPlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE)));
}
//::///////////////////////////////////////////////
//:: Validate Jump
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    If the first three letters of the last module
    do not match the first three letters of the
    space port then function will return false.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 15, 2003
//:://////////////////////////////////////////////
int UT_ValidateJump(string sLastModule)
{
    int nJump = FALSE;
    string sCurrentModule = GetModuleFileName();
    PrintString("JUMP VALIDATION: CURRENT = " + sCurrentModule + " LAST = " + sLastModule);
    PrintString("JUMP VALIDATION: SUBSTRING: " + GetSubString(sCurrentModule, 0,3) + " = " + GetSubString(sLastModule, 0,3));
    if(GetSubString(sCurrentModule, 0,3) == GetSubString(sLastModule, 0,3))
    {
        nJump = TRUE;
    }
    else if(sCurrentModule != "ebo_m12aa")
    {
        SetGlobalString("K_LAST_MODULE", "NO_MODULE");
    }
    return nJump;
}
//::///////////////////////////////////////////////
//:: Play On Click Reaction
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Makes the animal face the PC, do its victory
    and play a sound passed in. Should be used
    in conjunction with the k_def_interact spawn in
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 31, 2003
//:://////////////////////////////////////////////
void UT_DoAmbientReaction(string sSound)
{
    //ActionDoCommand(SetLocalBoolean(OBJECT_SELF, 72, FALSE));
    PlaySound(sSound);
    SetFacingPoint(GetPosition(GetPCSpeaker()));
    ActionPlayAnimation(ANIMATION_FIREFORGET_VICTORY1);
    //DelayCommand(2.0, ActionDoCommand(SetLocalBoolean(OBJECT_SELF, 72, TRUE)));
}
// DJS-OEI 1/19/2004
//::///////////////////////////////////////////////
//:: Set Planet Global
//:://////////////////////////////////////////////
/*
    VARIABLE = K_CURRENT_PLANET
    Planet/Location         ID
    --------------------------
    Dantooine               5
    Dxun                    10
    Ebon Hawk               15
    Korriban                20
    M4-78                   25
    Malachor V              30
    Nar Shaddaa             35
    Onderon                 40
    Peragus                 45
    Telos                   50
    Harbinger               55
    Live 1                  60
    Live 2                  65
    Live 3                  70
    Live 4                  75
    Live 5                  80
    Live 6                  85
*/
//:://////////////////////////////////////////////
//:: Created By: Dan Spitzley
//:: Created On: January 19, 2004
//:://////////////////////////////////////////////
void UT_SetPlanetaryGlobal(int nPlanetConstant)
{
    if(nPlanetConstant == PLANET_DANTOOINE)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 5);
    }
    else if(nPlanetConstant == PLANET_DXUN)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 10);
    }
    else if(nPlanetConstant == PLANET_EBON_HAWK)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 15);
    }
    else if(nPlanetConstant == PLANET_KORRIBAN)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 20);
    }
    else if(nPlanetConstant == PLANET_M4_78)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 25);
    }
    else if(nPlanetConstant == PLANET_MALACHOR_V)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 30);
    }
    else if(nPlanetConstant == PLANET_NAR_SHADDAA)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 35);
    }
    else if(nPlanetConstant == PLANET_ONDERON)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 40);
    }
    else if(nPlanetConstant == PLANET_PERAGUS)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 45);
    }
    else if(nPlanetConstant == PLANET_TELOS)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 50);
    }
    else if(nPlanetConstant == PLANET_HARBINGER)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 55);
    }
    else if(nPlanetConstant == PLANET_LIVE_01)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 60);
    }
    else if(nPlanetConstant == PLANET_LIVE_02)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 65);
    }
    else if(nPlanetConstant == PLANET_LIVE_03)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 70);
    }
    else if(nPlanetConstant == PLANET_LIVE_04)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 75);
    }
    else if(nPlanetConstant == PLANET_LIVE_05)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 80);
    }
    else if(nPlanetConstant == PLANET_LIVE_06)
    {
        SetGlobalNumber("K_CURRENT_PLANET", 85);
    }
}
// JAB-OEI 8/5/04
// Stores the facing of the party leader to be preserved during conversation
// Can restore with UT_RestoreLeaderFacing
void UT_StoreLeaderFacing(object oLeader)
{
    SetLocalNumber(oLeader,8,1); // this is used by the headler AI routine (safe to use here)
    SetLocalNumber(oLeader,9,FloatToInt(GetFacing(oLeader)/10.0f + 0.5f));
}
// JAB-OEI 8/5/04
// Restores leader facing direction after conversation (call this on the last red node of a conversation)
// should be called in conjunction with UT_StoreLeaderFacing();
void UT_RestoreLeaderFacing(object oLeader)
{
    object oPC = GetPartyLeader();
    if(GetLocalNumber(oLeader,8) == 1)
    {
        float fFacing = IntToFloat(GetLocalNumber(oLeader,9)*10);
        SetLocalNumber(oLeader,8,0);
        DelayCommand(0.1,AssignCommand(oLeader,ActionDoCommand(SetFacing(fFacing))));
    }
}
// Tony Evans 9/14/04
// Counts the number of creatures of the OBJECT_TYPE of a given tag, or objects that contain a given tag
// Returns the number of objects
int UT_ObjectCount(string sTag, int iName)
{
    // This variable will contain the number of objects
    int iCount;
    object oObject;
    if (sTag == "") oObject = OBJECT_SELF;
    else oObject = GetObjectByTag(sTag);
    if (!GetIsObjectValid(oObject)) oObject = OBJECT_SELF;
    // Get OBJECT_TYPE of Object (This variable is not used unless iNum == 0)
    int iObjType = GetObjectType (oObject);
    object oTemp = GetFirstObjectInArea();
    if (iName == 1)
    {
        while(GetIsObjectValid(oTemp))
        {
            // If the beginning (left side) of the string contains sTag, increment iCount
            if(GetStringLeft(GetTag(oTemp),GetStringLength(sTag)) == sTag) iCount++;
            oTemp = GetNextObjectInArea();
        }
    }
    else if (iName == 2)
    {
        while(GetIsObjectValid(oTemp))
        {
            // If the end (right side) of the string contains sTag, increment iCount
            if(GetStringRight(GetTag(oTemp),GetStringLength(sTag)) == sTag) iCount++;
            oTemp = GetNextObjectInArea();
        }
    }
    else if (iName == 3)
    {
        while(GetIsObjectValid(oTemp))
        {
            // If sTag is anywhere within the string, increment iCount
            if(FindSubString(GetTag(oTemp),sTag) >= 0) iCount++;
            oTemp = GetNextObjectInArea();
        }
    }
    // assuming iName == 0
    else
    {
        while(GetIsObjectValid(oTemp))
        {
            if (GetObjectType(oTemp) == iObjType) iCount++;
            oTemp = GetNextObjectInArea();
        }
    }
    if (iName == 0) AurPostString("Number of object type " + IntToString(iObjType) + " = " + IntToString(iCount),5,9,5.0);
    else AurPostString("Number of " + sTag + " = " + IntToString(iCount),5,9,5.0);
    return iCount;
}
""",
    "k_inc_walkways": b"""//:: k_inc_walkways
/*
    v1.0
    Walk Way Points Include
    used by k_inc_generic
    NOTE - To get these functions
    use k_inc_generic
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
int WALKWAYS_CURRENT_POSITION = 0;
int WALKWAYS_END_POINT = 1;
int WALKWAYS_SERIES_NUMBER = 2;
int SW_FLAG_AMBIENT_ANIMATIONS  =   29;
// DJS-OEI 3/31/2004
// Modified to make room for designer-reserved values.
/*
int SW_FLAG_AMBIENT_ANIMATIONS_MOBILE = 30;
int SW_FLAG_WAYPOINT_WALK_ONCE  =   34;
int SW_FLAG_WAYPOINT_WALK_CIRCULAR  =   35;
int SW_FLAG_WAYPOINT_WALK_PATH  =   36;
int SW_FLAG_WAYPOINT_WALK_STOP  =   37; //One to three
int SW_FLAG_WAYPOINT_WALK_RANDOM    =   38;
int SW_FLAG_WAYPOINT_WALK_RUN    =   39;
int SW_FLAG_WAYPOINT_DIRECTION = 41;
int SW_FLAG_WAYPOINT_DEACTIVATE = 42;
int SW_FLAG_WAYPOINT_WALK_STOP_LONG = 46;
int SW_FLAG_WAYPOINT_WALK_STOP_RANDOM = 47;
int SW_FLAG_WAYPOINT_START_AT_NEAREST = 73;
*/
int SW_FLAG_AMBIENT_ANIMATIONS_MOBILE = 65;
int SW_FLAG_WAYPOINT_START_AT_NEAREST = 98;
int SW_FLAG_WAYPOINT_WALK_ONCE  =   99;
int SW_FLAG_WAYPOINT_WALK_CIRCULAR  =   100;
int SW_FLAG_WAYPOINT_WALK_PATH  =   101;
int SW_FLAG_WAYPOINT_WALK_RANDOM    =   103;
int SW_FLAG_WAYPOINT_WALK_RUN    =   104;
int SW_FLAG_WAYPOINT_DIRECTION = 105;
int SW_FLAG_WAYPOINT_DEACTIVATE = 106;
//new constants for WAYPOINT PAUSING
int SW_FLAG_WAYPOINT_PAUSE_SHORT  = 102;
int SW_FLAG_WAYPOINT_PAUSE_LONG   = 107;
int SW_FLAG_WAYPOINT_PAUSE_RANDOM = 108;
//old constants for WAYPOINT PAUSING. kept for backwards compatibility
int SW_FLAG_WAYPOINT_WALK_STOP        = 102;// DON'T USE ANYMORE
int SW_FLAG_WAYPOINT_WALK_STOP_LONG   = 107;// DON'T USE ANYMORE
int SW_FLAG_WAYPOINT_WALK_STOP_RANDOM = 108;// DON'T USE ANYMORE
//AWD-OEI 06/23/04 adding a local to store the waypoint animation
int SW_FLAG_USE_WAYPOINT_ANIMATION = 109;
//Makes OBJECT_SELF walk way points based on the spawn in conditions set out.
void GN_WalkWayPoints();
//Sets the series number from 01 to 99 on a creature so that the series number and not the creature's tag is used for walkway points
void GN_SetWalkWayPointsSeries(int nSeriesNumber);
//Sets Generic Spawn In Conditions
void GN_SetSpawnInCondition(int nFlag, int nState = TRUE);
//Gets the boolean state of a generic spawn in condition.
int GN_GetSpawnInCondition(int nFlag);
//Moves an object to the last waypoint in a series
void GN_MoveToLastWayPoint(object oToMove);
//Moves an object to a random point in the series
void GN_MoveToRandomWayPoint(object oToMove);
//Moves an object to a sepcific point in the series
void GN_MoveToSpecificWayPoint(object oToMove, int nArrayNumber);
//Determines the correct direction to proceed in a walkway points array.
int GN_GetWayPointDirection(int nEndArray, int nCurrentPosition);
//Should only be called from within SetListendingPatterns
void GN_SetUpWayPoints();
//Play an animation between way points.
void GN_PlayWalkWaysAnimation();
//Inserts a print string into the log file for debugging purposes for the walkways include.
void WK_MyPrintString(string sString);
//Are valid walkway points available
int GN_CheckWalkWays(object oTarget);
//GN_GetNearestWaypoint - RWT-OEI 01/23/04
//Returns an int representing which Nth into the series is the nearest WP.
//If nSeries is 0, then it will pull from the nearest waypoint in the path named after
//oCharacter.
int GN_GetNearestWaypoint(object oCharacter, int nSeriesNumber = 0);
//::///////////////////////////////////////////////
//:: Walk Way Points
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Makes OBJECT_SELF walk way points based on a
    number of spawn in conditions.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
void GN_WalkWayPoints()
{
    if(!GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE))
    {
        string sPost = "POST_";
        string sWays = "WP_";
        string sWayNumber;
        int nCurrentTarget = GetLocalNumber(OBJECT_SELF, WALKWAYS_CURRENT_POSITION);
        int nEndArray = GetLocalNumber(OBJECT_SELF, WALKWAYS_END_POINT);
        int nSeriesInt = GetLocalNumber(OBJECT_SELF, WALKWAYS_SERIES_NUMBER);
        //Used where you want the creature to use a numbered series instead of their own tag.
        if(nCurrentTarget < 10 &&  nCurrentTarget > 0)
        {
            sWayNumber = "0" + IntToString(nCurrentTarget);
        }
        else if(nCurrentTarget == 0)
        {
            //August 2, 2002 - Jason Booth - changed to randomize start wp
            if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RANDOM))
            {
                nCurrentTarget = Random(nEndArray) + 1;
                if(nCurrentTarget < 10)
                {
                  sWayNumber = "0" + IntToString(nCurrentTarget);
                }
                else
                {
                  sWayNumber = IntToString(nCurrentTarget);
                }
            }
            else if ( GN_GetSpawnInCondition( SW_FLAG_WAYPOINT_START_AT_NEAREST ) )
            {
                int nNearestNumber = GN_GetNearestWaypoint(OBJECT_SELF, nSeriesInt );
                if ( nNearestNumber > 0 && nNearestNumber < 10 )
                {
                    sWayNumber = "0" + IntToString(nNearestNumber);
                }
                else if ( nNearestNumber >= 10 )
                {
                    sWayNumber = IntToString(nNearestNumber);
                }
                else
                {
                    sWayNumber = "01";
                }
                nCurrentTarget = nNearestNumber;
            }
            else
            {
              sWayNumber = "01";
            }
        }
        else if(nCurrentTarget < 10)
        {
            sWayNumber = "0" + IntToString(nCurrentTarget);
        }
        else
        {
            sWayNumber = IntToString(nCurrentTarget);
        }
        string sMoveWay;
        string sTestWay;
        //Test to see if the series waypoints are being used and if so then build sTestWay with the number not tag.
        if(nSeriesInt > 0)
        {
            string sSeriesWay;
            if(nSeriesInt < 10)
            {
                sSeriesWay = "0" + IntToString(nSeriesInt);
            }
            else
            {
                sSeriesWay = IntToString(nSeriesInt);
            }
            sTestWay = sWays + sSeriesWay + "_02";
        }
        //Use object tag if there is no series number
        else
        {
            sTestWay = sWays + GetTag(OBJECT_SELF) + "_02";
        }
        object oTestWay = GetWaypointByTag(sTestWay);
        if(nEndArray == 0 && GetIsObjectValid(oTestWay))
        {
            //GN_PostString("SET LISTENING PATTERNS HAS NOT RUN PLEASE USE IN SPAWN IN SCRIPT");
        }
        if(GetIsObjectValid(oTestWay))
        {
            int nLength = GetStringLength(sTestWay);
            sMoveWay = GetStringLeft(sTestWay, nLength - 2) + sWayNumber;
            //sWays + GetTag(OBJECT_SELF) + "_" + sWayNumber;
        }
        else
        {
            sWays = "UNKNOWN";
            sMoveWay = sPost + GetTag(OBJECT_SELF);
        }
        object oWay = GetWaypointByTag(sMoveWay);
        int nRun = GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RUN);
        //Check if the target waypoint is close enough to warrent moving on to the next waypoint.
        float personalSpace = GetObjectPersonalSpace(OBJECT_SELF);
        personalSpace += 0.1;
        if(GetDistanceToObject2D(oWay) <= personalSpace)
        {
            int nDirection;
            if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RANDOM))
            {
                nCurrentTarget = Random(nEndArray) + 1;
            }
            //AWD-OEI else if(nCurrentTarget < nEndArray && !GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RANDOM))
            else if(nCurrentTarget < nEndArray)
            {
                nDirection = GN_GetWayPointDirection(nEndArray, nCurrentTarget);
                nCurrentTarget = nCurrentTarget + nDirection;
            }
            else if(nCurrentTarget == nEndArray)
            {
                nDirection = GN_GetWayPointDirection(nEndArray, nCurrentTarget);
                if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_ONCE))
                {
                    GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE);
                }
                else if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_CIRCULAR))
                {
                    nCurrentTarget = 1;
                    GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DIRECTION, FALSE);
                }
                else
                {
                    nCurrentTarget = nCurrentTarget + nDirection;
                }
            }
        }
        if(GetIsObjectValid(GetWaypointByTag(sMoveWay)))
        {
            int nRand;
            if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_PAUSE_SHORT))
            {
                nRand = 3;
            }
            else if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_PAUSE_LONG))
            {
                nRand = d3() + 3;
            }
            else if(GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_PAUSE_RANDOM))
            {
                nRand = d10();
            }
            else
            {
                nRand = 0;
            }
            //Calculate the timeout based on the distance that needs to be traveled.
            float fTimeOut = GetDistanceBetween2D(GetWaypointByTag(sMoveWay), OBJECT_SELF)/1.25;
            if(fTimeOut < 30.0)
            {
                fTimeOut = 30.0;
            }
            ActionForceMoveToObject(oWay, GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RUN), personalSpace, fTimeOut); //ACTION
            if(GN_GetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS))
            {
                ActionDoCommand(GN_PlayWalkWaysAnimation()); //ACTION
            }
            SetLocalNumber(OBJECT_SELF, WALKWAYS_CURRENT_POSITION, nCurrentTarget);
            if(sWays != "UNKNOWN")
            {
                if(nRand > 0)
                {
                    //need to point in direction of waypoint at this juncture
                    object oTempWay = GetWaypointByTag(sMoveWay);
                    float fFacing = GetFacing(oTempWay);
                    ActionDoCommand( SetFacing(fFacing) );
                    if( GN_GetSpawnInCondition(SW_FLAG_USE_WAYPOINT_ANIMATION) )
                    {
                        ActionPlayAnimation(GetLocalNumber(OBJECT_SELF, 29), 1.0, IntToFloat(nRand));
                        //ActionWait(IntToFloat(nRand)); //ACTION
                    }
                    else
                    {
                        ActionWait(IntToFloat(nRand)); //ACTION
                    }
                }
                ActionDoCommand(GN_WalkWayPoints());   //ACTION
            }
        }
    }
}
void GN_SetWalkWayPointsSeries(int nSeriesNumber)
{
    SetLocalNumber(OBJECT_SELF, WALKWAYS_SERIES_NUMBER, nSeriesNumber);
}
//::///////////////////////////////////////////////
//:: Set Spawn In Condition
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Sets the Generic Spawn In Conditions
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
void GN_SetSpawnInCondition(int nFlag, int nState = TRUE)
{
    //WK_MyPrintString("GENERIC DEBUG *************** Setting Local Number (" + IntToString(nFlag) + ") = " + IntToString(nState));
    SetLocalBoolean(OBJECT_SELF, nFlag, nState);
}
//::///////////////////////////////////////////////
//:: Get Spawn In Condition
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets the Generic Spawn In Conditions
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////
int GN_GetSpawnInCondition(int nFlag)
{
    int nLocal = GetLocalBoolean(OBJECT_SELF, nFlag);
    if(nLocal > 0)
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Preston Watamaniuk
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Moves the passed in object to the last waypoint
    in that NPCs series of waypoints.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 12, 2002
//:://////////////////////////////////////////////
void GN_MoveToLastWayPoint(object oToMove)
{
    int nLastWay = GetLocalNumber(oToMove, WALKWAYS_END_POINT);
    int nSeries = GetLocalNumber(oToMove, WALKWAYS_SERIES_NUMBER);
    string sString;
    if(nSeries > 0)
    {
        string sSeriesWay;
        if(nSeries < 10)
        {
            sSeriesWay = "0" + IntToString(nSeries);
        }
        else
        {
            sSeriesWay = IntToString(nSeries);
        }
        sString = "WP_" + sSeriesWay;
    }
    else
    {
        sString = "WP_" + GetTag(oToMove);
    }
    if(nLastWay < 10)
    {
        sString = sString + "_0" + IntToString(nLastWay);
    }
    else
    {
        sString = sString + "_" + IntToString(nLastWay);
    }
    object oWay = GetWaypointByTag(sString);
    if(GetIsObjectValid(oWay))
    {
        AssignCommand(oToMove, ClearAllActions());
        AssignCommand(oToMove, ActionMoveToObject(oWay, FALSE));
    }
}
//::///////////////////////////////////////////////
//:: Preston Watamaniuk
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Moves the passed in object to a random waypoint
    in that NPCs series of waypoints.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 12, 2002
//:://////////////////////////////////////////////
void GN_MoveToRandomWayPoint(object oToMove)
{
    int nLastWay = GetLocalNumber(oToMove, WALKWAYS_END_POINT);
    int nRandom = Random(nLastWay)+1;
    int nSeries = GetLocalNumber(oToMove, WALKWAYS_SERIES_NUMBER);
    string sString;
    if(nSeries > 0)
    {
        string sSeriesWay;
        if(nSeries < 10)
        {
            sSeriesWay = "0" + IntToString(nSeries);
        }
        else
        {
            sSeriesWay = IntToString(nSeries);
        }
        sString = "WP_" + sSeriesWay;
    }
    else
    {
        sString = "WP_" + GetTag(oToMove);
    }
    if(nLastWay < 10)
    {
        sString = sString + "_0" + IntToString(nRandom);
    }
    else
    {
        sString = sString + "_" + IntToString(nRandom);
    }
    object oWay = GetWaypointByTag(sString);
    if(GetIsObjectValid(oWay))
    {
        AssignCommand(oToMove, ClearAllActions());
        AssignCommand(oToMove, ActionMoveToObject(oWay, FALSE));
    }
}
//::///////////////////////////////////////////////
//:: Preston Watamaniuk
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Moves the passed in object to a specified waypoint
    in that NPCs series of waypoints.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 12, 2002
//:://////////////////////////////////////////////
void GN_MoveToSpecificWayPoint(object oToMove, int nArrayNumber)
{
    int nLastWay = GetLocalNumber(oToMove, WALKWAYS_END_POINT);
    int nSeries = GetLocalNumber(oToMove, WALKWAYS_SERIES_NUMBER);
    string sString;
    if(nArrayNumber <= nLastWay)
    {
        if(nSeries > 0)
        {
            string sSeriesWay;
            if(nSeries < 10)
            {
                sSeriesWay = "0" + IntToString(nSeries);
            }
            else
            {
                sSeriesWay = IntToString(nSeries);
            }
            sString = "WP_" + sSeriesWay;
        }
        else
        {
            sString = "WP_" + GetTag(oToMove);
        }
        if(nArrayNumber < 10)
        {
            sString = sString + "_0" + IntToString(nArrayNumber);
        }
        else
        {
            sString = sString + "_" + IntToString(nArrayNumber);
        }
        object oWay = GetWaypointByTag(sString);
        if(GetIsObjectValid(oWay))
        {
            AssignCommand(oToMove, ClearAllActions());
            AssignCommand(oToMove, ActionMoveToObject(oWay, FALSE));
        }
    }
}
//::///////////////////////////////////////////////
//:: Get Waypooint Direction
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Determines the direction that a NPC should be
    walking along their waypoints.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jul 20, 2002
//:://////////////////////////////////////////////
int GN_GetWayPointDirection(int nEndArray, int nCurrentPosition)
{
    int nDirection;
    int nFlag = GN_GetSpawnInCondition(SW_FLAG_WAYPOINT_DIRECTION);
    if(nEndArray == nCurrentPosition && nFlag == FALSE)
    {
        nDirection = -1;
        GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DIRECTION, TRUE);
    }
    else if(nCurrentPosition == 1 && nFlag == TRUE)
    {
        nDirection = 1;
        GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DIRECTION, FALSE);
    }
    else if(nFlag == FALSE)
    {
        nDirection = 1;
    }
    else if(nFlag == TRUE)
    {
        nDirection = -1;
    }
    return nDirection;
}
//::///////////////////////////////////////////////
//:: Set Up Way Points
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Used to initialize the NPCs waypoints
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 9, 2002
//:://////////////////////////////////////////////
void GN_SetUpWayPoints()
{
    string sString;
    int nSeries = GetLocalNumber(OBJECT_SELF, WALKWAYS_SERIES_NUMBER);
    if(nSeries > 0)
    {
        string sSeriesWay;
        if(nSeries < 10)
        {
            sSeriesWay = "0" + IntToString(nSeries);
        }
        else
        {
            sSeriesWay = IntToString(nSeries);
        }
        sString = "WP_" + sSeriesWay;
    }
    else
    {
        sString = "WP_" + GetTag(OBJECT_SELF);
    }
    int nCnt = 1;
    string sTest = sString + "_01";
    object oWay = GetWaypointByTag(sTest);
    while(GetIsObjectValid(oWay))
    {
        nCnt++;
        if(nCnt < 10)
        {
            sTest = sString + "_0" + IntToString(nCnt);
        }
        else
        {
            sTest = sString + "_" + IntToString(nCnt);
        }
        oWay = GetWaypointByTag(sTest);
    }
    nCnt = nCnt - 1;
    if(nCnt > 0)
    {
        SetLocalNumber(OBJECT_SELF, WALKWAYS_END_POINT, nCnt);
    }
}
//::///////////////////////////////////////////////
//:: Play Walk Ways Animations
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Plays an animation between way points
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: March 13, 2003
//:://////////////////////////////////////////////
void GN_PlayWalkWaysAnimation()
{
    int nRoll = d8();
    if(nRoll == 1)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Bored");
        ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_BORED, 1.0);
    }
    else if(nRoll == 2)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Scratch");
        ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0);
    }
    else if(nRoll == 3)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Pause 2");
        ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 3.0);
    }
    else if((nRoll == 4 || nRoll == 5) && GetRacialType(OBJECT_SELF) != RACIAL_TYPE_DROID)
    {
        if(GetGender(OBJECT_SELF) == GENDER_MALE)
        {
            //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Male Pause 3");
            GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
            ActionPlayAnimation(ANIMATION_LOOPING_PAUSE3, 1.0, 20.4);
            ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
        }
        else if(GetGender(OBJECT_SELF) == GENDER_FEMALE)
        {
            //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Female Pause 3");
            GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
            ActionPlayAnimation(ANIMATION_LOOPING_PAUSE3, 1.0, 13.3);
            ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
        }
    }
    else if(nRoll == 6 || nRoll == 4 || nRoll == 5)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Head Turn Left");
        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_LEFT);
    }
    else if(nRoll == 7)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Head Turn Right");
        ActionPlayAnimation(ANIMATION_FIREFORGET_HEAD_TURN_RIGHT);
    }
    else if(nRoll == 8)
    {
        //WK_MyPrintString("WALKWAYS DEBUG *************** Play Anim: Pause 2");
        GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, FALSE);
        ActionPlayAnimation(ANIMATION_LOOPING_PAUSE2, 1.0, 5.0);
        ActionDoCommand(GN_SetSpawnInCondition(SW_FLAG_AMBIENT_ANIMATIONS, TRUE));
    }
}
//::///////////////////////////////////////////////
//:: Are Walk Ways Available
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Are valid walkway points available for walking
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: May 22, 2003
//:://////////////////////////////////////////////
int GN_CheckWalkWays(object oTarget)
{
    string sTag = "WP_" + GetTag(oTarget) + "_01";
    string sPost = "POST_" + GetTag(oTarget);
    int nSeriesInt = GetLocalNumber(oTarget, WALKWAYS_SERIES_NUMBER);
    string sSeriesWay;
    if(nSeriesInt < 10)
    {
        sSeriesWay = "0" + IntToString(nSeriesInt);
    }
    else
    {
        sSeriesWay = IntToString(nSeriesInt);
    }
    string sTestWay = "WP_" + sSeriesWay + "_01";
    object oWay = GetWaypointByTag(sTag);
    object oWay2 = GetWaypointByTag(sTestWay);
    object oPost = GetWaypointByTag(sPost);
    WK_MyPrintString("Walk Initiate for " + GetTag(oTarget));
    WK_MyPrintString("TAG WAY FOUND = " + IntToString(GetIsObjectValid(oWay)));
    WK_MyPrintString("WAY POINT NAME = " + GetTag(oWay));
    WK_MyPrintString("SERIES INT = " + IntToString(nSeriesInt));
    WK_MyPrintString("SERIES WAY FOUND = " + IntToString(GetIsObjectValid(oWay2)));
    WK_MyPrintString("SERIES Series Tag = " + sTestWay);
    WK_MyPrintString("");
    if(GetIsObjectValid(oWay) || GetIsObjectValid(oWay2) || GetIsObjectValid(oPost))
    {
        return TRUE;
    }
    return FALSE;
}
void WK_MyPrintString(string sString)
{
    if(!ShipBuild())
    {
        PrintString(sString);
    }
}
//RWT-OEI 01/23/04
//GN_GetNearestWaypoint
//Returns an int representing which Nth into the series is the nearest WP.
//If nSeries is 0, then it will pull from the nearest waypoint in the path named after
//oCharacter.
int GN_GetNearestWaypoint( object oCharacter, int nSeriesNumber = 0 )
{
    string sWPNumber;
    string sSeriesName;
    object oClosestWP = OBJECT_INVALID;
    float  fMinDistance = 0.0f;
    //Need to determine the correct name for the waypoints.
    int nSeries = GetLocalNumber(OBJECT_SELF, WALKWAYS_SERIES_NUMBER);
    if ( nSeries > 0 ) {//We have a series number, so use it
        string sSeriesWay;
        if ( nSeries < 10 ) {
            sSeriesWay = "0" + IntToString(nSeries);
        } else {
            sSeriesWay = IntToString(nSeries);
        }
        sSeriesName = "WP_" + sSeriesWay;
    } else {//No series number, so use the object's tag
        sSeriesName = "WP_" + GetTag(oCharacter);
    }
    //Now we need to iterate through all the WPs in that series and figure out
    //which of them is closest.
    int nCurNumber = 1;
    int nClosestNumber = 0;
    string sCurWPName = sSeriesName + "_01";
    object oCurWP = GetWaypointByTag(sCurWPName);
    float fCurDistance = 0.0f;
    while (GetIsObjectValid(oCurWP)) {//Now iterate over all the WPs in the series
        //Check to see if this is the closest WP so far.
        fCurDistance = GetDistanceBetween( oCharacter, oCurWP );
        if ( fMinDistance == 0.0f ) {
            fMinDistance = fCurDistance;
            oClosestWP = oCurWP;
            nClosestNumber = nCurNumber;
        } else if ( fCurDistance < fMinDistance ) {
            fMinDistance = fCurDistance;
            oClosestWP = oCurWP;
            nClosestNumber = nCurNumber;
        }
        //Get next WP
        ++nCurNumber;
        if ( nCurNumber < 10 ) {
            sCurWPName = sSeriesName + "_0" + IntToString(nCurNumber);
        } else {
            sCurWPName = sSeriesName + "_" + IntToString(nCurNumber);
        }
        oCurWP = GetWaypointByTag(sCurWPName);
    }
    return nClosestNumber;
}
""",
    "k_inc_zone": b"""//:: k_inc_zones
/*
     Zone including for controlling
     the chaining of creatures
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.
#include "k_inc_generic"
//Function run by the trigger to catalog the control nodes followers
void ZN_CatalogFollowers();
//Checks zone conditional on creature to if they belong to the zone
int ZN_CheckIsFollower(object oController, object oTarget);
//Checks the distance and creatures around the PC to see if it should return home.
int ZN_CheckReturnConditions();
//Gets the followers to move back to the controller object
void ZN_MoveToController(object oController, object oFollower);
//Checks to see if a specific individual needs to return to the controller.
int ZN_CheckFollowerReturnConditions(object oTarget);
//::///////////////////////////////////////////////
//:: Catalog Zone Followers
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
     Catalogs all creatures within
     the trigger area and marks
     them with an integer which
     is part of the creature's
     tag.
     Use local number SW_NUMBER_LAST_COMBO
     as a test. A new local number will
     be defined if the system works.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 7, 2003
//:://////////////////////////////////////////////
void ZN_CatalogFollowers()
{
    GN_PostString("FIRING", 10,10, 10.0);
    if(GetLocalBoolean(OBJECT_SELF, 10) == FALSE) //Has talked to boolean
    {
        string sZoneTag = GetTag(OBJECT_SELF);
        int nZoneNumber = StringToInt(GetStringRight(sZoneTag, 2));
        //Set up creature followers
        object oZoneFollower = GetFirstInPersistentObject();
        while(GetIsObjectValid(oZoneFollower))
        {
            SetLocalNumber(oZoneFollower, SW_NUMBER_COMBAT_ZONE, nZoneNumber);
            //GN_MyPrintString("ZONING DEBUG ***************** Setup Follower = " + GN_ReturnDebugName(oZoneFollower));
            //GN_MyPrintString("ZONING DEBUG ***************** Setup Follower Zone # = " + GN_ITS(GetLocalNumber(oZoneFollower, SW_NUMBER_COMBAT_ZONE)));
            oZoneFollower = GetNextInPersistentObject();
        }
        SetLocalBoolean(OBJECT_SELF, 10, TRUE);//Has talked to boolean
    }
}
//::///////////////////////////////////////////////
//:: Check Object for Zoning
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks the object to see if they part of the
    zone. This function is run off of the control
    node.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 7, 2003
//:://////////////////////////////////////////////
int ZN_CheckIsFollower(object oController, object oTarget)
{
    int nNumber = GetLocalNumber(oTarget, SW_NUMBER_COMBAT_ZONE);
    string sZoneTag = GetTag(OBJECT_SELF);
    int nZoneNumber = StringToInt(GetStringRight(sZoneTag, 2));
    if(nZoneNumber == nNumber)
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Check Return Conditions
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks to see if the conditions exist to
    possibly check for followers to return to
    the controller.
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
int ZN_CheckReturnConditions()
{
    object oPC = GetPartyMemberByIndex(0);
    /*
        1.  Is the PC more than 21m away from the control node
        2.  Is the follower more than 20m away from the control node
        3.  Are there 9 or more individuals around the any single party member out to a distance of 30m
    */
    object oNinth = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, oPC, 9);
    //GN_MyPrintString("ZONING DEBUG ***************** 9th Creature = " + GN_ReturnDebugName(oNinth));
    //GN_MyPrintString("ZONING DEBUG ***************** 9th Creature Distance = " + FloatToString(GetDistanceBetween(oPC, oNinth), 4,2));
    if(GetIsObjectValid(oNinth) && GetDistanceBetween(oPC, oNinth) < 30.0)
    {
        if(GetDistanceBetween(OBJECT_SELF, oPC) > 21.0)
        {
            return TRUE;
        }
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Check Follower Return Conditions.
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Checks if the follower object needs to return
    to home base.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 8, 2003
//:://////////////////////////////////////////////
int ZN_CheckFollowerReturnConditions(object oTarget)
{
    float fDistance = GetDistanceBetween(oTarget, OBJECT_SELF);
    //GN_MyPrintString("ZONING DEBUG ***************** " + GN_ReturnDebugName(oTarget) + " control distance " + FloatToString(fDistance, 4, 2));
    if(fDistance >= 10.0 && GetIsEnemy(oTarget, GetFirstPC()))
    {
        return TRUE;
    }
    return FALSE;
}
//::///////////////////////////////////////////////
//:: Move to Controller
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Gets the follower object to move back to the
    controller object.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 7, 2003
//:://////////////////////////////////////////////
void ZN_MoveToController(object oController, object oFollower)
{
    //GN_MyPrintString("ZONING DEBUG ***************** Controller = " + GN_ReturnDebugName(oController));
    //GN_MyPrintString("ZONING DEBUG ***************** Follower = " + GN_ReturnDebugName(oFollower));
    //GN_MyPrintString("ZONING DEBUG ***************** Follower Zone # = " + GN_ITS(GetLocalNumber(oFollower, SW_NUMBER_LAST_COMBO)));
    if(GetCurrentAction(oFollower) != ACTION_INVALID)
    {
        SetCommandable(TRUE);
    }
    CancelCombat(oFollower);
    AssignCommand(oFollower, ClearAllActions());
    AssignCommand(oFollower, ActionForceMoveToObject(oController, TRUE, 5.0, 5.0));
    AssignCommand(oFollower, ActionDoCommand(SetCommandable(TRUE, oFollower)));
    AssignCommand(oFollower, SetCommandable(FALSE, oFollower));
}
""",
    "k_oei_hench_inc": b"""
//:: Script Name
/*
    Desc
*/
//:: Created By:
//:: Copyright (c) 2002 Bioware Corp.
// Modified by JAB-OEI 7/23/04
// Added special scripts for the 711KOR fight with the entire party
#include "k_inc_generic"
#include "k_inc_utility"
void DoSpecialSpawnIn(object pObject);
void DoSpecialUserDefined(object pObject, int pUserEvent);
//Party Member SpawnIns
void DoAttonSpawnIn(object oPartyMember, string sModuleName);
void DoBaoDurSpawnIn(object oPartyMember, string sModuleName);
void DoMandSpawnIn(object oPartyMember, string sModuleName);
void DoDiscipleSpawnIn(object oPartyMember, string sModuleName);
void DoG0T0SpawnIn(object oPartyMember, string sModuleName);
void DoHandmaidenSpawnIn(object oPartyMember, string sModuleName);
void DoHanharrSpawnIn(object oPartyMember, string sModuleName);
void DoHK47SpawnIn(object oPartyMember, string sModuleName);
void DoKreiaSpawnIn(object oPartyMember, string sModuleName);
void DoMiraSpawnIn(object oPartyMember, string sModuleName);
void DoRemoteSpawnIn(object oPartyMember, string sModuleName);
void DoT3M4SpawnIn(object oPartyMember, string sModuleName);
void DoVisasMarrSpawnIn(object oPartyMember, string sModuleName);
//Party Member UserDefs
void DoAttonUserDef(object oPartyMember, int pUserEvent, string sModuleName);
void DoBaoDurUserDef(object oPartyMember, int pUserEvent, string sModuleName);
void DoMandUserDef(object oPartyMember, int pUserEvent, string sModuleName);
void DoDiscipleUserDef(object oPartyMember, int pUserEvent, string sModuleName);
void DoG0T0UserDef(object oPartyMember,int pUserEvent, string sModuleName);
void DoHandmaidenUserDef(object oPartyMember,int pUserEvent, string sModuleName);
void DoHanharrUserDef(object oPartyMember,int pUserEvent, string sModuleName);
void DoHK47UserDef(object oPartyMember,int pUserEvent, string sModuleName);
void DoKreiaUserDef(object oPartyMember,int pUserEvent, string sModuleName);
void DoMiraUserDef(object oPartyMember,int pUserEvent, string sModuleName);
void DoRemoteUserDef(object oPartyMember,int pUserEvent, string sModuleName);
void DoT3M4UserDef(object oPartyMember,int pUserEvent, string sModuleName);
void DoVisasMarrUserDef(object oPartyMember,int pUserEvent, string sModuleName);
void DoRemoteDefaultUserDef(object oPartyMember, int pUserEvent);
void Do711UserDef(object oPartyMember,int pUserEvent);
void DoSpecialSpawnIn(object pObject)
{
    AurPostString("DoSpecialSpawnIn" + GetTag(pObject), 18, 18, 3.0);
    if(GetIsObjectValid(pObject))
    {
        string tTag = GetTag(pObject);//should be a party member tag
        string sModuleName = GetModuleName();
        if(tTag == "atton")//Atton Rand
        {
            DoAttonSpawnIn(pObject, sModuleName);
        }
        else if(tTag == "baodur")//Bao-Dur
        {
            DoBaoDurSpawnIn(pObject, sModuleName);
        }
        else if(tTag == "mand")//Canderous
        {
            DoMandSpawnIn(pObject, sModuleName);
        }
        else if(tTag == "disciple")//Disciple
        {
            DoDiscipleSpawnIn(pObject, sModuleName);
        }
        else if(tTag == "g0t0")//G0T0
        {
            DoG0T0SpawnIn(pObject, sModuleName);
        }
        else if(tTag == "handmaiden")//Handmaiden
        {
            DoHandmaidenSpawnIn(pObject, sModuleName);
        }
        else if(tTag == "hanharr")//Hanharr
        {
            DoHanharrSpawnIn(pObject, sModuleName);
        }
        else if(tTag == "hk47")//HK-47
        {
            DoHK47SpawnIn(pObject, sModuleName);
        }
        else if(tTag == "kreia")//Kreia
        {
            DoKreiaSpawnIn(pObject, sModuleName);
        }
        else if(tTag == "mira")//Mira
        {
            DoMiraSpawnIn(pObject, sModuleName);
        }
        else if(tTag == "t3m4")//T3M4
        {
            DoT3M4SpawnIn(pObject, sModuleName);
        }
        else if(tTag == "visasmarr")//Visas Marr
        {
            DoVisasMarrSpawnIn(pObject, sModuleName);
        }
        else if(tTag == "remote")//the Remote is a special case
        {
            DoRemoteSpawnIn(pObject, sModuleName);
        }
        else
        {
            AurPostString("PARTY MEMBER SPAWNIN ERROR!",5,15,20.0);
        }
    }
}
void DoSpecialUserDefined(object pObject, int pUserEvent)
{
    if(GetIsObjectValid(pObject))
    {
        string tTag = GetTag(pObject);//should be a party member tag
        string sModuleName = GetModuleName();
        if(tTag == "atton")//Atton Rand
        {
            DoAttonUserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "baodur")//Bao-Dur
        {
            DoBaoDurUserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "mand")//Canderous
        {
            DoMandUserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "disciple")//Disciple
        {
            DoDiscipleUserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "g0t0")//G0T0
        {
            DoG0T0UserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "handmaiden")//Handmaiden
        {
            DoHandmaidenUserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "hanharr")//Hanharr
        {
            DoHanharrUserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "hk47")//HK-47
        {
            DoHK47UserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "kreia")//Kreia
        {
            DoKreiaUserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "mira")//Mira
        {
            DoMiraUserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "t3m4")//T3M4
        {
            DoT3M4UserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "visasmarr")//Visas Marr
        {
            DoVisasMarrUserDef(pObject, pUserEvent, sModuleName);
        }
        else if(tTag == "remote")//the Remote is a special case
        {
            DoRemoteUserDef(pObject, pUserEvent, sModuleName);
        }
    }
}
void DoAttonSpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    int In101PER = (sModuleName == "101PER"); // DJS-OEI 10/1/2004
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));//OPTIONAL BEHAVIOR - Fire User Defined Event 1011
        //AssignCommand(oPartyMember, ClearAllActions());
        AssignCommand(oPartyMember, ActionPlayAnimation(ANIMATION_LOOPING_SIT_CHAIR_COMP2, 1.0, -1.0));
        //set atton's facing
        vector vFacing = GetPositionFromLocation(GetLocation(GetObjectByTag("WP_atton_facing")));
        AssignCommand( OBJECT_SELF, SetFacingPoint(vFacing));
        SetLockOrientationInDialog(oPartyMember, TRUE);
        SetOrientOnClick(oPartyMember, FALSE);
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else if(In101PER){
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_PERCEPTION));
    }
    else
    {//default spawn in
    }
}
void DoBaoDurSpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));//OPTIONAL BEHAVIOR - Fire User Defined Event 1011
        object oBike = GetObjectByTag("WP_baodur_bike");
        if(GetIsObjectValid(oBike))
        {
            vector vBike = GetPositionFromLocation(GetLocation(oBike));
            AssignCommand(oPartyMember, SetFacingPoint(vBike));
            AssignCommand(oPartyMember, ActionPlayAnimation(ANIMATION_LOOPING_USE_COMPUTER, 1.0, -1.0));
        }
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void DoMandSpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void DoDiscipleSpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RANDOM));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_START_AT_NEAREST));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_PAUSE_RANDOM));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_USE_WAYPOINT_ANIMATION));
        AssignCommand(oPartyMember, SetLocalNumber(OBJECT_SELF, 29, ANIMATION_LOOPING_USE_COMPUTER));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));     //OPTIONAL BEHAVIOR - Fire User Defined Event 1011
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, FALSE));//turn waypoints on
        AssignCommand(oPartyMember, GN_WalkWayPoints());
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void DoG0T0SpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RANDOM));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_START_AT_NEAREST));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_PAUSE_LONG));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_USE_WAYPOINT_ANIMATION));
        AssignCommand(oPartyMember, SetLocalNumber(OBJECT_SELF, 29, ANIMATION_LOOPING_USE_COMPUTER));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));     //OPTIONAL BEHAVIOR - Fire User Defined Event 1011
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, FALSE));//turn waypoints on
        AssignCommand(oPartyMember, GN_WalkWayPoints());
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void DoHandmaidenSpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        // JAB-OEI 9/15/04
        AurPostString("k_oei_hench_inc handmaiden spawnin", 19,19,3.0);
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_COMBAT_ROUND_END));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));//OPTIONAL BEHAVIOR - Fire User Defined Event 1011
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void DoHanharrSpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_CIRCULAR));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_START_AT_NEAREST));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_PAUSE_SHORT));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_USE_WAYPOINT_ANIMATION));
        AssignCommand(oPartyMember, SetLocalNumber(OBJECT_SELF, 29, ANIMATION_LOOPING_PAUSE3));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));//OPTIONAL BEHAVIOR - Fire User Defined Event 1011
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, FALSE));//turn waypoints on
        AssignCommand(oPartyMember, GN_WalkWayPoints());
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void DoHK47SpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));//OPTIONAL BEHAVIOR - Fire User Defined Event 1011
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void DoKreiaSpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));//OPTIONAL BEHAVIOR - Fire User Defined Event 1011
        AssignCommand(oPartyMember, ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE, 1.0, -1.0));
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void DoMiraSpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void DoRemoteSpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    //SetMinOneHP(oPartyMember,TRUE);//Remote should never die.
    //Remote has its own faction. RWT-OEI 09/08/04
    ChangeToStandardFaction(oPartyMember, STANDARD_FACTION_PARTYPUPPET);
    //Remote has its own combat AI. RWT-OEI 09/08/04
    SetNPCAIStyle(oPartyMember, NPC_AISTYLE_PARTY_REMOTE);
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RANDOM));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_START_AT_NEAREST));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_PAUSE_SHORT));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_USE_WAYPOINT_ANIMATION));
        AssignCommand(oPartyMember, SetLocalNumber(OBJECT_SELF, 29, ANIMATION_LOOPING_USE_COMPUTER));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT));//OPTIONAL BEHAVIOR - Fire User Defined Event 1001
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));     //OPTIONAL BEHAVIOR - Fire User Defined Event 1011
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, FALSE));//turn waypoints on
        AssignCommand(oPartyMember, GN_WalkWayPoints());
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        //SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT));//OPTIONAL BEHAVIOR - Fire User Defined Event 1001
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));     //OPTIONAL BEHAVIOR - Fire User Defined Event 1011
    }
}
void DoT3M4SpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (!GetGlobalBoolean("003_cutscene_mode")) )
    {
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_WALK_RANDOM));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_START_AT_NEAREST));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_PAUSE_RANDOM));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_USE_WAYPOINT_ANIMATION));
        AssignCommand(oPartyMember, SetLocalNumber(OBJECT_SELF, 29, ANIMATION_LOOPING_WELD));
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));     //OPTIONAL BEHAVIOR - Fire User Defined Event 1011
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, FALSE));//turn waypoints on
        AssignCommand(oPartyMember, GN_WalkWayPoints());
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void DoVisasMarrSpawnIn(object oPartyMember, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DIALOGUE_END));//OPTIONAL BEHAVIOR - Fire User Defined Event 1011
        AssignCommand(oPartyMember, ActionPlayAnimation(ANIMATION_LOOPING_SIT_AND_MEDITATE, 1.0, -1.0));
    }
    else if(In711KOR)
    {
        GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_DAMAGED);
        SetMinOneHP(oPartyMember,TRUE);
    }
    else
    {//default spawn in
    }
}
void AttonBark( int nChoice ) {
    // DJS-OEI 10/22/2004
    // Don't bark if Atton is in party.
    if( IsObjectPartyMember( OBJECT_SELF ) ) {
        return;
    }
    // Don't bark anything if the player is in
    // another dialogue. If the player is using
    // the console at the time, the barks will
    // pop up on top of the interface.
    if( !GetIsConversationActive() ) {
        switch( nChoice ) {
            case 0:
                BarkString( OBJECT_SELF, 50084 );
                break;
            case 1:
                BarkString( OBJECT_SELF, 50083 );
                break;
            case 2:
                BarkString( OBJECT_SELF, 50086 );
                break;
            case 3:
                BarkString( OBJECT_SELF, 50085 );
                break;
            case 4:
                BarkString( OBJECT_SELF, 50082 );
                break;
        }
    }
}
void DoAttonUserDef(object oPartyMember, int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    int In101PER = (sModuleName == "101PER"); // DJS-OEI 10/1/2004
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if(In101PER) {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            {
                // Perform the wandering at the Comm Blister if appropriate.
                // DJS-OEI 10/22/2004
                // Don't do this if Atton is in party.
                //if(!GetLocalBoolean(OBJECT_SELF,58) && GetLocalBoolean(OBJECT_SELF,57))
                if( !GetLocalBoolean(OBJECT_SELF,58) &&
                    GetLocalBoolean(OBJECT_SELF,57) &&
                    !IsObjectPartyMember( OBJECT_SELF ) )
                {
                    //AurPostString("Atton Heartbeat",15,15,5.0);
                    SetLocalBoolean(OBJECT_SELF,58,TRUE);
                    ClearAllActions();
                    ActionWait(7.0);
                    ActionMoveToObject(GetObjectByTag("WP_ATTON_FUTZ1"));
                    ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0, 1.0);
                    ActionWait(5.0);
                    ActionMoveToObject(GetObjectByTag("WP_ATTON_FUTZ2"));
                    ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_BORED,1.0,1.0);
                    //ActionBarkString(50084); // Jedi Stuff
                    ActionDoCommand( AttonBark( 0 ) );
                    ActionWait(4.0);
                    ActionMoveToObject(GetObjectByTag("WP_ATTON_FUTZ1"));
                    ActionWait(4.0);
                    ActionMoveToObject(GetObjectByTag("WP_ATTON_FUTZ3"));
                    ActionPlayAnimation(ANIMATION_LOOPING_USE_COMPUTER,1.0,1.0);
                    ActionWait(1.0);
                    //ActionBarkString(50083); // stupid computer
                    ActionDoCommand( AttonBark( 1 ) );
                    ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD, 1.0, 1.0);
                    ActionWait(3.0);
                    ActionMoveToObject(GetObjectByTag("WP_ADMCON_ATTON"));
                    ActionWait(4.0);
                    //ActionBarkString(50086); // try something else
                    ActionDoCommand( AttonBark( 2 ) );
                    ActionPlayAnimation(ANIMATION_LOOPING_USE_COMPUTER,1.0,1.0);
                    ActionDoCommand(SetLocalBoolean(OBJECT_SELF,58,FALSE));
                }
            }break;
            case 1002://PERCEIVE
            {
                // DJS-OEI 10/22/2004
                // Don't do this if Atton is in party.
                //if(GetLocalBoolean(oPartyMember,57))
                if( GetLocalBoolean(oPartyMember,57) &&
                    !IsObjectPartyMember( OBJECT_SELF ) )
                {
                    object oSeen = GetLastPerceived();
                    if(GetIsPC(oSeen) && GetLastPerceptionSeen())
                    {
                        ClearAllActions();
                        ActionWait(3.0);
                        // check if we have been to the mines
                        if(GetGlobalNumber("103PER_Talk_HK50") > 0)
                        {
                            //ActionBarkString(50085);
                            ActionDoCommand( AttonBark( 3 ) );
                        }
                        else
                        {
                            // do other one
                            //ActionBarkString(50082);
                            ActionDoCommand( AttonBark( 4 ) );
                        }
                    }
                }
            }break;
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            {
                // Set the flag to disable Comm Blister wandering.
                SetLocalBoolean(oPartyMember,58,TRUE);
            }break;
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                // Set the flag to fire Comm Blister wandering.
                SetLocalBoolean(oPartyMember,58,FALSE);
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                //AssignCommand(oPartyMember, ClearAllActions());
                AssignCommand(oPartyMember, ActionPlayAnimation(ANIMATION_LOOPING_SIT_CHAIR_COMP2, 1.0, -1.0));
                //set atton's facing
                vector vFacing = GetPositionFromLocation(GetLocation(GetObjectByTag("WP_atton_facing")));
                AssignCommand( OBJECT_SELF, SetFacingPoint(vFacing));
                SetLockOrientationInDialog(oPartyMember, TRUE);
                SetOrientOnClick(oPartyMember, FALSE);
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoBaoDurUserDef(object oPartyMember, int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                object oBike = GetObjectByTag("WP_baodur_bike");
                if(GetIsObjectValid(oBike))
                {
                    location lBike = GetLocation(oBike);
                    vector vBike = GetPositionFromLocation(lBike);
                    AssignCommand(oPartyMember, SetFacingPoint(vBike));
                    AssignCommand(oPartyMember, ActionPlayAnimation(ANIMATION_LOOPING_USE_COMPUTER, 1.0, -1.0));
                }
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoMandUserDef(object oPartyMember, int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoDiscipleUserDef(object oPartyMember, int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                AssignCommand(oPartyMember, GN_WalkWayPoints());
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoG0T0UserDef(object oPartyMember,int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            {
            }break;
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            {
            }break;
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                AssignCommand(oPartyMember, GN_WalkWayPoints());
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoHandmaidenUserDef(object oPartyMember,int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            {
            } break;
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            {
                // BMA-OEI 9/24/2004
                if ( GetLocalBoolean(oPartyMember, 28) ) // Sparring with PC
                {
                    int nHP = GetCurrentHitPoints(GetFirstPC());
                    AurPostString("k_oei_hench_inc " + IntToString(nHP), 5, 5, 2.0);
                    if ( nHP == 1 ) // PC lost
                    {
                        AurPostString("Player has 1 hp, you lose!", 5, 5, 5.0);
                        SetLocalBoolean(oPartyMember, 28, FALSE);
                        SetLocalBoolean(oPartyMember, 26, TRUE);
                        SurrenderToEnemies();
                        CancelCombat(oPartyMember);
                        CancelCombat(GetFirstPC());
                        NoClicksFor(1.2);
                        ChangeToStandardFaction(oPartyMember, STANDARD_FACTION_NEUTRAL);
                        ExecuteScript("k_inc_handfight", oPartyMember, 1);
                    }
                }
            }break;
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            {
                AurPostString("Hand is hurt!", 7, 7, 1.0);
                if ( GetLocalBoolean(oPartyMember, 28) ) // Sparring with PC
                {
                    int nHP = GetCurrentHitPoints(oPartyMember);
                    AurPostString("k_oei_hench_inc " + IntToString(nHP), 8, 8, 2.0);
                    if ( nHP == 1 ) // Hand lost
                    {
                        AurPostString("Hand has 1 hp, you win!", 5, 5, 5.0);
                        SetLocalBoolean(oPartyMember, 28, FALSE);
                        SetLocalBoolean(oPartyMember, 29, TRUE);
                        SurrenderToEnemies();
                        CancelCombat(oPartyMember);
                        CancelCombat(GetFirstPC());
                        NoClicksFor(1.2);
                        ChangeToStandardFaction(oPartyMember, STANDARD_FACTION_NEUTRAL);
                        ExecuteScript("k_inc_handfight", oPartyMember, 0);
                    }
                }
            }break;
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                if( !GetLocalBoolean(oPartyMember, 29) )
                {
                    AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, FALSE));
                    AssignCommand(oPartyMember, GN_WalkWayPoints());
                }
                else
                {
                    AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, TRUE));
                }
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoHanharrUserDef(object oPartyMember,int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                if( !GetGlobalBoolean("003EBO_HANHARR_MOVE") )
                {
                    AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, FALSE));
                    AssignCommand(oPartyMember, GN_WalkWayPoints());
                }
                else
                {
                    AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, TRUE));
                }
                }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoHK47UserDef(object oPartyMember,int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoKreiaUserDef(object oPartyMember,int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                AssignCommand(oPartyMember, ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE, 1.0, -1.0));
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoMiraUserDef(object oPartyMember,int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoRemoteUserDef(object oPartyMember,int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            {
                if( GetGlobalBoolean("003EBO_REMOTE_MOVE") )
                {
                    object oRemoteCrySound = GetObjectByTag("remote_cry");
                    location lRemote = GetLocation(GetObjectByTag("remote"));
                    vector vRemotePosition = GetPositionFromLocation(lRemote);
                    SoundObjectSetPosition(oRemoteCrySound, vRemotePosition);
                    SoundObjectPlay(oRemoteCrySound);
                }
            }break;
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                if( !GetGlobalBoolean("003EBO_REMOTE_MOVE") )
                {
                    AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, FALSE));
                    AssignCommand(oPartyMember, GN_WalkWayPoints());
                    object oRemoteCrySound = GetObjectByTag("remote_cry");
                    if(GetIsObjectValid(oRemoteCrySound))
                    {
                        SoundObjectStop(oRemoteCrySound);
                    }
                    AssignCommand(oPartyMember, GN_WalkWayPoints());
                }
                else
                {
                    AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, TRUE));
                }
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else if(GetGlobalBoolean("003_cutscene_mode") == FALSE)
    {//default user def
        DoRemoteDefaultUserDef(oPartyMember, pUserEvent);
    }
}
void DoT3M4UserDef(object oPartyMember,int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (!GetGlobalBoolean("003_cutscene_mode")) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                if( !GetGlobalBoolean("003EBO_T3M4_MOVE") )
                {
                    AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, FALSE));
                    AssignCommand(oPartyMember, GN_WalkWayPoints());
                }
                else
                {
                    AssignCommand(oPartyMember, GN_SetSpawnInCondition(SW_FLAG_WAYPOINT_DEACTIVATE, TRUE));
                }
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
}
void DoVisasMarrUserDef(object oPartyMember,int pUserEvent, string sModuleName)
{
    int In003EBO = (sModuleName == "003EBO");
    int In711KOR = (sModuleName == "711KOR");
    if(In711KOR)
    {
        Do711UserDef(oPartyMember, pUserEvent);
        return;
    }
    else if( In003EBO && (GetGlobalBoolean("003_cutscene_mode") == FALSE) )
    {
        switch(pUserEvent)
        {
            case 1001://HEARTBEAT
            case 1002://PERCEIVE
            case 1003://END OF COMBAT
            case 1004://ON DIALOGUE
            case 1005://ATTACKED
            case 1006://DAMAGED
            case 1007://DEATH
            case 1008://DISTURBED
            case 1009://BLOCKED
            case 1010://SPELL CAST AT
            {
            }break;
            case 1011://DIALOGUE END
            {
                AssignCommand(oPartyMember, ActionPlayAnimation(ANIMATION_LOOPING_SIT_AND_MEDITATE, 1.0, -1.0));
            }break;
            case 1100://HOSTILE RETREAT
            {
                AssignCommand(oPartyMember, UT_ReturnToBase());
            }break;
            default:
            {
            }break;
        }
    }
    else
    {//default user def
    }
}
void DoRemoteDefaultUserDef(object oPartyMember,int pUserEvent)
{
    switch(pUserEvent)
    {
        case 1001://HEARTBEAT
        {
         //Note that I'm using SW_NUMBER_COOLDOWN to store the counter for the number of heartbeats the puppet
         //has been more than 10 meters from their owner. If we decide to give this thing an healerAI, we'll
         //need to make new LocalNumbers available as to not overwrite the healerAI parameters.
            float fHeartBeatRate = 2.0f;//Rate at which we requeue heartbeats
            if ( !GetIsPuppet() )
            {//If it is not a party puppet, do nothing
                //AurPostString( "I am not a puppet.", 10, 15, 5.0f );
                return;//This is not an error condition.
            }
            //The first priority is to be within 5 meters of our owner. So check to see that that is the case first.
            object oOwner = GetPUPOwner();
            if ( !GetIsObjectValid(oOwner ))
            {   //It IS a critical error for a party puppet to not have an owner
                AurPostString( "oei_hench::DoRemoteDefaultUserDef - Puppet has no owner. Major error.", 10, 25, 30.0f);
                return;
            }
            int nThreshold = 0;
            if ( GetLocalNumber(OBJECT_SELF, SW_NUMBER_HEALERAI_THRESHOLD ) )
            {
                nThreshold = 90;
            }
            object oHealDroid = OBJECT_INVALID;
            //Before the distance check, look for damaged party droids
            //We don't want to heal if we're in combat, since then healing is
            //being handled by our Combat AI.
            //Don't run the healing AI if owner is unconcious.
            if ( nThreshold > 0  && !GetIsInCombat(oOwner) && (GetCurrentHitPoints(oOwner) > 0))
            {
                //Check to see if any of the party member droids are damaged.
                //AurPostString( "Checking need to heal.", 20, 20, 4.0f );
                int i = 0;
                for (i = 0; i < 3; ++i )
                {
                    object oMember = GetPartyMemberByIndex(i);
                    if ( GetIsObjectValid(oMember) )
                    {
                        if ( GetRacialType(oMember) == RACIAL_TYPE_DROID )
                        {
                            int nCurrentHP = GetCurrentHitPoints(oMember);
                            int nMaxHP = GetMaxHitPoints(oMember);
                            int nPercentage = (nCurrentHP * 100) / nMaxHP;
                            if ( nPercentage < nThreshold && nCurrentHP > 0 )
                            {
                                //AurPostString( "Found wounded droid in party:" + IntToString(nPercentage) + "/" + IntToString( nThreshold ), 20, 21, 4.0f );
                                //Make sure they're within 10 meters.
                                //TODO: Enable this check once we're confident in the rest.
        //                        if ( GetDistanceToObject2D(oMember) <= 10.0f )
        //                        {
                                    //AurPostString( "Setting ohealdroid to:" + GetTag(oMember),20,24,4.0f );
                                    oHealDroid = oMember;
                                    //break;
        //                        }
                            }
                        }
                    }
                }
                //AurPostString( "Damaged droid is: " + GetTag(oHealDroid), 20, 25, 4.0f );
                if ( GetIsObjectValid(oHealDroid) )
                {
                    ClearAllActions();
                    //AurPostString( "Attempting to heal.", 20, 22, 4.0f );
                    //If we get here, then we have a valid droid in the party that
                    //is in need of healing. Go ahead and take care of it.
                    int nHealAmount = GetLocalNumber(OBJECT_SELF, SW_NUMBER_HEALERAI_PERCENTAGE);
                    if ( nHealAmount < 1 )
                    {
                        nHealAmount = 10;
                    }
                    //Face the right direction
                    SetFacingPoint(GetPosition(oHealDroid));
                    int nCurrentHP = GetCurrentHitPoints(oHealDroid);
                    int nMaxHP = GetMaxHitPoints(oHealDroid);
                    //Don't heal over 100% health.
                    if ( (nMaxHP - nCurrentHP ) < nHealAmount )
                    {
                        nHealAmount = nMaxHP - nCurrentHP;
                    }
                    effect eHeal = EffectHeal( nHealAmount );
                    ApplyEffectToObject( DURATION_TYPE_INSTANT, eHeal, oHealDroid);
                    effect eBeam = EffectBeam( VFX_BEAM_STUN_RAY, OBJECT_SELF, BODY_NODE_HAND);
                    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eBeam, oHealDroid, 1.0f );
                    effect eHealField = EffectVisualEffect( 1048 );
                    ApplyEffectToObject( DURATION_TYPE_TEMPORARY, eHealField, oHealDroid, 3.0f );
                    //Jump out now as this was our action for this round.
                    return;
                }
            }
            float fDistance = GetDistanceBetween2D( OBJECT_SELF, oOwner );
            //If we are more than 10.0 meters away for 10 heartbeats, we may need to just give up and teleport ourself
            if ( fDistance >= 10.0f )
            {
                int nCounter = GetLocalNumber(OBJECT_SELF, SW_NUMBER_COOLDOWN);
                if ( nCounter >= 7 )
                {//We have been more than 10 meters away for 7 heartbeats, just teleport to the owner.
                    AurPostString( "Attempting to teleport.", 10, 16, 1.5f );
                    ClearAllActions();
                    ActionJumpToLocation(GetLocation(oOwner));
                    SetLocalNumber(OBJECT_SELF, SW_NUMBER_COOLDOWN, 0);
                    DelayCommand( fHeartBeatRate, ForceHeartbeat(OBJECT_SELF) );
                    return;
                }
                else
                {//Otherwise we have been more than 10 meters away for less than 10 HBs. So just increase the counter
                    //AurPostString( "Increasing counter.", 10, 17, 1.5f );
                    ++nCounter;
                    SetLocalNumber(OBJECT_SELF, SW_NUMBER_COOLDOWN, nCounter);
                }
            }
            else
            {//Make sure to reset the counter
                SetLocalNumber(OBJECT_SELF, SW_NUMBER_COOLDOWN, 0);
            }
            //If we get here, we're between 2 and 10 meters, or over 10 meters
            //but not for more than 10 heartbeat updates. Try to move normally to owner.
            if ( fDistance > 2.0f  )
            {
                //AurPostString( "I need to move closer.", 10, 18, 1.5f );
                //We are more than 5 meters apart. We need to move closer
                int nActionID = GetCurrentAction(OBJECT_SELF);
                if ( (nActionID != ACTION_MOVETOPOINT) &&   (nActionID != ACTION_FOLLOWOWNER) )
                {//If we're already moving, finish moving. This may end up being a problem. We'll see.
                    //AurPostString( "Queueing new move action.", 10, 19, 5.0f );
                    ClearAllActions();
                    ActionFollowOwner(2.0);
                    DelayCommand(fHeartBeatRate, ForceHeartbeat(OBJECT_SELF));
                    return;
                }
            }
        }break;
        case 1002://PERCEIVE
        case 1003://END OF COMBAT
        case 1004://ON DIALOGUE
        case 1005://ATTACKED
        case 1006://DAMAGED
        case 1007://DEATH
        case 1008://DISTURBED
        case 1009://BLOCKED
        case 1010://SPELL CAST AT
        {
        }break;
        case 1011://DIALOGUE END
        {
        }break;
        case 1100://HOSTILE RETREAT
        {
            AssignCommand(oPartyMember, UT_ReturnToBase());
        }break;
        default:
        {
        }break;
    }
}
// we need to check if we take damage, and if we do, we need to delete ourselves
void Do711UserDef(object oPartyMember,int pUserEvent)
{
    switch(pUserEvent)
    {
        case 1006://DAMAGED
        {
            // update global variable keeping track of stuff
            int nDead = GetGlobalNumber("711KOR_Party_Dead");
            AurPostString("k_oei_hench_inc: Party Hit: "+IntToString(nDead),10,15,10.0);
            nDead++;
            AurPostString("k_oei_hench_inc: Num Dead: "+IntToString(nDead),10,16,10.0);
            SetGlobalNumber("711KOR_Party_Dead",nDead);
            SetMinOneHP(oPartyMember,FALSE);
            if(nDead >= GetGlobalNumber("711KOR_Party_Count"))
            {
                // we need to clean up this fight
                AurPostString("k_oei_hench_inc: Clean Up",10,10,10.0);
                SignalEvent(GetArea(GetFirstPC()),EventUserDefined(1));
            }
            //DelayCommand(1.0,DestroyObject(oPartyMember));
            DestroyObject(oPartyMember);
        }break;
        default:
        {
            AurPostString("k_oei_hench_inc: ERROR",10,18,20.0);
        }break;
    }
}
""",
}
