1194 lines
36 KiB
Plaintext
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() {}
|