RATDOG/_module/nss/atropal_ai.nss
Jaysyn904 df709d33fc Horsefly Swamp update
Creatures & encounter tables to support Horsefly swamp expansion.
2023-08-13 17:21:44 -04:00

252 lines
7.7 KiB
Plaintext

#include "nw_i0_generic"
#include "x2_inc_switches"
#include "inc_AI"
#include "nw_i0_spells"
#include "prc_inc_spells"
void DoTouchAttack(object oTarget, object oCaster )
{
ActionPlayAnimation(ANIMATION_LOOPING_GET_MID,1.0,2.0);
int nDam = 5;
int nHeal = 20;
int nRoll = TouchAttackMelee(oTarget,TRUE);
if ( nRoll == 0 )
return;
// improved critical gives 19-20
if ( !GetIsImmune(oTarget,IMMUNITY_TYPE_CRITICAL_HIT) && ( nRoll == 2 || ( nRoll == 1 && d20() == 20 )) )
{
effect eNegative = EffectDamage(d6(),DAMAGE_TYPE_NEGATIVE);
// crit hit, overwhelming critical
nDam *= 2;
nHeal *= 2;
int nDC = 10 + GetHitDice(oCaster) / 2 + GetAbilityModifier(ABILITY_STRENGTH,oCaster);
FloatingTextStringOnCreature("Devastating Critical!",oTarget);
if ( !PRCMySavingThrow(SAVING_THROW_FORT,oTarget,nDC,SAVING_THROW_TYPE_NONE,oCaster) )
{
effect eHP = EffectDamage(GetMaxHitPoints(oTarget));
ApplyEffectToObject(DURATION_TYPE_INSTANT,eHP,oTarget);
}
ApplyEffectToObject(DURATION_TYPE_INSTANT,eNegative,oTarget);
}
if ( GetIsImmune(oTarget,IMMUNITY_TYPE_ABILITY_DECREASE) )
return;
effect eHeal = EffectHeal(nHeal);
effect eHealVis = EffectVisualEffect(VFX_IMP_HEALING_L);
effect eVis = EffectVisualEffect(VFX_IMP_REDUCE_ABILITY_SCORE);
effect eCon = EffectAbilityDecrease(ABILITY_CONSTITUTION,nDam);
eCon = SupernaturalEffect(eCon);
eCon = ExtraordinaryEffect(eCon);
int bKillEm = FALSE;
if ( !GetIsPC(oTarget) || GetGameDifficulty() == GAME_DIFFICULTY_CORE_RULES
|| GetGameDifficulty() == GAME_DIFFICULTY_DIFFICULT )
bKillEm = TRUE;
if ( !PRCMySavingThrow(SAVING_THROW_FORT,oTarget,59,SAVING_THROW_TYPE_NONE,oCaster) )
{
int nCon = GetAbilityScore(oTarget,ABILITY_CONSTITUTION);
if ( ( nCon - nDam ) < 3 && bKillEm )
{
effect eVis2 = EffectVisualEffect(VFX_IMP_DEATH);
effect eHP = EffectDamage( 9999 , DAMAGE_TYPE_MAGICAL , DAMAGE_POWER_PLUS_TWENTY);
effect eDeath = EffectDeath();
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis2,oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eDeath,oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eHP,oTarget);
}
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eCon,oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eHeal,oCaster);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eHealVis,oCaster);
}
}
/* void DoEnergyDrainRay(object oTarget, object oCaster )
{
int nRoll = TouchAttackRanged(oTarget,TRUE);
effect eBeam;
if ( nRoll == 0 )
{ // miss
eBeam = EffectBeam(VFX_BEAM_EVIL,oCaster,BODY_NODE_CHEST,TRUE);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eBeam,oTarget,1.5);
return;
}
int nDrain = 4;
int nHeal = 40;
if ( !GetIsImmune(oTarget,IMMUNITY_TYPE_CRITICAL_HIT) && ( nRoll == 2 || ( nRoll == 1 && d20() == 20 )) )
{
nDrain *= 2;
nHeal *= 2;
}
eBeam = EffectBeam(VFX_BEAM_EVIL,oCaster,BODY_NODE_CHEST);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eBeam,oTarget,1.5);
effect eVis = EffectVisualEffect(VFX_IMP_NEGATIVE_ENERGY);
effect eDrain = EffectNegativeLevel(nDrain);
eDrain = SupernaturalEffect(eDrain);
eDrain = ExtraordinaryEffect(eDrain);
effect eHeal = EffectHeal(nHeal);
effect eHealVis = EffectVisualEffect(VFX_IMP_HEALING_L);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eDrain,oTarget);
if ( !GetIsImmune(oTarget,IMMUNITY_TYPE_NEGATIVE_LEVEL) )
{
ApplyEffectToObject(DURATION_TYPE_INSTANT,eHeal,oCaster);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eHealVis,oCaster);
}
} */
void DoEnergyDrainRay( object oTarget, object oCaster )
{
ActionCastSpellAtObject(SPELLABILITY_BOLT_LEVEL_DRAIN,oTarget,METAMAGIC_ANY,TRUE);
}
void DoPhysical( object oTarget, object oCaster )
{
if ( !GetIsObjectValid(oTarget) || !GetIsEnemy(oTarget) )
{
oTarget = GetNearestEnemy();
if ( !GetIsObjectValid(oTarget) )
return;
}
if ( GetDistanceToObject(oTarget) > FeetToMeters(20.0) )
{
// SetLocalInt(OBJECT_SELF,"Acting",1);
DoEnergyDrainRay(oTarget,oCaster);
// DelayCommand(6.0,SetLocalInt(OBJECT_SELF,"Acting",0));
// DelayCommand(6.1,DetermineCombatRound());
}
else
{
ActionMoveToObject(oTarget,TRUE);
SetLocalInt(OBJECT_SELF,"Acting",1);
DelayCommand(0.1,DoTouchAttack(oTarget,oCaster));
DelayCommand(3.0,DoTouchAttack(oTarget,oCaster));
DelayCommand(6.0,SetLocalInt(OBJECT_SELF,"Acting",0));
DelayCommand(6.1,DetermineCombatRound());
}
SetCreatureOverrideAIScriptFinished();
}
void main()
{
// The following two lines should not be touched
object oIntruder = GetCreatureOverrideAIScriptTarget();
ClearCreatureOverrideAIScriptTarget();
int bAura = GetLocalInt(OBJECT_SELF,"aura");
if ( !bAura )
{
string sScript = GetLocalString(OBJECT_SELF,"Aura_Script");
ExecuteScript(sScript,OBJECT_SELF);
SetLocalInt(OBJECT_SELF,"aura",1);
}
if ( !GetCanAct(OBJECT_SELF) )
{
SetCreatureOverrideAIScriptFinished();
return;
}
if ( GetLocalInt(OBJECT_SELF,"Acting") == 1 )
{
// SpeakString("I am acting! rawr!");
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 )
{
// SpeakString("I am casting! Rawr!");
SetCreatureOverrideAIScriptFinished();
return;
}
if ( GetLocalInt(OBJECT_SELF,"physical") )
{
// SpeakString("Time to die!");
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 < 5 )
{
nSummonCount++;
SetLocalInt(OBJECT_SELF,"SummonCount",nSummonCount);
ClearAllActions();
ActionCastFakeSpellAtLocation(SPELL_SUMMON_CREATURE_IX,GetLocation(OBJECT_SELF));
effect eSummon = EffectSummonCreature("Nightcrawler",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;
}
// 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;
}
// SpeakString("DIEDIEIDE");
SetLocalInt(OBJECT_SELF,"physical",1);
DelayCommand(24.0,SetLocalInt(OBJECT_SELF,"physical",0));
ClearAllActions();
DoPhysical(oIntruder,OBJECT_SELF);
return;
}
}