//////////////////////////////////////////////////////////////////////////////// // // 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(){}