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