2021-08-30 17:31:44 -04:00
|
|
|
/*/////////////////////// [Ability - Dragon Wing Buffet] ///////////////////////
|
2021-08-29 23:34:48 -04:00
|
|
|
Filename: J_AI_WingBuffet
|
2021-08-30 17:31:44 -04:00
|
|
|
///////////////////////// [Ability - Dragon Wing Buffet] ///////////////////////
|
2021-08-29 23:34:48 -04:00
|
|
|
"The dragon will launch into the air, knockdown
|
|
|
|
all opponents who fail a Reflex Save and then
|
|
|
|
land on one of those opponents doing damage
|
|
|
|
up to a maximum of the Dragons HD + 10."
|
|
|
|
|
|
|
|
This is modified by Jasperre for use by Dragons in the AI. Instead of
|
|
|
|
crashing, using effect appear, disspear, it just uses effect appear.
|
|
|
|
|
2021-08-30 17:31:44 -04:00
|
|
|
///////////////////////// [History] ////////////////////////////////////////////
|
|
|
|
1.3 - Made the "action attack" work better, getting the nearest
|
|
|
|
seen and heard instead of the nearest (which may not be seen or heard).
|
|
|
|
- Added in random damage for each target!
|
|
|
|
- Faction Equal as well as GetIsFriend check.
|
|
|
|
1.4 - Cleaned it up a bit, to be more readable.
|
|
|
|
///////////////////////// [Workings] ///////////////////////////////////////////
|
2021-08-29 23:34:48 -04:00
|
|
|
Executed via. ExecuteScript from the AI file, it is seperate because it is
|
|
|
|
almost a new AI ability.
|
2021-08-30 17:31:44 -04:00
|
|
|
///////////////////////// [Arguments] //////////////////////////////////////////
|
2021-08-29 23:34:48 -04:00
|
|
|
Arguments: N/A
|
2021-08-30 17:31:44 -04:00
|
|
|
///////////////////////// [Ability - Dragon Wing Buffet] /////////////////////*/
|
2021-08-29 23:34:48 -04:00
|
|
|
|
|
|
|
void main()
|
|
|
|
{
|
2021-08-30 17:31:44 -04:00
|
|
|
// Stop the creature's actions.
|
2021-08-29 23:34:48 -04:00
|
|
|
ClearAllActions();// To rid errors.
|
2021-08-30 17:31:44 -04:00
|
|
|
|
|
|
|
// Declare major variables
|
2021-08-29 23:34:48 -04:00
|
|
|
int nDamage;
|
|
|
|
int nDC = GetHitDice(OBJECT_SELF);
|
|
|
|
location lSelf = GetLocation(OBJECT_SELF);
|
|
|
|
string sMessage = GetName(OBJECT_SELF) + " is using its wing buffet against you!";
|
|
|
|
location lTarget;
|
|
|
|
float fRandomKnockdown;
|
2021-08-30 17:31:44 -04:00
|
|
|
// Use a delay based on range,
|
|
|
|
float fDelay;
|
|
|
|
|
|
|
|
// Declare effects
|
|
|
|
effect eDam;
|
|
|
|
effect eKnockDown = EffectKnockdown();
|
|
|
|
effect eVis = EffectVisualEffect(VFX_IMP_PULSE_WIND);
|
|
|
|
|
2021-08-29 23:34:48 -04:00
|
|
|
// Pulse of wind applied...
|
|
|
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lSelf);
|
2021-08-30 17:31:44 -04:00
|
|
|
|
|
|
|
// Get first target in spell area
|
2021-08-29 23:34:48 -04:00
|
|
|
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lSelf);
|
|
|
|
while(GetIsObjectValid(oTarget))
|
|
|
|
{
|
2021-08-30 17:31:44 -04:00
|
|
|
// Get thier location (for visual) and the delay.
|
2021-08-29 23:34:48 -04:00
|
|
|
lTarget = GetLocation(oTarget);
|
|
|
|
fDelay = GetDistanceToObject(oTarget)/20.0;
|
2021-08-30 17:31:44 -04:00
|
|
|
|
2021-08-29 23:34:48 -04:00
|
|
|
// Wind pulse to all
|
|
|
|
DelayCommand(fDelay, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lTarget));
|
2021-08-30 17:31:44 -04:00
|
|
|
|
2021-08-29 23:34:48 -04:00
|
|
|
// Do not effect allies.
|
|
|
|
if(!GetIsFriend(oTarget) && !GetFactionEqual(oTarget))
|
|
|
|
{
|
2021-08-30 17:31:44 -04:00
|
|
|
// Send a message about the wing buffet (allies do not see this)
|
2021-08-29 23:34:48 -04:00
|
|
|
SendMessageToPC(oTarget, sMessage);
|
2021-08-30 17:31:44 -04:00
|
|
|
|
|
|
|
// Huge creatures (IE: Dragon size) are not affected.
|
2021-08-29 23:34:48 -04:00
|
|
|
if(GetCreatureSize(oTarget) != CREATURE_SIZE_HUGE)
|
|
|
|
{
|
2021-08-30 17:31:44 -04:00
|
|
|
// A standard (not spell) reflex save negates the damage and knockdown
|
2021-08-29 23:34:48 -04:00
|
|
|
if(!ReflexSave(oTarget, nDC))
|
|
|
|
{
|
|
|
|
// Randomise damage. (nDC = Hit dice)
|
|
|
|
nDamage = Random(nDC) + 11;
|
2021-08-30 17:31:44 -04:00
|
|
|
|
|
|
|
// Define the damage
|
2021-08-29 23:34:48 -04:00
|
|
|
eDam = EffectDamage(nDamage, DAMAGE_TYPE_BLUDGEONING);
|
2021-08-30 17:31:44 -04:00
|
|
|
|
|
|
|
// Randomise knockdown duration, to minimum of 6.0 (1.0/2 = 0.5. + 5.5 = 6.0)
|
2021-08-29 23:34:48 -04:00
|
|
|
fRandomKnockdown = 5.5 + ((IntToFloat(Random(30)) + 1.0)/10.0);
|
2021-08-30 17:31:44 -04:00
|
|
|
|
2021-08-29 23:34:48 -04:00
|
|
|
// We'll have a windy effect..depending on range
|
|
|
|
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
|
|
|
|
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eKnockDown, oTarget, fRandomKnockdown));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-08-30 17:31:44 -04:00
|
|
|
// Get next target in spell area
|
2021-08-29 23:34:48 -04:00
|
|
|
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lSelf);
|
|
|
|
}
|
2021-08-30 17:31:44 -04:00
|
|
|
|
2021-08-29 23:34:48 -04:00
|
|
|
// Do a great flapping wings on land effect.
|
|
|
|
effect eAppear = EffectAppear();
|
|
|
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eAppear, OBJECT_SELF);
|
2021-08-30 17:31:44 -04:00
|
|
|
|
|
|
|
// Attack the nearest seen (so not to stand there for 6 seconds, but get
|
|
|
|
// back in the action!).
|
2021-08-29 23:34:48 -04:00
|
|
|
object oNearest = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_IS_ALIVE, TRUE);
|
|
|
|
if(GetIsObjectValid(oNearest))
|
|
|
|
{
|
|
|
|
DelayCommand(1.0, ActionAttack(oNearest));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
oNearest = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_HEARD, CREATURE_TYPE_IS_ALIVE, TRUE);
|
|
|
|
if(GetIsObjectValid(oNearest))
|
|
|
|
{
|
|
|
|
DelayCommand(1.0, ActionAttack(oNearest));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|