Horsefly Swamp update
Creatures & encounter tables to support Horsefly swamp expansion.
This commit is contained in:
221
_module/nss/anaxim_ai.nss
Normal file
221
_module/nss/anaxim_ai.nss
Normal file
@@ -0,0 +1,221 @@
|
||||
|
||||
#include "nw_i0_generic"
|
||||
#include "x2_inc_switches"
|
||||
#include "inc_AI"
|
||||
|
||||
int AttackRanged(object oTarget,int nBonus)
|
||||
{
|
||||
int nRoll = d20();
|
||||
if ( nRoll == 20 && !GetIsImmune(oTarget,IMMUNITY_TYPE_CRITICAL_HIT) )
|
||||
return 2;
|
||||
nRoll += nBonus;
|
||||
int nAC = GetAC(oTarget);
|
||||
|
||||
if ( nRoll >= nAC )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DoSpecialRangedAttack( object oTarget, object oCaster )
|
||||
{
|
||||
|
||||
SetFacingPoint(GetPosition(oTarget));
|
||||
ActionPlayAnimation(ANIMATION_LOOPING_CONJURE1,1.0,2.0);
|
||||
|
||||
effect eBeam;
|
||||
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_LIGHTNING_S);
|
||||
int nDam = d6(10);
|
||||
|
||||
// float fAngle = GetAngleBetweenLocations(GetLocation(oCaster),GetLocation(oTarget));
|
||||
// SetFacing(fAngle);
|
||||
|
||||
|
||||
int nTouch = TouchAttackRanged(oTarget);
|
||||
if ( nTouch == 2 && !GetIsImmune(oTarget,IMMUNITY_TYPE_CRITICAL_HIT))
|
||||
nDam *= 2;
|
||||
|
||||
effect eDamage = EffectDamage(nDam,DAMAGE_TYPE_ELECTRICAL);
|
||||
|
||||
if ( !nTouch )
|
||||
{
|
||||
eBeam = EffectBeam(VFX_BEAM_LIGHTNING,oCaster,BODY_NODE_CHEST,TRUE);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eBeam,oTarget,1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
eBeam = EffectBeam(VFX_BEAM_LIGHTNING,oCaster,BODY_NODE_CHEST);
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eBeam,oTarget,1.0);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oTarget);
|
||||
}
|
||||
|
||||
int nCount;
|
||||
effect eImp = EffectVisualEffect(VFX_COM_BLOOD_SPARK_MEDIUM);
|
||||
effect eDam;
|
||||
effect eMIRV = EffectVisualEffect(359);
|
||||
|
||||
float fDist = GetDistanceBetween(OBJECT_SELF, oTarget);
|
||||
float fDelay = fDist/(3.0 * log(fDist) + 2.0);
|
||||
float fTime;
|
||||
float fDelay2 = 0.0;
|
||||
|
||||
for ( nCount = 1; nCount <= 6; nCount ++ )
|
||||
{
|
||||
nDam = d6(2)+12;
|
||||
nTouch = AttackRanged(oTarget,30);
|
||||
if ( nTouch == 2 )
|
||||
nDam *= 2;
|
||||
|
||||
DelayCommand(fDelay2, ApplyEffectToObject(DURATION_TYPE_INSTANT, eMIRV, oTarget));
|
||||
if ( nTouch )
|
||||
{
|
||||
eDam = EffectDamage(nDam,DAMAGE_TYPE_PIERCING,DAMAGE_POWER_PLUS_EIGHT);
|
||||
fTime = fDelay;
|
||||
fDelay2 += 0.1;
|
||||
fTime += fDelay2;
|
||||
|
||||
DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eImp, oTarget));
|
||||
|
||||
|
||||
DelayCommand(fTime, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
|
||||
// Play the sound of a dart hitting
|
||||
DelayCommand(fTime, PlaySound("cb_ht_dart1"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DoPhysical( object oTarget, object oCaster )
|
||||
{
|
||||
if ( d4() == 4 )
|
||||
{
|
||||
ClearAllActions();
|
||||
ActionCastSpellAtObject(SPELLABILITY_CONE_SONIC,oTarget,METAMAGIC_ANY,TRUE);
|
||||
return;
|
||||
}
|
||||
if ( !GetIsObjectValid(oTarget) || !GetIsEnemy(oTarget) )
|
||||
{
|
||||
oTarget = GetNearestEnemy();
|
||||
if ( !GetIsObjectValid(oTarget) )
|
||||
return;
|
||||
}
|
||||
// object oEquip = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND);
|
||||
if ( GetDistanceToObject(oTarget) > FeetToMeters(20.0) )
|
||||
{
|
||||
// if ( !GetIsObjectValid( oEquip ) || !GetWeaponRanged( oEquip ) )
|
||||
// ActionEquipMostDamagingRanged();
|
||||
// ActionAttack(oTarget);
|
||||
SetLocalInt(OBJECT_SELF,"Acting",1);
|
||||
DoSpecialRangedAttack(oTarget,oCaster);
|
||||
DelayCommand(6.0,SetLocalInt(OBJECT_SELF,"Acting",0));
|
||||
DelayCommand(6.1,DetermineCombatRound());
|
||||
}
|
||||
else
|
||||
{
|
||||
// if ( !GetIsObjectValid( oEquip ) || GetWeaponRanged( oEquip ) )
|
||||
// ActionEquipMostDamagingMelee();
|
||||
TalentMeleeAttack(oTarget);
|
||||
}
|
||||
SetCreatureOverrideAIScriptFinished();
|
||||
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// The following two lines should not be touched
|
||||
object oIntruder = GetCreatureOverrideAIScriptTarget();
|
||||
ClearCreatureOverrideAIScriptTarget();
|
||||
if ( !GetCanAct(OBJECT_SELF) )
|
||||
{
|
||||
SetCreatureOverrideAIScriptFinished();
|
||||
return;
|
||||
}
|
||||
if ( GetLocalInt(OBJECT_SELF,"Acting") )
|
||||
{
|
||||
SetCreatureOverrideAIScriptFinished();
|
||||
return;
|
||||
}
|
||||
/* if ( d6() == 1 ) // in case they get busy-stuck, also to add randomness
|
||||
{
|
||||
SetLocalInt(OBJECT_SELF,"busy",FALSE);
|
||||
return;
|
||||
} */
|
||||
// Don't inturupt actions in progress
|
||||
|
||||
|
||||
if ( GetCurrentAction() == ACTION_CASTSPELL )
|
||||
{
|
||||
SetCreatureOverrideAIScriptFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( GetLocalInt(OBJECT_SELF,"physical") )
|
||||
{
|
||||
ClearAllActions();
|
||||
DoPhysical(oIntruder,OBJECT_SELF);
|
||||
return;
|
||||
}
|
||||
// Haste = Super awesome;
|
||||
// Get those summons in there!
|
||||
int nSummonCount = GetLocalInt(OBJECT_SELF,"SummonCount");
|
||||
if ( !GetIsObjectValid(GetAssociate(ASSOCIATE_TYPE_SUMMONED)) && nSummonCount < 4 )
|
||||
{
|
||||
nSummonCount++;
|
||||
SetLocalInt(OBJECT_SELF,"SummonCount",nSummonCount);
|
||||
ClearAllActions();
|
||||
ActionCastFakeSpellAtLocation(SPELL_SUMMON_CREATURE_IX,GetLocation(OBJECT_SELF));
|
||||
effect eSummon = EffectSummonCreature("NW_GOLIRON",VFX_FNF_SUMMON_MONSTER_3,1.0);
|
||||
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,eSummon,GetLocation(OBJECT_SELF),HoursToSeconds(24));
|
||||
SetCreatureOverrideAIScriptFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Hostile targeting actions
|
||||
if ( !GetIsObjectValid(oIntruder) || !GetIsReactionTypeHostile(oIntruder) )
|
||||
{
|
||||
oIntruder = GetNearestPerceivedEnemy();
|
||||
if ( !GetIsObjectValid(oIntruder) )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( d3() == 3 )
|
||||
{
|
||||
ClearAllActions();
|
||||
ActionCastSpellAtObject(SPELLABILITY_CONE_SONIC,oIntruder,METAMAGIC_ANY,TRUE);
|
||||
SetCreatureOverrideAIScriptFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
// Melee up sometimes!
|
||||
|
||||
if ( d6() == 6 )
|
||||
{
|
||||
switch ( d4() )
|
||||
{
|
||||
case 1:
|
||||
PlayVoiceChat(VOICE_CHAT_BATTLECRY1);
|
||||
break;
|
||||
case 2:
|
||||
PlayVoiceChat(VOICE_CHAT_ATTACK);
|
||||
break;
|
||||
case 3:
|
||||
PlayVoiceChat(VOICE_CHAT_BATTLECRY2);
|
||||
break;
|
||||
case 4:
|
||||
PlayVoiceChat(VOICE_CHAT_BATTLECRY3);
|
||||
break;
|
||||
}
|
||||
|
||||
SetLocalInt(OBJECT_SELF,"physical",1);
|
||||
DelayCommand(24.0,SetLocalInt(OBJECT_SELF,"physical",0));
|
||||
ClearAllActions();
|
||||
DoPhysical(oIntruder,OBJECT_SELF);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user