Jaysyn904 d1c309ae63 Initial commit
Initial commit
2024-09-13 09:10:39 -04:00

1194 lines
36 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
//
// Olander's AI
// oai_inc_spawn
// by Don Anderson
// dandersonru@msn.com
//
// Main AI Spawn Script
//
////////////////////////////////////////////////////////////////////////////////
#include "oai_inc_base"
#include "oai_inc_eqweapon"
#include "x0_i0_spawncond"
#include "x0_i0_combat"
//Sets up Random Abilities
void SetRandomAbilitiesOnCreatureSpawn();
void WhoAmI()
{
object oCreature = OBJECT_SELF;
//Class 1 or 2 are the Setup Classes
int nClass1 = GetClassByPosition(1,oCreature);
int nClass2 = GetClassByPosition(1,oCreature);
//:: COMBAT ALLIANCES
int nSet = 0;
object oSpecial = GetObjectByTag("FACTION_1000");
object oCommoner = GetObjectByTag("FACTION_1001");
object oMerchant = GetObjectByTag("FACTION_1002");
object oDefender = GetObjectByTag("FACTION_1003");
object oHostile = GetObjectByTag("FACTION_1004");
if(GetFactionEqual(oCreature,oSpecial)) SetLocalString(oCreature,OAI_FACTION,NEUTRAL);
if(GetFactionEqual(oCreature,oCommoner)) SetLocalString(oCreature,OAI_FACTION,NEUTRAL);
if(GetFactionEqual(oCreature,oMerchant)) SetLocalString(oCreature,OAI_FACTION,NEUTRAL);
if(GetFactionEqual(oCreature,oDefender)) SetLocalString(oCreature,OAI_FACTION,NEUTRAL);
if(GetFactionEqual(oCreature,oHostile)) SetLocalString(oCreature,OAI_FACTION,HOSTILE);
string sCheck = GetLocalString(oCreature,OAI_FACTION);
if(sCheck != "") nSet = 1;
int nRth = 1;
string sFaction = "FACTION_";
string sName,sAllege,sNumber,sRep;
object oRep = GetObjectByTag("FACTION_001");
while(GetIsObjectValid(oRep) && nSet != 1)
{
if(GetFactionEqual(oCreature,oRep))
{
sName = GetName(oRep);
sAllege = GetLocalString(oRep,"ALLIANCE");
if(sAllege == "ALLY") SetLocalString(oCreature,OAI_FACTION,ALLY);
else if(sAllege == "AXIS") SetLocalString(oCreature,OAI_FACTION,AXIS);
else if(sAllege == "INDEPENDENT") SetLocalString(oCreature,OAI_FACTION,INDEPENDENT);
else SetLocalString(oCreature,OAI_FACTION,NEUTRAL);
sCheck = GetLocalString(oCreature,OAI_FACTION);
if(sCheck != "") nSet = 1;
break;
}
nRth++;
if(nRth > 0 && nRth < 10) sNumber = "00" + IntToString(nRth);
if(nRth >= 10 && nRth < 100) sNumber = "0" + IntToString(nRth);
if(nRth >= 100 && nRth < 1000) sNumber = IntToString(nRth);
sRep = sFaction + sNumber;
oRep = GetObjectByTag(sRep);
}
if(GetHasSpell(SPELL_POLYMORPH_SELF)
|| GetHasSpell(SPELL_SHAPECHANGE)
|| GetHasSpell(SPELL_TENSERS_TRANSFORMATION))
{
SetStatusCondition(OAI_I_CAN_POLYMORPH);
}
//Summoning
talent tSummon = GetCreatureTalent(TALENT_CATEGORY_BENEFICIAL_OBTAIN_ALLIES, 20);
if(GetIsTalentValid(tSummon)) { SetStatusCondition(OAI_I_CAN_SUMMON); }
//:: CLASS SPECIFIC CONDITIONS
if(nClass1 == CLASS_TYPE_BARBARIAN || nClass2 == CLASS_TYPE_BARBARIAN)
{
SetUpBarbarian(oCreature);
}
else if(nClass1 == CLASS_TYPE_BARD || nClass2 == CLASS_TYPE_BARD)
{
SetUpBard(oCreature);
}
else if(nClass1 == CLASS_TYPE_CLERIC || nClass2 == CLASS_TYPE_CLERIC)
{
SetUpCleric(oCreature);
}
else if(nClass1 == CLASS_TYPE_DRUID || nClass2 == CLASS_TYPE_DRUID)
{
SetUpDruid(oCreature);
}
else if(nClass1 == CLASS_TYPE_FIGHTER || nClass2 == CLASS_TYPE_FIGHTER)
{
SetUpFighter(oCreature);
}
else if(nClass1 == CLASS_TYPE_MONK || nClass2 == CLASS_TYPE_MONK)
{
SetUpMonk(oCreature);
}
else if(nClass1 == CLASS_TYPE_PALADIN || nClass2 == CLASS_TYPE_PALADIN)
{
SetUpPaladin(oCreature);
}
else if(nClass1 == CLASS_TYPE_RANGER || nClass2 == CLASS_TYPE_RANGER)
{
SetUpRanger(oCreature);
}
else if(nClass1 == CLASS_TYPE_ROGUE || nClass2 == CLASS_TYPE_ROGUE)
{
SetUpRogue(oCreature);
}
else if(nClass1 == CLASS_TYPE_SORCERER || nClass2 == CLASS_TYPE_SORCERER)
{
SetUpSorcerer(oCreature);
}
else if(nClass1 == CLASS_TYPE_WIZARD || nClass2 == CLASS_TYPE_WIZARD)
{
SetUpWizard(oCreature);
}
/******************************************************************************/
//:: OAI & NWN Default Spawn Setups
string sResRef = GetResRef(OBJECT_SELF);
string sTag = GetTag(OBJECT_SELF);
//Set Up Default NWN Animals
if(GetRacialType(OBJECT_SELF) == RACIAL_TYPE_ANIMAL)
{
ExecuteScript("oai_animals",OBJECT_SELF);
}
//Barmaid
if(sTag == "Barmaid")
{
SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING,FALSE);
SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS,FALSE);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS,FALSE);
SetAnimationCondition(NW_ANIM_FLAG_CHATTER,FALSE);
//Barmaid Speed =)
effect eRate = SupernaturalEffect(EffectMovementSpeedDecrease(15));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eRate, oCreature);
SetLocalInt(OBJECT_SELF, "OAI_BARMAID", 1);
}
//Inn Cook
if(sTag == "InnCook")
{
SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING,FALSE);
SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS,FALSE);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS,FALSE);
SetAnimationCondition(NW_ANIM_FLAG_CHATTER,FALSE);
//Cook Speed =)
effect eRate = SupernaturalEffect(EffectMovementSpeedDecrease(15));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eRate, oCreature);
SetLocalInt(OBJECT_SELF, "OAI_COOK", 1);
}
//Guards
int nGuard = GetLocalInt(OBJECT_SELF,"OAI_GUARD");
if(nGuard == 1)
{
SetBattleCondition(OAI_ROLE_GUARD);
}
//Stripper
int nStripper = GetLocalInt(OBJECT_SELF,"OAI_STRIPPER");
if(nStripper == 1)
{
SetBattleCondition(OAI_ROLE_STRIPPER);
//Stripper Speed =)
effect eRate = SupernaturalEffect(EffectMovementSpeedDecrease(25));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eRate, oCreature);
}
//Manual Shapechanger
if(GetLocalInt(OBJECT_SELF, "OAI_SHAPECHANGE") > 0) SetStatusCondition(OAI_I_CAN_POLYMORPH);
//Set Up For Default NWN Lycans
if(sResRef=="nw_werecat002") SetStatusCondition(OAI_I_CAN_POLYMORPH);
if(sResRef=="nw_wererat002") SetStatusCondition(OAI_I_CAN_POLYMORPH);
if(sResRef=="nw_werewolf002") SetStatusCondition(OAI_I_CAN_POLYMORPH);
//Default Blinkers and Teleporters
if(sResRef=="nw_blinkdog")
{
SetBattleCondition(OAI_BLINK_SELF);
SetLocalInt(OBJECT_SELF, "OAI_BLINK_FAILURE", 10);
}
//Default Gelatanous Cube
if(sResRef=="x2_gelcube") SetBattleCondition(OAI_ROLE_GELATINOUSCUBE);
//Set As Able To Raise Dead
if(GetHasSpell(SPELL_RESURRECTION) || GetHasSpell(SPELL_RAISE_DEAD))
{
SetStatusCondition(OAI_I_CAN_RAISE_DEAD);
}
//Default Spiders
if (GetStringLeft(sTag, 7) == "NW_SPID" || GetStringLeft(sTag, 11) == "NW_HCS_SPID" ||
GetStringLeft(sTag, 8) == "ZEP_SPID") {
//Standard Spiders
SetBattleCondition(OAI_RETURN_TO_SPAWNPOINT);
SetLocalInt(OBJECT_SELF,"FIGHT_OR_FLIGHT",0);
SetSpawnInCondition(NW_FLAG_SEARCH);
SetBattleCondition(OAI_ROLE_SPIDER);
SetBattleCondition(OAI_ROLE_NUMBEROFATTACKS);
SetLocalInt(OBJECT_SELF,"OAI_ROLE_NUMBEROFATTACKS",5); /* <= CHANGE THAT 5 */
SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
if (GetStringRight(sTag, 5) == "PHASE")
{
SetBattleCondition(OAI_BLINK_SELF);
SetLocalInt(OBJECT_SELF, "OAI_BLINK_FAILURE", 10); //failure rate of 10%
}
if (GetStringRight(sTag, 7) == "SPIDWRA")
{
SetBattleCondition(OAI_ROLE_GHOST);
}
}
//Default Trolls
if (GetStringLeft(sTag, 8) == "NW_TROLL" || GetStringLeft(sTag, 12) == "NW_HCS_TROLL" ||
GetStringLeft(sTag, 9) == "ZEP_TROLL") {
SetSpawnInCondition(NW_FLAG_SEARCH);
SetBattleCondition(OAI_ROLE_TROLL);
SetBattleCondition(OAI_ROLE_SPEEDY);
}
//Default MindFlayer
if (GetStringLeft(sTag, 8) == "X2_MINDF" || GetStringLeft(sTag, 12) == "ZEP_ILLITHID") {
SetBattleCondition(OAI_FAST_BUFF_ADVANCED);
SetBattleCondition(OAI_BLINK_SELF);
SetLocalInt(OBJECT_SELF, "OAI_BLINK_FAILURE", 10); //failure rate of 10%
SetBattleCondition(OAI_ROLE_MINDFLAYER);
}
//Default Beholder
if (GetStringLeft(sTag, 11) == "X2_BEHOLDER" || GetStringLeft(sTag, 12) == "ZEP_BEHOLDER") {
SetBattleCondition(OAI_FAST_BUFF_ADVANCED);
SetBattleCondition(OAI_CAST_AURAS_NOW);
SetBattleCondition(OAI_BLINK_SELF);
SetLocalInt(OBJECT_SELF, "OAI_BLINK_FAILURE", 70); //failure rate of 10%
SetBattleCondition(OAI_ROLE_BEHOLDER);
SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
}
//Dragon
if(GetRacialType(oCreature) == RACIAL_TYPE_DRAGON && GetCreatureSize(OBJECT_SELF) == CREATURE_SIZE_HUGE)
{
SetBattleCondition(OAI_ROLE_DRAGON);
SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
}
//:: OAI & NWN Default Spawn Setups
/******************************************************************************/
if(GetBattleCondition(OAI_ROLE_GROUP_LEADER)) SetLocalInt(OBJECT_SELF,"OAI_I_AM_A_LEADER",1);
int nIllusionary = GetLocalInt(OBJECT_SELF, "OAI_ILLUSION_DC");
int nAT = GetLocalInt(OBJECT_SELF, "OAI_REAL_SELF");
if(nIllusionary > 0)
{
if(nAT > 0)
{
SetLocalInt(OBJECT_SELF,"OAI_HAS_ILLUSION",TRUE);
SetCreatureAppearanceType(OBJECT_SELF ,nAT);
}
}
if(GetBattleCondition(OAI_ROLE_SPEEDY))
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectHaste(),OBJECT_SELF);
}
if(GetBattleCondition(OAI_ROLE_NUMBEROFATTACKS))
{
int nNOA = GetLocalInt(OBJECT_SELF,"OAI_ROLE_NUMBEROFATTACKS");
//Set Range
if(nNOA < 1) nNOA = 5;
if(nNOA > 5) nNOA = 5;
effect eNOA = EffectModifyAttacks(nNOA);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(eNOA), OBJECT_SELF);
}
if(GetBattleCondition(OAI_ROLE_GELATINOUSCUBE))
{
effect eConceal = EffectConcealment(50, MISS_CHANCE_TYPE_NORMAL);
eConceal = ExtraordinaryEffect(eConceal);
effect eGhost = EffectCutsceneGhost();
eGhost = ExtraordinaryEffect(eGhost);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eConceal, OBJECT_SELF);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGhost, OBJECT_SELF);
}
if(GetBattleCondition(OAI_ROLE_GHOST))
{
effect vfx = EffectVisualEffect(VFX_DUR_GHOSTLY_VISAGE);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, vfx, OBJECT_SELF);
ActionCastSpellAtObject(SPELL_GHOSTLY_VISAGE, OBJECT_SELF, METAMAGIC_EXTEND, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
effect eConceal = EffectConcealment(50, MISS_CHANCE_TYPE_NORMAL);
eConceal = ExtraordinaryEffect(eConceal);
effect eGhost = EffectCutsceneGhost();
eGhost = ExtraordinaryEffect(eGhost);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eConceal, OBJECT_SELF);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGhost, OBJECT_SELF);
}
//Special NWN Combat AI's
if(GetBattleCondition(OAI_COMBAT_FLAG_RANGED))
{
SetCombatCondition(X0_COMBAT_FLAG_RANGED);
}
if(GetBattleCondition(OAI_COMBAT_FLAG_DEFENSIVE))
{
SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE);
}
if(GetBattleCondition(OAI_COMBAT_FLAG_AMBUSHER))
{
SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER);
}
if(GetBattleCondition(OAI_COMBAT_FLAG_COWARDLY))
{
SetCombatCondition(X0_COMBAT_FLAG_COWARDLY);
}
//If Evil Do Not Buff Others
if(GetAlignmentGoodEvil(OBJECT_SELF) == ALIGNMENT_EVIL)
{
SetBattleCondition(OAI_ROLE_BUFFER, FALSE);
}
//Do we need to remember where we spawned?
if(GetBattleCondition(OAI_RETURN_TO_SPAWNPOINT)) SetLocalLocation(OBJECT_SELF, "OAI_SPAWN_LOCATION", GetLocation(OBJECT_SELF));
//Set Up Our Weapons
OAI_ChooseWeapons();
SetLocalInt(OBJECT_SELF,"OAI_HPW",TRUE);
OAI_UnequipWeapons();
//Racial Movement Rate for Small Creatures (Configured in oai_mod_onload)
int nRacial = GetLocalInt(GetModule(),"RACIALMOVE");
if(nRacial == 1) SetRacialMovementRate(OBJECT_SELF);
//Use Search and Stealth for Flag
if(GetSpawnInCondition(NW_FLAG_SEARCH)) ActionUseSkill(SKILL_SEARCH, OBJECT_SELF);
if(GetSpawnInCondition(NW_FLAG_STEALTH)) ActionUseSkill(SKILL_HIDE, OBJECT_SELF);
}
void Hench_WhoAmI()
{
object oCreature = OBJECT_SELF;
//Class 1 or 2 are the Setup Classes
int nClass1 = GetClassByPosition(1,oCreature);
int nClass2 = GetClassByPosition(1,oCreature);
//:: COMBAT ALLIANCES
int nSet = 0;
object oSpecial = GetObjectByTag("FACTION_1000");
object oCommoner = GetObjectByTag("FACTION_1001");
object oMerchant = GetObjectByTag("FACTION_1002");
object oDefender = GetObjectByTag("FACTION_1003");
object oHostile = GetObjectByTag("FACTION_1004");
if(GetFactionEqual(oCreature,oSpecial)) SetLocalString(oCreature,OAI_FACTION,NEUTRAL);
if(GetFactionEqual(oCreature,oCommoner)) SetLocalString(oCreature,OAI_FACTION,NEUTRAL);
if(GetFactionEqual(oCreature,oMerchant)) SetLocalString(oCreature,OAI_FACTION,NEUTRAL);
if(GetFactionEqual(oCreature,oDefender)) SetLocalString(oCreature,OAI_FACTION,NEUTRAL);
if(GetFactionEqual(oCreature,oHostile)) SetLocalString(oCreature,OAI_FACTION,HOSTILE);
string sCheck = GetLocalString(oCreature,OAI_FACTION);
if(sCheck != "") nSet = 1;
int nRth = 1;
string sFaction = "FACTION_";
string sName,sAllege,sNumber,sRep;
object oRep = GetObjectByTag("FACTION_001");
while(GetIsObjectValid(oRep) && nSet != 1)
{
if(GetFactionEqual(oCreature,oRep))
{
sName = GetName(oRep);
sAllege = GetLocalString(oRep,"ALLIANCE");
if(sAllege == "ALLY") SetLocalString(oCreature,OAI_FACTION,ALLY);
else if(sAllege == "AXIS") SetLocalString(oCreature,OAI_FACTION,AXIS);
else if(sAllege == "INDEPENDENT") SetLocalString(oCreature,OAI_FACTION,INDEPENDENT);
else SetLocalString(oCreature,OAI_FACTION,NEUTRAL);
sCheck = GetLocalString(oCreature,OAI_FACTION);
if(sCheck != "") nSet = 1;
break;
}
nRth++;
if(nRth > 0 && nRth < 10) sNumber = "00" + IntToString(nRth);
if(nRth >= 10 && nRth < 100) sNumber = "0" + IntToString(nRth);
if(nRth >= 100 && nRth < 1000) sNumber = IntToString(nRth);
sRep = sFaction + sNumber;
oRep = GetObjectByTag(sRep);
}
if(GetHasSpell(SPELL_POLYMORPH_SELF)
|| GetHasSpell(SPELL_SHAPECHANGE)
|| GetHasSpell(SPELL_TENSERS_TRANSFORMATION))
{
SetStatusCondition(OAI_I_CAN_POLYMORPH);
}
//Summoning
talent tSummon = GetCreatureTalent(TALENT_CATEGORY_BENEFICIAL_OBTAIN_ALLIES, 20);
if(GetIsTalentValid(tSummon)) { SetStatusCondition(OAI_I_CAN_SUMMON); }
//:: CLASS SPECIFIC CONDITIONS
if(nClass1 == CLASS_TYPE_BARBARIAN || nClass2 == CLASS_TYPE_BARBARIAN)
{
SetUpBarbarian(oCreature);
}
else if(nClass1 == CLASS_TYPE_BARD || nClass2 == CLASS_TYPE_BARD)
{
SetUpBard(oCreature);
}
else if(nClass1 == CLASS_TYPE_CLERIC || nClass2 == CLASS_TYPE_CLERIC)
{
SetUpCleric(oCreature);
}
else if(nClass1 == CLASS_TYPE_DRUID || nClass2 == CLASS_TYPE_DRUID)
{
SetUpDruid(oCreature);
}
else if(nClass1 == CLASS_TYPE_FIGHTER || nClass2 == CLASS_TYPE_FIGHTER)
{
SetUpFighter(oCreature);
}
else if(nClass1 == CLASS_TYPE_MONK || nClass2 == CLASS_TYPE_MONK)
{
SetUpMonk(oCreature);
}
else if(nClass1 == CLASS_TYPE_PALADIN || nClass2 == CLASS_TYPE_PALADIN)
{
SetUpPaladin(oCreature);
}
else if(nClass1 == CLASS_TYPE_RANGER || nClass2 == CLASS_TYPE_RANGER)
{
SetUpRanger(oCreature);
}
else if(nClass1 == CLASS_TYPE_ROGUE || nClass2 == CLASS_TYPE_ROGUE)
{
SetUpRogue(oCreature);
}
else if(nClass1 == CLASS_TYPE_SORCERER || nClass2 == CLASS_TYPE_SORCERER)
{
SetUpSorcerer(oCreature);
}
else if(nClass1 == CLASS_TYPE_WIZARD || nClass2 == CLASS_TYPE_WIZARD)
{
SetUpWizard(oCreature);
}
/******************************************************************************/
//:: OAI & NWN Default Spawn Setups
string sResRef = GetResRef(OBJECT_SELF);
string sTag = GetTag(OBJECT_SELF);
//Manual Shapechanger
if(GetLocalInt(OBJECT_SELF, "OAI_SHAPECHANGE") > 0) SetStatusCondition(OAI_I_CAN_POLYMORPH);
//Set As Able To Raise Dead
if(GetHasSpell(SPELL_RESURRECTION) || GetHasSpell(SPELL_RAISE_DEAD))
{
SetStatusCondition(OAI_I_CAN_RAISE_DEAD);
}
//Dragon
if(GetRacialType(oCreature) == RACIAL_TYPE_DRAGON && GetCreatureSize(OBJECT_SELF) == CREATURE_SIZE_HUGE)
{
SetBattleCondition(OAI_ROLE_DRAGON);
SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
}
//:: OAI & NWN Default Spawn Setups
/******************************************************************************/
int nIllusionary = GetLocalInt(OBJECT_SELF, "OAI_ILLUSION_DC");
int nAT = GetLocalInt(OBJECT_SELF, "OAI_REAL_SELF");
if(nIllusionary > 0)
{
if(nAT > 0)
{
SetLocalInt(OBJECT_SELF,"OAI_HAS_ILLUSION",TRUE);
SetCreatureAppearanceType(OBJECT_SELF ,nAT);
}
}
if(GetBattleCondition(OAI_ROLE_SPEEDY))
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectHaste(),OBJECT_SELF);
}
if(GetBattleCondition(OAI_ROLE_NUMBEROFATTACKS))
{
int nNOA = GetLocalInt(OBJECT_SELF,"OAI_ROLE_NUMBEROFATTACKS");
//Set Range
if(nNOA < 1) nNOA = 5;
if(nNOA > 5) nNOA = 5;
effect eNOA = EffectModifyAttacks(nNOA);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(eNOA), OBJECT_SELF);
}
if(GetBattleCondition(OAI_ROLE_GHOST))
{
effect vfx = EffectVisualEffect(VFX_DUR_GHOSTLY_VISAGE);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, vfx, OBJECT_SELF);
ActionCastSpellAtObject(SPELL_GHOSTLY_VISAGE, OBJECT_SELF, METAMAGIC_EXTEND, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
effect eConceal = EffectConcealment(50, MISS_CHANCE_TYPE_NORMAL);
eConceal = ExtraordinaryEffect(eConceal);
effect eGhost = EffectCutsceneGhost();
eGhost = ExtraordinaryEffect(eGhost);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eConceal, OBJECT_SELF);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGhost, OBJECT_SELF);
}
//Special NWN Combat AI's
if(GetBattleCondition(OAI_COMBAT_FLAG_RANGED))
{
SetCombatCondition(X0_COMBAT_FLAG_RANGED);
}
if(GetBattleCondition(OAI_COMBAT_FLAG_DEFENSIVE))
{
SetCombatCondition(X0_COMBAT_FLAG_DEFENSIVE);
}
if(GetBattleCondition(OAI_COMBAT_FLAG_AMBUSHER))
{
SetCombatCondition(X0_COMBAT_FLAG_AMBUSHER);
}
if(GetBattleCondition(OAI_COMBAT_FLAG_COWARDLY))
{
SetCombatCondition(X0_COMBAT_FLAG_COWARDLY);
}
//Do we need to remember where we spawned?
if(GetBattleCondition(OAI_RETURN_TO_SPAWNPOINT)) SetLocalLocation(OBJECT_SELF, "OAI_SPAWN_LOCATION", GetLocation(OBJECT_SELF));
//Set Up Our Weapons
OAI_ChooseWeapons();
SetLocalInt(OBJECT_SELF,"OAI_HPW",TRUE);
OAI_UnequipWeapons();
//Racial Movement Rate for Small Creatures (Configured in oai_mod_onload)
int nRacial = GetLocalInt(GetModule(),"RACIALMOVE");
if(nRacial == 1) SetRacialMovementRate(OBJECT_SELF);
//Equips Henchman's Heaviest Armor
ExecuteScript("hench_equip_ha",OBJECT_SELF);
}
void SetRandomAbilitiesOnCreatureSpawn()
{
int nRandomize = GetLocalInt(GetModule(),"OAI_RANDOM_ABILITIES");
if(nRandomize == 0) return;
object oSpawnedCreature = OBJECT_SELF;
int nSpawnCreatureAssociateType = GetAssociateType(oSpawnedCreature);
int nSpawnSummonCreatureLevel;
string sResRefCreature = GetResRef(oSpawnedCreature);
//BonusMalus Effects
effect eSpawnStrengthBonus;
effect eSpawnStrengthMalus;
effect eSpawnDexterityBonus;
effect eSpawnDexterityMalus;
effect eSpawnConstitutionBonus;
effect eSpawnConstitutionMalus;
effect eSpawnWisdomBonus;
effect eSpawnWisdomMalus;
effect eSpawnIntelligenceBonus;
effect eSpawnIntelligenceMalus;
effect eSpawnCharismaBonus;
effect eSpawnCharismaMalus;
effect eSpawnAttackBonus;
effect eSpawnAttackMalus;
effect eSpawnArmorClassBonus;
effect eSpawnArmorClassMalus;
effect eSpawnSavingThrowFortBonus;
effect eSpawnSavingThrowFortMalus;
effect eSpawnSavingThrowDexBonus;
effect eSpawnSavingThrowDexMalus;
effect eSpawnSavingThrowWillBonus;
effect eSpawnSavingThrowWillMalus;
effect eSpawnSkillDisciplineBonus;
effect eSpawnSkillDisciplineMalus;
effect eSpawnSkillSpotBonus;
effect eSpawnSkillSpotMalus;
effect eSpawnSkillListenBonus;
effect eSpawnSkillListenMalus;
effect eSpawnSkillConcentrationBonus;
effect eSpawnSkillConcentrationMalus;
effect eSpawnExtraAttackBonus;
//For undead, elementals, planars, constructs, vermin racial types only
effect eSpawnTurningResistenceBonus;
effect eSpawnTurningResistenceMalus;
//Final BonusMalus linked effects
effect eBonusMalusLink;
//Visual effects
effect eGhostSmoke1 = EffectVisualEffect(VFX_DUR_GHOST_SMOKE);
effect eGhostSmoke2 = EffectVisualEffect(VFX_DUR_GHOST_SMOKE_2);
effect eGhostTransparent = EffectVisualEffect(VFX_DUR_GHOST_TRANSPARENT);
effect eGhostlyVisagePulse = EffectVisualEffect(VFX_DUR_GHOSTLY_PULSE);
effect eGhostlyVisage = EffectVisualEffect(VFX_DUR_GHOSTLY_VISAGE);
effect eEtherealVisage = EffectVisualEffect(VFX_DUR_ETHEREAL_VISAGE);
effect eGhost = EffectCutsceneGhost();
//Illusionary creatures
int nIllusionary = GetLocalInt(OBJECT_SELF, "OAI_ILLUSION_DC");
int nAT = GetLocalInt(OBJECT_SELF, "OAI_REAL_SELF");
switch (nSpawnCreatureAssociateType)
{
/*
Animal companions, familiars and henchmen are not subjected
to randomizer functions as to maintain their specific profile
as characters.
Dominated creatures were already spawned before falling under
player control, hence were likely already applied a randomizer effect
*/
case ASSOCIATE_TYPE_ANIMALCOMPANION:
case ASSOCIATE_TYPE_DOMINATED:
case ASSOCIATE_TYPE_FAMILIAR:
case ASSOCIATE_TYPE_HENCHMAN:
break;
/*
Summoned creatures, as they are random creatures conjured by the caster,
are determined by the spell cast for what concerns the type of creature
and its basic power level (picking them from the module blueprint list for
creatures), and then their stats and talents are randomized upon spawning.
*/
case ASSOCIATE_TYPE_SUMMONED:
/*
Gets the power of the summoned creature
and sets the number of attacks depending
on creature power level.
It overrides the toolset settings, for easier customization.
*/
nSpawnSummonCreatureLevel = StringToInt(GetStringRight(sResRefCreature, 1));
switch (nSpawnSummonCreatureLevel)
{
case 1:
case 2:
case 3:
SetBaseAttackBonus(1, oSpawnedCreature);
break;
case 4:
case 5:
case 6:
SetBaseAttackBonus(2, oSpawnedCreature);
break;
case 7:
case 8:
case 9:
SetBaseAttackBonus(3, oSpawnedCreature);
break;
}
switch (d3())
{
case 1:
eSpawnStrengthBonus = EffectAbilityIncrease(ABILITY_STRENGTH, d4());
break;
case 2:
eSpawnStrengthMalus = EffectAbilityDecrease(ABILITY_STRENGTH, d4());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnDexterityBonus = EffectAbilityIncrease(ABILITY_DEXTERITY, d4());
break;
case 2:
eSpawnDexterityMalus = EffectAbilityDecrease(ABILITY_DEXTERITY, d4());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnConstitutionBonus = EffectAbilityIncrease(ABILITY_CONSTITUTION, d4());
break;
case 2:
eSpawnConstitutionMalus = EffectAbilityDecrease(ABILITY_CONSTITUTION, d4());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnWisdomBonus = EffectAbilityIncrease(ABILITY_WISDOM, d4());
break;
case 2:
eSpawnWisdomMalus = EffectAbilityDecrease(ABILITY_WISDOM, d4());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnAttackBonus = EffectAttackIncrease(ATTACK_BONUS_MISC, d4());
break;
case 2:
eSpawnAttackMalus = EffectAttackDecrease(d4(), ATTACK_BONUS_MISC);
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnArmorClassBonus = EffectACIncrease(d4(), AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
break;
case 2:
eSpawnArmorClassMalus = EffectACDecrease(d4(), AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSavingThrowFortBonus = EffectSavingThrowIncrease(SAVING_THROW_FORT, d8(), SAVING_THROW_ALL);
break;
case 2:
eSpawnSavingThrowFortMalus = EffectSavingThrowDecrease(SAVING_THROW_FORT, d4(), SAVING_THROW_ALL);
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSavingThrowDexBonus = EffectSavingThrowIncrease(SAVING_THROW_REFLEX, d8(), SAVING_THROW_ALL);
break;
case 2:
eSpawnSavingThrowDexMalus = EffectSavingThrowDecrease(SAVING_THROW_REFLEX, d4(), SAVING_THROW_ALL);
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSavingThrowWillBonus = EffectSavingThrowIncrease(SAVING_THROW_WILL, d8(), SAVING_THROW_ALL);
break;
case 2:
eSpawnSavingThrowWillMalus = EffectSavingThrowDecrease(SAVING_THROW_WILL, d4(), SAVING_THROW_ALL);
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSkillDisciplineBonus = EffectSkillIncrease(SKILL_DISCIPLINE, d8());
break;
case 2:
eSpawnSkillDisciplineMalus = EffectSkillDecrease(SKILL_DISCIPLINE, d4());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSkillSpotBonus = EffectSkillIncrease(SKILL_SPOT, d8());
break;
case 2:
eSpawnSkillSpotMalus = EffectSkillDecrease(SKILL_SPOT, d4());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSkillListenBonus = EffectSkillIncrease(SKILL_LISTEN, d8());
break;
case 2:
eSpawnSkillListenMalus = EffectSkillDecrease(SKILL_LISTEN, d4());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSkillConcentrationBonus = EffectSkillIncrease(SKILL_CONCENTRATION, d8());
break;
case 2:
eSpawnSkillConcentrationMalus = EffectSkillDecrease(SKILL_CONCENTRATION, d4());
break;
case 3:
break;
}
//Creature has a slight chance to get an extra attack per round */
switch (d10())
{
case 10:
eSpawnExtraAttackBonus = EffectModifyAttacks(1);
break;
default:
break;
}
if(nIllusionary > 0)
{
switch (d3())
{
case 1:
eSpawnCharismaBonus = EffectAbilityIncrease(ABILITY_CHARISMA, d4());
break;
case 2:
eSpawnCharismaMalus = EffectAbilityDecrease(ABILITY_CHARISMA, d4());
break;
case 3:
break;
}
}
/*
Racial types that are subjected to turn undead ability type
receive a random bonus or malus to their ability to resist it
*/
if ((GetRacialType(oSpawnedCreature) == RACIAL_TYPE_CONSTRUCT)
|| (GetRacialType(oSpawnedCreature) == RACIAL_TYPE_ELEMENTAL)
|| (GetRacialType(oSpawnedCreature) == RACIAL_TYPE_OUTSIDER)
|| (GetRacialType(oSpawnedCreature) == RACIAL_TYPE_UNDEAD)
|| (GetRacialType(oSpawnedCreature) == RACIAL_TYPE_VERMIN))
{
switch (d3())
{
case 1:
eSpawnTurningResistenceBonus = EffectTurnResistanceIncrease(d4());
break;
case 2:
eSpawnTurningResistenceMalus = EffectTurnResistanceDecrease(d4());
break;
case 3:
break;
}
}
break;
/*
All spawned creature that are not associates of the player characters,
i.e. are normal creatures spawned by other means (encounter, DM spawn, whatever),
get the randomizer effect applied to them, again to provide a wider and
less predictable range of NPC/monster encounters
*/
case ASSOCIATE_TYPE_NONE:
/*
Rolls a dice for each ability and depending on the result,
sets a bonus, a malus or simply does nothing
*/
switch (d3())
{
case 1:
eSpawnStrengthBonus = EffectAbilityIncrease(ABILITY_STRENGTH, d6());
break;
case 2:
eSpawnStrengthMalus = EffectAbilityDecrease(ABILITY_STRENGTH, d6());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnDexterityBonus = EffectAbilityIncrease(ABILITY_DEXTERITY, d6());
break;
case 2:
eSpawnDexterityMalus = EffectAbilityDecrease(ABILITY_DEXTERITY, d6());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnConstitutionBonus = EffectAbilityIncrease(ABILITY_CONSTITUTION, d6());
break;
case 2:
eSpawnConstitutionMalus = EffectAbilityDecrease(ABILITY_CONSTITUTION, d6());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnWisdomBonus = EffectAbilityIncrease(ABILITY_WISDOM, d6());
break;
case 2:
eSpawnWisdomMalus = EffectAbilityDecrease(ABILITY_WISDOM, d6());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnIntelligenceBonus = EffectAbilityIncrease(ABILITY_INTELLIGENCE, d6());
break;
case 2:
eSpawnIntelligenceMalus = EffectAbilityDecrease(ABILITY_INTELLIGENCE, d6());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnCharismaBonus = EffectAbilityIncrease(ABILITY_CHARISMA, d6());
break;
case 2:
eSpawnCharismaMalus = EffectAbilityDecrease(ABILITY_CHARISMA, d6());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnAttackBonus = EffectAttackIncrease(ATTACK_BONUS_MISC, d4());
break;
case 2:
eSpawnAttackMalus = EffectAttackDecrease(d4(), ATTACK_BONUS_MISC);
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnArmorClassBonus = EffectACIncrease(d4(), AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
break;
case 2:
eSpawnArmorClassMalus = EffectACDecrease(d4(), AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSavingThrowFortBonus = EffectSavingThrowIncrease(SAVING_THROW_FORT, d8(), SAVING_THROW_ALL);
break;
case 2:
eSpawnSavingThrowFortMalus = EffectSavingThrowDecrease(SAVING_THROW_FORT, d4(), SAVING_THROW_ALL);
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSavingThrowDexBonus = EffectSavingThrowIncrease(SAVING_THROW_REFLEX, d8(), SAVING_THROW_ALL);
break;
case 2:
eSpawnSavingThrowDexMalus = EffectSavingThrowDecrease(SAVING_THROW_REFLEX, d4(), SAVING_THROW_ALL);
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSavingThrowWillBonus = EffectSavingThrowIncrease(SAVING_THROW_WILL, d8(), SAVING_THROW_ALL);
break;
case 2:
eSpawnSavingThrowWillMalus = EffectSavingThrowDecrease(SAVING_THROW_WILL, d4(), SAVING_THROW_ALL);
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSkillDisciplineBonus = EffectSkillIncrease(SKILL_DISCIPLINE, d8());
break;
case 2:
eSpawnSkillDisciplineMalus = EffectSkillDecrease(SKILL_DISCIPLINE, d4());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSkillSpotBonus = EffectSkillIncrease(SKILL_SPOT, d8());
break;
case 2:
eSpawnSkillSpotMalus = EffectSkillDecrease(SKILL_SPOT, d4());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSkillListenBonus = EffectSkillIncrease(SKILL_LISTEN, d8());
break;
case 2:
eSpawnSkillListenMalus = EffectSkillDecrease(SKILL_LISTEN, d4());
break;
case 3:
break;
}
switch (d3())
{
case 1:
eSpawnSkillConcentrationBonus = EffectSkillIncrease(SKILL_CONCENTRATION, d8());
break;
case 2:
eSpawnSkillConcentrationMalus = EffectSkillDecrease(SKILL_CONCENTRATION, d4());
break;
case 3:
break;
}
//Creature has a slight chance to get an extra attack per round
switch (d10())
{
case 10:
eSpawnExtraAttackBonus = EffectModifyAttacks(1);
break;
default:
break;
}
/*
Racial types that are subjected to turn undead ability type
receive a random bonus or malus to their ability to resist it
*/
if ((GetRacialType(oSpawnedCreature) == RACIAL_TYPE_CONSTRUCT)
|| (GetRacialType(oSpawnedCreature) == RACIAL_TYPE_ELEMENTAL)
|| (GetRacialType(oSpawnedCreature) == RACIAL_TYPE_OUTSIDER)
|| (GetRacialType(oSpawnedCreature) == RACIAL_TYPE_UNDEAD)
|| (GetRacialType(oSpawnedCreature) == RACIAL_TYPE_VERMIN))
{
switch (d3())
{
case 1:
eSpawnTurningResistenceBonus = EffectTurnResistanceIncrease(d4());
break;
case 2:
eSpawnTurningResistenceMalus = EffectTurnResistanceDecrease(d4());
break;
case 3:
break;
}
}
break;
}
//Link Effects
eBonusMalusLink = EffectLinkEffects(eSpawnStrengthBonus, eSpawnStrengthMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnDexterityBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnDexterityMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnConstitutionBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnConstitutionMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnWisdomBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnWisdomMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnIntelligenceBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnIntelligenceMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnCharismaBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnCharismaMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnAttackBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnAttackMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnArmorClassBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnArmorClassMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSavingThrowFortBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSavingThrowFortMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSavingThrowDexBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSavingThrowDexMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSavingThrowWillBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSavingThrowWillMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSkillDisciplineBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSkillDisciplineMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSkillSpotBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSkillSpotMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSkillListenBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSkillListenMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSkillConcentrationBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnSkillConcentrationMalus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnTurningResistenceBonus);
eBonusMalusLink = EffectLinkEffects(eBonusMalusLink, eSpawnTurningResistenceMalus);
//Makes effects non dispellable
eBonusMalusLink = SupernaturalEffect(eBonusMalusLink);
//Apply Effects on Creature
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBonusMalusLink, oSpawnedCreature);
}
//void main() {}