Added henchman rental
Many areas, items, and creatures were adjusted for balance and aesthetics.
This commit is contained in:
654
_module/nss/hench_i0_generic.nss
Normal file
654
_module/nss/hench_i0_generic.nss
Normal file
@@ -0,0 +1,654 @@
|
||||
/*
|
||||
|
||||
Henchman Inventory And Battle AI
|
||||
|
||||
This file contains miscellaneous functions used by
|
||||
many scripts.
|
||||
|
||||
*/
|
||||
|
||||
// void main() { }
|
||||
|
||||
#include "nw_i0_generic"
|
||||
#include "x0_i0_voice"
|
||||
#include "hench_i0_strings"
|
||||
#include "hench_i0_options"
|
||||
#include "hench_i0_conv"
|
||||
|
||||
|
||||
|
||||
// This constant somewhat matches taking a henchmen hit dice and converting to CR rating
|
||||
const float HENCH_HITDICE_TO_CR = 0.7;
|
||||
|
||||
// general effects on self
|
||||
const int HENCH_HAS_ETHEREAL_EFFECT = 0x001;
|
||||
const int HENCH_HAS_CONCEALMENT_EFFECT = 0x002;
|
||||
const int HENCH_HAS_INVISIBILITY_EFFECT = 0x004;
|
||||
const int HENCH_HAS_SANTUARY_EFFECT = 0x008;
|
||||
const int HENCH_HAS_DAZED_EFFECT = 0x010;
|
||||
const int HENCH_HAS_CONFUSED_EFFECT = 0x020;
|
||||
const int HENCH_HAS_CHARMED_EFFECT = 0x040;
|
||||
const int HENCH_HAS_POLYMORPH_EFFECT = 0x080;
|
||||
const int HENCH_HAS_HASTE_EFFECT = 0x100;
|
||||
const int HENCH_HAS_TIMESTOP_EFFECT = 0x200;
|
||||
|
||||
|
||||
const string sHenchSummonedFamiliar = "HenchSummonedFamiliar";
|
||||
const string sHenchSummonedAniComp = "HenchSummonedAniComp";
|
||||
const string sHenchPseudoSummon = "HenchPseudoSummon";
|
||||
|
||||
|
||||
const string sHenchDontAttackFlag = "DoNotAttack";
|
||||
const string sHenchScoutingFlag = "Scouting";
|
||||
const string sHenchScoutTarget = "ScoutTarget";
|
||||
const string sHenchRunningAway = "RunningAway";
|
||||
|
||||
|
||||
const int HENCH_HEAL_SELF_UNKNOWN = 0;
|
||||
const int HENCH_HEAL_SELF_CANT = 1;
|
||||
const int HENCH_HEAL_SELF_WAIT = 2;
|
||||
const int HENCH_HEAL_SELF_IN_PROG = 3;
|
||||
const string HENCH_HEAL_SELF_STATE = "HenchHealSelfState";
|
||||
|
||||
|
||||
// As MyPrintString, but to screen instead of log
|
||||
void Jug_Debug(string sString);
|
||||
|
||||
// returns TRUE if any one of the two effect types are present
|
||||
int GetHasAnyEffect2(int nEffectType1, int nEffectType2, object oTarget = OBJECT_SELF);
|
||||
|
||||
// returns TRUE if the target is disabled
|
||||
int GetIsDisabled(object oTarget);
|
||||
|
||||
// returns TRUE if the target is disabled or has another effect
|
||||
int GetIsDisabled1(int nOtherEffect, object oTarget);
|
||||
|
||||
// returns TRUE if the target is disabled or has another effect
|
||||
int GetIsDisabled2(int nOtherEffect1, int nOtherEffect2, object oTarget);
|
||||
|
||||
// returns TRUE if racial type is a humanoid
|
||||
int GetIsHumanoid(int nRacial);
|
||||
|
||||
// returns TRUE if creature can use items from their inventory
|
||||
int GetCreatureUseItems(object oCreature);
|
||||
|
||||
// returns TRUE if the item property is present in any one of the equipped items
|
||||
int GetCreatureHasItemProperty(int nItemProperty, object oCreature = OBJECT_SELF);
|
||||
|
||||
// set array access for objects
|
||||
void SetObjectArray(object oSource, string sName, int iElem, object oElem);
|
||||
|
||||
// get array access for objects
|
||||
object GetObjectArray(object oSource, string sName, int iElem);
|
||||
|
||||
// set array access for ints
|
||||
void SetIntArray(object oSource, string sName, int iElem, int iState);
|
||||
|
||||
// get array access for ints
|
||||
int GetIntArray(object oSource, string sName, int iElem);
|
||||
|
||||
// set array access for floats
|
||||
void SetFloatArray(object oSource, string sName, int iElem, float fVal);
|
||||
|
||||
// get array access for floats
|
||||
float GetFloatArray(object oSource, string sName, int iElem);
|
||||
|
||||
// returns TRUE if object1 and object are on opposite sides of door
|
||||
int IsOnOppositeSideOfDoor(object oDoor, object obj1, object obj2);
|
||||
|
||||
// stores the last spell cast (no timeout)
|
||||
void HenchSetLastGenericSpellCast(int nSpell);
|
||||
|
||||
// returns the highest level master of oAssociate
|
||||
// returns OBJECT_INVALID if no master
|
||||
object GetRealMaster(object oAssociate = OBJECT_SELF);
|
||||
|
||||
// returns the highest level master of oAssociate
|
||||
// returns OBJECT_SELF if no master
|
||||
object GetTopMaster(object oAssociate = OBJECT_SELF);
|
||||
|
||||
// converts a prestige class into the best matching primary class
|
||||
int HenchConvertClass(int nClass, object oCharacter);
|
||||
|
||||
// returns the class type that best represents oCharacter
|
||||
int HenchDetermineClassToUse(object oCharacter = OBJECT_SELF);
|
||||
|
||||
// Cleans all temporary values used during combat
|
||||
void CleanCombatVars();
|
||||
|
||||
|
||||
|
||||
// As MyPrintString, but to screen instead of log
|
||||
void Jug_Debug(string sString)
|
||||
{
|
||||
SendMessageToPC(GetFirstPC(), sString);
|
||||
}
|
||||
|
||||
|
||||
int GetHasAnyEffect2(int nEffectType1, int nEffectType2, object oTarget = OBJECT_SELF)
|
||||
{
|
||||
effect eCheck = GetFirstEffect(oTarget);
|
||||
while(GetIsEffectValid(eCheck))
|
||||
{
|
||||
int nTestEffect = GetEffectType(eCheck);
|
||||
if(nTestEffect == nEffectType1)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if(nTestEffect == nEffectType2)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
eCheck = GetNextEffect(oTarget);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int GetIsDisabled(object oTarget)
|
||||
{
|
||||
effect eCheck = GetFirstEffect(oTarget);
|
||||
while(GetIsEffectValid(eCheck))
|
||||
{
|
||||
switch (GetEffectType(eCheck))
|
||||
{
|
||||
case EFFECT_TYPE_PARALYZE:
|
||||
case EFFECT_TYPE_STUNNED:
|
||||
case EFFECT_TYPE_FRIGHTENED:
|
||||
case EFFECT_TYPE_SLEEP:
|
||||
case EFFECT_TYPE_DAZED:
|
||||
case EFFECT_TYPE_CONFUSED:
|
||||
case EFFECT_TYPE_TURNED:
|
||||
case EFFECT_TYPE_PETRIFY:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
eCheck = GetNextEffect(oTarget);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int GetIsDisabled1(int nOtherEffect, object oTarget)
|
||||
{
|
||||
effect eCheck = GetFirstEffect(oTarget);
|
||||
while(GetIsEffectValid(eCheck))
|
||||
{
|
||||
int nTestEffect = GetEffectType(eCheck);
|
||||
switch (nTestEffect)
|
||||
{
|
||||
case EFFECT_TYPE_PARALYZE:
|
||||
case EFFECT_TYPE_STUNNED:
|
||||
case EFFECT_TYPE_FRIGHTENED:
|
||||
case EFFECT_TYPE_SLEEP:
|
||||
case EFFECT_TYPE_DAZED:
|
||||
case EFFECT_TYPE_CONFUSED:
|
||||
case EFFECT_TYPE_TURNED:
|
||||
case EFFECT_TYPE_PETRIFY:
|
||||
return TRUE;
|
||||
}
|
||||
if (nTestEffect == nOtherEffect)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
eCheck = GetNextEffect(oTarget);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int GetIsDisabled2(int nOtherEffect1, int nOtherEffect2, object oTarget)
|
||||
{
|
||||
effect eCheck = GetFirstEffect(oTarget);
|
||||
while(GetIsEffectValid(eCheck))
|
||||
{
|
||||
int nTestEffect = GetEffectType(eCheck);
|
||||
switch (nTestEffect)
|
||||
{
|
||||
case EFFECT_TYPE_PARALYZE:
|
||||
case EFFECT_TYPE_STUNNED:
|
||||
case EFFECT_TYPE_FRIGHTENED:
|
||||
case EFFECT_TYPE_SLEEP:
|
||||
case EFFECT_TYPE_DAZED:
|
||||
case EFFECT_TYPE_CONFUSED:
|
||||
case EFFECT_TYPE_TURNED:
|
||||
case EFFECT_TYPE_PETRIFY:
|
||||
return TRUE;
|
||||
}
|
||||
if (nTestEffect == nOtherEffect1)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (nTestEffect == nOtherEffect2)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
eCheck = GetNextEffect(oTarget);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int GetIsHumanoid(int nRacial)
|
||||
{
|
||||
return
|
||||
(nRacial == RACIAL_TYPE_DWARF) ||
|
||||
(nRacial == RACIAL_TYPE_ELF) ||
|
||||
(nRacial == RACIAL_TYPE_GNOME) ||
|
||||
(nRacial == RACIAL_TYPE_HUMANOID_GOBLINOID) ||
|
||||
(nRacial == RACIAL_TYPE_HALFLING) ||
|
||||
(nRacial == RACIAL_TYPE_HUMAN) ||
|
||||
(nRacial == RACIAL_TYPE_HALFELF) ||
|
||||
(nRacial == RACIAL_TYPE_HALFORC) ||
|
||||
(nRacial == RACIAL_TYPE_HUMANOID_MONSTROUS) ||
|
||||
(nRacial == RACIAL_TYPE_HUMANOID_ORC) ||
|
||||
(nRacial == RACIAL_TYPE_HUMANOID_REPTILIAN);
|
||||
}
|
||||
|
||||
|
||||
int GetCreatureUseItems(object oCreature)
|
||||
{
|
||||
if (GetIsPlayableRacialType(oCreature))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
int nRace = GetRacialType(oCreature);
|
||||
if ((nRace >= RACIAL_TYPE_HUMANOID_GOBLINOID && nRace <= RACIAL_TYPE_HUMANOID_REPTILIAN) ||
|
||||
nRace == RACIAL_TYPE_FEY || nRace == RACIAL_TYPE_GIANT)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
int nAppearanceType = GetAppearanceType(oCreature);
|
||||
if (nRace == RACIAL_TYPE_UNDEAD)
|
||||
{
|
||||
return nAppearanceType != APPEARANCE_TYPE_DRACOLICH &&
|
||||
nAppearanceType != APPEARANCE_TYPE_SKELETAL_DEVOURER &&
|
||||
nAppearanceType != APPEARANCE_TYPE_ALLIP;
|
||||
}
|
||||
if (nAppearanceType >= APPEARANCE_TYPE_DWARF && nAppearanceType <= APPEARANCE_TYPE_HUMAN)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (nRace == RACIAL_TYPE_ABERRATION)
|
||||
{
|
||||
return nAppearanceType == APPEARANCE_TYPE_MINDFLAYER ||
|
||||
nAppearanceType == APPEARANCE_TYPE_MINDFLAYER_2 ||
|
||||
nAppearanceType == APPEARANCE_TYPE_MINDFLAYER_ALHOON ||
|
||||
nAppearanceType == APPEARANCE_TYPE_DRIDER ||
|
||||
nAppearanceType == APPEARANCE_TYPE_DRIDER_CHIEF ||
|
||||
nAppearanceType == APPEARANCE_TYPE_DRIDER_FEMALE ||
|
||||
GetCreatureUseItemsOverride(oCreature);
|
||||
}
|
||||
if (nRace == RACIAL_TYPE_OUTSIDER)
|
||||
{
|
||||
return nAppearanceType == APPEARANCE_TYPE_SUCCUBUS ||
|
||||
nAppearanceType == APPEARANCE_TYPE_AZER_MALE ||
|
||||
nAppearanceType == APPEARANCE_TYPE_AZER_FEMALE ||
|
||||
nAppearanceType == APPEARANCE_TYPE_RAKSHASA_TIGER_FEMALE ||
|
||||
nAppearanceType == APPEARANCE_TYPE_RAKSHASA_TIGER_FEMALE ||
|
||||
GetCreatureUseItemsOverride(oCreature);
|
||||
}
|
||||
return GetCreatureUseItemsOverride(oCreature);
|
||||
}
|
||||
|
||||
|
||||
int GetCreatureHasItemProperty(int nItemProperty, object oCreature = OBJECT_SELF)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < NUM_INVENTORY_SLOTS; i++)
|
||||
{
|
||||
object oItem = GetItemInSlot(i, oCreature);
|
||||
if(GetItemHasItemProperty(oItem, nItemProperty))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void SetObjectArray(object oSource, string sName, int iElem, object oElem)
|
||||
{
|
||||
string sFull = sName+IntToString(iElem);
|
||||
SetLocalObject(oSource,sFull,oElem);
|
||||
}
|
||||
|
||||
object GetObjectArray(object oSource, string sName, int iElem)
|
||||
{
|
||||
string sFull = sName+IntToString(iElem);
|
||||
return GetLocalObject(oSource,sFull);
|
||||
}
|
||||
|
||||
void SetIntArray(object oSource, string sName, int iElem, int iState)
|
||||
{
|
||||
string sFull = sName+IntToString(iElem);
|
||||
SetLocalInt(oSource,sFull,iState);
|
||||
}
|
||||
|
||||
int GetIntArray(object oSource, string sName, int iElem)
|
||||
{
|
||||
string sFull = sName+IntToString(iElem);
|
||||
return GetLocalInt(oSource,sFull);
|
||||
}
|
||||
|
||||
void SetFloatArray(object oSource, string sName, int iElem, float fVal)
|
||||
{
|
||||
string sFull = sName+IntToString(iElem);
|
||||
SetLocalFloat(oSource,sFull,fVal);
|
||||
}
|
||||
|
||||
float GetFloatArray(object oSource, string sName, int iElem)
|
||||
{
|
||||
string sFull = sName+IntToString(iElem);
|
||||
return GetLocalFloat(oSource,sFull);
|
||||
}
|
||||
|
||||
int IsOnOppositeSideOfDoor(object oDoor, object obj1, object obj2)
|
||||
{
|
||||
float fDoorAngle = GetFacing(oDoor);
|
||||
|
||||
vector vDoor = GetPositionFromLocation(GetLocation(oDoor));
|
||||
vector v1 = GetPositionFromLocation(GetLocation(obj1));
|
||||
vector v2 = GetPositionFromLocation(GetLocation(obj2));
|
||||
|
||||
float fAngle1 = VectorToAngle(v1 - vDoor);
|
||||
float fAngle2 = VectorToAngle(v2 - vDoor);
|
||||
|
||||
fAngle1 -= fDoorAngle;
|
||||
fAngle2 -= fDoorAngle;
|
||||
if (fAngle1 < 0.0)
|
||||
{
|
||||
fAngle1 += 360.0;
|
||||
}
|
||||
if (fAngle2 < 0.0)
|
||||
{
|
||||
fAngle2 += 360.0;
|
||||
}
|
||||
|
||||
int bSide1 = fAngle1 < 90.0 || fAngle1 > 270.0;
|
||||
int bSide2 = fAngle2 < 90.0 || fAngle2 > 270.0;
|
||||
|
||||
return bSide1 != bSide2;
|
||||
}
|
||||
|
||||
|
||||
void HenchSetLastGenericSpellCast(int nSpell)
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, "NW_GENERIC_LAST_SPELL", nSpell);
|
||||
}
|
||||
|
||||
|
||||
//69MEH69 GetRealMaster Code
|
||||
object GetRealMaster(object oAssociate = OBJECT_SELF)
|
||||
{
|
||||
object oMaster = GetMaster(oAssociate);
|
||||
if (GetIsObjectValid(oMaster))
|
||||
{
|
||||
while (GetIsObjectValid(GetMaster(oMaster)))
|
||||
{
|
||||
oMaster = GetMaster(oMaster);
|
||||
}
|
||||
}
|
||||
return oMaster;
|
||||
}
|
||||
|
||||
|
||||
object GetTopMaster(object oAssociate = OBJECT_SELF)
|
||||
{
|
||||
object oRetVal = oAssociate;
|
||||
object oMaster = GetMaster(oAssociate);
|
||||
while (GetIsObjectValid(oMaster))
|
||||
{
|
||||
oRetVal = oMaster;
|
||||
oMaster = GetMaster(oMaster);
|
||||
}
|
||||
return oRetVal;
|
||||
}
|
||||
|
||||
|
||||
object GetTopAssociate(object oAssociate = OBJECT_SELF)
|
||||
{
|
||||
object oRetVal = oAssociate;
|
||||
object oMaster = GetMaster(oAssociate);
|
||||
if (GetIsObjectValid(oMaster))
|
||||
{
|
||||
while (GetIsObjectValid(GetMaster(oMaster)))
|
||||
{
|
||||
oRetVal = oMaster;
|
||||
oMaster = GetMaster(oMaster);
|
||||
}
|
||||
}
|
||||
return oRetVal;
|
||||
}
|
||||
|
||||
|
||||
int HenchConvertClass(int nClass, object oCharacter)
|
||||
{
|
||||
switch(nClass)
|
||||
{
|
||||
case CLASS_TYPE_SHADOWDANCER:
|
||||
case CLASS_TYPE_ASSASSIN:
|
||||
return CLASS_TYPE_ROGUE;
|
||||
case CLASS_TYPE_HARPER:
|
||||
case CLASS_TYPE_ARCANE_ARCHER:
|
||||
case CLASS_TYPE_DRAGON_DISCIPLE:
|
||||
return CLASS_TYPE_BARD;
|
||||
case CLASS_TYPE_SHIFTER:
|
||||
return CLASS_TYPE_DRUID;
|
||||
case CLASS_TYPE_PALE_MASTER:
|
||||
return GetClassByPosition(1, oCharacter);
|
||||
}
|
||||
return nClass;
|
||||
}
|
||||
|
||||
|
||||
int HenchDetermineClassToUse(object oCharacter = OBJECT_SELF)
|
||||
{
|
||||
int nClass;
|
||||
int nTotal = GetHitDice(oCharacter);
|
||||
if (nTotal < 1)
|
||||
{
|
||||
nTotal = 1;
|
||||
}
|
||||
|
||||
int nClassLevel1 = GetLevelByPosition(1, oCharacter);
|
||||
int nClass1 = GetClassByPosition(1, oCharacter);
|
||||
// quick exit
|
||||
if (nClassLevel1 >= nTotal)
|
||||
{
|
||||
return nClass1;
|
||||
}
|
||||
|
||||
int nClassLevel2 = GetLevelByPosition(2, oCharacter);
|
||||
int nClass2 = GetClassByPosition(2, oCharacter);
|
||||
int nClassLevel3 = GetLevelByPosition(3, oCharacter);
|
||||
int nClass3 = GetClassByPosition(3, oCharacter);
|
||||
|
||||
// blackguard over everthing else
|
||||
if (nClass1 == CLASS_TYPE_BLACKGUARD || nClass2 == CLASS_TYPE_BLACKGUARD ||
|
||||
nClass3 == CLASS_TYPE_BLACKGUARD)
|
||||
{
|
||||
return CLASS_TYPE_BLACKGUARD;
|
||||
}
|
||||
if (nClass1 == CLASS_TYPE_DIVINE_CHAMPION || nClass2 == CLASS_TYPE_DIVINE_CHAMPION ||
|
||||
nClass3 == CLASS_TYPE_DIVINE_CHAMPION)
|
||||
{
|
||||
return CLASS_TYPE_DIVINE_CHAMPION;
|
||||
}
|
||||
if (nClass1 == CLASS_TYPE_WEAPON_MASTER || nClass2 == CLASS_TYPE_WEAPON_MASTER ||
|
||||
nClass3 == CLASS_TYPE_WEAPON_MASTER)
|
||||
{
|
||||
return CLASS_TYPE_WEAPON_MASTER;
|
||||
}
|
||||
if (nClass1 == CLASS_TYPE_DWARVEN_DEFENDER || nClass2 == CLASS_TYPE_DWARVEN_DEFENDER ||
|
||||
nClass3 == CLASS_TYPE_DWARVEN_DEFENDER)
|
||||
{
|
||||
return CLASS_TYPE_DWARVEN_DEFENDER;
|
||||
}
|
||||
// adjust classes to remove prestige
|
||||
nClass1 = HenchConvertClass(nClass1, oCharacter);
|
||||
nClass2 = HenchConvertClass(nClass2, oCharacter);
|
||||
nClass3 = HenchConvertClass(nClass3, oCharacter);
|
||||
if (nClass1 == nClass2)
|
||||
{
|
||||
nClassLevel1 += nClassLevel2;
|
||||
nClassLevel2 = 0;
|
||||
}
|
||||
if (nClass1 == nClass3)
|
||||
{
|
||||
nClassLevel1 += nClassLevel3;
|
||||
nClassLevel3 = 0;
|
||||
}
|
||||
if (nClass2 == nClass3)
|
||||
{
|
||||
nClassLevel2 += nClassLevel3;
|
||||
nClassLevel3 = 0;
|
||||
}
|
||||
// find top class
|
||||
int nMaxClassLevel = nClassLevel1 >= nClassLevel2 ? nClassLevel1 : nClassLevel2;
|
||||
nMaxClassLevel = nMaxClassLevel >= nClassLevel3 ? nMaxClassLevel : nClassLevel3;
|
||||
// filter out classes less than two levels below the max
|
||||
if (nMaxClassLevel - 1 > nClassLevel1)
|
||||
{
|
||||
nClassLevel1 = 0;
|
||||
}
|
||||
if (nMaxClassLevel - 1 > nClassLevel2)
|
||||
{
|
||||
nClassLevel2 = 0;
|
||||
}
|
||||
if (nMaxClassLevel - 1 > nClassLevel3)
|
||||
{
|
||||
nClassLevel3 = 0;
|
||||
}
|
||||
nTotal = nClassLevel1 + nClassLevel2 + nClassLevel3;
|
||||
int nPickClass = Random(nTotal);
|
||||
nPickClass -= nClassLevel1;
|
||||
if (nPickClass < 0)
|
||||
{
|
||||
return nClass1;
|
||||
}
|
||||
nPickClass -= nClassLevel2;
|
||||
if (nPickClass < 0)
|
||||
{
|
||||
return nClass2;
|
||||
}
|
||||
return nClass3;
|
||||
}
|
||||
|
||||
|
||||
int CheckStealth()
|
||||
{
|
||||
int nStealthCheck = GetLocalInt(OBJECT_SELF, "canStealth");
|
||||
if (nStealthCheck == 0)
|
||||
{
|
||||
nStealthCheck = ((GetSkillRank(SKILL_HIDE, OBJECT_SELF, TRUE) > 0) ||
|
||||
(GetSkillRank(SKILL_MOVE_SILENTLY, OBJECT_SELF, TRUE) > 0)) ? 1 : 2;
|
||||
SetLocalInt(OBJECT_SELF, "canStealth", nStealthCheck);
|
||||
}
|
||||
return nStealthCheck == 1;
|
||||
}
|
||||
|
||||
|
||||
void SetCombatMode(int nCombatMode = -1)
|
||||
{
|
||||
int index;
|
||||
for (index = ACTION_MODE_PARRY; index <= ACTION_MODE_DIRTY_FIGHTING; index ++)
|
||||
{
|
||||
int bEnable = nCombatMode == index;
|
||||
if (GetActionMode(OBJECT_SELF, index) != bEnable)
|
||||
{
|
||||
if (bEnable)
|
||||
{
|
||||
ActionDoCommand(SetActionMode(OBJECT_SELF, index, TRUE));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetActionMode(OBJECT_SELF, index, bEnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const string sHenchLastAttackLocation = "HENCH_LAST_ATTACK_LOC";
|
||||
|
||||
void UseCombatAttack(object oTarget, int nFeatID = -1, int nCombatMode = -1)
|
||||
{
|
||||
SetCombatMode(nCombatMode);
|
||||
if (nFeatID < 0)
|
||||
{
|
||||
ActionAttack(oTarget);
|
||||
}
|
||||
else
|
||||
{
|
||||
ActionUseFeat(nFeatID, oTarget);
|
||||
}
|
||||
SetLocalLocation(OBJECT_SELF, sHenchLastAttackLocation, GetLocation(OBJECT_SELF));
|
||||
//const string sHenchLastAttackLocation = "HENCH_LAST_ATTACK_LOC";
|
||||
|
||||
}
|
||||
|
||||
|
||||
const string henchCombatRoundStr = "tkCombatRoundCount";
|
||||
const string henchLastDraBrStr = "tkLastDragonBreath";
|
||||
const string henchLastDispelStr = "tkLastDispel";
|
||||
const string henchLastDomStr = "tkLastDominate";
|
||||
const string henchLastTurnStr = "tkLastTurning";
|
||||
const string henchSpellKnownFlagsStr = "HenchSpellKnownFlags";
|
||||
const string henchNoAttackSpStr = "tkNoAttackSpellTalents";
|
||||
const string henchNoEnhanceSpStr = "tkNoEnhanceSpellTalents";
|
||||
const string henchNoCondSpStr = "tkNoConditionalSpellTalents";
|
||||
const string henchNoPotionStr = "tkNoPotions";
|
||||
const string henchBuffCountStr = "HenchCurBuffCount";
|
||||
const string henchHealCountStr = "HenchCurHealCount";
|
||||
const string sHenchLastTarget = "LastTarget";
|
||||
const string sHenchShouldIAttackMessageGiven = "HenchShouldIAttackMessageGiven";
|
||||
|
||||
|
||||
const int HENCH_MAIN_SPELL_SERIES = 0x1;
|
||||
const int HENCH_CURE_COND_SPELL = 0x2;
|
||||
|
||||
int GetSpellUnknownFlag(int flag)
|
||||
{
|
||||
return GetLocalInt(OBJECT_SELF, henchSpellKnownFlagsStr) & flag;
|
||||
}
|
||||
|
||||
|
||||
void SetSpellUnknownFlag(int flag)
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF, henchSpellKnownFlagsStr, GetLocalInt(OBJECT_SELF, henchSpellKnownFlagsStr) | flag);
|
||||
}
|
||||
|
||||
|
||||
void CleanCombatVars()
|
||||
{
|
||||
DeleteLocalInt(OBJECT_SELF, henchCombatRoundStr);
|
||||
DeleteLocalInt(OBJECT_SELF, henchLastDraBrStr);
|
||||
DeleteLocalInt(OBJECT_SELF, henchLastDispelStr);
|
||||
DeleteLocalInt(OBJECT_SELF, henchLastDomStr);
|
||||
DeleteLocalInt(OBJECT_SELF, henchLastTurnStr);
|
||||
DeleteLocalInt(OBJECT_SELF, henchSpellKnownFlagsStr);
|
||||
DeleteLocalInt(OBJECT_SELF, henchNoAttackSpStr);
|
||||
DeleteLocalInt(OBJECT_SELF, henchNoEnhanceSpStr);
|
||||
DeleteLocalInt(OBJECT_SELF, henchNoCondSpStr);
|
||||
DeleteLocalInt(OBJECT_SELF, henchNoPotionStr);
|
||||
DeleteLocalInt(OBJECT_SELF, "CloseRangeEnhanced");
|
||||
DeleteLocalObject(OBJECT_SELF, sHenchLastTarget);
|
||||
DeleteLocalLocation(OBJECT_SELF, sHenchLastAttackLocation);
|
||||
DeleteLocalInt(OBJECT_SELF, sHenchShouldIAttackMessageGiven);
|
||||
}
|
||||
|
||||
|
||||
void ReportUnseenAllies()
|
||||
{
|
||||
location testTargetLoc = GetLocation(OBJECT_SELF);
|
||||
object oAllyTest = GetFirstObjectInShape(SHAPE_SPHERE, 20.0, testTargetLoc, TRUE, OBJECT_TYPE_CREATURE);
|
||||
while (GetIsObjectValid(oAllyTest))
|
||||
{
|
||||
if (!GetObjectSeen(oAllyTest) && GetIsPC(GetTopMaster(oAllyTest)))
|
||||
{
|
||||
SpeakString(sHenchCantSeeTarget + GetName(oAllyTest));
|
||||
}
|
||||
oAllyTest = GetNextObjectInShape(SHAPE_SPHERE, 20.0, testTargetLoc, TRUE, OBJECT_TYPE_CREATURE);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user