Rune_PRC8/_module/nss/oai_inc_eqweapon.nss
Jaysyn904 d1c309ae63 Initial commit
Initial commit
2024-09-13 09:10:39 -04:00

325 lines
7.6 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
//
// Olander's AI
// oai_inc_eqweapon
// by Don Anderson
// dandersonru@msn.com
//
// Equip Appropriate Weaopns
// Originally Bioware
//
////////////////////////////////////////////////////////////////////////////////
#include "opw_inc_weapons"
#include "x0_i0_enemy"
/******************************************************************************/
//:: FUNCTION PROTOTYPES
//Unequips Left and Right Hands
void OAI_UnequipWeapons();
// Equip the appropriate weapons to face the target.
void OAI_EquipAppropriateWeapons(int nClearActions=TRUE);
//Equip Ranged Weapon
int OAI_EquipRanged();
// * returns true if out of ammo of currently equipped weapons
int OAI_IsOutOfAmmo();
//Equips the Stored Right Handed Melee
int OAI_EquipRHMelee();
//Equips the Left Handed Weapon or Shield
int OAI_EquipLHMelee();
//Chooses Weapons For Melee/Dual/Shield and Ranged
void OAI_ChooseWeapons();
// * checks to see if oUser has ambidexteriy and two weapon fighting
int OAI_WiseToDualWield(object oUser);
//This is just a wrapper around ActionAttack
//To make sure the creature equips weapons
void OAI_WrapperActionAttack(object oTarget);
//:: FUNCTION PROTOTYPES
/******************************************************************************/
/******************************************************************************/
//:: FUNCTIONS
void OAI_UnequipWeapons()
{
//Now We Unequip Melee Weapons and Shields
object oLHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,OBJECT_SELF);
if(GetIsObjectValid(oLHand)) AssignCommand(OBJECT_SELF, ActionUnequipItem(oLHand));
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,OBJECT_SELF);
int nMelee = IsMeleeWeapon(oWeapon);
if(nMelee == TRUE) AssignCommand(OBJECT_SELF, ActionUnequipItem(oWeapon));
}
void OAI_EquipAppropriateWeapons(int nClearActions=TRUE)
{
object oSelf = OBJECT_SELF;
int nEmptyHanded = FALSE;
int nAlreadyClearedActions = FALSE;
//Set Up Weapons
int nHPW = GetLocalInt(oSelf,"OAI_HPW");
if(nHPW == FALSE)
{
OAI_ChooseWeapons();
SetLocalInt(oSelf,"OAI_HPW",TRUE);
}
object oRightHand = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND);
object oLeftHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND);
object oGloves = GetItemInSlot(INVENTORY_SLOT_ARMS);
if(!GetIsObjectValid(oRightHand)) nEmptyHanded = TRUE;
//Determine Enemy Distance
object oEnemy = GetLocalObject(OBJECT_SELF,"OAI_ATTACK_TARGET");
if(!GetIsObjectValid(oEnemy)) oEnemy = GetNearestPerceivedEnemy();
float fDist = GetDistanceBetween(OBJECT_SELF, oEnemy);
//Ranged Attack
int nIsWieldingRanged = FALSE;
nIsWieldingRanged = IsRangedWeapon(oRightHand);
//Not Wielding a Ranged Weapon and At Ranged Distance
if(!nIsWieldingRanged && fDist > 5.0)
{
if(nClearActions && !nAlreadyClearedActions)
{
ClearAllActions();
nAlreadyClearedActions = TRUE;
}
//Equip a Ranged
if(OAI_EquipRanged() && !OAI_IsOutOfAmmo()) return;
}
//Not Wielding a Ranged Weapon and At Melee Distance
else if(!nIsWieldingRanged && fDist <= 5.0)
{
//Point Blank Shot Feat
int nPBS = FALSE;
if(GetHasFeat(FEAT_POINT_BLANK_SHOT) == TRUE)
{
nPBS = TRUE;
}
//Close Ranged Combat
if(nPBS == TRUE)
{
if(nClearActions && !nAlreadyClearedActions)
{
ClearAllActions();
nAlreadyClearedActions = TRUE;
}
//Equip a Ranged
if(OAI_EquipRanged() && !OAI_IsOutOfAmmo()) return;
}
}
//Melee Attack
else
{
//Dual Wield
//Are we already dual-wielding? Don't do anything.
if(IsSingleHandedMeleeWeapon(oRightHand) && IsSingleHandedMeleeWeapon(oLeftHand)) return;
//Have the Dualing Feats
else if(OAI_WiseToDualWield(oSelf))
{
if(nClearActions && !nAlreadyClearedActions)
{
ClearAllActions();
nAlreadyClearedActions = TRUE;
}
//Equips the Stored Right Handed Melee
if(OAI_EquipRHMelee()) {}
//Equips the Left Handed Weapon or Shield
if(OAI_EquipLHMelee()) {}
}
//Holding a Single Weapon Already
else if(IsSingleHandedMeleeWeapon(oRightHand)) return;
//Right Hand and Shield
else
{
if(nClearActions && !nAlreadyClearedActions)
{
ClearAllActions();
nAlreadyClearedActions = TRUE;
}
//Equips the Stored Right Handed Melee
if(OAI_EquipRHMelee()) {}
//Equips the Left Handed Weapon or Shield
if(OAI_EquipLHMelee() && GetHasFeat(FEAT_SHIELD_PROFICIENCY,oSelf)) {}
}
}
}
int OAI_EquipRanged()
{
object oItem = GetLocalObject(OBJECT_SELF, "OAI_RANGED");
if(oItem != OBJECT_INVALID)
{
ActionDoCommand(ActionEquipItem(oItem,INVENTORY_SLOT_RIGHTHAND));
return TRUE;
}
return FALSE;
}
int OAI_IsOutOfAmmo()
{
int nWeaponType = GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND));
object oAmmo = OBJECT_INVALID;
if (nWeaponType == BASE_ITEM_LONGBOW || nWeaponType == BASE_ITEM_SHORTBOW)
{
oAmmo = GetItemInSlot(INVENTORY_SLOT_ARROWS);
}
else if (nWeaponType == BASE_ITEM_LIGHTCROSSBOW || nWeaponType == BASE_ITEM_HEAVYCROSSBOW)
{
oAmmo = GetItemInSlot(INVENTORY_SLOT_BOLTS);
}
else if (nWeaponType == BASE_ITEM_SLING)
{
oAmmo = GetItemInSlot(INVENTORY_SLOT_BULLETS);
}
if (GetIsObjectValid(oAmmo) == FALSE)
{
return TRUE;
}
return FALSE;
}
int OAI_WiseToDualWield(object oUser)
{
if (GetHasFeat(FEAT_AMBIDEXTERITY, oUser) && GetHasFeat(FEAT_TWO_WEAPON_FIGHTING, oUser))
{
return TRUE;
}
return FALSE;
}
int OAI_EquipRHMelee()
{
object oItem = GetLocalObject(OBJECT_SELF, "OAI_RH_MELEE");
if(oItem != OBJECT_INVALID)
{
ActionDoCommand(ActionEquipItem(oItem,INVENTORY_SLOT_RIGHTHAND));
return FALSE;
}
return FALSE;
}
int OAI_EquipLHMelee()
{
object oItem = GetLocalObject(OBJECT_SELF, "OAI_LH_MELEE");
if(oItem != OBJECT_INVALID)
{
ActionDoCommand(ActionEquipItem(oItem,INVENTORY_SLOT_RIGHTHAND));
return FALSE;
}
return FALSE;
}
void OAI_ChooseWeapons()
{
object oSelf = OBJECT_SELF;
object oShield=OBJECT_INVALID;
object oLeft=OBJECT_INVALID;
object oRight=OBJECT_INVALID;
object oRanged=OBJECT_INVALID;
int nHaveShield = FALSE;
int nSingle = 0;
//Ranged Weapon First
oRanged = GetFirstItemInInventory(oSelf);
while(GetIsObjectValid(oRanged))
{
//Both Medium and Light
if(IsRangedWeapon(oRanged))
{
nSingle++;
if(nSingle == 1)
{
break;
}
}
oRanged = GetNextItemInInventory(oSelf);
}
//Ranged Weapon
if(GetIsObjectValid(oRanged))
{
SetLocalObject(OBJECT_SELF, "OAI_RANGED", oRanged);
}
//Weapons and Shields
nSingle = 0;
object oItem = GetFirstItemInInventory(oSelf);
while(GetIsObjectValid(oItem))
{
//Both Medium and Light
if(IsSingleHandedMeleeWeapon(oItem))
{
nSingle++;
if(nSingle == 1) oRight = oItem;
else if (nSingle == 2) oLeft = oItem;
else break;
}
else if(MatchShield(oItem))
{
nHaveShield = TRUE;
oShield = oItem;
}
oItem = GetNextItemInInventory(oSelf);
}
//Right Hand Weapon
if(GetIsObjectValid(oRight))
{
SetLocalObject(OBJECT_SELF, "OAI_RH_MELEE", oItem);
}
//Left Hand Shield
if(GetIsObjectValid(oShield)
&& nHaveShield
&& GetHasFeat(FEAT_SHIELD_PROFICIENCY,oSelf))
{
SetLocalObject(OBJECT_SELF, "OAI_LH_MELEE", oShield);
}
//Left Hand Weapon (Will Override Shield)
if(GetIsObjectValid(oLeft) && OAI_WiseToDualWield(OBJECT_SELF))
{
SetLocalObject(OBJECT_SELF, "OAI_LH_MELEE", oLeft);
}
}
void OAI_WrapperActionAttack(object oTarget)
{
OAI_EquipAppropriateWeapons();
ActionAttack(oTarget);
}
//void main(){}